diff --git a/docs/userguide/expectations.md b/docs/userguide/expectations.md index f17c2fefe..ae1adc7a6 100644 --- a/docs/userguide/expectations.md +++ b/docs/userguide/expectations.md @@ -27,6 +27,7 @@ Matcher is defining the comparison operation to be performed on expected and act - `be_greater_or_equal` - `be_false` - `be_between` +- `be_empty` ## match Allows regexp_like validations to be executed against the following datatypes: diff --git a/source/api/be_empty.syn b/source/api/be_empty.syn new file mode 100644 index 000000000..a8e28de6e --- /dev/null +++ b/source/api/be_empty.syn @@ -0,0 +1 @@ +create synonym be_empty for ut_be_empty; diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql index e06f25272..15750dc9b 100644 --- a/source/create_synonyms_and_grants_for_public.sql +++ b/source/create_synonyms_and_grants_for_public.sql @@ -28,6 +28,7 @@ alter session set current_schema = &&ut3_owner; prompt Granting privileges on UTPLSQL objects in &&ut3_owner schema to PUBLIC grant execute on ut_be_between to public; +grant execute on ut_be_empty to public; grant execute on ut_be_false to public; grant execute on ut_be_greater_or_equal to public; grant execute on ut_be_greater_than to public; @@ -51,6 +52,7 @@ grant execute on ut_reporter_base to public; prompt Creating synonyms for UTPLSQL objects in &&ut3_owner schema to PUBLIC create public synonym be_between for ut_be_between; +create public synonym be_empty for ut_be_empty; create public synonym be_false for ut_be_false; create public synonym be_greater_or_equal for ut_be_greater_or_equal; create public synonym be_greater_than for ut_be_greater_than; diff --git a/source/create_synonyms_and_grants_for_user.sql b/source/create_synonyms_and_grants_for_user.sql index 7b2514329..be4dc4f54 100644 --- a/source/create_synonyms_and_grants_for_user.sql +++ b/source/create_synonyms_and_grants_for_user.sql @@ -29,6 +29,7 @@ prompt Granting privileges on UTPLSQL objects in &&ut3_owner schema to user &&ut alter session set current_schema = &&ut3_owner; grant execute on ut_be_between to &ut3_user; +grant execute on ut_be_empty to &ut3_user; grant execute on ut_be_false to &ut3_user; grant execute on ut_be_greater_or_equal to &ut3_user; grant execute on ut_be_greater_than to &ut3_user; @@ -52,6 +53,7 @@ grant execute on ut_reporter_base to &ut3_user; prompt Creating synonyms for UTPLSQL objects in &&ut3_owner schema to user &&ut3_user create or replace synonym &ut3_user .be_between for be_between; +create or replace synonym &ut3_user .be_empty for be_empty; create or replace synonym &ut3_user .be_false for be_false; create or replace synonym &ut3_user .be_greater_or_equal for be_greater_or_equal; create or replace synonym &ut3_user .be_greater_than for be_greater_than; diff --git a/source/expectations/data_values/ut_data_value_refcursor.tpb b/source/expectations/data_values/ut_data_value_refcursor.tpb index 3f9876783..985a68cf3 100644 --- a/source/expectations/data_values/ut_data_value_refcursor.tpb +++ b/source/expectations/data_values/ut_data_value_refcursor.tpb @@ -53,6 +53,24 @@ create or replace type body ut_data_value_refcursor as end if; return ut_utils.to_string(l_result); end; - + + member function is_empty return boolean is + l_is_empty boolean := FALSE; + l_result CLOB; + begin + if self.data_value is not null then + ut_assert_processor.set_xml_nls_params(); + dbms_xmlgen.restartQuery(self.data_value); + dbms_xmlgen.setMaxRows(self.data_value, 1); + l_result := dbms_xmlgen.getxml(self.data_value); + + if l_result is null then + l_is_empty := true; + end if; + + ut_assert_processor.reset_nls_params(); + end if; + return l_is_empty; + end; end; / diff --git a/source/expectations/data_values/ut_data_value_refcursor.tps b/source/expectations/data_values/ut_data_value_refcursor.tps index 0cc693b22..cc7f17b63 100644 --- a/source/expectations/data_values/ut_data_value_refcursor.tps +++ b/source/expectations/data_values/ut_data_value_refcursor.tps @@ -45,6 +45,8 @@ create or replace type ut_data_value_refcursor under ut_data_value( overriding member function is_null return boolean, - overriding member function to_string return varchar2 + overriding member function to_string return varchar2, + + member function is_empty return boolean ) / diff --git a/source/expectations/matchers/ut_be_empty.tpb b/source/expectations/matchers/ut_be_empty.tpb new file mode 100644 index 000000000..ed847f1ea --- /dev/null +++ b/source/expectations/matchers/ut_be_empty.tpb @@ -0,0 +1,73 @@ +create or replace type body ut_be_empty as + /* + utPLSQL - Version X.X.X.X + Copyright 2016 - 2017 utPLSQL Project + + Licensed under the Apache License, Version 2.0 (the "License"): + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + + member procedure init(self in out nocopy ut_be_empty) is + begin + self.name := 'be_empty'; + end; + + constructor function ut_be_empty(self in out nocopy ut_be_empty) return self as result is + begin + init(); + return; + end; + + overriding member function run_matcher(self in out nocopy ut_be_empty, a_actual ut_data_value) return boolean is + l_result boolean; + begin + if a_actual is of(ut_data_value_refcursor) then + declare + l_actual ut_data_value_refcursor := treat(a_actual as ut_data_value_refcursor); + begin + if l_actual.data_value is not null then + l_result := l_actual.is_empty; + else + l_result := false; + end if; + end; + elsif a_actual is of(ut_data_value_anydata) then + declare + l_actual ut_data_value_anydata := treat(a_actual as ut_data_value_anydata); + l_type_name varchar2(61); + l_type anytype; + begin + if l_actual.data_value.gettype(l_type) in + (dbms_types.typecode_varray, dbms_types.typecode_table, dbms_types.typecode_namedcollection) then + if a_actual.is_null() then + l_result := false; + else + ut_assert_processor.set_xml_nls_params(); + l_type_name := l_actual.data_value.gettypename(); + l_type_name := substr(l_type_name, instr(l_type_name, '.') + 1); + l_result := xmltype(l_actual.data_value).getclobval() = '<' || l_type_name || '/>'; + ut_assert_processor.reset_nls_params(); + end if; + else + ut_utils.debug_log('Failure - ut_be_empty.run_matcher can only be used with collections and cursors'); + self.error_message := 'The matcher can only be used with collections and cursors'; + l_result := null; + end if; + end; + else + l_result := (self as ut_matcher).run_matcher(a_actual); + end if; + return l_result; + end; + +end; +/ diff --git a/source/expectations/matchers/ut_be_empty.tps b/source/expectations/matchers/ut_be_empty.tps new file mode 100644 index 000000000..a6d98b7fb --- /dev/null +++ b/source/expectations/matchers/ut_be_empty.tps @@ -0,0 +1,22 @@ +create or replace type ut_be_empty under ut_matcher( + /* + utPLSQL - Version X.X.X.X + Copyright 2016 - 2017 utPLSQL Project + + Licensed under the Apache License, Version 2.0 (the "License"): + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + member procedure init(self in out nocopy ut_be_empty), + constructor function ut_be_empty(self in out nocopy ut_be_empty) return self as result, + overriding member function run_matcher(self in out nocopy ut_be_empty, a_actual ut_data_value) return boolean +) +/ diff --git a/source/expectations/ut_expectation_anydata.tpb b/source/expectations/ut_expectation_anydata.tpb index bcd3323db..6f201b666 100644 --- a/source/expectations/ut_expectation_anydata.tpb +++ b/source/expectations/ut_expectation_anydata.tpb @@ -20,6 +20,12 @@ create or replace type body ut_expectation_anydata as ut_utils.debug_log('ut_expectation_anydata.to_equal(self in ut_expectation_anydata, a_expected anydata, a_nulls_are_equal boolean := null)'); self.to_( ut_equal(a_expected, a_nulls_are_equal) ); end; + + member procedure to_be_empty(self in ut_expectation_anydata) is + begin + ut_utils.debug_log('ut_expectation_anydata.to_be_empty(self in ut_expectation_anydata)'); + self.to_( ut_be_empty() ); + end; end; / diff --git a/source/expectations/ut_expectation_anydata.tps b/source/expectations/ut_expectation_anydata.tps index f374d4e97..ef49af228 100644 --- a/source/expectations/ut_expectation_anydata.tps +++ b/source/expectations/ut_expectation_anydata.tps @@ -15,6 +15,7 @@ create or replace type ut_expectation_anydata under ut_expectation( See the License for the specific language governing permissions and limitations under the License. */ - overriding member procedure to_equal(self in ut_expectation_anydata, a_expected anydata, a_nulls_are_equal boolean := null) + overriding member procedure to_equal(self in ut_expectation_anydata, a_expected anydata, a_nulls_are_equal boolean := null), + member procedure to_be_empty(self in ut_expectation_anydata) ) / diff --git a/source/expectations/ut_expectation_refcursor.tpb b/source/expectations/ut_expectation_refcursor.tpb index bb93dbbbe..d1b2b8838 100644 --- a/source/expectations/ut_expectation_refcursor.tpb +++ b/source/expectations/ut_expectation_refcursor.tpb @@ -20,6 +20,11 @@ create or replace type body ut_expectation_refcursor as ut_utils.debug_log('ut_expectation_refcursor.to_equal(self in ut_expectation_refcursor, a_expected sys_refcursor, a_nulls_are_equal boolean := null)'); self.to_( ut_equal(a_expected, a_nulls_are_equal) ); end; - + + member procedure to_be_empty(self in ut_expectation_refcursor) is + begin + ut_utils.debug_log('ut_expectation_refcursor.to_be_empty(self in ut_expectation_refcursor)'); + self.to_( ut_be_empty() ); + end; end; / diff --git a/source/expectations/ut_expectation_refcursor.tps b/source/expectations/ut_expectation_refcursor.tps index ba98fe3cf..2d1c56188 100644 --- a/source/expectations/ut_expectation_refcursor.tps +++ b/source/expectations/ut_expectation_refcursor.tps @@ -15,6 +15,7 @@ create or replace type ut_expectation_refcursor under ut_expectation( See the License for the specific language governing permissions and limitations under the License. */ - overriding member procedure to_equal(self in ut_expectation_refcursor, a_expected sys_refcursor, a_nulls_are_equal boolean := null) + overriding member procedure to_equal(self in ut_expectation_refcursor, a_expected sys_refcursor, a_nulls_are_equal boolean := null), + member procedure to_be_empty(self in ut_expectation_refcursor) ) / diff --git a/source/install.sql b/source/install.sql index 3b92e2c69..5f20417e9 100644 --- a/source/install.sql +++ b/source/install.sql @@ -118,6 +118,7 @@ whenever oserror exit failure rollback @@expectations/matchers/ut_be_true.tps @@expectations/matchers/ut_equal.tps @@expectations/matchers/ut_be_between.tps +@@expectations/matchers/ut_be_empty.tps @@expectations/matchers/ut_match.tps @@expectations/ut_expectation.tps @@expectations/ut_expectation_anydata.tps @@ -158,6 +159,7 @@ whenever oserror exit failure rollback @@expectations/matchers/ut_be_true.tpb @@expectations/matchers/ut_equal.tpb @@expectations/matchers/ut_be_between.tpb +@@expectations/matchers/ut_be_empty.tpb @@expectations/matchers/ut_match.tpb @@expectations/ut_expectation.tpb @@expectations/ut_expectation_anydata.tpb @@ -195,6 +197,7 @@ whenever oserror exit failure rollback @@reporters/ut_xunit_reporter.tpb @@api/be_between.syn +@@api/be_empty.syn @@api/be_false.syn @@api/be_greater_or_equal.syn @@api/be_greater_than.syn diff --git a/source/uninstall.sql b/source/uninstall.sql index 6d953b5ed..ba3e8af33 100644 --- a/source/uninstall.sql +++ b/source/uninstall.sql @@ -31,6 +31,8 @@ drop synonym match; drop synonym be_false; +drop synonym be_empty; + drop synonym be_greater_or_equal; drop synonym be_greater_than; @@ -103,6 +105,8 @@ drop type ut_be_like; drop type ut_be_greater_or_equal; +drop type ut_be_empty; + drop type ut_be_greater_than; drop type ut_be_less_or_equal; diff --git a/tests/RunAll.sql b/tests/RunAll.sql index b1ea37f6f..b6a5ce1b2 100644 --- a/tests/RunAll.sql +++ b/tests/RunAll.sql @@ -78,6 +78,8 @@ create table ut$test_table (val varchar2(1)); @@ut_matchers/greater_than.sql @@ut_matchers/less_or_equal.sql @@ut_matchers/less_than.sql +@@ut_matchers/be_empty.sql + @@lib/RunTest.sql ut_matchers/timestamp_between.sql @@lib/RunTest.sql ut_matchers/timestamp_ltz_between.sql @@lib/RunTest.sql ut_matchers/timestamp_ltz_not_between.sql @@ -172,6 +174,7 @@ create table ut$test_table (val varchar2(1)); @@lib/RunTest.sql ut_utils/ut_utils.to_string.veryBigVarchar2.sql @@lib/RunTest.sql ut_utils/ut_utils.to_string.verySmallNumber.sql + --Global cleanup drop package ut_example_tests; drop procedure check_annotation_parsing; diff --git a/tests/ut_matchers/be_empty.sql b/tests/ut_matchers/be_empty.sql new file mode 100644 index 000000000..70184b43e --- /dev/null +++ b/tests/ut_matchers/be_empty.sql @@ -0,0 +1,14 @@ +@@lib/RunTest.sql "ut_matchers/common/ut.expect.common.refcursor.be_empty.sql 'select * from dual where 1 = 1' 'ut_utils.tr_failure'" +@@lib/RunTest.sql "ut_matchers/common/ut.expect.common.refcursor.be_empty.sql 'select * from dual where 1 <> 1' 'ut_utils.tr_success'" + +@@lib/RunTest.sql "ut_matchers/common/ut.expect.common.refcursor.not_to_be_empty.sql 'select * from dual where 1 = 1' 'ut_utils.tr_success'" +@@lib/RunTest.sql "ut_matchers/common/ut.expect.common.refcursor.not_to_be_empty.sql 'select * from dual where 1 <> 1' 'ut_utils.tr_failure'" + +@@lib/RunTest.sql "ut_matchers/common/ut.expect.common.collection.be_empty.sql 'ora_mining_varchar2_nt' 'ora_mining_varchar2_nt()' 'ut_utils.tr_success'" +@@lib/RunTest.sql "ut_matchers/common/ut.expect.common.collection.be_empty.sql 'ora_mining_varchar2_nt' 'ora_mining_varchar2_nt(''a'')' 'ut_utils.tr_failure'" + +@@lib/RunTest.sql "ut_matchers/common/ut.expect.common.collection.not_be_empty.sql 'ora_mining_varchar2_nt' 'ora_mining_varchar2_nt()' 'ut_utils.tr_failure'" +@@lib/RunTest.sql "ut_matchers/common/ut.expect.common.collection.not_be_empty.sql 'ora_mining_varchar2_nt' 'ora_mining_varchar2_nt(''a'')' 'ut_utils.tr_success'" + +@@lib/RunTest.sql "ut_matchers/common/ut.expect.common.other.be_empty.sql 'ut_data_value_number' 'ut_data_value_number(1)' 'ConvertObject' 'ut_utils.tr_failure'" +@@lib/RunTest.sql "ut_matchers/common/ut.expect.common.other.not_be_empty.sql 'ut_data_value_varchar2' 'NULL' 'ConvertObject' 'ut_utils.tr_failure'" \ No newline at end of file diff --git a/tests/ut_matchers/common/ut.expect.common.collection.be_empty.sql b/tests/ut_matchers/common/ut.expect.common.collection.be_empty.sql new file mode 100644 index 000000000..02472ff17 --- /dev/null +++ b/tests/ut_matchers/common/ut.expect.common.collection.be_empty.sql @@ -0,0 +1,20 @@ +--Arrange +declare + l_var &&1; + l_result integer; + l_asserts_results ut_assert_results; +begin + --Act + l_var := &&2; + ut.expect(anydata.convertcollection(l_var)).to_(be_empty()); + l_asserts_results := ut_assert_processor.get_asserts_results(); + l_result := l_asserts_results(l_asserts_results.last).result; + --Assert + if l_result = &&3 then + :test_result := ut_utils.tr_success; + else + :test_result := ut_utils.tr_failure; + dbms_output.put_line('expected: '''||&&3||''', got: '''||l_result||'''' ); + end if; +end; +/ diff --git a/tests/ut_matchers/common/ut.expect.common.collection.not_be_empty.sql b/tests/ut_matchers/common/ut.expect.common.collection.not_be_empty.sql new file mode 100644 index 000000000..01a5b0deb --- /dev/null +++ b/tests/ut_matchers/common/ut.expect.common.collection.not_be_empty.sql @@ -0,0 +1,20 @@ +--Arrange +declare + l_var &&1; + l_result integer; + l_asserts_results ut_assert_results; +begin + --Act + l_var := &&2; + ut.expect(anydata.convertcollection(l_var)).not_to(be_empty()); + l_asserts_results := ut_assert_processor.get_asserts_results(); + l_result := l_asserts_results(l_asserts_results.last).result; + --Assert + if l_result = &&3 then + :test_result := ut_utils.tr_success; + else + :test_result := ut_utils.tr_failure; + dbms_output.put_line('expected: '''||&&3||''', got: '''||l_result||'''' ); + end if; +end; +/ diff --git a/tests/ut_matchers/common/ut.expect.common.other.be_empty.sql b/tests/ut_matchers/common/ut.expect.common.other.be_empty.sql new file mode 100644 index 000000000..9634dc96e --- /dev/null +++ b/tests/ut_matchers/common/ut.expect.common.other.be_empty.sql @@ -0,0 +1,20 @@ +--Arrange +declare + l_var &&1; + l_result integer; + l_asserts_results ut_assert_results; +begin + --Act + l_var := &&2; + ut.expect(anydata.&&3(l_var)).to_(be_empty()); + l_asserts_results := ut_assert_processor.get_asserts_results(); + l_result := l_asserts_results(l_asserts_results.last).result; + --Assert + if l_result = &&4 then + :test_result := ut_utils.tr_success; + else + :test_result := ut_utils.tr_failure; + dbms_output.put_line('expected: '''||&&4||''', got: '''||l_result||'''' ); + end if; +end; +/ diff --git a/tests/ut_matchers/common/ut.expect.common.other.not_be_empty.sql b/tests/ut_matchers/common/ut.expect.common.other.not_be_empty.sql new file mode 100644 index 000000000..0e331751d --- /dev/null +++ b/tests/ut_matchers/common/ut.expect.common.other.not_be_empty.sql @@ -0,0 +1,20 @@ +--Arrange +declare + l_var &&1; + l_result integer; + l_asserts_results ut_assert_results; +begin + --Act + l_var := &&2; + ut.expect(anydata.&&3(l_var)).not_to(be_empty()); + l_asserts_results := ut_assert_processor.get_asserts_results(); + l_result := l_asserts_results(l_asserts_results.last).result; + --Assert + if l_result = &&4 then + :test_result := ut_utils.tr_success; + else + :test_result := ut_utils.tr_failure; + dbms_output.put_line('expected: '''||&&4||''', got: '''||l_result||'''' ); + end if; +end; +/ diff --git a/tests/ut_matchers/common/ut.expect.common.refcursor.be_empty.sql b/tests/ut_matchers/common/ut.expect.common.refcursor.be_empty.sql new file mode 100644 index 000000000..867a1e19e --- /dev/null +++ b/tests/ut_matchers/common/ut.expect.common.refcursor.be_empty.sql @@ -0,0 +1,20 @@ +--Arrange +declare + l_cursor sys_refcursor; + l_result integer; + l_asserts_results ut_assert_results; +begin + --Act + open l_cursor for &&1; + ut.expect(l_cursor).to_be_empty(); + l_asserts_results := ut_assert_processor.get_asserts_results(); + l_result := l_asserts_results(l_asserts_results.last).result; + --Assert + if l_result = &&2 then + :test_result := ut_utils.tr_success; + else + :test_result := ut_utils.tr_failure; + dbms_output.put_line('expected: '''||&&2||''', got: '''||l_result||'''' ); + end if; +end; +/ diff --git a/tests/ut_matchers/common/ut.expect.common.refcursor.not_to_be_empty.sql b/tests/ut_matchers/common/ut.expect.common.refcursor.not_to_be_empty.sql new file mode 100644 index 000000000..4277a6696 --- /dev/null +++ b/tests/ut_matchers/common/ut.expect.common.refcursor.not_to_be_empty.sql @@ -0,0 +1,20 @@ +--Arrange +declare + l_cursor sys_refcursor; + l_result integer; + l_asserts_results ut_assert_results; +begin + --Act + open l_cursor for &&1; + ut.expect(l_cursor).not_to(be_empty()); + l_asserts_results := ut_assert_processor.get_asserts_results(); + l_result := l_asserts_results(l_asserts_results.last).result; + --Assert + if l_result = &&2 then + :test_result := ut_utils.tr_success; + else + :test_result := ut_utils.tr_failure; + dbms_output.put_line('expected: '''||&&2||''', got: '''||l_result||'''' ); + end if; +end; +/