1 ! Copyright (C) 2003, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs combinators compiler.units
4 continuations debugger effects fry generalizations io io.files
5 io.styles kernel lexer locals macros math.parser namespaces
6 parser prettyprint quotations sequences source-files splitting
7 stack-checker summary unicode.case vectors vocabs vocabs.loader
8 vocabs.files words tools.errors source-files.errors
9 io.streams.string make compiler.errors ;
12 TUPLE: test-failure < source-file-error continuation ;
14 SYMBOL: +test-failure+
16 M: test-failure error-type drop +test-failure+ ;
20 test-failures [ V{ } clone ] initialize
23 { type +test-failure+ }
24 { word ":test-failures" }
25 { plural "unit test failures" }
26 { icon "vocab:ui/tools/error-list/icons/unit-test-error.tiff" }
27 { quot [ test-failures get ] }
32 : <test-failure> ( error experiment file line# -- triple )
38 error-continuation get >>continuation ;
40 : failure ( error experiment file line# -- )
41 "--> test failed!" print
42 <test-failure> test-failures get push
43 notify-error-observers ;
47 : file-failure ( error -- )
48 f file get f failure ;
50 :: (unit-test) ( output input -- error ? )
51 [ { } input with-datastack output assert-sequence= f f ] [ t ] recover ;
53 : short-effect ( effect -- pair )
54 [ in>> length ] [ out>> length ] bi 2array ;
56 :: (must-infer-as) ( effect quot -- error ? )
57 [ quot infer short-effect effect assert= f f ] [ t ] recover ;
59 :: (must-infer) ( quot -- error ? )
60 [ quot infer drop f f ] [ t ] recover ;
63 CONSTANT: did-not-fail T{ did-not-fail }
65 M: did-not-fail summary drop "Did not fail" ;
67 :: (must-fail-with) ( quot pred -- error ? )
68 [ { } quot with-datastack drop did-not-fail t ]
69 [ dup pred call( error -- ? ) [ drop f f ] [ t ] if ] recover ;
71 :: (must-fail) ( quot -- error ? )
72 [ { } quot with-datastack drop did-not-fail t ] [ drop f f ] recover ;
74 : experiment-title ( word -- string )
75 "(" ?head drop ")" ?tail drop { { CHAR: - CHAR: \s } } substitute >title ;
77 MACRO: <experiment> ( word -- )
78 [ stack-effect in>> length dup ]
79 [ name>> experiment-title ] bi
80 '[ _ ndup _ narray _ prefix ] ;
82 : experiment. ( seq -- )
83 [ first write ": " write ] [ rest . ] bi ;
85 :: experiment ( word: ( -- error ? ) line# -- )
86 word <experiment> :> e
90 e file get line# failure
92 ] [ drop ] if ; inline
94 : parse-test ( accum word -- accum )
96 lexer get line>> parsed
97 \ experiment parsed ; inline
104 [ "(" ")" surround search '[ _ parse-test ] ] bi
109 : run-test-file ( path -- )
111 test-failures get file get +test-failure+ delete-file-errors
112 '[ _ run-file ] [ file-failure ] recover
115 : run-vocab-tests ( vocab -- )
116 dup vocab source-loaded?>> [
117 vocab-tests [ run-test-file ] each
120 : traceback-button. ( failure -- )
121 "[" write [ "Traceback" ] dip continuation>> write-object "]" print ;
131 M: test-failure error. ( error -- )
134 [ asset>> [ experiment. nl ] when* ]
136 [ traceback-button. ]
139 : :test-failures ( -- ) test-failures get errors. ;
142 child-vocabs [ run-vocab-tests ] each ;
144 : test-all ( -- ) "" test ;