Skip to content

Commit fd0b96b

Browse files
committed
CCM-11438 Update interpolate and tests
1 parent 2cb9498 commit fd0b96b

File tree

2 files changed

+42
-39
lines changed

2 files changed

+42
-39
lines changed
Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,41 @@
11
import { interpolate } from '@utils/interpolate';
22

33
describe('interpolate', () => {
4+
it('returns empty string if input is empty', () => {
5+
expect(interpolate('', { name: 'Test' })).toBe('');
6+
});
7+
8+
it('returns the same string if no placeholders are present', () => {
9+
expect(interpolate('No interpolation needed.', {})).toBe(
10+
'No interpolation needed.'
11+
);
12+
});
13+
414
it('replaces simple variables', () => {
515
expect(interpolate('Hello {{name}}!', { name: 'Test' })).toBe(
616
'Hello Test!'
717
);
818
});
919

10-
it('replaces plural based on value', () => {
20+
it('removes variable if missing', () => {
21+
expect(interpolate('Hello {{name}}!', {})).toBe('Hello !');
22+
});
23+
24+
it('replaces plural based on numeric value', () => {
1125
expect(interpolate('{{count|item|items}}', { count: 1 })).toBe('item');
1226
expect(interpolate('{{count|item|items}}', { count: 3 })).toBe('items');
1327
});
1428

15-
it('replaces variable and plural in same string', () => {
29+
it('falls back to plural if variable is not a number', () => {
30+
expect(interpolate('{{count|item|items}}', { count: 'abc' })).toBe('items');
31+
});
32+
33+
it('replaces variable and plural in the same string', () => {
1634
expect(interpolate('{{count}} {{count|item|items}}', { count: 2 })).toBe(
1735
'2 items'
1836
);
19-
});
20-
21-
it('removes variable if missing', () => {
22-
expect(interpolate('Hello {{name}}!', {})).toBe('Hello !');
23-
});
24-
25-
it('falls back to plural if count is invalid', () => {
26-
expect(interpolate('{{count|item|items}}', { count: 'not-a-number' })).toBe(
27-
'items'
37+
expect(interpolate('{{count}} {{count|item|items}}', { count: 1 })).toBe(
38+
'1 item'
2839
);
2940
});
3041

@@ -36,4 +47,13 @@ describe('interpolate', () => {
3647
)
3748
).toBe('2 characters as 1 text message');
3849
});
50+
51+
it('handles missing variables by not including them', () => {
52+
expect(
53+
interpolate(
54+
'{{characters}} {{characters|character|characters}} and {{missing}} {{missing|apple|apples}}',
55+
{ characters: 1 }
56+
)
57+
).toBe('1 character and apples');
58+
});
3959
});

frontend/src/utils/interpolate.ts

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,30 @@
66
* - pluralisation: `{{variable|singular|plural}}`
77
*
88
* Example:
9-
* ```ts
109
* interpolate('Hello {{name}}, you have {{count}} {{count|message|messages}}.', {
1110
* name: 'John',
1211
* count: 2,
13-
* });
14-
* // => 'Hello John, you have 2 messages.'
15-
*
16-
* interpolate('Hello {{name}}, you have {{count}} {{count|message|messages}}.', {
17-
* name: 'John',
18-
* count: 1,
19-
* });
20-
* // => 'Hello John, you have 1 message.'
21-
* ```
22-
*
23-
* @param template - The string containing `{{...}}` placeholders
24-
* @param variables - An object of variables
25-
* @returns The interpolated string
12+
* }); // => 'Hello John, you have 2 messages.'
2613
*/
2714

2815
// eslint-disable-next-line security/detect-unsafe-regex, sonarjs/slow-regex
29-
const interpolationPattern = /{{\s*([^|}]+)(?:\|([^|}]+)\|([^}]+))?\s*}}/g;
16+
const interpolationPattern = /{{([^|}]+)(?:\|([^|}]+)\|([^}]+))?}}/g;
3017

3118
export function interpolate(
3219
template: string,
3320
variables: Record<string, string | number> = {}
3421
): string {
3522
// eslint-disable-next-line unicorn/prefer-string-replace-all
36-
return template.replace(
37-
interpolationPattern,
38-
(_match, variable, singular, plural) => {
39-
const key = variable.trim();
40-
const value = variables[key];
41-
42-
if (singular !== undefined && plural !== undefined) {
43-
const count = Number(value);
23+
return template.replace(interpolationPattern, (_, key, singular, plural) => {
24+
const value = variables[key];
4425

45-
if (Number.isNaN(count)) return plural;
46-
return count === 1 ? singular : plural;
47-
}
26+
if (singular !== undefined && plural !== undefined) {
27+
const numeric = Number(value);
4828

49-
return value == null ? '' : String(value);
29+
if (Number.isNaN(numeric)) return plural;
30+
return numeric === 1 ? singular : plural;
5031
}
51-
);
32+
33+
return value == null ? '' : String(value);
34+
});
5235
}

0 commit comments

Comments
 (0)