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 }