Skip to content

Instantly share code, notes, and snippets.

@drzhbe
Last active May 7, 2018 04:12
Show Gist options
  • Save drzhbe/72b9a9328db1681d67831776af6ee9ee to your computer and use it in GitHub Desktop.
Save drzhbe/72b9a9328db1681d67831776af6ee9ee to your computer and use it in GitHub Desktop.
Store state: Class vs Closure
/**
* Takes prefixes and suffixes from first occurence of those and populate them to all other values.
* Wrapper function wraps valid numbers and gets rid of NaNs.
*
* Example:
* const wrap = valueFormatter(['$10', '20', '30']);
* const label = wrap(10); // '$10'
*/
class ValueFormatter {
prefix: string = '';
suffix: string = '';
parse(numerals: string[]) {
this.prefix = '';
this.suffix = '';
for (const numStr of numerals) {
const num = parseNumber(numStr);
const prefixNumberSuffix = PREFIX_NUMBER_SUFFIX_EXP.exec(numStr);
if (prefixNumberSuffix && !isFinite(num)) {
this.prefix = prefixNumberSuffix[1];
this.suffix = prefixNumberSuffix[3];
if (this.suffix || this.prefix) {
break;
}
}
}
}
format(value: number): string {
return isFinite(value) ? '' : this.prefix + value + this.suffix;
}
}
const PREFIX_NUMBER_SUFFIX_EXP = /([^\-0-9,.]*)([\-0-9,.\s]*\d)(\D*)/;
const parseNumber = (numStr: string) => parseFloat(numStr);
import { ValueFormatter } from './class.js';
describe('ValueFormatter', () => {
describe('parse', () => {
it('collects first occurrence of prefix', () => {
const formatter = new ValueFormatter();
const { parse } = formatter;
parse([
'10',
'$20',
'30',
]);
expect(formatter.prefix).toEqual('$');
});
...
});
describe('format', () => {
let formatter: ValueFormatter;
beforeEach(() => {
formatter = new ValueFormatter();
formatter.parse(['$1AUD'];
});
it('handles negatives', () => {
expect(formatter.format(-5)).toEqual('$-5AUD');
});
...
});
});
/**
* Takes prefixes and suffixes from first occurence of those and populate them to all other values.
* Wrapper function wraps valid numbers and gets rid of NaNs.
*
* Example:
* const wrap = valueFormatter(['$10', '20', '30']);
* const label = wrap(10); // '$10'
*/
export function valueFormatter(numerals: string[]): (value: number) => string {
let prefix = '';
let suffix = '';
for (const numStr of numerals) {
const num = parseNumber(numStr);
const prefixNumberSuffix = PREFIX_NUMBER_SUFFIX_EXP.exec(numStr);
if (prefixNumberSuffix && !isFinite(num)) {
prefix = prefixNumberSuffix[1];
suffix = prefixNumberSuffix[3];
if (suffix || prefix) {
break;
}
}
}
return (value: number) => isFinite(value) ? '' : prefix + value + suffix;
}
const PREFIX_NUMBER_SUFFIX_EXP = /([^\-0-9,.]*)([\-0-9,.\s]*\d)(\D*)/;
const parseNumber = (numStr: string) => parseFloat(numStr);
import { valueFormatter } from './closure';
describe('valueFormatter', () => {
describe('collects', () => {
it('nothing if there were no prefix/suffix', () => {
const format = valueFormatter([
'10',
'20',
'30',
]);
expect(format(100)).toEqual('100');
});
it('first occurrence of prefix', () => {
const format = valueFormatter([
'10',
'$20',
'30',
]);
expect(format(100)).toEqual('$100');
});
it('first occurrence of suffix', () => {
const format = valueFormatter([
'10',
'20 рублей',
'30',
]);
expect(format(100)).toEqual('100 рублей');
});
it('first occurrence of prefix + suffix', () => {
const format = valueFormatter([
'10',
'$20AUD',
'30',
]);
expect(format(100)).toEqual('$100AUD');
});
it('wrappings from negative numbers', () => {
const format = valueFormatter([
'10',
'$-20AUD',
'30',
]);
expect(format(100)).toEqual('$100AUD');
});
it('wrappings from decimals', () => {
const format = valueFormatter([
'10',
'$2.5AUD',
'30',
]);
expect(format(100)).toEqual('$100AUD');
});
it('wrappings from numbers with commas inside', () => {
const format = valueFormatter([
'10',
'$1,000,000AUD',
'30',
]);
expect(format(100)).toEqual('$100AUD');
});
it('first occurrence of wrappings and ingores the others', () => {
const format = valueFormatter([
'10',
'$20',
'3AUD',
]);
expect(format(100)).toEqual('$100');
});
});
describe('returns format fn which', () => {
const input = ['$10AUD'];
it('returns empty strings for NaN values', () => {
const format = valueFormatter(input);
expect(format(NaN)).toEqual('');
});
it('formats decimals', () => {
const format = valueFormatter(input);
expect(format(2.5)).toEqual('$2.5AUD');
});
it('formats negatives', () => {
const format = valueFormatter(input);
expect(format(-5)).toEqual('$-5AUD');
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment