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

Skip to content

Commit e172d40

Browse files
committed
[WIP] Ability to run expectations without test
> TODO - documentation updates Added ability to run expectations without tests. Expectation, when executed without test is reporter straight to dbms_output. So it is now possible to execute: `exec ut.expect(1).to_equal(0);` And get result: ``` FAILURE Actual: 1 (number) was expected to equal: 0 (number) ``` Resolves #956 Additionally: - utPLSQL is now cleaning up the application_info after run. - utPLSQL is setting session context during run, making it possible to access some of utPLSQL info within the test procedures directly. Resolves #781 The information is provided in sys_context(`UT3_INFO`,...). Following attributes are getting populated: - Always: - RUN_PATHS - SUITE_DESCRIPTION - SUITE_PACKAGE - SUITE_PATH - SUITE_START_TIME - CURRENT_EXECUTABLE_NAME - CURRENT_EXECUTABLE_TYPE - When running in suite context - CONTEXT_NAME - CONTEXT_PATH - CONTEXT_START_TIME - After first executable in suite - TIME_IN_SUITE - After first executable in suite context - TIME_IN_CONTEXT - When running a test or before/after each/test - TEST_DESCRIPTION - TEST_NAME - TEST_START_TIME - After first executable in test - TIME_IN_TEST
1 parent eaff720 commit e172d40

24 files changed

+899
-46
lines changed

.travis/install_utplsql_release.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ fi
4343

4444
"$SQLCLI" sys/$ORACLE_PWD@//$CONNECTION_STR AS SYSDBA <<SQL
4545
alter session set plsql_optimize_level=0;
46+
alter session set plsql_ccflags = 'SELF_TESTING_INSTALL:TRUE';
47+
4648
@${INSTALL_FILE} ${UT3_RELEASE_VERSION_SCHEMA}
4749
exit
4850
SQL

source/api/ut_runner.pkb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ create or replace package body ut_runner is
109109
else
110110
ut_event_manager.add_listener( ut_documentation_reporter() );
111111
end if;
112+
ut_event_manager.add_listener( ut_session_info() );
112113

113114
ut_event_manager.trigger_event(ut_event_manager.gc_initialize);
114115
ut_event_manager.trigger_event(ut_event_manager.gc_debug, ut_run_info());
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
create or replace package body ut_session_context as
2+
/*
3+
utPLSQL - Version 3
4+
Copyright 2016 - 2019 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+
$IF $$SELF_TESTING_INSTALL $THEN
19+
gc_context_name constant varchar2(30) := ut_utils.ut_owner()||'_INFO';
20+
$ELSE
21+
gc_context_name constant varchar2(30) := 'UT3_INFO';
22+
$END
23+
24+
procedure set_context(a_name varchar2, a_value varchar2) is
25+
begin
26+
dbms_session.set_context( gc_context_name, a_name, a_value );
27+
end;
28+
29+
procedure clear_context(a_name varchar2) is
30+
begin
31+
dbms_session.clear_context( namespace => gc_context_name, attribute => a_name );
32+
end;
33+
34+
procedure clear_all_context is
35+
begin
36+
dbms_session.clear_all_context( namespace => gc_context_name );
37+
end;
38+
39+
function is_ut_run return boolean is
40+
l_paths varchar2(32767);
41+
begin
42+
l_paths := sys_context(gc_context_name, 'RUN_PATHS');
43+
return l_paths is not null;
44+
end;
45+
46+
function get_namespace return varchar2 is
47+
begin
48+
return gc_context_name;
49+
end;
50+
51+
end;
52+
/
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
create or replace package ut_session_context as
2+
/*
3+
utPLSQL - Version 3
4+
Copyright 2016 - 2019 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+
/*
20+
* Sets value of a context
21+
*/
22+
procedure set_context(a_name varchar2, a_value varchar2);
23+
24+
/*
25+
* Clears value of a context
26+
*/
27+
procedure clear_context(a_name varchar2);
28+
29+
/*
30+
* Clears entire context for utPLSQL run
31+
*/
32+
procedure clear_all_context;
33+
34+
/*
35+
* Returns true, if session context UT3_INFO is not empty
36+
*/
37+
function is_ut_run return boolean;
38+
39+
/*
40+
* Returns utPLSQL session context namespace name
41+
*/
42+
function get_namespace return varchar2;
43+
44+
end;
45+
/
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
create or replace type body ut_session_info as
2+
/*
3+
utPLSQL - Version 3
4+
Copyright 2016 - 2019 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_session_info(self in out nocopy ut_session_info) return self as result is
20+
begin
21+
self.self_type := $$plsql_unit;
22+
dbms_application_info.read_client_info( client_info );
23+
dbms_application_info.read_module( module, action );
24+
return;
25+
end;
26+
27+
-- run hooks
28+
member procedure before_calling_run(self in out nocopy ut_session_info, a_run in ut_run) is
29+
begin
30+
ut_session_context.set_context( 'run_paths', ut_utils.to_string( ut_utils.table_to_clob( a_run.run_paths,',' ), null ) );
31+
dbms_application_info.set_module( 'utPLSQL', null );
32+
end;
33+
34+
member procedure after_calling_run(self in out nocopy ut_session_info, a_run in ut_run) is
35+
begin
36+
ut_session_context.clear_context( 'run_paths' );
37+
dbms_application_info.set_module( module, action );
38+
dbms_application_info.set_client_info( client_info );
39+
end;
40+
41+
-- suite hooks
42+
member procedure before_calling_suite(self in out nocopy ut_session_info, a_suite in ut_logical_suite) is
43+
begin
44+
if a_suite is not of (ut_suite_context) then
45+
suite_start_time := a_suite.start_time;
46+
ut_session_context.set_context( 'suite_path', a_suite.path );
47+
ut_session_context.set_context( 'suite_package', a_suite.object_owner||'.'||a_suite.object_name );
48+
ut_session_context.set_context( 'suite_description', a_suite.description );
49+
ut_session_context.set_context( 'suite_start_time', ut_utils.to_string(suite_start_time) );
50+
dbms_application_info.set_module( 'utPLSQL', a_suite.object_name );
51+
else
52+
context_start_time := a_suite.start_time;
53+
ut_session_context.set_context( 'context_name', a_suite.name );
54+
ut_session_context.set_context( 'context_path', a_suite.path);
55+
ut_session_context.set_context( 'context_description', a_suite.description );
56+
ut_session_context.set_context( 'context_start_time', ut_utils.to_string(context_start_time) );
57+
end if;
58+
end;
59+
60+
member procedure after_calling_suite(self in out nocopy ut_session_info, a_suite in ut_logical_suite) is
61+
begin
62+
if a_suite is not of (ut_suite_context) then
63+
ut_session_context.clear_context( 'suite_package' );
64+
ut_session_context.clear_context( 'suite_path' );
65+
ut_session_context.clear_context( 'suite_description' );
66+
ut_session_context.clear_context( 'suite_start_time' );
67+
ut_session_context.clear_context( 'time_in_suite' );
68+
suite_start_time := null;
69+
else
70+
ut_session_context.clear_context( 'context_name' );
71+
ut_session_context.clear_context( 'context_path' );
72+
ut_session_context.clear_context( 'context_description' );
73+
ut_session_context.clear_context( 'context_start_time' );
74+
ut_session_context.clear_context( 'time_in_context' );
75+
context_start_time := null;
76+
end if;
77+
end;
78+
79+
80+
member procedure before_calling_test(self in out nocopy ut_session_info, a_test in ut_test) is
81+
begin
82+
test_start_time := a_test.start_time;
83+
ut_session_context.set_context( 'test_name', a_test.object_owner||'.'||a_test.object_name||'.'||a_test.name );
84+
ut_session_context.set_context( 'test_description', a_test.description );
85+
ut_session_context.set_context( 'test_start_time', ut_utils.to_string(test_start_time) );
86+
end;
87+
88+
member procedure after_calling_test (self in out nocopy ut_session_info, a_test in ut_test) is
89+
begin
90+
ut_session_context.clear_context( 'test_name' );
91+
ut_session_context.clear_context( 'test_description' );
92+
ut_session_context.clear_context( 'test_start_time' );
93+
ut_session_context.clear_context( 'time_in_test' );
94+
test_start_time := null;
95+
end;
96+
97+
member procedure before_calling_executable(self in out nocopy ut_session_info, a_executable in ut_executable) is
98+
begin
99+
ut_session_context.set_context( 'current_executable_type', a_executable.executable_type );
100+
ut_session_context.set_context(
101+
'current_executable_name',
102+
a_executable.owner_name||'.'||a_executable.object_name||'.'||a_executable.procedure_name
103+
);
104+
dbms_application_info.set_client_info( a_executable.procedure_name );
105+
if suite_start_time is not null then
106+
ut_session_context.set_context( 'time_in_suite', current_timestamp - suite_start_time );
107+
if context_start_time is not null then
108+
ut_session_context.set_context( 'time_in_context', current_timestamp - context_start_time );
109+
end if;
110+
if test_start_time is not null then
111+
ut_session_context.set_context( 'time_in_test', current_timestamp - test_start_time );
112+
end if;
113+
end if;
114+
end;
115+
116+
member procedure after_calling_executable(self in out nocopy ut_session_info, a_executable in ut_executable) is
117+
begin
118+
ut_session_context.clear_context( 'current_executable_type' );
119+
ut_session_context.clear_context( 'current_executable_name' );
120+
dbms_application_info.set_client_info( null );
121+
end;
122+
123+
member procedure on_finalize(self in out nocopy ut_session_info, a_run in ut_run) is
124+
begin
125+
dbms_application_info.set_client_info( client_info );
126+
dbms_application_info.set_module( module, action );
127+
ut_session_context.clear_all_context();
128+
end;
129+
130+
overriding member function get_supported_events return ut_varchar2_list is
131+
begin
132+
return ut_varchar2_list(
133+
ut_event_manager.gc_before_run,
134+
ut_event_manager.gc_before_suite,
135+
ut_event_manager.gc_before_test,
136+
ut_event_manager.gc_before_before_all,
137+
ut_event_manager.gc_before_before_each,
138+
ut_event_manager.gc_before_before_test,
139+
ut_event_manager.gc_before_test_execute,
140+
ut_event_manager.gc_before_after_test,
141+
ut_event_manager.gc_before_after_each,
142+
ut_event_manager.gc_before_after_all,
143+
ut_event_manager.gc_after_run,
144+
ut_event_manager.gc_after_suite,
145+
ut_event_manager.gc_after_test,
146+
ut_event_manager.gc_after_before_all,
147+
ut_event_manager.gc_after_before_each,
148+
ut_event_manager.gc_after_before_test,
149+
ut_event_manager.gc_after_test_execute,
150+
ut_event_manager.gc_after_after_test,
151+
ut_event_manager.gc_after_after_each,
152+
ut_event_manager.gc_after_after_all,
153+
ut_event_manager.gc_finalize
154+
);
155+
end;
156+
157+
overriding member procedure on_event( self in out nocopy ut_session_info, a_event_name varchar2, a_event_item ut_event_item) is
158+
begin
159+
case
160+
when a_event_name in (
161+
ut_event_manager.gc_before_before_all,
162+
ut_event_manager.gc_before_before_each,
163+
ut_event_manager.gc_before_before_test,
164+
ut_event_manager.gc_before_test_execute,
165+
ut_event_manager.gc_before_after_test,
166+
ut_event_manager.gc_before_after_each,
167+
ut_event_manager.gc_before_after_all
168+
)
169+
then before_calling_executable(treat(a_event_item as ut_executable));
170+
when a_event_name in (
171+
ut_event_manager.gc_after_before_all,
172+
ut_event_manager.gc_after_before_each,
173+
ut_event_manager.gc_after_before_test,
174+
ut_event_manager.gc_after_test_execute,
175+
ut_event_manager.gc_after_after_test,
176+
ut_event_manager.gc_after_after_each,
177+
ut_event_manager.gc_after_after_all
178+
)
179+
then after_calling_executable(treat(a_event_item as ut_executable));
180+
when a_event_name = ut_event_manager.gc_before_test
181+
then self.before_calling_test(treat(a_event_item as ut_test));
182+
when a_event_name = ut_event_manager.gc_after_test
183+
then self.after_calling_test(treat(a_event_item as ut_test));
184+
when a_event_name = ut_event_manager.gc_after_suite
185+
then after_calling_suite(treat(a_event_item as ut_logical_suite));
186+
when a_event_name = ut_event_manager.gc_before_suite
187+
then before_calling_suite(treat(a_event_item as ut_logical_suite));
188+
when a_event_name = ut_event_manager.gc_before_run
189+
then before_calling_run(treat(a_event_item as ut_run));
190+
when a_event_name = ut_event_manager.gc_after_run
191+
then after_calling_run(treat(a_event_item as ut_run));
192+
when a_event_name = ut_event_manager.gc_finalize
193+
then on_finalize(treat(a_event_item as ut_run));
194+
else null;
195+
end case;
196+
end;
197+
198+
end;
199+
/
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
create or replace type ut_session_info under ut_event_listener (
2+
/*
3+
utPLSQL - Version 3
4+
Copyright 2016 - 2019 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+
module varchar2(4000),
20+
action varchar2(4000),
21+
client_info varchar2(4000),
22+
suite_start_time timestamp,
23+
context_start_time timestamp,
24+
test_start_time timestamp,
25+
constructor function ut_session_info(self in out nocopy ut_session_info) return self as result,
26+
27+
member procedure before_calling_run(self in out nocopy ut_session_info, a_run in ut_run),
28+
member procedure after_calling_run (self in out nocopy ut_session_info, a_run in ut_run),
29+
30+
member procedure before_calling_suite(self in out nocopy ut_session_info, a_suite in ut_logical_suite),
31+
member procedure after_calling_suite(self in out nocopy ut_session_info, a_suite in ut_logical_suite),
32+
33+
member procedure before_calling_executable(self in out nocopy ut_session_info, a_executable in ut_executable),
34+
member procedure after_calling_executable (self in out nocopy ut_session_info, a_executable in ut_executable),
35+
36+
member procedure before_calling_test(self in out nocopy ut_session_info, a_test in ut_test),
37+
member procedure after_calling_test (self in out nocopy ut_session_info, a_test in ut_test),
38+
39+
member procedure on_finalize(self in out nocopy ut_session_info, a_run in ut_run),
40+
41+
/**
42+
* Returns the list of events that are supported by particular implementation of the reporter
43+
*/
44+
overriding member function get_supported_events return ut_varchar2_list,
45+
46+
/**
47+
* Delegates execution of event into individual reporting procedures
48+
*/
49+
overriding member procedure on_event( self in out nocopy ut_session_info, a_event_name varchar2, a_event_item ut_event_item)
50+
51+
) final
52+
/

source/core/types/ut_executable.tpb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,6 @@ create or replace type body ut_executable is
104104
begin
105105
l_start_transaction_id := dbms_transaction.local_transaction_id(true);
106106

107-
-- report to application_info
108-
ut_utils.set_client_info(self.procedure_name);
109-
110107
--listener - before call to executable
111108
ut_event_manager.trigger_event('before_'||self.executable_type, self);
112109

@@ -173,7 +170,6 @@ create or replace type body ut_executable is
173170
if l_start_transaction_id != l_end_transaction_id or l_end_transaction_id is null then
174171
a_item.add_transaction_invalidator(self.form_name());
175172
end if;
176-
ut_utils.set_client_info(null);
177173

178174
return l_completed_without_errors;
179175

0 commit comments

Comments
 (0)