Skip to content

Commit 4eaca12

Browse files
committed
chore: moved tests into test/ folder
1 parent e283994 commit 4eaca12

11 files changed

Lines changed: 237 additions & 198 deletions

File tree

AGENTS.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,22 @@ try writer.flush();
9898
```
9999

100100
### Testing
101-
- Unit tests go in the same file as the code being tested
102-
- Integration tests go in `test/main.zig`
101+
- **All tests go in the `test/` folder, NOT in source files**
102+
- Tests import the shgit module via `const shgit = @import("shgit")`
103+
- Unit tests for specific modules go in `test/main.zig`
104+
- Integration tests also go in `test/main.zig`
105+
- The `src/root.zig` file exports all modules for testing
106+
- The `test/main.zig` file must include:
107+
```zig
108+
const std = @import("std");
109+
const shgit = @import("shgit");
110+
111+
test {
112+
std.testing.refAllDeclsRecursive(@This());
113+
}
114+
```
103115
- Use `std.testing.allocator` for memory leak detection
116+
- Access modules via `shgit.module_name` (e.g., `shgit.git`, `shgit.config`, `shgit.fs_utils`)
104117

105118
## CLI Argument Parsing (argzon)
106119
Arguments defined in `src/args.zon` using ZON format:

build.zig

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,36 +98,28 @@ pub fn build(b: *std.Build) void {
9898
}
9999

100100
// Tests (only available in default mode)
101-
if (argzon_mod_for_tests) |argzon_mod| {
102-
// Unit tests for src/
103-
const src_tests = b.addTest(.{
104-
.root_module = b.createModule(.{
105-
.root_source_file = b.path("src/main.zig"),
106-
.target = target,
107-
.optimize = optimize,
108-
.imports = &.{
109-
.{ .name = "argzon", .module = argzon_mod },
110-
.{ .name = "asset", .module = asset_mod },
111-
},
112-
}),
113-
.filters = if (test_filter) |f| &.{f} else &.{},
101+
if (argzon_mod_for_tests) |_| {
102+
// Create shgit module for tests
103+
const shgit_mod = b.addModule("shgit", .{
104+
.root_source_file = b.path("src/root.zig"),
114105
});
115-
const run_src_tests = b.addRunArtifact(src_tests);
116106

117107
// Integration tests in test/
118108
const integration_tests = b.addTest(.{
119109
.root_module = b.createModule(.{
120110
.root_source_file = b.path("test/main.zig"),
121111
.target = target,
122112
.optimize = optimize,
113+
.imports = &.{
114+
.{ .name = "shgit", .module = shgit_mod },
115+
},
123116
}),
124117
.filters = if (test_filter) |f| &.{f} else &.{},
125118
});
126119
const run_integration_tests = b.addRunArtifact(integration_tests);
127120

128121
// Test step
129122
const test_step = b.step("test", "Run all tests");
130-
test_step.dependOn(&run_src_tests.step);
131123
test_step.dependOn(&run_integration_tests.step);
132124
}
133125
}

src/commands/clone.zig

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,3 @@ fn extractRepoName(url: []const u8) ?[]const u8 {
118118
if (name.len > 0) return name;
119119
return null;
120120
}
121-
122-
test "extractRepoName" {
123-
try std.testing.expectEqualStrings("repo", extractRepoName("https://github.com/user/repo.git").?);
124-
try std.testing.expectEqualStrings("repo", extractRepoName("https://github.com/user/repo").?);
125-
try std.testing.expectEqualStrings("repo", extractRepoName("git@github.com:user/repo.git").?);
126-
try std.testing.expectEqualStrings("myrepo", extractRepoName("/path/to/myrepo").?);
127-
}

src/commands/link.zig

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,3 @@ fn linkFile(
119119
// Add to local git exclude
120120
try git.addLocalExclude(allocator, target_base, rel_path);
121121
}
122-
123-
test "link module compiles" {
124-
// Basic compilation test
125-
_ = linkDirectory;
126-
_ = linkFile;
127-
}

src/commands/worktree.zig

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,3 @@ fn matchesPattern(path: []const u8, pattern: []const u8) bool {
288288

289289
return false;
290290
}
291-
292-
test "matchesPattern" {
293-
try std.testing.expect(matchesPattern(".env", ".env"));
294-
try std.testing.expect(matchesPattern("src/.env", ".env"));
295-
try std.testing.expect(matchesPattern(".env.local", ".env.local"));
296-
try std.testing.expect(!matchesPattern(".env.local", ".env"));
297-
try std.testing.expect(matchesPattern("src/config/.env", ".env"));
298-
}

src/config.zig

Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub fn loadConfig(allocator: std.mem.Allocator, shgit_root: []const u8) !Config
9090
return parseConfig(allocator, content);
9191
}
9292

93-
fn parseConfig(allocator: std.mem.Allocator, content: []const u8) !Config {
93+
pub fn parseConfig(allocator: std.mem.Allocator, content: []const u8) !Config {
9494
// Simple ZON-like parsing for sync_patterns
9595
var cfg = Config{};
9696
var patterns: std.ArrayList(SyncPattern) = .empty;
@@ -238,62 +238,3 @@ pub fn initShgitStructure(allocator: std.mem.Allocator, path: []const u8) !void
238238

239239
log.info("created shgit structure at {s}", .{path});
240240
}
241-
242-
test "parseConfig new format" {
243-
const content =
244-
\\.{
245-
\\ .sync_patterns = .{
246-
\\ .{
247-
\\ .pattern = ".env",
248-
\\ .mode = .symlink,
249-
\\ },
250-
\\ .{
251-
\\ .pattern = ".env.local",
252-
\\ .mode = .copy,
253-
\\ },
254-
\\ },
255-
\\ .main_repo = "myrepo",
256-
\\}
257-
;
258-
259-
var cfg = try parseConfig(std.testing.allocator, content);
260-
defer cfg.deinit(std.testing.allocator);
261-
262-
try std.testing.expectEqual(@as(usize, 2), cfg.sync_patterns.len);
263-
try std.testing.expectEqualStrings(".env", cfg.sync_patterns[0].pattern);
264-
try std.testing.expectEqual(SyncMode.symlink, cfg.sync_patterns[0].mode);
265-
try std.testing.expectEqualStrings(".env.local", cfg.sync_patterns[1].pattern);
266-
try std.testing.expectEqual(SyncMode.copy, cfg.sync_patterns[1].mode);
267-
try std.testing.expectEqualStrings("myrepo", cfg.main_repo.?);
268-
}
269-
270-
test "parseConfig legacy format" {
271-
const content =
272-
\\.{
273-
\\ .sync_patterns = .{
274-
\\ ".env",
275-
\\ ".env.local",
276-
\\ },
277-
\\ .main_repo = "myrepo",
278-
\\}
279-
;
280-
281-
var cfg = try parseConfig(std.testing.allocator, content);
282-
defer cfg.deinit(std.testing.allocator);
283-
284-
try std.testing.expectEqual(@as(usize, 2), cfg.sync_patterns.len);
285-
try std.testing.expectEqualStrings(".env", cfg.sync_patterns[0].pattern);
286-
try std.testing.expectEqual(SyncMode.symlink, cfg.sync_patterns[0].mode);
287-
try std.testing.expectEqualStrings(".env.local", cfg.sync_patterns[1].pattern);
288-
try std.testing.expectEqual(SyncMode.symlink, cfg.sync_patterns[1].mode);
289-
try std.testing.expectEqualStrings("myrepo", cfg.main_repo.?);
290-
}
291-
292-
test "parseConfig empty" {
293-
const content = ".{\n}\n";
294-
var cfg = try parseConfig(std.testing.allocator, content);
295-
defer cfg.deinit(std.testing.allocator);
296-
297-
try std.testing.expectEqual(@as(usize, 0), cfg.sync_patterns.len);
298-
try std.testing.expect(cfg.main_repo == null);
299-
}

src/fs_utils.zig

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -60,31 +60,3 @@ pub fn relativePath(allocator: std.mem.Allocator, from: []const u8, to: []const
6060

6161
return result.toOwnedSlice(allocator);
6262
}
63-
64-
test "relativePath same directory" {
65-
const allocator = std.testing.allocator;
66-
const rel = try relativePath(allocator, "/a/b/file1", "/a/b/file2");
67-
defer allocator.free(rel);
68-
try std.testing.expectEqualStrings("file2", rel);
69-
}
70-
71-
test "relativePath parent directory" {
72-
const allocator = std.testing.allocator;
73-
const rel = try relativePath(allocator, "/a/b/c/file", "/a/b/target");
74-
defer allocator.free(rel);
75-
try std.testing.expectEqualStrings("../target", rel);
76-
}
77-
78-
test "relativePath sibling directory" {
79-
const allocator = std.testing.allocator;
80-
const rel = try relativePath(allocator, "/a/b/c/file", "/a/x/y/target");
81-
defer allocator.free(rel);
82-
try std.testing.expectEqualStrings("../../x/y/target", rel);
83-
}
84-
85-
test "relativePath deeply nested" {
86-
const allocator = std.testing.allocator;
87-
const rel = try relativePath(allocator, "/repo/worktree/.vscode/settings.json", "/link/.vscode/settings.json");
88-
defer allocator.free(rel);
89-
try std.testing.expectEqualStrings("../../../link/.vscode/settings.json", rel);
90-
}

src/git.zig

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -158,45 +158,3 @@ pub fn addLocalExclude(allocator: std.mem.Allocator, repo_path: []const u8, rel_
158158

159159
log.debug("added {s} to local exclude", .{rel_path});
160160
}
161-
162-
test "addLocalExclude with submodule" {
163-
const testing = std.testing;
164-
var arena = std.heap.ArenaAllocator.init(testing.allocator);
165-
defer arena.deinit();
166-
const allocator = arena.allocator();
167-
168-
// Create a temporary test directory structure
169-
var tmp_dir = testing.tmpDir(.{});
170-
defer tmp_dir.cleanup();
171-
172-
// Create repo structure similar to submodule
173-
try tmp_dir.dir.makePath("repo");
174-
try tmp_dir.dir.makePath(".git/modules/repo/info");
175-
176-
// Write .git file with relative gitdir (like submodules do)
177-
const git_file = try tmp_dir.dir.createFile("repo/.git", .{});
178-
defer git_file.close();
179-
try git_file.writeAll("gitdir: ../.git/modules/repo\n");
180-
181-
// Create exclude file
182-
const exclude_file = try tmp_dir.dir.createFile(".git/modules/repo/info/exclude", .{});
183-
defer exclude_file.close();
184-
try exclude_file.writeAll("# test exclude file\n");
185-
186-
// Get absolute path to repo
187-
const tmp_path = try tmp_dir.dir.realpathAlloc(allocator, ".");
188-
const repo_path = try std.fs.path.join(allocator, &.{ tmp_path, "repo" });
189-
190-
// Add a file to local exclude
191-
try addLocalExclude(allocator, repo_path, ".env");
192-
193-
// Read exclude file and verify it was added
194-
const exclude_content = try tmp_dir.dir.readFileAlloc(allocator, ".git/modules/repo/info/exclude", 4096);
195-
try testing.expect(std.mem.indexOf(u8, exclude_content, "/.env") != null);
196-
}
197-
198-
test "git module compiles" {
199-
_ = init;
200-
_ = addSubmodule;
201-
_ = addWorktree;
202-
}

src/main.zig

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,3 @@ pub fn main() !void {
5252
try stdout.flush();
5353
}
5454
}
55-
56-
test {
57-
std.testing.refAllDecls(@This());
58-
}

src/root.zig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Root module for shgit - exports all public modules for testing
2+
3+
pub const config = @import("config.zig");
4+
pub const git = @import("git.zig");
5+
pub const fs_utils = @import("fs_utils.zig");
6+
7+
// Commands
8+
pub const commands = struct {
9+
pub const clone = @import("commands/clone.zig");
10+
pub const link = @import("commands/link.zig");
11+
pub const worktree = @import("commands/worktree.zig");
12+
pub const sync = @import("commands/sync.zig");
13+
pub const init = @import("commands/init.zig");
14+
};

0 commit comments

Comments
 (0)