|
|
|
@ -1,9 +1,11 @@
|
|
|
|
|
#lang debug racket/base
|
|
|
|
|
(require rackunit
|
|
|
|
|
racket/dict
|
|
|
|
|
sugar/unstable/dict
|
|
|
|
|
"../helper.rkt"
|
|
|
|
|
"../number.rkt"
|
|
|
|
|
"../string.rkt"
|
|
|
|
|
"../pointer.rkt"
|
|
|
|
|
"../versioned-struct.rkt")
|
|
|
|
|
|
|
|
|
|
#|
|
|
|
|
@ -14,328 +16,259 @@ https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffe
|
|
|
|
|
(test-case
|
|
|
|
|
"decode should get version from number type"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
|
|
|
|
|
(check-equal? (dump (decode vstruct)) '((version . 0) (age . 21) (name . "roxyb"))))
|
|
|
|
|
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x0aroxyb 🤘\x15\x00"))])
|
|
|
|
|
(check-equal? (dump (decode vstruct)) '((version . 1) (age . 21) (name . "roxyb 🤘") (gender . 0))))))
|
|
|
|
|
|
|
|
|
|
#|
|
|
|
|
|
|
|
|
|
|
; it 'should throw for unknown version', ->
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x05\x05roxyb\x15")])
|
|
|
|
|
(check-exn exn:fail:contract? (λ () (decode struct)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
; it 'should support common header block', ->
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
'header (dictify 'age uint8
|
|
|
|
|
'alive uint8)
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii))
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x00\x15\x01\x05roxyb")])
|
|
|
|
|
(check-equal? (dump (decode struct)) (hasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'alive 1
|
|
|
|
|
'version 0)))
|
|
|
|
|
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x15\x01\x0aroxyb 🤘\x00"))])
|
|
|
|
|
(check-equal? (dump (decode struct)) (hasheq 'name "roxyb 🤘"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 1
|
|
|
|
|
'alive 1
|
|
|
|
|
'gender 0))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; it 'should support parent version key', ->
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct 'version
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x15")])
|
|
|
|
|
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (hasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 0)))
|
|
|
|
|
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x0aroxyb 🤘\x15\x00"))])
|
|
|
|
|
(check-equal? (dump (decode struct #:parent (mhash 'version 1))) (hasheq 'name "roxyb 🤘"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 1
|
|
|
|
|
'gender 0))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
; it 'should support sub versioned structs', ->
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8))
|
|
|
|
|
1 (dictify 'name (+StringT uint8)
|
|
|
|
|
'isDessert uint8)))))])
|
|
|
|
|
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
|
|
|
|
|
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (hasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 0)))
|
|
|
|
|
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x01\x00\x05pasta")])
|
|
|
|
|
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (hasheq 'name "pasta"
|
|
|
|
|
'version 0)))
|
|
|
|
|
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x01\x01\x09ice cream\x01")])
|
|
|
|
|
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (hasheq 'name "ice cream"
|
|
|
|
|
'isDessert 1
|
|
|
|
|
'version 1))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
; it 'should support process hook', ->
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
(set-field! post-decode struct (λ (o stream ctx) (ref-set! o 'processed "true") o))
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
|
|
|
|
|
(check-equal? (dump (decode struct)) (hasheq 'name "roxyb"
|
|
|
|
|
'processed "true"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 0))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
; describe 'size', ->
|
|
|
|
|
; it 'should compute the correct size', ->
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
|
|
|
|
|
(check-equal? (size struct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 0)) 8)
|
|
|
|
|
|
|
|
|
|
(check-equal? (size struct (mhasheq 'name "roxyb 🤘"
|
|
|
|
|
'gender 0
|
|
|
|
|
'age 21
|
|
|
|
|
'version 1)) 14))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
; it 'should throw for unknown version', ->
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
|
|
|
|
|
(check-exn exn:fail:contract? (λ () (size struct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 5)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
; it 'should support common header block', ->
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
'header (dictify 'age uint8
|
|
|
|
|
'alive uint8)
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii))
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
|
|
|
|
|
(check-equal? (size struct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'alive 1
|
|
|
|
|
'version 0)) 9)
|
|
|
|
|
|
|
|
|
|
(check-equal? (size struct (mhasheq 'name "roxyb 🤘"
|
|
|
|
|
'gender 0
|
|
|
|
|
'age 21
|
|
|
|
|
'alive 1
|
|
|
|
|
'version 1)) 15))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; it 'should compute the correct size with pointers', ->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'ptr (+Pointer uint8 (+StringT uint8)))))])
|
|
|
|
|
|
|
|
|
|
(check-equal? (size struct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 1
|
|
|
|
|
'ptr "hello")) 15))
|
|
|
|
|
|
|
|
|
|
(test-case
|
|
|
|
|
"decode should throw for unknown version"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x05\x05roxyb\x15")])
|
|
|
|
|
(check-exn exn:fail:contract? (λ () (decode vstruct))))))
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
; it 'should throw if no value is given', ->
|
|
|
|
|
(test-case
|
|
|
|
|
"decode should support common header block"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
'header (dictify 'age uint8
|
|
|
|
|
'alive uint8)
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii))
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x00\x15\x01\x05roxyb")])
|
|
|
|
|
(check-equal? (dump (decode vstruct)) '((version . 0) (name . "roxyb") (age . 21) (alive . 1))))
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x15\x01\x0aroxyb 🤘\x00"))])
|
|
|
|
|
(check-equal? (dump (decode vstruct)) '((version . 1)
|
|
|
|
|
(gender . 0)
|
|
|
|
|
(name . "roxyb 🤘")
|
|
|
|
|
(age . 21)
|
|
|
|
|
(alive . 1))))))
|
|
|
|
|
|
|
|
|
|
(test-case
|
|
|
|
|
"decode should support parent version key"
|
|
|
|
|
(let ([vstruct (+xversioned-struct 'version
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x15")])
|
|
|
|
|
(check-equal? (dump (decode vstruct #:parent (mhash 'version 0)))
|
|
|
|
|
'((version . 0) (age . 21) (name . "roxyb"))))
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x0aroxyb 🤘\x15\x00"))])
|
|
|
|
|
(check-equal? (dump (decode vstruct #:parent (mhash 'version 1)))
|
|
|
|
|
'((version . 1) (age . 21) (name . "roxyb 🤘") (gender . 0))))))
|
|
|
|
|
|
|
|
|
|
(test-case
|
|
|
|
|
"decode should support sub versioned structs"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8))
|
|
|
|
|
1 (dictify 'name (+xstring uint8)
|
|
|
|
|
'isDessert uint8)))))])
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
|
|
|
|
|
(check-equal? (dump (decode vstruct #:parent (mhash 'version 0)))
|
|
|
|
|
'((version . 0) (age . 21) (name . "roxyb"))))
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x01\x00\x05pasta")])
|
|
|
|
|
(check-equal? (dump (decode vstruct #:parent (mhash 'version 0)))
|
|
|
|
|
'((version . 0) (name . "pasta"))))
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x01\x01\x09ice cream\x01")])
|
|
|
|
|
(check-equal? (dump (decode vstruct #:parent (mhash 'version 0)))
|
|
|
|
|
'((version . 1) (isDessert . 1) (name . "ice cream"))))))
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
|
|
|
|
|
(check-exn exn:fail:contract? (λ () (size struct))))
|
|
|
|
|
(test-case
|
|
|
|
|
"decode should support process hook"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
(set-xversioned-struct-post-decode! vstruct (λ (o stream ctx) (dict-set! o 'processed "true") o))
|
|
|
|
|
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
|
|
|
|
|
(check-equal? (dump (decode vstruct))
|
|
|
|
|
'((processed . "true") (version . 0) (age . 21) (name . "roxyb"))))))
|
|
|
|
|
|
|
|
|
|
(test-case
|
|
|
|
|
"size should compute the correct size"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
(check-equal? (size vstruct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 0)) 8)
|
|
|
|
|
(check-equal? (size vstruct (mhasheq 'name "roxyb 🤘"
|
|
|
|
|
'gender 0
|
|
|
|
|
'age 21
|
|
|
|
|
'version 1)) 14)))
|
|
|
|
|
|
|
|
|
|
(test-case
|
|
|
|
|
"size should throw for unknown version"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
(check-exn exn:fail:contract? (λ () (size vstruct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 5))))))
|
|
|
|
|
|
|
|
|
|
; describe 'encode', ->
|
|
|
|
|
; it 'should encode objects to buffers', (done) ->
|
|
|
|
|
(test-case
|
|
|
|
|
"size should support common header block"
|
|
|
|
|
(let ([struct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
'header (dictify 'age uint8
|
|
|
|
|
'alive uint8)
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii))
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
(check-equal? (size struct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'alive 1
|
|
|
|
|
'version 0)) 9)
|
|
|
|
|
(check-equal? (size struct (mhasheq 'name "roxyb 🤘"
|
|
|
|
|
'gender 0
|
|
|
|
|
'age 21
|
|
|
|
|
'alive 1
|
|
|
|
|
'version 1)) 15)))
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))]
|
|
|
|
|
[port (open-output-bytes)])
|
|
|
|
|
(encode struct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 0) port)
|
|
|
|
|
(encode struct (mhasheq 'name "roxyb 🤘"
|
|
|
|
|
'age 21
|
|
|
|
|
'gender 0
|
|
|
|
|
'version 1) port)
|
|
|
|
|
(check-equal? (dump port) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00")))
|
|
|
|
|
(test-case
|
|
|
|
|
"size should compute the correct size with pointers"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'ptr (+xpointer uint8 (+xstring uint8)))))])
|
|
|
|
|
(check-equal? (size vstruct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 1
|
|
|
|
|
'ptr "hello")) 15)))
|
|
|
|
|
|
|
|
|
|
(test-case
|
|
|
|
|
"size should throw if no value is given"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))])
|
|
|
|
|
(check-exn exn:fail:contract? (λ () (size vstruct)))))
|
|
|
|
|
|
|
|
|
|
;
|
|
|
|
|
; it 'should throw for unknown version', ->
|
|
|
|
|
(test-case
|
|
|
|
|
"encode should encode objects to buffers"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))]
|
|
|
|
|
[op (open-output-bytes)])
|
|
|
|
|
(encode vstruct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 0) op)
|
|
|
|
|
(encode vstruct (mhasheq 'name "roxyb 🤘"
|
|
|
|
|
'age 21
|
|
|
|
|
'gender 0
|
|
|
|
|
'version 1) op)
|
|
|
|
|
(check-equal? (dump op) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00"))))
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))]
|
|
|
|
|
[port (open-output-bytes)])
|
|
|
|
|
(check-exn exn:fail:contract? (λ () (encode struct port (mhasheq 'name "roxyb"
|
|
|
|
|
(test-case
|
|
|
|
|
"encode should throw for unknown version"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))]
|
|
|
|
|
[op (open-output-bytes)])
|
|
|
|
|
(check-exn exn:fail:contract? (λ () (encode vstruct op (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 5)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; it 'should support common header block', (done) ->
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
'header (dictify 'age uint8
|
|
|
|
|
'alive uint8)
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii))
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'gender uint8)))]
|
|
|
|
|
[stream (open-output-bytes)])
|
|
|
|
|
|
|
|
|
|
(encode struct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'alive 1
|
|
|
|
|
'version 0) stream)
|
|
|
|
|
|
|
|
|
|
(encode struct (mhasheq 'name "roxyb 🤘"
|
|
|
|
|
'gender 0
|
|
|
|
|
'age 21
|
|
|
|
|
'alive 1
|
|
|
|
|
'version 1) stream)
|
|
|
|
|
|
|
|
|
|
(check-equal? (dump stream) (string->bytes/utf-8 "\x00\x15\x01\x05roxyb\x01\x15\x01\x0aroxyb 🤘\x00")))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; it 'should encode pointer data after structure', (done) ->
|
|
|
|
|
'version 5))))))
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'ptr (+Pointer uint8 (+StringT uint8)))))]
|
|
|
|
|
[stream (open-output-bytes)])
|
|
|
|
|
(encode struct (mhasheq 'version 1
|
|
|
|
|
'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'ptr "hello") stream)
|
|
|
|
|
|
|
|
|
|
(check-equal? (dump stream) (string->bytes/utf-8 "\x01\x05roxyb\x15\x09\x05hello")))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; it 'should support preEncode hook', (done) ->
|
|
|
|
|
(test-case
|
|
|
|
|
"encode should support common header block"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
'header (dictify 'age uint8
|
|
|
|
|
'alive uint8)
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii))
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'gender uint8)))]
|
|
|
|
|
[op (open-output-bytes)])
|
|
|
|
|
(encode vstruct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'alive 1
|
|
|
|
|
'version 0) op)
|
|
|
|
|
(encode vstruct (mhasheq 'name "roxyb 🤘"
|
|
|
|
|
'gender 0
|
|
|
|
|
'age 21
|
|
|
|
|
'alive 1
|
|
|
|
|
'version 1) op)
|
|
|
|
|
(check-equal? (dump op) (string->bytes/utf-8 "\x00\x15\x01\x05roxyb\x01\x15\x01\x0aroxyb 🤘\x00"))))
|
|
|
|
|
|
|
|
|
|
(let ([struct (+VersionedStruct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+StringT uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+StringT uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))]
|
|
|
|
|
[stream (open-output-bytes)])
|
|
|
|
|
(set-field! pre-encode struct (λ (val port) (ref-set! val 'version (if (ref val 'gender) 1 0)) val))
|
|
|
|
|
(encode struct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 0) stream)
|
|
|
|
|
(encode struct (mhasheq 'name "roxyb 🤘"
|
|
|
|
|
'age 21
|
|
|
|
|
'gender 0) stream)
|
|
|
|
|
(check-equal? (dump stream) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00")))
|
|
|
|
|
(test-case
|
|
|
|
|
"encode should encode pointer data after structure"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'ptr (+xpointer uint8 (+xstring uint8)))))]
|
|
|
|
|
[op (open-output-bytes)])
|
|
|
|
|
(encode vstruct (mhasheq 'version 1
|
|
|
|
|
'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'ptr "hello") op)
|
|
|
|
|
|
|
|
|
|
(check-equal? (dump op) (string->bytes/utf-8 "\x01\x05roxyb\x15\x09\x05hello"))))
|
|
|
|
|
|
|
|
|
|
|#
|
|
|
|
|
(test-case
|
|
|
|
|
"encode should support preEncode hook"
|
|
|
|
|
(let ([vstruct (+xversioned-struct uint8
|
|
|
|
|
(dictify
|
|
|
|
|
0 (dictify 'name (+xstring uint8 'ascii)
|
|
|
|
|
'age uint8)
|
|
|
|
|
1 (dictify 'name (+xstring uint8 'utf8)
|
|
|
|
|
'age uint8
|
|
|
|
|
'gender uint8)))]
|
|
|
|
|
[stream (open-output-bytes)])
|
|
|
|
|
(set-xversioned-struct-pre-encode! vstruct
|
|
|
|
|
(λ (val port) (dict-set! val 'version (if (dict-ref val 'gender #f) 1 0)) val))
|
|
|
|
|
(encode vstruct (mhasheq 'name "roxyb"
|
|
|
|
|
'age 21
|
|
|
|
|
'version 0) stream)
|
|
|
|
|
(encode vstruct (mhasheq 'name "roxyb 🤘"
|
|
|
|
|
'age 21
|
|
|
|
|
'gender 0) stream)
|
|
|
|
|
(check-equal? (dump stream) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00"))))
|