1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
/*************************************************************************
* Copyright (C) 2023 Blue Brain Project
*
* This file is part of NMODL distributed under the terms of the GNU
* Lesser General Public License. See top-level LICENSE file for details.
*************************************************************************/
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_string.hpp>
#include "ast/program.hpp"
#include "codegen/codegen_compatibility_visitor.hpp"
#include "parser/nmodl_driver.hpp"
#include "test/unit/utils/test_utils.hpp"
#include "visitors/perf_visitor.hpp"
#include "visitors/symtab_visitor.hpp"
using Catch::Matchers::ContainsSubstring;
using namespace nmodl;
using namespace visitor;
using namespace codegen;
using nmodl::parser::NmodlDriver;
/// Return true if it failed and false otherwise
bool runCompatibilityVisitor(const std::string& nmodl_text) {
const auto& ast = NmodlDriver().parse_string(nmodl_text);
SymtabVisitor().visit_program(*ast);
PerfVisitor().visit_program(*ast);
return CodegenCompatibilityVisitor().find_unhandled_ast_nodes(*ast);
}
SCENARIO("Uncompatible constructs should failed", "[codegen][compatibility_visitor]") {
GIVEN("A mod file containing an EXTERNAL construct") {
std::string const nmodl_text = R"(
NEURON {
EXTERNAL apc_metap
}
)";
THEN("should failed") {
bool failed = runCompatibilityVisitor(nmodl_text);
REQUIRE(failed);
}
}
GIVEN("A mod file containing a written GLOBAL var") {
std::string const nmodl_text = R"(
NEURON {
GLOBAL foo
}
PROCEDURE bar() {
foo = 1
}
)";
THEN("should failed") {
bool failed = runCompatibilityVisitor(nmodl_text);
REQUIRE(failed);
}
}
GIVEN("A mod file containing a written un-writtable var") {
std::string const nmodl_text = R"(
PARAMETER {
foo = 1
}
PROCEDURE bar() {
foo = 1
}
)";
THEN("should failed") {
bool failed = runCompatibilityVisitor(nmodl_text);
REQUIRE(failed);
}
}
GIVEN("A mod file with BBCOREPOINTER without bbcore_read / bbcore_write") {
std::string const nmodl_text = R"(
NEURON {
BBCOREPOINTER rng
}
)";
THEN("should failed") {
bool failed = runCompatibilityVisitor(nmodl_text);
REQUIRE(failed);
}
}
GIVEN("A mod file with BBCOREPOINTER without bbcore_write") {
std::string const nmodl_text = R"(
NEURON {
BBCOREPOINTER rng
}
VERBATIM
static void bbcore_read(double* x, int* d, int* xx, int* offset, _threadargsproto_) {
}
ENDVERBATIM
)";
THEN("should failed") {
bool failed = runCompatibilityVisitor(nmodl_text);
REQUIRE(failed);
}
}
GIVEN("A mod file with BBCOREPOINTER without bbcore_read") {
std::string const nmodl_text = R"(
NEURON {
BBCOREPOINTER rng
}
VERBATIM
static void bbcore_write(double* x, int* d, int* xx, int* offset, _threadargsproto_) {
}
ENDVERBATIM
)";
THEN("should failed") {
bool failed = runCompatibilityVisitor(nmodl_text);
REQUIRE(failed);
}
}
GIVEN("A mod file with BBCOREPOINTER with bbcore_read / bbcore_write") {
std::string const nmodl_text = R"(
NEURON {
BBCOREPOINTER rng
}
VERBATIM
static void bbcore_read(double* x, int* d, int* xx, int* offset, _threadargsproto_) {
}
static void bbcore_write(double* x, int* d, int* xx, int* offset, _threadargsproto_) {
}
ENDVERBATIM
)";
THEN("should succeed") {
bool failed = runCompatibilityVisitor(nmodl_text);
REQUIRE(!failed);
}
}
GIVEN("A mod file with a no SOLVE method") {
std::string const nmodl_text = R"(
BREAKPOINT {
SOLVE state
}
)";
THEN("should succeed") {
bool failed = runCompatibilityVisitor(nmodl_text);
REQUIRE(!failed);
}
}
GIVEN("A mod file with a invalid SOLVE method") {
std::string const nmodl_text = R"(
BREAKPOINT {
SOLVE state METHOD runge
}
)";
THEN("should failed") {
bool failed = runCompatibilityVisitor(nmodl_text);
REQUIRE(failed);
}
}
}
|