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
|
/*************************************************************************
* Copyright (C) 2018-2022 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 "test_utils.hpp"
#include "utils/logger.hpp"
#include "utils/string_utils.hpp"
#include <cassert>
#include <filesystem>
#include <fstream>
namespace fs = std::filesystem;
namespace nmodl {
namespace test_utils {
int count_leading_spaces(std::string text) {
auto const length = text.size();
nmodl::stringutils::ltrim(text);
auto const num_whitespaces = length - text.size();
assert(num_whitespaces <= std::numeric_limits<int>::max());
return static_cast<int>(num_whitespaces);
}
/// check if string has only whitespaces
bool is_empty(std::string text) {
nmodl::stringutils::trim(text);
return text.empty();
}
/** Reindent nmodl text for text-to-text comparison
*
* Nmodl constructs defined in test database has extra leading whitespace.
* This is done for readability reason in nmodl_constructs.cpp. For example,
* we have following nmodl text with 8 leading whitespaces:
NEURON {
RANGE x
}
* We convert above paragraph to:
NEURON {
RANGE x
}
* i.e. we get first non-empty line and count number of leading whitespaces (X).
* Then for every sub-sequent line, we remove first X characters (assuming those
* all are whitespaces). This is done because when ast is transformed back to
* nmodl, the nmodl output is without "extra" whitespaces in the provided input.
*/
std::string reindent_text(const std::string& text) {
std::string indented_text;
int num_whitespaces = 0;
bool flag = false;
std::string line;
std::stringstream stream(text);
while (std::getline(stream, line)) {
if (!line.empty()) {
/// count whitespaces for first non-empty line only
if (!flag) {
flag = true;
num_whitespaces = count_leading_spaces(line);
}
/// make sure we don't remove non whitespaces characters
if (!is_empty(line.substr(0, num_whitespaces))) {
throw std::runtime_error("Test nmodl input not correctly formatted");
}
line.erase(0, num_whitespaces);
indented_text += line;
}
/// discard empty lines at very beginning
if (!stream.eof() && flag) {
indented_text += "\n";
}
}
return indented_text;
}
TempFile::TempFile(fs::path path, const std::string& content)
: path_(std::move(path)) {
std::ofstream output(path_);
output << content;
}
TempFile::~TempFile() {
try {
fs::remove(path_);
} catch (...) {
// TODO: remove .string() once spdlog use fmt 9.1.0
logger->error("Cannot delete temporary file {}", path_.string());
}
}
} // namespace test_utils
} // namespace nmodl
|