From 77f99770cc211ae23f09a6f6ad01936f702357a8 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Thu, 17 Sep 2026 12:55:33 -0500 Subject: [PATCH 1/7] add a bunch of basic unit tests unit tests for dfhack lua library code --- test/library/class_extended.lua | 319 ++++++++++++++++++++++++++++++++ test/library/dfhack_core.lua | 236 +++++++++++++++++++++++ test/library/gui_basics.lua | 277 +++++++++++++++++++++++++++ test/library/utils_extended.lua | 300 ++++++++++++++++++++++++++++++ 4 files changed, 1132 insertions(+) create mode 100644 test/library/class_extended.lua create mode 100644 test/library/dfhack_core.lua create mode 100644 test/library/gui_basics.lua create mode 100644 test/library/utils_extended.lua diff --git a/test/library/class_extended.lua b/test/library/class_extended.lua new file mode 100644 index 0000000000..5c9ca9a6e6 --- /dev/null +++ b/test/library/class_extended.lua @@ -0,0 +1,319 @@ +config.target = 'core' + +function test.defclass_basic() + -- Test basic class creation + local MyClass = defclass(nil) + expect.table_eq(MyClass, {}) + expect.eq(MyClass.super, nil) + expect.ne(getmetatable(MyClass), nil) +end + +function test.defclass_with_parent() + -- Test class creation with parent + local ParentClass = defclass(nil) + local ChildClass = defclass(nil, ParentClass) + + expect.eq(ChildClass.super, ParentClass) + expect.eq(getmetatable(ChildClass).__index, ParentClass) +end + +function test.defclass_attrs() + -- Test class with ATTRS + local MyClass = defclass(nil) + MyClass.ATTRS { + attr1 = 'default1', + attr2 = 'default2', + } + + expect.eq(MyClass.ATTRS.attr1, 'default1') + expect.eq(MyClass.ATTRS.attr2, 'default2') +end + +function test.mkinstance() + -- Test basic instance creation + local MyClass = defclass(nil) + local instance = mkinstance(MyClass, {value = 100}) + + expect.eq(instance.value, 100) + expect.eq(getmetatable(instance), MyClass) +end + +function test.instance_creation() + -- Test instance creation via class call + local MyClass = defclass(nil) + MyClass.ATTRS { + default_attr = 'default_value', + } + + local instance = MyClass({custom_attr = 'custom_value'}) + + expect.eq(instance.default_attr, 'default_value') + expect.eq(instance.custom_attr, 'custom_value') +end + +function test.instance_inheritance() + -- Test instance method inheritance + local ParentClass = defclass(nil) + function ParentClass:parent_method() + return 'parent' + end + + local ChildClass = defclass(nil, ParentClass) + function ChildClass:child_method() + return 'child' + end + + local instance = ChildClass({}) + expect.eq(instance:parent_method(), 'parent') + expect.eq(instance:child_method(), 'child') +end + +function test.init_method() + -- Test init method + local MyClass = defclass(nil) + MyClass.ATTRS { + value = 0, + } + + function MyClass:init(init_table) + self.value = (init_table.value or 0) * 2 + end + + local instance = MyClass({value = 5}) + expect.eq(instance.value, 10) +end + +function test.preinit_postinit() + -- Test preinit and postinit methods + local call_order = {} + + local MyClass = defclass(nil) + function MyClass:preinit(init_table) + table.insert(call_order, 'preinit') + end + + function MyClass:init(init_table) + table.insert(call_order, 'init') + end + + function MyClass:postinit(init_table) + table.insert(call_order, 'postinit') + end + + MyClass({}) + + expect.eq(#call_order, 3) + expect.eq(call_order[1], 'preinit') + expect.eq(call_order[2], 'init') + expect.eq(call_order[3], 'postinit') +end + +function test.inheritance_init_order() + -- Test init order with inheritance + local call_order = {} + + local ParentClass = defclass(nil) + function ParentClass:preinit(init_table) + table.insert(call_order, 'parent_preinit') + end + + function ParentClass:init(init_table) + table.insert(call_order, 'parent_init') + end + + function ParentClass:postinit(init_table) + table.insert(call_order, 'parent_postinit') + end + + local ChildClass = defclass(nil, ParentClass) + function ChildClass:preinit(init_table) + table.insert(call_order, 'child_preinit') + end + + function ChildClass:init(init_table) + table.insert(call_order, 'child_init') + end + + function ChildClass:postinit(init_table) + table.insert(call_order, 'child_postinit') + end + + ChildClass({}) + + expect.eq(#call_order, 6) + expect.eq(call_order[1], 'child_preinit') + expect.eq(call_order[2], 'parent_preinit') + expect.eq(call_order[3], 'parent_init') + expect.eq(call_order[4], 'child_init') + expect.eq(call_order[5], 'parent_postinit') + expect.eq(call_order[6], 'child_postinit') +end + +function test.callback_method() + -- Test callback method + local MyClass = defclass(nil) + function MyClass:test_method(arg) + return arg * 2 + end + + local instance = MyClass({}) + local cb = instance:callback('test_method') + + expect.eq(cb(5), 10) +end + +function test.cb_getfield() + -- Test cb_getfield method + local MyClass = defclass(nil) + local instance = MyClass({value = 42}) + + local getter = instance:cb_getfield('value') + expect.eq(getter(), 42) +end + +function test.cb_setfield() + -- Test cb_setfield method + local MyClass = defclass(nil) + local instance = MyClass({value = 42}) + + local setter = instance:cb_setfield('value') + setter(100) + expect.eq(instance.value, 100) +end + +function test.assign_method() + -- Test assign method + local MyClass = defclass(nil) + local instance = MyClass({value = 1}) + + instance:assign({value = 2, new_field = 3}) + expect.eq(instance.value, 2) + expect.eq(instance.new_field, 3) +end + +function test.invoke_before() + -- Test invoke_before method + local call_order = {} + + local MyClass = defclass(nil) + function MyClass:test_method() + table.insert(call_order, 'original') + end + + function MyClass:invoke_before_test_method() + table.insert(call_order, 'before') + end + + local instance = MyClass({}) + instance:invoke_before('test_method') + + expect.eq(#call_order, 2) + expect.eq(call_order[1], 'before') + expect.eq(call_order[2], 'original') +end + +function test.invoke_after() + -- Test invoke_after method + local call_order = {} + + local MyClass = defclass(nil) + function MyClass:test_method() + table.insert(call_order, 'original') + end + + function MyClass:invoke_after_test_method() + table.insert(call_order, 'after') + end + + local instance = MyClass({}) + instance:invoke_after('test_method') + + expect.eq(#call_order, 2) + expect.eq(call_order[1], 'original') + expect.eq(call_order[2], 'after') +end + +function test.reserved_names() + -- Test that reserved names cannot be used + local MyClass = defclass(nil) + + expect.error_match('reserved', function() + MyClass.super = 'test' + end) + + expect.error_match('reserved', function() + MyClass.ATTRS = 'test' + end) +end + +function test.attrs_meta() + -- Test ATTRS metatable behavior + local MyClass = defclass(nil) + MyClass.ATTRS { + attr1 = 'value1', + attr2 = 'value2', + } + + -- Test that ATTRS can be called to add attributes + MyClass.ATTRS { + attr3 = 'value3', + } + + expect.eq(MyClass.ATTRS.attr1, 'value1') + expect.eq(MyClass.ATTRS.attr2, 'value2') + expect.eq(MyClass.ATTRS.attr3, 'value3') +end + +function test.default_nil() + -- Test DEFAULT_NIL behavior + local MyClass = defclass(nil) + MyClass.ATTRS { + optional = DEFAULT_NIL, + required = 'default', + } + + local instance1 = MyClass({}) + expect.eq(instance1.optional, nil) + expect.eq(instance1.required, 'default') + + local instance2 = MyClass({optional = 'provided'}) + expect.eq(instance2.optional, 'provided') + expect.eq(instance2.required, 'default') +end + +function test.class_reload() + -- Test that classes can be reloaded + local MyClass = defclass(nil) + MyClass.ATTRS { + version = 1, + } + + -- Simulate reload by updating ATTRS + MyClass.ATTRS { + version = 2, + new_attr = 'new', + } + + expect.eq(MyClass.ATTRS.version, 2) + expect.eq(MyClass.ATTRS.new_attr, 'new') +end + +function test.instance_field_access() + -- Test instance field access patterns + local MyClass = defclass(nil) + MyClass.ATTRS { + public_field = 'public', + } + + function MyClass:init(init_table) + self.private_field = 'private' + end + + local instance = MyClass({}) + expect.eq(instance.public_field, 'public') + expect.eq(instance.private_field, 'private') + + -- Test setting new fields + instance.dynamic_field = 'dynamic' + expect.eq(instance.dynamic_field, 'dynamic') +end diff --git a/test/library/dfhack_core.lua b/test/library/dfhack_core.lua new file mode 100644 index 0000000000..93e2f8ee21 --- /dev/null +++ b/test/library/dfhack_core.lua @@ -0,0 +1,236 @@ +config.target = 'core' + +function test.safe_index() + -- Test basic indexing + local t = {a = 1, b = {c = 2}} + expect.eq(dfhack.safe_index(t, 'a'), 1) + expect.eq(dfhack.safe_index(t, 'b', 'c'), 2) + + -- Test nil handling + expect.eq(dfhack.safe_index(nil, 'a'), nil) + expect.eq(dfhack.safe_index(t, 'nonexistent'), nil) + expect.eq(dfhack.safe_index(t, 'b', 'nonexistent'), nil) + + -- Test nested nil handling + expect.eq(dfhack.safe_index(t, 'b', 'c', 'd'), nil) +end + +local function test_ensure_key() + local t = {} + + -- Test creating new key + local result = dfhack.ensure_key(t, 'new_key') + expect.table_eq(result, {}) + expect.table_eq(t.new_key, {}) + + -- Test existing key + t.existing = {value = 1} + result = dfhack.ensure_key(t, 'existing') + expect.eq(result, t.existing) + expect.eq(t.existing.value, 1) + + -- Test with default value + result = dfhack.ensure_key(t, 'with_default', {default = true}) + expect.table_eq(result, {default = true}) +end + +function test.ensure_key() + test_ensure_key() +end + +local function test_ensure_keys() + local t = {} + + -- Test creating nested keys + local result = dfhack.ensure_keys(t, 'level1', 'level2', 'level3') + expect.eq(result, t.level1.level2.level3) + expect.table_eq(t.level1, {}) + expect.table_eq(t.level1.level2, {}) + expect.table_eq(t.level1.level2.level3, {}) + + -- Test partial existing path + t.level1.level2.level3 = {existing = true} + result = dfhack.ensure_keys(t, 'level1', 'level2', 'level3') + expect.eq(result, t.level1.level2.level3) + expect.true_(result.existing) +end + +function test.ensure_keys() + test_ensure_keys() +end + +local function test_copyall() + local t = {a = 1, b = 2, c = {nested = true}} + local copy = dfhack.copyall(t) + + expect.table_eq(copy, t) + expect.ne(copy, t) -- Different table reference + expect.eq(copy.c, t.c) -- Shallow copy +end + +function test.copyall() + test_copyall() +end + +local function test_pos_functions() + -- Test pos2xyz + local pos = {x = 10, y = 20, z = 30} + local x, y, z = dfhack.pos2xyz(pos) + expect.eq(x, 10) + expect.eq(y, 20) + expect.eq(z, 30) + + -- Test pos2xyz with invalid pos + local invalid_pos = {x = -30000} + expect.eq(dfhack.pos2xyz(invalid_pos), nil) + + -- Test xyz2pos + local new_pos = dfhack.xyz2pos(5, 10, 15) + expect.eq(new_pos.x, 5) + expect.eq(new_pos.y, 10) + expect.eq(new_pos.z, 15) + + -- Test xyz2pos with nil + local nil_pos = dfhack.xyz2pos(nil, nil, nil) + expect.eq(nil_pos.x, -30000) + expect.eq(nil_pos.y, -30000) + expect.eq(nil_pos.z, -30000) + + -- Test same_xyz + expect.true_(dfhack.same_xyz(pos, pos)) + expect.false_(dfhack.same_xyz(pos, {x = 10, y = 20, z = 25})) + + -- Test pos2xy + local x2, y2 = dfhack.pos2xy(pos) + expect.eq(x2, 10) + expect.eq(y2, 20) + + -- Test xy2pos + local pos2d = dfhack.xy2pos(3, 7) + expect.eq(pos2d.x, 3) + expect.eq(pos2d.y, 7) + + -- Test same_xy + expect.true_(dfhack.same_xy(pos, pos)) + expect.true_(dfhack.same_xy(pos, {x = 10, y = 20, z = 99})) + expect.false_(dfhack.same_xy(pos, {x = 10, y = 25, z = 30})) +end + +function test.pos_functions() + test_pos_functions() +end + +local function test_string_extensions() + -- Test startswith + expect.true_(("hello world"):startswith("hello")) + expect.false_(("hello world"):startswith("world")) + expect.true_(("test"):startswith("test")) + + -- Test endswith + expect.true_(("hello world"):endswith("world")) + expect.false_(("hello world"):endswith("hello")) + expect.true_(("test"):endswith("test")) + + -- Test split + local parts = "a,b,c":split(",") + expect.eq(parts[1], "a") + expect.eq(parts[2], "b") + expect.eq(parts[3], "c") + + -- Test split with default delimiter + local words = "hello world test":split() + expect.eq(words[1], "hello") + expect.eq(words[2], "world") + expect.eq(words[3], "test") + + -- Test trim + expect.eq((" hello "):trim(), "hello") + expect.eq(("\t\nworld\n\t"):trim(), "world") + + -- Test wrap + local wrapped = "This is a long string that needs to be wrapped":wrap(20) + expect.true_(#wrapped > 20) -- Should be multiple lines + + -- Test escape_pattern + local escaped = "a+b*c":escape_pattern() + expect.true_(escaped:find("%+")) + expect.true_(escaped:find("%*")) +end + +function test.string_extensions() + test_string_extensions() +end + +local function test_with_finalize() + local cleanup_called = false + local result + + dfhack.with_finalize( + function() cleanup_called = true end, + function() result = "success" end + ) + + expect.true_(cleanup_called) + expect.eq(result, "success") +end + +function test.with_finalize() + test_with_finalize() +end + +local function test_with_onerror() + local cleanup_called = false + local ok, err = dfhack.pcall(function() + dfhack.with_onerror( + function() cleanup_called = true end, + function() error("test error") end + ) + end) + + expect.false_(ok) + expect.true_(cleanup_called) +end + +function test.with_onerror() + test_with_onerror() +end + +local function test_mkmodule() + -- Test that mkmodule creates proper module structure + local test_module = mkmodule('test.temp_module') + expect.table_eq(test_module, {}) +end + +function test.mkmodule() + test_mkmodule() +end + +local function test_defclass() + -- Test basic class creation + local MyClass = defclass(nil) + expect.table_eq(MyClass, {}) + expect.eq(MyClass.super, nil) + + -- Test class with parent + local ParentClass = defclass(nil) + local ChildClass = defclass(nil, ParentClass) + expect.eq(ChildClass.super, ParentClass) + + -- Test instance creation + local instance = MyClass({test_value = 42}) + expect.eq(instance.test_value, 42) +end + +function test.defclass() + test_defclass() +end + +local function test_mkinstance() + local MyClass = defclass(nil) + local instance = mkinstance(MyClass, {value = 100}) + expect.eq(instance.value, 100) +end + +function test.mkinstance() + test_mkinstance() +end diff --git a/test/library/gui_basics.lua b/test/library/gui_basics.lua new file mode 100644 index 0000000000..62d1348b4e --- /dev/null +++ b/test/library/gui_basics.lua @@ -0,0 +1,277 @@ +config.target = 'core' + +local gui = require 'gui' + +function test.mkdims_xy() + local dims = gui.mkdims_xy(10, 20, 30, 40) + expect.eq(dims.x1, 10) + expect.eq(dims.y1, 20) + expect.eq(dims.x2, 30) + expect.eq(dims.y2, 40) + expect.eq(dims.width, 21) -- 30-10+1 + expect.eq(dims.height, 21) -- 40-20+1 +end + +function test.mkdims_wh() + local dims = gui.mkdims_wh(10, 20, 15, 25) + expect.eq(dims.x1, 10) + expect.eq(dims.y1, 20) + expect.eq(dims.x2, 24) -- 10+15-1 + expect.eq(dims.y2, 44) -- 20+25-1 + expect.eq(dims.width, 15) + expect.eq(dims.height, 25) +end + +function test.parse_inset() + -- Test with table + local inset = gui.parse_inset({l = 5, r = 10, t = 3, b = 7}) + expect.eq(inset, {5, 3, 10, 7}) + + -- Test with single value + local inset2 = gui.parse_inset(8) + expect.eq(inset2, {8, 8, 8, 8}) + + -- Test with x/y shorthand + local inset3 = gui.parse_inset({x = 4, y = 6}) + expect.eq(inset3, {4, 6, 4, 6}) +end + +function test.inset_frame() + local rect = gui.mkdims_wh(0, 0, 100, 50) + local inset = gui.inset_frame(rect, {l = 10, r = 10, t = 5, b = 5}) + + expect.eq(inset.x1, 10) + expect.eq(inset.y1, 5) + expect.eq(inset.x2, 89) -- 100-10-1 + expect.eq(inset.y2, 44) -- 50-5-1 + expect.eq(inset.width, 80) + expect.eq(inset.height, 40) +end + +function test.is_in_rect() + local rect = gui.mkdims_wh(10, 10, 20, 20) + + expect.true_(gui.is_in_rect(rect, 15, 15)) + expect.true_(gui.is_in_rect(rect, 10, 10)) + expect.true_(gui.is_in_rect(rect, 29, 29)) + expect.false_(gui.is_in_rect(rect, 9, 15)) + expect.false_(gui.is_in_rect(rect, 15, 9)) + expect.false_(gui.is_in_rect(rect, 30, 15)) + expect.false_(gui.is_in_rect(rect, 15, 30)) +end + +function test.ViewRect_basic() + local view_rect = gui.ViewRect{rect = gui.mkdims_wh(0, 0, 50, 30)} + + expect.eq(view_rect.x1, 0) + expect.eq(view_rect.y1, 0) + expect.eq(view_rect.x2, 49) + expect.eq(view_rect.y2, 29) + expect.eq(view_rect.width, 50) + expect.eq(view_rect.height, 30) +end + +function test.ViewRect_isDefunct() + local valid_rect = gui.ViewRect{rect = gui.mkdims_wh(0, 0, 50, 30)} + expect.false_(valid_rect:isDefunct()) + + local defunct_rect = gui.ViewRect{rect = gui.mkdims_wh(0, 0, 0, 0)} + expect.true_(defunct_rect:isDefunct()) +end + +function test.ViewRect_inClipGlobalXY() + local view_rect = gui.ViewRect{rect = gui.mkdims_wh(10, 10, 20, 20)} + + expect.true_(view_rect:inClipGlobalXY(15, 15)) + expect.true_(view_rect:inClipGlobalXY(10, 10)) + expect.true_(view_rect:inClipGlobalXY(29, 29)) + expect.false_(view_rect:inClipGlobalXY(9, 15)) + expect.false_(view_rect:inClipGlobalXY(15, 30)) +end + +function test.ViewRect_inClipLocalXY() + local view_rect = gui.ViewRect{rect = gui.mkdims_wh(10, 10, 20, 20)} + + expect.true_(view_rect:inClipLocalXY(5, 5)) -- Global 15,15 + expect.true_(view_rect:inClipLocalXY(0, 0)) -- Global 10,10 + expect.false_(view_rect:inClipLocalXY(-1, 5)) -- Global 9,15 + expect.false_(view_rect:inClipLocalXY(5, 20)) -- Global 15,30 +end + +function test.ViewRect_localXY() + local view_rect = gui.ViewRect{rect = gui.mkdims_wh(10, 10, 20, 20)} + + local lx, ly = view_rect:localXY(15, 25) + expect.eq(lx, 5) + expect.eq(ly, 15) +end + +function test.ViewRect_globalXY() + local view_rect = gui.ViewRect{rect = gui.mkdims_wh(10, 10, 20, 20)} + + local gx, gy = view_rect:globalXY(5, 15) + expect.eq(gx, 15) + expect.eq(gy, 25) +end + +function test.ViewRect_viewport() + local view_rect = gui.ViewRect{rect = gui.mkdims_wh(0, 0, 100, 100)} + local viewport = view_rect:viewport(10, 10, 20, 20) + + expect.eq(viewport.x1, 10) + expect.eq(viewport.y1, 10) + expect.eq(viewport.x2, 29) + expect.eq(viewport.y2, 29) + expect.eq(viewport.width, 20) + expect.eq(viewport.height, 20) +end + +function test.Painter_basic() + local painter = gui.Painter{rect = gui.mkdims_wh(0, 0, 50, 30)} + + expect.eq(painter.x, 0) + expect.eq(painter.y, 0) + expect.true_(painter:isValidPos()) +end + +function test.Painter_cursor() + local painter = gui.Painter{rect = gui.mkdims_wh(10, 10, 50, 30)} + + local cx, cy = painter:cursor() + expect.eq(cx, 0) + expect.eq(cy, 0) + + painter:seek(5, 10) + cx, cy = painter:cursor() + expect.eq(cx, 5) + expect.eq(cy, 10) +end + +function test.Painter_seek() + local painter = gui.Painter{rect = gui.mkdims_wh(0, 0, 50, 30)} + + painter:seek(10, 20) + expect.eq(painter.x, 10) + expect.eq(painter.y, 20) + + painter:seek(5) -- Only x + expect.eq(painter.x, 5) + expect.eq(painter.y, 20) -- y unchanged +end + +function test.Painter_advance() + local painter = gui.Painter{rect = gui.mkdims_wh(0, 0, 50, 30)} + + painter:advance(10, 5) + expect.eq(painter.x, 10) + expect.eq(painter.y, 5) + + painter:advance(5) -- Only x + expect.eq(painter.x, 15) + expect.eq(painter.y, 5) -- y unchanged +end + +function test.Painter_newline() + local painter = gui.Painter{rect = gui.mkdims_wh(0, 0, 50, 30)} + + painter:seek(10, 5) + painter:newline(3) + + expect.eq(painter.x, 3) + expect.eq(painter.y, 6) +end + +function test.Painter_viewport() + local painter = gui.Painter{rect = gui.mkdims_wh(0, 0, 100, 100)} + local viewport_painter = painter:viewport(10, 10, 20, 20) + + expect.eq(viewport_painter.x, 10) + expect.eq(viewport_painter.y, 10) + expect.eq(viewport_painter.width, 20) + expect.eq(viewport_painter.height, 20) +end + +function test.View_basic() + local view = gui.View{} + + expect.table_eq(view.subviews, {}) + expect.eq(view.focus, false) + expect.eq(#view.focus_group, 1) +end + +function test.View_addviews() + local parent = gui.View{} + local child1 = gui.View{view_id = 'child1'} + local child2 = gui.View{view_id = 'child2'} + + parent:addviews({child1, child2}) + + expect.eq(#parent.subviews, 2) + expect.eq(parent.subviews.child1, child1) + expect.eq(parent.subviews.child2, child2) + expect.eq(child1.parent_view, parent) + expect.eq(child2.parent_view, parent) +end + +function test.View_getPreferredFocusState() + local view = gui.View{} + expect.false_(view:getPreferredFocusState()) +end + +function test.View_setFocus() + local view = gui.View{} + + expect.false_(view.focus) + view:setFocus(true) + expect.true_(view.focus) + view:setFocus(false) + expect.false_(view.focus) +end + +function test.View_assign() + local view = gui.View{} + view:assign({custom_field = 'value', another_field = 42}) + + expect.eq(view.custom_field, 'value') + expect.eq(view.another_field, 42) +end + +function test.View_callback() + local view = gui.View{} + function view:test_method(arg) + return arg * 2 + end + + local cb = view:callback('test_method') + expect.eq(cb(5), 10) +end + +function test.View_cb_getfield() + local view = gui.View{test_field = 'test_value'} + local getter = view:cb_getfield('test_field') + + expect.eq(getter(), 'test_value') +end + +function test.View_cb_setfield() + local view = gui.View{test_field = 'initial'} + local setter = view:cb_setfield('test_field') + + setter('updated') + expect.eq(view.test_field, 'updated') +end + +function test.compute_frame_rect() + local rect = gui.compute_frame_rect(100, 50, {w = 80, h = 40}) + + expect.eq(rect.width, 80) + expect.eq(rect.height, 40) + expect.ge(rect.x1, 0) + expect.ge(rect.y1, 0) +end + +function test.blink_visible() + -- Test that blink_visible returns boolean + local result = gui.blink_visible(100) + expect.eq(type(result), 'boolean') +end diff --git a/test/library/utils_extended.lua b/test/library/utils_extended.lua new file mode 100644 index 0000000000..f665cc078c --- /dev/null +++ b/test/library/utils_extended.lua @@ -0,0 +1,300 @@ +config.target = 'core' + +local utils = require 'utils' + +function test.getval() + -- Test with static value + expect.eq(utils.getval(42), 42) + expect.eq(utils.getval("hello"), "hello") + + -- Test with function + expect.eq(utils.getval(function() return 100 end), 100) + expect.eq(utils.getval(function(x) return x * 2 end, 5), 10) +end + +function test.compare() + expect.eq(utils.compare(1, 2), -1) + expect.eq(utils.compare(2, 1), 1) + expect.eq(utils.compare(1, 1), 0) + + expect.eq(utils.compare('a', 'b'), -1) + expect.eq(utils.compare('b', 'a'), 1) + expect.eq(utils.compare('a', 'a'), 0) +end + +function test.compare_name() + expect.eq(utils.compare_name('', ''), 0) + expect.eq(utils.compare_name('', 'a'), 1) + expect.eq(utils.compare_name('a', ''), -1) + expect.eq(utils.compare_name('a', 'b'), -1) + expect.eq(utils.compare_name('b', 'a'), 1) +end + +function test.compare_field() + local cmp = utils.compare_field('value') + expect.lt(cmp({value = 1}, {value = 2}), 0) + expect.gt(cmp({value = 2}, {value = 1}), 0) + expect.eq(cmp({value = 1}, {value = 1}), 0) +end + +function test.make_index_sequence() + local seq = utils.make_index_sequence(1, 5) + expect.eq(#seq, 5) + expect.eq(seq[1], 1) + expect.eq(seq[5], 5) + + local seq2 = utils.make_index_sequence(10, 15) + expect.eq(#seq2, 6) + expect.eq(seq2[1], 10) + expect.eq(seq2[6], 15) +end + +function test.make_sort_order() + local data = {{value = 3}, {value = 1}, {value = 2}} + local ordering = {{key = function(item) return item.value end}} + + local order = utils.make_sort_order(data, ordering) + expect.eq(order[1], 2) -- Index of value 1 + expect.eq(order[2], 3) -- Index of value 2 + expect.eq(order[3], 1) -- Index of value 3 +end + +function test.clone() + -- Test shallow clone + local t = {a = 1, b = 2} + local cloned = utils.clone(t, false) + expect.table_eq(cloned, t) + expect.ne(cloned, t) + + -- Test deep clone + local nested = {a = {b = {c = 1}}} + local deep_cloned = utils.clone(nested, true) + expect.eq(deep_cloned.a.b.c, 1) + expect.ne(deep_cloned.a, nested.a) +end + +function test.clone_with_default() + local obj = {a = 1, b = 2, c = 3} + local default = {a = 1, b = 2, c = 3, d = 4} + + local result = utils.clone_with_default(obj, default) + expect.eq(result.a, nil) -- Same as default + expect.eq(result.b, nil) -- Same as default + expect.eq(result.c, nil) -- Same as default + expect.eq(result.d, nil) -- Not in obj + + -- Test with different values + local obj2 = {a = 5, b = 2, c = 3} + local result2 = utils.clone_with_default(obj2, default) + expect.eq(result2.a, 5) -- Different from default + expect.eq(result2.b, nil) -- Same as default +end + +function test.parse_bitfield_int() + local type_ref = {'flag1', 'flag2', 'flag3'} + + local result = utils.parse_bitfield_int(5, type_ref) -- Binary 101 + expect.true_(result.flag1) + expect.false_(result.flag2) + expect.true_(result.flag3) + + -- Test with zero + local zero_result = utils.parse_bitfield_int(0, type_ref) + expect.eq(zero_result, nil) +end + +function test.list_bitfield_flags() + local bitfield = {flag1 = true, flag2 = false, flag3 = true} + local list = utils.list_bitfield_flags(bitfield) + + expect.eq(#list, 2) + expect.true_(list[1] == 'flag1' or list[1] == 'flag3') + expect.true_(list[2] == 'flag1' or list[2] == 'flag3') +end + +function test.linear_index() + local data = {{id = 1}, {id = 2}, {id = 3}} + + local idx, obj = utils.linear_index(data, 2, 'id') + expect.eq(idx, 2) + expect.eq(obj.id, 2) + + -- Test without field + local idx2, obj2 = utils.linear_index(data, {id = 2}) + expect.eq(idx2, 2) + expect.eq(obj2.id, 2) + + -- Test not found + local idx3, obj3 = utils.linear_index(data, 99, 'id') + expect.eq(idx3, nil) + expect.eq(obj3, nil) +end + +function test.binsearch() + local data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + + local item, found, pos = utils.binsearch(data, 5) + expect.eq(item, 5) + expect.true_(found) + expect.eq(pos, 5) + + -- Test not found + local item2, found2, pos2 = utils.binsearch(data, 11) + expect.eq(item2, nil) + expect.false_(found2) +end + +function test.insert_sorted() + local data = {1, 3, 5, 7, 9} + + local added, item, pos = utils.insert_sorted(data, 4) + expect.true_(added) + expect.eq(item, 4) + expect.eq(pos, 3) + expect.eq(#data, 6) + + -- Test duplicate + local added2, item2, pos2 = utils.insert_sorted(data, 5) + expect.false_(added2) + expect.eq(item2, 5) +end + +function test.insert_or_update() + local data = {1, 3, 5, 7, 9} + + local added, item, pos = utils.insert_or_update(data, 4) + expect.true_(added) + expect.eq(item, 4) + + -- Test update existing + local added2, item2, pos2 = utils.insert_or_update(data, 5) + expect.false_(added2) + expect.eq(item2, 5) +end + +function test.erase_sorted_key() + local data = {1, 3, 5, 7, 9} + + local found, item, pos = utils.erase_sorted_key(data, 5) + expect.true_(found) + expect.eq(item, 5) + expect.eq(#data, 4) + + -- Test not found + local found2, item2, pos2 = utils.erase_sorted_key(data, 10) + expect.false_(found2) +end + +function test.search_text() + local text = "Hello World Test" + + -- Test basic search + expect.true_(utils.search_text(text, "Hello")) + expect.true_(utils.search_text(text, "World")) + expect.false_(utils.search_text(text, "NotFound")) + + -- Test multiple tokens + expect.true_(utils.search_text(text, {"Hello", "World"})) + expect.false_(utils.search_text(text, {"Hello", "NotFound"})) +end + +function test.split_string() + local text = "a,b,c" + local parts = utils.split_string(text, ",") + + expect.eq(#parts, 3) + expect.eq(parts[1], "a") + expect.eq(parts[2], "b") + expect.eq(parts[3], "c") +end + +function test.normalizePath() + expect.eq(utils.normalizePath("path\\to\\file"), "path/to/file") + expect.eq(utils.normalizePath("path//to//file"), "path/to/file") + expect.eq(utils.normalizePath("path/to/file"), "path/to/file") +end + +function test.invert() + local t = {a = 1, b = 2, c = 3} + local inverted = utils.invert(t) + + expect.eq(inverted[1], 'a') + expect.eq(inverted[2], 'b') + expect.eq(inverted[3], 'c') +end + +function test.tabulate() + local result = utils.tabulate(function(i) return i * 2 end, 1, 5) + + expect.eq(#result, 5) + expect.eq(result[1], 2) + expect.eq(result[5], 10) +end + +function test.fillTable() + local t1 = {a = 1} + local t2 = {b = 2, c = 3} + + utils.fillTable(t1, t2) + expect.eq(t1.a, 1) + expect.eq(t1.b, 2) + expect.eq(t1.c, 3) +end + +function test.unfillTable() + local t1 = {a = 1, b = 2, c = 3} + local t2 = {b = 2, c = 3} + + utils.unfillTable(t1, t2) + expect.eq(t1.a, 1) + expect.eq(t1.b, nil) + expect.eq(t1.c, nil) +end + +function test.df_shortcut_var() + -- Test global shortcut + local result = utils.df_shortcut_var('world') + expect.eq(result, df.global.world) + + -- Test non-existent + local result2 = utils.df_shortcut_var('nonexistent_var') + expect.eq(result2, nil) +end + +local function test_df_expr_to_ref() + -- Test simple global + expect.eq(utils.df_expr_to_ref('df.global.world'), df.global.world) + + -- Test field access + expect.eq(utils.df_expr_to_ref('df.global.world.original_save_version'), + df.global.world.original_save_version) + + -- Test array access + expect.eq(utils.df_expr_to_ref('df.global.world[0]'), df.global.world[0]) +end + +function test.df_expr_to_ref() + test_df_expr_to_ref() +end + +local function test_OrderedTable() + local t = utils.OrderedTable() + local keys = {'first', 'second', 'third', 'fourth'} + + for i, key in ipairs(keys) do + t[key] = i + end + + local collected_keys = {} + for k, v in pairs(t) do + table.insert(collected_keys, k) + end + + expect.eq(#collected_keys, 4) + expect.eq(collected_keys[1], 'first') + expect.eq(collected_keys[4], 'fourth') +end + +function test.OrderedTable() + test_OrderedTable() +end From 6fd7815a789760a6b82acba95bb4164a1d998ae4 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Thu, 17 Sep 2026 13:05:52 -0500 Subject: [PATCH 2/7] correct lua syntax --- test/library/dfhack_core.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/library/dfhack_core.lua b/test/library/dfhack_core.lua index 93e2f8ee21..184d60fbbb 100644 --- a/test/library/dfhack_core.lua +++ b/test/library/dfhack_core.lua @@ -132,13 +132,13 @@ local function test_string_extensions() expect.true_(("test"):endswith("test")) -- Test split - local parts = "a,b,c":split(",") + local parts = ("a,b,c"):split(",") expect.eq(parts[1], "a") expect.eq(parts[2], "b") expect.eq(parts[3], "c") -- Test split with default delimiter - local words = "hello world test":split() + local words = ("hello world test"):split() expect.eq(words[1], "hello") expect.eq(words[2], "world") expect.eq(words[3], "test") @@ -148,11 +148,11 @@ local function test_string_extensions() expect.eq(("\t\nworld\n\t"):trim(), "world") -- Test wrap - local wrapped = "This is a long string that needs to be wrapped":wrap(20) + local wrapped = ("This is a long string that needs to be wrapped"):wrap(20) expect.true_(#wrapped > 20) -- Should be multiple lines -- Test escape_pattern - local escaped = "a+b*c":escape_pattern() + local escaped = ("a+b*c"):escape_pattern() expect.true_(escaped:find("%+")) expect.true_(escaped:find("%*")) end From 13b96194f0cea32bd8fd66ac65a9dbfe530b1c8a Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Thu, 17 Sep 2026 13:28:36 -0500 Subject: [PATCH 3/7] remove redundant or improper tests two of these test something that we don't currently implement but might someday the others are incorrect and/or redundant with existing tests --- test/library/utils_extended.lua | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/test/library/utils_extended.lua b/test/library/utils_extended.lua index f665cc078c..4ea06e11da 100644 --- a/test/library/utils_extended.lua +++ b/test/library/utils_extended.lua @@ -209,8 +209,9 @@ function test.split_string() end function test.normalizePath() - expect.eq(utils.normalizePath("path\\to\\file"), "path/to/file") - expect.eq(utils.normalizePath("path//to//file"), "path/to/file") +-- normalizePath doesn't currently switch slashes; add these if we ever add that functionality +-- expect.eq(utils.normalizePath("path\\to\\file"), "path/to/file") +-- expect.eq(utils.normalizePath("path//to//file"), "path/to/file") expect.eq(utils.normalizePath("path/to/file"), "path/to/file") end @@ -261,22 +262,6 @@ function test.df_shortcut_var() expect.eq(result2, nil) end -local function test_df_expr_to_ref() - -- Test simple global - expect.eq(utils.df_expr_to_ref('df.global.world'), df.global.world) - - -- Test field access - expect.eq(utils.df_expr_to_ref('df.global.world.original_save_version'), - df.global.world.original_save_version) - - -- Test array access - expect.eq(utils.df_expr_to_ref('df.global.world[0]'), df.global.world[0]) -end - -function test.df_expr_to_ref() - test_df_expr_to_ref() -end - local function test_OrderedTable() local t = utils.OrderedTable() local keys = {'first', 'second', 'third', 'fourth'} From 9731ac5a1ad6ac55a97aa6321101daff2898cd02 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Thu, 17 Sep 2026 13:53:10 -0500 Subject: [PATCH 4/7] more adjustments correct basic test remove test of unimplemented default_value functionality --- test/library/class_extended.lua | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/test/library/class_extended.lua b/test/library/class_extended.lua index 5c9ca9a6e6..858d490088 100644 --- a/test/library/class_extended.lua +++ b/test/library/class_extended.lua @@ -3,7 +3,8 @@ config.target = 'core' function test.defclass_basic() -- Test basic class creation local MyClass = defclass(nil) - expect.table_eq(MyClass, {}) + expect.eq(MyClass.__index, MyClass) + expect.eq(MyClass.ATTRS, nil) expect.eq(MyClass.super, nil) expect.ne(getmetatable(MyClass), nil) end @@ -38,19 +39,6 @@ function test.mkinstance() expect.eq(getmetatable(instance), MyClass) end -function test.instance_creation() - -- Test instance creation via class call - local MyClass = defclass(nil) - MyClass.ATTRS { - default_attr = 'default_value', - } - - local instance = MyClass({custom_attr = 'custom_value'}) - - expect.eq(instance.default_attr, 'default_value') - expect.eq(instance.custom_attr, 'custom_value') -end - function test.instance_inheritance() -- Test instance method inheritance local ParentClass = defclass(nil) From f4d9de82b8c66716c063db3688b6e02a2aa0b40b Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Thu, 17 Sep 2026 14:46:23 -0500 Subject: [PATCH 5/7] more updates rewrite some tests for specifics of dfhack's libs comment out some that are either pointless or cannot be tested fix syntax on some --- test/library/class_extended.lua | 6 ++- test/library/dfhack_core.lua | 89 +++++++++++++-------------------- test/library/gui_basics.lua | 21 ++++---- test/library/utils_extended.lua | 68 +++++++++++++------------ 4 files changed, 86 insertions(+), 98 deletions(-) diff --git a/test/library/class_extended.lua b/test/library/class_extended.lua index 858d490088..8cf386ca02 100644 --- a/test/library/class_extended.lua +++ b/test/library/class_extended.lua @@ -153,7 +153,8 @@ end function test.cb_getfield() -- Test cb_getfield method local MyClass = defclass(nil) - local instance = MyClass({value = 42}) + local instance = MyClass() + instance.value = 42 local getter = instance:cb_getfield('value') expect.eq(getter(), 42) @@ -162,7 +163,8 @@ end function test.cb_setfield() -- Test cb_setfield method local MyClass = defclass(nil) - local instance = MyClass({value = 42}) + local instance = MyClass() + instance.value = 42 local setter = instance:cb_setfield('value') setter(100) diff --git a/test/library/dfhack_core.lua b/test/library/dfhack_core.lua index 184d60fbbb..ab0e3fbebc 100644 --- a/test/library/dfhack_core.lua +++ b/test/library/dfhack_core.lua @@ -3,34 +3,34 @@ config.target = 'core' function test.safe_index() -- Test basic indexing local t = {a = 1, b = {c = 2}} - expect.eq(dfhack.safe_index(t, 'a'), 1) - expect.eq(dfhack.safe_index(t, 'b', 'c'), 2) + expect.eq(safe_index(t, 'a'), 1) + expect.eq(safe_index(t, 'b', 'c'), 2) -- Test nil handling - expect.eq(dfhack.safe_index(nil, 'a'), nil) - expect.eq(dfhack.safe_index(t, 'nonexistent'), nil) - expect.eq(dfhack.safe_index(t, 'b', 'nonexistent'), nil) + expect.eq(safe_index(nil, 'a'), nil) + expect.eq(safe_index(t, 'nonexistent'), nil) + expect.eq(safe_index(t, 'b', 'nonexistent'), nil) -- Test nested nil handling - expect.eq(dfhack.safe_index(t, 'b', 'c', 'd'), nil) + expect.eq(safe_index(t, 'b', 'c', 'd'), nil) end local function test_ensure_key() local t = {} -- Test creating new key - local result = dfhack.ensure_key(t, 'new_key') + local result = ensure_key(t, 'new_key') expect.table_eq(result, {}) expect.table_eq(t.new_key, {}) -- Test existing key t.existing = {value = 1} - result = dfhack.ensure_key(t, 'existing') + result = ensure_key(t, 'existing') expect.eq(result, t.existing) expect.eq(t.existing.value, 1) -- Test with default value - result = dfhack.ensure_key(t, 'with_default', {default = true}) + result = ensure_key(t, 'with_default', {default = true}) expect.table_eq(result, {default = true}) end @@ -42,7 +42,7 @@ local function test_ensure_keys() local t = {} -- Test creating nested keys - local result = dfhack.ensure_keys(t, 'level1', 'level2', 'level3') + local result = ensure_keys(t, 'level1', 'level2', 'level3') expect.eq(result, t.level1.level2.level3) expect.table_eq(t.level1, {}) expect.table_eq(t.level1.level2, {}) @@ -50,7 +50,7 @@ local function test_ensure_keys() -- Test partial existing path t.level1.level2.level3 = {existing = true} - result = dfhack.ensure_keys(t, 'level1', 'level2', 'level3') + result = ensure_keys(t, 'level1', 'level2', 'level3') expect.eq(result, t.level1.level2.level3) expect.true_(result.existing) end @@ -61,7 +61,7 @@ end local function test_copyall() local t = {a = 1, b = 2, c = {nested = true}} - local copy = dfhack.copyall(t) + local copy = copyall(t) expect.table_eq(copy, t) expect.ne(copy, t) -- Different table reference @@ -75,45 +75,45 @@ end local function test_pos_functions() -- Test pos2xyz local pos = {x = 10, y = 20, z = 30} - local x, y, z = dfhack.pos2xyz(pos) + local x, y, z = pos2xyz(pos) expect.eq(x, 10) expect.eq(y, 20) expect.eq(z, 30) -- Test pos2xyz with invalid pos local invalid_pos = {x = -30000} - expect.eq(dfhack.pos2xyz(invalid_pos), nil) + expect.eq(pos2xyz(invalid_pos), nil) -- Test xyz2pos - local new_pos = dfhack.xyz2pos(5, 10, 15) + local new_pos = xyz2pos(5, 10, 15) expect.eq(new_pos.x, 5) expect.eq(new_pos.y, 10) expect.eq(new_pos.z, 15) -- Test xyz2pos with nil - local nil_pos = dfhack.xyz2pos(nil, nil, nil) + local nil_pos = xyz2pos(nil, nil, nil) expect.eq(nil_pos.x, -30000) expect.eq(nil_pos.y, -30000) expect.eq(nil_pos.z, -30000) -- Test same_xyz - expect.true_(dfhack.same_xyz(pos, pos)) - expect.false_(dfhack.same_xyz(pos, {x = 10, y = 20, z = 25})) + expect.true_(same_xyz(pos, pos)) + expect.false_(same_xyz(pos, {x = 10, y = 20, z = 25})) -- Test pos2xy - local x2, y2 = dfhack.pos2xy(pos) + local x2, y2 = pos2xy(pos) expect.eq(x2, 10) expect.eq(y2, 20) -- Test xy2pos - local pos2d = dfhack.xy2pos(3, 7) + local pos2d = xy2pos(3, 7) expect.eq(pos2d.x, 3) expect.eq(pos2d.y, 7) -- Test same_xy - expect.true_(dfhack.same_xy(pos, pos)) - expect.true_(dfhack.same_xy(pos, {x = 10, y = 20, z = 99})) - expect.false_(dfhack.same_xy(pos, {x = 10, y = 25, z = 30})) + expect.true_(same_xy(pos, pos)) + expect.true_(same_xy(pos, {x = 10, y = 20, z = 99})) + expect.false_(same_xy(pos, {x = 10, y = 25, z = 30})) end function test.pos_functions() @@ -165,7 +165,7 @@ local function test_with_finalize() local cleanup_called = false local result - dfhack.with_finalize( + with_finalize( function() cleanup_called = true end, function() result = "success" end ) @@ -180,8 +180,8 @@ end local function test_with_onerror() local cleanup_called = false - local ok, err = dfhack.pcall(function() - dfhack.with_onerror( + local ok, err = pcall(function() + with_onerror( function() cleanup_called = true end, function() error("test error") end ) @@ -195,35 +195,16 @@ function test.with_onerror() test_with_onerror() end -local function test_mkmodule() - -- Test that mkmodule creates proper module structure - local test_module = mkmodule('test.temp_module') - expect.table_eq(test_module, {}) -end - -function test.mkmodule() - test_mkmodule() -end - -local function test_defclass() - -- Test basic class creation - local MyClass = defclass(nil) - expect.table_eq(MyClass, {}) - expect.eq(MyClass.super, nil) +-- don't know how to test this function +-- local function test_mkmodule() +-- -- Test that mkmodule creates proper module structure +-- local test_module = mkmodule('test.temp_module') +-- expect.table_eq(test_module, {}) +-- end - -- Test class with parent - local ParentClass = defclass(nil) - local ChildClass = defclass(nil, ParentClass) - expect.eq(ChildClass.super, ParentClass) - - -- Test instance creation - local instance = MyClass({test_value = 42}) - expect.eq(instance.test_value, 42) -end - -function test.defclass() - test_defclass() -end +-- function test.mkmodule() +-- test_mkmodule() +-- end local function test_mkinstance() local MyClass = defclass(nil) diff --git a/test/library/gui_basics.lua b/test/library/gui_basics.lua index 62d1348b4e..e19eb68470 100644 --- a/test/library/gui_basics.lua +++ b/test/library/gui_basics.lua @@ -24,15 +24,15 @@ end function test.parse_inset() -- Test with table - local inset = gui.parse_inset({l = 5, r = 10, t = 3, b = 7}) + local inset = { gui.parse_inset({l = 5, r = 10, t = 3, b = 7}) } expect.eq(inset, {5, 3, 10, 7}) -- Test with single value - local inset2 = gui.parse_inset(8) + local inset2 = { gui.parse_inset(8) } expect.eq(inset2, {8, 8, 8, 8}) -- Test with x/y shorthand - local inset3 = gui.parse_inset({x = 4, y = 6}) + local inset3 = { gui.parse_inset({x = 4, y = 6}) } expect.eq(inset3, {4, 6, 4, 6}) end @@ -261,14 +261,15 @@ function test.View_cb_setfield() expect.eq(view.test_field, 'updated') end -function test.compute_frame_rect() - local rect = gui.compute_frame_rect(100, 50, {w = 80, h = 40}) +-- do not know how to test this function - it has no specified behavior and is not used +-- function test.compute_frame_rect() +-- local rect = gui.compute_frame_rect(100, 50, {w = 80, h = 40}) - expect.eq(rect.width, 80) - expect.eq(rect.height, 40) - expect.ge(rect.x1, 0) - expect.ge(rect.y1, 0) -end +-- expect.eq(rect.width, 80) +-- expect.eq(rect.height, 40) +-- expect.ge(rect.x1, 0) +-- expect.ge(rect.y1, 0) +-- end function test.blink_visible() -- Test that blink_visible returns boolean diff --git a/test/library/utils_extended.lua b/test/library/utils_extended.lua index 4ea06e11da..1d6988c1e9 100644 --- a/test/library/utils_extended.lua +++ b/test/library/utils_extended.lua @@ -73,35 +73,38 @@ function test.clone() expect.ne(deep_cloned.a, nested.a) end -function test.clone_with_default() - local obj = {a = 1, b = 2, c = 3} - local default = {a = 1, b = 2, c = 3, d = 4} - - local result = utils.clone_with_default(obj, default) - expect.eq(result.a, nil) -- Same as default - expect.eq(result.b, nil) -- Same as default - expect.eq(result.c, nil) -- Same as default - expect.eq(result.d, nil) -- Not in obj - - -- Test with different values - local obj2 = {a = 5, b = 2, c = 3} - local result2 = utils.clone_with_default(obj2, default) - expect.eq(result2.a, 5) -- Different from default - expect.eq(result2.b, nil) -- Same as default -end - -function test.parse_bitfield_int() - local type_ref = {'flag1', 'flag2', 'flag3'} - - local result = utils.parse_bitfield_int(5, type_ref) -- Binary 101 - expect.true_(result.flag1) - expect.false_(result.flag2) - expect.true_(result.flag3) - - -- Test with zero - local zero_result = utils.parse_bitfield_int(0, type_ref) - expect.eq(zero_result, nil) -end +-- need to come up with a way to test this +-- function test.clone_with_default() +-- local obj = {a = 1, b = 2, c = 3} +-- local default = {a = 1, b = 2, c = 3, d = 4} + +-- local result = utils.clone_with_default(obj, default) +-- expect.eq(result.a, nil) -- Same as default +-- expect.eq(result.b, nil) -- Same as default +-- expect.eq(result.c, nil) -- Same as default +-- expect.eq(result.d, nil) -- Not in obj + +-- -- Test with different values +-- local obj2 = {a = 5, b = 2, c = 3} +-- local result2 = utils.clone_with_default(obj2, default) +-- expect.eq(result2.a, 5) -- Different from default +-- expect.eq(result2.b, nil) -- Same as default +-- end + +-- need to come up with a way to test this + +--function test.parse_bitfield_int() +-- local type_ref = {'flag1', 'flag2', 'flag3'} +-- +-- local result = utils.parse_bitfield_int(5, type_ref) -- Binary 101 +-- expect.true_(result.flag1) +-- expect.false_(result.flag2) +-- expect.true_(result.flag3) +-- +-- -- Test with zero +-- local zero_result = utils.parse_bitfield_int(0, type_ref) +-- expect.eq(zero_result, nil) +--end function test.list_bitfield_flags() local bitfield = {flag1 = true, flag2 = false, flag3 = true} @@ -114,15 +117,16 @@ end function test.linear_index() local data = {{id = 1}, {id = 2}, {id = 3}} + local data2 = { 5, 4, 3, 2, 1 } local idx, obj = utils.linear_index(data, 2, 'id') expect.eq(idx, 2) expect.eq(obj.id, 2) -- Test without field - local idx2, obj2 = utils.linear_index(data, {id = 2}) - expect.eq(idx2, 2) - expect.eq(obj2.id, 2) + local idx2, obj2 = utils.linear_index(data2, 2) + expect.eq(idx2, 4) + expect.eq(obj2, 2) -- Test not found local idx3, obj3 = utils.linear_index(data, 99, 'id') From 4454d490d448214c0d28a365f16c55a1a902b343 Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Thu, 17 Sep 2026 15:08:52 -0500 Subject: [PATCH 6/7] yet more trims --- test/library/class_extended.lua | 79 ++++++++++++++------------------- test/library/dfhack_core.lua | 34 +++++++------- test/library/gui_basics.lua | 32 +++++++++---- 3 files changed, 73 insertions(+), 72 deletions(-) diff --git a/test/library/class_extended.lua b/test/library/class_extended.lua index 8cf386ca02..a0c6db5338 100644 --- a/test/library/class_extended.lua +++ b/test/library/class_extended.lua @@ -4,7 +4,7 @@ function test.defclass_basic() -- Test basic class creation local MyClass = defclass(nil) expect.eq(MyClass.__index, MyClass) - expect.eq(MyClass.ATTRS, nil) + expect.table_eq(MyClass.ATTRS, {}) expect.eq(MyClass.super, nil) expect.ne(getmetatable(MyClass), nil) end @@ -181,60 +181,47 @@ function test.assign_method() expect.eq(instance.new_field, 3) end -function test.invoke_before() - -- Test invoke_before method - local call_order = {} +-- function test.invoke_before() +-- -- Test invoke_before method +-- local call_order = {} - local MyClass = defclass(nil) - function MyClass:test_method() - table.insert(call_order, 'original') - end +-- local MyClass = defclass(nil) +-- function MyClass:test_method() +-- table.insert(call_order, 'original') +-- end - function MyClass:invoke_before_test_method() - table.insert(call_order, 'before') - end +-- function MyClass:invoke_before_test_method() +-- table.insert(call_order, 'before') +-- end - local instance = MyClass({}) - instance:invoke_before('test_method') +-- local instance = MyClass({}) +-- instance:invoke_before('test_method') - expect.eq(#call_order, 2) - expect.eq(call_order[1], 'before') - expect.eq(call_order[2], 'original') -end +-- expect.eq(#call_order, 2) +-- expect.eq(call_order[1], 'before') +-- expect.eq(call_order[2], 'original') +-- end -function test.invoke_after() - -- Test invoke_after method - local call_order = {} +-- function test.invoke_after() +-- -- Test invoke_after method +-- local call_order = {} - local MyClass = defclass(nil) - function MyClass:test_method() - table.insert(call_order, 'original') - end +-- local MyClass = defclass(nil) +-- function MyClass:test_method() +-- table.insert(call_order, 'original') +-- end - function MyClass:invoke_after_test_method() - table.insert(call_order, 'after') - end - - local instance = MyClass({}) - instance:invoke_after('test_method') - - expect.eq(#call_order, 2) - expect.eq(call_order[1], 'original') - expect.eq(call_order[2], 'after') -end - -function test.reserved_names() - -- Test that reserved names cannot be used - local MyClass = defclass(nil) +-- function MyClass:invoke_after_test_method() +-- table.insert(call_order, 'after') +-- end - expect.error_match('reserved', function() - MyClass.super = 'test' - end) +-- local instance = MyClass() +-- instance:invoke_after('test_method') - expect.error_match('reserved', function() - MyClass.ATTRS = 'test' - end) -end +-- expect.eq(#call_order, 2) +-- expect.eq(call_order[1], 'original') +-- expect.eq(call_order[2], 'after') +-- end function test.attrs_meta() -- Test ATTRS metatable behavior diff --git a/test/library/dfhack_core.lua b/test/library/dfhack_core.lua index ab0e3fbebc..a5fd601a33 100644 --- a/test/library/dfhack_core.lua +++ b/test/library/dfhack_core.lua @@ -38,22 +38,22 @@ function test.ensure_key() test_ensure_key() end -local function test_ensure_keys() - local t = {} - - -- Test creating nested keys - local result = ensure_keys(t, 'level1', 'level2', 'level3') - expect.eq(result, t.level1.level2.level3) - expect.table_eq(t.level1, {}) - expect.table_eq(t.level1.level2, {}) - expect.table_eq(t.level1.level2.level3, {}) - - -- Test partial existing path - t.level1.level2.level3 = {existing = true} - result = ensure_keys(t, 'level1', 'level2', 'level3') - expect.eq(result, t.level1.level2.level3) - expect.true_(result.existing) -end +-- local function test_ensure_keys() +-- local t = {} + +-- -- Test creating nested keys +-- local result = ensure_keys(t, 'level1', 'level2', 'level3') +-- expect.eq(result, t.level1.level2.level3) +-- expect.table_eq(t.level1, {}) +-- expect.table_eq(t.level1.level2, {}) +-- expect.table_eq(t.level1.level2.level3, {}) + +-- -- Test partial existing path +-- t.level1.level2.level3 = {existing = true} +-- result = ensure_keys(t, 'level1', 'level2', 'level3') +-- expect.eq(result, t.level1.level2.level3) +-- expect.true_(result.existing) +-- end function test.ensure_keys() test_ensure_keys() @@ -165,7 +165,7 @@ local function test_with_finalize() local cleanup_called = false local result - with_finalize( + dfhack.with_finalize( function() cleanup_called = true end, function() result = "success" end ) diff --git a/test/library/gui_basics.lua b/test/library/gui_basics.lua index e19eb68470..637102dd92 100644 --- a/test/library/gui_basics.lua +++ b/test/library/gui_basics.lua @@ -24,15 +24,27 @@ end function test.parse_inset() -- Test with table - local inset = { gui.parse_inset({l = 5, r = 10, t = 3, b = 7}) } - expect.eq(inset, {5, 3, 10, 7}) + local l,t,r,b = gui.parse_inset({l = 5, r = 10, t = 3, b = 7}) + expect.eq(l, 5); + expect.eq(t, 3) + expect.eq(r, 10) + expect.eq(b, 7) -- Test with single value - local inset2 = { gui.parse_inset(8) } - expect.eq(inset2, {8, 8, 8, 8}) + local l,t,r,b = gui.parse_inset(8) + expect.eq(l, 8) + expect.eq(t, 8) + expect.eq(r, 8) + expect.eq(b, 8) -- Test with x/y shorthand - local inset3 = { gui.parse_inset({x = 4, y = 6}) } + local l,t,r,b = gui.parse_inset({x = 4, y = 6}) + expect.eq(l, 4) + expect.eq(t, 6) + expect.eq(r, 4) + expect.eq(b, 6) + + expect.eq(inset3, {4, 6, 4, 6}) end @@ -247,16 +259,18 @@ function test.View_callback() end function test.View_cb_getfield() - local view = gui.View{test_field = 'test_value'} - local getter = view:cb_getfield('test_field') + local view = gui.View{} + view.test_field = 'test_value' + local getter = view:cb_getfield('test_field') expect.eq(getter(), 'test_value') end function test.View_cb_setfield() - local view = gui.View{test_field = 'initial'} - local setter = view:cb_setfield('test_field') + local view = gui.View{} + view.test_field = 'initial' + local setter = view:cb_setfield('test_field') setter('updated') expect.eq(view.test_field, 'updated') end From 40b6a763af3592106fc186808902f838af430c9d Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Thu, 17 Sep 2026 15:20:07 -0500 Subject: [PATCH 7/7] more fixes --- test/library/dfhack_core.lua | 10 +++++----- test/library/gui_basics.lua | 3 --- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/test/library/dfhack_core.lua b/test/library/dfhack_core.lua index a5fd601a33..cdcadc4dce 100644 --- a/test/library/dfhack_core.lua +++ b/test/library/dfhack_core.lua @@ -54,10 +54,10 @@ end -- expect.eq(result, t.level1.level2.level3) -- expect.true_(result.existing) -- end - -function test.ensure_keys() - test_ensure_keys() -end +-- +-- function test.ensure_keys() +-- test_ensure_keys() +-- end local function test_copyall() local t = {a = 1, b = 2, c = {nested = true}} @@ -181,7 +181,7 @@ end local function test_with_onerror() local cleanup_called = false local ok, err = pcall(function() - with_onerror( + dfhack.with_onerror( function() cleanup_called = true end, function() error("test error") end ) diff --git a/test/library/gui_basics.lua b/test/library/gui_basics.lua index 637102dd92..451199edc8 100644 --- a/test/library/gui_basics.lua +++ b/test/library/gui_basics.lua @@ -43,9 +43,6 @@ function test.parse_inset() expect.eq(t, 6) expect.eq(r, 4) expect.eq(b, 6) - - - expect.eq(inset3, {4, 6, 4, 6}) end function test.inset_frame()