file to header preprocessor for unit tests

This commit is contained in:
Daniel Sipka 2015-04-10 09:52:50 +02:00
parent eb98985815
commit bd4eb1349a
8 changed files with 136 additions and 31 deletions

View File

@ -1,13 +1,41 @@
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(mstch) project(mstch)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
find_package(Boost 1.54 REQUIRED) find_package(Boost 1.54 COMPONENTS program_options REQUIRED)
include_directories(src include vendor/include ${Boost_INCLUDE_DIR}) include_directories(${CMAKE_BINARY_DIR} src include vendor/include ${Boost_INCLUDE_DIR})
set(SRC set(SRC
src/mstch.cpp src/mstch.cpp
test/main.cpp) src/utils.cpp
src/token.cpp
src/render_context.cpp
src/state/in_section.cpp
src/state/in_inverted_section.cpp
src/state/outside_section.cpp
src/visitor/is_node_empty.cpp
src/visitor/render_node.cpp
src/visitor/render_section.cpp
src/visitor/to_json.cpp)
add_executable(mstch ${SRC} include/types.h src/utils.h src/utils.cpp src/token.cpp src/token.h src/render_context.cpp src/render_context.h src/state/render_state.h src/state/in_section.cpp src/state/in_section.h src/state/in_inverted_section.cpp src/state/in_inverted_section.h src/state/outside_section.cpp src/state/outside_section.h src/visitor/is_node_empty.cpp src/visitor/is_node_empty.h src/visitor/render_node.cpp src/visitor/render_node.h src/visitor/render_section.cpp src/visitor/render_section.h src/visitor/to_json.cpp src/visitor/to_json.h) add_library(mstch STATIC ${SRC})
add_executable(mstch_test test/main.cpp)
target_link_libraries(mstch_test mstch)
add_executable(filetoheader test/filetoheader.cpp)
target_link_libraries(filetoheader ${Boost_PROGRAM_OPTIONS_LIBRARY})
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/test_data.h
COMMAND ${CMAKE_BINARY_DIR}/filetoheader --output ${CMAKE_BINARY_DIR}/test_data.h --namespace mstchtest
-Dampersand_escape.h -Sampersand_escape.mustache -Sampersand_escape.txt
-Dapostrophe.h -Sapostrophe.mustache -Sapostrophe.txt
-Darray_of_strings.h -Sarray_of_strings.mustache -Sarray_of_strings.txt
-Dbackslashes.h -Sbackslashes.mustache -Sbackslashes.txt
DEPENDS ${CMAKE_BINARY_DIR}/filetoheader
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/test/data/)
set_source_files_properties(${CMAKE_BINARY_DIR}/test_data.h PROPERTIES GENERATED TRUE)
add_custom_target(test_data_h DEPENDS ${CMAKE_BINARY_DIR}/test_data.h)
add_dependencies(mstch test_data_h)

View File

@ -9,30 +9,30 @@ using namespace mstch;
const mstch::node render_context::null_node; const mstch::node render_context::null_node;
render_context::render_context(const mstch::object &object, const std::map<std::string,std::string>& partials): render_context::render_context(const mstch::object &object, const std::map<std::string,std::string>& partials):
objects{object},
partials(partials), partials(partials),
objects{object},
state(new state::outside_section) state(new state::outside_section)
{ {
} }
render_context::render_context(const mstch::object& object, const render_context& context): render_context::render_context(const mstch::object& object, const render_context& context):
objects(context.objects),
partials(context.partials), partials(context.partials),
objects(context.objects),
state(new state::outside_section) state(new state::outside_section)
{ {
objects.push_front(object); objects.push_front(object);
} }
const mstch::node& render_context::find_node(const std::string &token, const std::deque<object> &current_objects) { const mstch::node& render_context::find_node(const std::string &token, const std::deque<object> &current_objects) {
/*if(token != "." && token.find('.') != std::string::npos) { if(token != "." && token.find('.') != std::string::npos) {
return find_node(token.substr(token.rfind('.') + 1), return find_node(token.substr(token.rfind('.') + 1),
{boost::get<object>(find_node(token.substr(0, token.rfind('.')), current_objects))}); {boost::get<object>(find_node(token.substr(0, token.rfind('.')), current_objects))});
} else {*/ } else {
for (auto& object: current_objects) for (auto& object: current_objects)
if (object.count(token) != 0) if (object.count(token) != 0)
return object.at(token); return object.at(token);
return null_node; return null_node;
//} }
} }
const mstch::node& render_context::get_node(const std::string& token) { const mstch::node& render_context::get_node(const std::string& token) {

View File

@ -1,3 +1,3 @@
auto data = mstch::object{ mstch::object{
{"message", std::string{"Some <code>"}} {"message", std::string{"Some <code>"}}
}; }

View File

@ -1,4 +1,4 @@
auto data = mstch::object{ mstch::object{
{"apos", std::string{"'"}}, {"apos", std::string{"'"}},
{"control", std::string{"X"}} {"control", std::string{"X"}}
}; }

View File

@ -1,3 +1,3 @@
auto data = mstch::object{ mstch::object{
{"array_of_strings", mstch::array{std::string{"hello"}, std::string{"world"}}} {"array_of_strings", mstch::array{std::string{"hello"}, std::string{"world"}}}
}; }

View File

@ -1,3 +1,3 @@
auto data = mstch::object{ mstch::object{
{"value", std::string{"\\abc"}} {"value", std::string{"\\abc"}}
}; }

79
test/filetoheader.cpp Normal file
View File

@ -0,0 +1,79 @@
#include <iostream>
#include <fstream>
#include <boost/algorithm/string/replace.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
void wrap_data(std::istream& input, std::ostream& output, const std::string& variable_name) {
output << "const auto " << variable_name << " = ";
std::string line;
while (std::getline(input, line)) {
output << line;
if(!input.eof()) output << std::endl;
}
output << ";" << std::endl;
}
void wrap_string(std::istream& input, std::ostream& output, const std::string& variable_name) {
output << "const std::string " << variable_name << "{" << std::endl;;
std::string line;
while (std::getline(input, line)) {
boost::replace_all(line, "\\", "\\\\");
boost::replace_all(line, "\"", "\\\"");
output << " \"" << line << "\\n\"";
if(!input.eof()) output << std::endl;
}
output << "};" << std::endl;
}
int main(int argc, char* argv[]) {
namespace po = boost::program_options;
po::options_description desc("Allowed options");
desc.add_options()
("help", "show help")
("output", po::value<std::string>(), "output file")
("namespace", po::value<std::string>(), "namespace to use")
("input-string,S", po::value<std::vector<std::string>>(), "files to parse as strings")
("input-data,D", po::value<std::vector<std::string>>(), "files to parse as data");
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help")) {
std::cout << desc << std::endl;
return 1;
}
if (!vm.count("output")) {
std::cout << "Output file not set" << std::endl;
return 1;
}
std::ofstream output(vm["output"].as<std::string>(), std::ios::out);
if(vm.count("namespace"))
output << "namespace " << vm["namespace"].as<std::string>() << " {" << std::endl;
for(auto& string_filename: vm["input-string"].as<std::vector<std::string>>()) {
std::ifstream input(string_filename, std::ios::in);
wrap_string(input, output, boost::replace_all_copy(string_filename, ".", "_"));
input.close();
}
for(auto& data_filename: vm["input-data"].as<std::vector<std::string>>()) {
std::ifstream input(data_filename, std::ios::in);
wrap_data(input, output, boost::replace_all_copy(data_filename, ".", "_"));
input.close();
}
if(vm.count("namespace"))
output << "}" << std::endl;
output.close();
return 0;
}

View File

@ -3,16 +3,14 @@
#include <mstch.h> #include <mstch.h>
#include <string> #include "test_data.h"
#include <fstream>
#include <streambuf>
std::string file_to_string(const std::string& filename) { #define MSTCH_TEST(x,y) TEST_CASE(x) { REQUIRE(y ## _txt == mstch::render(y ## _mustache, y ## _h)); }
std::ifstream t(filename);
std::string str((std::istreambuf_iterator<char>(t)), MSTCH_TEST("Ampersand escape", mstchtest::ampersand_escape)
std::istreambuf_iterator<char>()); MSTCH_TEST("Apostrophe", mstchtest::apostrophe)
return str; MSTCH_TEST("Array of strings", mstchtest::array_of_strings)
} MSTCH_TEST("Backslashes", mstchtest::backslashes)
/*TEST_CASE("Ampersand escape") { /*TEST_CASE("Ampersand escape") {
#include "data/ampersand_escape.h" #include "data/ampersand_escape.h"
@ -119,12 +117,12 @@ TEST_CASE("Falsy") {
REQUIRE(exp == mstch::render(tpl, data)); REQUIRE(exp == mstch::render(tpl, data));
}*/ }*/
TEST_CASE("Falsy array") { /*TEST_CASE("Falsy array") {
#include "data/falsy_array.h" #include "data/falsy_array.h"
auto tpl = file_to_string("data/falsy_array.mustache"); auto tpl = file_to_string("data/falsy_array.mustache");
auto exp = file_to_string("data/falsy_array.txt"); auto exp = file_to_string("data/falsy_array.txt");
REQUIRE(exp == mstch::render(tpl, data)); REQUIRE(exp == mstch::render(tpl, data));
} }*/
/*TEST_CASE("Grandparent context") { /*TEST_CASE("Grandparent context") {
#include "data/grandparent_context.h" #include "data/grandparent_context.h"