Skip to content

Commit d1f5f3d

Browse files
committed
tests part 2 (VS choke on itself)
1 parent 6bcc9a3 commit d1f5f3d

File tree

8 files changed

+144
-82
lines changed

8 files changed

+144
-82
lines changed

Test/CMakeLists.txt

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,24 @@ target_link_libraries(cppjson-Test PRIVATE
44
cppjson::cppjson
55
)
66

7+
include(FetchContent)
8+
FetchContent_Declare(
9+
googletest
10+
URL https://github.com/google/googletest/archive/refs/heads/main.zip
11+
)
12+
FetchContent_MakeAvailable(googletest)
13+
14+
715
target_sources(cppjson-Test PRIVATE
816
Test.cpp
917
)
1018

11-
set(TEST_SOURCES
12-
TestEmptyObject.cpp
13-
TestPrimitives.cpp
14-
TestNestedObjects.cpp
15-
)
19+
target_link_libraries(cppjson-Test PRIVATE gtest_main)
20+
21+
include(GoogleTest)
22+
gtest_discover_tests(cppjson-Test)
1623

1724
if(MSVC)
1825
add_compile_options("/Zi")
1926
add_link_options("/PROFILE")
2027
endif()
21-
22-
23-
foreach(TEST_SRC IN LISTS TEST_SOURCES)
24-
message(Adding ${TEST_SRC})
25-
get_filename_component(TEST_NAME ${TEST_SRC} NAME_WE)
26-
add_executable(${TEST_NAME} tests/${TEST_SRC})
27-
target_link_libraries(${TEST_NAME} PRIVATE cppjson::cppjson)
28-
29-
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
30-
endforeach()

Test/Test.cpp

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,67 @@
1+
#include <gtest/gtest.h>
12
#include <cppjson/cppjson.hpp>
2-
#include <print>
33

4-
int main()
4+
TEST(BasicTests, ArraySize)
5+
{
6+
cppjson::Array array{};
7+
array[] = 1;
8+
array[] = 2;
9+
array[] = 3.0;
10+
EXPECT_TRUE(array.Size() == 3);
11+
}
12+
13+
TEST(BasicTests, InvalidAssignment)
14+
{
15+
cppjson::Object obj{};
16+
obj["number"] = 123.0;
17+
EXPECT_THROW({ obj["number"] = "NaN"; }, std::logic_error);
18+
}
19+
20+
TEST(BasicTests, NestedObjects)
21+
{
22+
cppjson::Object object{};
23+
object["sub"]["veryNested"] = 6.0;
24+
25+
EXPECT_EQ(6.0, (double)object["sub"]["veryNested"]);
26+
}
27+
28+
TEST(BasicTests, ObjectTypes)
29+
{
30+
cppjson::Object obj{};
31+
obj["string"] = "Hello";
32+
obj["number"] = 42.0;
33+
obj["boolean"] = true;
34+
obj["null"] = nullptr;
35+
36+
EXPECT_TRUE(IsType<std::string>(obj["string"]));
37+
EXPECT_TRUE(IsType<double>(obj["number"]));
38+
EXPECT_TRUE(IsType<bool>(obj["boolean"]));
39+
EXPECT_TRUE(IsType<std::nullptr_t>(obj["null"]));
40+
}
41+
42+
TEST(BasicTests, Primitives)
543
{
644
cppjson::Object object{};
7-
std::println("{}", object);
845
object["test1"] = "Hello World";
946
object["test2"] = 123.0;
10-
object["sub"]["veryNested"] = 6.0;
11-
cppjson::Array& array = object["array"];
12-
array[] = 2;
13-
array[] = 6.0;
14-
array[0] = 1;
15-
array[] = "Stirng";
16-
array.EmplaceBack(nullptr);
17-
try
18-
{
19-
array[2] = true;
20-
}
21-
catch (const std::logic_error& error)
22-
{
23-
std::println("Error = {}", error.what());
24-
}
25-
26-
std::println("{}", object);
27-
std::println("object[\"test1\"] = {}", object["test1"]);
28-
const std::string test = object["test1"];
29-
std::println("test = {}", test);
47+
48+
EXPECT_EQ("Hello World", static_cast<const std::string&>(object["test1"]));
49+
EXPECT_EQ(123.0, (double)object["test2"]);
50+
}
51+
52+
TEST(BasicTests, ValueComparisons)
53+
{
54+
cppjson::Object obj{};
55+
obj["a"] = 5.0;
56+
obj["b"] = 5.0;
57+
obj["c"] = 10.0;
58+
59+
EXPECT_TRUE(obj["a"] == obj["b"]);
60+
EXPECT_FALSE(obj["a"] == obj["c"]);
61+
}
62+
63+
int main(int argc, char** argv)
64+
{
65+
::testing::InitGoogleTest(&argc, argv);
66+
return RUN_ALL_TESTS();
3067
}

Test/tests/TestEmptyObject.cpp

Lines changed: 0 additions & 13 deletions
This file was deleted.

Test/tests/TestNestedObjects.cpp

Lines changed: 0 additions & 15 deletions
This file was deleted.

Test/tests/TestPrimitives.cpp

Lines changed: 0 additions & 16 deletions
This file was deleted.

cppjson-Test-results.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<testsuite name="(empty)"
3+
tests="0"
4+
failures="0"
5+
disabled="0"
6+
skipped="0"
7+
hostname=""
8+
time="0"
9+
timestamp="2025-09-14T20:47:43"/>

cppjson/include/cppjson/object.hpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ namespace cppjson
3838
template <typename T>
3939
const T& As() const noexcept(false);
4040

41+
[[nodiscard]] bool operator==(const JsonObject& other) const;
42+
4143
private:
4244
JsonType _dataType{};
4345
std::byte* _dataStorage{};
@@ -55,6 +57,9 @@ namespace cppjson
5557
}
5658

5759
friend struct std::formatter<cppjson::JsonObject>;
60+
61+
template <typename T>
62+
friend bool IsType(const JsonObject& object) noexcept;
5863
};
5964

6065
class Object
@@ -69,6 +74,8 @@ namespace cppjson
6974

7075
[[nodiscard]] bool IsEmpty() const noexcept { return this->_nodes.empty(); }
7176

77+
[[nodiscard]] bool operator==(const Object& other) const;
78+
7279
class ObjectProxy
7380
{
7481
public:
@@ -108,11 +115,14 @@ namespace cppjson
108115
{
109116
return (*this)[std::string{key}];
110117
}
118+
[[nodiscard]] bool operator==(const ObjectProxy& other) const { return this->_object.get() == other._object.get(); }
111119

112120
private:
113121
std::reference_wrapper<JsonObject> _object;
114122

115123
friend struct std::formatter<cppjson::Object::ObjectProxy>;
124+
template <typename T>
125+
friend bool IsType(const Object::ObjectProxy& proxy) noexcept;
116126
};
117127

118128
class ConstObjectProxy
@@ -180,10 +190,37 @@ namespace cppjson
180190
return Object::ConstObjectProxy{this->_objects.at(index)};
181191
}
182192

193+
[[nodiscard]] std::size_t Size() const noexcept { return this->_objects.size(); }
194+
195+
[[nodiscard]] bool operator==(const Array& other) const
196+
{
197+
if (this->_objects.size() != other._objects.size()) return false;
198+
return std::equal(this->_objects.begin(), this->_objects.end(), other._objects.begin());
199+
}
200+
183201
private:
184202
std::vector<JsonObject> _objects{};
185203

186204
friend struct std::formatter<cppjson::JsonObject>;
187205
friend struct std::formatter<cppjson::Array>;
188206
};
207+
208+
template <typename T>
209+
[[nodiscard]] bool IsType(const JsonObject& object) noexcept
210+
{
211+
if constexpr (std::same_as<std::remove_cvref_t<T>, std::nullptr_t>) return object._dataType == JsonType::Null;
212+
else if constexpr (std::same_as<std::remove_cvref_t<T>, std::string>) return object._dataType == JsonType::String;
213+
else if constexpr (std::same_as<std::remove_cvref_t<T>, Object>) return object._dataType == JsonType::Object;
214+
else if constexpr (std::same_as<std::remove_cvref_t<T>, double>) return object._dataType == JsonType::Number;
215+
else if constexpr (std::same_as<std::remove_cvref_t<T>, bool>) return object._dataType == JsonType::Bool;
216+
else if constexpr (std::same_as<std::remove_cvref_t<T>, Array>) return object._dataType == JsonType::Array;
217+
else
218+
return false;
219+
}
220+
221+
template <typename T>
222+
[[nodiscard]] bool IsType(const Object::ObjectProxy& proxy) noexcept
223+
{
224+
return IsType<T>(proxy._object.get());
225+
}
189226
} // namespace cppjson

cppjson/src/object.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,21 @@ cppjson::JsonObject::~JsonObject()
4646
::operator delete(this->_dataStorage);
4747
}
4848

49+
bool cppjson::JsonObject::operator==(const JsonObject& other) const
50+
{
51+
if (other._dataType != this->_dataType) return false;
52+
switch (this->_dataType)
53+
{
54+
case JsonType::Null: return true;
55+
case JsonType::Number: return this->DangerousAs<double>() == other.DangerousAs<double>();
56+
case JsonType::Bool: return this->DangerousAs<bool>() == other.DangerousAs<bool>();
57+
case JsonType::String: return this->DangerousAs<std::string>() == other.DangerousAs<std::string>();
58+
case JsonType::Object: return this->DangerousAs<cppjson::Object>() == other.DangerousAs<cppjson::Object>();
59+
case JsonType::Array: return this->DangerousAs<cppjson::Array>() == other.DangerousAs<cppjson::Array>();
60+
default: return false;
61+
}
62+
}
63+
4964
void cppjson::JsonObject::Destroy(void)
5065
{
5166
using cppjson::Array;
@@ -185,3 +200,14 @@ cppjson::Object::ConstObjectProxy cppjson::Object::ConstObjectProxy::operator[](
185200
{
186201
return ConstObjectProxy{this->_object.get().As<Object>()[key]};
187202
}
203+
204+
bool cppjson::Object::operator==(const Object& other) const
205+
{
206+
if (this->_nodes.size() != other._nodes.size()) return false;
207+
for (const auto& [key, value] : this->_nodes)
208+
{
209+
if (!other._nodes.contains(key)) return false;
210+
if (!(value == other._nodes.at(key))) return false;
211+
}
212+
return true;
213+
}

0 commit comments

Comments
 (0)