1 ! Copyright (C) 2003, 2010 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
5 sequences.generalizations io io.files io.styles kernel lexer
6 locals macros math.parser namespaces parser vocabs.parser
7 prettyprint quotations sequences source-files splitting
8 stack-checker summary unicode.case vectors vocabs vocabs.loader
9 vocabs.files vocabs.metadata words tools.errors
10 source-files.errors io.streams.string make compiler.errors ;
13 TUPLE: test-failure < source-file-error continuation ;
15 SYMBOL: +test-failure+
17 M: test-failure error-type drop +test-failure+ ;
21 test-failures [ V{ } clone ] initialize
24 { type +test-failure+ }
25 { word ":test-failures" }
26 { plural "unit test failures" }
27 { icon "vocab:ui/tools/error-list/icons/unit-test-error.tiff" }
28 { quot [ test-failures get ] }
31 SYMBOL: verbose-tests?
32 t verbose-tests? set-global
36 : <test-failure> ( error experiment file line# -- triple )
42 error-continuation get >>continuation ;
44 : failure ( error experiment file line# -- )
45 "--> test failed!" print
46 <test-failure> test-failures get push
47 notify-error-observers ;
51 : file-failure ( error -- )
52 [ f file get ] keep error-line failure ;
54 :: (unit-test) ( output input -- error ? )
55 [ { } input with-datastack output assert-sequence= f f ] [ t ] recover ;
57 : short-effect ( effect -- pair )
58 [ in>> length ] [ out>> length ] bi 2array ;
60 :: (must-infer-as) ( effect quot -- error ? )
61 [ quot infer short-effect effect assert= f f ] [ t ] recover ;
63 :: (must-infer) ( quot -- error ? )
64 [ quot infer drop f f ] [ t ] recover ;
67 CONSTANT: did-not-fail T{ did-not-fail }
69 M: did-not-fail summary drop "Did not fail" ;
71 :: (must-fail-with) ( quot pred -- error ? )
72 [ { } quot with-datastack drop did-not-fail t ]
73 [ dup pred call( error -- ? ) [ drop f f ] [ t ] if ] recover ;
75 :: (must-fail) ( quot -- error ? )
76 [ { } quot with-datastack drop did-not-fail t ] [ drop f f ] recover ;
78 : experiment-title ( word -- string )
79 "(" ?head drop ")" ?tail drop { { CHAR: - CHAR: \s } } substitute >title ;
81 MACRO: <experiment> ( word -- )
82 [ stack-effect in>> length dup ]
83 [ name>> experiment-title ] bi
84 '[ _ ndup _ narray _ prefix ] ;
86 : experiment. ( seq -- )
87 [ first write ": " write ]
88 [ rest verbose-tests? get [ . ] [ short. ] if flush ] bi ;
90 :: experiment ( word: ( -- error ? ) line# -- )
91 word <experiment> :> e
95 e file get line# failure
97 ] [ drop ] if ; inline
99 : parse-test ( accum word -- accum )
101 lexer get line>> suffix!
102 \ experiment suffix! ; inline
109 [ "(" ")" surround search '[ _ parse-test ] ] bi
114 : fake-unit-test ( quot -- test-failures )
117 V{ } clone test-failures set
120 ] with-scope ; inline
124 : run-test-file ( path -- )
126 test-failures get file get +test-failure+ delete-file-errors
127 '[ _ run-file ] [ file-failure ] recover
130 SYMBOL: forget-tests?
134 : forget-tests ( files -- )
136 [ [ [ forget-source ] each ] with-compilation-unit ] [ drop ] if ;
138 : test-vocab ( vocab -- )
140 dup source-loaded?>> [
142 [ [ run-test-file ] each ]
148 : test-vocabs ( vocabs -- ) [ test-vocab ] each ;
158 M: test-failure error. ( error -- )
160 [ error-location print nl ]
161 [ asset>> [ experiment. nl ] when* ]
163 [ continuation>> traceback-link. ]
166 : :test-failures ( -- ) test-failures get errors. ;
168 : test ( prefix -- ) child-vocabs test-vocabs ;
170 : test-all ( -- ) vocabs filter-don't-test test-vocabs ;