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