Skip to content

Add JSON object comparision #924

@lwasylow

Description

@lwasylow

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.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions