-- Load the helper script dofile("luahelper.lua") -- Test helper function local function assert(condition, message) if not condition then error("ASSERTION FAILED: " .. (message or "unknown error")) end end local function test(name, fn) local ok, err = pcall(fn) if ok then print("PASS: " .. name) else print("FAIL: " .. name .. " - " .. tostring(err)) end end -- Test fromCSV basic parsing test("fromCSV basic", function() local csv = "a,b,c\n1,2,3\n4,5,6" local rows = fromCSV(csv) assert(#rows == 3, "Should have 3 rows") assert(rows[1][1] == "a", "First row first field should be 'a'") assert(rows[2][2] == "2", "Second row second field should be '2'") end) -- Test fromCSV with headers test("fromCSV with headers", function() local csv = "foo,bar,baz\n1,2,3\n4,5,6" local rows = fromCSV(csv, ",", true) assert(#rows == 2, "Should have 2 data rows") assert(rows[1][1] == "1", "First row first field should be '1'") assert(rows[1].foo == "1", "First row foo should be '1'") assert(rows[1].bar == "2", "First row bar should be '2'") assert(rows[1].baz == "3", "First row baz should be '3'") end) -- Test fromCSV with custom delimiter test("fromCSV with tab delimiter", function() local csv = "a\tb\tc\n1\t2\t3" local rows = fromCSV(csv, "\t") assert(#rows == 2, "Should have 2 rows") assert(rows[1][1] == "a", "First row first field should be 'a'") assert(rows[2][2] == "2", "Second row second field should be '2'") end) -- Test fromCSV with quoted fields test("fromCSV with quoted fields", function() local csv = '"hello,world","test"\n"foo","bar"' local rows = fromCSV(csv) assert(#rows == 2, "Should have 2 rows") assert(rows[1][1] == "hello,world", "Quoted field with comma should be preserved") assert(rows[1][2] == "test", "Second field should be 'test'") end) -- Test toCSV basic test("toCSV basic", function() local rows = { { "a", "b", "c" }, { "1", "2", "3" } } local csv = toCSV(rows) assert(csv == "a,b,c\n1,2,3", "CSV output should match expected") end) -- Test toCSV with custom delimiter test("toCSV with tab delimiter", function() local rows = { { "a", "b", "c" }, { "1", "2", "3" } } local csv = toCSV(rows, "\t") assert(csv == "a\tb\tc\n1\t2\t3", "TSV output should match expected") end) -- Test toCSV with fields needing quoting test("toCSV with quoted fields", function() local rows = { { "hello,world", "test" }, { "foo", "bar" } } local csv = toCSV(rows) assert(csv == '"hello,world",test\nfoo,bar', "Fields with commas should be quoted") end) -- Test round trip test("fromCSV toCSV round trip", function() local original = "a,b,c\n1,2,3\n4,5,6" local rows = fromCSV(original) local csv = toCSV(rows) assert(csv == original, "Round trip should preserve original") end) -- Test round trip with headers test("fromCSV toCSV round trip with headers", function() local original = "foo,bar,baz\n1,2,3\n4,5,6" local rows = fromCSV(original, ",", true) local csv = toCSV(rows) local expected = "1,2,3\n4,5,6" assert(csv == expected, "Round trip with headers should preserve data rows") end) -- Math function tests test("min function", function() assert(min(5, 3) == 3, "min(5, 3) should be 3") assert(min(-1, 0) == -1, "min(-1, 0) should be -1") assert(min(10, 10) == 10, "min(10, 10) should be 10") end) test("max function", function() assert(max(5, 3) == 5, "max(5, 3) should be 5") assert(max(-1, 0) == 0, "max(-1, 0) should be 0") assert(max(10, 10) == 10, "max(10, 10) should be 10") end) test("round function", function() assert(round(3.14159) == 3, "round(3.14159) should be 3") assert(round(3.14159, 2) == 3.14, "round(3.14159, 2) should be 3.14") assert(round(3.5) == 4, "round(3.5) should be 4") assert(round(3.4) == 3, "round(3.4) should be 3") assert(round(123.456, 1) == 123.5, "round(123.456, 1) should be 123.5") end) test("floor function", function() assert(floor(3.7) == 3, "floor(3.7) should be 3") assert(floor(-3.7) == -4, "floor(-3.7) should be -4") assert(floor(5) == 5, "floor(5) should be 5") end) test("ceil function", function() assert(ceil(3.2) == 4, "ceil(3.2) should be 4") assert(ceil(-3.2) == -3, "ceil(-3.2) should be -3") assert(ceil(5) == 5, "ceil(5) should be 5") end) -- String function tests test("upper function", function() assert(upper("hello") == "HELLO", "upper('hello') should be 'HELLO'") assert(upper("Hello World") == "HELLO WORLD", "upper('Hello World') should be 'HELLO WORLD'") assert(upper("123abc") == "123ABC", "upper('123abc') should be '123ABC'") end) test("lower function", function() assert(lower("HELLO") == "hello", "lower('HELLO') should be 'hello'") assert(lower("Hello World") == "hello world", "lower('Hello World') should be 'hello world'") assert(lower("123ABC") == "123abc", "lower('123ABC') should be '123abc'") end) test("format function", function() assert(format("Hello %s", "World") == "Hello World", "format should work") assert(format("Number: %d", 42) == "Number: 42", "format with number should work") assert(format("%.2f", 3.14159) == "3.14", "format with float should work") end) test("trim function", function() assert(trim(" hello ") == "hello", "trim should remove leading and trailing spaces") assert(trim(" hello world ") == "hello world", "trim should preserve internal spaces") assert(trim("hello") == "hello", "trim should not affect strings without spaces") assert(trim(" ") == "", "trim should handle all spaces") end) test("strsplit function", function() local result = strsplit("a,b,c", ",") assert(#result == 3, "strsplit should return 3 elements") assert(result[1] == "a", "First element should be 'a'") assert(result[2] == "b", "Second element should be 'b'") assert(result[3] == "c", "Third element should be 'c'") end) test("strsplit with default separator", function() local result = strsplit("a b c") assert(#result == 3, "strsplit with default should return 3 elements") assert(result[1] == "a", "First element should be 'a'") assert(result[2] == "b", "Second element should be 'b'") assert(result[3] == "c", "Third element should be 'c'") end) test("strsplit with custom separator", function() local result = strsplit("a|b|c", "|") assert(#result == 3, "strsplit with pipe should return 3 elements") assert(result[1] == "a", "First element should be 'a'") assert(result[2] == "b", "Second element should be 'b'") assert(result[3] == "c", "Third element should be 'c'") end) -- Conversion function tests test("num function", function() assert(num("123") == 123, "num('123') should be 123") assert(num("45.67") == 45.67, "num('45.67') should be 45.67") assert(num("invalid") == 0, "num('invalid') should be 0") assert(num("") == 0, "num('') should be 0") end) test("str function", function() assert(str(123) == "123", "str(123) should be '123'") assert(str(45.67) == "45.67", "str(45.67) should be '45.67'") assert(str(0) == "0", "str(0) should be '0'") end) test("is_number function", function() assert(is_number("123") == true, "is_number('123') should be true") assert(is_number("45.67") == true, "is_number('45.67') should be true") assert(is_number("invalid") == false, "is_number('invalid') should be false") assert(is_number("") == false, "is_number('') should be false") assert(is_number("123abc") == false, "is_number('123abc') should be false") end) -- Table function tests test("isArray function", function() assert(isArray({ 1, 2, 3 }) == true, "isArray should return true for sequential array") assert(isArray({ "a", "b", "c" }) == true, "isArray should return true for string array") assert(isArray({}) == true, "isArray should return true for empty array") assert(isArray({ a = 1, b = 2 }) == false, "isArray should return false for map") assert(isArray({ 1, 2, [4] = 4 }) == false, "isArray should return false for sparse array") assert(isArray({ [1] = 1, [2] = 2, [3] = 3 }) == true, "isArray should return true for 1-indexed array") assert(isArray({ [0] = 1, [1] = 2 }) == false, "isArray should return false for 0-indexed array") assert(isArray({ [1] = 1, [2] = 2, [4] = 4 }) == false, "isArray should return false for non-sequential array") assert(isArray("not a table") == false, "isArray should return false for non-table") assert(isArray(123) == false, "isArray should return false for number") end) print("\nAll tests completed!")