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

Skip to content

Commit 5cd94f4

Browse files
authored
Merge pull request #556 from AlexisGaldamez/expect_closed_cur_raise_exec
When a closed cursor is passed to expect, it throws a exception
2 parents 5c6f426 + 655e5e9 commit 5cd94f4

3 files changed

Lines changed: 95 additions & 63 deletions

File tree

source/expectations/data_values/ut_data_value_refcursor.tpb

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -42,49 +42,58 @@ create or replace type body ut_data_value_refcursor as
4242
c_bulk_rows constant integer := 1000;
4343
l_current_date_format varchar2(4000);
4444
l_ut_owner varchar2(250) := ut_utils.ut_owner;
45+
cursor_not_open exception;
4546
begin
4647
self.is_cursor_null := ut_utils.boolean_to_int(a_value is null);
4748
self.self_type := $$plsql_unit;
4849
self.data_value := sys_guid();
4950
self.data_type := 'refcursor';
50-
if a_value is not null and a_value%isopen then
51-
self.row_count := 0;
52-
-- We use DBMS_XMLGEN in order to:
53-
-- 1) be able to process data in bulks (set of rows)
54-
-- 2) be able to influence the ROWSET/ROW tags
55-
-- 3) be able to influence the way NULL values are handled (empty TAG)
56-
-- 4) be able to influence the way TIMESTAMP is formatted.
57-
-- Due to Oracle feature/bug, it is not possible to change the DATE formatting of cursor data
58-
-- AFTER the cursor was opened.
59-
-- The only solution for this is to change NLS settings before opening the cursor.
60-
--
61-
-- This would work fine if we could use DBMS_XMLGEN.restartQuery.
62-
-- The restartQuery fails however if PLSQL variables of TIMESTAMP/INTERVAL or CLOB/BLOB are used.
63-
64-
ut_expectation_processor.set_xml_nls_params();
65-
l_ctx := dbms_xmlgen.newContext(a_value);
66-
dbms_xmlgen.setNullHandling(l_ctx, dbms_xmlgen.empty_tag);
67-
dbms_xmlgen.setMaxRows(l_ctx, c_bulk_rows);
68-
69-
loop
70-
l_xml := dbms_xmlgen.getxmltype(l_ctx);
71-
72-
execute immediate 'insert into ' || l_ut_owner || '.ut_cursor_data(cursor_data_guid, row_no, row_data)
73-
select :self_guid, :self_row_count + rownum, value(a) from table( xmlsequence( extract(:l_xml,''ROWSET/*'') ) ) a'
74-
using in self.data_value, self.row_count, l_xml;
75-
76-
exit when sql%rowcount = 0;
77-
78-
self.row_count := self.row_count + sql%rowcount;
79-
end loop;
8051

81-
ut_expectation_processor.reset_nls_params();
82-
if a_value%isopen then
83-
close a_value;
84-
end if;
85-
dbms_xmlgen.closeContext(l_ctx);
52+
if a_value is not null then
53+
if a_value%isopen then
54+
self.row_count := 0;
55+
-- We use DBMS_XMLGEN in order to:
56+
-- 1) be able to process data in bulks (set of rows)
57+
-- 2) be able to influence the ROWSET/ROW tags
58+
-- 3) be able to influence the way NULL values are handled (empty TAG)
59+
-- 4) be able to influence the way TIMESTAMP is formatted.
60+
-- Due to Oracle feature/bug, it is not possible to change the DATE formatting of cursor data
61+
-- AFTER the cursor was opened.
62+
-- The only solution for this is to change NLS settings before opening the cursor.
63+
--
64+
-- This would work fine if we could use DBMS_XMLGEN.restartQuery.
65+
-- The restartQuery fails however if PLSQL variables of TIMESTAMP/INTERVAL or CLOB/BLOB are used.
66+
67+
ut_expectation_processor.set_xml_nls_params();
68+
l_ctx := dbms_xmlgen.newContext(a_value);
69+
dbms_xmlgen.setNullHandling(l_ctx, dbms_xmlgen.empty_tag);
70+
dbms_xmlgen.setMaxRows(l_ctx, c_bulk_rows);
71+
72+
loop
73+
l_xml := dbms_xmlgen.getxmltype(l_ctx);
74+
75+
execute immediate 'insert into ' || l_ut_owner || '.ut_cursor_data(cursor_data_guid, row_no, row_data)
76+
select :self_guid, :self_row_count + rownum, value(a) from table( xmlsequence( extract(:l_xml,''ROWSET/*'') ) ) a'
77+
using in self.data_value, self.row_count, l_xml;
78+
79+
exit when sql%rowcount = 0;
80+
81+
self.row_count := self.row_count + sql%rowcount;
82+
end loop;
83+
84+
ut_expectation_processor.reset_nls_params();
85+
if a_value%isopen then
86+
close a_value;
87+
end if;
88+
dbms_xmlgen.closeContext(l_ctx);
89+
90+
elsif not a_value%isopen then
91+
raise cursor_not_open;
92+
end if;
8693
end if;
8794
exception
95+
when cursor_not_open then
96+
raise_application_error(-20155, 'Cursor is not open');
8897
when others then
8998
ut_expectation_processor.reset_nls_params();
9099
if a_value%isopen then
@@ -160,9 +169,9 @@ create or replace type body ut_data_value_refcursor as
160169
ucd.row_no
161170
from ' || l_ut_owner || '.ut_cursor_data ucd where ucd.cursor_data_guid = :l_other_guid) act
162171
on (exp.row_no = act.row_no)
163-
where nvl(dbms_lob.compare(xmlserialize( content exp.row_data no indent), xmlserialize( content act.row_data no indent)),1) != 0'
172+
where nvl(dbms_lob.compare(xmlserialize( content exp.row_data no indent), xmlserialize( content act.row_data no indent)),1) != 0'
164173
using in l_xpath, l_xpath, self.DATA_VALUE, l_xpath, l_xpath, l_other.DATA_VALUE;
165-
174+
166175
--result is OK only if both are same
167176
if sql%rowcount = 0 and self.row_count = l_other.row_count then
168177
l_result := 0;

test/core/expectations/test_expectations_cursor.pkb

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -101,25 +101,45 @@ create or replace package body test_expectations_cursor is
101101
ut.expect(ut3.ut_expectation_processor.get_status()).to_equal(ut3.ut_utils.tr_success);
102102
end;
103103

104-
procedure success_is_null
104+
procedure success_to_be_null
105105
as
106106
l_actual sys_refcursor;
107107
begin
108108
--Act
109109
ut3.ut.expect( l_actual ).to_be_null();
110+
--Assert
111+
ut.expect(ut3.ut_expectation_processor.get_status()).to_equal(ut3.ut_utils.tr_success);
112+
end;
113+
114+
procedure success_not_to_be_not_null
115+
as
116+
l_actual sys_refcursor;
117+
begin
118+
--Act
110119
ut3.ut.expect( l_actual ).not_to_be_not_null();
111120
--Assert
112121
ut.expect(ut3.ut_expectation_processor.get_status()).to_equal(ut3.ut_utils.tr_success);
113122
end;
114123

115-
procedure success_is_not_null
124+
procedure success_not_to_be_null
125+
as
126+
l_actual sys_refcursor;
127+
begin
128+
--Arrange
129+
open l_actual for select * from dual;
130+
--Act
131+
ut3.ut.expect( l_actual ).to_be_not_null();
132+
--Assert
133+
ut.expect(ut3.ut_expectation_processor.get_status()).to_equal(ut3.ut_utils.tr_success);
134+
end;
135+
136+
procedure success_to_be_not_null
116137
as
117138
l_actual sys_refcursor;
118139
begin
119140
--Arrange
120141
open l_actual for select * from dual;
121142
--Act
122-
ut3.ut.expect( l_actual ).not_to_be_null();
123143
ut3.ut.expect( l_actual ).to_be_not_null();
124144
--Assert
125145
ut.expect(ut3.ut_expectation_processor.get_status()).to_equal(ut3.ut_utils.tr_success);
@@ -331,7 +351,7 @@ procedure fail_on_different_column_order
331351
l_expected sys_refcursor;
332352
begin
333353
--Arrange
334-
open l_actual for select a.*, 'a' as "A_Column", 'c' as A_COLUMN, 'x' SOME_COL, 'd' "Some_Col" from all_objects a where rownum < 4;
354+
open l_actual for select a.*, 'a' as "A_Column", 'c' as A_COLUMN, 'x' SOME_COL, 'd' "Some_Col" from all_objects a where rownum < 4;
335355
open l_expected for select a.*, 'a' as "A_Column", 'd' as A_COLUMN, 'x' SOME_COL, 'c' "Some_Col" from all_objects a where rownum < 4;
336356
--Act
337357
ut3.ut.expect(l_actual).to_equal(l_expected, a_exclude=>ut3.ut_varchar2_list('A_COLUMN','Some_Col'));
@@ -515,22 +535,20 @@ was expected to equal:%
515535
end;
516536
end;
517537

518-
procedure reports_on_closed_cursor
519-
as
520-
l_actual sys_refcursor;
521-
l_error_code integer := -19202; --Error occurred in XML processing
538+
procedure exception_when_closed_cursor
539+
is
540+
l_actual sys_refcursor;
541+
l_error_code constant integer := -20155;
522542
begin
523-
--Act
524-
open l_actual for select 1 as value from dual connect by level < 10;
543+
--Arrange
544+
open l_actual for select * from dual;
525545
close l_actual;
526-
begin
527-
ut3.ut.expect(l_actual).to_be_empty();
528-
--Assert
529-
ut.fail('Expected '||l_error_code||' but nothing was raised');
530-
exception
531-
when others then
532-
ut.expect(sqlcode).to_equal(l_error_code);
533-
end;
546+
--Act
547+
ut3.ut.expect( l_actual ).not_to_be_null;
548+
exception
549+
when others then
550+
--Assert
551+
ut.expect(sqlcode).to_equal(l_error_code);
534552
end;
535553

536554
procedure compares_over_1000_rows

test/core/expectations/test_expectations_cursor.pks

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,17 @@ create or replace package test_expectations_cursor is
2323
--%test(Gives success when both cursors are null)
2424
procedure success_on_both_null;
2525

26-
--%test(Gives success on is_null if cursor is null)
27-
procedure success_is_null;
26+
--%test(Gives success on to_be_null if cursor is null)
27+
procedure success_to_be_null;
2828

29-
--%test(Gives success on is_not_null if cursor is not null)
30-
procedure success_is_not_null;
29+
--%test(Gives succes on not_to_be_not_null if cursor is null)
30+
procedure success_not_to_be_not_null;
31+
32+
--%test(Gives success on not_to_be_null if cursor is not null)
33+
procedure success_not_to_be_null;
34+
35+
--%test(Gives success on to_be_not_null if cursor is not null)
36+
procedure success_to_be_not_null;
3137

3238
--%test(Gives success on is_empty if cursor is empty)
3339
procedure success_is_empty;
@@ -107,12 +113,11 @@ create or replace package test_expectations_cursor is
107113
--%test(Reports exception when cursor raises exception)
108114
procedure reports_on_exception_in_cursor;
109115

110-
--%test(Reports exception when cursor is closed)
111-
--%disabled
112-
procedure reports_on_closed_cursor;
116+
--%test(Reports an exception when cursor is closed)
117+
procedure exception_when_closed_cursor;
113118

114119
--%test(Compares cursors with more than 1000 rows)
115120
procedure compares_over_1000_rows;
116121

117122
end;
118-
/
123+
/

0 commit comments

Comments
 (0)