1
- import { describe , expect , test } from 'vitest'
1
+ import { describe , expect , it } from 'vitest'
2
2
import {
3
3
parseAsArrayOf ,
4
4
parseAsBoolean ,
@@ -14,50 +14,50 @@ import {
14
14
parseAsStringLiteral ,
15
15
parseAsTimestamp
16
16
} from './parsers'
17
- import { testParseThenSerialize , testSerializeThenParse } from './testing'
17
+ import {
18
+ isParserBijective ,
19
+ testParseThenSerialize ,
20
+ testSerializeThenParse
21
+ } from './testing'
18
22
19
23
describe ( 'parsers' , ( ) => {
20
- test ( 'parseAsString' , ( ) => {
24
+ it ( 'parseAsString' , ( ) => {
21
25
expect ( parseAsString . parse ( '' ) ) . toBe ( '' )
22
26
expect ( parseAsString . parse ( 'foo' ) ) . toBe ( 'foo' )
23
- testParseThenSerialize ( parseAsString , 'foo' )
24
- testSerializeThenParse ( parseAsString , 'foo' )
27
+ expect ( isParserBijective ( parseAsString , 'foo' , 'foo' ) ) . toBe ( true )
25
28
} )
26
- test ( 'parseAsInteger' , ( ) => {
29
+ it ( 'parseAsInteger' , ( ) => {
27
30
expect ( parseAsInteger . parse ( '' ) ) . toBeNull ( )
28
31
expect ( parseAsInteger . parse ( '1' ) ) . toBe ( 1 )
29
32
expect ( parseAsInteger . parse ( '3.14' ) ) . toBe ( 3 )
30
33
expect ( parseAsInteger . parse ( '3,14' ) ) . toBe ( 3 )
31
34
expect ( parseAsInteger . serialize ( 3.14 ) ) . toBe ( '3' )
32
- testParseThenSerialize ( parseAsInteger , '3' )
33
- testSerializeThenParse ( parseAsInteger , 3 )
35
+ expect ( isParserBijective ( parseAsInteger , '3' , 3 ) ) . toBe ( true )
34
36
expect ( ( ) => testParseThenSerialize ( parseAsInteger , '3.14' ) ) . toThrow ( )
35
37
expect ( ( ) => testSerializeThenParse ( parseAsInteger , 3.14 ) ) . toThrow ( )
36
38
} )
37
- test ( 'parseAsHex' , ( ) => {
39
+ it ( 'parseAsHex' , ( ) => {
38
40
expect ( parseAsHex . parse ( '' ) ) . toBeNull ( )
39
41
expect ( parseAsHex . parse ( '1' ) ) . toBe ( 1 )
40
42
expect ( parseAsHex . parse ( 'a' ) ) . toBe ( 0xa )
41
43
expect ( parseAsHex . parse ( 'g' ) ) . toBeNull ( )
42
44
expect ( parseAsHex . serialize ( 0xa ) ) . toBe ( '0a' )
43
- for ( let i = 0 ; i < 256 ; i ++ ) {
44
- const hex = i . toString ( 16 ) . padStart ( 2 , '0' )
45
- testParseThenSerialize ( parseAsHex , hex )
46
- testSerializeThenParse ( parseAsHex , i )
45
+ for ( let byte = 0 ; byte < 256 ; byte ++ ) {
46
+ const hexString = byte . toString ( 16 ) . padStart ( 2 , '0' )
47
+ expect ( isParserBijective ( parseAsHex , hexString , byte ) ) . toBe ( true )
47
48
}
48
49
} )
49
- test ( 'parseAsFloat' , ( ) => {
50
+ it ( 'parseAsFloat' , ( ) => {
50
51
expect ( parseAsFloat . parse ( '' ) ) . toBeNull ( )
51
52
expect ( parseAsFloat . parse ( '1' ) ) . toBe ( 1 )
52
53
expect ( parseAsFloat . parse ( '3.14' ) ) . toBe ( 3.14 )
53
54
expect ( parseAsFloat . parse ( '3,14' ) ) . toBe ( 3 )
54
55
expect ( parseAsFloat . serialize ( 3.14 ) ) . toBe ( '3.14' )
55
56
// https://0.30000000000000004.com/
56
57
expect ( parseAsFloat . serialize ( 0.1 + 0.2 ) ) . toBe ( '0.30000000000000004' )
57
- testParseThenSerialize ( parseAsFloat , '3.14' )
58
- testSerializeThenParse ( parseAsFloat , 3.14 )
58
+ expect ( isParserBijective ( parseAsFloat , '3.14' , 3.14 ) ) . toBe ( true )
59
59
} )
60
- test ( 'parseAsIndex' , ( ) => {
60
+ it ( 'parseAsIndex' , ( ) => {
61
61
expect ( parseAsIndex . parse ( '' ) ) . toBeNull ( )
62
62
expect ( parseAsIndex . parse ( '1' ) ) . toBe ( 0 )
63
63
expect ( parseAsIndex . parse ( '3.14' ) ) . toBe ( 2 )
@@ -66,22 +66,20 @@ describe('parsers', () => {
66
66
expect ( parseAsIndex . parse ( '-1' ) ) . toBe ( - 2 )
67
67
expect ( parseAsIndex . serialize ( 0 ) ) . toBe ( '1' )
68
68
expect ( parseAsIndex . serialize ( 3.14 ) ) . toBe ( '4' )
69
- testParseThenSerialize ( parseAsIndex , '0' )
70
- testParseThenSerialize ( parseAsIndex , '1' )
71
- testSerializeThenParse ( parseAsIndex , 0 )
72
- testSerializeThenParse ( parseAsIndex , 1 )
69
+ expect ( isParserBijective ( parseAsIndex , '1' , 0 ) ) . toBe ( true )
70
+ expect ( isParserBijective ( parseAsIndex , '2' , 1 ) ) . toBe ( true )
73
71
} )
74
- test ( 'parseAsHex' , ( ) => {
72
+ it ( 'parseAsHex' , ( ) => {
75
73
expect ( parseAsHex . parse ( '' ) ) . toBeNull ( )
76
74
expect ( parseAsHex . parse ( '1' ) ) . toBe ( 1 )
77
75
expect ( parseAsHex . parse ( 'a' ) ) . toBe ( 0xa )
78
76
expect ( parseAsHex . parse ( 'g' ) ) . toBeNull ( )
79
77
expect ( parseAsHex . serialize ( 0x0a ) ) . toBe ( '0a' )
80
78
expect ( parseAsHex . serialize ( 0x2a ) ) . toBe ( '2a' )
81
- testParseThenSerialize ( parseAsHex , '2a' )
82
- testSerializeThenParse ( parseAsHex , 0x2a )
79
+ expect ( isParserBijective ( parseAsHex , '0a' , 0x0a ) ) . toBe ( true )
80
+ expect ( isParserBijective ( parseAsHex , '2a' , 0x2a ) ) . toBe ( true )
83
81
} )
84
- test ( 'parseAsBoolean' , ( ) => {
82
+ it ( 'parseAsBoolean' , ( ) => {
85
83
expect ( parseAsBoolean . parse ( '' ) ) . toBe ( false )
86
84
// In only triggers on 'true', everything else is false
87
85
expect ( parseAsBoolean . parse ( 'true' ) ) . toBe ( true )
@@ -92,19 +90,23 @@ describe('parsers', () => {
92
90
expect ( parseAsBoolean . parse ( 'no' ) ) . toBe ( false )
93
91
expect ( parseAsBoolean . serialize ( true ) ) . toBe ( 'true' )
94
92
expect ( parseAsBoolean . serialize ( false ) ) . toBe ( 'false' )
95
- testParseThenSerialize ( parseAsBoolean , 'true' )
96
- testSerializeThenParse ( parseAsBoolean , true )
97
- testParseThenSerialize ( parseAsBoolean , 'false' )
98
- testSerializeThenParse ( parseAsBoolean , false )
93
+ expect ( isParserBijective ( parseAsBoolean , 'true' , true ) ) . toBe ( true )
94
+ expect ( isParserBijective ( parseAsBoolean , 'false' , false ) ) . toBe ( true )
99
95
} )
100
96
101
- test ( 'parseAsTimestamp' , ( ) => {
97
+ it ( 'parseAsTimestamp' , ( ) => {
102
98
expect ( parseAsTimestamp . parse ( '' ) ) . toBeNull ( )
103
99
expect ( parseAsTimestamp . parse ( '0' ) ) . toStrictEqual ( new Date ( 0 ) )
104
- testParseThenSerialize ( parseAsTimestamp , '0' )
105
- testSerializeThenParse ( parseAsTimestamp , new Date ( 1234567890 ) )
100
+ expect ( testParseThenSerialize ( parseAsTimestamp , '0' ) ) . toBe ( true )
101
+ expect ( testSerializeThenParse ( parseAsTimestamp , new Date ( 1234567890 ) ) ) . toBe (
102
+ true
103
+ )
104
+ expect ( isParserBijective ( parseAsTimestamp , '0' , new Date ( 0 ) ) ) . toBe ( true )
105
+ expect (
106
+ isParserBijective ( parseAsTimestamp , '1234567890' , new Date ( 1234567890 ) )
107
+ ) . toBe ( true )
106
108
} )
107
- test ( 'parseAsIsoDateTime' , ( ) => {
109
+ it ( 'parseAsIsoDateTime' , ( ) => {
108
110
expect ( parseAsIsoDateTime . parse ( '' ) ) . toBeNull ( )
109
111
expect ( parseAsIsoDateTime . parse ( 'not-a-date' ) ) . toBeNull ( )
110
112
const moment = '2020-01-01T00:00:00.000Z'
@@ -114,20 +116,22 @@ describe('parsers', () => {
114
116
expect ( parseAsIsoDateTime . parse ( moment . slice ( 0 , 16 ) + 'Z' ) ) . toStrictEqual (
115
117
ref
116
118
)
117
- testParseThenSerialize ( parseAsIsoDateTime , moment )
118
- testSerializeThenParse ( parseAsIsoDateTime , ref )
119
+ expect ( testParseThenSerialize ( parseAsIsoDateTime , moment ) ) . toBe ( true )
120
+ expect ( testSerializeThenParse ( parseAsIsoDateTime , ref ) ) . toBe ( true )
121
+ expect ( isParserBijective ( parseAsIsoDateTime , moment , ref ) ) . toBe ( true )
119
122
} )
120
- test ( 'parseAsIsoDate' , ( ) => {
123
+ it ( 'parseAsIsoDate' , ( ) => {
121
124
expect ( parseAsIsoDate . parse ( '' ) ) . toBeNull ( )
122
125
expect ( parseAsIsoDate . parse ( 'not-a-date' ) ) . toBeNull ( )
123
126
const moment = '2020-01-01'
124
127
const ref = new Date ( moment )
125
128
expect ( parseAsIsoDate . parse ( moment ) ) . toStrictEqual ( ref )
126
129
expect ( parseAsIsoDate . serialize ( ref ) ) . toEqual ( moment )
127
- testParseThenSerialize ( parseAsIsoDate , moment )
128
- testSerializeThenParse ( parseAsIsoDate , ref )
130
+ expect ( testParseThenSerialize ( parseAsIsoDate , moment ) ) . toBe ( true )
131
+ expect ( testSerializeThenParse ( parseAsIsoDate , ref ) ) . toBe ( true )
132
+ expect ( isParserBijective ( parseAsIsoDate , moment , ref ) ) . toBe ( true )
129
133
} )
130
- test ( 'parseAsStringEnum' , ( ) => {
134
+ it ( 'parseAsStringEnum' , ( ) => {
131
135
enum Test {
132
136
A = 'a' ,
133
137
B = 'b' ,
@@ -142,10 +146,11 @@ describe('parsers', () => {
142
146
expect ( parser . serialize ( Test . A ) ) . toBe ( 'a' )
143
147
expect ( parser . serialize ( Test . B ) ) . toBe ( 'b' )
144
148
expect ( parser . serialize ( Test . C ) ) . toBe ( 'c' )
145
- testParseThenSerialize ( parser , 'a' )
146
- testSerializeThenParse ( parser , Test . A )
149
+ expect ( testParseThenSerialize ( parser , 'a' ) ) . toBe ( true )
150
+ expect ( testSerializeThenParse ( parser , Test . A ) ) . toBe ( true )
151
+ expect ( isParserBijective ( parser , 'b' , Test . B ) ) . toBe ( true )
147
152
} )
148
- test ( 'parseAsStringLiteral' , ( ) => {
153
+ it ( 'parseAsStringLiteral' , ( ) => {
149
154
const parser = parseAsStringLiteral ( [ 'a' , 'b' , 'c' ] as const )
150
155
expect ( parser . parse ( '' ) ) . toBeNull ( )
151
156
expect ( parser . parse ( 'a' ) ) . toBe ( 'a' )
@@ -155,10 +160,13 @@ describe('parsers', () => {
155
160
expect ( parser . serialize ( 'a' ) ) . toBe ( 'a' )
156
161
expect ( parser . serialize ( 'b' ) ) . toBe ( 'b' )
157
162
expect ( parser . serialize ( 'c' ) ) . toBe ( 'c' )
158
- testParseThenSerialize ( parser , 'a' )
159
- testSerializeThenParse ( parser , 'a' )
163
+ expect ( testParseThenSerialize ( parser , 'a' ) ) . toBe ( true )
164
+ expect ( testSerializeThenParse ( parser , 'a' ) ) . toBe ( true )
165
+ expect ( isParserBijective ( parser , 'a' , 'a' ) ) . toBe ( true )
166
+ expect ( isParserBijective ( parser , 'b' , 'b' ) ) . toBe ( true )
167
+ expect ( isParserBijective ( parser , 'c' , 'c' ) ) . toBe ( true )
160
168
} )
161
- test ( 'parseAsNumberLiteral' , ( ) => {
169
+ it ( 'parseAsNumberLiteral' , ( ) => {
162
170
const parser = parseAsNumberLiteral ( [ 1 , 2 , 3 ] as const )
163
171
expect ( parser . parse ( '' ) ) . toBeNull ( )
164
172
expect ( parser . parse ( '1' ) ) . toBe ( 1 )
@@ -168,20 +176,27 @@ describe('parsers', () => {
168
176
expect ( parser . serialize ( 1 ) ) . toBe ( '1' )
169
177
expect ( parser . serialize ( 2 ) ) . toBe ( '2' )
170
178
expect ( parser . serialize ( 3 ) ) . toBe ( '3' )
171
- testParseThenSerialize ( parser , '1' )
172
- testSerializeThenParse ( parser , 1 )
179
+ expect ( testParseThenSerialize ( parser , '1' ) ) . toBe ( true )
180
+ expect ( testSerializeThenParse ( parser , 1 ) ) . toBe ( true )
181
+ expect ( isParserBijective ( parser , '1' , 1 ) ) . toBe ( true )
182
+ expect ( isParserBijective ( parser , '2' , 2 ) ) . toBe ( true )
183
+ expect ( isParserBijective ( parser , '3' , 3 ) ) . toBe ( true )
173
184
} )
174
185
175
- test ( 'parseAsArrayOf' , ( ) => {
186
+ it ( 'parseAsArrayOf' , ( ) => {
176
187
const parser = parseAsArrayOf ( parseAsString )
177
188
expect ( parser . serialize ( [ ] ) ) . toBe ( '' )
178
189
// It encodes its separator
179
190
expect ( parser . serialize ( [ 'a' , ',' , 'b' ] ) ) . toBe ( 'a,%2C,b' )
180
- testParseThenSerialize ( parser , 'a,b' )
181
- testSerializeThenParse ( parser , [ 'a' , 'b' ] )
191
+ expect ( testParseThenSerialize ( parser , 'a,b' ) ) . toBe ( true )
192
+ expect ( testSerializeThenParse ( parser , [ 'a' , 'b' ] ) ) . toBe ( true )
193
+ expect ( isParserBijective ( parser , 'a,b' , [ 'a' , 'b' ] ) ) . toBe ( true )
194
+ expect ( ( ) =>
195
+ isParserBijective ( parser , 'not-an-array' , [ 'a' , 'b' ] )
196
+ ) . toThrow ( )
182
197
} )
183
198
184
- test ( 'parseServerSide with default (#384)' , ( ) => {
199
+ it ( 'parseServerSide with default (#384)' , ( ) => {
185
200
const p = parseAsString . withDefault ( 'default' )
186
201
const searchParams = {
187
202
string : 'foo' ,
@@ -195,18 +210,18 @@ describe('parsers', () => {
195
210
expect ( p . parseServerSide ( searchParams . nope ) ) . toBe ( 'default' )
196
211
} )
197
212
198
- test ( 'chaining options does not reset them', ( ) => {
213
+ it ( ' does not reset options when chaining them', ( ) => {
199
214
const p = parseAsString . withOptions ( { scroll : true } ) . withOptions ( { } )
200
215
expect ( p . scroll ) . toBe ( true )
201
216
} )
202
- test ( 'chaining options merges them', ( ) => {
217
+ it ( 'merges options when chaining them', ( ) => {
203
218
const p = parseAsString
204
219
. withOptions ( { scroll : true } )
205
220
. withOptions ( { history : 'push' } )
206
221
expect ( p . scroll ) . toBe ( true )
207
222
expect ( p . history ) . toBe ( 'push' )
208
223
} )
209
- test ( 'chaining options & default value ', ( ) => {
224
+ it ( 'merges default values when chaining options ', ( ) => {
210
225
const p = parseAsString
211
226
. withOptions ( { scroll : true } )
212
227
. withDefault ( 'default' )
@@ -216,15 +231,15 @@ describe('parsers', () => {
216
231
expect ( p . defaultValue ) . toBe ( 'default' )
217
232
expect ( p . parseServerSide ( undefined ) ) . toBe ( 'default' )
218
233
} )
219
- test ( ' changing default value', ( ) => {
234
+ it ( 'allows changing the default value', ( ) => {
220
235
const p = parseAsString . withDefault ( 'foo' ) . withDefault ( 'bar' )
221
236
expect ( p . defaultValue ) . toBe ( 'bar' )
222
237
expect ( p . parseServerSide ( undefined ) ) . toBe ( 'bar' )
223
238
} )
224
239
} )
225
240
226
241
describe ( 'parsers/equality' , ( ) => {
227
- test ( 'parseAsArrayOf' , ( ) => {
242
+ it ( 'parseAsArrayOf' , ( ) => {
228
243
const eq = parseAsArrayOf ( parseAsString ) . eq !
229
244
expect ( eq ( [ ] , [ ] ) ) . toBe ( true )
230
245
expect ( eq ( [ 'foo' ] , [ 'foo' ] ) ) . toBe ( true )
0 commit comments