brewery
notashelf /
63a9eddc49735e9136a6cde78cdc772d9e7ad259

nixir

public

Import-resolving Nix IR plugin

Star0tarball
clone
ssh://git@git.notashelf.dev:33/notashelf/nixir.git
tests/regression_test.cppCpp184 lines6.3 KB
1
#include "irc/serializer.h"
2
#include "irc/types.h"
3
#include <cassert>
4
#include <iostream>
5
6
using namespace nix_irc;
7
8
int failures = 0;
9
10
#define TEST_CHECK(cond, msg)                                                  \
11
  do {                                                                         \
12
    if (!(cond)) {                                                             \
13
      std::cerr << "  FAIL: " << msg << std::endl;                             \
14
      failures++;                                                              \
15
    } else {                                                                   \
16
      std::cout << "  PASS: " << msg << std::endl;                             \
17
    }                                                                          \
18
  } while (0)
19
20
#define TEST_PASS(msg) std::cout << "  PASS: " << msg << std::endl
21
#define TEST_FAIL(msg)                                                         \
22
  do {                                                                         \
23
    std::cerr << "  FAIL: " << msg << std::endl;                               \
24
    failures++;                                                                \
25
  } while (0)
26
27
void test_enum_compatibility() {
28
  std::cout << "> Enum compatibility..." << std::endl;
29
30
  if (static_cast<uint8_t>(NodeType::WITH) == 0x32) {
31
    std::cout << "  PASS: WITH has correct value 0x32" << std::endl;
32
  } else {
33
    std::cerr << "  FAIL: WITH should be 0x32, got "
34
              << static_cast<uint8_t>(NodeType::WITH) << std::endl;
35
  }
36
37
  if (static_cast<uint8_t>(NodeType::HAS_ATTR) == 0x34) {
38
    std::cout << "  PASS: HAS_ATTR has value 0x34 (new slot after WITH bump)"
39
              << std::endl;
40
  } else if (static_cast<uint8_t>(NodeType::HAS_ATTR) == 0x33 &&
41
             static_cast<uint8_t>(NodeType::WITH) == 0x32) {
42
    std::cout << "  PASS: HAS_ATTR has value 0x33 (restored original with WITH "
43
                 "at 0x32)"
44
              << std::endl;
45
  } else {
46
    std::cerr << "  FAIL: HAS_ATTR value is "
47
              << static_cast<uint8_t>(NodeType::HAS_ATTR)
48
              << " (expected 0x34 or 0x33 with WITH=0x32)" << std::endl;
49
  }
50
51
  if (IR_VERSION == 2) {
52
    std::cout << "  PASS: IR_VERSION bumped to 2 for breaking change"
53
              << std::endl;
54
  } else if (static_cast<uint8_t>(NodeType::WITH) == 0x32) {
55
    std::cout << "  PASS: IR_VERSION unchanged but WITH restored to 0x32"
56
              << std::endl;
57
  } else {
58
    std::cerr << "  FAIL: Either bump IR_VERSION or fix enum values"
59
              << std::endl;
60
  }
61
}
62
63
void test_serializer_select_with_default() {
64
  std::cout << "> SELECT serialization with default_expr..." << std::endl;
65
66
  auto expr = std::make_shared<Node>(ConstIntNode(42));
67
  auto attr = std::make_shared<Node>(ConstStringNode("key"));
68
  auto default_val = std::make_shared<Node>(ConstIntNode(100));
69
70
  SelectNode select_node(expr, attr);
71
  select_node.default_expr = default_val;
72
  auto select = std::make_shared<Node>(select_node);
73
74
  IRModule module;
75
  module.entry = select;
76
77
  Serializer ser;
78
  auto bytes = ser.serialize_to_bytes(module);
79
80
  Deserializer deser;
81
  auto loaded = deser.deserialize(bytes);
82
83
  auto *loaded_select = loaded.entry->get_if<SelectNode>();
84
  if (loaded_select && loaded_select->default_expr &&
85
      *loaded_select->default_expr) {
86
    auto *def_val = (*loaded_select->default_expr)->get_if<ConstIntNode>();
87
    if (def_val && def_val->value == 100) {
88
      std::cout << "  PASS: SELECT with default_expr round-trips correctly"
89
                << std::endl;
90
    } else {
91
      std::cerr << "  FAIL: default_expr value incorrect" << std::endl;
92
    }
93
  } else {
94
    std::cerr << "  FAIL: default_expr not deserialized (missing u8 flag read)"
95
              << std::endl;
96
  }
97
}
98
99
void test_serializer_select_without_default() {
100
  std::cout << "> SELECT serialization without default_expr..." << std::endl;
101
102
  auto expr = std::make_shared<Node>(ConstIntNode(42));
103
  auto attr = std::make_shared<Node>(ConstStringNode("key"));
104
105
  SelectNode select_node(expr, attr);
106
  auto select = std::make_shared<Node>(select_node);
107
108
  IRModule module;
109
  module.entry = select;
110
111
  Serializer ser;
112
  auto bytes = ser.serialize_to_bytes(module);
113
114
  Deserializer deser;
115
  auto loaded = deser.deserialize(bytes);
116
117
  auto *loaded_select = loaded.entry->get_if<SelectNode>();
118
  if (loaded_select &&
119
      (!loaded_select->default_expr || !*loaded_select->default_expr)) {
120
    std::cout << "  PASS: SELECT without default_expr round-trips correctly"
121
              << std::endl;
122
  } else {
123
    std::cerr << "  FAIL: default_expr should be null/absent" << std::endl;
124
  }
125
}
126
127
void test_parser_brace_depth_in_strings() {
128
  std::cout << "> Parser brace depth handling in strings..." << std::endl;
129
130
  std::string test_input = R"(
131
        let s = "test}"; in ${s}
132
    )";
133
134
  std::cout << "  Test input contains '}' inside string - should not end "
135
               "interpolation"
136
            << std::endl;
137
  std::cout << "  NOTE: This test requires running through actual parser"
138
            << std::endl;
139
}
140
141
void test_parser_has_ellipsis_usage() {
142
  std::cout << "> Parser has_ellipsis usage..." << std::endl;
143
144
  std::cout << "  NOTE: LambdaNode should have strict_pattern field when "
145
               "has_ellipsis is false"
146
            << std::endl;
147
  std::cout << "  This requires checking the parser output for strict patterns"
148
            << std::endl;
149
}
150
151
void test_parser_expect_in_speculative_parsing() {
152
  std::cout << "> Parser expect() in speculative parsing..." << std::endl;
153
154
  std::cout << "  NOTE: try_parse_lambda should not throw on non-lambda input"
155
            << std::endl;
156
  std::cout << "  This requires testing parser with invalid lambda patterns"
157
            << std::endl;
158
}
159
160
int main() {
161
  std::cout << "=== Regression Tests for Nixir ===" << std::endl << std::endl;
162
163
  test_enum_compatibility();
164
  std::cout << std::endl;
165
166
  test_serializer_select_with_default();
167
  std::cout << std::endl;
168
169
  test_serializer_select_without_default();
170
  std::cout << std::endl;
171
172
  test_parser_brace_depth_in_strings();
173
  std::cout << std::endl;
174
175
  test_parser_has_ellipsis_usage();
176
  std::cout << std::endl;
177
178
  test_parser_expect_in_speculative_parsing();
179
  std::cout << std::endl;
180
181
  std::cout << "=== Tests Complete ===" << std::endl;
182
  std::cout << "Failures: " << failures << std::endl;
183
  return failures > 0 ? 1 : 0;
184
}