NEURON
test_utils.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 Blue Brain Project, EPFL.
3  * See the top-level LICENSE file for details.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include "test_utils.hpp"
9 #include "nmodl/utils/logger.hpp"
10 #include "utils/string_utils.hpp"
11 
12 #include <cassert>
13 
14 #include <spdlog/sinks/ostream_sink.h>
15 
16 namespace nmodl {
17 namespace test_utils {
18 
19 int count_leading_spaces(std::string text) {
20  auto const length = text.size();
22  auto const num_whitespaces = length - text.size();
23  assert(num_whitespaces <= std::numeric_limits<int>::max());
24  return static_cast<int>(num_whitespaces);
25 }
26 
27 /// check if string has only whitespaces
28 bool is_empty(const std::string& text) {
29  return nmodl::stringutils::trim(text).empty();
30 }
31 
32 /** Reindent nmodl text for text-to-text comparison
33  *
34  * Nmodl constructs defined in test database has extra leading whitespace.
35  * This is done for readability reason in nmodl_constructs.cpp. For example,
36  * we have following nmodl text with 8 leading whitespaces:
37 
38 
39  NEURON {
40  RANGE x
41  }
42 
43  * We convert above paragraph to:
44 
45 NEURON {
46  RANGE x
47 }
48 
49  * i.e. we get first non-empty line and count number of leading whitespaces (X).
50  * Then for every sub-sequent line, we remove first X characters (assuming those
51  * all are whitespaces). This is done because when ast is transformed back to
52  * nmodl, the nmodl output is without "extra" whitespaces in the provided input.
53  */
54 
55 std::string reindent_text(const std::string& text, int indent_level) {
56  std::string indented_text;
57  int num_whitespaces = 0;
58  bool flag = false;
59  std::string line;
60  std::stringstream stream(text);
61  std::string indent(4 * indent_level, ' ');
62 
63  while (std::getline(stream, line)) {
64  if (!line.empty()) {
65  /// count whitespaces for first non-empty line only
66  if (!flag) {
67  flag = true;
68  num_whitespaces = count_leading_spaces(line);
69  }
70 
71  /// make sure we don't remove non whitespaces characters
72  if (!is_empty(line.substr(0, num_whitespaces))) {
73  throw std::runtime_error("Test nmodl input not correctly formatted");
74  }
75 
76  line.erase(0, num_whitespaces);
77  indented_text += indent + line;
78  }
79  /// discard empty lines at very beginning
80  if (!stream.eof() && flag) {
81  indented_text += "\n";
82  }
83  }
84  return indented_text;
85 }
86 
88  : original_logger(nmodl::logger) {
89  capture_stream = std::make_shared<std::ostringstream>();
90  auto capture_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(*capture_stream);
91  auto test_logger = std::make_shared<spdlog::logger>("TEST_LOGGER", capture_sink);
92  test_logger->set_pattern("[%n] [%l] :: %v");
93  nmodl::logger = test_logger;
94 }
95 
98 }
99 
100 std::string LoggerCapture::output() const {
101  return capture_stream->str();
102 }
103 
104 
105 } // namespace test_utils
106 } // namespace nmodl
std::shared_ptr< std::ostringstream > capture_stream
Definition: test_utils.hpp:27
nmodl::logger_type original_logger
Definition: test_utils.hpp:28
static std::string ltrim(std::string text)
static std::string trim(std::string text)
#define assert(ex)
Definition: hocassrt.h:24
int count_leading_spaces(std::string text)
Definition: test_utils.cpp:19
bool is_empty(const std::string &text)
check if string has only whitespaces
Definition: test_utils.cpp:28
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
logger_type logger
Definition: logger.cpp:34
Implement logger based on spdlog library.
static int indent
Definition: noccout.cpp:360
#define text
Definition: plot.cpp:60
Implement string manipulation functions.