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

Skip to content

Commit e5b4b78

Browse files
authored
Merge pull request #577 from utPLSQL/feature/have_count_of_matcher
Added `have_count` matcher.
2 parents e57b635 + b2ef572 commit e5b4b78

16 files changed

Lines changed: 410 additions & 31 deletions

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The framework follows industry standards and best patterns of modern Unit Testin
88
- [Getting Started](userguide/getting-started.md)
99
- [Annotations](userguide/annotations.md)
1010
- [Expectations](userguide/expectations.md)
11+
- [Advanced data comparison](userguide/advanced_data_comparison.md)
1112
- [Running unit tests](userguide/running-unit-tests.md)
1213
- [Testing best pracitces](userguide/best-practices.md)
1314
- [Upgrade utPLSQL](userguide/upgrade.md)

docs/userguide/expectations.md

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ utPLSQL provides the following matchers to perform checks on the expected and ac
136136
- `be_null`
137137
- `be_true`
138138
- `equal`
139+
- `have_count`
139140
- `match`
140141

141142
## be_between
@@ -288,6 +289,23 @@ begin
288289
end;
289290
```
290291

292+
## have_count
293+
Unary matcher that validates if the provided dataset count is equal to expected value.
294+
295+
Can be used with `refcursor` or `table type`
296+
297+
Usage:
298+
```sql
299+
procedure test_if_cursor_is_empty is
300+
l_cursor sys_refcursor;
301+
begin
302+
open l_cursor for select * from dual connect by level <=10;
303+
ut.expect( l_cursor ).to_have_count(10);
304+
--or
305+
ut.expect( l_cursor ).to_( have_count(10) );
306+
end;
307+
```
308+
291309
## match
292310
Validates that the actual value is matching the expected regular expression.
293311

@@ -649,21 +667,21 @@ Since NULL is neither *true* nor *false*, both expectations will report failure.
649667

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

652-
| | be_between | be_empty | be_false | be_greater_than | be_greater_or_equal | be_less_or_equal | be_less_than | be_like | be_not_null | be_null | be_true | equal | match |
653-
|:------------------------------|:----------:|:--------:|:--------:|:---------------:|:-------------------:|:----------------:|:------------:|:-------:|:-----------:|:-------:|:-------:|:-----:|:-----:|
654-
| anydata( collection, object ) | | X | | | | | | | X | X | | X | |
655-
| blob | | | | | | | | | X | X | | X | |
656-
| boolean | | | X | | | | | | X | X | X | X | |
657-
| clob | | | | | | | | X | X | X | | X | X |
658-
| date | X | | | X | X | X | X | | X | X | | X | |
659-
| number | X | | | X | X | X | X | | X | X | | X | |
660-
| refcursor | | X | | | | | | | X | X | | X | |
661-
| timestamp | X | | | X | X | X | X | | X | X | | X | |
662-
| timestamp with timezone | X | | | X | X | X | X | | X | X | | X | |
663-
| timestamp with local timezone | X | | | X | X | X | X | | X | X | | X | |
664-
| varchar2 | X | | | | | | | X | X | X | | X | X |
665-
| interval year to month | X | | | X | X | X | X | | X | X | | X | |
666-
| interval day to second | X | | | X | X | X | X | | X | X | | X | |
670+
| | be_between | be_empty | be_false | be_greater_than | be_greater_or_equal | be_less_or_equal | be_less_than | be_like | be_not_null | be_null | be_true | equal | have_count | match |
671+
|:------------------------------|:----------:|:--------:|:--------:|:---------------:|:-------------------:|:----------------:|:------------:|:-------:|:-----------:|:-------:|:-------:|:-----:|:----------:|:-----:|
672+
| anydata( collection, object ) | | X | | | | | | | X | X | | X | X | |
673+
| blob | | | | | | | | | X | X | | X | | |
674+
| boolean | | | X | | | | | | X | X | X | X | | |
675+
| clob | | | | | | | | X | X | X | | X | | X |
676+
| date | X | | | X | X | X | X | | X | X | | X | | |
677+
| number | X | | | X | X | X | X | | X | X | | X | | |
678+
| refcursor | | X | | | | | | | X | X | | X | X | |
679+
| timestamp | X | | | X | X | X | X | | X | X | | X | | |
680+
| timestamp with timezone | X | | | X | X | X | X | | X | X | | X | | |
681+
| timestamp with local timezone | X | | | X | X | X | X | | X | X | | X | | |
682+
| varchar2 | X | | | | | | | X | X | X | | X | | X |
683+
| interval year to month | X | | | X | X | X | X | | X | X | | X | | |
684+
| interval day to second | X | | | X | X | X | X | | X | X | | X | | |
667685

668686

669687

source/api/have_count.syn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
create synonym have_count for ut_have_count;

source/create_synonyms_and_grants_for_public.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ grant execute on &&ut3_owner..ut_be_not_null to public;
4343
grant execute on &&ut3_owner..ut_be_null to public;
4444
grant execute on &&ut3_owner..ut_be_true to public;
4545
grant execute on &&ut3_owner..ut_equal to public;
46+
grant execute on &&ut3_owner..ut_have_count to public;
4647
grant execute on &&ut3_owner..ut_match to public;
4748
grant execute on &&ut3_owner..ut to public;
4849
grant execute on &&ut3_owner..ut_runner to public;
@@ -95,6 +96,7 @@ create public synonym be_not_null for &&ut3_owner..ut_be_not_null;
9596
create public synonym be_null for &&ut3_owner..ut_be_null;
9697
create public synonym be_true for &&ut3_owner..ut_be_true;
9798
create public synonym equal for &&ut3_owner..ut_equal;
99+
create public synonym have_count for &&ut3_owner..have_count;
98100
create public synonym match for &&ut3_owner..ut_match;
99101
create public synonym ut for &&ut3_owner..ut;
100102
create public synonym ut_runner for &&ut3_owner..ut_runner;

source/create_synonyms_and_grants_for_user.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ grant execute on &&ut3_owner..ut_be_not_null to &ut3_user;
6363
grant execute on &&ut3_owner..ut_be_null to &ut3_user;
6464
grant execute on &&ut3_owner..ut_be_true to &ut3_user;
6565
grant execute on &&ut3_owner..ut_equal to &ut3_user;
66+
grant execute on &&ut3_owner..ut_have_count to &ut3_user;
6667
grant execute on &&ut3_owner..ut_match to &ut3_user;
6768
grant execute on &&ut3_owner..ut to &ut3_user;
6869
grant execute on &&ut3_owner..ut_runner to &ut3_user;
@@ -114,6 +115,7 @@ create or replace synonym &ut3_user..be_not_null for &&ut3_owner..be_not_null;
114115
create or replace synonym &ut3_user..be_null for &&ut3_owner..be_null;
115116
create or replace synonym &ut3_user..be_true for &&ut3_owner..be_true;
116117
create or replace synonym &ut3_user..equal for &&ut3_owner..equal;
118+
create or replace synonym &ut3_user..have_count for &&ut3_owner..have_count;
117119
create or replace synonym &ut3_user..match for &&ut3_owner..match;
118120
create or replace synonym &ut3_user..ut for &&ut3_owner..ut;
119121
create or replace synonym &ut3_user..ut_runner for &&ut3_owner..ut_runner;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
create or replace type body ut_have_count as
2+
/*
3+
utPLSQL - Version 3
4+
Copyright 2016 - 2017 utPLSQL Project
5+
6+
Licensed under the Apache License, Version 2.0 (the "License"):
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
constructor function ut_have_count(self in out nocopy ut_have_count, a_expected integer) return self as result is
20+
begin
21+
self.self_type := $$plsql_unit;
22+
self.expected := a_expected;
23+
return;
24+
end;
25+
26+
overriding member function run_matcher(self in out nocopy ut_have_count, a_actual ut_data_value) return boolean is
27+
l_result boolean;
28+
begin
29+
if a_actual is of(ut_data_value_refcursor) then
30+
l_result := ( self.expected = treat(a_actual as ut_data_value_refcursor).row_count );
31+
elsif a_actual is of(ut_data_value_collection) then
32+
l_result := ( self.expected = treat(a_actual as ut_data_value_collection).elements_count );
33+
else
34+
l_result := (self as ut_matcher).run_matcher(a_actual);
35+
end if;
36+
return l_result;
37+
end;
38+
39+
overriding member function failure_message(a_actual ut_data_value) return varchar2 is
40+
begin
41+
return 'Actual: (' || a_actual.get_object_info()||') was expected to have [ count = '||ut_utils.to_string(self.expected)||' ]';
42+
end;
43+
44+
overriding member function failure_message_when_negated(a_actual ut_data_value) return varchar2 is
45+
begin
46+
return 'Actual: ' || a_actual.get_object_info()||' was expected not to have [ count = '||ut_utils.to_string(self.expected)||' ]';
47+
end;
48+
49+
end;
50+
/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
create or replace type ut_have_count under ut_matcher(
2+
/*
3+
utPLSQL - Version 3
4+
Copyright 2016 - 2017 utPLSQL Project
5+
6+
Licensed under the Apache License, Version 2.0 (the "License"):
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
expected integer,
20+
21+
constructor function ut_have_count(self in out nocopy ut_have_count, a_expected integer) return self as result,
22+
overriding member function run_matcher(self in out nocopy ut_have_count, a_actual ut_data_value) return boolean,
23+
overriding member function failure_message(a_actual ut_data_value) return varchar2,
24+
overriding member function failure_message_when_negated(a_actual ut_data_value) return varchar2
25+
)
26+
/

source/expectations/ut_expectation.tpb

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,6 @@ create or replace type body ut_expectation as
7979
self.not_to( ut_be_false() );
8080
end;
8181

82-
member procedure to_be_empty(self in ut_expectation) is
83-
begin
84-
self.to_( ut_be_empty() );
85-
end;
86-
87-
member procedure not_to_be_empty(self in ut_expectation) is
88-
begin
89-
self.not_to( ut_be_empty() );
90-
end;
91-
92-
9382
member procedure to_equal(self in ut_expectation, a_expected anydata, a_nulls_are_equal boolean := null) is
9483
begin
9584
self.to_( ut_equal(a_expected, a_nulls_are_equal) );

source/expectations/ut_expectation.tps

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ create or replace type ut_expectation authid current_user as object(
3333
member procedure not_to_be_true(self in ut_expectation),
3434
member procedure not_to_be_false(self in ut_expectation),
3535

36-
member procedure to_be_empty(self in ut_expectation),
37-
member procedure not_to_be_empty(self in ut_expectation),
38-
3936
-- this is done to provide strong type comparison. other comporators should be implemented in the type-specific classes
4037
member procedure to_equal(self in ut_expectation, a_expected anydata, a_nulls_are_equal boolean := null),
4138
member procedure to_equal(self in ut_expectation, a_expected anydata, a_exclude varchar2, a_nulls_are_equal boolean := null),

source/expectations/ut_expectation_compound.tpb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,28 @@ create or replace type body ut_expectation_compound as
2424
return;
2525
end;
2626

27+
member procedure to_be_empty(self in ut_expectation_compound) is
28+
begin
29+
self.to_( ut_be_empty() );
30+
end;
31+
32+
member procedure not_to_be_empty(self in ut_expectation_compound) is
33+
begin
34+
self.not_to( ut_be_empty() );
35+
end;
36+
37+
38+
member procedure to_have_count(self in ut_expectation_compound, a_expected integer) is
39+
begin
40+
self.to_( ut_have_count(a_expected) );
41+
end;
42+
43+
member procedure not_to_have_count(self in ut_expectation_compound, a_expected integer) is
44+
begin
45+
self.not_to( ut_have_count(a_expected) );
46+
end;
47+
48+
2749
member function to_equal(a_expected anydata, a_nulls_are_equal boolean := null) return ut_expectation_compound is
2850
l_result ut_expectation_compound := self;
2951
begin

0 commit comments

Comments
 (0)