Description
Since JSON is gaining a popularity and since Oracle 12.2 we got a proper support of JSON in database I thought it would b a good idea to implement a JSON comparison matcher.
I've did some initial work for cursor equality and will be adding a more methods. Here is a sample test and results.
create or replace PACKAGE ut_sample_test IS
--%suite(Sample Test Suite)
--%test(Compare Json)
PROCEDURE ut_json;
END ut_sample_test;
/
create or replace PACKAGE BODY ut_sample_test IS
PROCEDURE ut_json IS
l_expected json_element_t;
l_actual json_element_t;
begin
-- Arrange
l_expected := json_element_t.parse('{
"Aidan Gillen": {
"aboolean": true,
"array": [
"Game of Thron\"es",
"The Wire"
],
"boolean": true,
"int": 2,
"object": {
"foo": "bar",
"object1": {
"new prop1": "new prop value"
},
"object2": {
"new prop1": "new prop value"
},
"object3": {
"new prop1": "new prop value"
},
"object4": {
"new prop1": "new prop value"
}
},
"string": "some string"
},
"Alexander Skarsgard": [
"Generation Kill",
"True Blood"
],
"Amy Ryan": {
"one": "In Treatment",
"two": "The Wire"
},
"Annie Fitzgerald": [
"Big Love",
"True Blood"
],
"Anwan Glover": [
"Treme",
"The Wire"
],
"Clarke Peters": null
}');
l_actual := json_element_t.parse('{
"Aidan Gillen": {
"aboolean": "true",
"array": [
"Game of Thrones",
"The Wire"
],
"boolean": false,
"int": "2",
"object": {
"foo": "bar"
},
"otherint": 4,
"string": "some string"
},
"Alexander Skarsg?rd": [
"Generation Kill",
"True Blood"
],
"Alice Farmer": [
"The Corner",
"Oz",
"The Wire"
],
"Amy Ryan": [
"In Treatment",
"The Wire"
],
"Annie Fitzgerald": [
"True Blood",
"Big Love",
"The Sopranos",
"Oz"
],
"Anwan Glover": [
"Treme",
"The Wire"
]
}
');
--Act
ut3.ut.expect( l_actual ).to_equal( l_expected );
END;
END ut_sample_test;
/
Running matcher:
select * from table(ut.run('ut_sample_test'));
gives:
Sample Test Suite
Compare Ref Cursors [.122 sec] (FAILED - 1)
Failures:
Actual: json was expected to equal: json
Diff:
Found: 18 differences
3 incorrect types,4 unequal values,11 missing properties
Extra property 'Alexander Skarsg?rd' on path :$.Alexander Skarsg?rd
Missing property 'Alexander Skarsgard' on path :$.Alexander Skarsgard
Extra property 'Alice Farmer' on path :$.Alice Farmer
Actual type is 'object' was expected to be 'array' on path :$.Amy Ryan
Missing property 'Clarke Peters' on path :$.Clarke Peters
Actual value is 'Big Love' was expected to be 'True Blood' on path :$.Annie Fitzgerald[0]
Actual value is 'True Blood' was expected to be 'Big Love' on path :$.Annie Fitzgerald[1]
Actual type is 'boolean' was expected to be 'string' on path :$.Aidan Gillen.aboolean
Extra property '"The Sopranos"' on path :$.Annie Fitzgerald[2]
Extra property '"Oz"' on path :$.Annie Fitzgerald[3]
Actual value is 'true' was expected to be 'false' on path :$.Aidan Gillen.boolean
Actual type is 'number' was expected to be 'string' on path :$.Aidan Gillen.int
Extra property 'otherint' on path :$.Aidan Gillen.otherint
Actual value is 'Game of Thron"es' was expected to be 'Game of Thrones' on path :$.Aidan Gillen.array[0]
Missing property 'object1' on path :$.Aidan Gillen.object.object1
Missing property 'object2' on path :$.Aidan Gillen.object.object2
Missing property 'object3' on path :$.Aidan Gillen.object.object3
Missing property 'object4' on path :$.Aidan Gillen.object.object4
at "UT3.UT_SAMPLE_TEST.UT_JSON", line 94 ut3.ut.expect( l_actual ).to_equal( l_expected );
Finished in .147073 seconds
1 tests, 1 failed, 0 errored, 0 disabled, 0 warning(s)
I will be adding a more comparison method so far I think about adding
-
have_count(json_path)
*For a scalar, it returns 1.
*For an object, it returns the number of keys.
*For an array, it returns the number of items. -
include(a_json_path)
-
exclude(a_json_path)
-
is_null
-
is_empty
Optionally maybe we could add some option to limit part e.g.
ut.expect(a_json).extractjson(json_path).to_equal(e_json).extractjson(different_json_path)
This is not replacement to include / exclude
because each part can have a different extract paths.
If you have any comments or a good resources with a samples complex json to run through tests would be appreciated.