Skip to content

Add JSON object comparision #924

Closed
Closed
@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

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions