/ src / common / UnitTests-CommonUtils / Json.Tests.cpp
Json.Tests.cpp
  1  #include "pch.h"
  2  #include "TestHelpers.h"
  3  #include <json.h>
  4  
  5  using namespace Microsoft::VisualStudio::CppUnitTestFramework;
  6  using namespace winrt::Windows::Data::Json;
  7  
  8  namespace UnitTestsCommonUtils
  9  {
 10      TEST_CLASS(JsonTests)
 11      {
 12      public:
 13          // from_file tests
 14          TEST_METHOD(FromFile_NonExistentFile_ReturnsNullopt)
 15          {
 16              auto result = json::from_file(L"C:\\NonExistent\\File\\Path.json");
 17              Assert::IsFalse(result.has_value());
 18          }
 19  
 20          TEST_METHOD(FromFile_ValidJsonFile_ReturnsJsonObject)
 21          {
 22              TestHelpers::TempFile tempFile(L"", L".json");
 23              tempFile.write("{\"key\": \"value\"}");
 24  
 25              auto result = json::from_file(tempFile.path());
 26              Assert::IsTrue(result.has_value());
 27          }
 28  
 29          TEST_METHOD(FromFile_InvalidJson_ReturnsNullopt)
 30          {
 31              TestHelpers::TempFile tempFile(L"", L".json");
 32              tempFile.write("not valid json {{{");
 33  
 34              auto result = json::from_file(tempFile.path());
 35              Assert::IsFalse(result.has_value());
 36          }
 37  
 38          TEST_METHOD(FromFile_EmptyFile_ReturnsNullopt)
 39          {
 40              TestHelpers::TempFile tempFile(L"", L".json");
 41              // File is empty
 42  
 43              auto result = json::from_file(tempFile.path());
 44              Assert::IsFalse(result.has_value());
 45          }
 46  
 47          TEST_METHOD(FromFile_ValidComplexJson_ParsesCorrectly)
 48          {
 49              TestHelpers::TempFile tempFile(L"", L".json");
 50              tempFile.write("{\"name\": \"test\", \"value\": 42, \"enabled\": true}");
 51  
 52              auto result = json::from_file(tempFile.path());
 53              Assert::IsTrue(result.has_value());
 54  
 55              auto& obj = *result;
 56              Assert::IsTrue(obj.HasKey(L"name"));
 57              Assert::IsTrue(obj.HasKey(L"value"));
 58              Assert::IsTrue(obj.HasKey(L"enabled"));
 59          }
 60  
 61          // to_file tests
 62          TEST_METHOD(ToFile_ValidObject_WritesFile)
 63          {
 64              TestHelpers::TempFile tempFile(L"", L".json");
 65  
 66              JsonObject obj;
 67              obj.SetNamedValue(L"key", JsonValue::CreateStringValue(L"value"));
 68              json::to_file(tempFile.path(), obj);
 69  
 70              // Read back and verify
 71              auto result = json::from_file(tempFile.path());
 72              Assert::IsTrue(result.has_value());
 73              Assert::IsTrue(result->HasKey(L"key"));
 74          }
 75  
 76          TEST_METHOD(ToFile_ComplexObject_WritesFile)
 77          {
 78              TestHelpers::TempFile tempFile(L"", L".json");
 79  
 80              JsonObject obj;
 81              obj.SetNamedValue(L"name", JsonValue::CreateStringValue(L"test"));
 82              obj.SetNamedValue(L"value", JsonValue::CreateNumberValue(42));
 83              obj.SetNamedValue(L"enabled", JsonValue::CreateBooleanValue(true));
 84              json::to_file(tempFile.path(), obj);
 85  
 86              auto result = json::from_file(tempFile.path());
 87              Assert::IsTrue(result.has_value());
 88              Assert::AreEqual(std::wstring(L"test"), std::wstring(result->GetNamedString(L"name")));
 89              Assert::AreEqual(42.0, result->GetNamedNumber(L"value"));
 90              Assert::IsTrue(result->GetNamedBoolean(L"enabled"));
 91          }
 92  
 93          // has tests
 94          TEST_METHOD(Has_ExistingKey_ReturnsTrue)
 95          {
 96              JsonObject obj;
 97              obj.SetNamedValue(L"key", JsonValue::CreateStringValue(L"value"));
 98              Assert::IsTrue(json::has(obj, L"key", JsonValueType::String));
 99          }
100  
101          TEST_METHOD(Has_NonExistingKey_ReturnsFalse)
102          {
103              JsonObject obj;
104              Assert::IsFalse(json::has(obj, L"key", JsonValueType::String));
105          }
106  
107          TEST_METHOD(Has_WrongType_ReturnsFalse)
108          {
109              JsonObject obj;
110              obj.SetNamedValue(L"key", JsonValue::CreateStringValue(L"value"));
111              Assert::IsFalse(json::has(obj, L"key", JsonValueType::Number));
112          }
113  
114          TEST_METHOD(Has_NumberType_ReturnsTrue)
115          {
116              JsonObject obj;
117              obj.SetNamedValue(L"key", JsonValue::CreateNumberValue(42));
118              Assert::IsTrue(json::has(obj, L"key", JsonValueType::Number));
119          }
120  
121          TEST_METHOD(Has_BooleanType_ReturnsTrue)
122          {
123              JsonObject obj;
124              obj.SetNamedValue(L"key", JsonValue::CreateBooleanValue(true));
125              Assert::IsTrue(json::has(obj, L"key", JsonValueType::Boolean));
126          }
127  
128          TEST_METHOD(Has_ObjectType_ReturnsTrue)
129          {
130              JsonObject obj;
131              JsonObject nested;
132              obj.SetNamedValue(L"key", nested);
133              Assert::IsTrue(json::has(obj, L"key", JsonValueType::Object));
134          }
135  
136          // value function tests
137          TEST_METHOD(Value_IntegerType_CreatesNumberValue)
138          {
139              auto val = json::value(42);
140              Assert::IsTrue(val.ValueType() == JsonValueType::Number);
141              Assert::AreEqual(42.0, val.GetNumber());
142          }
143  
144          TEST_METHOD(Value_DoubleType_CreatesNumberValue)
145          {
146              auto val = json::value(3.14);
147              Assert::IsTrue(val.ValueType() == JsonValueType::Number);
148              Assert::AreEqual(3.14, val.GetNumber());
149          }
150  
151          TEST_METHOD(Value_BooleanTrue_CreatesBooleanValue)
152          {
153              auto val = json::value(true);
154              Assert::IsTrue(val.ValueType() == JsonValueType::Boolean);
155              Assert::IsTrue(val.GetBoolean());
156          }
157  
158          TEST_METHOD(Value_BooleanFalse_CreatesBooleanValue)
159          {
160              auto val = json::value(false);
161              Assert::IsTrue(val.ValueType() == JsonValueType::Boolean);
162              Assert::IsFalse(val.GetBoolean());
163          }
164  
165          TEST_METHOD(Value_String_CreatesStringValue)
166          {
167              auto val = json::value(L"hello");
168              Assert::IsTrue(val.ValueType() == JsonValueType::String);
169              Assert::AreEqual(std::wstring(L"hello"), std::wstring(val.GetString()));
170          }
171  
172          TEST_METHOD(Value_JsonObject_ReturnsJsonValue)
173          {
174              JsonObject obj;
175              obj.SetNamedValue(L"key", JsonValue::CreateStringValue(L"value"));
176              auto val = json::value(obj);
177              Assert::IsTrue(val.ValueType() == JsonValueType::Object);
178          }
179  
180          TEST_METHOD(Value_JsonValue_ReturnsIdentity)
181          {
182              auto original = JsonValue::CreateStringValue(L"test");
183              auto result = json::value(original);
184              Assert::AreEqual(std::wstring(L"test"), std::wstring(result.GetString()));
185          }
186  
187          // get function tests
188          TEST_METHOD(Get_BooleanValue_ReturnsValue)
189          {
190              JsonObject obj;
191              obj.SetNamedValue(L"enabled", JsonValue::CreateBooleanValue(true));
192  
193              bool result = false;
194              json::get(obj, L"enabled", result);
195              Assert::IsTrue(result);
196          }
197  
198          TEST_METHOD(Get_IntValue_ReturnsValue)
199          {
200              JsonObject obj;
201              obj.SetNamedValue(L"count", JsonValue::CreateNumberValue(42));
202  
203              int result = 0;
204              json::get(obj, L"count", result);
205              Assert::AreEqual(42, result);
206          }
207  
208          TEST_METHOD(Get_DoubleValue_ReturnsValue)
209          {
210              JsonObject obj;
211              obj.SetNamedValue(L"ratio", JsonValue::CreateNumberValue(3.14));
212  
213              double result = 0.0;
214              json::get(obj, L"ratio", result);
215              Assert::AreEqual(3.14, result);
216          }
217  
218          TEST_METHOD(Get_StringValue_ReturnsValue)
219          {
220              JsonObject obj;
221              obj.SetNamedValue(L"name", JsonValue::CreateStringValue(L"test"));
222  
223              std::wstring result;
224              json::get(obj, L"name", result);
225              Assert::AreEqual(std::wstring(L"test"), result);
226          }
227  
228          TEST_METHOD(Get_MissingKey_UsesDefault)
229          {
230              JsonObject obj;
231  
232              int result = 0;
233              json::get(obj, L"missing", result, 99);
234              Assert::AreEqual(99, result);
235          }
236  
237          TEST_METHOD(Get_MissingKeyNoDefault_PreservesOriginal)
238          {
239              JsonObject obj;
240  
241              int result = 42;
242              json::get(obj, L"missing", result);
243              // When key is missing and no default, original value is preserved
244              Assert::AreEqual(42, result);
245          }
246  
247          TEST_METHOD(Get_JsonObject_ReturnsObject)
248          {
249              JsonObject obj;
250              JsonObject nested;
251              nested.SetNamedValue(L"inner", JsonValue::CreateStringValue(L"value"));
252              obj.SetNamedValue(L"nested", nested);
253  
254              JsonObject result;
255              json::get(obj, L"nested", result);
256              Assert::IsTrue(result.HasKey(L"inner"));
257          }
258  
259          // Roundtrip tests
260          TEST_METHOD(Roundtrip_ComplexObject_PreservesData)
261          {
262              TestHelpers::TempFile tempFile(L"", L".json");
263  
264              JsonObject original;
265              original.SetNamedValue(L"string", JsonValue::CreateStringValue(L"hello"));
266              original.SetNamedValue(L"number", JsonValue::CreateNumberValue(42));
267              original.SetNamedValue(L"boolean", JsonValue::CreateBooleanValue(true));
268  
269              JsonObject nested;
270              nested.SetNamedValue(L"inner", JsonValue::CreateStringValue(L"world"));
271              original.SetNamedValue(L"object", nested);
272  
273              json::to_file(tempFile.path(), original);
274              auto loaded = json::from_file(tempFile.path());
275  
276              Assert::IsTrue(loaded.has_value());
277              Assert::AreEqual(std::wstring(L"hello"), std::wstring(loaded->GetNamedString(L"string")));
278              Assert::AreEqual(42.0, loaded->GetNamedNumber(L"number"));
279              Assert::IsTrue(loaded->GetNamedBoolean(L"boolean"));
280              Assert::AreEqual(std::wstring(L"world"), std::wstring(loaded->GetNamedObject(L"object").GetNamedString(L"inner")));
281          }
282      };
283  }