@pushwoosh/dumb-components 2.9.12 → 2.9.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Switch/styles.js +1 -1
- package/package.json +4 -6
- package/Banner/__tests__/Banner.test.d.ts +0 -1
- package/Banner/__tests__/Banner.test.js +0 -57
- package/Button/__tests__/Button.test.d.ts +0 -1
- package/Button/__tests__/Button.test.js +0 -27
- package/Calendar/__tests__/CalendarMonthSlider.test.d.ts +0 -1
- package/Calendar/__tests__/CalendarMonthSlider.test.js +0 -85
- package/Calendar/__tests__/CellBox.test.d.ts +0 -1
- package/Calendar/__tests__/CellBox.test.js +0 -34
- package/Calendar/__tests__/helpers.test.d.ts +0 -1
- package/Calendar/__tests__/helpers.test.js +0 -143
- package/CardMetric/__tests__/CardMetric.test.d.ts +0 -1
- package/CardMetric/__tests__/CardMetric.test.js +0 -31
- package/Chip/__tests__/Chip.test.d.ts +0 -1
- package/Chip/__tests__/Chip.test.js +0 -101
- package/DateTimePicker/__tests__/YearView.test.d.ts +0 -1
- package/DateTimePicker/__tests__/YearView.test.js +0 -15
- package/DropdownMenu/__tests__/DropdownMenuItem.test.d.ts +0 -1
- package/DropdownMenu/__tests__/DropdownMenuItem.test.js +0 -109
- package/EditableField/__tests__/EditableField.test.d.ts +0 -1
- package/EditableField/__tests__/EditableField.test.js +0 -19
- package/EmailTemplatePreview/__tests__/clickMap.test.d.ts +0 -1
- package/EmailTemplatePreview/__tests__/clickMap.test.js +0 -168
- package/ExternalImagePreview/__tests__/ExternalImagePreview.test.d.ts +0 -1
- package/ExternalImagePreview/__tests__/ExternalImagePreview.test.js +0 -18
- package/InboxPreview/__tests__/helpers.test.d.ts +0 -1
- package/InboxPreview/__tests__/helpers.test.js +0 -201
- package/NativeRichMediaPreview/__tests__/NativeRichMediaPreview.test.d.ts +0 -1
- package/NativeRichMediaPreview/__tests__/NativeRichMediaPreview.test.js +0 -81
- package/PageHeader/__tests__/PageHeader.test.d.ts +0 -1
- package/PageHeader/__tests__/PageHeader.test.js +0 -37
- package/PushPreview/__tests__/PushPreview.test.d.ts +0 -1
- package/PushPreview/__tests__/PushPreview.test.js +0 -26
- package/PushStoriesPreview/__tests__/PushStoriesPreview.test.d.ts +0 -1
- package/PushStoriesPreview/__tests__/PushStoriesPreview.test.js +0 -234
- package/RadioCard/__tests__/RadioCard.test.d.ts +0 -1
- package/RadioCard/__tests__/RadioCard.test.js +0 -23
- package/RichmediaPreview/__tests__/RichmediaPreview.test.d.ts +0 -1
- package/RichmediaPreview/__tests__/RichmediaPreview.test.js +0 -21
- package/SandboxedHtmlFrame/__tests__/SandboxedHtmlFrame.test.d.ts +0 -1
- package/SandboxedHtmlFrame/__tests__/SandboxedHtmlFrame.test.js +0 -57
- package/Skeleton/__tests__/Skeleton.test.d.ts +0 -1
- package/Skeleton/__tests__/Skeleton.test.js +0 -101
- package/Spinner/__tests__/Spinner.test.d.ts +0 -1
- package/Spinner/__tests__/Spinner.test.js +0 -15
- package/Switch/__tests__/Switch.test.d.ts +0 -1
- package/Switch/__tests__/Switch.test.js +0 -44
- package/Tabs/__tests__/TabBar.test.d.ts +0 -1
- package/Tabs/__tests__/TabBar.test.js +0 -36
- package/Toast/__tests__/Toast.test.d.ts +0 -1
- package/Toast/__tests__/Toast.test.js +0 -20
- package/WhatsAppPreview/__tests__/WhatsAppAttachment.test.d.ts +0 -1
- package/WhatsAppPreview/__tests__/WhatsAppAttachment.test.js +0 -53
- package/WhatsAppPreview/__tests__/WhatsAppPreview.test.d.ts +0 -1
- package/WhatsAppPreview/__tests__/WhatsAppPreview.test.js +0 -55
- package/WhatsAppPreview/__tests__/attachment.test.d.ts +0 -1
- package/WhatsAppPreview/__tests__/attachment.test.js +0 -103
- package/WhatsAppPreview/__tests__/parseWhatsAppMarkup.test.d.ts +0 -1
- package/WhatsAppPreview/__tests__/parseWhatsAppMarkup.test.js +0 -59
- package/helpers/__tests__/barcodeUrl.test.d.ts +0 -1
- package/helpers/__tests__/barcodeUrl.test.js +0 -43
- package/helpers/__tests__/timezones.test.d.ts +0 -1
- package/helpers/__tests__/timezones.test.js +0 -188
- package/hooks/__tests__/useLayer.test.d.ts +0 -1
- package/hooks/__tests__/useLayer.test.js +0 -71
- package/polyglot/__tests__/filters.test.d.ts +0 -1
- package/polyglot/__tests__/filters.test.js +0 -152
- package/polyglot/__tests__/helpers.test.d.ts +0 -1
- package/polyglot/__tests__/helpers.test.js +0 -176
- package/polyglot/__tests__/parser.test.d.ts +0 -1
- package/polyglot/__tests__/parser.test.js +0 -108
- package/polyglot/__tests__/render.test.d.ts +0 -1
- package/polyglot/__tests__/render.test.js +0 -285
- package/shared/dropdownField/__tests__/useDropdownPosition.test.d.ts +0 -1
- package/shared/dropdownField/__tests__/useDropdownPosition.test.js +0 -60
- package/shared/dynamicContent/__tests__/token.test.d.ts +0 -1
- package/shared/dynamicContent/__tests__/token.test.js +0 -32
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { filters } from '../liquid/filters';
|
|
2
|
-
const createContext = (language = 'en', timezone = 'UTC') => ({
|
|
3
|
-
values: {},
|
|
4
|
-
language,
|
|
5
|
-
timezone
|
|
6
|
-
});
|
|
7
|
-
const scalar = value => ({
|
|
8
|
-
type: 'Scalar',
|
|
9
|
-
value
|
|
10
|
-
});
|
|
11
|
-
describe('filters', () => {
|
|
12
|
-
describe('capitalize', () => {
|
|
13
|
-
test('capitalizes first letter', () => {
|
|
14
|
-
expect(filters.capitalize('hello', [], createContext())).toBe('Hello');
|
|
15
|
-
});
|
|
16
|
-
test('handles empty string', () => {
|
|
17
|
-
expect(filters.capitalize('', [], createContext())).toBe('');
|
|
18
|
-
});
|
|
19
|
-
test('returns non-string as is', () => {
|
|
20
|
-
expect(filters.capitalize(42, [], createContext())).toBe(42);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
describe('upperCase', () => {
|
|
24
|
-
test('converts to uppercase', () => {
|
|
25
|
-
expect(filters.upperCase('hello', [], createContext())).toBe('HELLO');
|
|
26
|
-
});
|
|
27
|
-
test('returns non-string as is', () => {
|
|
28
|
-
expect(filters.upperCase(42, [], createContext())).toBe(42);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
describe('lowerCase', () => {
|
|
32
|
-
test('converts to lowercase', () => {
|
|
33
|
-
expect(filters.lowerCase('HELLO', [], createContext())).toBe('hello');
|
|
34
|
-
});
|
|
35
|
-
test('returns non-string as is', () => {
|
|
36
|
-
expect(filters.lowerCase(42, [], createContext())).toBe(42);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
describe('pluralize', () => {
|
|
40
|
-
describe('English', () => {
|
|
41
|
-
const ctx = createContext('en');
|
|
42
|
-
test('returns singular for 1', () => {
|
|
43
|
-
expect(filters.pluralize(1, [scalar('item'), scalar('items')], ctx)).toBe('item');
|
|
44
|
-
});
|
|
45
|
-
test('returns plural for 0', () => {
|
|
46
|
-
expect(filters.pluralize(0, [scalar('item'), scalar('items')], ctx)).toBe('items');
|
|
47
|
-
});
|
|
48
|
-
test('returns plural for 2+', () => {
|
|
49
|
-
expect(filters.pluralize(5, [scalar('item'), scalar('items')], ctx)).toBe('items');
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
describe('Russian', () => {
|
|
53
|
-
const ctx = createContext('ru');
|
|
54
|
-
test('returns first form for 1', () => {
|
|
55
|
-
expect(filters.pluralize(1, [scalar('яблоко'), scalar('яблока'), scalar('яблок')], ctx)).toBe('яблоко');
|
|
56
|
-
});
|
|
57
|
-
test('returns second form for 2-4', () => {
|
|
58
|
-
expect(filters.pluralize(2, [scalar('яблоко'), scalar('яблока'), scalar('яблок')], ctx)).toBe('яблока');
|
|
59
|
-
expect(filters.pluralize(3, [scalar('яблоко'), scalar('яблока'), scalar('яблок')], ctx)).toBe('яблока');
|
|
60
|
-
expect(filters.pluralize(4, [scalar('яблоко'), scalar('яблока'), scalar('яблок')], ctx)).toBe('яблока');
|
|
61
|
-
});
|
|
62
|
-
test('returns third form for 5-20', () => {
|
|
63
|
-
expect(filters.pluralize(5, [scalar('яблоко'), scalar('яблока'), scalar('яблок')], ctx)).toBe('яблок');
|
|
64
|
-
expect(filters.pluralize(11, [scalar('яблоко'), scalar('яблока'), scalar('яблок')], ctx)).toBe('яблок');
|
|
65
|
-
expect(filters.pluralize(20, [scalar('яблоко'), scalar('яблока'), scalar('яблок')], ctx)).toBe('яблок');
|
|
66
|
-
});
|
|
67
|
-
test('returns first form for 21', () => {
|
|
68
|
-
expect(filters.pluralize(21, [scalar('яблоко'), scalar('яблока'), scalar('яблок')], ctx)).toBe('яблоко');
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
test('returns value as is for non-number', () => {
|
|
72
|
-
expect(filters.pluralize('not a number', [scalar('a'), scalar('b')], createContext())).toBe('not a number');
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
describe('pluralize with CLDR forms', () => {
|
|
76
|
-
const arabic = ['صفر', 'صف', 'صفان', 'صفوف', 'صفًا', 'صف*'].map(scalar);
|
|
77
|
-
test('picks each of the six Arabic forms', () => {
|
|
78
|
-
const ctx = createContext('ar');
|
|
79
|
-
expect(filters.pluralize(0, arabic, ctx)).toBe('صفر');
|
|
80
|
-
expect(filters.pluralize(1, arabic, ctx)).toBe('صف');
|
|
81
|
-
expect(filters.pluralize(2, arabic, ctx)).toBe('صفان');
|
|
82
|
-
expect(filters.pluralize(3, arabic, ctx)).toBe('صفوف');
|
|
83
|
-
expect(filters.pluralize(10, arabic, ctx)).toBe('صفوف');
|
|
84
|
-
expect(filters.pluralize(11, arabic, ctx)).toBe('صفًا');
|
|
85
|
-
expect(filters.pluralize(99, arabic, ctx)).toBe('صفًا');
|
|
86
|
-
expect(filters.pluralize(100, arabic, ctx)).toBe('صف*');
|
|
87
|
-
expect(filters.pluralize(103, arabic, ctx)).toBe('صفوف');
|
|
88
|
-
});
|
|
89
|
-
test('keeps the legacy one/other split when fewer forms are given', () => {
|
|
90
|
-
const ctx = createContext('ar');
|
|
91
|
-
expect(filters.pluralize(1, [scalar('صف'), scalar('صفوف')], ctx)).toBe('صف');
|
|
92
|
-
expect(filters.pluralize(0, [scalar('صف'), scalar('صفوف')], ctx)).toBe('صفوف');
|
|
93
|
-
expect(filters.pluralize(2, [scalar('صف'), scalar('صفوف')], ctx)).toBe('صفوف');
|
|
94
|
-
});
|
|
95
|
-
test('Russian three-form rule matches CLDR one/few/many for integers', () => {
|
|
96
|
-
const ctx = createContext('ru');
|
|
97
|
-
const forms = [scalar('one'), scalar('few'), scalar('many')];
|
|
98
|
-
const rules = new Intl.PluralRules('ru');
|
|
99
|
-
for (let n = 0; n <= 1000; n += 1) {
|
|
100
|
-
expect(filters.pluralize(n, forms, ctx)).toBe(rules.select(n));
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
describe('formatNumber', () => {
|
|
105
|
-
test('formats integer with spaces', () => {
|
|
106
|
-
expect(filters.formatNumber('1000000', [], createContext())).toBe('1 000 000');
|
|
107
|
-
});
|
|
108
|
-
test('formats with decimal places', () => {
|
|
109
|
-
expect(filters.formatNumber('1234.5', [scalar(2)], createContext())).toBe('1 234,50');
|
|
110
|
-
});
|
|
111
|
-
test('truncates excess decimal places', () => {
|
|
112
|
-
expect(filters.formatNumber('1234.5678', [scalar(2)], createContext())).toBe('1 234,56');
|
|
113
|
-
});
|
|
114
|
-
test('handles integer without decimal', () => {
|
|
115
|
-
expect(filters.formatNumber('1234', [], createContext())).toBe('1 234');
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
describe('formatDate', () => {
|
|
119
|
-
const testDate = '2024-06-15T12:30:00Z';
|
|
120
|
-
test('formats date with context timezone', () => {
|
|
121
|
-
const result = filters.formatDate(testDate, [], createContext('en', 'UTC'));
|
|
122
|
-
expect(result).toBe('Jun 15, 2024');
|
|
123
|
-
});
|
|
124
|
-
test('formats date with short format', () => {
|
|
125
|
-
const result = filters.formatDate(testDate, [scalar('short')], createContext('en', 'UTC'));
|
|
126
|
-
expect(result).toMatch(/\d{1,2}\/\d{1,2}\/\d{2,4}/);
|
|
127
|
-
});
|
|
128
|
-
test('formats date with long format', () => {
|
|
129
|
-
const result = filters.formatDate(testDate, [scalar('long')], createContext('en', 'UTC'));
|
|
130
|
-
expect(result).toContain('June');
|
|
131
|
-
expect(result).toContain('2024');
|
|
132
|
-
});
|
|
133
|
-
test('formats date with different locale', () => {
|
|
134
|
-
const result = filters.formatDate(testDate, [], createContext('ru', 'UTC'));
|
|
135
|
-
expect(result).toContain('2024');
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
describe('formatDateTime', () => {
|
|
139
|
-
const testDate = '2024-06-15T12:30:00Z';
|
|
140
|
-
test('formats date and time with context timezone', () => {
|
|
141
|
-
const result = filters.formatDateTime(testDate, [], createContext('en', 'UTC'));
|
|
142
|
-
expect(result).toContain('Jun');
|
|
143
|
-
expect(result).toContain('2024');
|
|
144
|
-
expect(result).toContain('12:30');
|
|
145
|
-
});
|
|
146
|
-
test('formats date and time with short format', () => {
|
|
147
|
-
const result = filters.formatDateTime(testDate, [scalar('short')], createContext('en', 'UTC'));
|
|
148
|
-
expect(result).toMatch(/\d{1,2}\/\d{1,2}\/\d{2,4}/);
|
|
149
|
-
expect(result).toContain(':');
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import { smartSplit, smartSplitAtFirstDelimiter, ensureNumber, ensureString, parseScalarOrVariable, addSpaceAroundOperators, unpackScalarOrValue, decodeHtmlEntities } from '../liquid/helpers';
|
|
2
|
-
describe('smartSplit', () => {
|
|
3
|
-
test('splits simple string by delimiter', () => {
|
|
4
|
-
expect(smartSplit('a,b,c', ',')).toEqual(['a', 'b', 'c']);
|
|
5
|
-
});
|
|
6
|
-
test('preserves quoted strings', () => {
|
|
7
|
-
expect(smartSplit('"a,b",c', ',')).toEqual(['"a,b"', 'c']);
|
|
8
|
-
});
|
|
9
|
-
test('handles escaped quotes in strings', () => {
|
|
10
|
-
expect(smartSplit('"a\\"b",c', ',')).toEqual(['"a\\"b"', 'c']);
|
|
11
|
-
});
|
|
12
|
-
test('handles empty string', () => {
|
|
13
|
-
expect(smartSplit('', ',')).toEqual([]);
|
|
14
|
-
});
|
|
15
|
-
test('handles single element', () => {
|
|
16
|
-
expect(smartSplit('abc', ',')).toEqual(['abc']);
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
describe('smartSplitAtFirstDelimiter', () => {
|
|
20
|
-
test('splits at first delimiter', () => {
|
|
21
|
-
expect(smartSplitAtFirstDelimiter('a:b:c', ':')).toEqual(['a', 'b:c']);
|
|
22
|
-
});
|
|
23
|
-
test('returns original string when no delimiter', () => {
|
|
24
|
-
expect(smartSplitAtFirstDelimiter('abc', ':')).toEqual(['abc']);
|
|
25
|
-
});
|
|
26
|
-
test('preserves quoted strings before delimiter', () => {
|
|
27
|
-
expect(smartSplitAtFirstDelimiter('"a:b":c', ':')).toEqual(['"a:b"', 'c']);
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
describe('ensureNumber', () => {
|
|
31
|
-
test('returns number as is', () => {
|
|
32
|
-
expect(ensureNumber(42)).toBe(42);
|
|
33
|
-
});
|
|
34
|
-
test('parses string number', () => {
|
|
35
|
-
expect(ensureNumber('42')).toBe(42);
|
|
36
|
-
});
|
|
37
|
-
test('parses float', () => {
|
|
38
|
-
expect(ensureNumber('3.14')).toBe(3.14);
|
|
39
|
-
});
|
|
40
|
-
test('returns 0 for NaN', () => {
|
|
41
|
-
expect(ensureNumber('not a number')).toBe(0);
|
|
42
|
-
});
|
|
43
|
-
test('returns 0 for undefined', () => {
|
|
44
|
-
expect(ensureNumber(undefined)).toBe(0);
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
describe('ensureString', () => {
|
|
48
|
-
test('returns string as is', () => {
|
|
49
|
-
expect(ensureString('hello')).toBe('hello');
|
|
50
|
-
});
|
|
51
|
-
test('converts number to string', () => {
|
|
52
|
-
expect(ensureString(42)).toBe('42');
|
|
53
|
-
});
|
|
54
|
-
test('returns empty string for null', () => {
|
|
55
|
-
expect(ensureString(null)).toBe('');
|
|
56
|
-
});
|
|
57
|
-
test('returns empty string for undefined', () => {
|
|
58
|
-
expect(ensureString(undefined)).toBe('');
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
describe('parseScalarOrVariable', () => {
|
|
62
|
-
test('parses quoted string as scalar', () => {
|
|
63
|
-
expect(parseScalarOrVariable('"hello"')).toEqual({
|
|
64
|
-
type: 'Scalar',
|
|
65
|
-
value: 'hello'
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
test('parses boolean true', () => {
|
|
69
|
-
expect(parseScalarOrVariable('true')).toEqual({
|
|
70
|
-
type: 'Scalar',
|
|
71
|
-
value: true
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
test('parses boolean false', () => {
|
|
75
|
-
expect(parseScalarOrVariable('false')).toEqual({
|
|
76
|
-
type: 'Scalar',
|
|
77
|
-
value: false
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
test('parses integer as scalar', () => {
|
|
81
|
-
expect(parseScalarOrVariable('42')).toEqual({
|
|
82
|
-
type: 'Scalar',
|
|
83
|
-
value: 42
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
test('parses float as scalar', () => {
|
|
87
|
-
expect(parseScalarOrVariable('3.14')).toEqual({
|
|
88
|
-
type: 'Scalar',
|
|
89
|
-
value: 3.14
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
test('parses identifier as variable', () => {
|
|
93
|
-
expect(parseScalarOrVariable('name')).toEqual({
|
|
94
|
-
type: 'Variable',
|
|
95
|
-
name: 'name'
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
describe('addSpaceAroundOperators', () => {
|
|
100
|
-
test('adds spaces around ==', () => {
|
|
101
|
-
expect(addSpaceAroundOperators('a==b')).toBe('a == b');
|
|
102
|
-
});
|
|
103
|
-
test('adds spaces around !=', () => {
|
|
104
|
-
expect(addSpaceAroundOperators('a!=b')).toBe('a != b');
|
|
105
|
-
});
|
|
106
|
-
test('adds spaces around >=', () => {
|
|
107
|
-
expect(addSpaceAroundOperators('a>=b')).toBe('a >= b');
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
describe('unpackScalarOrValue', () => {
|
|
111
|
-
const context = {
|
|
112
|
-
values: {
|
|
113
|
-
name: 'John'
|
|
114
|
-
},
|
|
115
|
-
language: 'en',
|
|
116
|
-
timezone: 'UTC'
|
|
117
|
-
};
|
|
118
|
-
test('returns scalar value directly', () => {
|
|
119
|
-
expect(unpackScalarOrValue({
|
|
120
|
-
type: 'Scalar',
|
|
121
|
-
value: 'hello'
|
|
122
|
-
}, context)).toBe('hello');
|
|
123
|
-
});
|
|
124
|
-
test('returns variable value from context', () => {
|
|
125
|
-
expect(unpackScalarOrValue({
|
|
126
|
-
type: 'Variable',
|
|
127
|
-
name: 'name'
|
|
128
|
-
}, context)).toBe('John');
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
describe('decodeHtmlEntities', () => {
|
|
132
|
-
describe('named entities', () => {
|
|
133
|
-
test('decodes to non-breaking space', () => {
|
|
134
|
-
expect(decodeHtmlEntities('Hello World')).toBe('Hello\u00A0World');
|
|
135
|
-
});
|
|
136
|
-
test('decodes & to ampersand', () => {
|
|
137
|
-
expect(decodeHtmlEntities('A&B')).toBe('A&B');
|
|
138
|
-
});
|
|
139
|
-
test('decodes < and >', () => {
|
|
140
|
-
expect(decodeHtmlEntities('<div>')).toBe('<div>');
|
|
141
|
-
});
|
|
142
|
-
test('decodes " and '', () => {
|
|
143
|
-
expect(decodeHtmlEntities('"hello'')).toBe('"hello\'');
|
|
144
|
-
});
|
|
145
|
-
test('leaves unknown named entities as is', () => {
|
|
146
|
-
expect(decodeHtmlEntities('&unknown;')).toBe('&unknown;');
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
describe('decimal numeric entities', () => {
|
|
150
|
-
test('decodes   to non-breaking space', () => {
|
|
151
|
-
expect(decodeHtmlEntities('Hello World')).toBe('Hello\u00A0World');
|
|
152
|
-
});
|
|
153
|
-
test('decodes < and >', () => {
|
|
154
|
-
expect(decodeHtmlEntities('<div>')).toBe('<div>');
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
describe('hex numeric entities', () => {
|
|
158
|
-
test('decodes   to non-breaking space', () => {
|
|
159
|
-
expect(decodeHtmlEntities('Hello World')).toBe('Hello\u00A0World');
|
|
160
|
-
});
|
|
161
|
-
test('decodes   (short form)', () => {
|
|
162
|
-
expect(decodeHtmlEntities('Hello World')).toBe('Hello\u00A0World');
|
|
163
|
-
});
|
|
164
|
-
test('decodes < and >', () => {
|
|
165
|
-
expect(decodeHtmlEntities('<div>')).toBe('<div>');
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
describe('mixed entities', () => {
|
|
169
|
-
test('decodes multiple different entity types', () => {
|
|
170
|
-
expect(decodeHtmlEntities('<div> <span> ')).toBe('<div>\u00A0<span>\u00A0');
|
|
171
|
-
});
|
|
172
|
-
test('returns text without entities unchanged', () => {
|
|
173
|
-
expect(decodeHtmlEntities('Hello World')).toBe('Hello World');
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { stringToAst } from '../liquid/parser';
|
|
2
|
-
describe('stringToAst', () => {
|
|
3
|
-
describe('text parsing', () => {
|
|
4
|
-
test('parses plain text', () => {
|
|
5
|
-
const ast = stringToAst('Hello World');
|
|
6
|
-
expect(ast).toHaveLength(1);
|
|
7
|
-
expect(ast[0].type).toBe('Text');
|
|
8
|
-
expect(ast[0].content).toBe('Hello World');
|
|
9
|
-
});
|
|
10
|
-
test('parses empty string', () => {
|
|
11
|
-
const ast = stringToAst('');
|
|
12
|
-
expect(ast).toHaveLength(0);
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
describe('variable parsing', () => {
|
|
16
|
-
test('parses simple variable', () => {
|
|
17
|
-
const ast = stringToAst('{{ name }}');
|
|
18
|
-
expect(ast).toHaveLength(1);
|
|
19
|
-
const node = ast[0];
|
|
20
|
-
expect(node.type).toBe('Variable');
|
|
21
|
-
expect(node.value).toEqual({
|
|
22
|
-
type: 'Variable',
|
|
23
|
-
name: 'name'
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
test('parses variable with filter', () => {
|
|
27
|
-
const ast = stringToAst('{{ name | capitalize }}');
|
|
28
|
-
expect(ast).toHaveLength(1);
|
|
29
|
-
const node = ast[0];
|
|
30
|
-
expect(node.type).toBe('Variable');
|
|
31
|
-
expect(node.filters).toHaveLength(1);
|
|
32
|
-
expect(node.filters[0].name).toBe('capitalize');
|
|
33
|
-
});
|
|
34
|
-
test('parses variable with multiple filters', () => {
|
|
35
|
-
const ast = stringToAst('{{ name | capitalize | upperCase }}');
|
|
36
|
-
expect(ast).toHaveLength(1);
|
|
37
|
-
const node = ast[0];
|
|
38
|
-
expect(node.filters).toHaveLength(2);
|
|
39
|
-
expect(node.filters[0].name).toBe('capitalize');
|
|
40
|
-
expect(node.filters[1].name).toBe('upperCase');
|
|
41
|
-
});
|
|
42
|
-
test('parses variable mixed with text', () => {
|
|
43
|
-
const ast = stringToAst('Hello {{ name }}!');
|
|
44
|
-
expect(ast).toHaveLength(3);
|
|
45
|
-
expect(ast[0].content).toBe('Hello ');
|
|
46
|
-
expect(ast[1].type).toBe('Variable');
|
|
47
|
-
expect(ast[2].content).toBe('!');
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
describe('if control parsing', () => {
|
|
51
|
-
test('parses simple if block', () => {
|
|
52
|
-
const ast = stringToAst('{% if count == 1 %}one{% endif %}');
|
|
53
|
-
expect(ast).toHaveLength(1);
|
|
54
|
-
const node = ast[0];
|
|
55
|
-
expect(node.type).toBe('Control');
|
|
56
|
-
expect(node.name).toBe('if');
|
|
57
|
-
expect(node.condition[1]).toBe('==');
|
|
58
|
-
});
|
|
59
|
-
test('parses if-else block', () => {
|
|
60
|
-
const ast = stringToAst('{% if active == true %}yes{% else %}no{% endif %}');
|
|
61
|
-
expect(ast).toHaveLength(1);
|
|
62
|
-
const node = ast[0];
|
|
63
|
-
expect(node.children).toHaveLength(1);
|
|
64
|
-
expect(node.elseChildren).toHaveLength(1);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
describe('for control parsing', () => {
|
|
68
|
-
test('parses for loop', () => {
|
|
69
|
-
const ast = stringToAst('{% for item in items %}{{ item }}{% endfor %}');
|
|
70
|
-
expect(ast).toHaveLength(1);
|
|
71
|
-
const node = ast[0];
|
|
72
|
-
expect(node.type).toBe('Control');
|
|
73
|
-
expect(node.name).toBe('for');
|
|
74
|
-
expect(node.varName).toBe('item');
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
describe('HTML tag parsing', () => {
|
|
78
|
-
test('parses self-closing br tag', () => {
|
|
79
|
-
const ast = stringToAst('line1<br/>line2');
|
|
80
|
-
expect(ast).toHaveLength(3);
|
|
81
|
-
expect(ast[0].content).toBe('line1');
|
|
82
|
-
expect(ast[1].type).toBe('Tag');
|
|
83
|
-
expect(ast[1].name).toBe('br');
|
|
84
|
-
expect(ast[2].content).toBe('line2');
|
|
85
|
-
});
|
|
86
|
-
test('parses void hr tag', () => {
|
|
87
|
-
const ast = stringToAst('before<hr>after');
|
|
88
|
-
expect(ast).toHaveLength(3);
|
|
89
|
-
expect(ast[1].name).toBe('hr');
|
|
90
|
-
});
|
|
91
|
-
test('parses img tag with attributes', () => {
|
|
92
|
-
const ast = stringToAst('<img src="test.png" alt="test">');
|
|
93
|
-
expect(ast).toHaveLength(1);
|
|
94
|
-
const node = ast[0];
|
|
95
|
-
expect(node.name).toBe('img');
|
|
96
|
-
expect(node.params).toHaveProperty('src');
|
|
97
|
-
expect(node.params).toHaveProperty('alt');
|
|
98
|
-
});
|
|
99
|
-
test('parses nested tags', () => {
|
|
100
|
-
const ast = stringToAst('<strong>bold text</strong>');
|
|
101
|
-
expect(ast).toHaveLength(1);
|
|
102
|
-
const node = ast[0];
|
|
103
|
-
expect(node.name).toBe('strong');
|
|
104
|
-
expect(node.children).toHaveLength(1);
|
|
105
|
-
expect(node.children[0].content).toBe('bold text');
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import '@testing-library/jest-dom';
|