]> gitweb.factorcode.org Git - factor.git/blob - basis/tools/test/test.factor
Refactor the lexer/parser to expose friendlier words for scanning tokens. The preferr...
[factor.git] / basis / tools / test / test.factor
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 ;
11 IN: tools.test
12
13 TUPLE: test-failure < source-file-error continuation ;
14
15 SYMBOL: +test-failure+
16
17 M: test-failure error-type drop +test-failure+ ;
18
19 SYMBOL: test-failures
20
21 test-failures [ V{ } clone ] initialize
22
23 T{ error-type
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 ] }
29 } define-error-type
30
31 SYMBOL: verbose-tests?
32 t verbose-tests? set-global
33
34 <PRIVATE
35
36 : <test-failure> ( error experiment file line# -- triple )
37     test-failure new
38         swap >>line#
39         swap >>file
40         swap >>asset
41         swap >>error
42         error-continuation get >>continuation ;
43
44 : failure ( error experiment file line# -- )
45     "--> test failed!" print
46     <test-failure> test-failures get push
47     notify-error-observers ;
48
49 SYMBOL: file
50
51 : file-failure ( error -- )
52     [ f file get ] keep error-line failure ;
53
54 :: (unit-test) ( output input -- error ? )
55     [ { } input with-datastack output assert-sequence= f f ] [ t ] recover ;
56
57 : short-effect ( effect -- pair )
58     [ in>> length ] [ out>> length ] bi 2array ;
59
60 :: (must-infer-as) ( effect quot -- error ? )
61     [ quot infer short-effect effect assert= f f ] [ t ] recover ;
62
63 :: (must-infer) ( quot -- error ? )
64     [ quot infer drop f f ] [ t ] recover ;
65
66 TUPLE: did-not-fail ;
67 CONSTANT: did-not-fail T{ did-not-fail }
68
69 M: did-not-fail summary drop "Did not fail" ;
70
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 ;
74
75 :: (must-fail) ( quot -- error ? )
76     [ { } quot with-datastack drop did-not-fail t ] [ drop f f ] recover ;
77
78 : experiment-title ( word -- string )
79     "(" ?head drop ")" ?tail drop { { CHAR: - CHAR: \s } } substitute >title ;
80
81 MACRO: <experiment> ( word -- )
82     [ stack-effect in>> length dup ]
83     [ name>> experiment-title ] bi
84     '[ _ ndup _ narray _ prefix ] ;
85
86 : experiment. ( seq -- )
87     [ first write ": " write ]
88     [ rest verbose-tests? get [ . ] [ short. ] if flush ] bi ;
89
90 :: experiment ( word: ( -- error ? ) line# -- )
91     word <experiment> :> e
92     e experiment.
93     word execute [
94         file get [
95             e file get line# failure
96         ] [ rethrow ] if
97     ] [ drop ] if ; inline
98
99 : parse-test ( accum word -- accum )
100     literalize suffix!
101     lexer get line>> suffix!
102     \ experiment suffix! ; inline
103
104 <<
105
106 SYNTAX: TEST:
107     scan-token
108     [ create-in ]
109     [ "(" ")" surround search '[ _ parse-test ] ] bi
110     define-syntax ;
111
112 >>
113
114 PRIVATE>
115
116 : run-test-file ( path -- )
117     dup file [
118         test-failures get file get +test-failure+ delete-file-errors
119         '[ _ run-file ] [ file-failure ] recover
120     ] with-variable ;
121
122 SYMBOL: forget-tests?
123
124 <PRIVATE
125
126 : forget-tests ( files -- )
127     forget-tests? get
128     [ [ [ forget-source ] each ] with-compilation-unit ] [ drop ] if ;
129
130 : test-vocab ( vocab -- )
131     vocab dup [
132         dup source-loaded?>> [
133             vocab-tests
134             [ [ run-test-file ] each ]
135             [ forget-tests ]
136             bi
137         ] [ drop ] if
138     ] [ drop ] if ;
139
140 : test-vocabs ( vocabs -- ) [ test-vocab ] each ;
141
142 PRIVATE>
143
144 TEST: unit-test
145 TEST: must-infer-as
146 TEST: must-infer
147 TEST: must-fail-with
148 TEST: must-fail
149
150 M: test-failure error. ( error -- )
151     {
152         [ error-location print nl ]
153         [ asset>> [ experiment. nl ] when* ]
154         [ error>> error. ]
155         [ continuation>> traceback-link. ]
156     } cleave ;
157
158 : :test-failures ( -- ) test-failures get errors. ;
159
160 : test ( prefix -- ) child-vocabs test-vocabs ;
161
162 : test-all ( -- ) vocabs filter-don't-test test-vocabs ;