hx: attempt to add tests in separate file
This commit is contained in:
parent
b524b97146
commit
a64d7c3afa
5 changed files with 273 additions and 2 deletions
64
build.zig
64
build.zig
|
|
@ -621,6 +621,67 @@ pub fn build_exe(
|
|||
},
|
||||
});
|
||||
|
||||
const helix_mod = b.createModule(.{
|
||||
.root_source_file = b.path("src/tui/mode/helix.zig"),
|
||||
});
|
||||
// const editor_mod = b.createModule(.{
|
||||
// .root_source_file = b.path("src/tui/editor.zig"),
|
||||
// });
|
||||
// const Widget_mod = b.createModule(.{
|
||||
// .root_source_file = b.path("src/tui/Widget.zig"),
|
||||
// });
|
||||
// const mainview_mod = b.createModule(.{
|
||||
// .root_source_file = b.path("src/tui/mainview.zig"),
|
||||
// });
|
||||
// const WidgetList_mod = b.createModule(.{
|
||||
// .root_source_file = b.path("src/tui/WidgetList.zig"),
|
||||
// });
|
||||
// const MessageFilter_mod = b.createModule(.{
|
||||
// .root_source_file = b.path("src/tui/MessageFilter.zig"),
|
||||
// });
|
||||
// const editor_gutter_mod = b.createModule(.{
|
||||
// .root_source_file = b.path("src/tui/editor_gutter.zig"),
|
||||
// });
|
||||
// const scrollbar_v_mod = b.createModule(.{
|
||||
// .root_source_file = b.path("src/tui//scrollbar_v.zig"),
|
||||
// });
|
||||
// const palette_mod = b.createModule(.{
|
||||
// .root_source_file = b.path("src/tui/mode/overlay/palette.zig"),
|
||||
// });
|
||||
// const open_recent_project_mod = b.createModule(.{
|
||||
// .root_source_file = b.path("src/tui/mode/overlay/open_recent_project.zig"),
|
||||
// });
|
||||
|
||||
// const helix_test_run_cmd = blk: {
|
||||
// const tests = b.addTest(.{
|
||||
// .root_module = b.createModule(.{
|
||||
// .root_source_file = b.path("src/tui/mode/helix.zig"),
|
||||
// .target = target,
|
||||
// .optimize = optimize,
|
||||
// }),
|
||||
// });
|
||||
// tests.root_module.addImport("cbor", cbor_mod);
|
||||
// tests.root_module.addImport("command", command_mod);
|
||||
// tests.root_module.addImport("EventHandler", EventHandler_mod);
|
||||
// tests.root_module.addImport("input", input_mod);
|
||||
// tests.root_module.addImport("thespian", thespian_mod);
|
||||
// tests.root_module.addImport("log", log_mod);
|
||||
// tests.root_module.addImport("tui", tui_mod);
|
||||
// tests.root_module.addImport("helix", helix_mod);
|
||||
// tests.root_module.addImport("editor", editor_mod);
|
||||
// tests.root_module.addImport("Widget", Widget_mod);
|
||||
// tests.root_module.addImport("WidgetList", WidgetList_mod);
|
||||
// tests.root_module.addImport("mainview", mainview_mod);
|
||||
// tests.root_module.addImport("Buffer", Buffer_mod);
|
||||
// tests.root_module.addImport("MessageFilter", MessageFilter_mod);
|
||||
// tests.root_module.addImport("editor_gutter", editor_gutter_mod);
|
||||
// tests.root_module.addImport("scrollbar_v", scrollbar_v_mod);
|
||||
// tests.root_module.addImport("palette", palette_mod);
|
||||
// tests.root_module.addImport("open_recent_project", open_recent_project_mod);
|
||||
// tests.root_module.addImport("renderer", renderer_mod);
|
||||
// break :blk b.addRunArtifact(tests);
|
||||
// };
|
||||
|
||||
const exe_name = if (gui) "flow-gui" else "flow";
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
|
|
@ -712,6 +773,7 @@ pub fn build_exe(
|
|||
check_exe.root_module.addImport("version_info", b.createModule(.{ .root_source_file = version_info_file }));
|
||||
check_step.dependOn(&check_exe.step);
|
||||
|
||||
const test_filters = b.option([]const []const u8, "test-filter", "Skip tests that do not match any filter") orelse &[0][]const u8{};
|
||||
const tests = b.addTest(.{
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("test/tests.zig"),
|
||||
|
|
@ -721,6 +783,7 @@ pub fn build_exe(
|
|||
}),
|
||||
.use_llvm = use_llvm,
|
||||
.use_lld = use_llvm,
|
||||
.filters = test_filters,
|
||||
});
|
||||
|
||||
tests.pie = pie;
|
||||
|
|
@ -730,6 +793,7 @@ pub fn build_exe(
|
|||
tests.root_module.addImport("log", log_mod);
|
||||
tests.root_module.addImport("Buffer", Buffer_mod);
|
||||
tests.root_module.addImport("color", color_mod);
|
||||
tests.root_module.addImport("helix", helix_mod);
|
||||
// b.installArtifact(tests);
|
||||
|
||||
const test_run_cmd = b.addRunArtifact(tests);
|
||||
|
|
|
|||
|
|
@ -2143,11 +2143,11 @@ pub const Editor = struct {
|
|||
return false;
|
||||
}
|
||||
|
||||
fn is_whitespace(c: []const u8) bool {
|
||||
pub fn is_whitespace(c: []const u8) bool {
|
||||
return (c.len == 0) or (c[0] == ' ') or (c[0] == '\t');
|
||||
}
|
||||
|
||||
fn is_whitespace_or_eol(c: []const u8) bool {
|
||||
pub fn is_whitespace_or_eol(c: []const u8) bool {
|
||||
return is_whitespace(c) or c[0] == '\n';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -232,6 +232,20 @@ const cmds_ = struct {
|
|||
}
|
||||
pub const move_next_word_start_meta: Meta = .{ .description = "Move next word start", .arguments = &.{.integer} };
|
||||
|
||||
pub fn move_next_long_word_start(_: *void, ctx: Ctx) Result {
|
||||
const mv = tui.mainview() orelse return;
|
||||
const ed = mv.get_active_editor() orelse return;
|
||||
const root = try ed.buf_root();
|
||||
|
||||
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
|
||||
cursel.selection = null;
|
||||
};
|
||||
|
||||
ed.with_selections_const_repeat(root, move_cursor_long_word_right, ctx) catch {};
|
||||
ed.clamp();
|
||||
}
|
||||
pub const move_next_long_word_start_meta: Meta = .{ .description = "Move next long word start", .arguments = &.{.integer} };
|
||||
|
||||
pub fn move_prev_word_start(_: *void, ctx: Ctx) Result {
|
||||
const mv = tui.mainview() orelse return;
|
||||
const ed = mv.get_active_editor() orelse return;
|
||||
|
|
@ -246,6 +260,20 @@ const cmds_ = struct {
|
|||
}
|
||||
pub const move_prev_word_start_meta: Meta = .{ .description = "Move previous word start", .arguments = &.{.integer} };
|
||||
|
||||
pub fn move_prev_long_word_start(_: *void, ctx: Ctx) Result {
|
||||
const mv = tui.mainview() orelse return;
|
||||
const ed = mv.get_active_editor() orelse return;
|
||||
const root = try ed.buf_root();
|
||||
|
||||
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
|
||||
cursel.selection = null;
|
||||
};
|
||||
|
||||
ed.with_selections_const_repeat(root, move_cursor_long_word_left, ctx) catch {};
|
||||
ed.clamp();
|
||||
}
|
||||
pub const move_prev_long_word_start_meta: Meta = .{ .description = "Move previous long word start", .arguments = &.{.integer} };
|
||||
|
||||
pub fn move_next_word_end(_: *void, ctx: Ctx) Result {
|
||||
const mv = tui.mainview() orelse return;
|
||||
const ed = mv.get_active_editor() orelse return;
|
||||
|
|
@ -260,6 +288,20 @@ const cmds_ = struct {
|
|||
}
|
||||
pub const move_next_word_end_meta: Meta = .{ .description = "Move next word end", .arguments = &.{.integer} };
|
||||
|
||||
pub fn move_next_long_word_end(_: *void, ctx: Ctx) Result {
|
||||
const mv = tui.mainview() orelse return;
|
||||
const ed = mv.get_active_editor() orelse return;
|
||||
const root = try ed.buf_root();
|
||||
|
||||
for (ed.cursels.items) |*cursel_| if (cursel_.*) |*cursel| {
|
||||
cursel.selection = null;
|
||||
};
|
||||
|
||||
ed.with_selections_const_repeat(root, move_cursor_long_word_right_end, ctx) catch {};
|
||||
ed.clamp();
|
||||
}
|
||||
pub const move_next_long_word_end_meta: Meta = .{ .description = "Move next long word end", .arguments = &.{.integer} };
|
||||
|
||||
pub fn cut_forward_internal_inclusive(_: *void, _: Ctx) Result {
|
||||
const mv = tui.mainview() orelse return;
|
||||
const ed = mv.get_active_editor() orelse return;
|
||||
|
|
@ -467,3 +509,88 @@ fn insert_line(ed: *Editor, root: Buffer.Root, cursel: *CurSel, s: []const u8, a
|
|||
cursel.selection = Selection{ .begin = begin, .end = cursor.* };
|
||||
return root_;
|
||||
}
|
||||
|
||||
fn is_not_whitespace_or_eol(c: []const u8) bool {
|
||||
return !Editor.is_whitespace_or_eol(c);
|
||||
}
|
||||
|
||||
fn is_whitespace_or_eol_at_cursor(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
return cursor.test_at(root, Editor.is_whitespace_or_eol, metrics);
|
||||
}
|
||||
|
||||
fn is_non_whitespace_or_eol_at_cursor(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
return cursor.test_at(root, is_not_whitespace_or_eol, metrics);
|
||||
}
|
||||
|
||||
fn is_long_word_boundary_left(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
if (cursor.test_at(root, Editor.is_whitespace, metrics)) return false;
|
||||
var next = cursor.*;
|
||||
next.move_left(root, metrics) catch return true;
|
||||
|
||||
const next_is_whitespace = Editor.is_whitespace_at_cursor(root, &next, metrics);
|
||||
if (next_is_whitespace) return true;
|
||||
|
||||
const curr_is_non_word = is_non_whitespace_or_eol_at_cursor(root, cursor, metrics);
|
||||
const next_is_non_word = is_non_whitespace_or_eol_at_cursor(root, &next, metrics);
|
||||
return curr_is_non_word != next_is_non_word;
|
||||
}
|
||||
|
||||
pub fn move_cursor_long_word_left(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
try Editor.move_cursor_left(root, cursor, metrics);
|
||||
|
||||
// Consume " "
|
||||
while (Editor.is_whitespace_at_cursor(root, cursor, metrics)) {
|
||||
try Editor.move_cursor_left(root, cursor, metrics);
|
||||
}
|
||||
|
||||
var next = cursor.*;
|
||||
next.move_left(root, metrics) catch return;
|
||||
var next_next = next;
|
||||
next_next.move_left(root, metrics) catch return;
|
||||
|
||||
const cur = next.test_at(root, is_not_whitespace_or_eol, metrics);
|
||||
const nxt = next_next.test_at(root, is_not_whitespace_or_eol, metrics);
|
||||
if (cur != nxt) {
|
||||
try Editor.move_cursor_left(root, cursor, metrics);
|
||||
return;
|
||||
} else {
|
||||
try move_cursor_long_word_left(root, cursor, metrics);
|
||||
}
|
||||
}
|
||||
|
||||
fn is_word_boundary_right(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
if (Editor.is_whitespace_at_cursor(root, cursor, metrics)) return false;
|
||||
var next = cursor.*;
|
||||
next.move_right(root, metrics) catch return true;
|
||||
|
||||
const next_is_whitespace = Editor.is_whitespace_at_cursor(root, &next, metrics);
|
||||
if (next_is_whitespace) return true;
|
||||
|
||||
const curr_is_non_word = is_non_whitespace_or_eol_at_cursor(root, cursor, metrics);
|
||||
const next_is_non_word = is_non_whitespace_or_eol_at_cursor(root, &next, metrics);
|
||||
return curr_is_non_word != next_is_non_word;
|
||||
}
|
||||
|
||||
pub fn move_cursor_long_word_right(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
try cursor.move_right(root, metrics);
|
||||
Editor.move_cursor_right_until(root, cursor, is_long_word_boundary_left, metrics);
|
||||
}
|
||||
|
||||
fn is_long_word_boundary_right(root: Buffer.Root, cursor: *const Cursor, metrics: Buffer.Metrics) bool {
|
||||
if (Editor.is_whitespace_at_cursor(root, cursor, metrics)) return false;
|
||||
var next = cursor.*;
|
||||
next.move_right(root, metrics) catch return true;
|
||||
|
||||
const next_is_whitespace = Editor.is_whitespace_at_cursor(root, &next, metrics);
|
||||
if (next_is_whitespace) return true;
|
||||
|
||||
const curr_is_non_word = is_non_whitespace_or_eol_at_cursor(root, cursor, metrics);
|
||||
const next_is_non_word = is_non_whitespace_or_eol_at_cursor(root, &next, metrics);
|
||||
return curr_is_non_word != next_is_non_word;
|
||||
}
|
||||
|
||||
pub fn move_cursor_long_word_right_end(root: Buffer.Root, cursor: *Cursor, metrics: Buffer.Metrics) error{Stop}!void {
|
||||
// try Editor.move_cursor_right(root, cursor, metrics);
|
||||
Editor.move_cursor_right_until(root, cursor, is_long_word_boundary_right, metrics);
|
||||
try cursor.move_right(root, metrics);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const std = @import("std");
|
||||
pub const buffer = @import("tests_buffer.zig");
|
||||
pub const color = @import("tests_color.zig");
|
||||
pub const helix = @import("tests_helix.zig");
|
||||
|
||||
test {
|
||||
std.testing.refAllDecls(@This());
|
||||
|
|
|
|||
79
test/tests_helix.zig
Normal file
79
test/tests_helix.zig
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
const std = @import("std");
|
||||
const Buffer = @import("Buffer");
|
||||
const Cursor = @import("Cursor");
|
||||
const helix = @import("helix");
|
||||
|
||||
// error: import of file outside module path
|
||||
// const helix = @import("../src/tui/mode/helix.zig");
|
||||
|
||||
const ArrayList = std.ArrayList;
|
||||
const a = std.testing.allocator;
|
||||
|
||||
fn metrics() Buffer.Metrics {
|
||||
return .{
|
||||
.ctx = undefined,
|
||||
.egc_length = struct {
|
||||
fn f(_: Buffer.Metrics, _: []const u8, colcount: *c_int, _: usize) usize {
|
||||
colcount.* = 1;
|
||||
return 1;
|
||||
}
|
||||
}.f,
|
||||
.egc_chunk_width = struct {
|
||||
fn f(_: Buffer.Metrics, chunk_: []const u8, _: usize) usize {
|
||||
return chunk_.len;
|
||||
}
|
||||
}.f,
|
||||
.egc_last = struct {
|
||||
fn f(_: Buffer.Metrics, _: []const u8) []const u8 {
|
||||
@panic("not implemented");
|
||||
}
|
||||
}.f,
|
||||
.tab_width = 8,
|
||||
};
|
||||
}
|
||||
|
||||
fn the_pos(buffer: Buffer, pos: u8) Cursor {
|
||||
return buffer.root.byte_offset_to_line_and_col(pos, metrics(), .lf);
|
||||
}
|
||||
|
||||
test "word_movement" {
|
||||
const W = helix.move_cursor_long_word_right;
|
||||
const B = helix.move_cursor_long_word_left;
|
||||
const E = helix.move_cursor_long_word_right_end;
|
||||
const doc: []const u8 =
|
||||
\\a small $% Test.here, with.things()to demo
|
||||
\\ with surrounding.space a bb AA a small and long
|
||||
\\
|
||||
\\
|
||||
\\nospace.
|
||||
\\ try std.testing.expectEqual(Buffer.Cursor{ .row = 0, .col = 0 }, buffer.root.byte_offset_to_line_and_col(0, test_metrics(), eol_mode));
|
||||
\\
|
||||
\\
|
||||
\\ $$%. []{{}. dart de
|
||||
\\da
|
||||
;
|
||||
|
||||
//44 55 0 8 0
|
||||
// TODO: test selections. Parity with Helix
|
||||
|
||||
var eol_mode: Buffer.EolMode = .lf;
|
||||
var sanitized: bool = false;
|
||||
const buffer = try Buffer.create(a);
|
||||
defer buffer.deinit();
|
||||
buffer.update(try buffer.load_from_string(doc, &eol_mode, &sanitized));
|
||||
const root: Buffer.Root = buffer.root;
|
||||
var c = Cursor{ .row = 0, .col = 0, .target = 0 };
|
||||
const t = the_pos;
|
||||
|
||||
try std.testing.expectEqual(Buffer.Cursor{ .row = 0, .col = 0 }, buffer.root.byte_offset_to_line_and_col(0, metrics(), eol_mode));
|
||||
try std.testing.expectEqual(try buffer.root.line_width(0, metrics()), 44);
|
||||
try std.testing.expectEqual(try buffer.root.line_width(1, metrics()), 55);
|
||||
try E(root, &c, metrics());
|
||||
try std.testing.expectEqual(c, t(buffer.*, 1));
|
||||
try B(root, &c, metrics());
|
||||
try std.testing.expectEqual(c, t(buffer.*, 0));
|
||||
try W(root, &c, metrics());
|
||||
try std.testing.expectEqual(c, t(buffer.*, 2));
|
||||
try B(root, &c, metrics());
|
||||
try std.testing.expectEqual(c, t(buffer.*, 1));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue