pub const TestFileCache = struct { files: std.StringHashMap([]const u8), allocator: std.mem.Allocator, pub const test_files = [_][]const u8{ // Control Flow "control_flow/if", "control_flow/if_error", "control_flow/if_block", "control_flow/if_only", "control_flow/if_only_block", "control_flow/for", "control_flow/for_block", "control_flow/switch", "control_flow/switch_capture", "control_flow/switch_multicaseval", "control_flow/switch_block", "control_flow/while", "control_flow/while_block", // Nested Control Flow (2-level nesting) "control_flow/if_if", "control_flow/if_for", "control_flow/if_switch", "control_flow/if_while", "control_flow/if_if_only", "control_flow/if_if_only_block", "control_flow/if_else_if", "control_flow/if_capture", "control_flow/for_if", "control_flow/for_for", "control_flow/for_switch", "control_flow/for_while", "control_flow/switch_if", "control_flow/switch_for", "control_flow/switch_switch", "control_flow/switch_while", "control_flow/while_if", "control_flow/while_for", "control_flow/while_switch", "control_flow/while_while", "control_flow/while_capture", "control_flow/while_else", "control_flow/while_error", // Deeply Nested Control Flow (3-level nesting) "control_flow/if_for_if", "control_flow/if_while_if", // Expression "expression/text", "expression/format", "expression/component", "expression/mixed", "expression/struct_access", "expression/function_call", "expression/multiline_string", // Component "component/basic", "component/multiple", "component/nested", "component/children_only", "component/contexted", "component/contexted_props", "component/react", "component/csr_react_multiple", "component/csr_zig", "component/import", "component/root_cmp", "component/caching", // Attribute "attribute/builtin", "attribute/component", "attribute/builtin_escaping", "attribute/dynamic", "attribute/types", "attribute/shorthand", "attribute/spread", // Element "element/void", "element/empty", "element/nested", "element/fragment", "element/fragment_root", // Expression "expression/optional", "expression/template", // Raw "escaping/pre", "escaping/quotes", }; pub fn init(allocator: std.mem.Allocator) !TestFileCache { var cache = TestFileCache{ .files = std.StringHashMap([]const u8).init(allocator), .allocator = allocator, }; const base_path = "test/data/"; // Load .zx and .zig files for each test file for (test_files) |file_path| { for ([_]struct { ext: []const u8 }{ .{ .ext = ".zx" }, .{ .ext = ".zig" } }) |ext_info| { const full_path = try std.fmt.allocPrint(allocator, "{s}{s}{s}", .{ base_path, file_path, ext_info.ext }); defer allocator.free(full_path); const content = std.Io.Dir.cwd().readFileAlloc( std.testing.io, full_path, allocator, .limited(std.math.maxInt(usize)), ) catch |err| switch (err) { error.FileNotFound => continue, else => return err, }; const cache_key = try std.fmt.allocPrint(allocator, "{s}{s}", .{ file_path, ext_info.ext }); try cache.files.put(cache_key, content); } } return cache; } pub fn deinit(self: *TestFileCache) void { var it = self.files.iterator(); while (it.next()) |entry| { self.allocator.free(entry.key_ptr.*); self.allocator.free(entry.value_ptr.*); } self.files.deinit(); } pub fn get(self: *TestFileCache, path: []const u8) !?[]const u8 { // Check if file is already in cache if (self.files.get(path)) |content| { return content; } // File not in cache, try to fetch it from disk const base_path = "test/data/"; const full_path = try std.fmt.allocPrint(self.allocator, "{s}{s}", .{ base_path, path }); defer self.allocator.free(full_path); const content = std.Io.Dir.cwd().readFileAlloc( std.testing.io, full_path, self.allocator, .limited(std.math.maxInt(usize)), ) catch |err| switch (err) { error.FileNotFound => return null, else => return err, }; // Cache the file for future calls const cache_key = try std.fmt.allocPrint(self.allocator, "{s}", .{path}); try self.files.put(cache_key, content); return content; } }; pub fn shouldRunSlowTest() bool { return testing.environ.contains(testing.allocator, "E2E") catch false; } pub fn shouldRunNetworkTest() bool { return testing.environ.contains(testing.allocator, "E2E_NET") catch false; } const std = @import("std"); const testing = std.testing; const zx = @import("zx");