Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
[[tags: egg]] == SRFI 252 Property Testing [[toc:]] == Description A Chicken port of the reference implementation of [[http://srfi.schemers.org/srfi-252/srfi-252.html|SRFI 252]]. Note that this egg depends on the [[srfi-64]] egg, not the [[test]] egg. == Authors SRFI author: Antero Mejr Maintainer: Peter McGoron == Repository https://software.mcgoron.com/peter/srfi-252-egg == Requirements * [[r7rs]] * [[srfi-1]] * [[srfi-64]] * [[srfi-158]] * [[srfi-194]] * [[srfi-143]] * [[srfi-144]] == API The following is from the SRFI. == Testing forms It is an error to invoke the testing procedures if there is no current test runner. <procedure>(test-property property generator-list [runs])</procedure> Run a property test. The {{property}} argument is a predicate procedure with an arity equal to the length of the {{generator-list}} argument. The {{generator-list}} argument must be a proper list containing SRFI 158 generators. The {{property}} procedure must be applied to the values returned by the {{generator-list}} such that the value generated by the car position of the {{generator-list}} will be the first argument to {{property}}, and so on. The {{runs}} argument, if provided, must be a non-negative integer. This argument specifies how many times the property will be tested with newly generated inputs. If not provided, the implementation may choose how many times to run the test. It is an error if any generator in {{generator-list}} is exhausted before the specified number of runs is completed. Property tests can be named by placing them inside an SRFI 64 test group. <procedure>(test-property-expect-fail property generator-list [runs])</procedure> Run a property test that is expected to fail for all inputs. This only affects test reporting, not test execution. <procedure>(test-property-skip property generator-list [runs])</procedure> Do not run a property test. The active test-runner will skip the test, and no runs will be performed. <procedure>(test-property-error property generator-list [runs])</procedure> Run a property test that is expected to raise an exception for all inputs. The exception raised may be of any type. <procedure>(test-property-error-type error-type property generator-list [runs])</procedure> Run a property test that is expected to raise a specific type of exception for all inputs. In order for the test to pass, the exception raised must match the error type specified by the error-type argument. The error type may be implementation-specific, or one specified in SRFI 36. === Test runner <procedure>(property-test-runner)</procedure> Creates a SRFI 64 test-runner. This is just {{(test-runner-create)}}. === Generators The generator procedures in this SRFI must be implemented using SRFI 194, such that the {{current-random-source}} parameter can be configured to facilitate deterministic generation of property test inputs. <procedure>(boolean-generator)</procedure> Create an infinite generator that returns #t and #f. The generator should return the sequence (#t #f) first, then a uniformly random distribution of #t and #f. <procedure>(bytevector-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{bytevector?}} predicate. The generator should return an empty bytevector first, then a series of bytevectors with uniformly randomly distributed contents and lengths. The maximum length of the generated bytevectors is chosen by the implementation. <procedure>(char-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{char?}} predicate. The generator should return the character {{#\null}} first, then a uniformly random distribution of characters. <enscript language="scheme"> (define char-gen (char-generator)) (char-gen) ; => #\null (char-gen) ; => #\something </enscript> <procedure>(string-generator)</procedure> Create an infinite generator that returns strings. The generator should return an empty string first, then a series of strings with uniformly randomly distributed contents and lengths. The maximum length of the generated strings is chosen by the implementation. <enscript language="scheme"> (define string-gen (string-generator)) (string-gen) ; => "" (string-gen) ; => "..." </enscript> <procedure>(symbol-generator)</procedure> Create an infinite generator that returns symbols. The generator should return the empty symbol first, then a series of randomized symbols. <enscript language="scheme"> (define symbol-gen (symbol-generator)) (symbol-gen) ; => || (symbol-gen) ; => 'something </enscript> === Number generators The ranges of the random numbers returned by the numeric generators below are defined by the implementation. Applications that require a specific range of numeric test inputs are encouraged to create custom generators using SRFI 158. <procedure>(complex-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{complex?}} predicate. The real and imaginary parts of the complex numbers may be exact or inexact. The generator should return a uniformly random sampling of the values generated by exact-complex-generator and inexact-complex-generator. <enscript language="scheme"> (define complex-gen (complex-generator)) (complex-gen) ; => 0 or 0.0 </enscript> <procedure>(integer-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{integer?}} predicate. The generator should return a uniformly random sampling of the values generated by {{exact-integer-generator}} and {{inexact-integer-generator}}. <enscript language="scheme"> (define integer-gen (integer-generator)) (integer-gen) ; => 0 or 0.0 </enscript> <procedure>(number-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{number?}} predicate. The generator should return a uniformly random sampling of the values generated by {{exact-number-generator}} and {{inexact-number-generator}}. <enscript language="scheme"> (define number-gen (number-generator)) (number-gen) ; => 0 or 0.0 </enscript> <procedure>(rational-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{rational?}} predicate. The generator should return a uniformly random sampling of the values generated by {{exact-rational-generator}} and {{inexact-rational-generator}}. <enscript language="scheme"> (define rational-gen (rational-generator)) (rational-gen) ; => 0 or 0.0 </enscript> <procedure>(real-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{real?}} predicate. The generator should return a uniformly random sampling of the values generated by {{exact-real-generator}} and {{inexact-real-generator}}. <enscript language="scheme"> (define real-gen (real-generator)) (real-gen) ; => 0 or 0.0 </enscript> Exact number generators <procedure>(exact-complex-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{exact?}} and {{complex?}} predicates. The real and imaginary parts of the complex numbers must be exact. The generator should return the sequence <enscript> 0 1 -1 1/2 -1/2 0+i 0-i 1+i 1-i -1+i -1-i 1/2+1/2i 1/2-1/2i -1/2+1/2i -1/2-1/2i </enscript> first, then a uniformly random distribution of exact complex numbers. Elements of the above sequence may be omitted if they are not distinguished in the implementation. If the implementation does not support the {{exact-complex}} feature, it is an error to call this procedure. <enscript language="scheme"> (define exact-complex-gen (exact-complex-generator)) (exact-complex-gen) ; => 0 </enscript> <procedure>(exact-integer-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{exact?}} and {{integer?}} predicates. The generator should return the sequence <enscript> 0 1 -1 </enscript> first, then a uniformly random distribution of exact integers. Elements of the above sequence may be omitted if they are not distinguished in the implementation. <enscript language="scheme"> (define exact-int-gen (exact-integer-generator)) (exact-int-gen) ; => 0 </enscript> <procedure>(exact-integer-complex-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{exact?}} and {{complex?}} predicates. The real and imaginary parts of the complex numbers must be exact integers. The generator should return the sequence <enscript> 0 1 -1 0+i 0-i 1+i 1-i -1+i -1-i </enscript> first, then a uniformly random distribution of exact complex numbers with integer components. Elements of the above sequence may be omitted if they are not distinguished in the implementation. <enscript language="scheme"> (define exact-int-comp-gen (exact-integer-complex-generator)) (exact-int-comp-gen) ; => 0 </enscript> <procedure>(exact-number-generator)</procedure> Create an infinite generator that returns objects that fulfill the exact? predicate. The generator should return the sequence <enscript> 0 1 -1 1/2 -1/2 0+i 0-i 1+i 1-i -1+i -1-i 1/2+1/2i 1/2-1/2i -1/2+1/2i -1/2-1/2i </enscript> first, then a uniformly random distribution of exact numbers. Elements of the above sequence may be omitted if they are not distinguished in the implementation. <enscript language="scheme"> (define exact-gen (exact-number-generator)) (exact-gen) ; => 0 </enscript> <procedure>(exact-rational-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{exact?}} and {{rational?}} predicates. The generator should return the sequence <enscript> 0 1 -1 1/2 -1/2 </enscript> first, then a uniformly random distribution of exact rational numbers. Elements of the above sequence may be omitted if they are not distinguished in the implementation. <enscript language="scheme"> (define exact-rational-gen (exact-rational-generator)) (exact-rational-gen) ; => 0 </enscript> <procedure>(exact-real-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{exact?}} and {{real?}} predicates. The generator should return the sequence <enscript> 0 1 -1 1/2 -1/2 </enscript> first, then a uniformly random distribution of exact real numbers. Elements of the above sequence may be omitted if they are not distinguished in the implementation. <enscript language="scheme"> (define exact-real-gen (exact-real-generator)) (exact-real-gen) ; => 0 </enscript> === Inexact number generators <procedure>(inexact-complex-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{inexact?}} and {{complex?}} predicates. The real and imaginary parts of the complex numbers must be inexact. The generator should return the sequence <enscript> 0.0 -0.0 0.5 -0.5 1.0 -1.0 0.0+1.0i 0.0-1.0i -0.0+1.0i -0.0-1.0i 0.5+0.5i 0.5-0.5i -0.5+0.5i -0.5-0.5i 1.0+1.0i 1.0-1.0i -1.0+1.0i -1.0-1.0i +inf.0+inf.0i +inf.0-inf.0i -inf.0+inf.0i -inf.0-inf.0i +nan.0+nan.0i +inf.0 -inf.0 +nan.0 </enscript> first, then a uniformly random distribution of inexact complex numbers. Elements of the above sequence may be omitted if they are not distinguished in the implementation. <enscript language="scheme"> (define inexact-complex-gen (inexact-complex-generator)) (inexact-complex-gen) ; => 0.0+0.0i </enscript> <procedure>(inexact-integer-generator)</procedure> Create an infinite generator that returns objects that fulfill the inexact? and integer? predicates. The generator should return the sequence <enscript> 0.0 -0.0 1.0 -1.0 </enscript> first, then a uniformly random distribution of inexact integers. Elements of the above sequence may be omitted if they are not distinguished in the implementation. <enscript language="scheme"> (define inexact-int-gen (inexact-integer-generator)) (inexact-int-gen) ; => 0.0 </enscript> <procedure>(inexact-number-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{inexact?}} predicate. The generator should return the sequence <enscript> 0.0 -0.0 0.5 -0.5 1.0 -1.0 0.0+1.0i 0.0-1.0i -0.0+1.0i -0.0-1.0i 0.5+0.5i 0.5-0.5i -0.5+0.5i -0.5-0.5i 1.0+1.0i 1.0-1.0i -1.0+1.0i -1.0-1.0i +inf.0+inf.0i +inf.0-inf.0i -inf.0+inf.0i -inf.0-inf.0i +nan.0+nan.0i +inf.0 -inf.0 +nan.0 </enscript> first, then a uniformly random distribution of inexact numbers. Elements of the above sequence may be omitted if they are not distinguished in the implementation. <enscript language="scheme"> (define inexact-gen (inexact-number-generator)) (inexact-gen) ; => 0.0 </enscript> <procedure>(inexact-rational-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{inexact?}} and {{rational?}} predicates. The generator should return the sequence <enscript> 0.0 -0.0 0.5 -0.5 1.0 -1.0 </enscript> first, then a uniformly random distribution of inexact rational numbers. Elements of the above sequence may be omitted if they are not distinguished in the implementation. <enscript language="scheme"> (define inexact-rational-gen (inexact-rational-generator)) (inexact-rational-gen) ; => 0.0 </enscript> <procedure>(inexact-real-generator)</procedure> Create an infinite generator that returns objects that fulfill the {{inexact?}} and {{real?}} predicates. The generator should return the sequence <enscript> 0.0 -0.0 0.5 -0.5 1.0 -1.0 +inf.0 -inf.0 +nan.0 </enscript> first, then a uniformly random distribution of inexact real numbers. Elements of the above sequence may be omitted if they are not distinguished in the implementation. <enscript language="scheme"> (define inexact-real-gen (inexact-real-generator)) (inexact-real-gen) ; => 0.0 </enscript> === Special generators <procedure>(list-generator-of subgenerator [max-length])</procedure> Create an infinite generator that returns lists. The generator should return the empty list first. Then it should return lists containing values generated by {{subgenerator}}, with a length uniformly randomly distributed between 1 and {{max-length}}, if specified. If the {{max-length}} argument is not specified, the implementation may select the size range. <enscript language="scheme"> (define list-gen (list-generator-of (integer-generator))) (list-gen) ; => '() (list-gen) ; => '(0 1 -1 ...) </enscript> <procedure>(pair-generator-of subgenerator-car [subgenerator-cdr])</procedure> Create an infinite generator that returns pairs. The contents of the pairs are values generated by the {{subgenerator-car}}, and if specified, {{subgenerator-cdr}} arguments. If both subgenerator arguments are specified, {{subgenerator-car}} will populate the car, while {{subgenerator-cdr}} will populate the cdr of the pair. If the {{subgenerator-cdr}} argument is not specified, {{subgenerator-car}} will be used to generate both elements of the pair. <enscript language="scheme"> (define pair-gen (pair-generator-of (integer-generator) (boolean-generator))) (pair-gen) ; => '(0 . #t) </enscript> <procedure>(procedure-generator-of subgenerator)</procedure> Create an infinite generator that returns procedures. The return values of those procedures are values generated by the {{subgenerator}] argument. The procedures generated should be variadic. <enscript language="scheme"> (define proc-gen (procedure-generator-of (boolean-generator))) ((proc-gen) 1) ; => #t ((proc-gen) 'foo 'bar) ; => #f ((proc-gen) "x" "y" "z") ; => #t or #f </enscript> <procedure>(vector-generator-of subgenerator [max-length])</procedure> Create an infinite generator that returns vectors. The generator should return the empty vector first. Then it should return vectors containing values generated by {{subgenerator}}, with a length uniformly randomly distributed between 1 and max-length, if specified. If the {{max-length}} argument is not specified, the implementation may select the size range. <enscript language="scheme"> (define vector-gen (vector-generator-of (boolean-generator))) (vector-gen) ; => #() (vector-gen) ; => #(#t #f ...) </enscript> == Examples === Named property tests <enscript language="scheme"> (define (my-square z) (* z z)) (define (my-square-property z) (= (sqrt (my-square z)) z)) ;; Test the property ten times. (test-begin "my-square-prop-test") (test-property my-square-property (list (integer-generator)) 10) (test-end "my-square-prop-test") </enscript> === Property tests that are expected to fail <enscript language="scheme"> (define (my-square z) (+ z 1)) ; Incorrect for all inputs (define (my-square-property z) (= (sqrt (my-square z)) z)) (test-property-expect-fail my-square-property (list (integer-generator))) </enscript> === Skip a property test <enscript language="scheme"> (test-property-skip (lambda (x) #t) (list (integer-generator))) </enscript> === Test property error <enscript language="scheme"> (define (my-square z) (* z "foo")) ; will cause an error (define (my-square-property z) (= (sqrt (my-square z)) z)) (test-property-error my-square-property (list (integer-generator))) </enscript> === Error type <enscript language="scheme"> (define (cause-read-error str) (read (open-input-string (string-append ")" str)))) (define (cause-read-error-property str) (symbol? (cause-read-error str))) (test-property-error-type &read-error cause-read-error-property (list (string-generator))) </enscript> === Boolean Generator <enscript language="scheme"> (define bool-gen (boolean-generator)) (bool-gen) ; => #t (bool-gen) ; => #f (bool-gen) ; => #t or #f </enscript> == Bytevector generator <enscript language="scheme"> (define bytevector-gen (bytevector-generator)) (bytevector-gen) ; => #u8() (bytevector-gen) ; => #u8(...) </enscript>
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you multiply 7 by 0?