Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for util functions used by NumericFormat #808

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 44 additions & 38 deletions src/numeric_format.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ function getSeparators<BaseType = InputAttributes>(props: NumericFormatProps<Bas
};
}

function handleNegation(value: string = '', allowNegative: boolean) {
export function handleNegation(value: string = '', allowNegative: boolean) {
const negationRegex = new RegExp('(-)');
const doubleNegationRegex = new RegExp('(-)(.)*(-)');

Expand Down Expand Up @@ -133,6 +133,47 @@ function isNumericString(
);
}

export const stripNegation = (
value: string,
start: number,
end: number,
prefix: string,
suffix: string,
) => {
/**
* if prefix starts with - we don't allow negative number to avoid confusion
* if suffix starts with - and the value length is same as suffix length, then the - sign is from the suffix
* In other cases, if the value starts with - then it is a negation
*/
let hasNegation = false;
let hasDoubleNegation = false;

if (prefix.startsWith('-')) {
hasNegation = false;
} else if (value.startsWith('--')) {
hasNegation = false;
hasDoubleNegation = true;
} else if (suffix.startsWith('-') && value.length === suffix.length) {
hasNegation = false;
} else if (value[0] === '-') {
hasNegation = true;
}

let charsToRemove = hasNegation ? 1 : 0;
if (hasDoubleNegation) charsToRemove = 2;

// remove negation/double negation from start to simplify prefix logic as negation comes before prefix
if (charsToRemove) {
value = value.substring(charsToRemove);

// account for the removal of the negation for start and end index
start -= charsToRemove;
end -= charsToRemove;
}

return { value, start, end, hasNegation };
};

export function removeFormatting<BaseType = InputAttributes>(
value: string,
changeMeta: ChangeMeta = getDefaultChangeMeta(value),
Expand Down Expand Up @@ -163,50 +204,15 @@ export function removeFormatting<BaseType = InputAttributes>(
value = value.substring(0, start) + separator + value.substring(start + 1, value.length);
}

const stripNegation = (value: string, start: number, end: number) => {
/**
* if prefix starts with - we don't allow negative number to avoid confusion
* if suffix starts with - and the value length is same as suffix length, then the - sign is from the suffix
* In other cases, if the value starts with - then it is a negation
*/
let hasNegation = false;
let hasDoubleNegation = false;

if (prefix.startsWith('-')) {
hasNegation = false;
} else if (value.startsWith('--')) {
hasNegation = false;
hasDoubleNegation = true;
} else if (suffix.startsWith('-') && value.length === suffix.length) {
hasNegation = false;
} else if (value[0] === '-') {
hasNegation = true;
}

let charsToRemove = hasNegation ? 1 : 0;
if (hasDoubleNegation) charsToRemove = 2;

// remove negation/double negation from start to simplify prefix logic as negation comes before prefix
if (charsToRemove) {
value = value.substring(charsToRemove);

// account for the removal of the negation for start and end index
start -= charsToRemove;
end -= charsToRemove;
}

return { value, start, end, hasNegation };
};

const toMetadata = stripNegation(value, start, end);
const toMetadata = stripNegation(value, start, end, prefix, suffix);
const { hasNegation } = toMetadata;
({ value, start, end } = toMetadata);

const {
start: fromStart,
end: fromEnd,
value: lastValue,
} = stripNegation(changeMeta.lastValue, from.start, from.end);
} = stripNegation(changeMeta.lastValue, from.start, from.end, prefix, suffix);

// if only prefix and suffix part is updated reset the value to last value
// if the changed range is from suffix in the updated value, and the the suffix starts with the same characters, allow the change
Expand Down
39 changes: 39 additions & 0 deletions test/library/utils/numeric-format/handle-negation.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { handleNegation } from '../../../../src/numeric_format';
import { TestCases } from '../common';

type Expected = string;

type Arguments = {
value: string;
allowNegative: boolean;
};

describe('handleNegation', () => {
const testCases: TestCases<Arguments, Expected>[] = [
{
label: 'negative integers',
cases: [
{ arguments: { value: '-10-1000', allowNegative: true }, expected: '-10' },
{ arguments: { value: '-110', allowNegative: false }, expected: '110' },
],
},
{
label: 'negative floats',
cases: [
{ arguments: { value: '-10.1', allowNegative: true }, expected: '-10.1' },
{ arguments: { value: '-110.100', allowNegative: false }, expected: '110.100' },
],
},
];

for (const testCase of testCases) {
describe.only(testCase.label, () => {
test.each(testCase.cases)(
'%arguments.value',
({ arguments: { value, allowNegative }, expected }) => {
expect(handleNegation(value, allowNegative)).toEqual(expected);
},
);
});
}
});
54 changes: 54 additions & 0 deletions test/library/utils/numeric-format/remove-formatting.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { removeFormatting } from '../../../../src/numeric_format';
import { ChangeMeta, InputAttributes, NumericFormatProps } from '../../../../src/types';
import { TestCases } from '../common';

type Expected = string;

type Arguments = {
value: string;
changeMeta: ChangeMeta;
props: NumericFormatProps<InputAttributes>;
};

describe('removeFormatting', () => {
const defaultProps = { allowNegative: true, decimalScale: 2, thousandSeparator: ',' };

const testCases: TestCases<Arguments, Expected>[] = [
{
label: 'with prefix and suffix',
cases: [
{
arguments: {
value: '100-1000 USD',
changeMeta: { from: { start: 0, end: 0 }, to: { start: 0, end: 12 }, lastValue: '' },
props: { ...defaultProps, prefix: '100-', suffix: '000 USD' },
},
expected: '1',
},
{
arguments: {
value: '100-10000 USD',
changeMeta: {
from: { start: 8, end: 8 },
to: { start: 8, end: 9 },
lastValue: '100-10000 USD',
},
props: { ...defaultProps, prefix: '100-', suffix: '000 USD' },
},
expected: '10',
},
],
},
];

for (const testCase of testCases) {
describe(testCase.label, () => {
test.each(testCase.cases)(
'%arguments.value',
({ arguments: { value, changeMeta, props }, expected }) => {
expect(removeFormatting(value, changeMeta, props)).toBe(expected);
},
);
});
}
});
56 changes: 56 additions & 0 deletions test/library/utils/numeric-format/strip-negation.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { stripNegation } from '../../../../src/numeric_format';
import { TestCases } from '../common';

type Expected = {
value: string;
start: number;
end: number;
hasNegation: boolean;
};

type Arguments = {
value: string;
start: number;
end: number;
prefix: string;
suffix: string;
};

describe('stripNegation', () => {
const testCases: TestCases<Arguments, Expected>[] = [
{
label: 'negative floats',
cases: [
{
arguments: { value: '0.0345', start: 0, end: 6, prefix: '100-', suffix: '1000 USD' },
expected: { value: '0.0345', start: 0, end: 6, hasNegation: false },
},
{
arguments: { value: '-0.0345', start: 0, end: 6, prefix: '100-', suffix: '1000 USD' },
expected: { value: '0.0345', start: 0, end: 1, hasNegation: true },
},
{
arguments: {
value: '100-10000 USD',
start: 8,
end: 8,
prefix: '100-',
suffix: '1000 USD',
},
expected: { value: '100-10000 USD', start: 8, end: 8, hasNegation: false },
},
],
},
];

for (const testCase of testCases) {
describe(testCase.label, () => {
test.each(testCase.cases)(
'%arguments.value',
({ arguments: { value, start, end, prefix, suffix }, expected }) => {
expect(stripNegation(value, start, end, prefix, suffix)).toEqual(expected);
},
);
});
}
});