Mercurial > projects > ddmd
comparison test.d @ 124:731ab26f07bf
testing tool added
author | korDen |
---|---|
date | Fri, 03 Sep 2010 21:39:37 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
123:9e39c7de8438 | 124:731ab26f07bf |
---|---|
1 import std.stdio; | |
2 import std.utf; | |
3 import std.file; | |
4 import std.path; | |
5 import std.algorithm; | |
6 import std.string; | |
7 import std.process; | |
8 import core.stdc.ctype; | |
9 import std.c.windows.windows; | |
10 | |
11 string compiler = "dmd"; | |
12 | |
13 class Test | |
14 { | |
15 enum EXTRA_SOURCES = "EXTRA_SOURCES"; | |
16 enum COMPILE_SEPARATELY = "COMPILE_SEPARATELY"; | |
17 enum PERMUTE_ARGS = "PERMUTE_ARGS"; | |
18 enum REQUIRED_ARGS = "REQUIRED_ARGS"; | |
19 enum POST_SCRIPT = "POST_SCRIPT"; | |
20 enum EXECUTE_ARGS = "EXECUTE_ARGS"; | |
21 | |
22 this(string path, string outputDir) | |
23 { | |
24 this.outputDir = outputDir; | |
25 this.baseDir = dirname(path); | |
26 | |
27 this.baseName = getBaseName(path); | |
28 this.name = getName(baseName); | |
29 | |
30 this.fileNames ~= baseName; | |
31 | |
32 auto file = File(path); | |
33 while (true) { | |
34 auto line = file.readln(); | |
35 if (!line.startsWith("// ")) { | |
36 break; | |
37 } | |
38 | |
39 line = trim(line[3..$]); | |
40 if (line.startsWith(EXTRA_SOURCES)) { | |
41 fileNames ~= split(line[EXTRA_SOURCES.length + 2..$], " "); | |
42 } else if (line.startsWith(COMPILE_SEPARATELY)) { | |
43 compileSeparately = true; | |
44 } else if (line.startsWith(EXECUTE_ARGS)) { | |
45 executeArgs = line[EXECUTE_ARGS.length + 2..$]; | |
46 } else if (line.startsWith(PERMUTE_ARGS)) { | |
47 // ignore for now | |
48 } else if (line.startsWith(REQUIRED_ARGS)) { | |
49 requiredArgs = line[REQUIRED_ARGS.length + 2..$]; | |
50 } else if (line.startsWith(POST_SCRIPT)) { | |
51 // ignore for now | |
52 } else { | |
53 continue; | |
54 } | |
55 } | |
56 } | |
57 | |
58 private string prefix() | |
59 { | |
60 return std.string.format(compiler ~ " -od%s -I%s %s", outputDir, baseDir, requiredArgs); | |
61 } | |
62 | |
63 private string csuffix(string fileName) | |
64 { | |
65 // output to console | |
66 return ""; //std.string.format(" > %s\\%s.clog", outputDir, getBaseName(fileName)); | |
67 } | |
68 | |
69 private string lsuffix(string fileName) | |
70 { | |
71 return std.string.format(" > %s\\%s.llog", outputDir, getBaseName(fileName)); | |
72 } | |
73 | |
74 private string output() | |
75 { | |
76 return std.string.format(" -of%s\\%s.exe", outputDir, name); | |
77 } | |
78 | |
79 private void execute(string command) | |
80 { | |
81 system(command); | |
82 } | |
83 | |
84 void compile() | |
85 { | |
86 if (compileSeparately) { | |
87 string link_command = compiler ~ output(); | |
88 foreach (fileName; fileNames) { | |
89 string compile_command = prefix(); | |
90 | |
91 compile_command ~= std.string.format(" %s\\%s -c", baseDir, fileName); | |
92 compile_command ~= csuffix(fileName); | |
93 | |
94 execute(compile_command); | |
95 link_command ~= std.string.format(" %s\\%s.obj", outputDir, getName(getBaseName(fileName))); | |
96 } | |
97 | |
98 link_command ~= lsuffix(baseName); | |
99 | |
100 execute(link_command); | |
101 } else { | |
102 string compile_command = prefix(); | |
103 foreach (fileName; fileNames) { | |
104 compile_command ~= std.string.format(" %s\\%s", baseDir, fileName); | |
105 } | |
106 | |
107 compile_command ~= output(); | |
108 compile_command ~= csuffix(baseName); | |
109 | |
110 execute(compile_command); | |
111 } | |
112 } | |
113 | |
114 private string[] fileNames; | |
115 | |
116 private string name; | |
117 private string baseName; | |
118 private string outputDir; | |
119 private string baseDir; | |
120 private string requiredArgs; | |
121 private string executeArgs; | |
122 | |
123 private bool compileSeparately = false; | |
124 } | |
125 | |
126 class RunnableTest : Test | |
127 { | |
128 this(string path, string outputDir) | |
129 { | |
130 super(path, outputDir); | |
131 } | |
132 | |
133 void run() | |
134 { | |
135 string run_command = std.string.format("%s\\%s.exe %s > %s\\%s.exe.rlog", outputDir, name, executeArgs, outputDir, name); | |
136 execute(run_command); | |
137 } | |
138 } | |
139 | |
140 int main(string[] args) | |
141 { | |
142 auto runnable_tests = wildcard("runnable/*.d"/*, "runnable/*.html", "runnable/*.sh"*/); | |
143 auto runnable_test_results = map!q{"result/" ~ a ~ ".out"}(runnable_tests); | |
144 | |
145 auto outputDir = "result"; | |
146 | |
147 if (args.length >= 2) { | |
148 compiler = args[1]; | |
149 } else { | |
150 // compiler = "dmd"; // value by default | |
151 } | |
152 | |
153 foreach (fileName; runnable_tests) { | |
154 //fileName = "runnable\\a18.d"; | |
155 writeln("testing ", fileName); | |
156 auto test = new RunnableTest(fileName, outputDir); | |
157 test.compile(); | |
158 // test.run(); | |
159 // break; | |
160 } | |
161 | |
162 return 0; | |
163 } | |
164 | |
165 string[] wildcard(string[] paths...) | |
166 { | |
167 string[] fileNames; | |
168 | |
169 foreach (path; paths) { | |
170 filter(path, (string fileName) { fileNames ~= fileName; return true; }); | |
171 } | |
172 | |
173 return fileNames; | |
174 } | |
175 | |
176 string trimLeft(string s) | |
177 { | |
178 for (int i = 0; i < s.length; ++i) { | |
179 if (!isspace(s[i])) { | |
180 return s[i..$]; | |
181 } | |
182 } | |
183 | |
184 return null; | |
185 } | |
186 | |
187 string trimRight(string s) | |
188 { | |
189 for (int i = s.length - 1; i >= 0; --i) { | |
190 if (!isspace(s[i])) { | |
191 return s[0..i + 1]; | |
192 } | |
193 } | |
194 | |
195 return null; | |
196 } | |
197 | |
198 string trim(string s) | |
199 { | |
200 return trimLeft(trimRight(s)); | |
201 } | |
202 | |
203 version(Windows) void filter(string pattern, bool delegate(string fileName) callback) | |
204 { | |
205 WIN32_FIND_DATAW fileinfo; | |
206 | |
207 auto h = FindFirstFileW(std.utf.toUTF16z(pattern), &fileinfo); | |
208 if (h == INVALID_HANDLE_VALUE) | |
209 return; | |
210 | |
211 auto path = dirname(pattern); | |
212 | |
213 do | |
214 { | |
215 // Skip "." and ".." | |
216 auto name = fileinfo.cFileName.ptr; | |
217 if (name[0] == '.' && (name[1] == 0 || name[1] == '.')) | |
218 continue; | |
219 | |
220 size_t clength = std.string.wcslen(fileinfo.cFileName.ptr); | |
221 auto fileName = std.path.join(path, std.utf.toUTF8(fileinfo.cFileName[0 .. clength])); | |
222 | |
223 if (!callback(fileName)) { | |
224 break; | |
225 } | |
226 } while (FindNextFileW(h, &fileinfo) != FALSE); | |
227 | |
228 FindClose(h); | |
229 } | |
230 | |
231 string getBaseName(string fullname, string extension = null) | |
232 { | |
233 auto i = fullname.length; | |
234 for (; i > 0; i--) | |
235 { | |
236 version(Windows) | |
237 { | |
238 if (fullname[i - 1] == ':' || fullname[i - 1] == '\\' || fullname[i - 1] == '/') | |
239 break; | |
240 } | |
241 else version(Posix) | |
242 { | |
243 if (fullname[i - 1] == '/') | |
244 break; | |
245 } | |
246 else | |
247 { | |
248 static assert(0); | |
249 } | |
250 } | |
251 return chomp(fullname[i .. fullname.length], | |
252 extension.length ? extension : ""); | |
253 } |