Mercurial > projects > dang
comparison tests/run.d @ 208:41ccd50e7cbc
Added missing tests
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Tue, 12 Aug 2008 18:21:06 +0200 |
parents | d3c148ca429b |
children |
comparison
equal
deleted
inserted
replaced
207:e0551773a005 | 208:41ccd50e7cbc |
---|---|
1 // skip | |
1 module run.d; | 2 module run.d; |
2 | 3 |
3 import tango.io.Stdout, | 4 import tango.core.Array, |
4 tango.core.Array, | 5 tango.io.FileConduit, |
5 tango.io.FilePath, | 6 tango.io.FileScan, |
6 tango.io.GrowBuffer, | 7 tango.io.Stdout, |
7 tango.io.UnicodeFile, | 8 tango.sys.Process, |
8 tango.io.stream.BufferStream, | 9 tango.text.Ascii, |
9 tango.text.Util, | 10 tango.text.Regex, |
10 tango.io.protocol.Reader, | 11 tango.text.Util; |
11 tango.io.protocol.Writer, | |
12 tango.text.Unicode, | |
13 tango.sys.Process; | |
14 | 12 |
13 // -- Settings -- | |
14 char[] compiler = "./Dang"; | |
15 char[] test_folder = "tests"; | |
16 char[] valid_filenames = r"^[^.].*"; | |
17 bool print_expected = false; | |
18 char[][] options; | |
19 // the tests can be sorted by one of the following functions | |
20 bool nameSort (FilePath a, FilePath b) { return a.name < b.name; } | |
21 bool pathSort (FilePath a, FilePath b) { return a.toString < b.toString; } | |
22 bool modifiedSort(FilePath a, FilePath b) { return a.modified < b.modified; } | |
23 bool createdSort (FilePath a, FilePath b) { return a.created < b.created; } | |
24 const sortBy = &pathSort; | |
15 | 25 |
16 enum | 26 // -- end of settings |
27 | |
28 enum TestResult | |
17 { | 29 { |
18 SuccessSuccess, | 30 Skipped, |
19 SuccessFailure, | 31 Expected, |
20 FailureSuccess, | 32 Unexpected |
21 FailureFailure, | |
22 } | 33 } |
23 | |
24 char[] prog = "./Dang"; | |
25 | 34 |
26 void main(char[][] args) | 35 void main(char[][] args) |
27 { | 36 { |
28 auto cPath = FilePath("tests"); | 37 foreach (arg ; args[1..$]) |
38 options ~= arg; | |
29 | 39 |
30 ubyte success_success, success_failure, failure_failure, failure_success; | 40 scope scan = new FileScan; |
41 // scope regex = new Regex(valid_filenames); // DMD FAILS!! ?? | |
42 // Return true for files/folders to include | |
43 bool filter(FilePath p, bool isDir) | |
44 { | |
45 if (isDir) | |
46 return p.name[0] != '.'; | |
47 else | |
48 return p.ext == "d" ; //&& regex.test(p.name); | |
49 } | |
50 scan.sweep(test_folder, &filter, true); | |
51 FilePath[] files = scan.files; | |
52 int total_tests = files.length; | |
31 | 53 |
32 foreach( path ; cPath.toList((FilePath path, bool isFolder){return isFolder;})) | 54 // Sort the result by the chosen function - default is the full path |
55 sort(files, sortBy); | |
56 | |
57 int[TestResult.max + 1] results = 0; | |
58 foreach (i, ref test; files) | |
33 { | 59 { |
34 Stdout(path.name)(":").newline; | 60 begin_test(i + 1, total_tests, test.name); |
35 auto paths = path.toList( | 61 TestResult res = run_test(test); |
36 (FilePath path, bool isFolder) | 62 results[res] += 1; |
37 { | 63 end_test(); |
38 if(path.ext == "d" && path.name[0] != '.') | 64 } |
39 return true; | 65 Stdout.format("\r{,80}\r", " "); |
40 return false; | 66 Stdout.newline; |
41 }); | 67 int good = TestResult.Expected; |
42 sort(paths, (FilePath a, FilePath b) { return a.name < b.name; }); | 68 int bad = TestResult.Unexpected; |
43 foreach (p ; paths) | 69 int tests_run = results[good] + results[bad]; |
70 Stdout.formatln("{}/{} tests failed", results[bad], tests_run); | |
71 } | |
72 | |
73 void begin_test(int number, int total_tests, char[] name) | |
74 { | |
75 char[60] progressbar = ' '; | |
76 int progress = number*progressbar.length/total_tests; | |
77 progressbar[0 .. progress] = '='; | |
78 if(progress) | |
79 progressbar[progress-1] = '>'; | |
80 Stdout.format("\r{}% - [{}]", 1e2 * number / total_tests, progressbar); | |
81 Stdout.flush(); | |
82 //Thread.sleep(0.05); | |
83 } | |
84 | |
85 void end_test() { } | |
86 | |
87 enum { | |
88 NoFail, | |
89 CompiletimeFail, | |
90 RuntimeFail | |
91 } | |
92 | |
93 private int min(int a, int b) { return a < b? a : b; } | |
94 TestResult run_test(ref FilePath p) | |
95 { | |
96 auto file = new FileConduit(p.toString(), FileConduit.ReadExisting); | |
97 char[256] content; | |
98 int len = file.read(content); | |
99 file.close(); | |
100 char[] line = content[0 .. min(len, content.find('\n'))]; | |
101 | |
102 bool compile = true; | |
103 int fail = NoFail; | |
104 if (line.length >= 2 && line[0 .. 2] == "//") | |
105 { | |
106 foreach (command; line[2 .. $].delimiters(",;")) | |
44 { | 107 { |
45 auto test = new Test(p); | 108 switch (toLower(substitute(command, " ", ""))) |
46 ubyte result = test.run(); | |
47 | |
48 switch(result) | |
49 { | 109 { |
50 case SuccessSuccess: | 110 case "skip", "dontcompile": |
51 success_success++; | 111 compile = false; |
52 break; | 112 break; |
53 case SuccessFailure: | 113 case "fail", "compilefail", |
54 success_failure++; | 114 "compiletimefail", "failatcompiletime": |
115 fail = CompiletimeFail; | |
55 break; | 116 break; |
56 case FailureFailure: | 117 case "runtime", "runtimefail", "failatruntime": |
57 failure_failure++; | 118 fail = RuntimeFail; |
58 break; | 119 Stderr("== Compiled tests will not be run! ==").newline; |
59 case FailureSuccess: | 120 return TestResult.Skipped; |
60 failure_success++; | 121 default: |
61 break; | 122 break; |
62 } | 123 } |
63 | 124 break; |
64 } | 125 } |
65 } | 126 } |
66 | 127 |
67 Stdout().newline.newline() | 128 if (compile) |
68 ("Result:").newline() | 129 { |
69 (" - Success/Success: ")(success_success).newline() | 130 auto o = compiler ~ options ~ p.toString; |
70 (" - Success/Failure: ")(success_failure).newline() | 131 auto process = new Process(o); |
71 (" - Failure/Failure: ")(failure_failure).newline() | 132 process.execute(); |
72 (" - Failure/Success: ")(failure_success).newline; | 133 auto result = process.wait(); |
134 return resultOf(p, result.status, fail); | |
135 } | |
136 | |
137 return TestResult.Skipped; | |
73 } | 138 } |
74 | 139 |
75 class Test | 140 private TestResult resultOf(FilePath p, int result, int expected) |
76 { | 141 { |
77 enum TestValue | 142 char[] good(char[] s) |
78 { | 143 { |
79 Success = 0, | 144 version (Posix) |
80 Lexer = 2, | 145 return "\033[1;32m" ~ s ~ "\033[m"; |
81 Parser = 3, | 146 else |
82 Gen = 4, | 147 return s; |
83 | |
84 Fail = 100 | |
85 } | 148 } |
86 | 149 |
87 FilePath target; | 150 char[] bad(char[] s) |
88 | |
89 TestValue[int] testValues; | |
90 | |
91 public this(FilePath target) | |
92 { | 151 { |
93 this.target = target; | 152 s = s ~ " - Unexpected"; |
153 version (Posix) | |
154 return "\033[1;31m" ~ s ~ "\033[m"; | |
155 else | |
156 return s; | |
94 } | 157 } |
95 | 158 |
96 public ubyte run() | 159 bool unexpected = expected == 0 ? result != 0 : result == 0; |
160 auto f = unexpected? &bad : &good; | |
161 char[] s = (result == 0)? "SUCCESS" : "FAILURE"; | |
162 // always print if unexpeted, otherwise check the settings | |
163 if (unexpected || print_expected) | |
97 { | 164 { |
98 auto process = new Process(prog,"--gen-llvm",target.path~target.file); | 165 Stdout.format("\r{,80}\r", " "); |
99 | 166 Stdout.format(" {,-45}", p); |
100 auto file = new UnicodeFile!(char)(target.path~target.file, Encoding.UTF_8); | 167 Stdout(f(s)).newline; |
101 | |
102 TestValue mode; | |
103 | |
104 char[] data = file.read; | |
105 char[][] commands = split(splitLines(data)[0], " "); | |
106 if(commands[0] == "//fail") | |
107 { | |
108 mode = TestValue.Fail; | |
109 if(commands.length > 1) | |
110 { | |
111 try | |
112 { | |
113 int i = Integer.toInt(commands[1]); | |
114 if(i in testValues) | |
115 mode = testValues[i]; | |
116 } | |
117 catch{} | |
118 } | |
119 } | |
120 /* if(data.length > 6 && data[0..6] == "//fail") | |
121 { | |
122 char[] str = data.splitLines()[0][6..$]; | |
123 | |
124 switch(toLower(trim(str))) | |
125 { | |
126 case "fail": | |
127 case "failure": | |
128 mode = 1; | |
129 break; | |
130 default: | |
131 mode = 0; | |
132 } | |
133 } | |
134 */ | |
135 Stdout.format(" {,-25}", target.file); | |
136 | |
137 process.execute; | |
138 auto result = process.wait; | |
139 | |
140 /* | |
141 if(result.status == 0) | |
142 { | |
143 auto llvm_process = new Process("llvm-as"); | |
144 llvm_process.execute; | |
145 llvm_process.stdin.copy(process.stdout); | |
146 llvm_process.stdin.close(); | |
147 result = llvm_process.wait; | |
148 } | |
149 */ | |
150 | |
151 return resultOf(result.status, mode); | |
152 } | 168 } |
153 | 169 return unexpected? TestResult.Unexpected : TestResult.Expected; |
154 private int resultOf(int status, TestValue mode) | |
155 { | |
156 char[] good(char[] s) | |
157 { | |
158 version (Posix) | |
159 return "\033[1;32m" ~ s ~ "\033[m"; | |
160 else | |
161 return s; | |
162 } | |
163 | |
164 char[] bad(char[] s) | |
165 { | |
166 version (Posix) | |
167 return "\033[1;31m" ~ s ~ "\033[m"; | |
168 else | |
169 return s; | |
170 } | |
171 | |
172 if(status == 0) | |
173 { | |
174 if(mode == TestValue.Success) | |
175 { | |
176 Stdout(good("SUCCESS")).newline; | |
177 return SuccessSuccess; | |
178 } | |
179 if(mode == TestValue.Fail) | |
180 { | |
181 Stdout(bad("SUCCESS - Unexpected")).newline; | |
182 return FailureSuccess; | |
183 } | |
184 } | |
185 else | |
186 { | |
187 if(mode == TestValue.Fail) | |
188 { | |
189 Stdout(good("FAILURE")).newline; | |
190 return FailureFailure; | |
191 } | |
192 if(mode == TestValue.Success) | |
193 { | |
194 Stdout(bad("FAILURE - Unexpected")).newline; | |
195 return SuccessFailure; | |
196 } | |
197 } | |
198 } | |
199 } | 170 } |
200 | 171 |