1+ #include " gtest/gtest.h"
2+ #include " taggedjsonobject.h"
3+ #include " taggedjsonarray.h"
4+ #include " taggedjsonobjectmacros.h"
5+
6+ namespace {
7+ constexpr auto EXAMPLE_FILE_PATH = " ../Tests/test_file.json" ;
8+ constexpr auto EXPECTED_ARRAY_FIRST_ELEMENT_RESULT = " Hello" ;
9+ constexpr int EXPECTED_MIXEDARRAY_FIRST_ELEMENT_RESULT = 42 ;
10+ constexpr auto EXPECTED_MIXEDARRAY_LAST_ELEMENT_RESULT = " everything" ;
11+ constexpr auto EXPECTED_REDUCED_RESULT = " HelloWorld" ;
12+ constexpr auto EXPECTED_NAME_RESULT = " Michael" ;
13+ constexpr auto EXPECTED_TOTAL_AGE = 75 ;
14+
15+ QJsonDocument jsonFromFile ()
16+ {
17+ QFile f{ EXAMPLE_FILE_PATH };
18+ f.open (QIODevice::ReadOnly);
19+ return QJsonDocument::fromJson (f.readAll ());
20+ }
21+ }
22+
23+ TJO_DEFINE_JSON_TAGGED_OBJECT (Identity,
24+ (TaggedJSONString, name),
25+ (TaggedJSONInt, age))
26+
27+
28+ TJO_DEFINE_JSON_TAGGED_OBJECT(TestClass,
29+ (TaggedJSONStringArray, example_arr),
30+ (TaggedJSONVariantArray, example_mixed_arr),
31+ (TaggedJSONArray<Identity>, example_tagged_object_array))
32+
33+
34+ class TaggedArrayFixture : public testing::Test
35+ {
36+ public:
37+ TaggedArrayFixture () : testObj (TestClass{jsonFromFile ().toJson ()}) {};
38+ TestClass testObj;
39+ };
40+
41+ // Square bracket operator can be used to access the n'th element for TaggedJSONArray
42+ TEST_F (TaggedArrayFixture, ArrayGetFromBrackets)
43+ {
44+ ASSERT_EQ (EXPECTED_ARRAY_FIRST_ELEMENT_RESULT, testObj.example_arr [0 ].toString ());
45+ }
46+
47+ // At method can be used to access the n'th element for TaggedJSONArray
48+ TEST_F (TaggedArrayFixture, ArrayGetFromMethod)
49+ {
50+ ASSERT_EQ (EXPECTED_ARRAY_FIRST_ELEMENT_RESULT, testObj.example_arr .at (0 ).toString ());
51+ }
52+
53+ // At method can also be used to return QJSonValueRef, which can be mutated
54+ TEST_F (TaggedArrayFixture, ArraySetFromAssignment)
55+ {
56+ constexpr auto MODIFIED_VALUE = " Another World" ;
57+ testObj.example_arr .at (0 ) = MODIFIED_VALUE;
58+ ASSERT_EQ (MODIFIED_VALUE, testObj.example_arr [0 ].toString ());
59+ }
60+
61+ // Square bracket operator can also be used to return QJSonValueRef, which can be mutated
62+ TEST_F (TaggedArrayFixture, ArraySetFromBrackets)
63+ {
64+ constexpr auto MODIFIED_VALUE = " Another World" ;
65+ testObj.example_arr [0 ] = MODIFIED_VALUE;
66+ ASSERT_EQ (MODIFIED_VALUE, testObj.example_arr [0 ].toString ());
67+ }
68+
69+ // Arrow operator can be used to access some of the useful QJsonArray features like iterators
70+ TEST_F (TaggedArrayFixture, ArrayArrowOperator)
71+ {
72+ auto lambda_customSum = [](QString previous, QJsonValue current) -> QString {return previous + current.toString (); };
73+ const QString concatText = std::reduce (testObj.example_arr ->begin (), testObj.example_arr ->end (), QString (), lambda_customSum);
74+ ASSERT_EQ (std::string (EXPECTED_REDUCED_RESULT), concatText.toStdString ());
75+ }
76+
77+ // Using stout stream on the TaggedJSONArray prints all of its elements
78+ TEST_F (TaggedArrayFixture, ArrayWholeSTDOutTest)
79+ {
80+ testing::internal::CaptureStdout ();
81+ std::cout << testObj.example_arr << std::endl;
82+ const std::string textOutput (testing::internal::GetCapturedStdout ());
83+ ASSERT_STREQ (" Hello\n World\n\n " , textOutput.data ());
84+ }
85+
86+ // QDebug can also be used to print all of its elements
87+ TEST_F (TaggedArrayFixture, ArrayWholeQDebugTest)
88+ {
89+ QString qDebugOutput (testObj.example_arr );
90+ ASSERT_EQ (std::string (" Hello\n World\n " ), qDebugOutput.toStdString ());
91+ }
92+
93+ // Mixed arrays can be wrapped thanks to the QVariant containers
94+ TEST_F (TaggedArrayFixture, MixedArrayGetFromBrackets)
95+ {
96+ ASSERT_EQ (EXPECTED_MIXEDARRAY_FIRST_ELEMENT_RESULT, testObj.example_mixed_arr [0 ].toInt ());
97+ }
98+
99+ // Tagged objects can be placed on the TaggedJSONArrays and at method can be used to immutable access to the indexed object (just like the std::vector)
100+ TEST_F (TaggedArrayFixture, TaggedObjectContainer)
101+ {
102+ ASSERT_EQ (QString (EXPECTED_NAME_RESULT), *testObj.example_tagged_object_array .at (1 ).name );
103+ }
104+
105+ // Internal vector of the TaggedJSONArray can be accessed by the asterisk operator
106+ TEST_F (TaggedArrayFixture, TaggedObjectContainerVectorOperations)
107+ {
108+ const auto lambda_accumulateAges = [](const int previous, const Identity& curIdentity) -> int {return previous + *curIdentity.age ; };
109+ const int totalAge = std::reduce (testObj.example_tagged_object_array ->cbegin (), testObj.example_tagged_object_array ->cend (), 0 , lambda_accumulateAges);
110+
111+ ASSERT_EQ (EXPECTED_TOTAL_AGE, totalAge);
112+ }
113+
114+ // Square brackets can be used for the mutable access of the indexed object (just like the std::vector)
115+ TEST_F (TaggedArrayFixture, TaggedObjectContainerMutation)
116+ {
117+ constexpr auto MODIFIED_NAME = " Charles" ;
118+ constexpr auto MODIFIED_AGE = 16 ;
119+
120+ QJsonObject newObj;
121+ newObj[" name" ] = MODIFIED_NAME;
122+ newObj[" age" ] = MODIFIED_AGE;
123+
124+ testObj.example_tagged_object_array [0 ] = Identity{ newObj };
125+ ASSERT_EQ (MODIFIED_AGE, *testObj.example_tagged_object_array .at (0 ).age );
126+ }
0 commit comments