diff --git a/.gitignore b/.gitignore index 511fa92..72790de 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ # Development stuff .direnv + +# Vim +*.swp diff --git a/README.rst b/README.rst index 0f126e9..4958a69 100644 --- a/README.rst +++ b/README.rst @@ -6,4 +6,39 @@ cpp-parselglossy :target: https://travis-ci.org/dev-cafe/cpp-parselglossy :alt: Linux build status -Example of using parselglossy with a C++ project +This repo contains a simple example of how to use ``parselglossy`` in a C++ +project using two different CMake setups: externalproject and fetchcontent. +The code example is identical in the two setups. + +To install ``parselglossy`` through pipenv using the provided Pipfile: + +.. code:: bash + + $ cd cpp-parselglossy + $ pipenv install + $ pipenv shell + +To configure and build the ``fetchcontent`` example (identical for ``externalproject``): + +.. code:: bash + + $ cd fetchcontent + $ mkdir build + $ cmake -H. -Bbuild + $ cd build + $ make + +To run the test suite: + +.. code:: bash + + $ cd build + $ ctest + +To run example: + +.. code:: bash + + $ cd examples + $ parselglossy parse --outfile=throw_darts.json --template=../build/share/template.yml --grammar=getkw throw_darts.inp + $ ../build/bin/pi throw_darts.json diff --git a/fetchcontent/CMakeLists.txt b/fetchcontent/CMakeLists.txt index b381a33..2d6b44a 100644 --- a/fetchcontent/CMakeLists.txt +++ b/fetchcontent/CMakeLists.txt @@ -8,4 +8,40 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) include(${PROJECT_SOURCE_DIR}/external/upstream/fetch_nlohmann_json.cmake) +message(STATUS "Project will be installed to ${CMAKE_INSTALL_PREFIX}") + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) +endif() + +message(STATUS "Build type set to ${CMAKE_BUILD_TYPE}") + +include(GNUInstallDirs) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) + +# Offer the user the choice of overriding the installation directories +set(INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries") +set(INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for executables") +set(INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for header files") +if(WIN32 AND NOT CYGWIN) + set(DEF_INSTALL_CMAKEDIR CMake) +else() + set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME}) +endif() +set(INSTALL_CMAKEDIR ${DEF_INSTALL_CMAKEDIR} CACHE PATH "Installation directory for CMake files") + +# Report to user +foreach(p LIB BIN INCLUDE CMAKE) + file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}DIR} _path ) + message(STATUS "Installing ${p} components to ${_path}") + unset(_path) +endforeach() + add_subdirectory(src) + +enable_testing() +include(CTest) +add_subdirectory(tests) diff --git a/fetchcontent/examples/integration.inp b/fetchcontent/examples/integration.inp new file mode 100644 index 0000000..682a735 --- /dev/null +++ b/fetchcontent/examples/integration.inp @@ -0,0 +1,7 @@ +title = "This program computes Pi" +method = integration + +Integration { + n_steps = 10**4 +} + diff --git a/fetchcontent/examples/throw_darts.inp b/fetchcontent/examples/throw_darts.inp new file mode 100644 index 0000000..cc32d3c --- /dev/null +++ b/fetchcontent/examples/throw_darts.inp @@ -0,0 +1,8 @@ +title = "This program computes Pi" +method = darts + +Darts { + n_darts = 10**4 + random_seed = 1 +} + diff --git a/fetchcontent/external/upstream/CMakeLists.txt b/fetchcontent/external/upstream/CMakeLists.txt deleted file mode 100644 index 57721a1..0000000 --- a/fetchcontent/external/upstream/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(nlohmann_json) diff --git a/fetchcontent/external/upstream/fetch_nlohmann_json.cmake b/fetchcontent/external/upstream/fetch_nlohmann_json.cmake index 527f0a6..fd7434a 100644 --- a/fetchcontent/external/upstream/fetch_nlohmann_json.cmake +++ b/fetchcontent/external/upstream/fetch_nlohmann_json.cmake @@ -1,6 +1,6 @@ find_package(nlohmann_json 3.5.0 CONFIG QUIET) -if(TARGET nlohmann_json::nlhomann_json) +if(TARGET nlohmann_json::nlohmann_json) get_target_property( _loc nlohmann_json::nlohmann_json diff --git a/fetchcontent/external/upstream/nlohmann_json/CMakeLists.txt b/fetchcontent/external/upstream/nlohmann_json/CMakeLists.txt deleted file mode 100644 index fd33509..0000000 --- a/fetchcontent/external/upstream/nlohmann_json/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -find_package(nlohmann_json 2.2.3 CONFIG QUIET) - -if(nlohmann_json_FOUND) - message(STATUS "Found nlohmann_json: ${nlohmann_json_INCLUDE_DIR} (found version ${nlohmann_json_VERSION})") - add_library(nlohmann_json_external INTERFACE) # dummy -else() - include(ExternalProject) - message(STATUS "Suitable nlohmann_json could not be located: downloading and building nlohmann_json instead.") - ExternalProject_Add(nlohmann_json_external - GIT_REPOSITORY https://github.com/nlohmann/json - GIT_TAG v3.5.0 - UPDATE_COMMAND "" - CMAKE_ARGS - -DCMAKE_INSTALL_PREFIX=${STAGED_INSTALL_PREFIX} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} - -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} - -DJSON_BuildTests=OFF - LOG_DOWNLOAD 1 - LOG_UPDATE 1 - LOG_CONFIGURE 1 - LOG_BUILD 1 - LOG_INSTALL 1 - ) - set(nlohmann_json_DIR ${STAGED_INSTALL_PREFIX}/lib/cmake/nlohmann_json CACHE PATH "Path to internally built nlohmann_jsonConfig.cmake" FORCE) -endif() diff --git a/fetchcontent/src/CMakeLists.txt b/fetchcontent/src/CMakeLists.txt index 710a43a..e961285 100644 --- a/fetchcontent/src/CMakeLists.txt +++ b/fetchcontent/src/CMakeLists.txt @@ -1,6 +1,48 @@ -add_executable(example example.cpp) +add_executable(pi pi.cpp) -target_link_libraries(example +target_link_libraries(pi PRIVATE nlohmann_json::nlohmann_json ) + +# RPATH fixing +file(RELATIVE_PATH _rel ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR} ${CMAKE_INSTALL_PREFIX}) +if(APPLE) + set(_rpath "@loader_path/${_rel}") +else() + set(_rpath "\$ORIGIN/${_rel}") +endif() +file(TO_NATIVE_PATH "${_rpath}/${CMAKE_INSTALL_LIBDIR}" Pi_RPATH) + +set_target_properties(pi + PROPERTIES + MACOSX_RPATH ON + SKIP_BUILD_RPATH OFF + BUILD_WITH_INSTALL_RPATH OFF + INSTALL_RPATH "${Pi_RPATH}" + INSTALL_RPATH_USE_LINK_PATH ON + ) + +install( + TARGETS + pi + RUNTIME + DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT bin + ) + + +file( + COPY + template.yml + DESTINATION + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR} + ) + +install( + FILES + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/template.yml + DESTINATION + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR} + ) + diff --git a/fetchcontent/src/pi.cpp b/fetchcontent/src/pi.cpp new file mode 100644 index 0000000..1d04673 --- /dev/null +++ b/fetchcontent/src/pi.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include + +#include "nlohmann/json.hpp" + +using json = nlohmann::json; + +int fetch_input(int argc, char **argv, json &input); +void integration(const json &input, json &output); +void throw_darts(const json &input, json &output); + +int main(int argc, char **argv) { + // Read JSON input + json inp_json; + if (fetch_input(argc, argv, inp_json)) return EXIT_FAILURE; + + // Prepare JSON output + json out_json; + out_json["title"] = inp_json["title"]; + + // Fetch computation method from input + auto method = inp_json["method"].get(); + if (method == "integration") { + const auto &int_json = inp_json["Integration"].get(); + integration(int_json, out_json); + } + if (method == "darts") { + const auto &dart_json = inp_json["Darts"].get(); + throw_darts(dart_json, out_json); + } + + // Dump JSON input + std::cout << "\n-------------- JSON input -----------------\n"; + std::cout << inp_json.dump(2) << std::endl; + std::cout << "-------------------------------------------\n"; + + // Dump JSON output + std::cout << "\n-------------- JSON output ----------------\n"; + std::cout << out_json.dump(2) << std::endl; + std::cout << "-------------------------------------------\n\n"; + + return EXIT_SUCCESS; +} + +int fetch_input(int argc, char **argv, json &input) { + if (argc != 2) { + std::cout << "Wrong number of arguments!" << std::endl; + return 1; + } + + std::ifstream ifs(argv[1], std::ios_base::in); + if (ifs.fail()) { + std::cout << "Failed to open file!" << std::endl; + return 1; + } + + ifs >> input; + ifs.close(); + + return 0; +} + +void integration(const json &input, json &output) { + auto n_steps = input["n_steps"].get(); + auto step = 1.0 / n_steps; + + auto sum = 0.0; + for (auto i = 0; i < n_steps; i++) { + auto x = (i + 0.5) * step; + auto f_x = 1.0 / (1.0 + x * x); + sum += step * f_x; + } + + output["method"] = "Numerical integration"; + output["pi"] = 4.0 * sum; +} + +void throw_darts(const json &input, json &output) { + auto n_darts = input["n_darts"].get(); + auto seed = input["random_seed"].get(); + + // Seed the random number generator + std::mt19937 rand_en(seed); + std::uniform_real_distribution<> uniform_dist(0.0, 1.0); + + auto n_hits = 0; + for (auto i = 0; i < n_darts; i++) { + //creates 2 random numbers between 0 and 1 + auto x = uniform_dist(rand_en); + auto y = uniform_dist(rand_en); + auto r = std::sqrt(x*x + y*y); + + //counts how often the dart hits the circle + if (r <= 1.0) n_hits++; + } + + output["method"] = "Throwing darts"; + output["pi"] = 4.0 * n_hits / n_darts; +} + diff --git a/fetchcontent/src/template.yml b/fetchcontent/src/template.yml new file mode 100644 index 0000000..88a6adf --- /dev/null +++ b/fetchcontent/src/template.yml @@ -0,0 +1,44 @@ +keywords: + - name: title + type: str + docstring: | + Please provide a title of the calculation to display in the beginning. + - name: method + type: str + predicates: + - "value == 'integration' or value == 'darts'" + docstring: | + Choose which method to use, numerical integration or throwing darts. +sections: + - name: Integration + docstring: | + Section giving details on the numerical integration method. + keywords: + - name: n_steps + type: int + default: 1000 + predicates: + - 'value > 0' + - 'value < 1000000' + docstring: | + Number of intervals in the numerical integration. Larger number means higher accuracy. + - name: Darts + docstring: | + Section giving details on the dart throwing method. + keywords: + - name: n_darts + type: int + default: 1000 + predicates: + - 'value > 0' + - 'value < 1000000' + docstring: | + Number of darts to throw. Larger number means higher accuracy. + - name: random_seed + type: int + default: 0 + predicates: + - 'value >= 0' + - 'value < 2**32' + docstring: | + Number used as seed in the pseudo-random number generator. diff --git a/fetchcontent/tests/CMakeLists.txt b/fetchcontent/tests/CMakeLists.txt new file mode 100644 index 0000000..5456071 --- /dev/null +++ b/fetchcontent/tests/CMakeLists.txt @@ -0,0 +1,5 @@ +# Integration tests +add_subdirectory(darts) +add_subdirectory(darts_default) +add_subdirectory(integration) +add_subdirectory(integration_default) diff --git a/fetchcontent/tests/darts/CMakeLists.txt b/fetchcontent/tests/darts/CMakeLists.txt new file mode 100644 index 0000000..43da875 --- /dev/null +++ b/fetchcontent/tests/darts/CMakeLists.txt @@ -0,0 +1,25 @@ +execute_process( + COMMAND + cmake -E create_symlink + "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/template.yml" # Old name + "${CMAKE_CURRENT_BINARY_DIR}/template.yml" # New name + ) + +file( + COPY + pi.inp + DESTINATION + ${CMAKE_CURRENT_BINARY_DIR} + ) + +add_test( + NAME + darts + COMMAND + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/test + --binary=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} + --work-dir=${CMAKE_CURRENT_BINARY_DIR} + --verbose + WORKING_DIRECTORY + ${CMAKE_CURRENT_BINARY_DIR} + ) diff --git a/fetchcontent/tests/darts/pi.inp b/fetchcontent/tests/darts/pi.inp new file mode 100644 index 0000000..588f29c --- /dev/null +++ b/fetchcontent/tests/darts/pi.inp @@ -0,0 +1,8 @@ +title = "This program computes Pi" +method = darts + +Darts { + n_darts = 100000 + random_seed = 225512 +} + diff --git a/fetchcontent/tests/darts/reference/pi.stdout b/fetchcontent/tests/darts/reference/pi.stdout new file mode 100644 index 0000000..88d68a3 --- /dev/null +++ b/fetchcontent/tests/darts/reference/pi.stdout @@ -0,0 +1,23 @@ + +-------------- JSON input ----------------- +{ + "Darts": { + "n_darts": 100000, + "random_seed": 225512 + }, + "Integration": { + "n_steps": 1000 + }, + "method": "darts", + "title": "This program computes Pi" +} +------------------------------------------- + +-------------- JSON output ---------------- +{ + "method": "Throwing darts", + "pi": 3.14152, + "title": "This program computes Pi" +} +------------------------------------------- + diff --git a/fetchcontent/tests/darts/test b/fetchcontent/tests/darts/test new file mode 100755 index 0000000..c59fbbb --- /dev/null +++ b/fetchcontent/tests/darts/test @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +import os +import sys +import subprocess + +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) + +from runtest import cli, get_filter, run, version_info # isort:skip +from runtest_config import configure # isort:skip + +assert version_info.major == 2 + +in_file = 'pi.inp' +fr_file = 'pi.json' +tp_file = 'template.yml' +grammar = 'getkw' + +# Running parselglossy CLI: pi.inp -> pi.json +parsel_command = [] +parsel_command.append('parselglossy') +parsel_command.append('parse') +parsel_command.append('--outfile=' + fr_file) +parsel_command.append('--template=' + tp_file) +parsel_command.append('--grammar=' + grammar) +parsel_command.append(in_file) +subprocess.call(parsel_command) + +f = [ + get_filter(string='pi', rel_tolerance=1.0e-6), +] + +options = cli() + +ierr = 0 +ierr += run(options, configure, input_files=fr_file, filters={'stdout': f}) + +sys.exit(ierr) diff --git a/fetchcontent/tests/darts_default/CMakeLists.txt b/fetchcontent/tests/darts_default/CMakeLists.txt new file mode 100644 index 0000000..8babec4 --- /dev/null +++ b/fetchcontent/tests/darts_default/CMakeLists.txt @@ -0,0 +1,25 @@ +execute_process( + COMMAND + cmake -E create_symlink + "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/template.yml" # Old name + "${CMAKE_CURRENT_BINARY_DIR}/template.yml" # New name + ) + +file( + COPY + pi.inp + DESTINATION + ${CMAKE_CURRENT_BINARY_DIR} + ) + +add_test( + NAME + darts-default + COMMAND + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/test + --binary=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} + --work-dir=${CMAKE_CURRENT_BINARY_DIR} + --verbose + WORKING_DIRECTORY + ${CMAKE_CURRENT_BINARY_DIR} + ) diff --git a/fetchcontent/tests/darts_default/pi.inp b/fetchcontent/tests/darts_default/pi.inp new file mode 100644 index 0000000..5b53b57 --- /dev/null +++ b/fetchcontent/tests/darts_default/pi.inp @@ -0,0 +1,2 @@ +title = "This program computes Pi" +method = darts diff --git a/fetchcontent/tests/darts_default/reference/pi.stdout b/fetchcontent/tests/darts_default/reference/pi.stdout new file mode 100644 index 0000000..2844a57 --- /dev/null +++ b/fetchcontent/tests/darts_default/reference/pi.stdout @@ -0,0 +1,23 @@ + +-------------- JSON input ----------------- +{ + "Darts": { + "n_darts": 1000, + "random_seed": 0 + }, + "Integration": { + "n_steps": 1000 + }, + "method": "darts", + "title": "This program computes Pi" +} +------------------------------------------- + +-------------- JSON output ---------------- +{ + "method": "Throwing darts", + "pi": 3.088, + "title": "This program computes Pi" +} +------------------------------------------- + diff --git a/fetchcontent/tests/darts_default/test b/fetchcontent/tests/darts_default/test new file mode 100755 index 0000000..c59fbbb --- /dev/null +++ b/fetchcontent/tests/darts_default/test @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +import os +import sys +import subprocess + +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) + +from runtest import cli, get_filter, run, version_info # isort:skip +from runtest_config import configure # isort:skip + +assert version_info.major == 2 + +in_file = 'pi.inp' +fr_file = 'pi.json' +tp_file = 'template.yml' +grammar = 'getkw' + +# Running parselglossy CLI: pi.inp -> pi.json +parsel_command = [] +parsel_command.append('parselglossy') +parsel_command.append('parse') +parsel_command.append('--outfile=' + fr_file) +parsel_command.append('--template=' + tp_file) +parsel_command.append('--grammar=' + grammar) +parsel_command.append(in_file) +subprocess.call(parsel_command) + +f = [ + get_filter(string='pi', rel_tolerance=1.0e-6), +] + +options = cli() + +ierr = 0 +ierr += run(options, configure, input_files=fr_file, filters={'stdout': f}) + +sys.exit(ierr) diff --git a/fetchcontent/tests/integration/CMakeLists.txt b/fetchcontent/tests/integration/CMakeLists.txt new file mode 100644 index 0000000..10b46b5 --- /dev/null +++ b/fetchcontent/tests/integration/CMakeLists.txt @@ -0,0 +1,25 @@ +execute_process( + COMMAND + cmake -E create_symlink + "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/template.yml" # Old name + "${CMAKE_CURRENT_BINARY_DIR}/template.yml" # New name + ) + +file( + COPY + pi.inp + DESTINATION + ${CMAKE_CURRENT_BINARY_DIR} + ) + +add_test( + NAME + integration + COMMAND + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/test + --binary=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} + --work-dir=${CMAKE_CURRENT_BINARY_DIR} + --verbose + WORKING_DIRECTORY + ${CMAKE_CURRENT_BINARY_DIR} + ) diff --git a/fetchcontent/tests/integration/pi.inp b/fetchcontent/tests/integration/pi.inp new file mode 100644 index 0000000..ff66720 --- /dev/null +++ b/fetchcontent/tests/integration/pi.inp @@ -0,0 +1,7 @@ +title = "This program computes Pi" +method = integration + +Integration { + n_steps = 113623 +} + diff --git a/fetchcontent/tests/integration/reference/pi.stdout b/fetchcontent/tests/integration/reference/pi.stdout new file mode 100644 index 0000000..5653f54 --- /dev/null +++ b/fetchcontent/tests/integration/reference/pi.stdout @@ -0,0 +1,23 @@ + +-------------- JSON input ----------------- +{ + "Darts": { + "n_darts": 1000, + "random_seed": 0 + }, + "Integration": { + "n_steps": 113623 + }, + "method": "integration", + "title": "This program computes Pi" +} +------------------------------------------- + +-------------- JSON output ---------------- +{ + "method": "Numerical integration", + "pi": 3.141592653596236, + "title": "This program computes Pi" +} +------------------------------------------- + diff --git a/fetchcontent/tests/integration/test b/fetchcontent/tests/integration/test new file mode 100755 index 0000000..c59fbbb --- /dev/null +++ b/fetchcontent/tests/integration/test @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +import os +import sys +import subprocess + +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) + +from runtest import cli, get_filter, run, version_info # isort:skip +from runtest_config import configure # isort:skip + +assert version_info.major == 2 + +in_file = 'pi.inp' +fr_file = 'pi.json' +tp_file = 'template.yml' +grammar = 'getkw' + +# Running parselglossy CLI: pi.inp -> pi.json +parsel_command = [] +parsel_command.append('parselglossy') +parsel_command.append('parse') +parsel_command.append('--outfile=' + fr_file) +parsel_command.append('--template=' + tp_file) +parsel_command.append('--grammar=' + grammar) +parsel_command.append(in_file) +subprocess.call(parsel_command) + +f = [ + get_filter(string='pi', rel_tolerance=1.0e-6), +] + +options = cli() + +ierr = 0 +ierr += run(options, configure, input_files=fr_file, filters={'stdout': f}) + +sys.exit(ierr) diff --git a/fetchcontent/tests/integration_default/CMakeLists.txt b/fetchcontent/tests/integration_default/CMakeLists.txt new file mode 100644 index 0000000..b28d5f6 --- /dev/null +++ b/fetchcontent/tests/integration_default/CMakeLists.txt @@ -0,0 +1,25 @@ +execute_process( + COMMAND + cmake -E create_symlink + "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/template.yml" # Old name + "${CMAKE_CURRENT_BINARY_DIR}/template.yml" # New name + ) + +file( + COPY + pi.inp + DESTINATION + ${CMAKE_CURRENT_BINARY_DIR} + ) + +add_test( + NAME + integration-default + COMMAND + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/test + --binary=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} + --work-dir=${CMAKE_CURRENT_BINARY_DIR} + --verbose + WORKING_DIRECTORY + ${CMAKE_CURRENT_BINARY_DIR} + ) diff --git a/fetchcontent/tests/integration_default/pi.inp b/fetchcontent/tests/integration_default/pi.inp new file mode 100644 index 0000000..8df3428 --- /dev/null +++ b/fetchcontent/tests/integration_default/pi.inp @@ -0,0 +1,2 @@ +title = "This program computes Pi" +method = integration diff --git a/fetchcontent/tests/integration_default/reference/pi.stdout b/fetchcontent/tests/integration_default/reference/pi.stdout new file mode 100644 index 0000000..def6eee --- /dev/null +++ b/fetchcontent/tests/integration_default/reference/pi.stdout @@ -0,0 +1,23 @@ + +-------------- JSON input ----------------- +{ + "Darts": { + "n_darts": 1000, + "random_seed": 0 + }, + "Integration": { + "n_steps": 1000 + }, + "method": "integration", + "title": "This program computes Pi" +} +------------------------------------------- + +-------------- JSON output ---------------- +{ + "method": "Numerical integration", + "pi": 3.1415927369231307, + "title": "This program computes Pi" +} +------------------------------------------- + diff --git a/fetchcontent/tests/integration_default/test b/fetchcontent/tests/integration_default/test new file mode 100755 index 0000000..c59fbbb --- /dev/null +++ b/fetchcontent/tests/integration_default/test @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +import os +import sys +import subprocess + +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) + +from runtest import cli, get_filter, run, version_info # isort:skip +from runtest_config import configure # isort:skip + +assert version_info.major == 2 + +in_file = 'pi.inp' +fr_file = 'pi.json' +tp_file = 'template.yml' +grammar = 'getkw' + +# Running parselglossy CLI: pi.inp -> pi.json +parsel_command = [] +parsel_command.append('parselglossy') +parsel_command.append('parse') +parsel_command.append('--outfile=' + fr_file) +parsel_command.append('--template=' + tp_file) +parsel_command.append('--grammar=' + grammar) +parsel_command.append(in_file) +subprocess.call(parsel_command) + +f = [ + get_filter(string='pi', rel_tolerance=1.0e-6), +] + +options = cli() + +ierr = 0 +ierr += run(options, configure, input_files=fr_file, filters={'stdout': f}) + +sys.exit(ierr) diff --git a/fetchcontent/tests/runtest_config.py b/fetchcontent/tests/runtest_config.py new file mode 100644 index 0000000..4c779aa --- /dev/null +++ b/fetchcontent/tests/runtest_config.py @@ -0,0 +1,25 @@ +from os import path +from sys import platform + +def configure(options, input_files, extra_args): + """ + This function configures runtest + at runtime for code specific launch command and file naming. + """ + + # Running C++ executable + launcher = 'pi' + launcher_full_path = path.normpath(path.join(options.binary_dir, launcher)) + + command = [] + command.append(launcher_full_path) + command.append(input_files) + + if extra_args is not None: + command.append(extra_args) + + full_command = ' '.join(command) + output_prefix = path.splitext(input_files)[0] + relative_reference_path = 'reference' + + return launcher, full_command, output_prefix, relative_reference_path