Commit d12f1f5b49

Andrew Kelley <superjoe30@gmail.com>
2017-04-19 21:38:12
test framework supports name prefix and filter argument
rename self hosted tests to behavior tests
1 parent 9b7f438
src/all_types.hpp
@@ -1458,6 +1458,9 @@ struct CodeGen {
     ZigList<Buf *> link_objects;
 
     ZigList<TypeTableEntry *> name_table_enums;
+
+    Buf *test_filter;
+    Buf *test_name_prefix;
 };
 
 enum VarLinkage {
src/analyze.cpp
@@ -1959,7 +1959,14 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope
     if (import->package != g->root_package)
         return;
 
-    Buf *test_name = node->data.test_decl.name;
+    Buf *decl_name_buf = node->data.test_decl.name;
+
+    Buf *test_name = g->test_name_prefix ?
+        buf_sprintf("%s%s", buf_ptr(g->test_name_prefix), buf_ptr(decl_name_buf)) : decl_name_buf;
+
+    if (g->test_filter != nullptr && strstr(buf_ptr(test_name), buf_ptr(g->test_filter)) == nullptr) {
+        return;
+    }
 
     TldFn *tld_fn = allocate<TldFn>(1);
     init_tld(&tld_fn->base, TldIdFn, test_name, VisibModPrivate, node, &decls_scope->base);
src/codegen.cpp
@@ -147,6 +147,14 @@ void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt) {
     g->omit_zigrt = omit_zigrt;
 }
 
+void codegen_set_test_filter(CodeGen *g, Buf *filter) {
+    g->test_filter = filter;
+}
+
+void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix) {
+    g->test_name_prefix = prefix;
+}
+
 void codegen_set_is_test(CodeGen *g, bool is_test_build) {
     g->is_test_build = is_test_build;
 }
src/codegen.hpp
@@ -44,6 +44,8 @@ void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min);
 void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min);
 void codegen_set_linker_script(CodeGen *g, const char *linker_script);
 void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt);
+void codegen_set_test_filter(CodeGen *g, Buf *filter);
+void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);
 
 PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path);
 void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
src/main.cpp
@@ -64,6 +64,9 @@ static int usage(const char *arg0) {
         "  -mwindows                    (windows only) --subsystem windows to the linker\n"
         "  -rdynamic                    add all symbols to the dynamic symbol table\n"
         "  -rpath [path]                add directory to the runtime library search path\n"
+        "Test Options:\n"
+        "  --test-filter [text]         skip tests that do not match filter\n"
+        "  --test-name-prefix [text]    add prefix to all tests\n"
     , arg0);
     return EXIT_FAILURE;
 }
@@ -151,6 +154,8 @@ int main(int argc, char **argv) {
     ZigList<const char *> rpath_list = {0};
     bool each_lib_rpath = false;
     ZigList<const char *> objects = {0};
+    const char *test_filter = nullptr;
+    const char *test_name_prefix = nullptr;
 
     if (argc >= 2 && strcmp(argv[1], "build") == 0) {
         const char *zig_exe_path = arg0;
@@ -341,6 +346,10 @@ int main(int argc, char **argv) {
                     linker_script = argv[i];
                 } else if (strcmp(arg, "-rpath") == 0) {
                     rpath_list.append(argv[i]);
+                } else if (strcmp(arg, "--test-filter") == 0) {
+                    test_filter = argv[i];
+                } else if (strcmp(arg, "--test-name-prefix") == 0) {
+                    test_name_prefix = argv[i];
                 } else {
                     fprintf(stderr, "Invalid argument: %s\n", arg);
                     return usage(arg0);
@@ -562,6 +571,14 @@ int main(int argc, char **argv) {
                 codegen_set_mios_version_min(g, buf_create_from_str(mios_version_min));
             }
 
+            if (test_filter) {
+                codegen_set_test_filter(g, buf_create_from_str(test_filter));
+            }
+
+            if (test_name_prefix) {
+                codegen_set_test_name_prefix(g, buf_create_from_str(test_name_prefix));
+            }
+
             if (cmd == CmdBuild) {
                 codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code);
                 codegen_link(g, out_file);
std/build.zig
@@ -10,7 +10,7 @@ const StdIo = os.ChildProcess.StdIo;
 const Term = os.ChildProcess.Term;
 const BufSet = @import("buf_set.zig").BufSet;
 const BufMap = @import("buf_map.zig").BufMap;
-const fmt = @import("fmt.zig");
+const fmt_lib = @import("fmt.zig");
 
 error ExtraArg;
 error UncleanExit;
@@ -189,7 +189,7 @@ pub const Builder = struct {
     }
 
     pub fn addLog(self: &Builder, comptime format: []const u8, args: ...) -> &LogStep {
-        const data = %%fmt.allocPrint(self.allocator, format, args);
+        const data = self.fmt(format, args);
         const log_step = %%self.allocator.create(LogStep);
         *log_step = LogStep.init(self, data);
         return log_step;
@@ -543,6 +543,10 @@ pub const Builder = struct {
     fn pathFromRoot(self: &Builder, rel_path: []const u8) -> []u8 {
         return %%os.path.join(self.allocator, self.build_root, rel_path);
     }
+
+    pub fn fmt(self: &Builder, comptime format: []const u8, args: ...) -> []u8 {
+        return %%fmt_lib.allocPrint(self.allocator, format, args);
+    }
 };
 
 const Version = struct {
@@ -891,19 +895,16 @@ pub const LinkStep = struct {
     fn computeOutFileName(self: &LinkStep) {
         switch (self.out_type) {
             OutType.Exe => {
-                self.out_filename = %%fmt.allocPrint(self.builder.allocator, "{}{}",
-                    self.name, self.target.exeFileExt());
+                self.out_filename = self.builder.fmt("{}{}", self.name, self.target.exeFileExt());
             },
             OutType.Lib => {
                 if (self.static) {
-                    self.out_filename = %%fmt.allocPrint(self.builder.allocator, "lib{}.a", self.name);
+                    self.out_filename = self.builder.fmt("lib{}.a", self.name);
                 } else {
-                    self.out_filename = %%fmt.allocPrint(self.builder.allocator, "lib{}.so.{d}.{d}.{d}",
+                    self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}",
                         self.name, self.version.major, self.version.minor, self.version.patch);
-                    self.major_only_filename = %%fmt.allocPrint(self.builder.allocator,
-                        "lib{}.so.{d}", self.name, self.version.major);
-                    self.name_only_filename = %%fmt.allocPrint(self.builder.allocator,
-                        "lib{}.so", self.name);
+                    self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);
+                    self.name_only_filename = self.builder.fmt("lib{}.so", self.name);
                 }
             },
         }
@@ -1051,15 +1052,19 @@ pub const TestStep = struct {
     release: bool,
     verbose: bool,
     link_libs: BufSet,
+    name_prefix: []const u8,
+    filter: ?[]const u8,
 
     pub fn init(builder: &Builder, root_src: []const u8) -> TestStep {
-        const step_name = %%fmt.allocPrint(builder.allocator, "test {}", root_src);
+        const step_name = builder.fmt("test {}", root_src);
         TestStep {
             .step = Step.init(step_name, builder.allocator, make),
             .builder = builder,
             .root_src = root_src,
             .release = false,
             .verbose = false,
+            .name_prefix = "",
+            .filter = null,
             .link_libs = BufSet.init(builder.allocator),
         }
     }
@@ -1076,6 +1081,14 @@ pub const TestStep = struct {
         %%self.link_libs.put(name);
     }
 
+    pub fn setNamePrefix(self: &TestStep, text: []const u8) {
+        self.name_prefix = text;
+    }
+
+    pub fn setFilter(self: &TestStep, text: ?[]const u8) {
+        self.filter = text;
+    }
+
     fn make(step: &Step) -> %void {
         const self = @fieldParentPtr(TestStep, "step", step);
         const builder = self.builder;
@@ -1094,6 +1107,16 @@ pub const TestStep = struct {
             %%zig_args.append("--release");
         }
 
+        if (const filter ?= self.filter) {
+            %%zig_args.append("--test-filter");
+            %%zig_args.append(filter);
+        }
+
+        if (self.name_prefix.len != 0) {
+            %%zig_args.append("--test-name-prefix");
+            %%zig_args.append(self.name_prefix);
+        }
+
         {
             var it = self.link_libs.iterator();
             while (true) {
@@ -1169,14 +1192,12 @@ pub const CLibrary = struct {
 
     fn computeOutFileName(self: &CLibrary) {
         if (self.static) {
-            self.out_filename = %%fmt.allocPrint(self.builder.allocator, "lib{}.a", self.name);
+            self.out_filename = self.builder.fmt("lib{}.a", self.name);
         } else {
-            self.out_filename = %%fmt.allocPrint(self.builder.allocator, "lib{}.so.{d}.{d}.{d}",
+            self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}",
                 self.name, self.version.major, self.version.minor, self.version.patch);
-            self.major_only_filename = %%fmt.allocPrint(self.builder.allocator,
-                "lib{}.so.{d}", self.name, self.version.major);
-            self.name_only_filename = %%fmt.allocPrint(self.builder.allocator,
-                "lib{}.so", self.name);
+            self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);
+            self.name_only_filename = self.builder.fmt("lib{}.so", self.name);
         }
     }
 
@@ -1235,7 +1256,7 @@ pub const CLibrary = struct {
             %%cc_args.append(source_file);
 
             // TODO don't dump the .o file in the same place as the source file
-            const o_file = %%fmt.allocPrint(builder.allocator, "{}{}", source_file, self.target.oFileExt());
+            const o_file = builder.fmt("{}{}", source_file, self.target.oFileExt());
             defer builder.allocator.free(o_file);
             %%cc_args.append("-o");
             %%cc_args.append(o_file);
@@ -1262,8 +1283,7 @@ pub const CLibrary = struct {
             %%cc_args.append("-fPIC");
             %%cc_args.append("-shared");
 
-            const soname_arg = %%fmt.allocPrint(builder.allocator, "-Wl,-soname,lib{}.so.{d}",
-                self.name, self.version.major);
+            const soname_arg = builder.fmt("-Wl,-soname,lib{}.so.{d}", self.name, self.version.major);
             defer builder.allocator.free(soname_arg);
             %%cc_args.append(soname_arg);
 
@@ -1372,7 +1392,7 @@ pub const CExecutable = struct {
             %%cc_args.append(source_file);
 
             // TODO don't dump the .o file in the same place as the source file
-            const o_file = %%fmt.allocPrint(builder.allocator, "{}{}", source_file, self.target.oFileExt());
+            const o_file = builder.fmt("{}{}", source_file, self.target.oFileExt());
             defer builder.allocator.free(o_file);
             %%cc_args.append("-o");
             %%cc_args.append(o_file);
@@ -1400,7 +1420,7 @@ pub const CExecutable = struct {
         %%cc_args.append("-o");
         %%cc_args.append(self.name);
 
-        const rpath_arg = %%fmt.allocPrint(builder.allocator, "-Wl,-rpath,{}", builder.out_dir);
+        const rpath_arg = builder.fmt("-Wl,-rpath,{}", builder.out_dir);
         defer builder.allocator.free(rpath_arg);
         %%cc_args.append(rpath_arg);
 
@@ -1462,9 +1482,7 @@ pub const InstallCLibraryStep = struct {
     pub fn init(builder: &Builder, lib: &CLibrary) -> InstallCLibraryStep {
         var self = InstallCLibraryStep {
             .builder = builder,
-            .step = Step.init(
-                %%fmt.allocPrint(builder.allocator, "install {}", lib.step.name),
-                builder.allocator, make),
+            .step = Step.init(builder.fmt("install {}", lib.step.name), builder.allocator, make),
             .lib = lib,
             .dest_file = undefined,
         };
@@ -1497,9 +1515,7 @@ pub const InstallFileStep = struct {
     pub fn init(builder: &Builder, src_path: []const u8, dest_path: []const u8) -> InstallFileStep {
         return InstallFileStep {
             .builder = builder,
-            .step = Step.init(
-                %%fmt.allocPrint(builder.allocator, "install {}", src_path),
-                builder.allocator, make),
+            .step = Step.init(builder.fmt("install {}", src_path), builder.allocator, make),
             .src_path = src_path,
             .dest_path = dest_path,
         };
@@ -1521,9 +1537,7 @@ pub const WriteFileStep = struct {
     pub fn init(builder: &Builder, file_path: []const u8, data: []const u8) -> WriteFileStep {
         return WriteFileStep {
             .builder = builder,
-            .step = Step.init(
-                %%fmt.allocPrint(builder.allocator, "writefile {}", file_path),
-                builder.allocator, make),
+            .step = Step.init(builder.fmt("writefile {}", file_path), builder.allocator, make),
             .file_path = file_path,
             .data = data,
         };
@@ -1550,9 +1564,7 @@ pub const LogStep = struct {
     pub fn init(builder: &Builder, data: []const u8) -> LogStep {
         return LogStep {
             .builder = builder,
-            .step = Step.init(
-                %%fmt.allocPrint(builder.allocator, "log {}", data),
-                builder.allocator, make),
+            .step = Step.init(builder.fmt("log {}", data), builder.allocator, make),
             .data = data,
         };
     }
test/self_hosted.zig → test/behavior.zig
File renamed without changes
test/tests.zig
@@ -341,8 +341,8 @@ pub const CompareOutputContext = struct {
             },
             Special.None => {
                 for ([]bool{false, true}) |release| {
-                    const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "{} ({})",
-                        case.name, if (release) "release" else "debug");
+                    const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "{} {} ({})",
+                        "compare-output", case.name, if (release) "release" else "debug");
                     if (const filter ?= self.test_filter) {
                         if (mem.indexOf(u8, annotated_case_name, filter) == null)
                             continue;
build.zig
@@ -5,18 +5,20 @@ pub fn build(b: &Builder) {
     const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
     const test_step = b.step("test", "Run all the tests");
 
-    const self_hosted_tests = b.step("test-self-hosted", "Run the self-hosted tests");
-    test_step.dependOn(self_hosted_tests);
+    const behavior_tests = b.step("test-behavior", "Run the behavior tests");
+    test_step.dependOn(behavior_tests);
     for ([]bool{false, true}) |release| {
         for ([]bool{false, true}) |link_libc| {
-            const these_tests = b.addTest("test/self_hosted.zig");
-            // TODO add prefix to test names
-            // TODO pass test_filter to these_tests
+            const these_tests = b.addTest("test/behavior.zig");
+            these_tests.setNamePrefix(b.fmt("behavior-{}-{} ",
+                if (release) "release" else "debug",
+                if (link_libc) "c" else "bare"));
+            these_tests.setFilter(test_filter);
             these_tests.setRelease(release);
             if (link_libc) {
                 these_tests.linkLibrary("c");
             }
-            self_hosted_tests.dependOn(&these_tests.step);
+            behavior_tests.dependOn(&these_tests.step);
         }
     }
 
@@ -25,8 +27,10 @@ pub fn build(b: &Builder) {
     for ([]bool{false, true}) |release| {
         for ([]bool{false, true}) |link_libc| {
             const these_tests = b.addTest("std/index.zig");
-            // TODO add prefix to test names
-            // TODO pass test_filter to these_tests
+            these_tests.setNamePrefix(b.fmt("std-{}-{} ",
+                if (release) "release" else "debug",
+                if (link_libc) "c" else "bare"));
+            these_tests.setFilter(test_filter);
             these_tests.setRelease(release);
             if (link_libc) {
                 these_tests.linkLibrary("c");