Skip to content

Commit

Permalink
Merge 6dd2026 into c6c3af5
Browse files Browse the repository at this point in the history
  • Loading branch information
lwasylow committed Jun 15, 2019
2 parents c6c3af5 + 6dd2026 commit 11b6913
Show file tree
Hide file tree
Showing 33 changed files with 2,834 additions and 33 deletions.
2 changes: 1 addition & 1 deletion development/cleanup.sh
Expand Up @@ -3,7 +3,7 @@
#goto git root directory
git rev-parse && cd "$(git rev-parse --show-cdup)"

. development/env.sh
#. development/env.sh

"${SQLCLI}" sys/${ORACLE_PWD}@//${CONNECTION_STR} AS SYSDBA <<-SQL
set echo on
Expand Down
2 changes: 1 addition & 1 deletion development/install.sh
Expand Up @@ -3,7 +3,7 @@
#goto git root directory
git rev-parse && cd "$(git rev-parse --show-cdup)"

. development/env.sh
#. development/env.sh

header="******************************************************************************************"
if ! development/cleanup.sh; then
Expand Down
5 changes: 4 additions & 1 deletion docs/userguide/advanced_data_comparison.md
Expand Up @@ -7,10 +7,11 @@ utPLSQL expectations incorporates advanced data comparison options when comparin
- refcursor
- object type
- nested table and varray
- json data-types

Advanced data-comparison options are available for the [`equal`](expectations.md#equal) and [`contain`](expectations.md#include--contain) matcher.

## Syntax
Syntax

```
ut.expect( a_actual {data-type} ).to_( equal( a_expected {data-type})[.extendend_option()[.extendend_option()[...]]]);
Expand Down Expand Up @@ -503,3 +504,5 @@ Finished in .046193 seconds
1 tests, 0 failed, 0 errored, 0 disabled, 0 warning(s)
```



247 changes: 229 additions & 18 deletions docs/userguide/expectations.md
Expand Up @@ -319,7 +319,7 @@ end;
## have_count
Unary matcher that validates if the provided dataset count is equal to expected value.

Can be used with `refcursor` or `table type`
Can be used with `refcursor` , `json`or `table type`

Usage:
```sql
Expand Down Expand Up @@ -1177,7 +1177,218 @@ Finished in .048181 seconds
```



# Comparing Json objects

utPLSQL is capable of comparing json data-types on Oracle 12.2 and above.

### Notes on comparison of json data

- Json data can contain objects, scalar or arrays.
- During comparison of json objects the order doesn't matter.
- During comparison of json arrays the index of element is taken into account
- To compare json you have to make sure its type of `json_element_t` or its subtypes



Some examples of using json data-types in matcher are :

```sql
create or replace package test_expectations_json is

--%suite(json expectations)

--%test(Gives success for identical data)
procedure success_on_same_data;
end;
/

create or replace package body test_expectations_json is

procedure success_on_same_data is
l_expected json_element_t;
l_actual json_element_t;
begin
-- Arrange
l_expected := json_element_t.parse('
{
"Actors":[
{
"name":"Tom Cruise",
"age":56,
"Born At":"Syracuse, NY",
"Birthdate":"July 3, 1962",
"photo":"https://jsonformatter.org/img/tom-cruise.jpg",
"wife":null,
"weight":67.5,
"hasChildren":true,
"hasGreyHair":false,
"children":[
"Suri",
"Isabella Jane",
"Connor"
]
},
{
"name":"Robert Downey Jr.",
"age":53,
"Born At":"New York City, NY",
"Birthdate":"April 4, 1965",
"photo":"https://jsonformatter.org/img/Robert-Downey-Jr.jpg",
"wife":"Susan Downey",
"weight":77.1,
"hasChildren":true,
"hasGreyHair":false,
"children":[
"Indio Falconer",
"Avri Roel",
"Exton Elias"
]
}
]
}');

l_actual := json_element_t.parse('
{
"Actors":[
{
"name":"Tom Cruise",
"age":56,
"Born At":"Syracuse, NY",
"Birthdate":"July 3, 1962",
"photo":"https://jsonformatter.org/img/tom-cruise.jpg",
"wife":null,
"weight":67.5,
"hasChildren":true,
"hasGreyHair":false,
"children":[
"Suri",
"Isabella Jane",
"Connor"
]
},
{
"name":"Robert Downey Jr.",
"age":53,
"Born At":"New York City, NY",
"Birthdate":"April 4, 1965",
"photo":"https://jsonformatter.org/img/Robert-Downey-Jr.jpg",
"wife":"Susan Downey",
"weight":77.1,
"hasChildren":true,
"hasGreyHair":false,
"children":[
"Indio Falconer",
"Avri Roel",
"Exton Elias"
]
}
]
}');

ut3.ut.expect( l_actual ).to_equal( l_actual );

end;
end;
/
```

It is possible to use a PL/SQL to extract a piece of JSON and compare it as follow

```sql
create or replace package test_expectations_json is

--%suite(json expectations)

--%test(Gives success for identical pieces of two different jsons)
procedure to_diff_json_extract_same;

end;
/

create or replace package body test_expectations_json is

procedure to_diff_json_extract_same as
l_expected json_object_t;
l_actual json_object_t;
l_array_actual json_array_t;
l_array_expected json_array_t;
begin
-- Arrange
l_expected := json_object_t.parse(' {
"Actors": [
{
"name": "Tom Cruise",
"age": 56,
"Born At": "Syracuse, NY",
"Birthdate": "July 3, 1962",
"photo": "https://jsonformatter.org/img/tom-cruise.jpg",
"wife": null,
"weight": 67.5,
"hasChildren": true,
"hasGreyHair": false,
"children": [
"Suri",
"Isabella Jane",
"Connor"
]
},
{
"name": "Robert Downey Jr.",
"age": 53,
"Born At": "New York City, NY",
"Birthdate": "April 4, 1965",
"photo": "https://jsonformatter.org/img/Robert-Downey-Jr.jpg",
"wife": "Susan Downey",
"weight": 77.1,
"hasChildren": true,
"hasGreyHair": false,
"children": [
"Indio Falconer",
"Avri Roel",
"Exton Elias"
]
}
]
}'
);

l_actual := json_object_t.parse(' {
"Actors":
{
"name": "Krzystof Jarzyna",
"age": 53,
"Born At": "Szczecin",
"Birthdate": "April 4, 1965",
"photo": "niewidzialny",
"wife": "Susan Downey",
"children": [
"Indio Falconer",
"Avri Roel",
"Exton Elias"
]
}
}'
);

l_array_actual := json_array_t(json_query(l_actual.stringify,'$.Actors.children'));
l_array_expected := json_array_t(json_query(l_expected.stringify,'$.Actors[1].children'));
--Act
ut3.ut.expect(l_array_actual).to_equal(l_array_expected);

end;
end;
/
```







# Negating a matcher

Expectations provide a very convenient way to perform a check on a negated matcher.

Syntax to check for matcher evaluating to true:
Expand Down Expand Up @@ -1211,21 +1422,21 @@ Since NULL is neither *true* nor *false*, both expectations will report failure.

The matrix below illustrates the data types supported by different matchers.

| 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 |
| :---------------------- | :--: | :-----: | :--: | :--: | :----: | :-------: | :---------------------------: | :------------------------------------: | :------: | :-----------------------------: | :-----------------------------: | :----: | :-------------------------: | :----: |
| **be_not_null** | X | X | X | X | X | X | X | X | X | X | X | X | X | X |
| **be_null** | X | X | X | X | X | X | X | X | X | X | X | X | X | X |
| **be_false** | | X | | | | | | | | | | | | |
| **be_true** | | X | | | | | | | | | | | | |
| **be_greater_than** | | | | X | X | X | X | X | | X | X | | | |
| **be_greater_or_equal** | | | | X | X | X | X | X | | X | X | | | |
| **be_less_or_equal** | | | | X | X | X | X | X | | X | X | | | |
| **be_less_than** | | | | X | X | X | X | X | | X | X | | | |
| **be_between** | | | | X | X | X | X | X | X | X | X | | | |
| **equal** | X | X | X | X | X | X | X | X | X | X | X | X | X | X |
| **contain** | | | | | | | | | | | | X | X | X |
| **match** | | | X | | | | | | X | | | | | |
| **be_like** | | | X | | | | | | X | | | | | |
| **be_empty** | X | | X | | | | | | | | | X | X | |
| **have_count** | | | | | | | | | | | | X | X | |
| 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 |
| :---------------------: | :--: | :-----: | :--: | :--: | :----: | :-------: | :---------------------------: | :------------------------------------: | :------: | :-----------------------------: | :-----------------------------: | :----: | :-------------------------: | :----: | :--: |
| **be_not_null** | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X |
| **be_null** | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X |
| **be_false** | | X | | | | | | | | | | | | | |
| **be_true** | | X | | | | | | | | | | | | | |
| **be_greater_than** | | | | X | X | X | X | X | | X | X | | | | |
| **be_greater_or_equal** | | | | X | X | X | X | X | | X | X | | | | |
| **be_less_or_equal** | | | | X | X | X | X | X | | X | X | | | | |
| **be_less_than** | | | | X | X | X | X | X | | X | X | | | | |
| **be_between** | | | | X | X | X | X | X | X | X | X | | | | |
| **equal** | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X |
| **contain** | | | | | | | | | | | | X | X | X | |
| **match** | | | X | | | | | | X | | | | | | |
| **be_like** | | | X | | | | | | X | | | | | | |
| **be_empty** | X | | X | | | | | | | | | X | X | | X |
| **have_count** | | | | | | | | | | | | X | X | | X |

5 changes: 5 additions & 0 deletions source/api/ut.pkb
Expand Up @@ -93,6 +93,11 @@ create or replace package body ut is
return ut_expectation(ut_data_value_dsinterval(a_actual), a_message);
end;

function expect(a_actual in json_element_t , a_message varchar2 := null) return ut_expectation_json is
begin
return ut_expectation_json(ut_data_value_json(a_actual), a_message);
end;

procedure fail(a_message in varchar2) is
begin
ut_expectation_processor.report_failure(a_message);
Expand Down
2 changes: 2 additions & 0 deletions source/api/ut.pks
Expand Up @@ -45,6 +45,8 @@ create or replace package ut authid current_user as

function expect(a_actual in dsinterval_unconstrained, a_message varchar2 := null) return ut_expectation;

function expect(a_actual in json_element_t , a_message varchar2 := null) return ut_expectation_json;

procedure fail(a_message in varchar2);

function run(
Expand Down
1 change: 1 addition & 0 deletions source/core/ut_utils.pkb
Expand Up @@ -490,6 +490,7 @@ create or replace package body ut_utils is
begin
execute immediate 'delete from ut_compound_data_tmp';
execute immediate 'delete from ut_compound_data_diff_tmp';
execute immediate 'delete from ut_json_data_diff_tmp';
end;

function to_version(a_version_no varchar2) return t_version is
Expand Down
2 changes: 2 additions & 0 deletions source/create_synonyms_and_grants_for_public.sql
Expand Up @@ -33,6 +33,7 @@ alter session set current_schema = &&ut3_owner;

grant execute on &&ut3_owner..ut_expectation to public;
grant execute on &&ut3_owner..ut_expectation_compound to public;
grant execute on &&ut3_owner..ut_expectation_json to public;
grant execute on &&ut3_owner..ut_be_between to public;
grant execute on &&ut3_owner..ut_be_empty to public;
grant execute on &&ut3_owner..ut_be_false to public;
Expand Down Expand Up @@ -113,6 +114,7 @@ prompt Creating synonyms for UTPLSQL objects in &&ut3_owner schema to PUBLIC

create public synonym ut_expectation for &&ut3_owner..ut_expectation;
create public synonym ut_expectation_compound for &&ut3_owner..ut_expectation_compound;
create public synonym ut_expectation_json for &&ut3_owner..ut_expectation_json;

create public synonym be_between for &&ut3_owner..be_between;
create public synonym be_empty for &&ut3_owner..be_empty;
Expand Down
1 change: 1 addition & 0 deletions source/create_user_grants.sql
Expand Up @@ -53,6 +53,7 @@ alter session set current_schema = &&ut3_owner;

grant execute on &&ut3_owner..ut_expectation to &ut3_user;
grant execute on &&ut3_owner..ut_expectation_compound to &ut3_user;
grant execute on &&ut3_owner..ut_expectation_json to &ut3_user;

grant execute on &&ut3_owner..ut_be_between to &ut3_user;
grant execute on &&ut3_owner..ut_be_empty to &ut3_user;
Expand Down
1 change: 1 addition & 0 deletions source/create_user_synonyms.sql
Expand Up @@ -55,6 +55,7 @@ prompt Creating synonyms for UTPLSQL objects in &&ut3_owner schema to user &&ut3

create or replace synonym &ut3_user..ut_expectation for &&ut3_owner..ut_expectation;
create or replace synonym &ut3_user..ut_expectation_compound for &&ut3_owner..ut_expectation_compound;
create or replace synonym &ut3_user..ut_expectation_json for &&ut3_owner..ut_expectation_json;

create or replace synonym &ut3_user..be_between for &&ut3_owner..be_between;
create or replace synonym &ut3_user..be_empty for &&ut3_owner..be_empty;
Expand Down

0 comments on commit 11b6913

Please sign in to comment.