1- import { describe , expect , test } from " vitest"
2- import { defaultParseSearch , defaultStringifySearch } from " ../src"
1+ import { describe , expect , test } from ' vitest'
2+ import { defaultParseSearch , defaultStringifySearch } from ' ../src'
33
4- describe ( " Search Params serialization and deserialization" , ( ) => {
5- /*
6- * JSON-compatible objects can be serialized into a string,
7- * and then deserialized back into the original object.
8- */
9- test . each ( [
10- [ { } , '' ] ,
11- [ { foo : '' } , '?foo=' ] ,
12- [ { foo : " bar" } , '?foo=bar' ] ,
13- [ { foo : " bar baz" } , '?foo=bar+baz' ] ,
14- [ { foo : 123 } , '?foo=123' ] ,
15- [ { foo : '123' } , '?foo=%22123%22' ] ,
16- [ { foo : true } , '?foo=true' ] ,
17- [ { foo : 'true' } , '?foo=%22true%22' ] ,
18- [ { foo : null } , '?foo=null' ] ,
19- [ { foo : 'null' } , '?foo=%22null%22' ] ,
20- [ { foo : undefined } , '' ] ,
21- [ { foo : 'undefined' } , '?foo=undefined' ] ,
22- [ { foo : { } } , '?foo=%7B%7D' ] ,
23- [ { foo : '{}' } , '?foo=%22%7B%7D%22' ] ,
24- [ { foo : [ ] } , '?foo=%5B%5D' ] ,
25- [ { foo : '[]' } , '?foo=%22%5B%5D%22' ] ,
26- [ { foo : [ 1 , 2 , 3 ] } , '?foo=%5B1%2C2%2C3%5D' ] ,
27- [ { foo : '1,2,3' } , '?foo=1%2C2%2C3' ] ,
28- [ { foo : { bar : " baz" } } , '?foo=%7B%22bar%22%3A%22baz%22%7D' ] ,
29- [ { 0 : 1 } , '?0=1' ] ,
30- [ { 'foo=bar' : 1 } , '?foo%3Dbar=1' ] ,
31- [ { '{}' : 1 } , '?%7B%7D=1' ] ,
32- [ { '' : 1 } , '?=1' ] ,
33- [ { '=' : '=' } , '?%3D=%3D' ] ,
34- [ { '=' : '' , '' : '=' } , '?%3D=&=%3D' ] ,
35- [ { 'foo=2&bar' : 3 } , '?foo%3D2%26bar=3' ] ,
36- [ { 'foo?' : 1 } , '?foo%3F=1' ] ,
37- [ { foo : 'bar=' } , '?foo=bar%3D' ] ,
38- [ { foo : '2&bar=3' } , '?foo=2%26bar%3D3' ] ,
39- ] ) ( 'isomorphism %j' , ( input , expected ) => {
40- const str = defaultStringifySearch ( input )
41- expect ( str ) . toEqual ( expected )
42- expect ( defaultParseSearch ( str ) ) . toEqual ( input )
43- } )
4+ describe ( ' Search Params serialization and deserialization' , ( ) => {
5+ /*
6+ * JSON-compatible objects can be serialized into a string,
7+ * and then deserialized back into the original object.
8+ */
9+ test . each ( [
10+ [ { } , '' ] ,
11+ [ { foo : '' } , '?foo=' ] ,
12+ [ { foo : ' bar' } , '?foo=bar' ] ,
13+ [ { foo : ' bar baz' } , '?foo=bar+baz' ] ,
14+ [ { foo : 123 } , '?foo=123' ] ,
15+ [ { foo : '123' } , '?foo=%22123%22' ] ,
16+ [ { foo : true } , '?foo=true' ] ,
17+ [ { foo : 'true' } , '?foo=%22true%22' ] ,
18+ [ { foo : null } , '?foo=null' ] ,
19+ [ { foo : 'null' } , '?foo=%22null%22' ] ,
20+ [ { foo : undefined } , '' ] ,
21+ [ { foo : 'undefined' } , '?foo=undefined' ] ,
22+ [ { foo : { } } , '?foo=%7B%7D' ] ,
23+ [ { foo : '{}' } , '?foo=%22%7B%7D%22' ] ,
24+ [ { foo : [ ] } , '?foo=%5B%5D' ] ,
25+ [ { foo : '[]' } , '?foo=%22%5B%5D%22' ] ,
26+ [ { foo : [ 1 , 2 , 3 ] } , '?foo=%5B1%2C2%2C3%5D' ] ,
27+ [ { foo : '1,2,3' } , '?foo=1%2C2%2C3' ] ,
28+ [ { foo : { bar : ' baz' } } , '?foo=%7B%22bar%22%3A%22baz%22%7D' ] ,
29+ [ { 0 : 1 } , '?0=1' ] ,
30+ [ { 'foo=bar' : 1 } , '?foo%3Dbar=1' ] ,
31+ [ { '{}' : 1 } , '?%7B%7D=1' ] ,
32+ [ { '' : 1 } , '?=1' ] ,
33+ [ { '=' : '=' } , '?%3D=%3D' ] ,
34+ [ { '=' : '' , '' : '=' } , '?%3D=&=%3D' ] ,
35+ [ { 'foo=2&bar' : 3 } , '?foo%3D2%26bar=3' ] ,
36+ [ { 'foo?' : 1 } , '?foo%3F=1' ] ,
37+ [ { foo : 'bar=' } , '?foo=bar%3D' ] ,
38+ [ { foo : '2&bar=3' } , '?foo=2%26bar%3D3' ] ,
39+ ] ) ( 'isomorphism %j' , ( input , expected ) => {
40+ const str = defaultStringifySearch ( input )
41+ expect ( str ) . toEqual ( expected )
42+ expect ( defaultParseSearch ( str ) ) . toEqual ( input )
43+ } )
4444
45- test ( '[edge case] self-reference serializes to "object Object"' , ( ) => {
46- const obj = { } as any
47- obj . self = obj
48- const str = defaultStringifySearch ( obj )
49- expect ( str ) . toEqual ( '?self=%5Bobject+Object%5D' )
50- expect ( defaultParseSearch ( str ) ) . toEqual ( { self : '[object Object]' } )
51- } )
45+ test ( '[edge case] self-reference serializes to "object Object"' , ( ) => {
46+ const obj = { } as any
47+ obj . self = obj
48+ const str = defaultStringifySearch ( obj )
49+ expect ( str ) . toEqual ( '?self=%5Bobject+Object%5D' )
50+ expect ( defaultParseSearch ( str ) ) . toEqual ( { self : '[object Object]' } )
51+ } )
5252
53- /*
54- * It is able to parse strings that could not have come
55- * from the serializer.
56- *
57- * This can be useful because search params can be manipulated
58- * by human users.
59- */
60- test . each ( [
61- [ '?foo={}' , { foo : { } } ] ,
62- [ '?foo=[]' , { foo : [ ] } ] ,
63- [ '?foo=1,2,3' , { foo : '1,2,3' } ] ,
64- [ '?foo={"bar":"baz"}' , { foo : { bar : " baz" } } ] ,
65- [ '?foo=1&foo=2' , { foo : [ 1 , 2 ] } ] ,
66- [ '?foo=""' , { foo : '' } ] ,
67- [ '?foo=""""' , { foo : '""""' } ] ,
68- [ '?foo=()' , { foo : '()' } ] ,
69- [ '?foo=[{}]' , { foo : [ { } ] } ] ,
70- ] ) ( 'alien deserialization %s' , ( input , expected ) => {
71- const obj = defaultParseSearch ( input )
72- expect ( obj ) . toEqual ( expected )
73- expect ( defaultStringifySearch ( obj ) ) . not . toBe ( input )
74- } )
53+ /*
54+ * It is able to parse strings that could not have come
55+ * from the serializer.
56+ *
57+ * This can be useful because search params can be manipulated
58+ * by human users.
59+ */
60+ test . each ( [
61+ [ '?foo={}' , { foo : { } } ] ,
62+ [ '?foo=[]' , { foo : [ ] } ] ,
63+ [ '?foo=1,2,3' , { foo : '1,2,3' } ] ,
64+ [ '?foo={"bar":"baz"}' , { foo : { bar : ' baz' } } ] ,
65+ [ '?foo=1&foo=2' , { foo : [ 1 , 2 ] } ] ,
66+ [ '?foo=""' , { foo : '' } ] ,
67+ [ '?foo=""""' , { foo : '""""' } ] ,
68+ [ '?foo=()' , { foo : '()' } ] ,
69+ [ '?foo=[{}]' , { foo : [ { } ] } ] ,
70+ ] ) ( 'alien deserialization %s' , ( input , expected ) => {
71+ const obj = defaultParseSearch ( input )
72+ expect ( obj ) . toEqual ( expected )
73+ expect ( defaultStringifySearch ( obj ) ) . not . toBe ( input )
74+ } )
7575
76- /*
77- * It can serialize stuff that really shouldn't be passed as input.
78- * But just in case, this test serves as documentation of "what would happen"
79- * if you did.
80- */
81- test ( '[edge case] inputs that are not primitive objects' , ( ) => {
82- expect ( defaultStringifySearch ( new Number ( 99 ) ) ) . toEqual ( '' )
83- expect ( defaultStringifySearch ( { foo : new Number ( 99 ) } ) ) . toEqual ( '?foo=99' )
84- expect ( defaultStringifySearch ( new String ( 'foo' ) ) ) . toEqual ( '?0=f&1=o&2=o' )
85- expect ( defaultStringifySearch ( new Promise ( ( ) => { } ) ) ) . toEqual ( '' )
86- expect ( defaultStringifySearch ( { foo : new Promise ( ( ) => { } ) } ) ) . toEqual ( '?foo=%7B%7D' )
87- expect ( defaultStringifySearch ( [ 1 ] ) ) . toEqual ( '?0=1' )
88- const date = new Date ( )
89- expect ( defaultStringifySearch ( date ) ) . toEqual ( '' )
90- expect ( defaultStringifySearch ( { foo : date } ) ) . toEqual ( `?foo=%22${ encodeURIComponent ( date . toISOString ( ) ) } %22` )
91- } )
92- } )
76+ /*
77+ * It can serialize stuff that really shouldn't be passed as input.
78+ * But just in case, this test serves as documentation of "what would happen"
79+ * if you did.
80+ */
81+ test ( '[edge case] inputs that are not primitive objects' , ( ) => {
82+ expect ( defaultStringifySearch ( new Number ( 99 ) ) ) . toEqual ( '' )
83+ expect ( defaultStringifySearch ( { foo : new Number ( 99 ) } ) ) . toEqual ( '?foo=99' )
84+ expect ( defaultStringifySearch ( new String ( 'foo' ) ) ) . toEqual ( '?0=f&1=o&2=o' )
85+ expect ( defaultStringifySearch ( new Promise ( ( ) => { } ) ) ) . toEqual ( '' )
86+ expect ( defaultStringifySearch ( { foo : new Promise ( ( ) => { } ) } ) ) . toEqual (
87+ '?foo=%7B%7D' ,
88+ )
89+ expect ( defaultStringifySearch ( [ 1 ] ) ) . toEqual ( '?0=1' )
90+ const date = new Date ( )
91+ expect ( defaultStringifySearch ( date ) ) . toEqual ( '' )
92+ expect ( defaultStringifySearch ( { foo : date } ) ) . toEqual (
93+ `?foo=%22${ encodeURIComponent ( date . toISOString ( ) ) } %22` ,
94+ )
95+ } )
96+ } )
0 commit comments