Skip to content

Commit

Permalink
Add more tests for the argument parsing. (#270)
Browse files Browse the repository at this point in the history
* Add more tests for the argument parsing.

Easy to add some simple tests of argparsing functionality.

* It's in algorithm, of course. Thanks ubuntu.

* Correct doxygen string.

* Fixes #272.

* Go for 100%.
  • Loading branch information
samcunliffe authored Apr 27, 2023
1 parent d8baa55 commit 16387f0
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 19 deletions.
174 changes: 174 additions & 0 deletions tdms/tests/unit/test_argument_parser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/**
* @file test_argument_parser.cpp
* @brief Tests of the argument parsing and file I/O.
*/
#include "argument_parser.h"

#include <algorithm>
#include <stdexcept>
#include <string>
#include <unistd.h>
#include <vector>

#include <catch2/catch_test_macros.hpp>

using std::string;
using std::vector;

/**
* @brief Test that the argument namespace recovers the input arguments
* provided.
*/
TEST_CASE("Test parsing help") {
const char *input_args[] = {"tdms", "-h"};
auto args = ArgumentNamespace(2, const_cast<char **>(input_args));
REQUIRE(args.have_flag("-h"));
}

/** Drop the first and last component of an std::vector (needs size > 2!!). */
template<typename T>
vector<T> drop_first_and_last(const vector<T> &v) {
return vector<T>(v.begin() + 1, v.end() - 1);
}

/** Convert a vector of std::strings to an array of chars */
const char **vector_to_array(const vector<string> &vec) {
const char **arr = new const char *[vec.size()] {};
std::transform(vec.begin(), vec.end(), arr,
[](const std::string &s) { return s.c_str(); });
return arr;
}
// TODO: check with Will that this doesn't shadow the implementation

/**
* @brief Test that the argument parser returns the correct filenames.
*/
TEST_CASE("Test parsing two filenames") {

const vector<string> input_args = {"tdms", "input_file.mat",
"output_file.mat"};
ArgumentParser ap;
auto args = ap.parse_args(input_args.size(),
const_cast<char **>(vector_to_array(input_args)));

SECTION("Inputs") {
vector<string> expected_filenames = drop_first_and_last(input_args);
vector<string> parsed_filenames = args.input_filenames();
REQUIRE(expected_filenames == parsed_filenames);
}
SECTION("Output") {
string parsed = args.output_filename();
string expected = input_args[input_args.size() - 1];
REQUIRE(expected == parsed);
}
SECTION("Grid") {
REQUIRE(!args.has_grid_filename());
REQUIRE_THROWS_AS(args.grid_filename(), std::runtime_error);
}
}

/**
* @brief Test that the argument parser returns the correct filenames.
*/
TEST_CASE("Test parsing three filenames") {
vector<string> input_args = {"tdms", "input_file.mat", "grid_file.mat",
"output_file.mat"};
ArgumentParser ap;
auto args = ap.parse_args(input_args.size(),
const_cast<char **>(vector_to_array(input_args)));

SECTION("Input") {
vector<string> expected_filenames = drop_first_and_last(input_args);
vector<string> parsed_filenames = args.input_filenames();
REQUIRE(expected_filenames == parsed_filenames);
}
SECTION("Output") {
string parsed = args.output_filename();
string expected = input_args[input_args.size() - 1];
REQUIRE(expected == parsed);
}
SECTION("Grid") {
string parsed = args.grid_filename();
string expected = input_args[input_args.size() - 2];
REQUIRE(args.has_grid_filename());
REQUIRE(expected == parsed);
}
}

/**
* @brief Test that the argument correctly errors with the wrong number of file
* names.
*/
TEST_CASE("Test wrong number of file names") {
SECTION("Zero") {
const char *input_args[] = {"tdms"};
auto args = ArgumentNamespace(1, const_cast<char **>(input_args));
REQUIRE(!args.have_correct_number_of_filenames());
REQUIRE_THROWS_AS(args.input_filename(), std::runtime_error);
REQUIRE_THROWS_AS(args.grid_filename(), std::runtime_error);
REQUIRE_THROWS_AS(args.output_filename(), std::runtime_error);
}
SECTION("One") {
const char *input_args[] = {"tdms", "input_file.mat"};
auto args = ArgumentNamespace(2, const_cast<char **>(input_args));
REQUIRE(!args.have_correct_number_of_filenames());
REQUIRE_THROWS_AS(args.grid_filename(), std::runtime_error);
REQUIRE_THROWS_AS(args.output_filename(), std::runtime_error);
}
SECTION("Four") {
const char *input_args[] = {"tdms", "input_file.mat", "grid_file.mat",
"output_file.mat", "fourth_file.mat"};
auto args = ArgumentNamespace(5, const_cast<char **>(input_args));
REQUIRE(!args.have_correct_number_of_filenames());
}
}

/**
* @brief Test of the CLI options.
*
* TODO: FD will need to be removed.
*/
TEST_CASE("CL options") {
vector<string> input_args = {"tdms", "input_file.mat", "output_file.mat"};
SECTION("Doesn't have flags") {
auto args =
ArgumentNamespace(input_args.size(),
const_cast<char **>(vector_to_array(input_args)));
REQUIRE(!args.finite_difference());
REQUIRE(!args.cubic_interpolation());
}

SECTION("Interpolation flag") {
input_args.push_back("--cubic-interpolation");
auto args =
ArgumentNamespace(input_args.size(),
const_cast<char **>(vector_to_array(input_args)));
REQUIRE(!args.finite_difference());
REQUIRE(args.cubic_interpolation());
}
SECTION("Solver method flag") {
input_args.push_back("--finite-difference");
auto args =
ArgumentNamespace(input_args.size(),
const_cast<char **>(vector_to_array(input_args)));
REQUIRE(args.finite_difference());
REQUIRE(!args.cubic_interpolation());
}
SECTION("Interpolation quick option") {
input_args.push_back("-c");
auto args =
ArgumentNamespace(input_args.size(),
const_cast<char **>(vector_to_array(input_args)));
REQUIRE(!args.finite_difference());
REQUIRE(args.cubic_interpolation());
}

SECTION("Solver method quick option") {
input_args.push_back("-fd");
auto args =
ArgumentNamespace(input_args.size(),
const_cast<char **>(vector_to_array(input_args)));
REQUIRE(args.finite_difference());
REQUIRE(!args.cubic_interpolation());
}
}
19 changes: 0 additions & 19 deletions tdms/tests/unit/test_openandorder.cpp

This file was deleted.

0 comments on commit 16387f0

Please sign in to comment.