In dep.zig I import root.zig for a function declared in there.
If I now run zig test src/dep/dep.zig I get the following
error: import of file outside module path ‘…/root.zig’
This is an oversimplified sample but as far as I can see is that as soon as you have an import outside of the directory of the file you want to test than it will fail.
Is this an issue with my setup or a limitation of the zig test command? And is there a way arround this?
zig build test works fine in this case but sometimes it can be nice to be able to test some code eventhough the overal build would fail because of some unrelated code.
Its just an oversimplified sample, the same happens with the following code:
const root = @import("../root.zig");
fn functionToTest() void {
const i = root.functionToTest();
// do something with i
_ = i; // autofix
}
test "test" {
functionToTest();
}
I think this is a somewhat standard usecase right? your code can have dependencies outside the current file, the issue is that as soon as one of those dependencies is outside the same directory it goes wrong.
Haha no idea , but in your sample the test does not depend on something in a parent dir. lets say you have a test defined in a.zig. and a.zig has a dependency on b.zig. in that case it will fail. And yes you could indeed than define the tests as you did in the parent dir but I prefer to have the tests close to the source otherwise test.zig can become very large. Here a sample using your code:
.
├── a
│ └── a.zig
├── b
│ └── b.zig
└── test.zig
2 directories, 3 files
test.zig
const std = @import("std");
pub const a = @import("a/a.zig");
pub const b = @import("b/b.zig");
test {
@import("std").testing.refAllDecls(@This());
}
a/a.zig
const std = @import("std");
const b = @import("../b/b.zig");
pub fn a() void {
b.b();
}
test "test" {
a();
}
In this case test.zig is used to execute all tests but I would still like to be able to run the single test in a.zig, unfortunatly that is not possible. But indeed it can be a work around by for example defining tests_a.zig next to tests.zig that contains the a specific tests. I just had hoped that would not be needed.
The way I see it, in Zig we are sort of building pyramids, the lowest layer has access to everything above it, next layer up has access to everything above it and so on.
Then you can use modules to refer to the base layer of another pyramid.
Basically if something needs to be accessed from multiple files, it should have a common parent directory and be at the same level or below the file that refers to it.
In this analogy, this prevents us from building inverted pyramids where layers higher up get bigger and wider, it is a sort of loose ordering on how things can be organized.
Personally it took a bit to get used to, but now I appreciate that I don’t have to follow crazy redirecting relative imports that send me to crazy places all over the place in that folder structure. One of the good things about it is that folders can be seen as sub units in some sense.
How would I get access to the enum Mode in my native window? Using your anology I would need to declare Mode in win32/native_window.zig but that would mean I would need to redeclare it for all platforms.
I could remove the platform specific directory and call it win32_window.zig or something but I would like to be able to organize it in some way.
I searched my code base and there is one place where I actually use .. to navigate in a deeper folder structure one level up to refer to a bunch of types that are common to a bunch of different files. I guess there are places where the analogy fails.
I think the problem might be that the zig test command doesn’t seem to have support for being used for projects with more complex imports, I think you need to use a custom build step to define your test run similar to this (but for testing instead of docs) Zig Autodoc : exclude anonymous imports? - #2 by dimdin
Basically I think the zig test command is only for simple cases, for more complex ones define a build step that does the testing.
I don’t quite know how the zig test command determines the root of the module, you also could try calling it from a parent directory, but I am not sure if that works.
Have you tried cd src and the zig test dep/dep.zig so that theoretically the command may have the same root directory?
I just know that I had cases where I gave up trying to use zig test and then just used testing via a build system run step.
Why do you want to have platform-specific code in subdirectories? I see it uses non-platform-specific code Mode, so the separation seems broken already? Maybe an interface is something you could consider here? Not sure though if that solves the problem you have in mind.
Concerning testing (and since my question on autodoc was mentioned - which is not related to a directory structure btw.), I really like to configure and call specific tests via steps in the build.zig. That way, you can for example use library code in a test just like an application would use it. A nice side effect is that you can put your tests in separate files in a separate directory
I feel like zig test should take an argument that is the main.zig/root.zig so it can include items in the same way the build would. The suggestions here feel like a bandaid.
More baindaids, I would use test but that means:
Moving test cases to the root folder.
Marking items as public that would not typically be pubilc to support test cases.
Moving items included from a sibling folder into the same folder, to make some of the test work, or worse making a copy.
I believe that the proper solution would be more akin to zig test accepting a root file: zig test ./token_test.zig --test_root=main.zig