From ddfbc91b5888d1d176b921af489a94eaedfbd25a Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Sat, 21 Feb 2026 22:52:13 +0300 Subject: [PATCH] tests: add regression test suite; update test fixtures Signed-off-by: NotAShelf Change-Id: I5ccf7cb25394bdcae068b49f66787c3a6a6a6964 --- tests/attrset.nixir | Bin 109 -> 109 bytes tests/comparison.nixir | Bin 107 -> 107 bytes tests/if.nixir | Bin 58 -> 58 bytes tests/lambda_pattern.nix | 4 +- tests/let.nixir | Bin 75 -> 75 bytes tests/logical.nixir | Bin 149 -> 149 bytes tests/operators.nixir | Bin 109 -> 109 bytes tests/precedence.nixir | Bin 318 -> 318 bytes tests/regression_test.cpp | 184 ++++++++++++++++++++++++++++++++++++++ tests/simple.nixir | Bin 34 -> 34 bytes tests/simple_op.nixir | Bin 53 -> 53 bytes tests/unary.nixir | Bin 113 -> 113 bytes 12 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 tests/regression_test.cpp diff --git a/tests/attrset.nixir b/tests/attrset.nixir index ad8b3e2d6836c80f26d9b6382c7b2980e8bd9f90..708f5ddd3bfd673373e97f8e7fb2703ef3e2b501 100644 GIT binary patch delta 11 Scmd1JWsL~(^kbUHngIY4kOLtA delta 11 Scmd1JWsL~(^kbaJngIY4i~}G5 diff --git a/tests/comparison.nixir b/tests/comparison.nixir index 3b41e90df303895ccf9d516428c005cae320689a..fb7b4fd62f9b8ac0f3c19b3a9c5eb7b0dcc7058f 100644 GIT binary patch delta 11 Scmd1KW{n8)^kbUHng#$9WCI%j delta 11 Scmd1KW{n8)^kbaJng#$9U;`Qe diff --git a/tests/if.nixir b/tests/if.nixir index 2668f3f78628ac947d2722bc160cffd2ebed17b7..4ee0f5992c9cf0477d61dbc9a4d28e10556fff9d 100644 GIT binary patch literal 58 fcmazD^7Lb3Kn08rAU+F-U}OZ7AOZ-$9GGeVQQrZN literal 58 gcmazD^7Lb5Kn08rAU+F-UIMK1qyoDD delta 11 ScmebFW{n8)^kbaJ>IMK1paQx8 diff --git a/tests/logical.nixir b/tests/logical.nixir index 2544d5cd95e5f503526e013fea2508eaf43c1358..010a5f558addb374be5e2b3786b015f964a46663 100644 GIT binary patch delta 13 UcmbQrIF*q#BFNK^X(H +#include + +using namespace nix_irc; + +int failures = 0; + +#define TEST_CHECK(cond, msg) \ + do { \ + if (!(cond)) { \ + std::cerr << " FAIL: " << msg << std::endl; \ + failures++; \ + } else { \ + std::cout << " PASS: " << msg << std::endl; \ + } \ + } while (0) + +#define TEST_PASS(msg) std::cout << " PASS: " << msg << std::endl +#define TEST_FAIL(msg) \ + do { \ + std::cerr << " FAIL: " << msg << std::endl; \ + failures++; \ + } while (0) + +void test_enum_compatibility() { + std::cout << "> Enum compatibility..." << std::endl; + + if (static_cast(NodeType::WITH) == 0x32) { + std::cout << " PASS: WITH has correct value 0x32" << std::endl; + } else { + std::cerr << " FAIL: WITH should be 0x32, got " + << static_cast(NodeType::WITH) << std::endl; + } + + if (static_cast(NodeType::HAS_ATTR) == 0x34) { + std::cout << " PASS: HAS_ATTR has value 0x34 (new slot after WITH bump)" + << std::endl; + } else if (static_cast(NodeType::HAS_ATTR) == 0x33 && + static_cast(NodeType::WITH) == 0x32) { + std::cout << " PASS: HAS_ATTR has value 0x33 (restored original with WITH " + "at 0x32)" + << std::endl; + } else { + std::cerr << " FAIL: HAS_ATTR value is " + << static_cast(NodeType::HAS_ATTR) + << " (expected 0x34 or 0x33 with WITH=0x32)" << std::endl; + } + + if (IR_VERSION == 2) { + std::cout << " PASS: IR_VERSION bumped to 2 for breaking change" + << std::endl; + } else if (static_cast(NodeType::WITH) == 0x32) { + std::cout << " PASS: IR_VERSION unchanged but WITH restored to 0x32" + << std::endl; + } else { + std::cerr << " FAIL: Either bump IR_VERSION or fix enum values" + << std::endl; + } +} + +void test_serializer_select_with_default() { + std::cout << "> SELECT serialization with default_expr..." << std::endl; + + auto expr = std::make_shared(ConstIntNode(42)); + auto attr = std::make_shared(ConstStringNode("key")); + auto default_val = std::make_shared(ConstIntNode(100)); + + SelectNode select_node(expr, attr); + select_node.default_expr = default_val; + auto select = std::make_shared(select_node); + + IRModule module; + module.entry = select; + + Serializer ser; + auto bytes = ser.serialize_to_bytes(module); + + Deserializer deser; + auto loaded = deser.deserialize(bytes); + + auto *loaded_select = loaded.entry->get_if(); + if (loaded_select && loaded_select->default_expr && + *loaded_select->default_expr) { + auto *def_val = (*loaded_select->default_expr)->get_if(); + if (def_val && def_val->value == 100) { + std::cout << " PASS: SELECT with default_expr round-trips correctly" + << std::endl; + } else { + std::cerr << " FAIL: default_expr value incorrect" << std::endl; + } + } else { + std::cerr << " FAIL: default_expr not deserialized (missing u8 flag read)" + << std::endl; + } +} + +void test_serializer_select_without_default() { + std::cout << "> SELECT serialization without default_expr..." << std::endl; + + auto expr = std::make_shared(ConstIntNode(42)); + auto attr = std::make_shared(ConstStringNode("key")); + + SelectNode select_node(expr, attr); + auto select = std::make_shared(select_node); + + IRModule module; + module.entry = select; + + Serializer ser; + auto bytes = ser.serialize_to_bytes(module); + + Deserializer deser; + auto loaded = deser.deserialize(bytes); + + auto *loaded_select = loaded.entry->get_if(); + if (loaded_select && + (!loaded_select->default_expr || !*loaded_select->default_expr)) { + std::cout << " PASS: SELECT without default_expr round-trips correctly" + << std::endl; + } else { + std::cerr << " FAIL: default_expr should be null/absent" << std::endl; + } +} + +void test_parser_brace_depth_in_strings() { + std::cout << "> Parser brace depth handling in strings..." << std::endl; + + std::string test_input = R"( + let s = "test}"; in ${s} + )"; + + std::cout << " Test input contains '}' inside string - should not end " + "interpolation" + << std::endl; + std::cout << " NOTE: This test requires running through actual parser" + << std::endl; +} + +void test_parser_has_ellipsis_usage() { + std::cout << "> Parser has_ellipsis usage..." << std::endl; + + std::cout << " NOTE: LambdaNode should have strict_pattern field when " + "has_ellipsis is false" + << std::endl; + std::cout << " This requires checking the parser output for strict patterns" + << std::endl; +} + +void test_parser_expect_in_speculative_parsing() { + std::cout << "> Parser expect() in speculative parsing..." << std::endl; + + std::cout << " NOTE: try_parse_lambda should not throw on non-lambda input" + << std::endl; + std::cout << " This requires testing parser with invalid lambda patterns" + << std::endl; +} + +int main() { + std::cout << "=== Regression Tests for Nixir ===" << std::endl << std::endl; + + test_enum_compatibility(); + std::cout << std::endl; + + test_serializer_select_with_default(); + std::cout << std::endl; + + test_serializer_select_without_default(); + std::cout << std::endl; + + test_parser_brace_depth_in_strings(); + std::cout << std::endl; + + test_parser_has_ellipsis_usage(); + std::cout << std::endl; + + test_parser_expect_in_speculative_parsing(); + std::cout << std::endl; + + std::cout << "=== Tests Complete ===" << std::endl; + std::cout << "Failures: " << failures << std::endl; + return failures > 0 ? 1 : 0; +} diff --git a/tests/simple.nixir b/tests/simple.nixir index ee4989f321a6af3fbb555b83bf86fb1f8eac086d..3e26f836aabd5acf5d45ae244f70fbff8eab4fea 100644 GIT binary patch literal 34 VcmazD^7Lb3Kn0A9Aifq<5CAHj0dN2S literal 34 UcmazD^7Lb5Kn09o0WGK?04je0ZvX%Q diff --git a/tests/simple_op.nixir b/tests/simple_op.nixir index fa2a99e7ff07eb831392b19d0ce5ea126620cd74..18ffbd3e6a78b619ea3c0a76bafd0c43e9d94148 100644 GIT binary patch literal 53 acmazD^7Lb3Kn09SU_K*=1QReCrVs!{>j7*4 literal 53 acmazD^7Lb5Kn09SU_MwFCI_aOpy~icx&dnd diff --git a/tests/unary.nixir b/tests/unary.nixir index 00c75c62a194b746260cf64638ba4c4429a1ec94..652fabc4b463b276334d7d94b5fbff4d886983e0 100644 GIT binary patch delta 11 ScmXRcWQ_>&^kbUHngak6=mRYP delta 11 ScmXRcWQ_>&^kbaJngak6