Changeset 39579 in project


Ignore:
Timestamp:
02/06/21 17:24:53 (3 weeks ago)
Author:
juergen
Message:

simple-tests 3.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/eggref/5/simple-tests

    r39511 r39579  
    22[[toc:]]
    33
    4 == simple-tests
    5 
    6 This module exports some macros and procedures which help in debugging
    7 and testing. Two interfaces are supplied.
    8 The old interface is a straight-forward port of Peter
    9 Seibel's test suite in "Practical Common Lisp" to Chicken Scheme.
    10 
    11 Notice the special meaning of dots and colons in the documentation.
    12 Two dots: Repeat the form to the left zero or one times,
    13 three dots: zero or many times
    14 four dots: one or many times.
    15 Colons to the left of dots group forms: the dots refer to as many forms
    16 as are enclosed by colons.
    17 
    18 === Common
     4== Rationale
     5
     6This is a simple Unit Test Framework inspired by Peter Seibel's
     7"Practical Common Lisp" together with some routines which might be
     8useful for debugging.  It underwent several changes in the maintenance
     9process, most of them are now marked deprecated but are still there in
     10favor of backwards compatibility.
     11
     12For the future, it's sufficient to use only the following six routines,
     13the parameter verbose? and the macros pe, ppp, check, make-tester and
     14test-all.
     15
     16pe, ppp and check are mostly used in the development phase, make-tester
     17and test-all are the actual test routines to go into tests/run.scm.
     18
     19A tester is a nullary predicate which produces a lot of information as
     20side-effects provided the parameter verbose? is true. These testers are
     21invoked in test-all.
     22
     23pe is a combination of pretty-print and expand enhanced with additional
     24text; ppp pretty-prints a list of expressions and its values, while
     25check does the same but accompanies these computed values with expected
     26ones, allowing for local variables in the checks.
     27
     28=== API
     29
     30==== verbose?
     31 
     32<parameter>(verbose? ..)</parameter>
     33
     34gets or sets the value of the parameter verbose?
     35
     36==== writeln
     37 
     38<procedure>(writeln xpr ...)</procedure>
     39
     40write analog of print, expressions separated by whitespace
     41
     42==== and?
     43 
     44<procedure>(and? . xprs)</procedure>
     45
     46non-short-circuited and which executes all side-effects
     47
     48==== pe
     49 
     50<macro>(pe macro-code)</macro>
     51
     52composes pretty-print and expand,
     53does nothing in compiled code.
     54
     55==== xpr:val
     56 
     57<macro>(xpr:val xpr ...)</macro>
     58
     59Deprecated!
     60Print each xpr quoted in a headline and pretty-print xpr's computed
     61value.
     62
     63==== ppp
     64 
     65<macro>(ppp xpr ...)</macro>
     66
     67print each xpr quoted in a headline and pretty-print xpr's computed
     68value. Alias to xpr:val.
     69
     70==== ppp*
     71 
     72<macro>(ppp* {xpr ypr} ...)</macro>
     73
     74Deprecated!
     75Print each xpr quoted in a headline and pretty-print xpr's computed
     76and expected value, ypr.
     77
     78==== xpr:val*
     79 
     80<macro>(xpr:val* {xpr ypr} ...)</macro>
     81
     82Deprecated!
     83Print each xpr quoted in a headline and pretty-print xpr's computed
     84and expected value, ypr.
     85Alias to ppp*
     86
     87==== ppp**
     88 
     89<macro>(ppp** ((var val) ...) xpr ypr . other-xpr-ypr-pairs)</macro>
     90
     91Deprecated!
     92ppp* wrapped into a let
     93
     94==== define-test
     95 
     96<macro>(define-test (name . parameters) form . forms)</macro>
     97
     98Deprecated!
     99Creates a test function
     100
     101==== compound-test
     102 
     103<macro>(compound-test (name) test . tests)</macro>
     104
     105Deprecated!
     106Invokes all tests and reports a summary
     107
     108==== ==
     109 
     110<procedure>(==)</procedure>
     111
     112<procedure>(== x)</procedure>
     113
     114<procedure>(== type? type-equal?)</procedure>
     115
     116Deprecated!
     117Generic type equality as curried procedure
     118
     119==== check
     120 
     121<macro>(check ((var val) ...) xpr ypr . xpr-yprs)</macro>
     122
     123Compare xpr and ypr .... in sequence with equal?
     124in the environment defined by var val ...
     125
     126==== define-checks
     127 
     128<macro>(define-checks (name? verbose? . var-vals) xpr ypr . xpr-yprs)</macro>
     129
     130Deprecated!
     131Returns a unary predicate, name?, comparing xpr with ypr ....
     132and using var val ... within this checks,
     133verbose? controls the reported summary.
     134
     135==== do-checks
     136 
     137<macro>(do-checks (name? verbose? . var-val-pairs) xpr ypr . xpr-yprs)</macro>
     138
     139Deprecated!
     140Returns a unary predicate, name?, comparing xpr with ypr ....
     141and using var val ... within this checks,
     142alias to define-checks
     143
     144==== define-tester
     145 
     146<macro>(define-tester (name? . var-vals) xpr ypr . xpr-yprs)</macro>
     147
     148Returns a thunk predicate, name?, comparing xpr with ypr ....
     149and using var val ... within this tests.
     150The parameter verbose? controls the reported summary, i. e.
     151the side effects.
     152
     153==== test-all
     154 
     155<macro>(test-all Name tester ....)</macro>
     156
     157invokes all testers defined with define-tester
     158producing a list of failures and exiting with 0 or 1
     159
     160==== check-all
     161 
     162<macro>(check-all Name check-xpr ....)</macro>
     163
     164Deprecated!
     165checks all check-expressions defined with define-checks
     166producing a list of failures and exiting with 0 or 1
    19167
    20168==== simple-tests
    21 
    22 <procedure>(simple-tests ..)</procedure>
    23 
    24 documentation-procedure; returns the list of exported symbols if called
    25 with no symbol, otherwise the signature of that exported symbol sym.
    26 
    27 ==== and?
    28 
    29 <procedure>(and? xpr . xprs)</procedure>
    30 
    31 non-short-circuated and, which executes all side-effects.
    32 
    33 ==== writeln
    34 
    35 <procedure>(writeln xpr . xprs)</procedure>
    36 
    37 like print, but writes expressions separated by a space in one line.
    38 
    39 ==== pe
    40 
    41 <procedure>(pe macro-code)</procedure>
    42 
    43 pretty-prints expanded macro-code.
    44 
    45 ==== ppp
    46 
    47 <macro>(ppp xpr ...)</macro>
    48 
    49 print each xpr quoted in a headline and pretty-print its computed value.
    50 
    51 ==== ppp*
    52 
    53 <macro>(ppp* xpr ypr . xpr-yprs)</macro>
    54 
    55 print each xpr quoted in a headline, and pretty-print xpr's computed as well as
    56 its expected value, ypr.
    57 
    58 ==== ppp**
    59 
    60 <macro>(ppp** ((var val) ...) xpr ypr . xpr-yprs)
    61 
    62 wrap ppp* into a let.
    63 
    64 ==== xpr:val
    65 
    66 <macro>(xpr:val xpr ...)</macro>
    67 
    68 print each xpr quoted in a headline and pretty-print its computed value,
    69 alias to ppp.
    70 
    71 ==== xpr:val*
    72 
    73 <macro>(xpr:val* xpr ypr . xpr-yprs)</macro>
    74 
    75 alias to ppp*
    76 
    77 ==== ==
    78 
    79 <procedure>(==)</procedure>
    80 <procedure>(== x)</procedure>
    81 <procedure>(== type? type-equal?)</procedure>
    82 
    83 generic procedure.
    84 The first resets the local database,
    85 the second returns the curried equality operator, corresponding to x,
    86 and the third adds a new pair to the local database.
    87 Using (== x) for comparison, you needn't supply a special comparison
    88 operator, (== x) will do it for you.
    89 
    90 === Old interface
    91 
    92 ==== compound-test
    93 
    94 <macro>(compound-test (name) test ...)</macro>
    95 
    96 This is the obligatory wrapper around each individual test predicate.
    97 Runs each test (usually created by define-test) in sequence and
    98 prints the results of each as well as a combined result.
    99 Exits with 0 or 1 depending on success or failure.
    100 
    101 ==== define-test
    102 
    103 <macro>(define-test (name . parameters) form . forms)</macro>
    104 
    105 creates a test predicate, (name . parameters), to be called within
    106 compound-test. That predicate will test and report the results of all of
    107 its form arguments.
    108 
    109 ==== *locations*
    110 
    111 global dynamic variable controlling location of possibly nested tests.
    112 
    113 ==== *failures*
    114 
    115 global variable collecting failure information
    116 
    117 === New interface
    118 
    119 ==== check
    120 
    121 <macro>(check ((var val) ...) xpr ypr . xpr-yprs)</macro>
    122 
    123 compares xpr and ypr .... with == in the environment
    124 defined by (var val)
    125 
    126 ==== define-checks
    127 
    128 <macro>(define-checks (name? verbose? var val . var-vals) xpr ypr .  xpr-yprs)</macro>
    129 
    130 defines a unary predicate, name?, with argument verbose?, which compares
    131 all pairs xpr ypr and prints a list of failures, if verbose? is
    132 #t or not given.  Otherwise simply returns #t or #f, depending on the
    133 comparison of the pairs' items.
    134 If the verbose? argument in the generated predicate is missing, it's #t,
    135 so the output is verbose.  Inside another check-predicate, it's usually
    136 #f, cf. arithmetic? below.
    137 
    138 Comparison is done by the generic procedure ==.
    139 Each var val pair is translated into a let,  supplying values to be used in test pairs.
    140 
    141 ==== do-checks
    142 
    143 <macro>(do-checks (name? verbose? var val . var-vals) xpr ypr .  xpr-yprs)</macro>
    144 
    145 alias to define-checks
    146 
    147 ==== check-all
    148 
    149 <macro>(check-all name check ...)</macro>
    150 
    151 tests each check in sequence and names it.
     169 
     170<procedure>(simple-tests)</procedure>
     171
     172<procedure>(simple-tests sym)</procedure>
     173
     174with sym: documentation of exported symbol
     175without sym: list of exported symbols
    152176
    153177=== Examples
     
    157181(import simple-tests)
    158182
    159 (define-test (+?)
    160   (= (+ 1 2) 3)
    161   (= (+ 1 2 3) 6))
    162 
    163 (define-test (*?)
    164   (= (* 1 2) 2)
    165   (= (* 1 2 3) 6))
    166 
    167 (define-test (arithmetic?)
    168   (+?)
    169   (*?))
    170 
    171 (compound-test (simple-tests)
    172   (arithmetic?))
    173 
    174 or, ALTERNATIVELY
    175 
    176 (check ((lst '(0 1 2 3)))
    177   lst
    178   '(0 1 2 3)
    179   (car lst)
    180   0
    181   (cadr lst)
    182   1
    183   (cddr lst)
    184   '(2 3)
    185   )
    186 
    187 (define-checks (+? verbose?)
    188   (+ 1 2) 3
    189   (+ 1 2 3) 6)
    190 
    191 (define-checks (*? verbose?)
    192   (* 1 2) 2
    193   (* 1 2 3) 6)
    194 
    195 (define-checks (arithmetic? verbose?)
    196   (+? #f) #t
    197   (*? #f) #t)
    198 
    199 (check-all SIMPLE (+?) (*?) (arithmetic?))
     183(newline)
     184
     185(define-test (bar n) (positive? n) (even? n))
     186
     187(bar 5)
     188
     189(define-test (foo x y) (< x y) "COMMENT" (bar 4) (odd? 3) (positive? 3))
     190
     191(foo 1 2)
     192
     193(define-test (++) (= (+ 1 2) 3) (= (+ 1 2 3) 6))
     194
     195(++)
     196
     197(define-test (**) (= (* 1 2) 2) (= (* 1 2 3) 6))
     198
     199(**)
     200
     201(define-test (arithmetic) (++) (**))
     202
     203(arithmetic)
     204
     205(define-test (baz) (and? #t #t #t) (and?) (not (and? #t #f #t)))
     206
     207(baz)
     208
     209'(compound-test (OLD) (bar 5) (foo 1 2) (++) (**) (arithmetic) (baz))
     210
     211(newline)
     212
     213(positive? n)
     214;-> #t
     215
     216(even? n)
     217;-> #f
     218
     219(bar?)
     220
     221(+ 1 2)
     222;-> 3
     223
     224(+ 1 2 3)
     225;-> 6
     226
     227(+?)
     228
     229(* 1 2)
     230;-> 2
     231
     232(* 1 2 3)
     233;-> 6
     234
     235(*?)
     236
     237(+? #f)
     238;-> #t
     239
     240(*? #f)
     241;-> #t
     242
     243(arithmetic?)
     244
     245(and? #t #t #t)
     246;-> #t
     247
     248(and?)
     249;-> #t
     250
     251(and? #t #f #t)
     252;-> #f
     253
     254(baz?)
     255
     256((== "x") "y")
     257;-> #f
     258
     259((== "x") "x")
     260;-> #t
     261
     262((== baz?) baz?)
     263;-> #t
     264
     265((== baz?) bar?)
     266;-> #f
     267
     268((== '()) '())
     269;-> #t
     270
     271((== 'x) 'y)
     272;-> #f
     273
     274((== 'x) 'x)
     275;-> #t
     276
     277((== #(0 1 2)) #(0 1 2))
     278;-> #t
     279
     280((== #(0 1 2)) '(0 1 2))
     281;-> #f
     282
     283(qux?)
     284
     285(define counter
     286  (let ((n 0)) (case-lambda (() (set! n (add1 n)) n) ((k) (set! n k) n))))
     287
     288(counter 0)
     289;-> 0
     290
     291(counter)
     292;-> 1
     293
     294(counter)
     295;-> 2
     296
     297(counter)
     298;-> 3
     299
     300(counter)
     301;-> 4
     302
     303(counter?)
     304
     305'(check-all NEW (bar?) (*?) (+?) (arithmetic?) (baz?) (qux?) (counter?))
     306
     307(positive? n)
     308;-> #t
     309
     310(even? n)
     311;-> #f
     312
     313(+ 1 2)
     314;-> 3
     315
     316(+ 1 2 3)
     317;-> 6
     318
     319(* 1 2)
     320;-> 2
     321
     322(* 1 2 3)
     323;-> 6
     324
     325(parameterize ((verbose? #f)) (Plus?))
     326;-> #t
     327
     328(parameterize ((verbose? #f)) (Times?))
     329;-> #t
     330
     331(define Counter
     332  (let ((n 0)) (case-lambda (() (set! n (add1 n)) n) ((k) (set! n k) n))))
     333
     334(Counter 0)
     335;-> 0
     336
     337(Counter)
     338;-> 1
     339
     340(Counter)
     341;-> 2
     342
     343(Counter)
     344;-> 3
     345
     346(Counter)
     347;-> 4
     348
     349(Counter 0)
     350;-> 0
     351
     352'(test-all SIMPLE-TESTS Bar? Times? Plus? Arithmetic? Counter?)
    200353
    201354</enscript>
    202355
     356
     357== Requirements
     358
     359None
     360
    203361== Last update
    204362
    205 Jan 16, 2021
     363Feb 6, 2021
    206364
    207365== Author
    208366
    209 [[/users/juergen-lorenz|Juergen Lorenz]]
     367Juergen Lorenz
    210368
    211369== License
    212370
    213  Copyright (c) 2013-2021, Juergen Lorenz
    214  All rights reserved.
    215 
    216  Redistribution and use in source and binary forms, with or without
    217  modification, are permitted provided that the following conditions are
    218  met:
    219  
    220  Redistributions of source code must retain the above copyright
    221  notice, this list of conditions and the following disclaimer.
    222  
    223  Redistributions in binary form must reproduce the above copyright
    224  notice, this list of conditions and the following disclaimer in the
    225  documentation and/or other materials provided with the distribution.
    226  Neither the name of the author nor the names of its contributors may be
    227  used to endorse or promote products derived from this software without
    228  specific prior written permission.
    229    
    230  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
    231  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
    232  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    233  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    234  HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    235  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
    236  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    237  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    238  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    239  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    240  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    241 
    242 == Version History
    243 
     371Copyright (c) 2013-2021 , Juergen Lorenz, ju (at) jugilo (dot) de
     372All rights reserved.
     373
     374Redistribution and use in source and binary forms, with or without
     375modification, are permitted provided that the following conditions are
     376met:
     377
     378Redistributions of source code must retain the above copyright
     379notice, this list of conditions and the following disclaimer.
     380
     381Redistributions in binary form must reproduce the above copyright
     382notice, this list of conditions and the following disclaimer in the
     383documentation and/or other materials provided with the distribution.
     384Neither the name of the author nor the names of its contributors may be
     385used to endorse or promote products derived from this software without
     386specific prior written permission.
     387 
     388THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     389IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     390TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     391PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     392HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     393SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
     394TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     395PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     396LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     397NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     398SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     399
     400== Version history
     401; 3.0 : support for define-tester and test-all, deprecated routines marked
    244402; 2.3.2 : locals in checks with letrec
    245403; 2.3.1 : aesthetic changes
     
    252410; 1.1 : ppp* added
    253411; 1.0 : port with modifications from chicken-4, version 2.6, to chicken-5
     412
Note: See TracChangeset for help on using the changeset viewer.