From 82ffd3e718771d2bc635264c03f002372b34893a Mon Sep 17 00:00:00 2001
From: Richard Walters <rwalters@digitalstirling.com>
Date: Wed, 4 Jul 2018 00:02:10 -0700
Subject: Refactoring

Add unit tests for stand-alone modules that were formerly
part of Uri and so were previously tested along with Uri.
---
 test/CMakeLists.txt                              |   5 ++
 test/src/CharacterSetTests.cpp                   | 108 +++++++++++++++++++++++
 test/src/NormalizeCaseInsensitiveStringTests.cpp |  41 +++++++++
 test/src/PercentEncodedCharacterDecoderTests.cpp |  48 ++++++++++
 4 files changed, 202 insertions(+)
 create mode 100644 test/src/CharacterSetTests.cpp
 create mode 100644 test/src/NormalizeCaseInsensitiveStringTests.cpp
 create mode 100644 test/src/PercentEncodedCharacterDecoderTests.cpp

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 7c3eb76..7f2fc59 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -7,6 +7,9 @@ set(This UriTests)
 
 set(Sources
     src/UriTests.cpp
+    src/CharacterSetTests.cpp
+    src/NormalizeCaseInsensitiveStringTests.cpp
+    src/PercentEncodedCharacterDecoderTests.cpp
 )
 
 add_executable(${This} ${Sources})
@@ -14,6 +17,8 @@ set_target_properties(${This} PROPERTIES
     FOLDER Tests
 )
 
+target_include_directories(${This} PRIVATE ..)
+
 target_link_libraries(${This} PUBLIC
     gtest_main
     Uri
diff --git a/test/src/CharacterSetTests.cpp b/test/src/CharacterSetTests.cpp
new file mode 100644
index 0000000..7013127
--- /dev/null
+++ b/test/src/CharacterSetTests.cpp
@@ -0,0 +1,108 @@
+/**
+ * @file CharacterSetTests.cpp
+ *
+ * This module contains the unit tests of the Uri::CharacterSet class.
+ *
+ * © 2018 by Richard Walters
+ */
+
+#include <gtest/gtest.h>
+#include <src/CharacterSet.hpp>
+#include <utility>
+#include <vector>
+
+TEST(CharacterSetTests, DefaultConstructor) {
+    Uri::CharacterSet cs;
+    for (char c = 0; c < 0x7F; ++c) {
+        ASSERT_FALSE(cs.Contains(c));
+    }
+}
+
+TEST(CharacterSetTests, SingleCharacterConstructor) {
+    Uri::CharacterSet cs('X');
+    for (char c = 0; c < 0x7F; ++c) {
+        if (c == 'X') {
+            ASSERT_TRUE(cs.Contains(c));
+        } else {
+            ASSERT_FALSE(cs.Contains(c));
+        }
+    }
+}
+
+TEST(CharacterSetTests, RangeConstructor) {
+    Uri::CharacterSet cs('A', 'G');
+    for (char c = 0; c < 0x7F; ++c) {
+        if (
+            (c >= 'A')
+            && (c <= 'G')
+        ) {
+            ASSERT_TRUE(cs.Contains(c));
+        } else {
+            ASSERT_FALSE(cs.Contains(c));
+        }
+    }
+}
+
+TEST(CharacterSetTests, InitializerListConstructor) {
+    Uri::CharacterSet cs1{'X'};
+    for (char c = 0; c < 0x7F; ++c) {
+        if (c == 'X') {
+            ASSERT_TRUE(cs1.Contains(c));
+        } else {
+            ASSERT_FALSE(cs1.Contains(c));
+        }
+    }
+    Uri::CharacterSet cs2{'A', 'G'};
+    for (char c = 0; c < 0x7F; ++c) {
+        if (
+            (c == 'A')
+            || (c == 'G')
+        ) {
+            ASSERT_TRUE(cs2.Contains(c));
+        } else {
+            ASSERT_FALSE(cs2.Contains(c));
+        }
+    }
+    Uri::CharacterSet cs3{Uri::CharacterSet('f', 'i')};
+    for (char c = 0; c < 0x7F; ++c) {
+        if (
+            (c >= 'f')
+            && (c <= 'i')
+        ) {
+            ASSERT_TRUE(cs3.Contains(c));
+        } else {
+            ASSERT_FALSE(cs3.Contains(c));
+        }
+    }
+    Uri::CharacterSet cs4{Uri::CharacterSet('a', 'c'), Uri::CharacterSet('f', 'i')};
+    for (char c = 0; c < 0x7F; ++c) {
+        if (
+            (
+                (c >= 'a')
+                && (c <= 'c')
+            )
+            || (
+                (c >= 'f')
+                && (c <= 'i')
+            )
+        ) {
+            ASSERT_TRUE(cs4.Contains(c));
+        } else {
+            ASSERT_FALSE(cs4.Contains(c));
+        }
+    }
+    Uri::CharacterSet cs5{Uri::CharacterSet('a', 'c'), Uri::CharacterSet('x')};
+    for (char c = 0; c < 0x7F; ++c) {
+        if (
+            (
+                (c >= 'a')
+                && (c <= 'c')
+            )
+            || (c == 'x')
+        ) {
+            ASSERT_TRUE(cs5.Contains(c));
+        } else {
+            ASSERT_FALSE(cs5.Contains(c));
+        }
+    }
+}
diff --git a/test/src/NormalizeCaseInsensitiveStringTests.cpp b/test/src/NormalizeCaseInsensitiveStringTests.cpp
new file mode 100644
index 0000000..f68d344
--- /dev/null
+++ b/test/src/NormalizeCaseInsensitiveStringTests.cpp
@@ -0,0 +1,41 @@
+/**
+ * @file NormalizeCaseInsensitiveStringTests.cpp
+ *
+ * This module contains the unit tests of the Uri::NormalizeCaseInsensitiveString class.
+ *
+ * © 2018 by Richard Walters
+ */
+
+#include <gtest/gtest.h>
+#include <src/NormalizeCaseInsensitiveString.hpp>
+
+TEST(NormalizeCaseInsensitiveStringTests, NormalizeCaseInsensitiveString) {
+    ASSERT_EQ(
+        "example",
+        Uri::NormalizeCaseInsensitiveString("eXAmplE")
+    );
+    ASSERT_EQ(
+        "example",
+        Uri::NormalizeCaseInsensitiveString("example")
+    );
+    ASSERT_EQ(
+        "example",
+        Uri::NormalizeCaseInsensitiveString("EXAMPLE")
+    );
+    ASSERT_EQ(
+        "foo1bar",
+        Uri::NormalizeCaseInsensitiveString("foo1BAR")
+    );
+    ASSERT_EQ(
+        "foo1bar",
+        Uri::NormalizeCaseInsensitiveString("fOo1bAr")
+    );
+    ASSERT_EQ(
+        "foo1bar",
+        Uri::NormalizeCaseInsensitiveString("foo1bar")
+    );
+    ASSERT_EQ(
+        "foo1bar",
+        Uri::NormalizeCaseInsensitiveString("FOO1BAR")
+    );
+}
diff --git a/test/src/PercentEncodedCharacterDecoderTests.cpp b/test/src/PercentEncodedCharacterDecoderTests.cpp
new file mode 100644
index 0000000..fbc3d5e
--- /dev/null
+++ b/test/src/PercentEncodedCharacterDecoderTests.cpp
@@ -0,0 +1,48 @@
+/**
+ * @file PercentEncodedCharacterDecoderTests.cpp
+ *
+ * This module contains the unit tests of the Uri::PercentEncodedCharacterDecoder class.
+ *
+ * © 2018 by Richard Walters
+ */
+
+#include <gtest/gtest.h>
+#include <src/PercentEncodedCharacterDecoder.hpp>
+#include <stddef.h>
+#include <vector>
+
+TEST(PercentEncodedCharacterDecoderTests, GoodSequences) {
+    Uri::PercentEncodedCharacterDecoder pec;
+    struct TestVector {
+        char sequence[2];
+        char expectedOutput;
+    };
+    const std::vector< TestVector > testVectors{
+        {{'4', '1'}, 'A'},
+        {{'5', 'A'}, 'Z'},
+        {{'6', 'e'}, 'n'},
+    };
+    size_t index = 0;
+    for (auto testVector: testVectors) {
+        pec = Uri::PercentEncodedCharacterDecoder();
+        ASSERT_FALSE(pec.Done());
+        ASSERT_TRUE(pec.NextEncodedCharacter(testVector.sequence[0]));
+        ASSERT_FALSE(pec.Done());
+        ASSERT_TRUE(pec.NextEncodedCharacter(testVector.sequence[1]));
+        ASSERT_TRUE(pec.Done());
+        ASSERT_EQ(testVector.expectedOutput, pec.GetDecodedCharacter()) << index;
+        ++index;
+    }
+}
+
+TEST(PercentEncodedCharacterDecoderTests, BadSequences) {
+    Uri::PercentEncodedCharacterDecoder pec;
+    std::vector< char > testVectors{
+        'G', 'g', '.', 'z', '-', ' ', 'V',
+    };
+    for (auto testVector: testVectors) {
+        pec = Uri::PercentEncodedCharacterDecoder();
+        ASSERT_FALSE(pec.Done());
+        ASSERT_FALSE(pec.NextEncodedCharacter(testVector));
+    }
+}
-- 
cgit v1.2.3