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 }