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

Skip to content

Commit 4ec39b3

Browse files
committed
Merge remote-tracking branch 'upstream/release/v3.0.4'
2 parents b6bafce + 10553ac commit 4ec39b3

150 files changed

Lines changed: 3569 additions & 3866 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v3.0.3
1+
v3.0.4

development/cleanup.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ drop user ${UT3_USER} cascade;
1515
begin
1616
for i in (
1717
select decode(owner,'PUBLIC','drop public synonym "','drop synonym "'||owner||'"."')|| synonym_name ||'"' drop_orphaned_synonym from dba_synonyms a
18-
where not exists (select null from dba_objects b where a.table_name=b.object_name and a.table_owner=b.owner )
19-
and a.table_owner <> 'SYS'
18+
where not exists (select 1 from dba_objects b where (a.table_name=b.object_name and a.table_owner=b.owner or b.owner='SYS' and a.table_owner=b.object_name) )
19+
and a.table_owner not in ('SYS','SYSTEM')
2020
) loop
21+
dbms_output.put_line(i.drop_orphaned_synonym);
2122
execute immediate i.drop_orphaned_synonym;
2223
end loop;
2324
end;

development/releasing.md

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1-
The release process is automated in the following way:
2-
1) With every build, the build process on Travis updates files with an appropriate version number before deployment into the database.
3-
This is to confirm that the update of versions works properly.
4-
2) When a build is executed on a branch named `release/v1.2.3-something` then additional steps are taken:
5-
- the project version in files: `sonar-project.properties`, `VERSION` is updated from the version number derived from the release branch
6-
- changes to those two files are committed and pushed - this should happen only once, when the release branch is initially created on the main repo
7-
3) To create a release, just create a tag on the code to be released. The tag name must match the regex pattern: `^v[0-9]+\.[0-9]+\.[0-9]+.*$`
8-
- When a tag build is executed, the documentation is built and files are uploaded to the tag.
9-
- The version number is derived from the tag name.
10-
4) The release version does not provide access to unversioned source files (the default zip file from GitHub is empty).
11-
The sources for release are provided in separate zip files delivered from the Travis build process.
1+
The release process is semi-automated.
2+
3+
With every build, the build process on Travis updates files with an appropriate version number before deployment into the database.
4+
This step is performed, to confirm that the update of versions works properly.
5+
6+
To create a release:
7+
- create release branch and wait for release build to complete successfully
8+
- merge release branch to master and wait for master build to complete successfully
9+
- create a release from the master branch using github web page and populate release description using information found on the issues and pull requests for release
10+
11+
The following will happen:
12+
- build executed on branch `release/v1.2.3-[something]` updates files `sonar-project.properties`, `VERSION` with project version derived from the release branch name
13+
- changes to those two files are committed and pushed back to release branch by Travis
14+
- when a release is created, a new tag is added in on the repository and a tag build is executed
15+
- the documentation for new release is published on `utplsql.github.io` and installation archives are added to the tag.
16+
17+
Note:
18+
The released version does not provide access to un-versioned source files (the default zip file from GitHub is empty).
19+
The sources for release are provided in separate zip files delivered from the Travis build process.
20+
This is because we do not keep version in our source files in develop branch.

docs/about/project-details.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
utPLSQL is open source project [hosted on GitHub](https://github.com/utPLSQL/utPLSQL).
1010

1111
Contributions, help and constructive feedback is always appreciated.
12-
If you are interested in helping please read our [guide to contributing](https://github.com/utPLSQL/utPLSQL/CONTRIBUTING.md)
12+
13+
If you are interested in helping please read our [contributing guide](https://github.com/utPLSQL/utPLSQL/blob/develop/CONTRIBUTING.md)
1314

1415

1516

docs/userguide/annotations.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,26 @@ When processing the test suite `test_pkg` defined in [Example of annotated test
214214
rollback to savepoint 'beforeall'
215215
216216
```
217+
218+
# Annotation cache
219+
220+
utPLSQL needs to scan sources of package specifications to identify and parse annotations.
221+
To improve framework startup time, specially when dealing with database users owning large amount of packages the framework has build-in persistent cache for annotations.
222+
223+
Cache is checked for staleness and refreshed automatically on every run.
224+
The initial startup of utPLSQL for a schema will take longer than consecutive executions.
225+
226+
If you're in situation, where your database is controlled via CI/CD server and gets refreshed/wiped before each run of your tests,
227+
consider building upfront and creating the snapshot of our database after the cache was refreshed.
228+
229+
To build annotation cache without actually invoking any tests, call `ut_runner.rebuild_annotation_cache(a_object_owner, a_object_type)` sql block for every unit test owner that you want to have annotations cache prebuilt.
230+
231+
Example:
232+
```sql
233+
exec ut_runner.rebuild_annotation_cache('HR', 'PACKAGE');
234+
```
235+
236+
To purge annotations cache call:
237+
```sql
238+
exec ut_runner.purge_cache('HR', 'PACKAGE');
239+
```

docs/userguide/expectations.md

Lines changed: 109 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ To achieve that, we use a combination of expectation and matcher to perform the
66
Example of a unit test procedure body.
77
```sql
88
begin
9-
ut.expect( 'the tested value' ).to_( equal('the expected value') );
9+
ut.expect( 'the tested value', 'optional custom failure message' ).to_( equal('the expected value') );
1010
end;
1111
```
1212

1313
Expectation is a set of the expected value(s), actual values(s) and the matcher(s) to run on those values.
14+
You can also add a custom failure message for an expectation.
1415

1516
Matcher defines the comparison operation to be performed on expected and actual values.
1617
Pseudo-code:
1718
```
18-
ut.expect( a_actual {data-type} ).to_( {matcher} );
19-
ut.expect( a_actual {data-type} ).not_to( {matcher} );
19+
ut.expect( a_actual {data-type} [, a_message {varchar2}] ).to_( {matcher} );
20+
ut.expect( a_actual {data-type} [, a_message {varchar2}] ).not_to( {matcher} );
2021
```
2122

2223
All matchers have shortcuts like:
@@ -25,6 +26,62 @@ All matchers have shortcuts like:
2526
ut.expect( a_actual {data-type} ).not_to_{matcher};
2627
```
2728

29+
## Providing a custom failure message
30+
Expectations allow you to provide a custom error message as second argument:
31+
````sql
32+
-- Pseudocode
33+
ut.expect( a_actual {data-type}, a_message {varchar2} ).to_{matcher};
34+
-- Example
35+
ut.expect( 'supercat', 'checked superhero-animal was not a dog' ).to_( equal('superdog') );
36+
````
37+
The message is added to the normal failure message returned by the matcher.
38+
39+
This is not only useful to give more detailed and specific information about a test, but also if you have some kind of dynamic tests.
40+
41+
### Dynamic tests example
42+
You have a bunch of tables and an archive-functionality for them and you want to test if the things you put into live-tables are removed from live-tables and present in archive-tables:
43+
44+
````sql
45+
procedure test_data_existance( i_tableName varchar2 )
46+
as
47+
v_count_real integer;
48+
v_count_archive integer;
49+
begin
50+
51+
execute immediate 'select count(*) from ' || i_tablename || '' into v_count_real;
52+
execute immediate 'select count(*) from ' || i_tablename || '_archive' into v_count_archive;
53+
54+
ut.expect( v_count_archive, 'failure checking entry-count of ' || i_tablename || '_archive' ).to_( equal(1) );
55+
ut.expect( v_count_real, 'failure checking entry-count of ' || i_tablename ).to_( equal(0) );
56+
57+
end;
58+
59+
procedure test_archive_data
60+
as
61+
begin
62+
-- Arrange
63+
-- insert several data into real-tables here
64+
65+
-- Act
66+
package_to_test.archive_data();
67+
68+
-- Assert
69+
test_data_existance('TABLE_A');
70+
test_data_existance('TABLE_B');
71+
test_data_existance('TABLE_C');
72+
test_data_existance('TABLE_D');
73+
end;
74+
````
75+
A failed output will look like this:
76+
````
77+
Failures:
78+
79+
1) test_archive_data
80+
"failure checking entry-count of TABLE_A_archive"
81+
Actual: 2 (number) was expected to equal: 1 (number)
82+
at "UT_TEST_PACKAGE.TEST_DATA_EXISTANCE", line 12 ut.expect( v_count_archive, 'failure checking entry-count of ' || i_tablename || '_archive' ).to_( equal(1) );
83+
````
84+
2885
# Matchers
2986
utPLSQL provides the following matchers to perform checks on the expected and actual values.
3087

@@ -190,6 +247,22 @@ begin
190247
end;
191248
```
192249

250+
## match
251+
Validates that the actual value is matching the expected regular expression.
252+
253+
Usage:
254+
```sql
255+
begin
256+
ut.expect( a_actual => '123-456-ABcd' ).to_match( a_pattern => '\d{3}-\d{3}-[a-z]', a_modifiers => 'i' );
257+
ut.expect( 'some value' ).to_match( '^some.*' );
258+
--or
259+
ut.expect( a_actual => '123-456-ABcd' ).to_( match( a_pattern => '\d{3}-\d{3}-[a-z]', a_modifiers => 'i' ) );
260+
ut.expect( 'some value' ).to_( match( '^some.*' ) );
261+
end;
262+
```
263+
264+
Parameters `a_pattern` and `a_modifiers` represent a valid regexp pattern accepted by [Oracle REGEXP_LIKE condition](https://docs.oracle.com/database/121/SQLRF/conditions007.htm#SQLRF00501)
265+
193266
## equal
194267

195268
The equal matcher is a very restrictive matcher. It only returns true if the compared data-types are the same.
@@ -401,22 +474,44 @@ end;
401474

402475
This test will fail as `v_actual` is not equal `v_expected`.
403476

404-
## match
405-
Validates that the actual value is matching the expected regular expression.
477+
# Expecting exceptions
478+
479+
Below example illustrates how to write test to check for expected exceptions (thrown by tested code).
406480

407-
Usage:
408481
```sql
409-
begin
410-
ut.expect( a_actual => '123-456-ABcd' ).to_match( a_pattern => '\d{3}-\d{3}-[a-z]', a_modifiers => 'i' );
411-
ut.expect( 'some value' ).to_match( '^some.*' );
412-
--or
413-
ut.expect( a_actual => '123-456-ABcd' ).to_( match( a_pattern => '\d{3}-\d{3}-[a-z]', a_modifiers => 'i' ) );
414-
ut.expect( 'some value' ).to_( match( '^some.*' ) );
482+
create or replace procedure divide(p_a number, p_b number) is
483+
begin
484+
return p_a / p_b;
415485
end;
486+
/
487+
488+
create or replace package test_divide is
489+
--%suite(Divide functionality)
490+
491+
--%test(Raises exception when divisor is zero)
492+
procedure divide_raises_zero_divisor;
493+
end;
494+
/
495+
create or replace package body test_divide is
496+
procedure divide_raises_zero_divisor is
497+
l_my_number number;
498+
begin
499+
l_my_number := divide(1,0); -- PLSQL call throwing ORA-01476 exception
500+
ut.fail('Expected exception but nothing was raised');
501+
exception
502+
when others then
503+
ut.expect( sqlcode ).to_equal( -1476 );
504+
ut.expect( sqlerrm ).to_match( 'equal to zero' );
505+
end;
506+
end;
507+
/
416508
```
417509

418-
Parameters `a_pattern` and `a_modifiers` represent a valid regexp pattern accepted by [Oracle REGEXP_LIKE condition](https://docs.oracle.com/database/121/SQLRF/conditions007.htm#SQLRF00501)
510+
The call to `ut.fail` is required to make sure that the test fails, if we expect an exception, but the tested code does not throw any.
511+
512+
The call to `ut.expect` uses `equal` matcher to check that the exception that was raised was exactly the one we were expecting to get in particular situation.
419513

514+
Depending on the situation you will want to check for `sqlcode`, `sqlerrm`, both or perform additional expectation checks to make sure nothing was changed by the called procedure in the database.
420515

421516

422517
# Supported data types
@@ -471,3 +566,4 @@ end;
471566
```
472567
Since NULL is neither *true* nor *not true*, both expectations will report failure.
473568

569+

examples/demo_of_expectations/demo_equal_matcher.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ create or replace package body demo_equal_matcher as
9898
l_expected demo_department;
9999
l_actual demo_department;
100100
begin
101-
ut.expect(anydata.convertObject(l_actual)).to_equal(anydata.convertObject(l_expected),false);
101+
ut.expect(anydata.convertObject(l_actual)).to_equal(anydata.convertObject(l_expected),a_nulls_are_equal => false);
102102
end;
103103

104104

examples/developer_examples/RunExampleTestAnnotationsParsingTimeHugePackage.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ set echo off
66
@@tst_pkg_huge.pks
77

88
declare
9-
l_suite ut_logical_suite;
9+
l_suites ut_suite_items;
1010
begin
11-
l_suite := ut_suite_manager.config_package(a_owner_name => USER,a_object_name => 'TST_PKG_HUGE');
11+
l_suites := ut_suite_manager.configure_execution_by_path(ut_varchar2_list(USER||'.TST_PKG_HUGE'));
1212
end;
1313
/
1414

examples/developer_examples/RunExampleTestSuite.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ begin
4444
dbms_output.put_line('Test:' || test_item.item.form_name);
4545
dbms_output.put_line('Result: ' || ut_utils.test_result_to_char(test_item.result));
4646
dbms_output.put_line('expectation Results:');
47-
for i in test_item.results.first .. test_item.results.last loop
48-
expectation := test_item.results(i);
47+
for i in 1 .. test_item.failed_expectations.count loop
48+
expectation := test_item.failed_expectations(i);
4949
dbms_output.put_line(i || ' - result: ' || ut_utils.test_result_to_char(expectation.result));
5050
dbms_output.put_line(i || ' - Message: ' || expectation.message);
5151
end loop;

old_tests/RunAll.sql

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ spool RunAll.log
1818
--Global setup
1919
@@helpers/ut_example_tests.pks
2020
@@helpers/ut_example_tests.pkb
21-
@@helpers/check_annotation_parsing.prc
2221
--@@helpers/cre_tab_ut_test_table.sql
2322
create table ut$test_table (val varchar2(1));
2423
@@helpers/ut_transaction_control.pck
@@ -38,19 +37,6 @@ create table ut$test_table (val varchar2(1));
3837
--Regular coverage excludes the framework
3938
exec ut_coverage.coverage_start_develop();
4039

41-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.IgnoreWrappedPackageAndDoesNotRaiseException.sql
42-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParseAnnotationMixedWithWrongBeforeProcedure.sql
43-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParseAnnotationNotBeforeProcedure.sql
44-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParseAnnotationParamsWithBrackets.sql
45-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParsePackageAndProcedureLevelAnnotations.sql
46-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParsePackageLevelAnnotation.sql
47-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParsePackageLevelAnnotationAccessibleBy.sql
48-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParsePackageLevelAnnotationMultilineDeclare.sql
49-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParsePackageLevelAnnotationWithKeyValue.sql
50-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParsePackageLevelAnnotationWithMultilineComment.sql
51-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.spaceBeforeAnnotationParams.sql
52-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParseAnnotationWithWindowsNewline.sql
53-
@@lib/RunTest.sql ut_annotations/ut_annotations.parse_package_annotations.ParseProcedureAnnotationWithVeryLongName.sql
5440
@@lib/RunTest.sql ut_expectation_processor/who_called_expectation.parseStackTrace.sql
5541
@@lib/RunTest.sql ut_expectation_processor/who_called_expectation.parseStackTraceWith0x.sql
5642
@@ut_expectations/ut.expect.not_to_be_null.sql
@@ -284,7 +270,6 @@ spool off
284270
--Global cleanup
285271
--removing objects that should not be part of coverage report
286272
drop package ut_example_tests;
287-
drop procedure check_annotation_parsing;
288273
drop package ut_transaction_control;
289274
drop table ut$test_table;
290275
drop type department$;
@@ -341,8 +326,12 @@ begin
341326
'source/api/ut_runner.pks',
342327
'source/core/coverage',
343328
'source/core/types',
344-
'source/core/ut_annotations.pkb',
345-
'source/core/ut_annotations.pks',
329+
'source/core/annotations/ut_annotation_manager.pkb',
330+
'source/core/annotations/ut_annotation_manager.pks',
331+
'source/core/annotations/ut_annotation_parser.pkb',
332+
'source/core/annotations/ut_annotation_parser.pks',
333+
'source/core/annotations/ut_annotation_cache_manager.pkb',
334+
'source/core/annotations/ut_annotation_cache_manager.pks',
346335
'source/core/ut_expectation_processor.pkb',
347336
'source/core/ut_expectation_processor.pks',
348337
'source/core/ut_file_mapper.pkb',

0 commit comments

Comments
 (0)