UNPKG

17.3 kBtext/coffeescriptView Raw
1
2
3############################################################################################################
4CND = require 'cnd'
5rpr = CND.rpr
6badge = 'HOLLERITH-CODEC/tests'
7log = CND.get_logger 'plain', badge
8info = CND.get_logger 'info', badge
9whisper = CND.get_logger 'whisper', badge
10alert = CND.get_logger 'alert', badge
11debug = CND.get_logger 'debug', badge
12warn = CND.get_logger 'warn', badge
13help = CND.get_logger 'help', badge
14urge = CND.get_logger 'urge', badge
15echo = CND.echo.bind CND
16#...........................................................................................................
17test = require 'guy-test'
18CODEC = require './main'
19ƒ = CND.format_number
20{ jr, } = CND
21
22#-----------------------------------------------------------------------------------------------------------
23@[ "codec encodes and decodes numbers" ] = ( T ) ->
24 key = [ 'foo', 1234, 5678, ]
25 key_bfr = CODEC.encode key
26 T.eq key, CODEC.decode key_bfr
27 whisper "key length: #{key_bfr.length}"
28
29#-----------------------------------------------------------------------------------------------------------
30@[ "codec encodes and decodes dates" ] = ( T ) ->
31 key = [ 'foo', ( new Date() ), 5678, ]
32 key_bfr = CODEC.encode key
33 T.eq key, CODEC.decode key_bfr
34 whisper "key length: #{key_bfr.length}"
35
36#-----------------------------------------------------------------------------------------------------------
37@[ "codec accepts long numbers" ] = ( T ) ->
38 key = [ 'foo', ( i for i in [ 0 .. 1000 ] ), 'bar', ]
39 key_bfr = CODEC.encode key
40 T.eq key, CODEC.decode key_bfr
41 whisper "key length: #{key_bfr.length}"
42
43#-----------------------------------------------------------------------------------------------------------
44@[ "codec accepts long texts" ] = ( T ) ->
45 long_text = ( new Array 1e4 ).join '#'
46 key = [ 'foo', [ long_text, long_text, long_text, long_text, ], 42, ]
47 key_bfr = CODEC.encode key
48 T.eq key, CODEC.decode key_bfr
49 whisper "key length: #{key_bfr.length}"
50
51#-----------------------------------------------------------------------------------------------------------
52@[ "codec preserves critical escaped characters (roundtrip) (1)" ] = ( T ) ->
53 text = 'abc\x00\x00\x00\x00def'
54 key = [ 'xxx', [ text, ], 0, ]
55 key_bfr = CODEC.encode key
56 T.eq key, CODEC.decode key_bfr
57
58#-----------------------------------------------------------------------------------------------------------
59@[ "codec preserves critical escaped characters (roundtrip) (2)" ] = ( T ) ->
60 text = 'abc\x01\x01\x01\x01def'
61 key = [ 'xxx', [ text, ], 0, ]
62 key_bfr = CODEC.encode key
63 T.eq key, CODEC.decode key_bfr
64
65#-----------------------------------------------------------------------------------------------------------
66@[ "codec preserves critical escaped characters (roundtrip) (3)" ] = ( T ) ->
67 text = 'abc\x00\x01\x00\x01def'
68 key = [ 'xxx', [ text, ], 0, ]
69 key_bfr = CODEC.encode key
70 T.eq key, CODEC.decode key_bfr
71
72#-----------------------------------------------------------------------------------------------------------
73@[ "codec preserves critical escaped characters (roundtrip) (4)" ] = ( T ) ->
74 text = 'abc\x01\x00\x01\x00def'
75 key = [ 'xxx', [ text, ], 0, ]
76 key_bfr = CODEC.encode key
77 T.eq key, CODEC.decode key_bfr
78
79#-----------------------------------------------------------------------------------------------------------
80@[ "codec accepts private type (1)" ] = ( T ) ->
81 key = [ { type: 'price', value: 'abc', }, ]
82 key_bfr = CODEC.encode key
83 T.eq key, CODEC.decode key_bfr
84
85#-----------------------------------------------------------------------------------------------------------
86@[ "codec accepts private type (2)" ] = ( T ) ->
87 key = [ 123, 456, { type: 'price', value: 'abc', }, 'xxx', ]
88 key_bfr = CODEC.encode key
89 T.eq key, CODEC.decode key_bfr
90
91#-----------------------------------------------------------------------------------------------------------
92@[ "codec decodes private type with custom decoder (1)" ] = ( T ) ->
93 value = '/etc/cron.d/anacron'
94 matcher = [ value, ]
95 encoded_value = value.split '/'
96 key = [ { type: 'route', value: encoded_value, }, ]
97 key_bfr = CODEC.encode key
98 #.........................................................................................................
99 decoded_key = CODEC.decode key_bfr, ( type, value ) ->
100 return value.join '/' if type is 'route'
101 throw new Error "unknown private type #{rpr type}"
102 #.........................................................................................................
103 # debug CODEC.rpr_of_buffer key_bfr
104 # debug CODEC.decode key_bfr
105 # debug decoded_key
106 T.eq matcher, decoded_key
107
108#-----------------------------------------------------------------------------------------------------------
109@_sets_are_equal = ( a, b ) ->
110 ### TAINT doesn't work for (sub-) elements that are sets or maps ###
111 return false unless ( CODEC.types.isa.set a ) and ( CODEC.types.isa.set b )
112 return false unless a.size is b.size
113 a_keys = a.keys()
114 b_keys = b.keys()
115 loop
116 { value: a_value, done: a_done, } = a_keys.next()
117 { value: b_value, done: b_done, } = b_keys.next()
118 break if a_done or b_done
119 return false unless CODEC.types.equals a_value, b_value
120 return true
121
122#-----------------------------------------------------------------------------------------------------------
123@[ "codec decodes private type with custom decoder (2)" ] = ( T ) ->
124 value = new Set 'qwert'
125 matcher = [ value, ]
126 encoded_value = Array.from value
127 key = [ { type: 'set', value: encoded_value, }, ]
128 key_bfr = CODEC.encode key
129 #.........................................................................................................
130 decoded_key = CODEC.decode key_bfr, ( type, value ) ->
131 return new Set value if type is 'set'
132 throw new Error "unknown private type #{rpr type}"
133 #.........................................................................................................
134 # debug CODEC.rpr_of_buffer key_bfr
135 # debug CODEC.decode key_bfr
136 # debug decoded_key
137 # debug matcher
138 T.ok @_sets_are_equal matcher[ 0 ], decoded_key[ 0 ]
139
140#-----------------------------------------------------------------------------------------------------------
141@[ "Support for Sets" ] = ( T ) ->
142 key = [ ( new Set 'qwert' ), ]
143 matcher = [ ( new Set 'qwert' ), ]
144 key_bfr = CODEC.encode key
145 decoded_key = CODEC.decode key_bfr
146 # debug CODEC.rpr_of_buffer key_bfr
147 # debug CODEC.decode key_bfr
148 # debug decoded_key
149 # debug matcher
150 T.ok @_sets_are_equal matcher[ 0 ], decoded_key[ 0 ]
151
152#-----------------------------------------------------------------------------------------------------------
153@[ "codec decodes private type with custom encoder and decoder (3)" ] = ( T ) ->
154 route = '/usr/local/lib/node_modules/coffee-script/README.md'
155 parts = route.split '/'
156 key = [ { type: 'route', value: route, }, ]
157 matcher_1 = [ { type: 'route', value: parts, }]
158 matcher_2 = [ route, ]
159 #.........................................................................................................
160 encoder = ( type, value ) ->
161 return value.split '/' if type is 'route'
162 throw new Error "unknown private type #{rpr type}"
163 #.........................................................................................................
164 decoder = ( type, value ) ->
165 return value.join '/' if type is 'route'
166 throw new Error "unknown private type #{rpr type}"
167 #.........................................................................................................
168 key_bfr = CODEC.encode key, encoder
169 # debug '©T4WKz', CODEC.rpr_of_buffer key_bfr
170 decoded_key_1 = CODEC.decode key_bfr
171 T.eq matcher_1, decoded_key_1
172 decoded_key_2 = CODEC.decode key_bfr, decoder
173 T.eq matcher_2, decoded_key_2
174
175#-----------------------------------------------------------------------------------------------------------
176@[ "private type takes default shape when handler returns use_fallback" ] = ( T ) ->
177 matcher = [ 84, { type: 'bar', value: 108, }, ]
178 key = [ { type: 'foo', value: 42, }, { type: 'bar', value: 108, }, ]
179 key_bfr = CODEC.encode key
180 #.........................................................................................................
181 decoded_key = CODEC.decode key_bfr, ( type, value, use_fallback ) ->
182 return value * 2 if type is 'foo'
183 return use_fallback
184 #.........................................................................................................
185 T.eq matcher, decoded_key
186
187#-----------------------------------------------------------------------------------------------------------
188@[ "test: flat file DB storage (1)" ] = ( T ) ->
189 probes = [
190 [ 'foo', -Infinity, ]
191 [ 'foo', -1e12, ]
192 [ 'foo', -3, ]
193 [ 'foo', -2, ]
194 [ 'foo', -1, ]
195 [ 'foo', 1, ]
196 [ 'foo', 2, ]
197 [ 'foo', 3, ]
198 [ 'foo', 1e12, ]
199 [ 'foo', Infinity, ]
200 [ 'bar', 'blah', ]
201 [ 'bar', 'gnu', ]
202 [ 'a', ]
203 [ 'b', ]
204 [ 'c', ]
205 [ 'A', ]
206 [ '箲' ]
207 [ '筅' ]
208 [ '𥬗' ]
209 [ 'B', ]
210 [ 'C', ]
211 [ '0', ]
212 [ '1', ]
213 [ '2', ]
214 [ 'Number', Number.EPSILON, 'EPSILON', ]
215 [ 'Number', Number.MAX_SAFE_INTEGER, 'MAX_SAFE_INTEGER', ]
216 [ 'Number', Number.MAX_VALUE, 'MAX_VALUE', ]
217 [ 'Number', 0, 'ZERO', ]
218 [ 'Number', Number.MIN_SAFE_INTEGER, 'MIN_SAFE_INTEGER', ]
219 [ 'Number', Number.MIN_VALUE, 'MIN_VALUE', ]
220 ]
221 buffer_as_text = ( buffer ) ->
222 R = []
223 for idx in [ 0 ... buffer.length ]
224 R.push String.fromCodePoint 0x2800 + buffer[ idx ]
225 # R.push String.fromCodePoint 0x2800 while R.length < 32
226 # R.push ' ' while R.length < 32
227 return R.join ''
228 probes = ( [ ( buffer_as_text CODEC.encode probe ), JSON.stringify probe, ] for probe in probes )
229 probes.sort ( a, b ) ->
230 return -1 if a[ 0 ] < b[ 0 ]
231 return +1 if a[ 0 ] > b[ 0 ]
232 return 0
233 for probe in probes
234 urge probe.join ' - '
235 # for probe in probes
236 # probe_txt = JSON.stringify probe
237 # key_txt = buffer_as_text CODEC.encode probe
238 # debug '33301', "#{key_txt} - #{probe_txt}"
239 urge "use `( export LC_ALL=C && sort hollerith-codec-flatfile-db.txt ) | less -SRN`"
240 urge "to sort a file with these lines"
241 return null
242
243#-----------------------------------------------------------------------------------------------------------
244@[ "test: flat file DB storage (2)" ] = ( T ) ->
245 probes_and_matchers = [
246 [["foo",-1000000000000],"⡔⡦⡯⡯⠀⡋⢽⢒⣥⡫⡝⣿⣿⣿![\"foo\",-1000000000000]"]
247 [["foo",-3],"⡔⡦⡯⡯⠀⡋⢿⣷⣿⣿⣿⣿⣿⣿![\"foo\",-3]"]
248 [["foo",-2],"⡔⡦⡯⡯⠀⡋⢿⣿⣿⣿⣿⣿⣿⣿![\"foo\",-2]"]
249 [["foo",-1],"⡔⡦⡯⡯⠀⡋⣀⠏⣿⣿⣿⣿⣿⣿![\"foo\",-1]"]
250 [["foo",1],"⡔⡦⡯⡯⠀⡍⠿⣰⠀⠀⠀⠀⠀⠀![\"foo\",1]"]
251 [["foo",2],"⡔⡦⡯⡯⠀⡍⡀⠀⠀⠀⠀⠀⠀⠀![\"foo\",2]"]
252 [["foo",3],"⡔⡦⡯⡯⠀⡍⡀⠈⠀⠀⠀⠀⠀⠀![\"foo\",3]"]
253 [["foo",1000000000000],"⡔⡦⡯⡯⠀⡍⡂⡭⠚⢔⢢⠀⠀⠀![\"foo\",1000000000000]"]
254 [["bar","blah"],"⡔⡢⡡⡲⠀⡔⡢⡬⡡⡨⠀![\"bar\",\"blah\"]"]
255 [["bar","gnu"],"⡔⡢⡡⡲⠀⡔⡧⡮⡵⠀![\"bar\",\"gnu\"]"]
256 [["a"],"⡔⡡⠀![\"a\"]"]
257 [["b"],"⡔⡢⠀![\"b\"]"]
258 [["c"],"⡔⡣⠀![\"c\"]"]
259 [["A"],"⡔⡁⠀![\"A\"]"]
260 [["箲"],"⡔⣧⢮⢲⠀![\"箲\"]"]
261 [["筅"],"⡔⣧⢭⢅⠀![\"筅\"]"]
262 [["𥬗"],"⡔⣰⢥⢬⢗⠀![\"𥬗\"]"]
263 [["B"],"⡔⡂⠀![\"B\"]"]
264 [["C"],"⡔⡃⠀![\"C\"]"]
265 [["0"],"⡔⠰⠀![\"0\"]"]
266 [["1"],"⡔⠱⠀![\"1\"]"]
267 [["2"],"⡔⠲⠀![\"2\"]"]
268 [["Number",2.220446049250313e-16,"EPSILON"],"⡔⡎⡵⡭⡢⡥⡲⠀⡍⠼⢰⠀⠀⠀⠀⠀⠀⡔⡅⡐⡓⡉⡌⡏⡎⠀![\"Number\",2.220446049250313e-16,\"EPSILON\"]"]
269 [["Number",9007199254740991,"MAX_SAFE_INTEGER"],"⡔⡎⡵⡭⡢⡥⡲⠀⡍⡃⠿⣿⣿⣿⣿⣿⣿⡔⡍⡁⡘⡟⡓⡁⡆⡅⡟⡉⡎⡔⡅⡇⡅⡒⠀![\"Number\",9007199254740991,\"MAX_SAFE_INTEGER\"]"]
270 [["Number",1.7976931348623157e+308,"MAX_VALUE"],"⡔⡎⡵⡭⡢⡥⡲⠀⡍⡿⣯⣿⣿⣿⣿⣿⣿⡔⡍⡁⡘⡟⡖⡁⡌⡕⡅⠀![\"Number\",1.7976931348623157e+308,\"MAX_VALUE\"]"]
271 [["Number",0,"ZERO"],"⡔⡎⡵⡭⡢⡥⡲⠀⡍⠀⠀⠀⠀⠀⠀⠀⠀⡔⡚⡅⡒⡏⠀![\"Number\",0,\"ZERO\"]"]
272 [["Number",-9007199254740991,"MIN_SAFE_INTEGER"],"⡔⡎⡵⡭⡢⡥⡲⠀⡋⢼⣀⠀⠀⠀⠀⠀⠀⡔⡍⡉⡎⡟⡓⡁⡆⡅⡟⡉⡎⡔⡅⡇⡅⡒⠀![\"Number\",-9007199254740991,\"MIN_SAFE_INTEGER\"]"]
273 [["Number",5e-324,"MIN_VALUE"],"⡔⡎⡵⡭⡢⡥⡲⠀⡍⠀⠀⠀⠀⠀⠀⠀⠁⡔⡍⡉⡎⡟⡖⡁⡌⡕⡅⠀![\"Number\",5e-324,\"MIN_VALUE\"]"]
274 ]
275 # stringify = ( x ) -> ( require 'util' ).inspect x, { maxArrayLength: null, breakLength: Infinity, }
276 stringify = jr
277 # settings = { stringify, base: 0x1e00, }
278 # settings = { stringify, base: 0x2200, }
279 # settings = { stringify, base: 0x2600, }
280 # settings = { stringify, base: 0xac00, }
281 # settings = { stringify, base: 0xa000, }
282 # settings = { stringify, base: 0x1d6a8, }
283 settings = { stringify, joiner: '!', }
284 for [ probe, matcher, ] in probes_and_matchers
285 result = CODEC.as_sortline probe, settings
286 debug '33392', stringify [ probe, result, ]
287 T.eq result, matcher
288 return null
289
290#-----------------------------------------------------------------------------------------------------------
291@[ "test: flat file DB storage (3)" ] = ( T ) ->
292 stringify = ( x ) -> ( require 'util' ).inspect x, { maxArrayLength: null, breakLength: Infinity, }
293 probes_and_matchers = [
294 [ [ 'foo', 1234 ], { bare: false, joiner: ',', base: 19968 }, '乔书乯乯一乍乀亓么一一一一一,["foo",1234]' ]
295 [ [ 'foo', 1234 ], { bare: true, joiner: ',', base: null }, '⡔⡦⡯⡯⠀⡍⡀⢓⡈⠀⠀⠀⠀⠀' ]
296 ]
297 for [ probe, settings, matcher, ] in probes_and_matchers
298 result = CODEC.as_sortline probe, settings
299 debug '33392', stringify [ probe, settings, result, ]
300 T.eq result, matcher
301 # echo result
302 return null
303
304
305# #-----------------------------------------------------------------------------------------------------------
306# @[ "buffers" ] = ( T ) ->
307# debug 'µ76776-1', d = Buffer.from 'hällo wörld'
308# debug 'µ76776-2', key_bfr = CODEC.encode [ d, ]
309# debug 'µ76776-3', decoded_key = CODEC.decode key_bfr
310 # debug CODEC.rpr_of_buffer key_bfr
311 # debug CODEC.decode key_bfr
312 # debug decoded_key
313 # debug matcher
314 # T.ok @_sets_are_equal matcher[ 0 ], decoded_key[ 0 ]
315
316
317#-----------------------------------------------------------------------------------------------------------
318@[ "test: ordering where negatives precede void" ] = ( T ) ->
319 probes = [
320 [-10,]
321 [10,]
322 [10,0]
323 [10,-1]
324 [10,-2]
325 [10,1]
326 [10,2]
327 [10,4]
328 [10,4,0]
329 [10,4,-1]
330 [10,4,-2]
331 [10,4,1]
332 [10,4,2]
333 [10,0,3]
334 [10,-1,3]
335 [10,-2,3]
336 [10,1,3]
337 [10,2,3]
338 []
339 [0]
340 [-1]
341 [1]
342 [1,0]
343 [1,-1]
344 [1,1]
345 ]
346 buffer_as_text = ( buffer ) -> buffer.toString 'hex'
347 jrx = ( x ) -> ( JSON.stringify x ).padEnd 15
348 encode = ( x ) -> buffer_as_text CODEC.encode x
349 results = ( [ ( jrx probe ), ( probe ), ( encode probe ), ] for probe in probes )
350 results.sort ( a, b ) ->
351 return -1 if a[ 2 ] < b[ 2 ]
352 return +1 if a[ 2 ] > b[ 2 ]
353 return 0
354 for result in results
355 urge result[ 0 ] + ' ... ' + result[ 2 ]
356 results = ( result[ 1 ] for result in results )
357 T.eq results, [[-10],[-1],[],[0],[1,-1],[1],[1,0],[1,1],[10,-2],[10,-2,3],[10,-1],[10,-1,3],[10],[10,0],[10,0,3],[10,1],[10,1,3],[10,2],[10,2,3],[10,4,-2],[10,4,-1],[10,4],[10,4,0],[10,4,1],[10,4,2]]
358 return null
359
360
361############################################################################################################
362unless module.parent?
363 test @
364 # test @[ "test: ordering where negatives precede void" ]
365
366 # buffer_as_text = ( buffer ) -> buffer.toString 'hex'
367 # jrx = ( x ) -> ( JSON.stringify x ).padEnd 15
368 # encode = ( x ) -> CODEC.encode x
369 # decode = ( x ) -> CODEC.decode x
370 # info ( buffer_as_text blob = encode [ 10, -3, ] ), ( decode blob )
371 # info ( buffer_as_text blob = encode [ 10, -2, ] ), ( decode blob )
372 # info ( buffer_as_text blob = encode [ 10, -1, ] ), ( decode blob )
373 # info ( buffer_as_text blob = encode [ 10, ] ), ( decode blob )
374 # info ( buffer_as_text blob = encode [ 10, 0, ] ), ( decode blob )
375 # info ( buffer_as_text blob = encode [ 10, 1, ] ), ( decode blob )
376
377
378
379