Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6477abf

Browse files
committed
Added XPath support for column exclusion in cursor.
Added support for attribute exclusion in object/collection (Xpath/names CSV string/names list)
1 parent 625232c commit 6477abf

22 files changed

Lines changed: 290 additions & 132 deletions

source/core/ut_utils.pkb

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,5 +328,33 @@ create or replace package body ut_utils is
328328
end if;
329329
end;
330330

331+
function to_xpath(a_list varchar2) return varchar2 is
332+
l_xpath varchar2(32767) := a_list;
333+
begin
334+
if l_xpath not like '/%' then
335+
l_xpath := '//'||replace(l_xpath,',','|//');
336+
end if;
337+
return l_xpath;
338+
end;
339+
340+
function to_xpath(a_list ut_varchar2_list) return varchar2 is
341+
l_xpath varchar2(32767);
342+
i integer;
343+
begin
344+
i := a_list.first;
345+
while i is not null loop
346+
if a_list(i) is not null then
347+
if a_list(i) not like '/%' then
348+
l_xpath := l_xpath || '//'||a_list(i)||'|';
349+
else
350+
l_xpath := l_xpath ||a_list(i)||'|';
351+
end if;
352+
end if;
353+
i := a_list.next(i);
354+
end loop;
355+
l_xpath := rtrim(l_xpath,',|');
356+
return l_xpath;
357+
end;
358+
331359
end ut_utils;
332-
/
360+
/

source/core/ut_utils.pks

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ create or replace package ut_utils authid definer is
177177
ut_varchar2_list - table of string
178178

179179
Splits a given string into table of string by delimiter.
180-
Default value of a_max_amount is 8191 because of code can contains multibyte character.
180+
Default value of a_max_amount is 8191 because of code can contains multibyte character.
181181
The delimiter gets removed.
182182
If null passed as any of the parameters, empty table is returned.
183183
If split text is longer than a_max_amount it gets split into pieces of a_max_amount.
@@ -212,5 +212,9 @@ create or replace package ut_utils authid definer is
212212
procedure append_to_clob(a_src_clob in out nocopy clob, a_new_data clob);
213213
procedure append_to_clob(a_src_clob in out nocopy clob, a_new_data varchar2);
214214

215+
function to_xpath(a_list varchar2) return varchar2;
216+
217+
function to_xpath(a_list ut_varchar2_list) return varchar2;
218+
215219
end ut_utils;
216220
/

source/expectations/data_values/ut_data_value_anydata.tpb

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,55 @@ create or replace type body ut_data_value_anydata as
2929
end;
3030

3131
overriding member function to_string return varchar2 is
32+
l_result varchar2(32767);
33+
l_clob clob;
3234
begin
33-
return ut_utils.to_string( to_char(null) );
35+
if self.is_null() then
36+
l_result := ut_utils.to_string( to_char(null) );
37+
else
38+
ut_expectation_processor.set_xml_nls_params();
39+
select xmlserialize(content xmltype(self.data_value) indent) into l_clob from dual;
40+
l_result := ut_utils.to_string( l_clob, null );
41+
ut_expectation_processor.reset_nls_params();
42+
end if;
43+
return self.format_multi_line( l_result );
3444
end;
3545

36-
overriding member function compare_implementation( a_other ut_data_value ) return integer is
46+
overriding member function compare_implementation(a_other ut_data_value) return integer is
47+
l_self_data xmltype;
48+
l_other_data xmltype;
49+
l_other ut_data_value_anydata;
50+
l_result integer;
51+
procedure exclude_xpaths(a_xml in out nocopy xmltype, a_xpath varchar2) is
52+
begin
53+
select case when a_xpath is not null then deletexml( a_xml, a_xpath ) else a_xml end into a_xml from dual;
54+
end;
3755
begin
38-
return null;
56+
if a_other is of (ut_data_value_anydata) then
57+
l_other := treat(a_other as ut_data_value_anydata);
58+
--needed for 11g xe as it fails on constructing XMLTYPE from null ANYDATA
59+
if not self.is_null() and not l_other.is_null() then
60+
ut_expectation_processor.set_xml_nls_params();
61+
l_self_data := xmltype.createxml(self.data_value);
62+
l_other_data := xmltype.createxml(l_other.data_value);
63+
exclude_xpaths(l_self_data, coalesce(self.exclude_xpath, l_other.exclude_xpath));
64+
exclude_xpaths(l_other_data, coalesce(self.exclude_xpath, l_other.exclude_xpath));
65+
ut_expectation_processor.reset_nls_params();
66+
if l_self_data is not null and l_other_data is not null then
67+
l_result := dbms_lob.compare( l_self_data.getclobval(), l_other_data.getclobval() );
68+
end if;
69+
end if;
70+
else
71+
raise value_error;
72+
end if;
73+
return l_result;
74+
end;
75+
76+
final member procedure init(self in out nocopy ut_data_value_anydata, a_value anydata, a_self_type varchar2) is
77+
begin
78+
self.data_value := a_value;
79+
self.self_type := a_self_type;
80+
self.data_type := case when a_value is not null then lower(a_value.gettypename) else 'undefined' end;
3981
end;
4082

4183
static function get_instance(a_data_value anydata) return ut_data_value_anydata is
@@ -56,5 +98,21 @@ create or replace type body ut_data_value_anydata as
5698
return l_result;
5799
end;
58100

101+
static function get_instance(a_data_value anydata, a_exclude varchar2) return ut_data_value_anydata is
102+
l_result ut_data_value_anydata := ut_data_value_anydata();
103+
begin
104+
l_result := ut_data_value_anydata.get_instance(a_data_value);
105+
l_result.exclude_xpath := ut_utils.to_xpath(a_exclude);
106+
return l_result;
107+
end;
108+
109+
static function get_instance(a_data_value anydata, a_exclude ut_varchar2_list) return ut_data_value_anydata is
110+
l_result ut_data_value_anydata := ut_data_value_anydata();
111+
begin
112+
l_result := ut_data_value_anydata.get_instance(a_data_value);
113+
l_result.exclude_xpath := ut_utils.to_xpath(a_exclude);
114+
return l_result;
115+
end;
116+
59117
end;
60118
/

source/expectations/data_values/ut_data_value_anydata.tps

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,18 @@ create or replace type ut_data_value_anydata under ut_data_value(
1616
limitations under the License.
1717
*/
1818
data_value anydata,
19+
/*
20+
var: exclude_xpath
21+
Holds xpath (list of columns) to exclude when comparing cursor
22+
*/
23+
exclude_xpath varchar2(32767),
1924
constructor function ut_data_value_anydata(self in out nocopy ut_data_value_anydata) return self as result,
2025
overriding member function is_null return boolean,
2126
overriding member function to_string return varchar2,
2227
overriding member function compare_implementation( a_other ut_data_value ) return integer,
23-
static function get_instance(a_data_value anydata) return ut_data_value_anydata
28+
final member procedure init(self in out nocopy ut_data_value_anydata, a_value anydata, a_self_type varchar2),
29+
static function get_instance(a_data_value anydata) return ut_data_value_anydata,
30+
static function get_instance(a_data_value anydata, a_exclude varchar2) return ut_data_value_anydata,
31+
static function get_instance(a_data_value anydata, a_exclude ut_varchar2_list) return ut_data_value_anydata
2432
) not final
2533
/

source/expectations/data_values/ut_data_value_collection.tpb

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ create or replace type body ut_data_value_collection as
1818

1919
constructor function ut_data_value_collection(self in out nocopy ut_data_value_collection, a_value anydata) return self as result is
2020
begin
21-
self.data_value := a_value;
22-
self.self_type := $$plsql_unit;
23-
self.data_type := case when a_value is not null then lower(a_value.gettypename) else 'undefined' end;
21+
self.init(a_value, $$plsql_unit);
2422
return;
2523
end;
2624

@@ -74,45 +72,6 @@ create or replace type body ut_data_value_collection as
7472
end if;
7573
end;
7674

77-
overriding member function to_string return varchar2 is
78-
l_result varchar2(32767);
79-
l_clob clob;
80-
begin
81-
if self.is_null() then
82-
l_result := ut_utils.to_string( to_char(null) );
83-
else
84-
ut_expectation_processor.set_xml_nls_params();
85-
select xmlserialize(content xmltype(self.data_value) indent) into l_clob from dual;
86-
l_result := ut_utils.to_string( l_clob, null );
87-
ut_expectation_processor.reset_nls_params();
88-
end if;
89-
return self.format_multi_line( l_result );
90-
end;
91-
92-
overriding member function compare_implementation(a_other ut_data_value) return integer is
93-
l_self_data xmltype;
94-
l_other_data xmltype;
95-
l_other ut_data_value_collection;
96-
l_result integer;
97-
begin
98-
if a_other is of (ut_data_value_collection) then
99-
l_other := treat(a_other as ut_data_value_collection);
100-
--needed for 11g xe as it fails on constructing XMLTYPE from null ANYDATA
101-
if not self.is_null() and not l_other.is_null() then
102-
ut_expectation_processor.set_xml_nls_params();
103-
l_self_data := xmltype.createxml(self.data_value);
104-
l_other_data := xmltype.createxml(l_other.data_value);
105-
ut_expectation_processor.reset_nls_params();
106-
if l_self_data is not null and l_other_data is not null then
107-
l_result := dbms_lob.compare( l_self_data.getclobval(), l_other_data.getclobval() );
108-
end if;
109-
end if;
110-
else
111-
raise value_error;
112-
end if;
113-
return l_result;
114-
end;
115-
11675
overriding member function is_multi_line return boolean is
11776
begin
11877
return not self.is_null();

source/expectations/data_values/ut_data_value_collection.tps

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ create or replace type ut_data_value_collection under ut_data_value_anydata(
1818
constructor function ut_data_value_collection(self in out nocopy ut_data_value_collection, a_value anydata) return self as result,
1919
overriding member function is_null return boolean,
2020
member function is_empty return boolean,
21-
overriding member function to_string return varchar2,
22-
overriding member function is_multi_line return boolean,
23-
overriding member function compare_implementation(a_other ut_data_value) return integer
21+
overriding member function is_multi_line return boolean
2422
)
2523
/

source/expectations/data_values/ut_data_value_object.tpb

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ create or replace type body ut_data_value_object as
1818

1919
constructor function ut_data_value_object(self in out nocopy ut_data_value_object, a_value anydata) return self as result is
2020
begin
21-
self.data_value := a_value;
22-
self.self_type := $$plsql_unit;
23-
self.data_type := case when a_value is not null then lower(a_value.gettypename) else 'undefined' end;
21+
self.init(a_value, $$plsql_unit);
2422
return;
2523
end;
2624

@@ -64,45 +62,6 @@ create or replace type body ut_data_value_object as
6462
return l_is_null;
6563
end;
6664

67-
overriding member function to_string return varchar2 is
68-
l_result varchar2(32767);
69-
l_clob clob;
70-
begin
71-
if self.is_null() then
72-
l_result := ut_utils.to_string( to_char(null) );
73-
else
74-
ut_expectation_processor.set_xml_nls_params();
75-
select xmlserialize(content xmltype(self.data_value) indent) into l_clob from dual;
76-
l_result := ut_utils.to_string( l_clob, null );
77-
ut_expectation_processor.reset_nls_params();
78-
end if;
79-
return self.format_multi_line( l_result );
80-
end;
81-
82-
overriding member function compare_implementation(a_other ut_data_value) return integer is
83-
l_self_data xmltype;
84-
l_other_data xmltype;
85-
l_other ut_data_value_object;
86-
l_result integer;
87-
begin
88-
if a_other is of (ut_data_value_object) then
89-
l_other := treat(a_other as ut_data_value_object);
90-
--needed for 11g xe as it fails on constructing XMLTYPE from null ANYDATA
91-
if not self.is_null() and not l_other.is_null() then
92-
ut_expectation_processor.set_xml_nls_params();
93-
l_self_data := xmltype.createxml(self.data_value);
94-
l_other_data := xmltype.createxml(l_other.data_value);
95-
ut_expectation_processor.reset_nls_params();
96-
if l_self_data is not null and l_other_data is not null then
97-
l_result := dbms_lob.compare( l_self_data.getclobval(), l_other_data.getclobval() );
98-
end if;
99-
end if;
100-
else
101-
raise value_error;
102-
end if;
103-
return l_result;
104-
end;
105-
10665
overriding member function is_multi_line return boolean is
10766
begin
10867
return not self.is_null();

source/expectations/data_values/ut_data_value_object.tps

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ create or replace type ut_data_value_object under ut_data_value_anydata(
1717
*/
1818
constructor function ut_data_value_object(self in out nocopy ut_data_value_object, a_value anydata) return self as result,
1919
overriding member function is_null return boolean,
20-
overriding member function to_string return varchar2,
21-
overriding member function is_multi_line return boolean,
22-
overriding member function compare_implementation(a_other ut_data_value) return integer
20+
overriding member function is_multi_line return boolean
2321
)
2422
/

source/expectations/data_values/ut_data_value_refcursor.tpb

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,14 @@ create or replace type body ut_data_value_refcursor as
2424

2525
constructor function ut_data_value_refcursor(self in out nocopy ut_data_value_refcursor, a_value sys_refcursor, a_exclude varchar2 ) return self as result is
2626
begin
27-
if a_exclude is not null then
28-
self.exclude_xpath := '//'||replace(a_exclude,',','|//');
29-
end if;
27+
self.exclude_xpath := ut_utils.to_xpath(a_exclude);
3028
init(a_value);
3129
return;
3230
end;
3331

3432
constructor function ut_data_value_refcursor(self in out nocopy ut_data_value_refcursor, a_value sys_refcursor, a_exclude ut_varchar2_list ) return self as result is
35-
i integer;
3633
begin
37-
i := a_exclude.first;
38-
while i is not null loop
39-
if a_exclude(i) is not null then
40-
self.exclude_xpath := self.exclude_xpath || '//'||a_exclude(i)||'|';
41-
end if;
42-
i := a_exclude.next(i);
43-
end loop;
44-
self.exclude_xpath := rtrim(self.exclude_xpath,',|');
34+
self.exclude_xpath := ut_utils.to_xpath(a_exclude);
4535
init(a_value);
4636
return;
4737
end;
@@ -146,15 +136,17 @@ create or replace type body ut_data_value_refcursor as
146136
overriding member function compare_implementation(a_other ut_data_value) return integer is
147137
l_result integer;
148138
l_other ut_data_value_refcursor;
139+
l_xpath varchar2(32767);
149140
begin
141+
l_xpath := coalesce(self.exclude_xpath, l_other.exclude_xpath);
150142
if a_other is of (ut_data_value_refcursor) then
151143
l_other := treat(a_other as ut_data_value_refcursor);
152144
select count(1)
153145
into l_result
154-
from (select case when coalesce(self.exclude_xpath, l_other.exclude_xpath) is not null then deletexml( ucd.row_data, coalesce(self.exclude_xpath, l_other.exclude_xpath) ) else ucd.row_data end as row_data,
146+
from (select case when l_xpath is not null then deletexml( ucd.row_data, l_xpath ) else ucd.row_data end as row_data,
155147
ucd.row_no
156148
from ut_cursor_data ucd where ucd.cursor_data_guid = self.data_value) exp
157-
full outer join (select case when coalesce(self.exclude_xpath, l_other.exclude_xpath) is not null then deletexml( ucd.row_data, coalesce(self.exclude_xpath, l_other.exclude_xpath) ) else ucd.row_data end as row_data,
149+
full outer join (select case when l_xpath is not null then deletexml( ucd.row_data, l_xpath ) else ucd.row_data end as row_data,
158150
ucd.row_no
159151
from ut_cursor_data ucd where ucd.cursor_data_guid = l_other.data_value) act
160152
on (exp.row_no = act.row_no)

source/expectations/matchers/ut_equal.tpb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,14 @@ create or replace type body ut_equal as
2929
return ( a_assert_result or ( self.expected.is_null() and a_actual.is_null() and ut_utils.int_to_boolean( nulls_are_equal_flag ) ) );
3030
end;
3131

32-
constructor function ut_equal(self in out nocopy ut_equal, a_expected anydata, a_nulls_are_equal boolean := null) return self as result is
32+
constructor function ut_equal(self in out nocopy ut_equal, a_expected anydata, a_exclude varchar2 := null, a_nulls_are_equal boolean := null) return self as result is
3333
begin
34-
init(ut_data_value_anydata.get_instance(a_expected), a_nulls_are_equal);
34+
init(ut_data_value_anydata.get_instance(a_expected, a_exclude), a_nulls_are_equal);
35+
return;
36+
end;
37+
constructor function ut_equal(self in out nocopy ut_equal, a_expected anydata, a_exclude ut_varchar2_list, a_nulls_are_equal boolean := null) return self as result is
38+
begin
39+
init(ut_data_value_anydata.get_instance(a_expected, a_exclude), a_nulls_are_equal);
3540
return;
3641
end;
3742

0 commit comments

Comments
 (0)