You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
typesetting/pitfall/xenomorph/test/versioned-struct-test.rkt

340 lines
14 KiB
Racket

7 years ago
#lang reader (submod "racket.rkt" reader)
#|
approximates
https://github.com/mbutterick/restructure/blob/master/test/VersionedStruct.coffee
|#
;describe 'VersionedStruct', ->
; describe 'decode', ->
; it 'should get version from number type', ->
(let ([struct (+VersionedStruct uint8
(dictify
0 (dictify 'name (+StringT uint8 'ascii)
'age uint8)
1 (dictify 'name (+StringT uint8 'utf8)
'age uint8
'gender uint8)))])
7 years ago
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
7 years ago
(check-equal? (dump (decode struct)) (hasheq 'name "roxyb"
'age 21
'version 0)))
7 years ago
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x0aroxyb 🤘\x15\x00"))])
7 years ago
(check-equal? (dump (decode struct)) (hasheq 'name "roxyb 🤘"
'age 21
'version 1
'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)))])
7 years ago
(parameterize ([current-input-port (open-input-bytes #"\x05\x05roxyb\x15")])
7 years ago
(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)))])
7 years ago
(parameterize ([current-input-port (open-input-bytes #"\x00\x15\x01\x05roxyb")])
7 years ago
(check-equal? (dump (decode struct)) (hasheq 'name "roxyb"
'age 21
'alive 1
'version 0)))
7 years ago
7 years ago
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x01\x15\x01\x0aroxyb 🤘\x00"))])
7 years ago
(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)))])
7 years ago
(parameterize ([current-input-port (open-input-bytes #"\x05roxyb\x15")])
7 years ago
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (hasheq 'name "roxyb"
'age 21
'version 0)))
7 years ago
7 years ago
(parameterize ([current-input-port (open-input-bytes (string->bytes/utf-8 "\x0aroxyb 🤘\x15\x00"))])
7 years ago
(check-equal? (dump (decode struct #:parent (mhash 'version 1))) (hasheq 'name "roxyb 🤘"
'age 21
'version 1
'gender 0))))
7 years ago
;
; 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)))))])
7 years ago
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
7 years ago
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (hasheq 'name "roxyb"
'age 21
'version 0)))
7 years ago
(parameterize ([current-input-port (open-input-bytes #"\x01\x00\x05pasta")])
7 years ago
(check-equal? (dump (decode struct #:parent (mhash 'version 0))) (hasheq 'name "pasta"
'version 0)))
7 years ago
(parameterize ([current-input-port (open-input-bytes #"\x01\x01\x09ice cream\x01")])
7 years ago
(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)))])
7 years ago
(set-field! post-decode struct (λ (o stream ctx) (ref-set! o 'processed "true") o))
7 years ago
(parameterize ([current-input-port (open-input-bytes #"\x00\x05roxyb\x15")])
7 years ago
(check-equal? (dump (decode struct)) (hasheq 'name "roxyb"
'processed "true"
'age 21
'version 0))))
7 years ago
;
; 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)))])
7 years ago
(check-equal? (size struct (mhasheq 'name "roxyb"
7 years ago
'age 21
'version 0)) 8)
7 years ago
(check-equal? (size struct (mhasheq 'name "roxyb 🤘"
7 years ago
'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)))])
7 years ago
(check-exn exn:fail:contract? (λ () (size struct (mhasheq 'name "roxyb"
7 years ago
'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)))])
7 years ago
(check-equal? (size struct (mhasheq 'name "roxyb"
7 years ago
'age 21
'alive 1
'version 0)) 9)
7 years ago
(check-equal? (size struct (mhasheq 'name "roxyb 🤘"
7 years ago
'gender 0
'age 21
'alive 1
'version 1)) 15))
7 years ago
; 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)))))])
7 years ago
(check-equal? (size struct (mhasheq 'name "roxyb"
7 years ago
'age 21
'version 1
'ptr "hello")) 15))
;
; it 'should throw if no value is given', ->
7 years ago
(let ([struct (+VersionedStruct uint8
(dictify
0 (dictify 'name (+StringT uint8 'ascii)
'age uint8)
1 (dictify 'name (+StringT uint8 'utf8)
'age uint8
'gender uint8)))])
7 years ago
(check-exn exn:fail:contract? (λ () (size struct))))
7 years ago
; describe 'encode', ->
; it 'should encode objects to buffers', (done) ->
(let ([struct (+VersionedStruct uint8
(dictify
0 (dictify 'name (+StringT uint8 'ascii)
'age uint8)
1 (dictify 'name (+StringT uint8 'utf8)
'age uint8
'gender uint8)))]
7 years ago
[port (open-output-bytes)])
7 years ago
(encode struct (mhasheq 'name "roxyb"
7 years ago
'age 21
'version 0) port)
7 years ago
(encode struct (mhasheq 'name "roxyb 🤘"
7 years ago
'age 21
'gender 0
'version 1) port)
7 years ago
(check-equal? (dump port) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00")))
;
; 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)))]
7 years ago
[port (open-output-bytes)])
7 years ago
(check-exn exn:fail:contract? (λ () (encode struct port (mhasheq 'name "roxyb"
7 years ago
'age 21
'version 5)))))
7 years ago
; 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)))]
7 years ago
[stream (open-output-bytes)])
7 years ago
(encode struct (mhasheq 'name "roxyb"
7 years ago
'age 21
'alive 1
'version 0) stream)
7 years ago
(encode struct (mhasheq 'name "roxyb 🤘"
7 years ago
'gender 0
'age 21
'alive 1
'version 1) stream)
7 years ago
(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) ->
(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)))))]
7 years ago
[stream (open-output-bytes)])
(encode struct (mhasheq 'version 1
7 years ago
'name "roxyb"
7 years ago
'age 21
'ptr "hello") stream)
7 years ago
(check-equal? (dump stream) (string->bytes/utf-8 "\x01\x05roxyb\x15\x09\x05hello")))
7 years ago
; it 'should support preEncode hook', (done) ->
(let ([struct (+VersionedStruct uint8
(dictify
0 (dictify 'name (+StringT uint8 'ascii)
'age uint8)
1 (dictify 'name (+StringT uint8 'utf8)
'age uint8
'gender uint8)))]
7 years ago
[stream (open-output-bytes)])
(set-field! pre-encode struct (λ (val port) (ref-set! val 'version (if (ref val 'gender) 1 0)) val))
7 years ago
(encode struct (mhasheq 'name "roxyb"
7 years ago
'age 21
'version 0) stream)
7 years ago
(encode struct (mhasheq 'name "roxyb 🤘"
7 years ago
'age 21
'gender 0) stream)
7 years ago
(check-equal? (dump stream) (string->bytes/utf-8 "\x00\x05roxyb\x15\x01\x0aroxyb 🤘\x15\x00")))