198 lines
No EOL
6.5 KiB
Text
198 lines
No EOL
6.5 KiB
Text
---
|
|
.title = "Testing",
|
|
.date = @date("2025-10-20T00:00:00"),
|
|
.author = "Igor Támara",
|
|
.layout = "tutorial.shtml",
|
|
.draft = false,
|
|
.custom = {
|
|
.githubedit = "/docs/testing.smd",
|
|
.codepath ="test",
|
|
},
|
|
---
|
|
Currently flow tests are aimed to work as unit tests.
|
|
|
|
If new to zig, it always is a good idea to review the
|
|
[zig tests documentation](https://ziglang.org/documentation/master/#Zig-Test)
|
|
and also an
|
|
[introduction to testing](https://pedropark99.github.io/zig-book/Chapters/03-unittests.html).
|
|
|
|
To work with tests you will need to:
|
|
|
|
* [Clone](https://github.com/neurocyte/flow) the repository
|
|
* Have [zig installed](https://ziglang.org/download/). Highly recommended to use
|
|
[anyzig](https://github.com/marler8997/anyzig)
|
|
|
|
Flow tests are placed in the directory `test`.
|
|
|
|
## [Running the tests]($section.id("running_tests"))
|
|
|
|
To run the full set of tests, inside flow, use `f5`, which runs a task that
|
|
invokes:
|
|
|
|
```
|
|
zig build test
|
|
```
|
|
|
|
it will work if flow was invoked from the project root, which is the same
|
|
place that you would normally run the tests when on the terminal.
|
|
|
|
### [Run a particular test]($section.id("running_a_test"))
|
|
|
|
To run an specific test use `Dtest-filter` option with the name of your
|
|
test, i.e., for the test called **test_block_name** use:
|
|
|
|
```
|
|
zig build test -Dtest-filter="test_block_name"
|
|
```
|
|
|
|
## [Adding tests]($section.id("first_test"))
|
|
|
|
Tests are needed when:
|
|
|
|
* There is some logic that might be difficult to understand given it's
|
|
nature, for example, when there are a lot of branching
|
|
* You find something that could be changed in the future affecting the
|
|
current behavior
|
|
* A bug is fixed
|
|
* A defined behavior could be thought different, for example when in a
|
|
mode, it was defined that something might diverge from other programs.
|
|
|
|
Tests are placed under `test` directory. Add your test in the file that
|
|
exercises the functionality and makes proof of it behaving as expected.
|
|
Maintain the logic test as simple as possible. It's possible to add
|
|
additional functions to make the tests readable and extendable though.
|
|
|
|
public functions are straightforward tested, while there are some
|
|
conventions for testing private functions.
|
|
|
|
### [Testing private functions]($section.id("private_functions_testing"))
|
|
|
|
Some internal logic of a module can be tested without the need to be
|
|
exposed to other modules.
|
|
|
|
In such cases the module that has the logic should provide a pub
|
|
`test_internal`, by convention, exposing the target functionalities to
|
|
be tested.
|
|
|
|
For example in `src/tui/mode/helix.zig`, `test_internal` exposes the
|
|
private function
|
|
|
|
```zig
|
|
fn move_cursor_long_word_right_end(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void
|
|
```
|
|
|
|
with
|
|
|
|
```zig
|
|
pub const test_internal = struct {
|
|
pub const move_cursor_long_word_right = private.move_cursor_long_word_right;
|
|
.
|
|
.
|
|
.
|
|
};
|
|
```
|
|
|
|
And in `test/tests_helix.zig`, helix is imported as
|
|
|
|
```zig
|
|
const helix = @import("tui").exports.mode.helix;
|
|
```
|
|
|
|
Later on using the function `move_cursor_long_word_right` as
|
|
|
|
```zig
|
|
try helix.test_internal.move_cursor_long_word_right_end(root, cursor, the_metrics);
|
|
```
|
|
|
|
In case there is need of a new test file for concern separation, continue
|
|
to the next section.
|
|
|
|
## [Adding a new test file]($section.id("new_test_file"))
|
|
|
|
Three steps are required for adding a new test file:
|
|
|
|
1. Create a new test file
|
|
1. Include the test to the set of tests
|
|
1. Optionally, make available a module to the build system
|
|
for your particular test
|
|
|
|
### [Create the test file]($section.id("create_test_file"))
|
|
|
|
Place your test file under `test` directory, the name should be prefixed
|
|
with `tests_`.
|
|
|
|
For the rest of this section we will use as a sample
|
|
`tests_project_manager.zig`.
|
|
|
|
### [Include the test file]($section.id("linking_tests"))
|
|
|
|
Tests files are linked via `test/tests.zig`, import your new test_file
|
|
alphabetically as in our sample:
|
|
|
|
```zig
|
|
pub const project_manager = @import("tests_project_manager.zig");
|
|
```
|
|
|
|
### [Import required modules when building tests]($section.id("import_in_build_zig"))
|
|
|
|
In `build.zig` import the required module under `tests.root_module`, for
|
|
the current example:
|
|
|
|
```zig
|
|
tests.root_module.addImport("project_manager", project_manager_mod);
|
|
```
|
|
|
|
[Sample](https://github.com/neurocyte/flow/commit/e053a0dcf4b4c93f1ce1fe6d14a3c04e886d393c)
|
|
of adding a new test file for project manager.
|
|
|
|
## [FAQ on tests]($section.id("faq"))
|
|
|
|
### [I need to test something that requires importing the editor ¿What do I do?]($section.id("import_editor"))
|
|
|
|
There are two paths from here:
|
|
|
|
1. Refactor your code to test the lower level functions
|
|
1. Extend the tests to automate via external tools
|
|
|
|
### [Refactor to test lower level functions]($section.id("lower_level"))
|
|
|
|
Refactor the functions involved in the functionality to make them
|
|
not rely directly with editor and other higher level components, and
|
|
test the lower level ones.
|
|
|
|
For example, in `vim NORMAL` mode, the key `F` looks for a character to
|
|
the left in the same line, if the character is not found it goes to the
|
|
beginning of the line. In the case of `hx NOR` mode, the `F` key looks
|
|
for a character to the beginning of the file, if found, makes a
|
|
selection from the initial cursor position to the character found, if
|
|
not, no selection is made and the cursor is not moved at all.
|
|
|
|
|
|
Given that Helix has that movement and selection functionality, finding
|
|
the character was the first action and hence the search function is
|
|
the one tested in `test/tests_helix.zig`, given that positioning the
|
|
selection is rather simple compared to looking for the character. It
|
|
was decided to test the search functionality making it not depend
|
|
on editor, but only on the cursor, buffer, metrics and context, all
|
|
of them do not require graphic elements at all.
|
|
|
|
The group of functions `beyond_eol` can be seen in
|
|
[this commit](https://github.com/neurocyte/flow/pull/330/commits/baac14b3ae5243cef6461df42dae6fcf5ea15201)
|
|
and whose tests are
|
|
[here](https://github.com/neurocyte/flow/pull/330/commits/38a08aed49f4fbba18aab9ccbd3c8b9758414221).
|
|
|
|
### [Use additional tools to test a running flow session]($section.id("end_to_end"))
|
|
|
|
Use additional tools to invoke the built editor and send keys to
|
|
it, modify a file and then compare the initial contents of the file
|
|
and the resulting contents of your file and the expected ones.
|
|
|
|
If in doubt about how to do something,
|
|
[please ask](https://discord.com/invite/4wvteUPphx).
|
|
|
|
## [Next steps]($section.id("next"))
|
|
|
|
* [How to contribute](/docs/contributing)
|
|
* [Personalizing keybindings](/docs/architecture/keybind)
|
|
* [Enhance flow with commands](/docs/architecture/command)
|
|
* [Other Flow topics](/docs/architecture) |