Add tests for FileVerifier, DirectoryVerifier, and DateTimeVerifier (closes #1563)

This commit is contained in:
Alexander Bock
2023-01-21 22:14:09 +01:00
parent c488231e65
commit 45b1b9e7e7
4 changed files with 183 additions and 58 deletions

View File

@@ -174,6 +174,8 @@ private:
* refers to an existing file on disk.
*/
struct FileVerifier : public StringVerifier {
FileVerifier();
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;
@@ -185,6 +187,8 @@ struct FileVerifier : public StringVerifier {
* refers to an existing directory on disk.
*/
struct DirectoryVerifier : public StringVerifier {
DirectoryVerifier();
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;
@@ -196,6 +200,8 @@ struct DirectoryVerifier : public StringVerifier {
* a valid date time
*/
struct DateTimeVerifier : public StringVerifier {
DateTimeVerifier();
TestResult operator()(const ghoul::Dictionary& dict,
const std::string& key) const override;

View File

@@ -231,6 +231,8 @@ std::string StringVerifier::type() const {
return "String";
}
FileVerifier::FileVerifier() : StringVerifier(true) {}
TestResult FileVerifier::operator()(const ghoul::Dictionary& dict,
const std::string& key) const
{
@@ -255,6 +257,8 @@ std::string FileVerifier::type() const {
return "File";
}
DirectoryVerifier::DirectoryVerifier() : StringVerifier(true) {}
TestResult DirectoryVerifier::operator()(const ghoul::Dictionary& dict,
const std::string& key) const
{
@@ -279,6 +283,8 @@ std::string DirectoryVerifier::type() const {
return "Directory";
}
DateTimeVerifier::DateTimeVerifier() : StringVerifier(true) {}
TestResult DateTimeVerifier::operator()(const ghoul::Dictionary& dict,
const std::string& key) const
{
@@ -303,26 +309,6 @@ TestResult DateTimeVerifier::operator()(const ghoul::Dictionary& dict,
off.explanation = "Not a valid format, should be: YYYY MM DD hh:mm:ss";
res.offenses.push_back(off);
}
// then check if valid date
else {
// normalize e.g. 29/02/2013 would become 01/03/2013
std::tm t_copy(t);
time_t when = mktime(&t_copy);
std::tm* norm = localtime(&when);
// validate (is the normalized date still the same?):
if (norm->tm_mday != t.tm_mday &&
norm->tm_mon != t.tm_mon &&
norm->tm_year != t.tm_year)
{
res.success = false;
TestResult::Offense off;
off.offender = key;
off.reason = TestResult::Offense::Reason::Verification;
off.explanation = "Not a valid date";
res.offenses.push_back(off);
}
}
return res;
}

View File

@@ -27,6 +27,7 @@
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/documentationengine.h>
#include <openspace/documentation/verifier.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/misc/dictionary.h>
#include <string>
@@ -56,6 +57,21 @@ TEST_CASE("Documentation: Constructor", "[documentation]") {
new StringVerifier,
Optional::No
);
doc.entries.emplace_back(
"FileVerifier",
new FileVerifier,
Optional::No
);
doc.entries.emplace_back(
"DirectoryVerifier",
new DirectoryVerifier,
Optional::No
);
doc.entries.emplace_back(
"DateTimeVerifier",
new DateTimeVerifier,
Optional::No
);
doc.entries.emplace_back(
"TableVerifier",
new TableVerifier,
@@ -263,6 +279,9 @@ TEST_CASE("Documentation: Initializer Constructor", "[documentation]") {
{"DoubleVerifier", new DoubleVerifier, Optional::No },
{"IntVerifier", new IntVerifier, Optional::No },
{"StringVerifier", new StringVerifier, Optional::No },
{"FileVerifier", new FileVerifier, Optional::No },
{"DirectoryVerifier", new DirectoryVerifier, Optional::No },
{"DateTimeVerifier", new DateTimeVerifier, Optional::No },
{"TableVerifier", new TableVerifier, Optional::No },
// Operator Verifiers
@@ -330,10 +349,9 @@ TEST_CASE("Documentation: BoolVerifier", "[documentation]") {
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative;
negative.setValue("Bool", 0);
TestResult negativeRes = testSpecification(doc, negative);
ghoul::Dictionary negativeType;
negativeType.setValue("Bool", 0);
TestResult negativeRes = testSpecification(doc, negativeType);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "Bool");
@@ -363,10 +381,9 @@ TEST_CASE("Documentation: DoubleVerifier", "[documentation]") {
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative;
negative.setValue("Double", 0);
TestResult negativeRes = testSpecification(doc, negative);
ghoul::Dictionary negativeType;
negativeType.setValue("Double", 0);
TestResult negativeRes = testSpecification(doc, negativeType);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "Double");
@@ -400,10 +417,9 @@ TEST_CASE("Documentation: IntVerifier", "[documentation]") {
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative;
negative.setValue("Int", 0.1);
TestResult negativeRes = testSpecification(doc, negative);
ghoul::Dictionary negativeType;
negativeType.setValue("Int", 0.1);
TestResult negativeRes = testSpecification(doc, negativeType);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "Int");
@@ -432,9 +448,9 @@ TEST_CASE("Documentation: StringVerifier", "[documentation]") {
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative;
negative.setValue("String", 0);
TestResult negativeRes = testSpecification(doc, negative);
ghoul::Dictionary negativeType;
negativeType.setValue("String", 0);
TestResult negativeRes = testSpecification(doc, negativeType);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "String");
@@ -449,6 +465,123 @@ TEST_CASE("Documentation: StringVerifier", "[documentation]") {
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::MissingKey);
}
TEST_CASE("Documentation: FileVerifier", "[documentation]") {
using namespace openspace::documentation;
using namespace std::string_literals;
Documentation doc {
{{ "File", new FileVerifier, Optional::No }}
};
ghoul::Dictionary positive;
positive.setValue("File", absPath("${TESTDIR}/verifier/dummyfile.txt").string());
TestResult positiveRes = testSpecification(doc, positive);
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative404;
negative404.setValue("File", absPath("${TESTDIR}/verifier/404.txt").string());
TestResult negativeRes = testSpecification(doc, negative404);
CHECK(!negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "File");
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::Verification);
ghoul::Dictionary negativeType;
negativeType.setValue("File", 0);
negativeRes = testSpecification(doc, negativeType);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "File");
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::WrongType);
ghoul::Dictionary negativeExist;
negativeExist.setValue("File2", ""s);
negativeRes = testSpecification(doc, negativeExist);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "File");
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::MissingKey);
}
TEST_CASE("Documentation: DirectoryVerifier", "[documentation]") {
using namespace openspace::documentation;
using namespace std::string_literals;
Documentation doc{
{{ "Dir", new DirectoryVerifier, Optional::No }}
};
ghoul::Dictionary positive;
positive.setValue("Dir", absPath("${TESTDIR}/verifier").string());
TestResult positiveRes = testSpecification(doc, positive);
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative404;
negative404.setValue("Dir", absPath("${TESTDIR}/verifier404").string());
TestResult negativeRes = testSpecification(doc, negative404);
CHECK(!negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "Dir");
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::Verification);
ghoul::Dictionary negativeType;
negativeType.setValue("Dir", 0);
negativeRes = testSpecification(doc, negativeType);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "Dir");
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::WrongType);
ghoul::Dictionary negativeExist;
negativeExist.setValue("Dir2", ""s);
negativeRes = testSpecification(doc, negativeExist);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "Dir");
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::MissingKey);
}
TEST_CASE("Documentation: DateTimeVerifier", "[documentation]") {
using namespace openspace::documentation;
using namespace std::string_literals;
Documentation doc{
{{ "DateTime", new DateTimeVerifier, Optional::No }}
};
ghoul::Dictionary positive;
positive.setValue("DateTime", "1969 07 20 20:17:00"s);
TestResult positiveRes = testSpecification(doc, positive);
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative404;
negative404.setValue("DateTime", "abc"s);
TestResult negativeRes = testSpecification(doc, negative404);
CHECK(!negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "DateTime");
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::Verification);
ghoul::Dictionary negativeType;
negativeType.setValue("DateTime", 0);
negativeRes = testSpecification(doc, negativeType);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "DateTime");
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::WrongType);
ghoul::Dictionary negativeExist;
negativeExist.setValue("DateTime2", ""s);
negativeRes = testSpecification(doc, negativeExist);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "DateTime");
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::MissingKey);
}
TEST_CASE("Documentation: TableVerifierType", "[documentation]") {
using namespace openspace::documentation;
@@ -462,9 +595,9 @@ TEST_CASE("Documentation: TableVerifierType", "[documentation]") {
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative;
negative.setValue("Table", 0);
TestResult negativeRes = testSpecification(doc, negative);
ghoul::Dictionary negativeType;
negativeType.setValue("Table", 0);
TestResult negativeRes = testSpecification(doc, negativeType);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "Table");
@@ -499,9 +632,9 @@ TEST_CASE("Documentation: StringListVerifierType", "[documentation]") {
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative;
negative.setValue("StringList", 0);
TestResult negativeRes = testSpecification(doc, negative);
ghoul::Dictionary negativeType;
negativeType.setValue("StringList", 0);
TestResult negativeRes = testSpecification(doc, negativeType);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "StringList");
@@ -551,9 +684,9 @@ TEST_CASE("Documentation: IntListVerifierType", "[documentation]") {
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative;
negative.setValue("IntList", 0);
TestResult negativeRes = testSpecification(doc, negative);
ghoul::Dictionary negativeType;
negativeType.setValue("IntList", 0);
TestResult negativeRes = testSpecification(doc, negativeType);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "IntList");
@@ -606,25 +739,25 @@ TEST_CASE("Documentation: MixedVerifiers", "[documentation]") {
CHECK(positiveRes.success);
CHECK(positiveRes.offenses.empty());
ghoul::Dictionary negative1;
negative1.setValue("Bool", true);
negative1.setValue("Double", 1);
negative1.setValue("Int", 0);
negative1.setValue("String", ""s);
negative1.setValue("Table", ghoul::Dictionary());
TestResult negativeRes = testSpecification(doc, negative1);
ghoul::Dictionary negativeType1;
negativeType1.setValue("Bool", true);
negativeType1.setValue("Double", 1);
negativeType1.setValue("Int", 0);
negativeType1.setValue("String", ""s);
negativeType1.setValue("Table", ghoul::Dictionary());
TestResult negativeRes = testSpecification(doc, negativeType1);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 1);
CHECK(negativeRes.offenses[0].offender == "Double");
CHECK(negativeRes.offenses[0].reason == TestResult::Offense::Reason::WrongType);
ghoul::Dictionary negative2;
negative2.setValue("Bool", true);
negative2.setValue("Double", 0.0);
negative2.setValue("Int", ""s);
negative2.setValue("String", 1);
negative2.setValue("Table", ghoul::Dictionary());
negativeRes = testSpecification(doc, negative2);
ghoul::Dictionary negativeType2;
negativeType2.setValue("Bool", true);
negativeType2.setValue("Double", 0.0);
negativeType2.setValue("Int", ""s);
negativeType2.setValue("String", 1);
negativeType2.setValue("Table", ghoul::Dictionary());
negativeRes = testSpecification(doc, negativeType2);
CHECK_FALSE(negativeRes.success);
REQUIRE(negativeRes.offenses.size() == 2);
CHECK(negativeRes.offenses[0].offender == "Int");

View File