8 #include <catch2/catch_test_macros.hpp>
20 using namespace nmodl;
21 using namespace visitor;
23 using namespace test_utils;
33 const std::string& text,
34 const std::vector<std::pair<std::string, std::string>>& variables) {
37 for (
const auto& variable: variables) {
38 RenameVisitor(variable.first, variable.second).visit_program(*ast);
40 std::stringstream stream;
41 NmodlPrintVisitor(stream).visit_program(*ast);
44 CheckParentVisitor().check_ast(*ast);
49 SCENARIO(
"Renaming any variable in mod file with RenameVisitor",
"[visitor][rename]") {
52 std::string input_nmodl_text = R
"(
55 USEION na READ ena WRITE ina
60 gNaTs2_tbar = 0.1 (S/cm2)
69 m and gNaTs2_tbar remain same here
74 gNaTs2_t = gNaTs2_tbar*m*m*m*h
75 ina = gNaTs2_t*(v-ena)
83 std::string output_nmodl_text = R
"(
86 USEION na READ ena WRITE ina
91 new_gNaTs2_tbar = 0.1 (S/cm2)
100 m and gNaTs2_tbar remain same here
105 gNaTs2_t = new_gNaTs2_tbar*mm*mm*mm*h
106 ina = gNaTs2_t*(v-ena)
114 std::string expected_output = reindent_text(output_nmodl_text);
116 THEN("existing variables could be renamed") {
117 std::vector<std::pair<std::string, std::string>> variables = {
119 {
"gNaTs2_tbar",
"new_gNaTs2_tbar"},
123 REQUIRE(result == expected_output);
126 THEN(
"non-existing variables will be ignored") {
127 std::vector<std::pair<std::string, std::string>> variables = {
128 {
"unknown_variable",
"doesnot_matter"}};
130 REQUIRE(result == input);
143 SymtabVisitor().visit_program(*ast);
145 VerbatimVarRenameVisitor().visit_program(*ast);
146 LocalVarRenameVisitor().visit_program(*ast);
147 std::stringstream stream;
148 NmodlPrintVisitor(stream).visit_program(*ast);
152 SCENARIO(
"Renaming with presence of local and global variables in same block",
153 "[visitor][rename]") {
154 GIVEN(
"A neuron block and procedure with same variable name") {
155 std::string nmodl_text = R
"(
158 USEION na READ ena WRITE ina
164 gNaTs2_tbar = 2.1 + ena
168 std::string expected_nmodl_text = R"(
171 USEION na READ ena WRITE ina
176 LOCAL gNaTs2_tbar_r_0
177 gNaTs2_tbar_r_0 = 2.1+ena
181 THEN("var renaming pass changes only local variables in procedure") {
185 REQUIRE(result == expected_result);
190 SCENARIO(
"Renaming in the absence of global blocks",
"[visitor][rename]") {
191 GIVEN(
"Procedures containing same variables") {
192 std::string nmodl_text = R
"(
193 PROCEDURE rates_1() {
195 gNaTs2_tbar = 2.1+ena
198 PROCEDURE rates_2() {
200 gNaTs2_tbar = 2.1+ena
204 THEN("nothing gets renamed") {
207 REQUIRE(result == input);
212 SCENARIO(
"Variable renaming in nested blocks",
"[visitor][rename]") {
213 GIVEN(
"Mod file containing procedures with nested blocks") {
214 std::string input_nmodl_text = R
"(
217 USEION na READ ena WRITE ina
222 gNaTs2_tbar = 0.1 (S/cm2)
233 gNaTs2_t = gNaTs2_tbar*m*m*m*h
234 ina = gNaTs2_t*(v-ena)
256 LOCAL h, x, gNaTs2_tbar
257 m = h * x * gNaTs2_tbar + tau
263 std::string expected_nmodl_text = R"(
266 USEION na READ ena WRITE ina
271 gNaTs2_tbar = 0.1 (S/cm2)
282 gNaTs2_t = gNaTs2_tbar*m*m*m*h
283 ina = gNaTs2_t*(v-ena)
285 LOCAL gNaTs2_t_r_0, h_r_1
286 gNaTs2_t_r_0 = m+h_r_1
289 m_r_1 = gNaTs2_t_r_0+h_r_1
302 m_r_2 = x+gNaTs2_tbar
305 LOCAL h_r_2, x_r_0, gNaTs2_tbar_r_0
306 m_r_2 = h_r_2*x_r_0*gNaTs2_tbar_r_0+tau
312 THEN("variables conflicting with global variables get renamed starting from inner block") {
316 REQUIRE(result == expected_result);
322 SCENARIO(
"Renaming in presence of local variable in verbatim block",
"[visitor][rename]") {
323 GIVEN(
"A neuron block and procedure with same variable name") {
324 std::string nmodl_text = R
"(
333 #define my_macro_var _lgNaTs2_tbar*2
335 gNaTs2_tbar = my_macro_var + 1
345 std::string expected_nmodl_text = R"(
351 LOCAL gNaTs2_tbar_r_0, x
354 #define my_macro_var gNaTs2_tbar_r_0*2
356 gNaTs2_tbar_r_0 = my_macro_var+1
366 THEN("var renaming pass changes local & global variable in verbatim block") {
370 REQUIRE(result == expected_result);