|
319 | 319 | ## have_count |
320 | 320 | Unary matcher that validates if the provided dataset count is equal to expected value. |
321 | 321 |
|
322 | | -Can be used with `refcursor` or `table type` |
| 322 | +Can be used with `refcursor` , `json`or `table type` |
323 | 323 |
|
324 | 324 | Usage: |
325 | 325 | ```sql |
@@ -1177,7 +1177,218 @@ Finished in .048181 seconds |
1177 | 1177 | ``` |
1178 | 1178 |
|
1179 | 1179 |
|
| 1180 | + |
| 1181 | +# Comparing Json objects |
| 1182 | + |
| 1183 | +utPLSQL is capable of comparing json data-types on Oracle 12.2 and above. |
| 1184 | + |
| 1185 | +### Notes on comparison of json data |
| 1186 | + |
| 1187 | +- Json data can contain objects, scalar or arrays. |
| 1188 | +- During comparison of json objects the order doesn't matter. |
| 1189 | +- During comparison of json arrays the index of element is taken into account |
| 1190 | +- To compare json you have to make sure its type of `json_element_t` or its subtypes |
| 1191 | + |
| 1192 | + |
| 1193 | + |
| 1194 | +Some examples of using json data-types in matcher are : |
| 1195 | + |
| 1196 | +```sql |
| 1197 | +create or replace package test_expectations_json is |
| 1198 | + |
| 1199 | + --%suite(json expectations) |
| 1200 | + |
| 1201 | + --%test(Gives success for identical data) |
| 1202 | + procedure success_on_same_data; |
| 1203 | +end; |
| 1204 | +/ |
| 1205 | + |
| 1206 | +create or replace package body test_expectations_json is |
| 1207 | + |
| 1208 | + procedure success_on_same_data is |
| 1209 | + l_expected json_element_t; |
| 1210 | + l_actual json_element_t; |
| 1211 | + begin |
| 1212 | + -- Arrange |
| 1213 | + l_expected := json_element_t.parse(' |
| 1214 | +{ |
| 1215 | + "Actors":[ |
| 1216 | + { |
| 1217 | + "name":"Tom Cruise", |
| 1218 | + "age":56, |
| 1219 | + "Born At":"Syracuse, NY", |
| 1220 | + "Birthdate":"July 3, 1962", |
| 1221 | + "photo":"https://jsonformatter.org/img/tom-cruise.jpg", |
| 1222 | + "wife":null, |
| 1223 | + "weight":67.5, |
| 1224 | + "hasChildren":true, |
| 1225 | + "hasGreyHair":false, |
| 1226 | + "children":[ |
| 1227 | + "Suri", |
| 1228 | + "Isabella Jane", |
| 1229 | + "Connor" |
| 1230 | + ] |
| 1231 | + }, |
| 1232 | + { |
| 1233 | + "name":"Robert Downey Jr.", |
| 1234 | + "age":53, |
| 1235 | + "Born At":"New York City, NY", |
| 1236 | + "Birthdate":"April 4, 1965", |
| 1237 | + "photo":"https://jsonformatter.org/img/Robert-Downey-Jr.jpg", |
| 1238 | + "wife":"Susan Downey", |
| 1239 | + "weight":77.1, |
| 1240 | + "hasChildren":true, |
| 1241 | + "hasGreyHair":false, |
| 1242 | + "children":[ |
| 1243 | + "Indio Falconer", |
| 1244 | + "Avri Roel", |
| 1245 | + "Exton Elias" |
| 1246 | + ] |
| 1247 | + } |
| 1248 | + ] |
| 1249 | +}'); |
| 1250 | + |
| 1251 | + l_actual := json_element_t.parse(' |
| 1252 | +{ |
| 1253 | + "Actors":[ |
| 1254 | + { |
| 1255 | + "name":"Tom Cruise", |
| 1256 | + "age":56, |
| 1257 | + "Born At":"Syracuse, NY", |
| 1258 | + "Birthdate":"July 3, 1962", |
| 1259 | + "photo":"https://jsonformatter.org/img/tom-cruise.jpg", |
| 1260 | + "wife":null, |
| 1261 | + "weight":67.5, |
| 1262 | + "hasChildren":true, |
| 1263 | + "hasGreyHair":false, |
| 1264 | + "children":[ |
| 1265 | + "Suri", |
| 1266 | + "Isabella Jane", |
| 1267 | + "Connor" |
| 1268 | + ] |
| 1269 | + }, |
| 1270 | + { |
| 1271 | + "name":"Robert Downey Jr.", |
| 1272 | + "age":53, |
| 1273 | + "Born At":"New York City, NY", |
| 1274 | + "Birthdate":"April 4, 1965", |
| 1275 | + "photo":"https://jsonformatter.org/img/Robert-Downey-Jr.jpg", |
| 1276 | + "wife":"Susan Downey", |
| 1277 | + "weight":77.1, |
| 1278 | + "hasChildren":true, |
| 1279 | + "hasGreyHair":false, |
| 1280 | + "children":[ |
| 1281 | + "Indio Falconer", |
| 1282 | + "Avri Roel", |
| 1283 | + "Exton Elias" |
| 1284 | + ] |
| 1285 | + } |
| 1286 | + ] |
| 1287 | +}'); |
| 1288 | + |
| 1289 | + ut3.ut.expect( l_actual ).to_equal( l_actual ); |
| 1290 | + |
| 1291 | + end; |
| 1292 | +end; |
| 1293 | +/ |
| 1294 | +``` |
| 1295 | + |
| 1296 | +It is possible to use a PL/SQL to extract a piece of JSON and compare it as follow |
| 1297 | + |
| 1298 | +```sql |
| 1299 | +create or replace package test_expectations_json is |
| 1300 | + |
| 1301 | + --%suite(json expectations) |
| 1302 | + |
| 1303 | + --%test(Gives success for identical pieces of two different jsons) |
| 1304 | + procedure to_diff_json_extract_same; |
| 1305 | + |
| 1306 | +end; |
| 1307 | +/ |
| 1308 | + |
| 1309 | +create or replace package body test_expectations_json is |
| 1310 | + |
| 1311 | + procedure to_diff_json_extract_same as |
| 1312 | + l_expected json_object_t; |
| 1313 | + l_actual json_object_t; |
| 1314 | + l_array_actual json_array_t; |
| 1315 | + l_array_expected json_array_t; |
| 1316 | + begin |
| 1317 | + -- Arrange |
| 1318 | + l_expected := json_object_t.parse(' { |
| 1319 | + "Actors": [ |
| 1320 | + { |
| 1321 | + "name": "Tom Cruise", |
| 1322 | + "age": 56, |
| 1323 | + "Born At": "Syracuse, NY", |
| 1324 | + "Birthdate": "July 3, 1962", |
| 1325 | + "photo": "https://jsonformatter.org/img/tom-cruise.jpg", |
| 1326 | + "wife": null, |
| 1327 | + "weight": 67.5, |
| 1328 | + "hasChildren": true, |
| 1329 | + "hasGreyHair": false, |
| 1330 | + "children": [ |
| 1331 | + "Suri", |
| 1332 | + "Isabella Jane", |
| 1333 | + "Connor" |
| 1334 | + ] |
| 1335 | + }, |
| 1336 | + { |
| 1337 | + "name": "Robert Downey Jr.", |
| 1338 | + "age": 53, |
| 1339 | + "Born At": "New York City, NY", |
| 1340 | + "Birthdate": "April 4, 1965", |
| 1341 | + "photo": "https://jsonformatter.org/img/Robert-Downey-Jr.jpg", |
| 1342 | + "wife": "Susan Downey", |
| 1343 | + "weight": 77.1, |
| 1344 | + "hasChildren": true, |
| 1345 | + "hasGreyHair": false, |
| 1346 | + "children": [ |
| 1347 | + "Indio Falconer", |
| 1348 | + "Avri Roel", |
| 1349 | + "Exton Elias" |
| 1350 | + ] |
| 1351 | + } |
| 1352 | + ] |
| 1353 | + }' |
| 1354 | + ); |
| 1355 | + |
| 1356 | + l_actual := json_object_t.parse(' { |
| 1357 | + "Actors": |
| 1358 | + { |
| 1359 | + "name": "Krzystof Jarzyna", |
| 1360 | + "age": 53, |
| 1361 | + "Born At": "Szczecin", |
| 1362 | + "Birthdate": "April 4, 1965", |
| 1363 | + "photo": "niewidzialny", |
| 1364 | + "wife": "Susan Downey", |
| 1365 | + "children": [ |
| 1366 | + "Indio Falconer", |
| 1367 | + "Avri Roel", |
| 1368 | + "Exton Elias" |
| 1369 | + ] |
| 1370 | + } |
| 1371 | + }' |
| 1372 | + ); |
| 1373 | + |
| 1374 | + l_array_actual := json_array_t(json_query(l_actual.stringify,'$.Actors.children')); |
| 1375 | + l_array_expected := json_array_t(json_query(l_expected.stringify,'$.Actors[1].children')); |
| 1376 | + --Act |
| 1377 | + ut3.ut.expect(l_array_actual).to_equal(l_array_expected); |
| 1378 | + |
| 1379 | + end; |
| 1380 | +end; |
| 1381 | +/ |
| 1382 | +``` |
| 1383 | + |
| 1384 | + |
| 1385 | + |
| 1386 | + |
| 1387 | + |
| 1388 | + |
| 1389 | + |
1180 | 1390 | # Negating a matcher |
| 1391 | + |
1181 | 1392 | Expectations provide a very convenient way to perform a check on a negated matcher. |
1182 | 1393 |
|
1183 | 1394 | Syntax to check for matcher evaluating to true: |
@@ -1211,21 +1422,21 @@ Since NULL is neither *true* nor *false*, both expectations will report failure. |
1211 | 1422 |
|
1212 | 1423 | The matrix below illustrates the data types supported by different matchers. |
1213 | 1424 |
|
1214 | | -| Matcher | blob | boolean | clob | date | number | timestamp | timestamp<br>with<br>timezone | timestamp<br>with<br>local<br>timezone | varchar2 | interval<br>year<br>to<br>month | interval<br>day<br>to<br>second | cursor | nested<br>table<br>/ varray | object | |
1215 | | -| :---------------------- | :--: | :-----: | :--: | :--: | :----: | :-------: | :---------------------------: | :------------------------------------: | :------: | :-----------------------------: | :-----------------------------: | :----: | :-------------------------: | :----: | |
1216 | | -| **be_not_null** | X | X | X | X | X | X | X | X | X | X | X | X | X | X | |
1217 | | -| **be_null** | X | X | X | X | X | X | X | X | X | X | X | X | X | X | |
1218 | | -| **be_false** | | X | | | | | | | | | | | | | |
1219 | | -| **be_true** | | X | | | | | | | | | | | | | |
1220 | | -| **be_greater_than** | | | | X | X | X | X | X | | X | X | | | | |
1221 | | -| **be_greater_or_equal** | | | | X | X | X | X | X | | X | X | | | | |
1222 | | -| **be_less_or_equal** | | | | X | X | X | X | X | | X | X | | | | |
1223 | | -| **be_less_than** | | | | X | X | X | X | X | | X | X | | | | |
1224 | | -| **be_between** | | | | X | X | X | X | X | X | X | X | | | | |
1225 | | -| **equal** | X | X | X | X | X | X | X | X | X | X | X | X | X | X | |
1226 | | -| **contain** | | | | | | | | | | | | X | X | X | |
1227 | | -| **match** | | | X | | | | | | X | | | | | | |
1228 | | -| **be_like** | | | X | | | | | | X | | | | | | |
1229 | | -| **be_empty** | X | | X | | | | | | | | | X | X | | |
1230 | | -| **have_count** | | | | | | | | | | | | X | X | | |
| 1425 | +| Matcher | blob | boolean | clob | date | number | timestamp | timestamp<br>with<br>timezone | timestamp<br>with<br>local<br>timezone | varchar2 | interval<br>year<br>to<br>month | interval<br>day<br>to<br>second | cursor | nested<br>table<br>/ varray | object | json | |
| 1426 | +| :---------------------: | :--: | :-----: | :--: | :--: | :----: | :-------: | :---------------------------: | :------------------------------------: | :------: | :-----------------------------: | :-----------------------------: | :----: | :-------------------------: | :----: | :--: | |
| 1427 | +| **be_not_null** | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | |
| 1428 | +| **be_null** | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | |
| 1429 | +| **be_false** | | X | | | | | | | | | | | | | | |
| 1430 | +| **be_true** | | X | | | | | | | | | | | | | | |
| 1431 | +| **be_greater_than** | | | | X | X | X | X | X | | X | X | | | | | |
| 1432 | +| **be_greater_or_equal** | | | | X | X | X | X | X | | X | X | | | | | |
| 1433 | +| **be_less_or_equal** | | | | X | X | X | X | X | | X | X | | | | | |
| 1434 | +| **be_less_than** | | | | X | X | X | X | X | | X | X | | | | | |
| 1435 | +| **be_between** | | | | X | X | X | X | X | X | X | X | | | | | |
| 1436 | +| **equal** | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | |
| 1437 | +| **contain** | | | | | | | | | | | | X | X | X | | |
| 1438 | +| **match** | | | X | | | | | | X | | | | | | | |
| 1439 | +| **be_like** | | | X | | | | | | X | | | | | | | |
| 1440 | +| **be_empty** | X | | X | | | | | | | | | X | X | | X | |
| 1441 | +| **have_count** | | | | | | | | | | | | X | X | | X | |
1231 | 1442 |
|
0 commit comments