NEURON
initial_block.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2025 EPFL.
3  * See the top-level LICENSE file for details.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include "ast/program.hpp"
10 #include "utils/test_utils.hpp"
16 
17 #include <catch2/catch_test_macros.hpp>
18 #include <catch2/matchers/catch_matchers_string.hpp>
19 
20 using namespace nmodl;
22 
23 using Catch::Matchers::ContainsSubstring; // ContainsSubstring in newer Catch2
24 
25 //=============================================================================
26 // MergeInitialBlocks visitor tests
27 //=============================================================================
28 
31  auto ast = driver.parse_string(text);
33  return to_nmodl(*ast);
34 }
35 
36 SCENARIO("Check multiple INITIAL blocks are handled properly", "[visitor][merge_initial_blocks]") {
37  GIVEN("A mod file with multiple INITIAL blocks") {
38  const auto nmodl_text_before = R"(
39  NEURON {
40  SUFFIX InitialBlockTest
41  RANGE foo, bar
42  }
43  INITIAL {
44  foo = 1
45  }
46  INITIAL {
47  bar = 2
48  }
49  )";
50  const auto nmodl_text_after = R"(
51  NEURON {
52  SUFFIX InitialBlockTest
53  RANGE foo, bar
54  }
55  INITIAL {
56  foo = 1
57  bar = 2
58  }
59  )";
61  auto ast_expected = driver.parse_string(nmodl_text_after);
62  const auto program_expected = to_nmodl(ast_expected);
63  const auto program_actual = generate_mod_after_merge_initial_blocks_visitor(
64  nmodl_text_before);
65  THEN("expected and actual should be identical at the level of the AST") {
66  // TODO the AST class lacks an overload for `operator==` so here we compare it at the
67  // string level
68  REQUIRE(reindent_text(program_actual) == reindent_text(program_expected));
69  }
70  }
71  GIVEN("A mod file with an INITIAL block only inside of a NET_RECEIVE block") {
72  const auto nmodl_text_before = R"(
73  NEURON {
74  SUFFIX test
75  RANGE foo, bar
76  }
77 
78  NET_RECEIVE (w) {
79  INITIAL {
80  foo = 1
81  }
82  }
83  )";
84  const auto program_actual = generate_mod_after_merge_initial_blocks_visitor(
85  nmodl_text_before);
86  THEN("leave the mod file as-is") {
87  REQUIRE(reindent_text(program_actual) == reindent_text(nmodl_text_before));
88  }
89  }
90  GIVEN("A mod file with an INITIAL block, and one inside of a NET_RECEIVE block") {
91  // Note that the visitor actually modifies the AST (since there is > 1 INITIAL block in the
92  // entire file: one top-level, and one in NET_RECEIVE). If we place the top-level INITIAL
93  // block before NET_RECEIVE in the below, the top-level INITIAL block will be deleted and
94  // appended. However, since the position of the INITIAL block in the mod file has no impact
95  // on the semantics, the visitor works as expected
96  const auto nmodl_text_before = R"(
97  NEURON {
98  SUFFIX test
99  RANGE foo, bar
100  }
101 
102  NET_RECEIVE (w) {
103  INITIAL {
104  foo = 1
105  }
106  }
107 
108  INITIAL {
109  bar = 2
110  }
111  )";
112  const auto program_actual = generate_mod_after_merge_initial_blocks_visitor(
113  nmodl_text_before);
114  THEN("leave the mod file as-is") {
115  REQUIRE(reindent_text(program_actual) == reindent_text(nmodl_text_before));
116  }
117  }
118 }
Class that binds all pieces together for parsing nmodl file.
Visitor which merges all INITIAL blocks into one.
void visit_program(ast::Program &node) override
visit node of type ast::Program
bool parse_string(const std::string &input)
parser Units provided as string (used for testing)
Definition: unit_driver.cpp:40
auto generate_mod_after_merge_initial_blocks_visitor(std::string const &text)
SCENARIO("Check multiple INITIAL blocks are handled properly", "[visitor][merge_initial_blocks]")
Visitor which merges all INITIAL blocks into one.
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
std::string reindent_text(const std::string &text, int indent_level)
Reindent nmodl text for text-to-text comparison.
Definition: test_utils.cpp:55
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
std::string to_nmodl(const ast::Ast &node, const std::set< ast::AstNodeType > &exclude_types)
Given AST node, return the NMODL string representation.
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
#define text
Definition: plot.cpp:60
Auto generated AST classes declaration.
THIS FILE IS GENERATED AT BUILD TIME AND SHALL NOT BE EDITED.
nmodl::parser::UnitDriver driver
Definition: parser.cpp:28
Utility functions for visitors implementation.