From e90a790963a66fb5af66b55ae3cc16146b2c2845 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Wed, 21 Aug 2019 22:18:21 +0100 Subject: [PATCH] First real running tests with the new design, and several concomitant fixes and new tests --- implementations/racket/preserves/main.rkt | 196 ++++++++++++++-------- tests/samples.txt | 35 ++-- 2 files changed, 145 insertions(+), 86 deletions(-) diff --git a/implementations/racket/preserves/main.rkt b/implementations/racket/preserves/main.rkt index 4698acd..b6ecde5 100644 --- a/implementations/racket/preserves/main.rkt +++ b/implementations/racket/preserves/main.rkt @@ -4,8 +4,11 @@ (provide (struct-out stream-of) (struct-out record) (struct-out annotated) + annotate strip-annotations + strip-annotations-proc peel-annotations + peel-annotations-proc read-preserve read-preserve-syntax string->preserve @@ -52,7 +55,14 @@ (with-handlers [(exn:fail:contract? (lambda (e) (record label fields)))] (apply make-prefab-struct label fields))) -(define (strip-annotations v #:depth [depth +inf.0]) +(define (annotate v . as) + (match v + [(annotated annotations srcloc item) + (annotated (append as annotations) srcloc item)] + [item + (annotated as #f item)])) + +(define (strip-annotations-proc v #:depth [depth +inf.0]) (let walk* ((v v) (depth depth)) (define next-depth (- depth 1)) (define (walk v) (walk* v next-depth)) @@ -72,8 +82,16 @@ [_ item])] [_ v])))) -(define (peel-annotations v) - (strip-annotations v #:depth 1)) +(define (peel-annotations-proc v) + (strip-annotations-proc v #:depth 1)) + +(define-match-expander strip-annotations + (syntax-rules () [(_ pat extra ...) (app (lambda (v) (strip-annotations-proc v extra ...)) pat)]) + (syntax-rules () [(_ args ...) (strip-annotations-proc args ...)])) + +(define-match-expander peel-annotations + (syntax-rules () [(_ pat extra ...) (app (lambda (v) (peel-annotations-proc v extra ...)) pat)]) + (syntax-rules () [(_ args ...) (peel-annotations-proc args ...)])) (define current-value->placeholder (make-parameter (lambda (v) #f))) (define current-placeholder->value (make-parameter (lambda (v) (void)))) @@ -96,7 +114,7 @@ (define (decode-syntax bs #:on-short [on-short (default-on-short bs)] [on-fail (default-on-fail bs)]) - (decode #:read-syntax? #t #:on-short on-short #:on-fail on-fail)) + (decode bs on-fail #:read-syntax? #t #:on-short on-short)) (define-syntax wire-value (syntax-rules () @@ -777,7 +795,7 @@ (module+ test (require rackunit) (require racket/runtime-path) - (require (for-syntax racket syntax/srcloc)) + (require syntax/srcloc) (check-equal? (bit-string->bytes (bit-string (0 :: bits 4) (0 :: (wire-length)))) (bytes 0)) (check-equal? (bit-string->bytes (bit-string (0 :: bits 4) (3 :: (wire-length)))) (bytes 3)) @@ -811,34 +829,37 @@ void) 'short)) (error 'd "~a-byte prefix of ~v does not read as short" i bs))) - (decode bs - #:on-short (lambda () 'short) - void)) + (decode-syntax bs + #:on-short (lambda () 'short) + void)) - (define-syntax (cross-check stx) - (syntax-case stx () - ((_ text v (b ...)) - #'(let ((val v)) (cross-check text v v (b ...)))) - ((_ text forward back (b ...)) - #`(let ((loc #,(source-location->string #'forward))) - (check-equal? (string->preserve text) back loc) - (check-equal? (d (encode forward)) back loc) - (check-equal? (d (encode back)) back loc) - (check-equal? (d (expected b ...)) back loc) - (check-equal? (encode forward) (expected b ...) loc) - )))) + (define (d-strip bs) + (strip-annotations (d bs))) - (define-syntax (cross-check/nondeterministic stx) - (syntax-case stx () - ((_ text v (b ...)) - #'(let ((val v)) (cross-check/nondeterministic text v v (b ...)))) - ((_ text forward back (b ...)) - #`(let ((loc #,(source-location->string #'forward))) - (check-equal? (string->preserve text) back loc) - (check-equal? (d (encode forward)) back loc) - (check-equal? (d (encode back)) back loc) - (check-equal? (d (expected b ...)) back loc) - )))) + ;; (define-syntax (cross-check stx) + ;; (syntax-case stx () + ;; ((_ text v (b ...)) + ;; #'(let ((val v)) (cross-check text v v (b ...)))) + ;; ((_ text forward back (b ...)) + ;; #`(let ((loc #,(source-location->string #'forward))) + ;; (check-equal? (string->preserve text) back loc) + ;; (check-equal? (d (encode forward)) back loc) + ;; (check-equal? (d (encode back)) back loc) + ;; (check-equal? (d (expected b ...)) back loc) + ;; (check-equal? (encode forward) (expected b ...) loc) + ;; )))) + + ;; (define-syntax (cross-check/nondeterministic stx) + ;; (syntax-case stx () + ;; ((_ text v (b ...)) + ;; #'(let ((val v)) (cross-check/nondeterministic text v v (b ...)))) + ;; ((_ text forward back (b ...)) + ;; #`(let ((loc #,(source-location->string #'forward))) + ;; (check-equal? (string->preserve text) back loc) + ;; (check-equal? (d (encode forward)) back loc) + ;; (check-equal? (d (encode back)) back loc) + ;; (check-equal? (d (expected b ...)) back loc) + ;; )))) (struct discard () #:prefab) (struct capture (detail) #:prefab) @@ -852,7 +873,6 @@ (struct titled person (title) #:prefab) (struct asymmetric (forward back)) - (struct nondeterministic (value)) (define samples-txt-expected (hash 'record1 (capture (discard)) @@ -898,7 +918,11 @@ 'string4 "abc\u6c34\u6C34\\/\"\b\f\n\r\txyz" 'bytes13 #"abc\x6c\x34\xf0\\/\"\b\f\n\r\txyz" 'string5 "\U0001D11E" - 'list2 '("abc" "def") + 'list2 (asymmetric (stream-of 'sequence + (sequence->generator + (list (stream-of 'string (sequence->generator '(#"abc"))) + (stream-of 'string (sequence->generator '(#"def")))))) + '("abc" "def")) 'record1 (capture (discard)) 'record2 (observe (speak (discard) (capture (discard)))) 'record3 (titled 101 "Blackwell" (date 1821 2 3) "Dr") @@ -913,35 +937,41 @@ "b" #t '(1 2 3) #"c" (hash 'first-name "Elizabeth") (hash 'surname "Blackwell")) - 'rfc8259-example1 (nondeterministic - (hash "Image" - (hash "Width" 800 - "Height" 600 - "Title" "View from 15th Floor" - "Thumbnail" (hash "Url" "http://www.example.com/image/481989943" - "Height" 125 - "Width" 100) - "Animated" #f - "IDs" (list 116 943 234 38793)))) - 'rfc8259-example2 (nondeterministic - (list (hash - "precision" "zip" - "Latitude" 37.7668 - "Longitude" -122.3959 - "Address" "" - "City" "SAN FRANCISCO" - "State" "CA" - "Zip" "94107" - "Country" "US") - (hash - "precision" "zip" - "Latitude" 37.371991 - "Longitude" -122.026020 - "Address" "" - "City" "SUNNYVALE" - "State" "CA" - "Zip" "94085" - "Country" "US"))) + 'rfc8259-example1 (hash "Image" + (hash "Width" 800 + "Height" 600 + "Title" "View from 15th Floor" + "Thumbnail" (hash "Url" "http://www.example.com/image/481989943" + "Height" 125 + "Width" 100) + "Animated" #f + "IDs" (list 116 943 234 38793))) + 'rfc8259-example2 (list (hash + "precision" "zip" + "Latitude" 37.7668 + "Longitude" -122.3959 + "Address" "" + "City" "SAN FRANCISCO" + "State" "CA" + "Zip" "94107" + "Country" "US") + (hash + "precision" "zip" + "Latitude" 37.371991 + "Longitude" -122.026020 + "Address" "" + "City" "SUNNYVALE" + "State" "CA" + "Zip" "94085" + "Country" "US")) + 'annotation1 (asymmetric (annotate 9 "abc") 9) + 'annotation2 (asymmetric (annotate (list '() (annotate '() "x")) "abc" "def") '(() ())) + 'annotation3 (asymmetric (annotate 5 (annotate 2 1) (annotate 4 3)) 5) + 'annotation4 (asymmetric (hash (annotate 'a 'ak) (annotate 1 'av) + (annotate 'b 'bk) (annotate 2 'bv)) + (hash 'a 1 'b 2)) + 'annotation5 (asymmetric (annotate `#s(R ,(annotate 'f 'af)) 'ar) `#s(R f)) + 'annotation6 (asymmetric (record (annotate 'R 'ar) (list (annotate 'f 'af))) `#s(R f)) )) (define-runtime-path tests-path "../../../tests") @@ -951,12 +981,38 @@ (port-count-lines! p) (read-preserve-syntax p #:source path))))) (local-require racket/pretty) - (for [((t-name t) (in-hash (annotated-item tests)))] - (newline) - (newline) - (write-preserve t #:indent #f) - (newline) - (newline) - (pretty-print (list (peel-annotations t-name) - (peel-annotations t))))) + (define placeholder->value-map + (or (for/or [(a* (annotated-annotations tests))] + (match (strip-annotations a*) + [`#s(ExpectedPlaceholderMapping ,p->v) p->v] + [_ #f])) + (hash))) + (define value->placeholder-map + (for/hash [((k v) (in-hash placeholder->value-map))] + (values v k))) + (parameterize + ((current-value->placeholder (lambda (v) (hash-ref value->placeholder-map v #f))) + (current-placeholder->value (lambda (p) (hash-ref placeholder->value-map p void)))) + (for [((t-name* t*) (in-hash (annotated-item tests)))] + (define t-name (strip-annotations t-name*)) + (define loc (format "Test case '~a' (~a)" t-name (source-location->string (annotated-srcloc t*)))) + (displayln loc) + (match t* + [(peel-annotations `#s(Test ,(strip-annotations binary-form) ,annotated-text-form)) + (define text-form (strip-annotations annotated-text-form)) + (define-values (forward back) + (match (hash-ref samples-txt-expected t-name text-form) + [(asymmetric f b) (values f b)] + [v (values v v)])) + (check-equal? text-form back loc) + (check-equal? (d-strip (encode text-form)) back loc) + (check-equal? (d-strip (encode forward)) back loc) + (check-equal? (d-strip binary-form) back loc) + (check-equal? (d binary-form) annotated-text-form loc) + (check-equal? (encode forward) binary-form loc) + (check-equal? (encode annotated-text-form) binary-form loc)] + [_ + (write-preserve t* #:indent #f) + (newline)]))) + ) ) diff --git a/tests/samples.txt b/tests/samples.txt index 01f18af..dcb6029 100644 --- a/tests/samples.txt +++ b/tests/samples.txt @@ -1,15 +1,18 @@ @ -@"Expects placeholder mapping of:" -@"{ 0: discard, 1: capture, 2: observe }" +@ { annotation1: annotation2: annotation3: - annotation4: + annotation4: annotation5: > annotation6: > - bytes1: + bytes1: bytes2: bytes3: bytes4: @@ -24,7 +27,7 @@ bytes13: dict0: - dict1: + dict1: dict2: @"Missing close brace" dict2a: @"Missing close brace" dict3: @"Duplicate key" @@ -56,13 +59,13 @@ int65536: int131072: list0: - list1: - list2: - list3: + list1: + list2: + list3: list4: list4a: list5: - list6: + list6: list7: list8: @"Missing close bracket" placeholder0: @@ -79,8 +82,8 @@ record9: @"Missing record label" "> record10: @"Missing close-angle-bracket" set0: - set1: - set1a: + set1: + set1a: set2: @"Missing close brace" set2a: @"Missing close brace" stream1: @"Chunk must be bytes" @@ -92,14 +95,14 @@ stream7: @"Missing end byte" stream8: @"Missing element" string0: - string0a: - string1: - string2: + string0a: + string1: + string2: string3: string4: string5: symbol0: - symbol1: + symbol1: symbol2: value1: value2: