@ditojs/utils 2.100.0 → 3.1.0
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/package.json +5 -9
- package/src/array/shuffle.js +1 -1
- package/src/string/formatPlainDate.js +14 -0
- package/src/string/index.js +2 -0
- package/src/string/isDomain.js +10 -3
- package/src/string/parsePlainDate.js +18 -0
- package/types/index.d.ts +13 -0
- package/src/__snapshots__/index.test.js.snap +0 -88
- package/src/array/flattten.test.js +0 -29
- package/src/array/shuffle.test.js +0 -25
- package/src/base/base.test.js +0 -590
- package/src/class/mixin.test.js +0 -70
- package/src/dataPath/getEntriesAtDataPath.test.js +0 -204
- package/src/dataPath/getValueAtDataPath.test.js +0 -140
- package/src/dataPath/normalizeDataPath.test.js +0 -36
- package/src/dataPath/parseDataPath.test.js +0 -67
- package/src/dataPath/setDataPathEntries.test.js +0 -36
- package/src/dataPath/setValueAtDataPath.test.js +0 -34
- package/src/function/toAsync.test.js +0 -31
- package/src/function/toCallback.test.js +0 -29
- package/src/function/toPromiseCallback.test.js +0 -24
- package/src/html/escapeHtml.test.js +0 -19
- package/src/html/stripHtml.test.js +0 -37
- package/src/index.test.js +0 -7
- package/src/object/clone.test.js +0 -131
- package/src/object/equals.test.js +0 -278
- package/src/object/groupBy.test.js +0 -70
- package/src/object/mapKeys.test.js +0 -16
- package/src/object/mapValues.test.js +0 -38
- package/src/object/mergeDeeply.test.js +0 -152
- package/src/object/pick.test.js +0 -23
- package/src/object/pickBy.test.js +0 -48
- package/src/string/camelize.test.js +0 -37
- package/src/string/capitalize.test.js +0 -33
- package/src/string/decamelize.test.js +0 -83
- package/src/string/deindent.test.js +0 -181
- package/src/string/format.test.js +0 -196
- package/src/string/formatDate.test.js +0 -28
- package/src/string/getCommonPrefix.test.js +0 -23
- package/src/string/isAbsoluteUrl.test.js +0 -15
- package/src/string/isCreditCard.test.js +0 -50
- package/src/string/isDomain.test.js +0 -15
- package/src/string/isEmail.test.js +0 -37
- package/src/string/isHostname.test.js +0 -12
- package/src/string/isUrl.test.js +0 -1595
- package/src/string/labelize.test.js +0 -39
- package/src/timer/debounce.test.js +0 -101
- package/src/timer/debounceAsync.test.js +0 -143
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import { getEntriesAtDataPath } from './getEntriesAtDataPath.js'
|
|
2
|
-
|
|
3
|
-
describe('getEntriesAtDataPath()', () => {
|
|
4
|
-
const data = {
|
|
5
|
-
object: {
|
|
6
|
-
array: [
|
|
7
|
-
null,
|
|
8
|
-
{
|
|
9
|
-
prop: 'expected'
|
|
10
|
-
}
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
it('should return data at a given path in property access notation', () => {
|
|
16
|
-
expect(getEntriesAtDataPath(data, 'object.array[1].prop')).toStrictEqual({
|
|
17
|
-
'object/array/1/prop': 'expected'
|
|
18
|
-
})
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('should return data at a given JSON pointer path', () => {
|
|
22
|
-
expect(getEntriesAtDataPath(data, '/object/array/1/prop')).toStrictEqual({
|
|
23
|
-
'object/array/1/prop': 'expected'
|
|
24
|
-
})
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it(`should return data at a given 'relative' JSON pointer path`, () => {
|
|
28
|
-
expect(getEntriesAtDataPath(data, 'object/array/1/prop')).toStrictEqual({
|
|
29
|
-
'object/array/1/prop': 'expected'
|
|
30
|
-
})
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('should throw an error with faulty paths', () => {
|
|
34
|
-
expect(() => getEntriesAtDataPath(data, 'object/unknown/prop'))
|
|
35
|
-
.toThrow('Invalid path: object/unknown/prop')
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('should throw an error with nullish objects', () => {
|
|
39
|
-
expect(() => getEntriesAtDataPath(null, 'object'))
|
|
40
|
-
.toThrow('Invalid path: object')
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('should support custom error handler', () => {
|
|
44
|
-
const handleError = (object, part, index) => `Error: ${part}, ${index}`
|
|
45
|
-
expect(getEntriesAtDataPath(data, 'object/unknown/prop', handleError))
|
|
46
|
-
.toStrictEqual({ 'object/unknown/prop': 'Error: unknown, 1' })
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('should handle non-existing paths with custom `handleError()`', () => {
|
|
50
|
-
const handleError = () => undefined
|
|
51
|
-
expect(getEntriesAtDataPath(data, 'object/unknown/prop', handleError))
|
|
52
|
-
.toStrictEqual({})
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should return shallow wildcard matches', () => {
|
|
56
|
-
const data = {
|
|
57
|
-
object1: {
|
|
58
|
-
array: [
|
|
59
|
-
{
|
|
60
|
-
name: 'one',
|
|
61
|
-
array: [
|
|
62
|
-
{ name: 'one.one' },
|
|
63
|
-
{ name: 'one.two' }
|
|
64
|
-
]
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
name: 'two',
|
|
68
|
-
array: [
|
|
69
|
-
{ name: 'two.one' },
|
|
70
|
-
{ name: 'two.two' }
|
|
71
|
-
]
|
|
72
|
-
}
|
|
73
|
-
]
|
|
74
|
-
},
|
|
75
|
-
object2: {
|
|
76
|
-
object: {
|
|
77
|
-
one: {
|
|
78
|
-
name: 'one',
|
|
79
|
-
object: {
|
|
80
|
-
one: { name: 'one.one' },
|
|
81
|
-
two: { name: 'one.two' }
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
two: {
|
|
85
|
-
name: 'two',
|
|
86
|
-
object: {
|
|
87
|
-
one: { name: 'two.one' },
|
|
88
|
-
two: { name: 'two.two' }
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
object3: {
|
|
94
|
-
array: [
|
|
95
|
-
{
|
|
96
|
-
one: { name: 'one.one' },
|
|
97
|
-
two: { name: 'one.two' }
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
one: { name: 'two.one' },
|
|
101
|
-
two: { name: 'two.two' }
|
|
102
|
-
}
|
|
103
|
-
]
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
expect(getEntriesAtDataPath(data, 'object1/array/*/name'))
|
|
108
|
-
.toStrictEqual({
|
|
109
|
-
'object1/array/0/name': 'one',
|
|
110
|
-
'object1/array/1/name': 'two'
|
|
111
|
-
})
|
|
112
|
-
expect(getEntriesAtDataPath(data, 'object1.array[*].name'))
|
|
113
|
-
.toStrictEqual({
|
|
114
|
-
'object1/array/0/name': 'one',
|
|
115
|
-
'object1/array/1/name': 'two'
|
|
116
|
-
})
|
|
117
|
-
expect(getEntriesAtDataPath(data, 'object1/array/*/array/*/name'))
|
|
118
|
-
.toStrictEqual({
|
|
119
|
-
'object1/array/0/array/0/name': 'one.one',
|
|
120
|
-
'object1/array/0/array/1/name': 'one.two',
|
|
121
|
-
'object1/array/1/array/0/name': 'two.one',
|
|
122
|
-
'object1/array/1/array/1/name': 'two.two'
|
|
123
|
-
})
|
|
124
|
-
expect(getEntriesAtDataPath(data, 'object2/object/*/name'))
|
|
125
|
-
.toStrictEqual({
|
|
126
|
-
'object2/object/one/name': 'one',
|
|
127
|
-
'object2/object/two/name': 'two'
|
|
128
|
-
})
|
|
129
|
-
expect(getEntriesAtDataPath(data, 'object2/object/*/object/*/name'))
|
|
130
|
-
.toStrictEqual({
|
|
131
|
-
'object2/object/one/object/one/name': 'one.one',
|
|
132
|
-
'object2/object/one/object/two/name': 'one.two',
|
|
133
|
-
'object2/object/two/object/one/name': 'two.one',
|
|
134
|
-
'object2/object/two/object/two/name': 'two.two'
|
|
135
|
-
})
|
|
136
|
-
expect(getEntriesAtDataPath(data, 'object3/array/*/*/name'))
|
|
137
|
-
.toStrictEqual({
|
|
138
|
-
'object3/array/0/one/name': 'one.one',
|
|
139
|
-
'object3/array/0/two/name': 'one.two',
|
|
140
|
-
'object3/array/1/one/name': 'two.one',
|
|
141
|
-
'object3/array/1/two/name': 'two.two'
|
|
142
|
-
})
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
it('should return deep wildcard matches', () => {
|
|
146
|
-
const data = {
|
|
147
|
-
object: {
|
|
148
|
-
array: [
|
|
149
|
-
{ name: 'one' },
|
|
150
|
-
{ name: 'two' },
|
|
151
|
-
{
|
|
152
|
-
object: {
|
|
153
|
-
one: { name: 'three' },
|
|
154
|
-
two: { name: 'four' }
|
|
155
|
-
},
|
|
156
|
-
array: [
|
|
157
|
-
{ name: 'five' },
|
|
158
|
-
{ name: 'six' },
|
|
159
|
-
{
|
|
160
|
-
object: {
|
|
161
|
-
one: { name: 'seven' },
|
|
162
|
-
two: { name: 'eight' }
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
]
|
|
166
|
-
}
|
|
167
|
-
]
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const expected = {
|
|
172
|
-
'object/array/0/name': 'one',
|
|
173
|
-
'object/array/1/name': 'two',
|
|
174
|
-
'object/array/2/object/one/name': 'three',
|
|
175
|
-
'object/array/2/object/two/name': 'four',
|
|
176
|
-
'object/array/2/array/0/name': 'five',
|
|
177
|
-
'object/array/2/array/1/name': 'six',
|
|
178
|
-
'object/array/2/array/2/object/one/name': 'seven',
|
|
179
|
-
'object/array/2/array/2/object/two/name': 'eight'
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
let result = getEntriesAtDataPath(data, '**/name')
|
|
183
|
-
expect(result).toEqual(expected)
|
|
184
|
-
expect(Object.values(result)).toEqual(Object.values(expected))
|
|
185
|
-
|
|
186
|
-
result = getEntriesAtDataPath(data, 'object/**/name')
|
|
187
|
-
expect(result).toEqual(expected)
|
|
188
|
-
expect(Object.values(result)).toEqual(Object.values(expected))
|
|
189
|
-
|
|
190
|
-
expect(getEntriesAtDataPath(data, 'object/**/array/**/name')).toEqual({
|
|
191
|
-
'object/array/2/array/0/name': 'five',
|
|
192
|
-
'object/array/2/array/1/name': 'six',
|
|
193
|
-
'object/array/2/array/2/object/one/name': 'seven',
|
|
194
|
-
'object/array/2/array/2/object/two/name': 'eight'
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
expect(getEntriesAtDataPath(data, 'object/**/object/**/name')).toEqual({
|
|
198
|
-
'object/array/2/object/one/name': 'three',
|
|
199
|
-
'object/array/2/object/two/name': 'four',
|
|
200
|
-
'object/array/2/array/2/object/one/name': 'seven',
|
|
201
|
-
'object/array/2/array/2/object/two/name': 'eight'
|
|
202
|
-
})
|
|
203
|
-
})
|
|
204
|
-
})
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { getValueAtDataPath } from './getValueAtDataPath.js'
|
|
2
|
-
|
|
3
|
-
describe('getValueAtDataPath()', () => {
|
|
4
|
-
const data = {
|
|
5
|
-
object: {
|
|
6
|
-
array: [
|
|
7
|
-
null,
|
|
8
|
-
{
|
|
9
|
-
prop: 'expected'
|
|
10
|
-
}
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
it('should return the root data for empty paths', () => {
|
|
16
|
-
expect(getValueAtDataPath(data, '')).toBe(data)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
it('should return data at a given path in property access notation', () => {
|
|
20
|
-
expect(getValueAtDataPath(data, 'object.array[1].prop')).toBe('expected')
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('should return data at a given JSON pointer path', () => {
|
|
24
|
-
expect(getValueAtDataPath(data, '/object/array/1/prop')).toBe('expected')
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it(`should return data at a given 'relative' JSON pointer path`, () => {
|
|
28
|
-
expect(getValueAtDataPath(data, 'object/array/1/prop')).toBe('expected')
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('should throw an error with faulty paths', () => {
|
|
32
|
-
expect(() => getValueAtDataPath(data, 'object/unknown/prop'))
|
|
33
|
-
.toThrow('Invalid path: object/unknown/prop')
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it('should throw an error with nullish objects', () => {
|
|
37
|
-
expect(() => getValueAtDataPath(null, 'object'))
|
|
38
|
-
.toThrow('Invalid path: object')
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('should support custom error handler', () => {
|
|
42
|
-
const handleError = (object, part, index) => `Error: ${part}, ${index}`
|
|
43
|
-
expect(getValueAtDataPath(data, 'object/unknown/prop', handleError))
|
|
44
|
-
.toBe('Error: unknown, 1')
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('should return shallow wildcard matches', () => {
|
|
48
|
-
const data = {
|
|
49
|
-
object1: {
|
|
50
|
-
array: [
|
|
51
|
-
{ name: 'one' },
|
|
52
|
-
{ name: 'two' }
|
|
53
|
-
]
|
|
54
|
-
},
|
|
55
|
-
object2: {
|
|
56
|
-
object: {
|
|
57
|
-
one: { name: 'one' },
|
|
58
|
-
two: { name: 'two' }
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
expect(getValueAtDataPath(data, 'object1/array/*/name'))
|
|
64
|
-
.toEqual(['one', 'two'])
|
|
65
|
-
expect(getValueAtDataPath(data, 'object1.array[*].name'))
|
|
66
|
-
.toEqual(['one', 'two'])
|
|
67
|
-
expect(getValueAtDataPath(data, 'object2/object/*/name'))
|
|
68
|
-
.toEqual(['one', 'two'])
|
|
69
|
-
expect(getValueAtDataPath(data, 'object2.object[*].name'))
|
|
70
|
-
.toEqual(['one', 'two'])
|
|
71
|
-
expect(getValueAtDataPath(data, '*/*/*'))
|
|
72
|
-
.toEqual([
|
|
73
|
-
{ name: 'one' },
|
|
74
|
-
{ name: 'two' },
|
|
75
|
-
{ name: 'one' },
|
|
76
|
-
{ name: 'two' }
|
|
77
|
-
])
|
|
78
|
-
expect(getValueAtDataPath(data, '*/*/*/name'))
|
|
79
|
-
.toEqual(['one', 'two', 'one', 'two'])
|
|
80
|
-
|
|
81
|
-
expect(getValueAtDataPath(data, '**/name'))
|
|
82
|
-
.toEqual(['one', 'two', 'one', 'two'])
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
it('should return deep wildcard matches', () => {
|
|
86
|
-
const data = {
|
|
87
|
-
object: {
|
|
88
|
-
object: {
|
|
89
|
-
array: [
|
|
90
|
-
{ name: 'one' },
|
|
91
|
-
{ name: 'two' },
|
|
92
|
-
{
|
|
93
|
-
object: {
|
|
94
|
-
one: { name: 'three' },
|
|
95
|
-
two: { name: 'four' }
|
|
96
|
-
},
|
|
97
|
-
array: [
|
|
98
|
-
{ name: 'five' },
|
|
99
|
-
{ name: 'six' },
|
|
100
|
-
{
|
|
101
|
-
object: {
|
|
102
|
-
one: { name: 'seven' },
|
|
103
|
-
two: { name: 'eight' }
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
]
|
|
107
|
-
}
|
|
108
|
-
]
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
expect(getValueAtDataPath(data, 'object/**/name'))
|
|
114
|
-
.toEqual(['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'])
|
|
115
|
-
|
|
116
|
-
expect(getValueAtDataPath(data, 'object/**/object/one/name'))
|
|
117
|
-
.toEqual(['three', 'seven'])
|
|
118
|
-
|
|
119
|
-
expect(getValueAtDataPath(data, 'object/**/object/two/name'))
|
|
120
|
-
.toEqual(['four', 'eight'])
|
|
121
|
-
|
|
122
|
-
expect(getValueAtDataPath(data, 'object/**/array/0/name'))
|
|
123
|
-
.toEqual(['one', 'five'])
|
|
124
|
-
|
|
125
|
-
expect(getValueAtDataPath(data, 'object/**/array/1/name'))
|
|
126
|
-
.toEqual(['two', 'six'])
|
|
127
|
-
|
|
128
|
-
expect(getValueAtDataPath(data, 'object/**/object'))
|
|
129
|
-
.toEqual([
|
|
130
|
-
{
|
|
131
|
-
one: { name: 'three' },
|
|
132
|
-
two: { name: 'four' }
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
one: { name: 'seven' },
|
|
136
|
-
two: { name: 'eight' }
|
|
137
|
-
}
|
|
138
|
-
])
|
|
139
|
-
})
|
|
140
|
-
})
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { normalizeDataPath } from './normalizeDataPath.js'
|
|
2
|
-
|
|
3
|
-
describe('normalizeDataPath()', () => {
|
|
4
|
-
it('should normalize JSON pointers', () => {
|
|
5
|
-
expect(normalizeDataPath('/object/array/1/prop'))
|
|
6
|
-
.toStrictEqual('object/array/1/prop')
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
it('should normalize property access notation', () => {
|
|
10
|
-
const expected = 'object/array/1/prop'
|
|
11
|
-
expect(normalizeDataPath('.object.array[1].prop')).toStrictEqual(expected)
|
|
12
|
-
expect(normalizeDataPath('.object["array"][1].prop'))
|
|
13
|
-
.toStrictEqual(expected)
|
|
14
|
-
expect(normalizeDataPath(`['object']['array'][1]['prop']`))
|
|
15
|
-
.toStrictEqual(expected)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('should normalize relative tokens', () => {
|
|
19
|
-
expect(normalizeDataPath('/object/property1/..'))
|
|
20
|
-
.toStrictEqual('object')
|
|
21
|
-
expect(normalizeDataPath('/object/property1/../'))
|
|
22
|
-
.toStrictEqual('object')
|
|
23
|
-
expect(normalizeDataPath('/object/property1/../value'))
|
|
24
|
-
.toStrictEqual('object/value')
|
|
25
|
-
expect(normalizeDataPath('/object/property1/../value/'))
|
|
26
|
-
.toStrictEqual('object/value')
|
|
27
|
-
expect(normalizeDataPath('/object/property1/../property2/../value'))
|
|
28
|
-
.toStrictEqual('object/value')
|
|
29
|
-
expect(normalizeDataPath('/object/property1/property2/../../value'))
|
|
30
|
-
.toStrictEqual('object/value')
|
|
31
|
-
expect(normalizeDataPath('/object/property1//object/value'))
|
|
32
|
-
.toStrictEqual('object/value')
|
|
33
|
-
expect(normalizeDataPath('/object1/object2/./object3/value'))
|
|
34
|
-
.toStrictEqual('object1/object2/object3/value')
|
|
35
|
-
})
|
|
36
|
-
})
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { parseDataPath } from './parseDataPath.js'
|
|
2
|
-
|
|
3
|
-
describe('parseDataPath()', () => {
|
|
4
|
-
it('should parse JSON pointers', () => {
|
|
5
|
-
expect(parseDataPath('/object/array/1/prop'))
|
|
6
|
-
.toStrictEqual(['object', 'array', '1', 'prop'])
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
it('should parse property access notation', () => {
|
|
10
|
-
const expected = ['object', 'array', '1', 'prop']
|
|
11
|
-
expect(parseDataPath('.object.array[1].prop')).toStrictEqual(expected)
|
|
12
|
-
expect(parseDataPath(`.object["array"][1].prop`)).toStrictEqual(expected)
|
|
13
|
-
expect(parseDataPath(`['object']['array'][1]['prop']`))
|
|
14
|
-
.toStrictEqual(expected)
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
it(`should parse 'relative' JSON pointers`, () => {
|
|
18
|
-
expect(parseDataPath('object/array/1/prop'))
|
|
19
|
-
.toStrictEqual(['object', 'array', '1', 'prop'])
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it(`should parse 'relative' property access notation`, () => {
|
|
23
|
-
expect(parseDataPath('object.array[1].prop'))
|
|
24
|
-
.toStrictEqual(['object', 'array', '1', 'prop'])
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should parse relative and absolute tokens', () => {
|
|
28
|
-
expect(parseDataPath('/object/property1/../property2/../value'))
|
|
29
|
-
.toStrictEqual(['object', 'property1', '..', 'property2', '..', 'value'])
|
|
30
|
-
expect(parseDataPath('../object/value'))
|
|
31
|
-
.toStrictEqual(['..', 'object', 'value'])
|
|
32
|
-
expect(parseDataPath('./object/value'))
|
|
33
|
-
.toStrictEqual(['.', 'object', 'value'])
|
|
34
|
-
// This happens when concatenating a data path with another absolute one, an
|
|
35
|
-
// empty space will be interpreted as "start from scratch" when normalizing.
|
|
36
|
-
expect(parseDataPath('//object/value'))
|
|
37
|
-
.toStrictEqual(['', 'object', 'value'])
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('should handle white-space in JSON pointers', () => {
|
|
41
|
-
expect(parseDataPath('/object/property name'))
|
|
42
|
-
.toStrictEqual(['object', 'property name'])
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('should handle white-space in property access notation', () => {
|
|
46
|
-
const expected = ['object', 'property name']
|
|
47
|
-
expect(parseDataPath(`.object["property name"]`)).toStrictEqual(expected)
|
|
48
|
-
expect(parseDataPath(`.object['property name']`)).toStrictEqual(expected)
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
it('should return a clone if argument is already an array', () => {
|
|
52
|
-
const array = ['object', 'array', '1']
|
|
53
|
-
const actual = parseDataPath(array)
|
|
54
|
-
expect(actual).toStrictEqual(array)
|
|
55
|
-
expect(actual).not.toBe(array)
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
it('should return undefined for values other than array / string', () => {
|
|
59
|
-
expect(parseDataPath({})).toBe(undefined)
|
|
60
|
-
expect(parseDataPath(false)).toBe(undefined)
|
|
61
|
-
expect(parseDataPath(10)).toBe(undefined)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('should parse an empty string to an empty array', () => {
|
|
65
|
-
expect(parseDataPath('')).toStrictEqual([])
|
|
66
|
-
})
|
|
67
|
-
})
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { setDataPathEntries } from './setDataPathEntries.js'
|
|
2
|
-
|
|
3
|
-
describe('setDataPathEntries()', () => {
|
|
4
|
-
const data = {
|
|
5
|
-
object: {
|
|
6
|
-
array: [
|
|
7
|
-
{}
|
|
8
|
-
],
|
|
9
|
-
number: 10
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const add = { prop: 'new' }
|
|
14
|
-
|
|
15
|
-
it('should add data at a path to a given object and array', () => {
|
|
16
|
-
expect(() =>
|
|
17
|
-
setDataPathEntries(data, {
|
|
18
|
-
'object.array[0].added': add,
|
|
19
|
-
'object.array[1]': add
|
|
20
|
-
})
|
|
21
|
-
)
|
|
22
|
-
.not.toThrow()
|
|
23
|
-
expect(data.object.array[0].added).toStrictEqual(add)
|
|
24
|
-
expect(data.object.array[1]).toStrictEqual(add)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should throw an error with faulty paths', () => {
|
|
28
|
-
expect(() => setDataPathEntries(data, { 'object/unknown/prop': add }))
|
|
29
|
-
.toThrow()
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('should throw an error with invalid target', () => {
|
|
33
|
-
expect(() => setDataPathEntries(data, { 'object/number/invalid': add }))
|
|
34
|
-
.toThrow('Invalid path: object/number/invalid')
|
|
35
|
-
})
|
|
36
|
-
})
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { setValueAtDataPath } from './setValueAtDataPath.js'
|
|
2
|
-
|
|
3
|
-
describe('setValueAtDataPath()', () => {
|
|
4
|
-
const data = {
|
|
5
|
-
object: {
|
|
6
|
-
array: [
|
|
7
|
-
{}
|
|
8
|
-
],
|
|
9
|
-
number: 10
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const add = { prop: 'new' }
|
|
14
|
-
|
|
15
|
-
it('should add data at a path to a given object', () => {
|
|
16
|
-
expect(() => setValueAtDataPath(data, 'object.array[0].added', add))
|
|
17
|
-
.not.toThrow()
|
|
18
|
-
expect(data.object.array[0].added).toStrictEqual(add)
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('should add data at a path to a given array', () => {
|
|
22
|
-
expect(() => setValueAtDataPath(data, 'object.array[1]', add)).not.toThrow()
|
|
23
|
-
expect(data.object.array[1]).toStrictEqual(add)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('should throw an error with faulty paths', () => {
|
|
27
|
-
expect(() => setValueAtDataPath(data, 'object/unknown/prop', add)).toThrow()
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it('should throw an error with invalid target', () => {
|
|
31
|
-
expect(() => setValueAtDataPath(data, 'object/number/invalid', add))
|
|
32
|
-
.toThrow('Invalid path: object/number/invalid')
|
|
33
|
-
})
|
|
34
|
-
})
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { toAsync } from './toAsync.js'
|
|
2
|
-
|
|
3
|
-
describe('toAsync()', () => {
|
|
4
|
-
it('should convert callback functions to async', async () => {
|
|
5
|
-
expect.assertions(1)
|
|
6
|
-
const asyncFunc = toAsync(function (toResolve, callback) {
|
|
7
|
-
process.nextTick(() => {
|
|
8
|
-
callback(null, toResolve)
|
|
9
|
-
})
|
|
10
|
-
})
|
|
11
|
-
const expected = 10
|
|
12
|
-
const actual = await asyncFunc(expected)
|
|
13
|
-
expect(actual).toBe(expected)
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('should convert callback errors to exceptions', async () => {
|
|
17
|
-
expect.assertions(1)
|
|
18
|
-
const error = new Error('This error is intentional')
|
|
19
|
-
const throwError = toAsync(function (toReject, callback) {
|
|
20
|
-
process.nextTick(() => {
|
|
21
|
-
callback(toReject)
|
|
22
|
-
})
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
await throwError(error)
|
|
27
|
-
} catch (err) {
|
|
28
|
-
expect(err).toBe(error)
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
})
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { toCallback } from './toCallback.js'
|
|
2
|
-
|
|
3
|
-
describe('toCallback()', () => {
|
|
4
|
-
it('should convert async functions to callbacks', async () => {
|
|
5
|
-
expect.assertions(2)
|
|
6
|
-
const callback = toCallback(async result => {
|
|
7
|
-
await Promise.resolve()
|
|
8
|
-
return result
|
|
9
|
-
})
|
|
10
|
-
const expected = 10
|
|
11
|
-
callback(expected, (err, actual) => {
|
|
12
|
-
expect(err).toBeNull()
|
|
13
|
-
expect(actual).toBe(expected)
|
|
14
|
-
})
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
it('should convert async exceptions to callback errors', async () => {
|
|
18
|
-
expect.assertions(2)
|
|
19
|
-
const error = new Error('This error is intentional')
|
|
20
|
-
const callback = toCallback(async error => {
|
|
21
|
-
await Promise.resolve()
|
|
22
|
-
throw error
|
|
23
|
-
})
|
|
24
|
-
callback(error, (err, actual) => {
|
|
25
|
-
expect(err).toBe(error)
|
|
26
|
-
expect(actual).toBe(undefined)
|
|
27
|
-
})
|
|
28
|
-
})
|
|
29
|
-
})
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { toPromiseCallback } from './toPromiseCallback.js'
|
|
2
|
-
import { vi } from 'vitest'
|
|
3
|
-
|
|
4
|
-
describe('toPromiseCallback()', () => {
|
|
5
|
-
it('should call reject() when called with an error', () => {
|
|
6
|
-
const error = new Error('My Error')
|
|
7
|
-
const resolve = vi.fn()
|
|
8
|
-
const reject = vi.fn()
|
|
9
|
-
const callback = toPromiseCallback(resolve, reject)
|
|
10
|
-
callback(error)
|
|
11
|
-
expect(resolve).not.toBeCalled()
|
|
12
|
-
expect(reject).toBeCalledWith(error)
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('should call resolve() when called with a result', () => {
|
|
16
|
-
const result = 42
|
|
17
|
-
const resolve = vi.fn()
|
|
18
|
-
const reject = vi.fn()
|
|
19
|
-
const callback = toPromiseCallback(resolve, reject)
|
|
20
|
-
callback(null, result)
|
|
21
|
-
expect(reject).not.toBeCalled()
|
|
22
|
-
expect(resolve).toBeCalledWith(result)
|
|
23
|
-
})
|
|
24
|
-
})
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { escapeHtml } from './escapeHtml.js'
|
|
2
|
-
|
|
3
|
-
describe('escapeHtml()', () => {
|
|
4
|
-
it('should escape quotes, ampersands, and smaller/greater than signs', () => {
|
|
5
|
-
expect(escapeHtml('<div id="me, myself & i"/>'))
|
|
6
|
-
.toBe('<div id="me, myself & i"/>')
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
it('should return an empty string if nothing can be processed', () => {
|
|
10
|
-
expect(escapeHtml()).toBe('')
|
|
11
|
-
expect(escapeHtml(null)).toBe('')
|
|
12
|
-
expect(escapeHtml('')).toBe('')
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('should handle falsy values correctly', () => {
|
|
16
|
-
expect(escapeHtml(0)).toBe('0')
|
|
17
|
-
expect(escapeHtml(false)).toBe('false')
|
|
18
|
-
})
|
|
19
|
-
})
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { stripHtml } from './stripHtml.js'
|
|
2
|
-
|
|
3
|
-
describe('stripHtml()', () => {
|
|
4
|
-
it('should remove html tags from strings', () => {
|
|
5
|
-
expect(stripHtml('<p><b>this</b> is a marked-up string</p>'))
|
|
6
|
-
.toBe('this is a marked-up string')
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
it('should return an empty string if nothing can be processed', () => {
|
|
10
|
-
expect(stripHtml()).toBe('')
|
|
11
|
-
expect(stripHtml(null)).toBe('')
|
|
12
|
-
expect(stripHtml('')).toBe('')
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('should handle falsy values correctly', () => {
|
|
16
|
-
expect(stripHtml(0)).toBe('0')
|
|
17
|
-
expect(stripHtml(false)).toBe('false')
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('should convert <br> tags to line-breaks', () => {
|
|
21
|
-
expect(stripHtml('hello<br>world')).toBe('hello\nworld')
|
|
22
|
-
expect(stripHtml('hello<br/>world')).toBe('hello\nworld')
|
|
23
|
-
expect(stripHtml('hello<br />world')).toBe('hello\nworld')
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('should convert <p> tags to line-breaks', () => {
|
|
27
|
-
expect(stripHtml('<p>First paragraph</p><p>Second paragraph</p>'))
|
|
28
|
-
.toBe('First paragraph\nSecond paragraph')
|
|
29
|
-
expect(stripHtml('<p>Only paragraph</p>'))
|
|
30
|
-
.toBe('Only paragraph')
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('should trim leading and trailing whitespace', () => {
|
|
34
|
-
expect(stripHtml(' <p>text</p> ')).toBe('text')
|
|
35
|
-
expect(stripHtml('<p> text </p>')).toBe('text')
|
|
36
|
-
})
|
|
37
|
-
})
|