From b1f632389af6bc7912a75d44103908a2a447cbb0 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Mon, 17 Dec 2018 19:11:04 +0100 Subject: [PATCH 01/38] Initial, incomplete version of reporter --- source/reporters/ut_sqldev_reporter.tpb | 93 +++++++++++++++++++++++++ source/reporters/ut_sqldev_reporter.tps | 56 +++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 source/reporters/ut_sqldev_reporter.tpb create mode 100644 source/reporters/ut_sqldev_reporter.tps diff --git a/source/reporters/ut_sqldev_reporter.tpb b/source/reporters/ut_sqldev_reporter.tpb new file mode 100644 index 000000000..2288dfa86 --- /dev/null +++ b/source/reporters/ut_sqldev_reporter.tpb @@ -0,0 +1,93 @@ +create or replace type body ut_sqldev_reporter is + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + + constructor function ut_sqldev_reporter(self in out nocopy ut_sqldev_reporter) return self as result is + begin + self.init($$plsql_unit); + return; + end; + + overriding member procedure before_calling_run(self in out nocopy ut_sqldev_reporter, a_run in ut_run) is + procedure print_test_elements(a_test ut_test) is + begin + self.print_text(''); + end; + + procedure print_suite_elements(a_suite ut_logical_suite) is + begin + self.print_text(''); + for i in 1 .. a_suite.items.count loop + if a_suite.items(i) is of(ut_test) then + print_test_elements(treat(a_suite.items(i) as ut_test)); + elsif a_suite.items(i) is of(ut_logical_suite) then + print_suite_elements(treat(a_suite.items(i) as ut_logical_suite)); + end if; + end loop; + self.print_text(''); + end; + + begin + self.print_text(ut_utils.get_xml_header(a_run.client_character_set)); + self.print_text(''); + self.print_text(''); + self.print_text(''); + for i in 1 .. a_run.items.count loop + print_suite_elements(treat(a_run.items(i) as ut_logical_suite)); + end loop; + self.print_text(''); + self.print_text(''); + self.print_text(''); + end; + + overriding member procedure before_calling_test(self in out nocopy ut_sqldev_reporter, a_test in ut_test) as + begin + self.print_text(''); + end; + + overriding member procedure after_calling_test(self in out nocopy ut_sqldev_reporter, a_test in ut_test) as + begin + self.print_text(''); + end; + + overriding member procedure after_calling_run(self in out nocopy ut_sqldev_reporter, a_run in ut_run) as + begin + self.print_text(''); + self.print_text(''); + end; + + overriding member function get_description return varchar2 as + begin + return 'Provides test results in a XML format, to consumed by clients such as SQL Developer interested progressing details.'; + end; + +end; +/ diff --git a/source/reporters/ut_sqldev_reporter.tps b/source/reporters/ut_sqldev_reporter.tps new file mode 100644 index 000000000..c5c4dc64e --- /dev/null +++ b/source/reporters/ut_sqldev_reporter.tps @@ -0,0 +1,56 @@ +create or replace type ut_sqldev_reporter force under ut_output_reporter_base( + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + + -- TODO: grant execute on ut_sqldev_reporter to public; + -- TODO: handle public synonym + -- TODO: unit test + + /** + * The SQL Developer reporter. + * Provides test results in a XML format, to consumed by clients such as SQL Developer interested progressing details. + */ + constructor function ut_sqldev_reporter(self in out nocopy ut_sqldev_reporter) return self as result, + + /** + * Provides meta data of complete run in advance. + * Used in IDE to show total tests and initialize a progress bar. + */ + overriding member procedure before_calling_run(self in out nocopy ut_sqldev_reporter, a_run in ut_run), + + /** + * Provides meta data of test to be called. + */ + overriding member procedure before_calling_test(self in out nocopy ut_sqldev_reporter, a_test in ut_test), + + /** + * Provides meta data of a completed test with runtime, status, + */ + overriding member procedure after_calling_test(self in out nocopy ut_sqldev_reporter, a_test in ut_test), + + /** + * Provides closing tag with runtime summary. + */ + overriding member procedure after_calling_run(self in out nocopy ut_sqldev_reporter, a_run in ut_run), + + /** + * Provides the description of this reporter. + */ + overriding member function get_description return varchar2 +) +not final +/ From e83eeaf64d08b0c4649a1e2d0f4bb2353c7b63bb Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Mon, 17 Dec 2018 19:52:35 +0100 Subject: [PATCH 02/38] added grants ans synonyms for ut_sqldev_reporter --- source/create_synonyms_and_grants_for_public.sql | 2 ++ source/create_user_grants.sql | 1 + source/create_user_synonyms.sql | 1 + source/install.sql | 2 ++ source/uninstall_objects.sql | 2 ++ 5 files changed, 8 insertions(+) diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql index b8daca313..e24b8880d 100644 --- a/source/create_synonyms_and_grants_for_public.sql +++ b/source/create_synonyms_and_grants_for_public.sql @@ -97,6 +97,7 @@ grant execute on &&ut3_owner..ut_annotation_objs_cache_info to public; grant execute on &&ut3_owner..ut_annotation_obj_cache_info to public; grant execute on &&ut3_owner..ut_suite_items_info to public; grant execute on &&ut3_owner..ut_suite_item_info to public; +grant execute on &&ut3_owner..ut_sqldev_reporter to public; begin $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then execute immediate 'grant select, insert, delete, update on &&ut3_owner..dbmspcc_blocks to public'; @@ -156,6 +157,7 @@ create public synonym ut_key_value_pair for &&ut3_owner..ut_key_value_pair; create public synonym ut_sonar_test_reporter for &&ut3_owner..ut_sonar_test_reporter; create public synonym ut_suite_items_info for &&ut3_owner..ut_suite_items_info; create public synonym ut_suite_item_info for &&ut3_owner..ut_suite_item_info; +create public synonym ut_sqldev_reporter for &&ut3_owner..ut_sqldev_reporter; begin $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then execute immediate 'create public synonym dbmspcc_blocks for &&ut3_owner..dbmspcc_blocks'; diff --git a/source/create_user_grants.sql b/source/create_user_grants.sql index 0967a0e8c..17f20ee09 100644 --- a/source/create_user_grants.sql +++ b/source/create_user_grants.sql @@ -115,6 +115,7 @@ grant execute on &&ut3_owner..ut_annotation_cache_manager to &ut3_user; grant execute on &&ut3_owner..ut_annotation_parser to &ut3_user; grant execute on &&ut3_owner..ut_annotation_objs_cache_info to &ut3_user; grant execute on &&ut3_owner..ut_annotation_obj_cache_info to &ut3_user; +grant execute on &&ut3_owner..ut_sqldev_reporter to &ut3_user; begin $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then execute immediate 'grant select, insert, delete, update on &&ut3_owner..dbmspcc_blocks to &ut3_user'; diff --git a/source/create_user_synonyms.sql b/source/create_user_synonyms.sql index 9a087f61a..88b48eee0 100644 --- a/source/create_user_synonyms.sql +++ b/source/create_user_synonyms.sql @@ -98,6 +98,7 @@ create or replace synonym &ut3_user..ut_key_value_pairs for &&ut3_owner..ut_key_ create or replace synonym &ut3_user..ut_key_value_pair for &&ut3_owner..ut_key_value_pair; create or replace synonym &ut3_user..ut_compound_data_tmp for &&ut3_owner..ut_cursor_data; create or replace synonym &ut3_user..ut_sonar_test_reporter for &&ut3_owner..ut_sonar_test_reporter; +create or replace synonym &ut3_user..ut_sqldev_reporter for &&ut3_owner..ut_sqldev_reporter; begin $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then execute immediate 'create or replace synonym &ut3_user..dbmspcc_blocks for &&ut3_owner..dbmspcc_blocks'; diff --git a/source/install.sql b/source/install.sql index 50d70c944..defa3da49 100644 --- a/source/install.sql +++ b/source/install.sql @@ -292,6 +292,8 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema @@install_component.sql 'reporters/ut_coveralls_reporter.tpb' @@install_component.sql 'reporters/ut_coverage_cobertura_reporter.tps' @@install_component.sql 'reporters/ut_coverage_cobertura_reporter.tpb' +@@install_component.sql 'reporters/ut_sqldev_reporter.tps' +@@install_component.sql 'reporters/ut_sqldev_reporter.tpb' @@install_component.sql 'api/be_between.syn' @@install_component.sql 'api/be_empty.syn' diff --git a/source/uninstall_objects.sql b/source/uninstall_objects.sql index 97f2c5a5d..681ab862a 100644 --- a/source/uninstall_objects.sql +++ b/source/uninstall_objects.sql @@ -39,6 +39,8 @@ drop type ut_coverage_html_reporter force; drop type ut_sonar_test_reporter force; +drop type ut_sqldev_reporter force; + drop package ut_coverage; drop package ut_coverage_helper; From 99c1d31f97c1bf76fefbb4e904b37c86fcccdff0 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Thu, 27 Dec 2018 16:28:54 +0100 Subject: [PATCH 03/38] rename ut_sqldev_reporter to ut_realtime_reporter --- source/create_synonyms_and_grants_for_public.sql | 4 ++-- source/create_user_grants.sql | 2 +- source/create_user_synonyms.sql | 2 +- source/install.sql | 4 ++-- ...ldev_reporter.tpb => ut_realtime_reporter.tpb} | 12 ++++++------ ...ldev_reporter.tps => ut_realtime_reporter.tps} | 15 +++++++-------- source/uninstall_objects.sql | 2 +- 7 files changed, 20 insertions(+), 21 deletions(-) rename source/reporters/{ut_sqldev_reporter.tpb => ut_realtime_reporter.tpb} (90%) rename source/reporters/{ut_sqldev_reporter.tps => ut_realtime_reporter.tps} (77%) diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql index e24b8880d..5bacdb60c 100644 --- a/source/create_synonyms_and_grants_for_public.sql +++ b/source/create_synonyms_and_grants_for_public.sql @@ -97,7 +97,7 @@ grant execute on &&ut3_owner..ut_annotation_objs_cache_info to public; grant execute on &&ut3_owner..ut_annotation_obj_cache_info to public; grant execute on &&ut3_owner..ut_suite_items_info to public; grant execute on &&ut3_owner..ut_suite_item_info to public; -grant execute on &&ut3_owner..ut_sqldev_reporter to public; +grant execute on &&ut3_owner..ut_realtime_reporter to public; begin $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then execute immediate 'grant select, insert, delete, update on &&ut3_owner..dbmspcc_blocks to public'; @@ -157,7 +157,7 @@ create public synonym ut_key_value_pair for &&ut3_owner..ut_key_value_pair; create public synonym ut_sonar_test_reporter for &&ut3_owner..ut_sonar_test_reporter; create public synonym ut_suite_items_info for &&ut3_owner..ut_suite_items_info; create public synonym ut_suite_item_info for &&ut3_owner..ut_suite_item_info; -create public synonym ut_sqldev_reporter for &&ut3_owner..ut_sqldev_reporter; +create public synonym ut_realtime_reporter for &&ut3_owner..ut_realtime_reporter; begin $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then execute immediate 'create public synonym dbmspcc_blocks for &&ut3_owner..dbmspcc_blocks'; diff --git a/source/create_user_grants.sql b/source/create_user_grants.sql index 17f20ee09..a8f3d5cb4 100644 --- a/source/create_user_grants.sql +++ b/source/create_user_grants.sql @@ -115,7 +115,7 @@ grant execute on &&ut3_owner..ut_annotation_cache_manager to &ut3_user; grant execute on &&ut3_owner..ut_annotation_parser to &ut3_user; grant execute on &&ut3_owner..ut_annotation_objs_cache_info to &ut3_user; grant execute on &&ut3_owner..ut_annotation_obj_cache_info to &ut3_user; -grant execute on &&ut3_owner..ut_sqldev_reporter to &ut3_user; +grant execute on &&ut3_owner..ut_realtime_reporter to &ut3_user; begin $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then execute immediate 'grant select, insert, delete, update on &&ut3_owner..dbmspcc_blocks to &ut3_user'; diff --git a/source/create_user_synonyms.sql b/source/create_user_synonyms.sql index 88b48eee0..806f02e6e 100644 --- a/source/create_user_synonyms.sql +++ b/source/create_user_synonyms.sql @@ -98,7 +98,7 @@ create or replace synonym &ut3_user..ut_key_value_pairs for &&ut3_owner..ut_key_ create or replace synonym &ut3_user..ut_key_value_pair for &&ut3_owner..ut_key_value_pair; create or replace synonym &ut3_user..ut_compound_data_tmp for &&ut3_owner..ut_cursor_data; create or replace synonym &ut3_user..ut_sonar_test_reporter for &&ut3_owner..ut_sonar_test_reporter; -create or replace synonym &ut3_user..ut_sqldev_reporter for &&ut3_owner..ut_sqldev_reporter; +create or replace synonym &ut3_user..ut_realtime_reporter for &&ut3_owner..ut_realtime_reporter; begin $if dbms_db_version.version = 12 and dbms_db_version.release >= 2 or dbms_db_version.version > 12 $then execute immediate 'create or replace synonym &ut3_user..dbmspcc_blocks for &&ut3_owner..dbmspcc_blocks'; diff --git a/source/install.sql b/source/install.sql index defa3da49..a3a1dc715 100644 --- a/source/install.sql +++ b/source/install.sql @@ -292,8 +292,8 @@ prompt Installing DBMSPLSQL Tables objects into &&ut3_owner schema @@install_component.sql 'reporters/ut_coveralls_reporter.tpb' @@install_component.sql 'reporters/ut_coverage_cobertura_reporter.tps' @@install_component.sql 'reporters/ut_coverage_cobertura_reporter.tpb' -@@install_component.sql 'reporters/ut_sqldev_reporter.tps' -@@install_component.sql 'reporters/ut_sqldev_reporter.tpb' +@@install_component.sql 'reporters/ut_realtime_reporter.tps' +@@install_component.sql 'reporters/ut_realtime_reporter.tpb' @@install_component.sql 'api/be_between.syn' @@install_component.sql 'api/be_empty.syn' diff --git a/source/reporters/ut_sqldev_reporter.tpb b/source/reporters/ut_realtime_reporter.tpb similarity index 90% rename from source/reporters/ut_sqldev_reporter.tpb rename to source/reporters/ut_realtime_reporter.tpb index 2288dfa86..0f76ba8de 100644 --- a/source/reporters/ut_sqldev_reporter.tpb +++ b/source/reporters/ut_realtime_reporter.tpb @@ -1,4 +1,4 @@ -create or replace type body ut_sqldev_reporter is +create or replace type body ut_realtime_reporter is /* utPLSQL - Version 3 Copyright 2016 - 2018 utPLSQL Project @@ -16,13 +16,13 @@ create or replace type body ut_sqldev_reporter is limitations under the License. */ - constructor function ut_sqldev_reporter(self in out nocopy ut_sqldev_reporter) return self as result is + constructor function ut_realtime_reporter(self in out nocopy ut_realtime_reporter) return self as result is begin self.init($$plsql_unit); return; end; - overriding member procedure before_calling_run(self in out nocopy ut_sqldev_reporter, a_run in ut_run) is + overriding member procedure before_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run) is procedure print_test_elements(a_test ut_test) is begin self.print_text(''); end; - overriding member procedure before_calling_test(self in out nocopy ut_sqldev_reporter, a_test in ut_test) as + overriding member procedure before_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test) as begin self.print_text(''); end; - overriding member procedure after_calling_test(self in out nocopy ut_sqldev_reporter, a_test in ut_test) as + overriding member procedure after_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test) as begin self.print_text(''); end; - overriding member procedure after_calling_run(self in out nocopy ut_sqldev_reporter, a_run in ut_run) as + overriding member procedure after_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run) as begin self.print_text(''); self.print_text(''); diff --git a/source/reporters/ut_sqldev_reporter.tps b/source/reporters/ut_realtime_reporter.tps similarity index 77% rename from source/reporters/ut_sqldev_reporter.tps rename to source/reporters/ut_realtime_reporter.tps index c5c4dc64e..455361f79 100644 --- a/source/reporters/ut_sqldev_reporter.tps +++ b/source/reporters/ut_realtime_reporter.tps @@ -1,4 +1,4 @@ -create or replace type ut_sqldev_reporter force under ut_output_reporter_base( +create or replace type ut_realtime_reporter force under ut_output_reporter_base( /* utPLSQL - Version 3 Copyright 2016 - 2018 utPLSQL Project @@ -16,36 +16,35 @@ create or replace type ut_sqldev_reporter force under ut_output_reporter_base( limitations under the License. */ - -- TODO: grant execute on ut_sqldev_reporter to public; - -- TODO: handle public synonym -- TODO: unit test + -- TODO: add after suite to handle dbms_output and warnings on this level. /** * The SQL Developer reporter. * Provides test results in a XML format, to consumed by clients such as SQL Developer interested progressing details. */ - constructor function ut_sqldev_reporter(self in out nocopy ut_sqldev_reporter) return self as result, + constructor function ut_realtime_reporter(self in out nocopy ut_realtime_reporter) return self as result, /** * Provides meta data of complete run in advance. * Used in IDE to show total tests and initialize a progress bar. */ - overriding member procedure before_calling_run(self in out nocopy ut_sqldev_reporter, a_run in ut_run), + overriding member procedure before_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run), /** * Provides meta data of test to be called. */ - overriding member procedure before_calling_test(self in out nocopy ut_sqldev_reporter, a_test in ut_test), + overriding member procedure before_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test), /** * Provides meta data of a completed test with runtime, status, */ - overriding member procedure after_calling_test(self in out nocopy ut_sqldev_reporter, a_test in ut_test), + overriding member procedure after_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test), /** * Provides closing tag with runtime summary. */ - overriding member procedure after_calling_run(self in out nocopy ut_sqldev_reporter, a_run in ut_run), + overriding member procedure after_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run), /** * Provides the description of this reporter. diff --git a/source/uninstall_objects.sql b/source/uninstall_objects.sql index 681ab862a..c20868079 100644 --- a/source/uninstall_objects.sql +++ b/source/uninstall_objects.sql @@ -39,7 +39,7 @@ drop type ut_coverage_html_reporter force; drop type ut_sonar_test_reporter force; -drop type ut_sqldev_reporter force; +drop type ut_realtime_reporter force; drop package ut_coverage; From 6531e08e538fdeeec17df51c040f39feec7ae2ab Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Dec 2018 09:14:20 +0100 Subject: [PATCH 04/38] add initial test suite for ut_realtime_reporter --- .../core/reporters/test_realtime_reporter.pkb | 85 +++++++++++++++++++ .../core/reporters/test_realtime_reporter.pks | 15 ++++ 2 files changed, 100 insertions(+) create mode 100644 test/core/reporters/test_realtime_reporter.pkb create mode 100644 test/core/reporters/test_realtime_reporter.pks diff --git a/test/core/reporters/test_realtime_reporter.pkb b/test/core/reporters/test_realtime_reporter.pkb new file mode 100644 index 000000000..e6345d86c --- /dev/null +++ b/test/core/reporters/test_realtime_reporter.pkb @@ -0,0 +1,85 @@ +create or replace package body test_realtime_reporter as + + procedure create_test_suites is + pragma autonomous_transaction; + begin + execute immediate q'[create or replace package ut3_tester.check_realtime_reporting1 is + --%suite(suite ) + --%suitepath(realtime_reporting) + + --%context(test context) + + --%test(test 1 - OK) + procedure test_1_ok; + + --%test(test 2 - NOK) + procedure test_2_nok; + + --%endcontext + end;]'; + execute immediate q'[create or replace package body ut3_tester.check_realtime_reporting1 is + procedure test_1_ok is + begin + ut3.ut.expect(1).to_equal(1); + end; + + procedure test_2_nok is + begin + ut3.ut.expect(1).to_equal(2); + end; + end;]'; + + execute immediate q'[create or replace package ut3_tester.check_realtime_reporting2 is + --%suite + --%suitepath(realtime_reporting) + + --%test + procedure test_3_ok; + + --%test + procedure test_4_nok; + + --%test + --%disabled + procedure test_5; + end;]'; + execute immediate q'[create or replace package body ut3_tester.check_realtime_reporting2 is + procedure test_3_ok is + begin + ut3.ut.expect(2).to_equal(2); + end; + + procedure test_4_nok is + begin + ut3.ut.expect(2).to_equal(3); + end; + + procedure test_5 is + begin + null; + end; + end;]'; + commit; + end; + + procedure report_produces_expected_out is + l_results ut3.ut_varchar2_list; + l_actual clob; + l_expected varchar2(32767) := q'[%]'; + begin + select * + bulk collect into l_results + from table(ut3.ut.run('ut3_tester:realtime_reporting', ut3.ut_realtime_reporter())); + l_actual := ut3.ut_utils.table_to_clob(l_results); + ut.expect(l_actual).to_be_like(l_expected); + end; + + procedure remove_test_suites is + pragma autonomous_transaction; + begin + execute immediate 'drop package ut3_tester.check_realtime_reporting1'; + execute immediate 'drop package ut3_tester.check_realtime_reporting2'; + end; + +end; +/ diff --git a/test/core/reporters/test_realtime_reporter.pks b/test/core/reporters/test_realtime_reporter.pks new file mode 100644 index 000000000..8ced907e4 --- /dev/null +++ b/test/core/reporters/test_realtime_reporter.pks @@ -0,0 +1,15 @@ +create or replace package test_realtime_reporter as + + --%suite(ut_realtime_reporter) + --%suitepath(utplsql.core.reporters) + + --%beforeall + procedure create_test_suites; + + --%test(Report produces expected output) + procedure report_produces_expected_out; + + --%afterall + procedure remove_test_suites; +end; +/ From 28a1a73d8e7ddaa3df5f4e8f509a2c7335b74984 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Dec 2018 09:15:05 +0100 Subject: [PATCH 05/38] install test_realtime_reporter --- test/install_tests.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/install_tests.sql b/test/install_tests.sql index af67534d7..72e9a75e0 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -42,6 +42,7 @@ set define off @@core/reporters/test_coverage/test_coveralls_reporter.pks @@core/reporters/test_coverage/test_cov_cobertura_reporter.pks @@core/reporters/test_junit_reporter.pks +@@core/reporters/test_realtime_reporter.pks set define on @@install_below_12_2.sql 'core/reporters/test_coverage/test_html_proftab_reporter.pks' set define off @@ -92,6 +93,7 @@ set define off @@core/reporters/test_coverage/test_coveralls_reporter.pkb @@core/reporters/test_coverage/test_cov_cobertura_reporter.pkb @@core/reporters/test_junit_reporter.pkb +@@core/reporters/test_realtime_reporter.pkb set define on @@install_below_12_2.sql 'core/reporters/test_coverage/test_html_proftab_reporter.pkb' set define off From 010b8fd15d524a24120b41a6b4e2aa14515d7686 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Dec 2018 09:16:19 +0100 Subject: [PATCH 06/38] add ut_realtime_reporter to list of core reporters --- test/api/test_ut_runner.pkb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/api/test_ut_runner.pkb b/test/api/test_ut_runner.pkb index 96ae08a94..1cbf5d188 100644 --- a/test/api/test_ut_runner.pkb +++ b/test/api/test_ut_runner.pkb @@ -301,6 +301,7 @@ end;'; select 'UT3.UT_COVERALLS_REPORTER', 'Y' from dual union all select 'UT3.UT_DOCUMENTATION_REPORTER', 'Y' from dual union all select 'UT3.UT_JUNIT_REPORTER', 'Y' from dual union all + select 'UT3.UT_REALTIME_REPORTER', 'Y' from dual union all select 'UT3.UT_SONAR_TEST_REPORTER', 'Y' from dual union all select 'UT3.UT_TEAMCITY_REPORTER', 'Y' from dual union all select 'UT3.UT_TFS_JUNIT_REPORTER', 'Y' from dual union all From 9e79e6f8e2238a3216b821e0fa766276b7bbd8a7 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Dec 2018 09:20:31 +0100 Subject: [PATCH 07/38] use print_xml_fragment for pretty printing --- source/reporters/ut_realtime_reporter.tpb | 52 +++++++++++++++-------- source/reporters/ut_realtime_reporter.tps | 44 ++++++++++++++++--- 2 files changed, 72 insertions(+), 24 deletions(-) diff --git a/source/reporters/ut_realtime_reporter.tpb b/source/reporters/ut_realtime_reporter.tpb index 0f76ba8de..ade156c69 100644 --- a/source/reporters/ut_realtime_reporter.tpb +++ b/source/reporters/ut_realtime_reporter.tpb @@ -19,13 +19,14 @@ create or replace type body ut_realtime_reporter is constructor function ut_realtime_reporter(self in out nocopy ut_realtime_reporter) return self as result is begin self.init($$plsql_unit); + current_indent := 0; return; end; overriding member procedure before_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run) is procedure print_test_elements(a_test ut_test) is begin - self.print_text(''); + || ' description="' || a_suite.description || '">', 0, 1); for i in 1 .. a_suite.items.count loop if a_suite.items(i) is of(ut_test) then print_test_elements(treat(a_suite.items(i) as ut_test)); @@ -47,41 +48,46 @@ create or replace type body ut_realtime_reporter is print_suite_elements(treat(a_suite.items(i) as ut_logical_suite)); end if; end loop; - self.print_text(''); + self.print_xml_fragment('', -1); end; begin - self.print_text(ut_utils.get_xml_header(a_run.client_character_set)); - self.print_text(''); - self.print_text(''); - self.print_text(''); + self.print_xml_fragment(ut_utils.get_xml_header(a_run.client_character_set)); + self.print_xml_fragment('', 0, 1); + self.print_xml_fragment('', 0, 1); + self.print_xml_fragment('', 0, 1); for i in 1 .. a_run.items.count loop print_suite_elements(treat(a_run.items(i) as ut_logical_suite)); end loop; - self.print_text(''); - self.print_text(''); - self.print_text(''); + self.print_xml_fragment('', -1); + self.print_xml_fragment('', -1); + self.print_xml_fragment('', 0, 1); end; overriding member procedure before_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test) as begin - self.print_text(''); + || ' disabled="' || case when a_test.get_disabled_flag() then 'true' else 'false' end || '"/>', 1, -1); end; overriding member procedure after_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test) as begin - self.print_text(''); + self.print_xml_fragment(''); end; - + + overriding member procedure after_calling_suite(self in out nocopy ut_realtime_reporter, a_suite in ut_logical_suite) as + begin + self.print_xml_fragment(''); + end; + overriding member procedure after_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run) as begin - self.print_text(''); - self.print_text(''); + self.print_xml_fragment('', -1); + self.print_xml_fragment('', -1); end; overriding member function get_description return varchar2 as @@ -89,5 +95,17 @@ create or replace type body ut_realtime_reporter is return 'Provides test results in a XML format, to consumed by clients such as SQL Developer interested progressing details.'; end; + member procedure print_xml_fragment( + self in out nocopy ut_realtime_reporter, + a_fragment in varchar2, + a_indent_summand_before in integer default 0, + a_indent_summand_after in integer default 0 + ) as + begin + current_indent := current_indent + a_indent_summand_before; + self.print_text(lpad(' ', 2 * current_indent) || a_fragment); + current_indent := current_indent + a_indent_summand_after; + end; + end; / diff --git a/source/reporters/ut_realtime_reporter.tps b/source/reporters/ut_realtime_reporter.tps index 455361f79..880bab080 100644 --- a/source/reporters/ut_realtime_reporter.tps +++ b/source/reporters/ut_realtime_reporter.tps @@ -15,19 +15,31 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( See the License for the specific language governing permissions and limitations under the License. */ - - -- TODO: unit test - -- TODO: add after suite to handle dbms_output and warnings on this level. /** - * The SQL Developer reporter. + * Private attribute containing the total number of all tests in the run (incl. disabled tests). + */ + total_number_of_tests integer, + + /** + * Private attribute containing the currently executed test. + */ + current_test_number integer, + + /** + * Private attribute containing the current indentation in logical tabs. + */ + current_indent integer, + + /** + * The realtime reporter. * Provides test results in a XML format, to consumed by clients such as SQL Developer interested progressing details. */ constructor function ut_realtime_reporter(self in out nocopy ut_realtime_reporter) return self as result, /** * Provides meta data of complete run in advance. - * Used in IDE to show total tests and initialize a progress bar. + * Used to show total tests and initialize a progress bar. */ overriding member procedure before_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run), @@ -37,10 +49,15 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( overriding member procedure before_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test), /** - * Provides meta data of a completed test with runtime, status, + * Provides meta data of a completed test with runtime and status. */ overriding member procedure after_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test), + /** + * Provides meta data of completed test suite with runtime. + */ + overriding member procedure after_calling_suite(self in out nocopy ut_realtime_reporter, a_suite in ut_logical_suite), + /** * Provides closing tag with runtime summary. */ @@ -49,7 +66,20 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( /** * Provides the description of this reporter. */ - overriding member function get_description return varchar2 + overriding member function get_description return varchar2, + + /** + * Private procedure to print a line of the resulting XML document using the current indentation. + * a_indent_summand_before is added before printing a line. + * a_indent_summand_after is added after printing a line. + * All output is produced through this function. + */ + member procedure print_xml_fragment( + self in out nocopy ut_realtime_reporter, + a_fragment in varchar2, + a_indent_summand_before in integer default 0, + a_indent_summand_after in integer default 0 + ) ) not final / From 4b29c564643f270358b4215c8a7827694b37f419 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Dec 2018 19:49:57 +0100 Subject: [PATCH 08/38] changed formatting and comments --- source/reporters/ut_realtime_reporter.tps | 95 +++++++++++++++++++---- 1 file changed, 78 insertions(+), 17 deletions(-) diff --git a/source/reporters/ut_realtime_reporter.tps b/source/reporters/ut_realtime_reporter.tps index 880bab080..d6c7776cc 100644 --- a/source/reporters/ut_realtime_reporter.tps +++ b/source/reporters/ut_realtime_reporter.tps @@ -17,51 +17,77 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( */ /** - * Private attribute containing the total number of all tests in the run (incl. disabled tests). + * Total number of all tests in the run (incl. disabled tests). */ total_number_of_tests integer, /** - * Private attribute containing the currently executed test. + * Currently executed test number. */ current_test_number integer, /** - * Private attribute containing the current indentation in logical tabs. + * Current indentation in logical tabs. */ current_indent integer, /** * The realtime reporter. - * Provides test results in a XML format, to consumed by clients such as SQL Developer interested progressing details. + * Provides test results in a XML format, for clients such as SQL Developer interested progressing details. */ - constructor function ut_realtime_reporter(self in out nocopy ut_realtime_reporter) return self as result, + constructor function ut_realtime_reporter( + self in out nocopy ut_realtime_reporter + ) return self as result, /** * Provides meta data of complete run in advance. * Used to show total tests and initialize a progress bar. */ - overriding member procedure before_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run), + overriding member procedure before_calling_run( + self in out nocopy ut_realtime_reporter, + a_run in ut_run + ), /** - * Provides meta data of test to be called. + * Provides closing tag with runtime summary. */ - overriding member procedure before_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test), + overriding member procedure after_calling_run( + self in out nocopy ut_realtime_reporter, + a_run in ut_run + ), /** - * Provides meta data of a completed test with runtime and status. + * Indicates the start of a test suite execution. */ - overriding member procedure after_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test), + overriding member procedure before_calling_suite( + self in out nocopy ut_realtime_reporter, + a_suite in ut_logical_suite + ), /** * Provides meta data of completed test suite with runtime. */ - overriding member procedure after_calling_suite(self in out nocopy ut_realtime_reporter, a_suite in ut_logical_suite), + overriding member procedure after_calling_suite( + self in out nocopy ut_realtime_reporter, + a_suite in ut_logical_suite + ), + /** - * Provides closing tag with runtime summary. + * Indicates the start of a test. + */ + overriding member procedure before_calling_test( + self in out nocopy ut_realtime_reporter, + a_test in ut_test + ), + + /** + * Provides meta data of a completed test with runtime and status. */ - overriding member procedure after_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run), + overriding member procedure after_calling_test( + self in out nocopy ut_realtime_reporter, + a_test in ut_test + ), /** * Provides the description of this reporter. @@ -69,16 +95,51 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( overriding member function get_description return varchar2, /** - * Private procedure to print a line of the resulting XML document using the current indentation. + * Prints the start tag of an XML with an optional id attribute. + */ + member procedure print_start_node( + self in out nocopy ut_realtime_reporter, + a_name in varchar2, + a_id in varchar2 default null + ), + + /** + * Prints the end tag of an XML node. + */ + member procedure print_end_node( + self in out nocopy ut_realtime_reporter, + a_name in varchar2 + ), + + /** + * Prints a child node with content. Content will be XML encoded. + */ + member procedure print_node( + self in out nocopy ut_realtime_reporter, + a_name in varchar2, + a_content in clob + ), + + /** + * Prints a child node with content. Content is passed 1:1 incl. new lines, etc. using CDATA. + */ + member procedure print_cdata_node( + self in out nocopy ut_realtime_reporter, + a_name in varchar2, + a_content in clob + ), + + /** + * Prints a line of the resulting XML document using the current indentation. * a_indent_summand_before is added before printing a line. * a_indent_summand_after is added after printing a line. * All output is produced through this function. */ member procedure print_xml_fragment( self in out nocopy ut_realtime_reporter, - a_fragment in varchar2, - a_indent_summand_before in integer default 0, - a_indent_summand_after in integer default 0 + a_fragment in clob, + a_indent_summand_before in integer default 0, + a_indent_summand_after in integer default 0 ) ) not final From 2f22a8955e2f42ea06c9e5a5ecf8dfbb5201ef8b Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Dec 2018 19:51:07 +0100 Subject: [PATCH 09/38] new XML report format, using XML attributes for id only --- source/reporters/ut_realtime_reporter.tpb | 231 +++++++++++++++++----- 1 file changed, 177 insertions(+), 54 deletions(-) diff --git a/source/reporters/ut_realtime_reporter.tpb b/source/reporters/ut_realtime_reporter.tpb index ade156c69..179cab95c 100644 --- a/source/reporters/ut_realtime_reporter.tpb +++ b/source/reporters/ut_realtime_reporter.tpb @@ -16,96 +16,219 @@ create or replace type body ut_realtime_reporter is limitations under the License. */ - constructor function ut_realtime_reporter(self in out nocopy ut_realtime_reporter) return self as result is + constructor function ut_realtime_reporter( + self in out nocopy ut_realtime_reporter + ) return self as result is begin self.init($$plsql_unit); + total_number_of_tests := 0; + current_test_number := 0; current_indent := 0; return; end; - overriding member procedure before_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run) is - procedure print_test_elements(a_test ut_test) is + overriding member procedure before_calling_run( + self in out nocopy ut_realtime_reporter, + a_run in ut_run + ) is + procedure print_test_elements( + a_test in ut_test + ) is begin - self.print_xml_fragment(''); - end; + total_number_of_tests := total_number_of_tests + 1; + self.print_start_node('test', a_test.path); + self.print_node('executableType', a_test.item.executable_type); + self.print_node('ownerName', a_test.item.owner_name); + self.print_node('objectName', a_test.item.object_name); + self.print_node('procedureName', a_test.item.procedure_name); + self.print_node('disabled', case when a_test.get_disabled_flag() then 'true' else 'false' end); + self.print_node('name', a_test.name); + self.print_node('description', a_test.description); + self.print_node('testNumber', to_char(total_number_of_tests)); + self.print_end_node('test'); + end print_test_elements; - procedure print_suite_elements(a_suite ut_logical_suite) is + procedure print_suite_elements( + a_suite in ut_logical_suite + ) is begin - self.print_xml_fragment('', 0, 1); + self.print_start_node('suite', a_suite.path); + self.print_node('name', a_suite.name); + self.print_node('description', a_suite.description); + <> for i in 1 .. a_suite.items.count loop if a_suite.items(i) is of(ut_test) then print_test_elements(treat(a_suite.items(i) as ut_test)); elsif a_suite.items(i) is of(ut_logical_suite) then print_suite_elements(treat(a_suite.items(i) as ut_logical_suite)); end if; - end loop; - self.print_xml_fragment('', -1); - end; - + end loop suite_elements; + self.print_end_node('suite'); + end print_suite_elements; begin self.print_xml_fragment(ut_utils.get_xml_header(a_run.client_character_set)); - self.print_xml_fragment('', 0, 1); - self.print_xml_fragment('', 0, 1); - self.print_xml_fragment('', 0, 1); + self.print_start_node('report'); + self.print_start_node('preRun'); + self.print_start_node('suites'); + <> for i in 1 .. a_run.items.count loop print_suite_elements(treat(a_run.items(i) as ut_logical_suite)); - end loop; - self.print_xml_fragment('', -1); - self.print_xml_fragment('', -1); - self.print_xml_fragment('', 0, 1); - end; + end loop items; + self.print_end_node('suites'); + self.print_node('totalNumberOfTests', to_char(total_number_of_tests)); + self.print_end_node('preRun'); + self.print_start_node('runEvents'); + end before_calling_run; + + overriding member procedure after_calling_run( + self in out nocopy ut_realtime_reporter, + a_run in ut_run + ) is + begin + self.print_xml_fragment('', -1); + self.print_xml_fragment('', -1); + end after_calling_run; - overriding member procedure before_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test) as + overriding member procedure before_calling_suite( + self in out nocopy ut_realtime_reporter, + a_suite in ut_logical_suite + ) is begin - self.print_xml_fragment('', 1, -1); - end; + self.print_start_node('startSuiteEvent', a_suite.path); + self.print_end_node('startSuiteEvent'); + end before_calling_suite; + + overriding member procedure after_calling_suite( + self in out nocopy ut_realtime_reporter, + a_suite in ut_logical_suite + ) is + begin + self.print_start_node('endSuiteEvent', a_suite.path); + self.print_node('startTime', to_char(a_suite.start_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6')); + self.print_node('endTime', to_char(a_suite.end_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6')); + self.print_node('executionTime', ut_utils.to_xml_number_format(a_suite.execution_time())); + self.print_start_node('counter'); + self.print_node('disabled', to_char(a_suite.results_count.disabled_count)); + self.print_node('success', to_char(a_suite.results_count.success_count)); + self.print_node('failure', to_char(a_suite.results_count.failure_count)); + self.print_node('error', to_char(a_suite.results_count.errored_count)); + self.print_node('warning', to_char(a_suite.results_count.warnings_count)); + self.print_end_node('counter'); + self.print_cdata_node('errorStack', ut_utils.table_to_clob(a_suite.get_error_stack_traces())); + self.print_cdata_node('serverOutput', a_suite.get_serveroutputs()); + self.print_end_node('endSuiteEvent'); + end after_calling_suite; + + overriding member procedure before_calling_test( + self in out nocopy ut_realtime_reporter, + a_test in ut_test + ) is + begin + current_test_number := current_test_number + 1; + self.print_start_node('startTestEvent', a_test.path); + self.print_node('testNumber', to_char(current_test_number)); + self.print_node('totalNumberOfTests', to_char(total_number_of_tests)); + self.print_end_node('startTestEvent'); + end before_calling_test; - overriding member procedure after_calling_test(self in out nocopy ut_realtime_reporter, a_test in ut_test) as + overriding member procedure after_calling_test( + self in out nocopy ut_realtime_reporter, + a_test in ut_test + ) is begin - self.print_xml_fragment(''); - end; + self.print_start_node('endTestEvent', a_test.path); + self.print_node('testNumber', to_char(current_test_number)); + self.print_node('totalNumberOfTests', to_char(total_number_of_tests)); + self.print_node('startTime', to_char(a_test.start_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6')); + self.print_node('endTime', to_char(a_test.end_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6')); + self.print_node('executionTime', ut_utils.to_xml_number_format(a_test.execution_time())); + self.print_start_node('counter'); + self.print_node('disabled', to_char(a_test.results_count.disabled_count)); + self.print_node('success', to_char(a_test.results_count.success_count)); + self.print_node('failure', to_char(a_test.results_count.failure_count)); + self.print_node('error', to_char(a_test.results_count.errored_count)); + self.print_node('warning', to_char(a_test.results_count.warnings_count)); + self.print_end_node('counter'); + self.print_cdata_node('errorStack', ut_utils.table_to_clob(a_test.get_error_stack_traces())); + self.print_cdata_node('serverOutput', a_test.get_serveroutputs()); + if a_test.failed_expectations.count > 0 then + self.print_start_node('failedExpectations'); + <> + for i in 1 .. a_test.failed_expectations.count loop + self.print_start_node('expectation'); + self.print_node('description', a_test.failed_expectations(i).description); + self.print_cdata_node('message', a_test.failed_expectations(i).message); + self.print_cdata_node('caller', a_test.failed_expectations(i).caller_info); + self.print_end_node('expectation'); + end loop expectations; + self.print_end_node('failedExpectations'); + end if; + self.print_end_node('endTestEvent'); + end after_calling_test; - overriding member procedure after_calling_suite(self in out nocopy ut_realtime_reporter, a_suite in ut_logical_suite) as + overriding member function get_description return varchar2 is begin - self.print_xml_fragment(''); - end; + return 'Provides test results in a XML format, for clients such as SQL Developer interested progressing details.'; + end get_description; - overriding member procedure after_calling_run(self in out nocopy ut_realtime_reporter, a_run in ut_run) as + member procedure print_start_node( + self in out nocopy ut_realtime_reporter, + a_name in varchar2, + a_id in varchar2 default null + ) is begin - self.print_xml_fragment('', -1); - self.print_xml_fragment('', -1); - end; + self.print_xml_fragment( + '<' || a_name + || case + when a_id is not null then + ' id="' || dbms_xmlgen.convert(a_id) || '"' + end + || '>', + 0, 1 + ); + end print_start_node; + + member procedure print_end_node( + self in out nocopy ut_realtime_reporter, + a_name in varchar2 + ) is + begin + self.print_xml_fragment('', -1); + end print_end_node; - overriding member function get_description return varchar2 as + member procedure print_node( + self in out nocopy ut_realtime_reporter, + a_name in varchar2, + a_content in clob + ) is begin - return 'Provides test results in a XML format, to consumed by clients such as SQL Developer interested progressing details.'; - end; + if a_content is not null then + self.print_xml_fragment('<' || a_name || '>' || dbms_xmlgen.convert(a_content) || ''); + end if; + end print_node; + + member procedure print_cdata_node( + self in out nocopy ut_realtime_reporter, + a_name in varchar2, + a_content in clob + ) is + begin + if a_content is not null then + self.print_xml_fragment('<' || a_name || '>'); + end if; + end print_cdata_node; member procedure print_xml_fragment( self in out nocopy ut_realtime_reporter, - a_fragment in varchar2, - a_indent_summand_before in integer default 0, - a_indent_summand_after in integer default 0 - ) as + a_fragment in clob, + a_indent_summand_before in integer default 0, + a_indent_summand_after in integer default 0 + ) is begin current_indent := current_indent + a_indent_summand_before; self.print_text(lpad(' ', 2 * current_indent) || a_fragment); current_indent := current_indent + a_indent_summand_after; - end; + end print_xml_fragment; end; / From d45c88ceb1fdb2772f1f77baba5370735d81ca46 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Dec 2018 19:52:36 +0100 Subject: [PATCH 10/38] extended unit test, reasonable coverage, helps understanding the reporter --- .../core/reporters/test_realtime_reporter.pkb | 271 ++++++++++++++++-- .../core/reporters/test_realtime_reporter.pks | 42 ++- 2 files changed, 293 insertions(+), 20 deletions(-) diff --git a/test/core/reporters/test_realtime_reporter.pkb b/test/core/reporters/test_realtime_reporter.pkb index e6345d86c..d1a027025 100644 --- a/test/core/reporters/test_realtime_reporter.pkb +++ b/test/core/reporters/test_realtime_reporter.pkb @@ -1,6 +1,8 @@ create or replace package body test_realtime_reporter as - procedure create_test_suites is + g_actual_xml_report xmltype; + + procedure create_test_suites_and_run is pragma autonomous_transaction; begin execute immediate q'[create or replace package ut3_tester.check_realtime_reporting1 is @@ -52,6 +54,7 @@ create or replace package body test_realtime_reporter as procedure test_4_nok is begin ut3.ut.expect(2).to_equal(3); + ut3.ut.expect(2).to_equal(4); end; procedure test_5 is @@ -59,27 +62,263 @@ create or replace package body test_realtime_reporter as null; end; end;]'; - commit; - end; + + execute immediate q'[create or replace package ut3_tester.check_realtime_reporting3 is + --%suite + --%suitepath(realtime_reporting) + + --%test + procedure test_6_with_runtime_error; + + --%test + procedure test_7_with_serveroutput; + + --%afterall + procedure print_and_raise; + end;]'; + execute immediate q'[create or replace package body ut3_tester.check_realtime_reporting3 is + procedure test_6_with_runtime_error is + l_actual integer; + begin + execute immediate 'select 6 from non_existing_table' into l_actual; + ut3.ut.expect(6).to_equal(l_actual); + end; + + procedure test_7_with_serveroutput is + begin + dbms_output.put_line('before test 7'); + ut3.ut.expect(7).to_equal(7); + dbms_output.put_line('after test 7'); + end; + + procedure print_and_raise is + begin + dbms_output.put_line('Now, a no_data_found exception is raised'); + dbms_output.put_line('dbms_output and error stack is reported for this suite.'); + dbms_output.put_line('A runtime error in afterall is counted as a warning.'); + raise no_data_found; + end; + end;]'; + + <> + declare + l_results ut3.ut_varchar2_list; + begin + select * + bulk collect into l_results + from table(ut3.ut.run('ut3_tester:realtime_reporting', ut3.ut_realtime_reporter())); + g_actual_xml_report := xmltype(ut3.ut_utils.table_to_clob(l_results)); + end run_report_and_cache_result; + end create_test_suites_and_run; + + procedure xml_report_structure is + l_actual clob; + l_expected_list ut3.ut_varchar2_list; + l_expected clob; + begin + l_actual := g_actual_xml_report.getclobval(); + ut3.ut_utils.append_to_list(l_expected_list, ''); + ut3.ut_utils.append_to_list(l_expected_list, '%'); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% %'); + ut3.ut_utils.append_to_list(l_expected_list, '% %'); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% %'); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '% '); + ut3.ut_utils.append_to_list(l_expected_list, '%'); + l_expected := ut3.ut_utils.table_to_clob(l_expected_list, null); + ut.expect(l_actual).to_be_like(l_expected); + end xml_report_structure; + + procedure total_number_of_tests is + l_actual integer; + l_expected integer := 7; + begin + l_actual := g_actual_xml_report.extract('/report/preRun/totalNumberOfTests/text()').getnumberval(); + ut.expect(l_actual).to_equal(l_expected); + end total_number_of_tests; + + procedure escaped_characters is + l_actual varchar2(32767); + l_expected varchar2(20) := 'suite <A>'; + begin + l_actual := + g_actual_xml_report.extract( + '//suite[@id="realtime_reporting.check_realtime_reporting1"]/description/text()' + ).getstringval(); + ut.expect(l_actual).to_equal(l_expected); + end escaped_characters; + + procedure number_of_starttestevent_nodes is + l_actual integer; + l_expected integer := 7; + begin + select count(*) + into l_actual + from xmltable( + '/report/runEvents/startTestEvent' + passing g_actual_xml_report + columns id varchar2(4000) path '@id', + test_number integer path 'testNumber', + total_number_of_tests integer path 'totalNumberOfTests' + ) + where id is not null + and test_number is not null + and total_number_of_tests is not null; + ut.expect(l_actual).to_equal(l_expected); + end number_of_starttestevent_nodes; + + procedure endtestevent_nodes is + l_actual sys_refcursor; + l_expected sys_refcursor; + begin + open l_actual for + select test_number, total_number_of_tests + from xmltable( + '/report/runEvents/endTestEvent' + passing g_actual_xml_report + columns id varchar2(4000) path '@id', + test_number integer path 'testNumber', + total_number_of_tests integer path 'totalNumberOfTests' + ) + where id is not null + and test_number is not null + and total_number_of_tests is not null; + open l_expected for + select level as test_number, + 7 as total_number_of_tests + from dual + connect by level <= 7; + ut.expect(l_actual).to_equal(l_expected).unordered; + end endtestevent_nodes; - procedure report_produces_expected_out is - l_results ut3.ut_varchar2_list; - l_actual clob; - l_expected varchar2(32767) := q'[%]'; + + procedure single_failed_message is + l_actual varchar2(32767); + l_expected varchar2(80) := ''; + begin + l_actual := + g_actual_xml_report.extract( + '/report/runEvents/endTestEvent[@id="realtime_reporting.check_realtime_reporting1.test context.test_2_nok"]/failedExpectations/expectation[1]/message/text()' + ).getstringval(); + ut.expect(l_actual).to_equal(l_expected); + end single_failed_message; + + procedure multiple_failed_messages is + l_actual integer; + l_expected integer := 2; + begin + select count(*) + into l_actual + from xmltable( + '/report/runEvents/endTestEvent[@id="realtime_reporting.check_realtime_reporting2.test_4_nok"]/failedExpectations/expectation' + passing g_actual_xml_report + columns message clob path 'message', + caller clob path 'caller' + ) + where message is not null + and caller is not null; + ut.expect(l_actual).to_equal(l_expected); + end multiple_failed_messages; + + procedure serveroutput_of_test is + l_actual clob; + l_expected_list ut3.ut_varchar2_list; + l_expected clob; begin - select * - bulk collect into l_results - from table(ut3.ut.run('ut3_tester:realtime_reporting', ut3.ut_realtime_reporter())); - l_actual := ut3.ut_utils.table_to_clob(l_results); - ut.expect(l_actual).to_be_like(l_expected); - end; + l_actual := + g_actual_xml_report.extract( + '/report/runEvents/endTestEvent[@id="realtime_reporting.check_realtime_reporting3.test_7_with_serveroutput"]/serverOutput/text()' + ).getclobval(); + ut3.ut_utils.append_to_list(l_expected_list, ''); + l_expected := ut3.ut_utils.table_to_clob(l_expected_list); + ut.expect(l_actual).to_equal(l_expected); + end serveroutput_of_test; + + procedure serveroutput_of_testsuite is + l_actual clob; + l_expected_list ut3.ut_varchar2_list; + l_expected clob; + begin + l_actual := + g_actual_xml_report.extract( + '/report/runEvents/endSuiteEvent[@id="realtime_reporting.check_realtime_reporting3"]/serverOutput/text()' + ).getclobval(); + ut3.ut_utils.append_to_list(l_expected_list, ''); + l_expected := ut3.ut_utils.table_to_clob(l_expected_list); + ut.expect(l_actual).to_equal(l_expected); + end serveroutput_of_testsuite; + + procedure error_stack_of_test is + l_actual clob; + l_expected_list ut3.ut_varchar2_list; + l_expected clob; + begin + l_actual := + g_actual_xml_report.extract( + '/report/runEvents/endTestEvent[@id="realtime_reporting.check_realtime_reporting3.test_6_with_runtime_error"]/errorStack/text()' + ).getclobval(); + ut3.ut_utils.append_to_list(l_expected_list, ''); + l_expected := ut3.ut_utils.table_to_clob(l_expected_list); + ut.expect(l_actual).to_equal(l_expected); + end error_stack_of_test; + + procedure error_stack_of_testsuite is + l_actual clob; + l_expected_list ut3.ut_varchar2_list; + l_expected clob; + begin + l_actual := + g_actual_xml_report.extract( + '/report/runEvents/endSuiteEvent[@id="realtime_reporting.check_realtime_reporting3"]/errorStack/text()' + ).getclobval(); + ut3.ut_utils.append_to_list(l_expected_list, ''); + l_expected := ut3.ut_utils.table_to_clob(l_expected_list); + ut.expect(l_actual).to_equal(l_expected); + end error_stack_of_testsuite; + + procedure get_description is + l_reporter ut3.ut_realtime_reporter; + l_actual varchar2(4000); + l_expected varchar2(80) := '%SQL Developer%'; + begin + l_reporter := ut3.ut_realtime_reporter(); + l_actual := l_reporter.get_description(); + ut.expect(l_actual).to_be_like(l_expected); + end get_description; procedure remove_test_suites is pragma autonomous_transaction; - begin + begin/* execute immediate 'drop package ut3_tester.check_realtime_reporting1'; execute immediate 'drop package ut3_tester.check_realtime_reporting2'; - end; + execute immediate 'drop package ut3_tester.check_realtime_reporting3'; + */ null; + end remove_test_suites; -end; +end test_realtime_reporter; / diff --git a/test/core/reporters/test_realtime_reporter.pks b/test/core/reporters/test_realtime_reporter.pks index 8ced907e4..98446aa5c 100644 --- a/test/core/reporters/test_realtime_reporter.pks +++ b/test/core/reporters/test_realtime_reporter.pks @@ -4,12 +4,46 @@ create or replace package test_realtime_reporter as --%suitepath(utplsql.core.reporters) --%beforeall - procedure create_test_suites; + procedure create_test_suites_and_run; - --%test(Report produces expected output) - procedure report_produces_expected_out; + --%test(Check XML report structure) + procedure xml_report_structure; + --%test(Check total number of tests) + procedure total_number_of_tests; + + --%test(Check escaped characters in test suite description) + procedure escaped_characters; + + --%test(Check number of startTestEvent nodes) + procedure number_of_starttestevent_nodes; + + --%test(Check testNumber and totalNumberOfTests in endTestEvent nodes) + procedure endtestevent_nodes; + + --%test(Check expectation message for a failed test) + procedure single_failed_message; + + --%test(Check existence of multiple expectation messages for a failed test) + procedure multiple_failed_messages; + + --%test(Check for serveroutput of test) + procedure serveroutput_of_test; + + --%test(Check for serveroutput of testsuite) + procedure serveroutput_of_testsuite; + + --%test(Check for error stack of test) + procedure error_stack_of_test; + + --%test(Check for error stack of testsuite) + procedure error_stack_of_testsuite; + + --%test(Check description of reporter) + procedure get_description; + --%afterall procedure remove_test_suites; -end; + +end test_realtime_reporter; / From b37b188abd430df040e10625e525d9e5d1053bf5 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Dec 2018 19:58:20 +0100 Subject: [PATCH 11/38] enable drop of test packages --- test/core/reporters/test_realtime_reporter.pkb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/core/reporters/test_realtime_reporter.pkb b/test/core/reporters/test_realtime_reporter.pkb index d1a027025..9dc4787db 100644 --- a/test/core/reporters/test_realtime_reporter.pkb +++ b/test/core/reporters/test_realtime_reporter.pkb @@ -313,11 +313,10 @@ create or replace package body test_realtime_reporter as procedure remove_test_suites is pragma autonomous_transaction; - begin/* + begin execute immediate 'drop package ut3_tester.check_realtime_reporting1'; execute immediate 'drop package ut3_tester.check_realtime_reporting2'; execute immediate 'drop package ut3_tester.check_realtime_reporting3'; - */ null; end remove_test_suites; end test_realtime_reporter; From 8c1c561acb135cd33a1c3b9c48ce4d369c2708ac Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Dec 2018 22:00:56 +0100 Subject: [PATCH 12/38] remove hard-coded owner ut3_tester --- .../core/reporters/test_realtime_reporter.pkb | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/test/core/reporters/test_realtime_reporter.pkb b/test/core/reporters/test_realtime_reporter.pkb index 9dc4787db..468a65769 100644 --- a/test/core/reporters/test_realtime_reporter.pkb +++ b/test/core/reporters/test_realtime_reporter.pkb @@ -5,7 +5,7 @@ create or replace package body test_realtime_reporter as procedure create_test_suites_and_run is pragma autonomous_transaction; begin - execute immediate q'[create or replace package ut3_tester.check_realtime_reporting1 is + execute immediate q'[create or replace package check_realtime_reporting1 is --%suite(suite ) --%suitepath(realtime_reporting) @@ -19,7 +19,7 @@ create or replace package body test_realtime_reporter as --%endcontext end;]'; - execute immediate q'[create or replace package body ut3_tester.check_realtime_reporting1 is + execute immediate q'[create or replace package body check_realtime_reporting1 is procedure test_1_ok is begin ut3.ut.expect(1).to_equal(1); @@ -31,7 +31,7 @@ create or replace package body test_realtime_reporter as end; end;]'; - execute immediate q'[create or replace package ut3_tester.check_realtime_reporting2 is + execute immediate q'[create or replace package check_realtime_reporting2 is --%suite --%suitepath(realtime_reporting) @@ -45,7 +45,7 @@ create or replace package body test_realtime_reporter as --%disabled procedure test_5; end;]'; - execute immediate q'[create or replace package body ut3_tester.check_realtime_reporting2 is + execute immediate q'[create or replace package body check_realtime_reporting2 is procedure test_3_ok is begin ut3.ut.expect(2).to_equal(2); @@ -63,7 +63,7 @@ create or replace package body test_realtime_reporter as end; end;]'; - execute immediate q'[create or replace package ut3_tester.check_realtime_reporting3 is + execute immediate q'[create or replace package check_realtime_reporting3 is --%suite --%suitepath(realtime_reporting) @@ -76,7 +76,7 @@ create or replace package body test_realtime_reporter as --%afterall procedure print_and_raise; end;]'; - execute immediate q'[create or replace package body ut3_tester.check_realtime_reporting3 is + execute immediate q'[create or replace package body check_realtime_reporting3 is procedure test_6_with_runtime_error is l_actual integer; begin @@ -277,11 +277,11 @@ create or replace package body test_realtime_reporter as '/report/runEvents/endTestEvent[@id="realtime_reporting.check_realtime_reporting3.test_6_with_runtime_error"]/errorStack/text()' ).getclobval(); ut3.ut_utils.append_to_list(l_expected_list, ''); l_expected := ut3.ut_utils.table_to_clob(l_expected_list); - ut.expect(l_actual).to_equal(l_expected); + ut.expect(l_actual).to_be_like(l_expected); end error_stack_of_test; procedure error_stack_of_testsuite is @@ -294,11 +294,11 @@ create or replace package body test_realtime_reporter as '/report/runEvents/endSuiteEvent[@id="realtime_reporting.check_realtime_reporting3"]/errorStack/text()' ).getclobval(); ut3.ut_utils.append_to_list(l_expected_list, ''); l_expected := ut3.ut_utils.table_to_clob(l_expected_list); - ut.expect(l_actual).to_equal(l_expected); + ut.expect(l_actual).to_be_like(l_expected); end error_stack_of_testsuite; procedure get_description is @@ -314,9 +314,9 @@ create or replace package body test_realtime_reporter as procedure remove_test_suites is pragma autonomous_transaction; begin - execute immediate 'drop package ut3_tester.check_realtime_reporting1'; - execute immediate 'drop package ut3_tester.check_realtime_reporting2'; - execute immediate 'drop package ut3_tester.check_realtime_reporting3'; + execute immediate 'drop package check_realtime_reporting1'; + execute immediate 'drop package check_realtime_reporting2'; + execute immediate 'drop package check_realtime_reporting3'; end remove_test_suites; end test_realtime_reporter; From bcf16063ce1d10244b4f37383217a2fa887cecf9 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Fri, 28 Dec 2018 23:45:36 +0100 Subject: [PATCH 13/38] make complete event a.s.a.p. visible in consuming session Even with "set arraysize 1" the last row in an output table is not consumed delayed. Inserting a new row after the closing event tag, makes the complete event immediately visible in the consuming session. The XML is still valid with these additional whitespaces (spaces based on indentation and new line). As a positive side effect, the different events are more visible. --- source/reporters/ut_realtime_reporter.tpb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/reporters/ut_realtime_reporter.tpb b/source/reporters/ut_realtime_reporter.tpb index 179cab95c..97e7c2b3d 100644 --- a/source/reporters/ut_realtime_reporter.tpb +++ b/source/reporters/ut_realtime_reporter.tpb @@ -194,6 +194,10 @@ create or replace type body ut_realtime_reporter is ) is begin self.print_xml_fragment('', -1); + if a_name like '%Event' then + -- force new line to make complete event a.s.a.p. visible in consuming session + self.print_xml_fragment(null); + end if; end print_end_node; member procedure print_node( From d4b09c7df2033c486d145cc18f4b2fdb63356cb2 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 08:10:06 +0100 Subject: [PATCH 14/38] fix incompatibility to 12.1 --- test/core/reporters/test_realtime_reporter.pkb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/core/reporters/test_realtime_reporter.pkb b/test/core/reporters/test_realtime_reporter.pkb index 468a65769..06449b70e 100644 --- a/test/core/reporters/test_realtime_reporter.pkb +++ b/test/core/reporters/test_realtime_reporter.pkb @@ -278,8 +278,7 @@ create or replace package body test_realtime_reporter as ).getclobval(); ut3.ut_utils.append_to_list(l_expected_list, ''); + ut3.ut_utils.append_to_list(l_expected_list, '%ORA-06512: at line 6]]>'); l_expected := ut3.ut_utils.table_to_clob(l_expected_list); ut.expect(l_actual).to_be_like(l_expected); end error_stack_of_test; @@ -295,8 +294,7 @@ create or replace package body test_realtime_reporter as ).getclobval(); ut3.ut_utils.append_to_list(l_expected_list, ''); + ut3.ut_utils.append_to_list(l_expected_list, '%ORA-06512: at line 6]]>'); l_expected := ut3.ut_utils.table_to_clob(l_expected_list); ut.expect(l_actual).to_be_like(l_expected); end error_stack_of_testsuite; From c2cc292cac46cba23db9bd24eae80d8aa6818657 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 08:21:16 +0100 Subject: [PATCH 15/38] Fixed typos in comments and made comments more precise. --- source/reporters/ut_realtime_reporter.tps | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/source/reporters/ut_realtime_reporter.tps b/source/reporters/ut_realtime_reporter.tps index d6c7776cc..8c596c956 100644 --- a/source/reporters/ut_realtime_reporter.tps +++ b/source/reporters/ut_realtime_reporter.tps @@ -33,7 +33,7 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( /** * The realtime reporter. - * Provides test results in a XML format, for clients such as SQL Developer interested progressing details. + * Provides test results in a XML format, for clients such as SQL Developer interested in showing progressing details. */ constructor function ut_realtime_reporter( self in out nocopy ut_realtime_reporter @@ -41,7 +41,6 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( /** * Provides meta data of complete run in advance. - * Used to show total tests and initialize a progress bar. */ overriding member procedure before_calling_run( self in out nocopy ut_realtime_reporter, @@ -49,7 +48,7 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( ), /** - * Provides closing tag with runtime summary. + * Provides closing tags. */ overriding member procedure after_calling_run( self in out nocopy ut_realtime_reporter, @@ -65,7 +64,7 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( ), /** - * Provides meta data of completed test suite with runtime. + * Provides meta data of completed test suite. */ overriding member procedure after_calling_suite( self in out nocopy ut_realtime_reporter, @@ -82,7 +81,7 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( ), /** - * Provides meta data of a completed test with runtime and status. + * Provides meta data of a completed test. */ overriding member procedure after_calling_test( self in out nocopy ut_realtime_reporter, @@ -95,7 +94,7 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( overriding member function get_description return varchar2, /** - * Prints the start tag of an XML with an optional id attribute. + * Prints the start tag of a XML node with an optional id attribute. */ member procedure print_start_node( self in out nocopy ut_realtime_reporter, @@ -104,7 +103,7 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( ), /** - * Prints the end tag of an XML node. + * Prints the end tag of a XML node. */ member procedure print_end_node( self in out nocopy ut_realtime_reporter, @@ -112,7 +111,7 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( ), /** - * Prints a child node with content. Content will be XML encoded. + * Prints a child node with content. Special characters are encoded. */ member procedure print_node( self in out nocopy ut_realtime_reporter, @@ -121,7 +120,7 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( ), /** - * Prints a child node with content. Content is passed 1:1 incl. new lines, etc. using CDATA. + * Prints a child node with content. Content is passed 1:1 using CDATA. */ member procedure print_cdata_node( self in out nocopy ut_realtime_reporter, From 0c6a0adb4a57e15cea3881fcb6f87da9ba488e78 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 08:23:30 +0100 Subject: [PATCH 16/38] get_description synchronized with type specification. --- source/reporters/ut_realtime_reporter.tpb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/reporters/ut_realtime_reporter.tpb b/source/reporters/ut_realtime_reporter.tpb index 97e7c2b3d..a4e1fdd49 100644 --- a/source/reporters/ut_realtime_reporter.tpb +++ b/source/reporters/ut_realtime_reporter.tpb @@ -168,7 +168,7 @@ create or replace type body ut_realtime_reporter is overriding member function get_description return varchar2 is begin - return 'Provides test results in a XML format, for clients such as SQL Developer interested progressing details.'; + return 'Provides test results in a XML format, for clients such as SQL Developer interested in showing progressing details.'; end get_description; member procedure print_start_node( From 7134f130681741b0d090facb7bd4fdd6085c5a64 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 08:31:17 +0100 Subject: [PATCH 17/38] use print_end_node to close tags --- source/reporters/ut_realtime_reporter.tpb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/reporters/ut_realtime_reporter.tpb b/source/reporters/ut_realtime_reporter.tpb index a4e1fdd49..c245063e0 100644 --- a/source/reporters/ut_realtime_reporter.tpb +++ b/source/reporters/ut_realtime_reporter.tpb @@ -85,8 +85,8 @@ create or replace type body ut_realtime_reporter is a_run in ut_run ) is begin - self.print_xml_fragment('', -1); - self.print_xml_fragment('', -1); + self.print_end_node('runEvents'); + self.print_end_node('report'); end after_calling_run; overriding member procedure before_calling_suite( From 257756673001f112863fab44ba88c28d5972518a Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 08:36:05 +0100 Subject: [PATCH 18/38] removed duplicate line feed --- source/reporters/ut_realtime_reporter.tps | 1 - 1 file changed, 1 deletion(-) diff --git a/source/reporters/ut_realtime_reporter.tps b/source/reporters/ut_realtime_reporter.tps index 8c596c956..8c0dcf379 100644 --- a/source/reporters/ut_realtime_reporter.tps +++ b/source/reporters/ut_realtime_reporter.tps @@ -71,7 +71,6 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( a_suite in ut_logical_suite ), - /** * Indicates the start of a test. */ From 16722482bd314ed81a97db108f8eb340ef796350 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 08:41:14 +0100 Subject: [PATCH 19/38] removed duplicate line feed --- test/core/reporters/test_realtime_reporter.pkb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/core/reporters/test_realtime_reporter.pkb b/test/core/reporters/test_realtime_reporter.pkb index 06449b70e..2eb7b2c21 100644 --- a/test/core/reporters/test_realtime_reporter.pkb +++ b/test/core/reporters/test_realtime_reporter.pkb @@ -205,7 +205,6 @@ create or replace package body test_realtime_reporter as ut.expect(l_actual).to_equal(l_expected).unordered; end endtestevent_nodes; - procedure single_failed_message is l_actual varchar2(32767); l_expected varchar2(80) := ''; From 42cf8ee11f120ccbce2dadce7b864943d209df37 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 16:39:53 +0100 Subject: [PATCH 20/38] change description of the tests to reflect the requirements as suggested by jgebal --- .../core/reporters/test_realtime_reporter.pks | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/core/reporters/test_realtime_reporter.pks b/test/core/reporters/test_realtime_reporter.pks index 98446aa5c..fa5bbd3ac 100644 --- a/test/core/reporters/test_realtime_reporter.pks +++ b/test/core/reporters/test_realtime_reporter.pks @@ -6,40 +6,40 @@ create or replace package test_realtime_reporter as --%beforeall procedure create_test_suites_and_run; - --%test(Check XML report structure) + --%test(Provide a report structure with pre-run information and event based messages per suite and per test) procedure xml_report_structure; - --%test(Check total number of tests) + --%test(Provide the total number of tests as part of the pre-run information structure) procedure total_number_of_tests; - --%test(Check escaped characters in test suite description) + --%test(Escape special characters in data such as the test suite description) procedure escaped_characters; - --%test(Check number of startTestEvent nodes) + --%test(Provide a startTestEvent node before starting a test with testNumber and totalNumberOfTests) procedure number_of_starttestevent_nodes; - --%test(Check testNumber and totalNumberOfTests in endTestEvent nodes) + --%test(Provide a endTestEvent node after completion of a test with test results) procedure endtestevent_nodes; - --%test(Check expectation message for a failed test) + --%test(Provide expectation message for a failed test) procedure single_failed_message; - --%test(Check existence of multiple expectation messages for a failed test) + --%test(Provide expectation messages for each failed assertion of a failed test) procedure multiple_failed_messages; - --%test(Check for serveroutput of test) + --%test(Provide dbms_output produced in a test) procedure serveroutput_of_test; - --%test(Check for serveroutput of testsuite) + --%test(Provide dbms_output produced in a testsuite) procedure serveroutput_of_testsuite; - --%test(Check for error stack of test) + --%test(Provide the error stack of a test) procedure error_stack_of_test; - --%test(Check for error stack of testsuite) + --%test(Provide the error stack of a testsuite) procedure error_stack_of_testsuite; - --%test(Check description of reporter) + --%test(Provide a description of the reporter explaining the use for SQL Developer) procedure get_description; --%afterall From 6512cf8c719aa62e5c31cda5e0dab6fc87779cab Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 16:44:10 +0100 Subject: [PATCH 21/38] replace granular self.print_text_lines calls with a few self.print_text calls to optimize runtime performance as suggested by jgebal --- source/reporters/ut_realtime_reporter.tpb | 17 ++++++++++++++++- source/reporters/ut_realtime_reporter.tps | 12 ++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/source/reporters/ut_realtime_reporter.tpb b/source/reporters/ut_realtime_reporter.tpb index c245063e0..c6568cd04 100644 --- a/source/reporters/ut_realtime_reporter.tpb +++ b/source/reporters/ut_realtime_reporter.tpb @@ -24,6 +24,7 @@ create or replace type body ut_realtime_reporter is total_number_of_tests := 0; current_test_number := 0; current_indent := 0; + print_buffer := ut_varchar2_rows(); return; end; @@ -78,6 +79,7 @@ create or replace type body ut_realtime_reporter is self.print_node('totalNumberOfTests', to_char(total_number_of_tests)); self.print_end_node('preRun'); self.print_start_node('runEvents'); + self.flush_print_buffer(); end before_calling_run; overriding member procedure after_calling_run( @@ -87,6 +89,7 @@ create or replace type body ut_realtime_reporter is begin self.print_end_node('runEvents'); self.print_end_node('report'); + self.flush_print_buffer(); end after_calling_run; overriding member procedure before_calling_suite( @@ -96,6 +99,7 @@ create or replace type body ut_realtime_reporter is begin self.print_start_node('startSuiteEvent', a_suite.path); self.print_end_node('startSuiteEvent'); + self.flush_print_buffer(); end before_calling_suite; overriding member procedure after_calling_suite( @@ -117,6 +121,7 @@ create or replace type body ut_realtime_reporter is self.print_cdata_node('errorStack', ut_utils.table_to_clob(a_suite.get_error_stack_traces())); self.print_cdata_node('serverOutput', a_suite.get_serveroutputs()); self.print_end_node('endSuiteEvent'); + self.flush_print_buffer(); end after_calling_suite; overriding member procedure before_calling_test( @@ -129,6 +134,7 @@ create or replace type body ut_realtime_reporter is self.print_node('testNumber', to_char(current_test_number)); self.print_node('totalNumberOfTests', to_char(total_number_of_tests)); self.print_end_node('startTestEvent'); + self.flush_print_buffer(); end before_calling_test; overriding member procedure after_calling_test( @@ -164,6 +170,7 @@ create or replace type body ut_realtime_reporter is self.print_end_node('failedExpectations'); end if; self.print_end_node('endTestEvent'); + self.flush_print_buffer(); end after_calling_test; overriding member function get_description return varchar2 is @@ -230,9 +237,17 @@ create or replace type body ut_realtime_reporter is ) is begin current_indent := current_indent + a_indent_summand_before; - self.print_text(lpad(' ', 2 * current_indent) || a_fragment); + ut_utils.append_to_list(print_buffer, lpad(' ', 2 * current_indent) || a_fragment); current_indent := current_indent + a_indent_summand_after; end print_xml_fragment; + + member procedure flush_print_buffer( + self in out nocopy ut_realtime_reporter + ) is + begin + self.print_text_lines(print_buffer); + print_buffer.delete; + end flush_print_buffer; end; / diff --git a/source/reporters/ut_realtime_reporter.tps b/source/reporters/ut_realtime_reporter.tps index 8c0dcf379..685ece7e4 100644 --- a/source/reporters/ut_realtime_reporter.tps +++ b/source/reporters/ut_realtime_reporter.tps @@ -31,6 +31,11 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( */ current_indent integer, + /** + * Buffers lines to be printed. + */ + print_buffer ut_varchar2_rows, + /** * The realtime reporter. * Provides test results in a XML format, for clients such as SQL Developer interested in showing progressing details. @@ -138,6 +143,13 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( a_fragment in clob, a_indent_summand_before in integer default 0, a_indent_summand_after in integer default 0 + ), + + /** + * Flushes the local print buffer to the output buffer. + */ + member procedure flush_print_buffer( + self in out nocopy ut_realtime_reporter ) ) not final From c1273afe1fc19ffa11dd066cd576b4157bd6b797 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 23:46:35 +0100 Subject: [PATCH 22/38] added text_xmltype_list collection type for test_realtime_reporter --- test/helpers/test_xmltype_list.tps | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 test/helpers/test_xmltype_list.tps diff --git a/test/helpers/test_xmltype_list.tps b/test/helpers/test_xmltype_list.tps new file mode 100644 index 000000000..9c1bd4445 --- /dev/null +++ b/test/helpers/test_xmltype_list.tps @@ -0,0 +1,2 @@ +create or replace type test_xmltype_list as table of xmltype; +/ From b05760d135e42ccc20865f80aa824815954e1090 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 23:47:07 +0100 Subject: [PATCH 23/38] install new collection type test_xmltype_list for test_realtime_reporter --- test/install_tests.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/test/install_tests.sql b/test/install_tests.sql index 72e9a75e0..3f758de3f 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -13,6 +13,7 @@ alter session set plsql_optimize_level=0; @@helpers/other_dummy_object.tps @@helpers/test_dummy_object.tps @@helpers/test_dummy_object_list.tps +@@helpers/test_xmltype_list.tps --Install tests @@core.pks From 93e4ea8020a0b4c64d5f71fab850152dba196de0 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 23:48:41 +0100 Subject: [PATCH 24/38] add xml_header attribute, used for each produced document --- source/reporters/ut_realtime_reporter.tps | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/reporters/ut_realtime_reporter.tps b/source/reporters/ut_realtime_reporter.tps index 685ece7e4..f4a5d799d 100644 --- a/source/reporters/ut_realtime_reporter.tps +++ b/source/reporters/ut_realtime_reporter.tps @@ -15,6 +15,11 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( See the License for the specific language governing permissions and limitations under the License. */ + + /** + * Cached XML header to be used for every XML document + */ + xml_header varchar2(4000), /** * Total number of all tests in the run (incl. disabled tests). From 290ca30aed176c41946adf4d1e97b0795cfcc5ad Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 23:50:37 +0100 Subject: [PATCH 25/38] replace hard-coded id attribute with name and value for an optional attribute --- source/reporters/ut_realtime_reporter.tps | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/reporters/ut_realtime_reporter.tps b/source/reporters/ut_realtime_reporter.tps index f4a5d799d..645351a17 100644 --- a/source/reporters/ut_realtime_reporter.tps +++ b/source/reporters/ut_realtime_reporter.tps @@ -103,12 +103,13 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( overriding member function get_description return varchar2, /** - * Prints the start tag of a XML node with an optional id attribute. + * Prints the start tag of a XML node with an optional attribute. */ member procedure print_start_node( - self in out nocopy ut_realtime_reporter, - a_name in varchar2, - a_id in varchar2 default null + self in out nocopy ut_realtime_reporter, + a_node_name in varchar2, + a_attr_name in varchar2 default null, + a_attr_value in varchar2 default null ), /** From e570e48126d9d3f5d7b4fcc83fbabca57ea42eaa Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 23:52:41 +0100 Subject: [PATCH 26/38] produce an XML document for each event resulting in a new output structure --- source/reporters/ut_realtime_reporter.tpb | 63 ++++++++++++++--------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/source/reporters/ut_realtime_reporter.tpb b/source/reporters/ut_realtime_reporter.tpb index c6568cd04..0e0b212fc 100644 --- a/source/reporters/ut_realtime_reporter.tpb +++ b/source/reporters/ut_realtime_reporter.tpb @@ -37,7 +37,7 @@ create or replace type body ut_realtime_reporter is ) is begin total_number_of_tests := total_number_of_tests + 1; - self.print_start_node('test', a_test.path); + self.print_start_node('test', 'id', a_test.path); self.print_node('executableType', a_test.item.executable_type); self.print_node('ownerName', a_test.item.owner_name); self.print_node('objectName', a_test.item.object_name); @@ -53,7 +53,7 @@ create or replace type body ut_realtime_reporter is a_suite in ut_logical_suite ) is begin - self.print_start_node('suite', a_suite.path); + self.print_start_node('suite', 'id', a_suite.path); self.print_node('name', a_suite.name); self.print_node('description', a_suite.description); <> @@ -67,9 +67,9 @@ create or replace type body ut_realtime_reporter is self.print_end_node('suite'); end print_suite_elements; begin - self.print_xml_fragment(ut_utils.get_xml_header(a_run.client_character_set)); - self.print_start_node('report'); - self.print_start_node('preRun'); + xml_header := ut_utils.get_xml_header(a_run.client_character_set); + self.print_xml_fragment(xml_header); + self.print_start_node('event', 'type', 'pre-run'); self.print_start_node('suites'); <> for i in 1 .. a_run.items.count loop @@ -77,8 +77,7 @@ create or replace type body ut_realtime_reporter is end loop items; self.print_end_node('suites'); self.print_node('totalNumberOfTests', to_char(total_number_of_tests)); - self.print_end_node('preRun'); - self.print_start_node('runEvents'); + self.print_end_node('event'); self.flush_print_buffer(); end before_calling_run; @@ -87,8 +86,9 @@ create or replace type body ut_realtime_reporter is a_run in ut_run ) is begin - self.print_end_node('runEvents'); - self.print_end_node('report'); + self.print_xml_fragment(xml_header); + self.print_start_node('event', 'type', 'post-run'); + self.print_end_node('event'); self.flush_print_buffer(); end after_calling_run; @@ -97,8 +97,11 @@ create or replace type body ut_realtime_reporter is a_suite in ut_logical_suite ) is begin - self.print_start_node('startSuiteEvent', a_suite.path); - self.print_end_node('startSuiteEvent'); + self.print_xml_fragment(xml_header); + self.print_start_node('event', 'type', 'pre-suite'); + self.print_start_node('suite', 'id', a_suite.path); + self.print_end_node('suite'); + self.print_end_node('event'); self.flush_print_buffer(); end before_calling_suite; @@ -107,7 +110,9 @@ create or replace type body ut_realtime_reporter is a_suite in ut_logical_suite ) is begin - self.print_start_node('endSuiteEvent', a_suite.path); + self.print_xml_fragment(xml_header); + self.print_start_node('event', 'type', 'post-suite'); + self.print_start_node('suite', 'id', a_suite.path); self.print_node('startTime', to_char(a_suite.start_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6')); self.print_node('endTime', to_char(a_suite.end_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6')); self.print_node('executionTime', ut_utils.to_xml_number_format(a_suite.execution_time())); @@ -120,7 +125,8 @@ create or replace type body ut_realtime_reporter is self.print_end_node('counter'); self.print_cdata_node('errorStack', ut_utils.table_to_clob(a_suite.get_error_stack_traces())); self.print_cdata_node('serverOutput', a_suite.get_serveroutputs()); - self.print_end_node('endSuiteEvent'); + self.print_end_node('suite'); + self.print_end_node('event'); self.flush_print_buffer(); end after_calling_suite; @@ -130,10 +136,13 @@ create or replace type body ut_realtime_reporter is ) is begin current_test_number := current_test_number + 1; - self.print_start_node('startTestEvent', a_test.path); + self.print_xml_fragment(xml_header); + self.print_start_node('event', 'type', 'pre-test'); + self.print_start_node('test', 'id', a_test.path); self.print_node('testNumber', to_char(current_test_number)); self.print_node('totalNumberOfTests', to_char(total_number_of_tests)); - self.print_end_node('startTestEvent'); + self.print_end_node('test'); + self.print_end_node('event'); self.flush_print_buffer(); end before_calling_test; @@ -142,7 +151,9 @@ create or replace type body ut_realtime_reporter is a_test in ut_test ) is begin - self.print_start_node('endTestEvent', a_test.path); + self.print_xml_fragment(xml_header); + self.print_start_node('event', 'type', 'post-test'); + self.print_start_node('test', 'id', a_test.path); self.print_node('testNumber', to_char(current_test_number)); self.print_node('totalNumberOfTests', to_char(total_number_of_tests)); self.print_node('startTime', to_char(a_test.start_time, 'YYYY-MM-DD"T"HH24:MI:SS.FF6')); @@ -169,7 +180,8 @@ create or replace type body ut_realtime_reporter is end loop expectations; self.print_end_node('failedExpectations'); end if; - self.print_end_node('endTestEvent'); + self.print_end_node('test'); + self.print_end_node('event'); self.flush_print_buffer(); end after_calling_test; @@ -179,16 +191,17 @@ create or replace type body ut_realtime_reporter is end get_description; member procedure print_start_node( - self in out nocopy ut_realtime_reporter, - a_name in varchar2, - a_id in varchar2 default null + self in out nocopy ut_realtime_reporter, + a_node_name in varchar2, + a_attr_name in varchar2 default null, + a_attr_value in varchar2 default null ) is begin self.print_xml_fragment( - '<' || a_name + '<' || a_node_name || case - when a_id is not null then - ' id="' || dbms_xmlgen.convert(a_id) || '"' + when a_attr_name is not null and a_attr_value is not null then + ' ' || a_attr_name || '="' || dbms_xmlgen.convert(a_attr_value) || '"' end || '>', 0, 1 @@ -201,9 +214,9 @@ create or replace type body ut_realtime_reporter is ) is begin self.print_xml_fragment('', -1); - if a_name like '%Event' then + if a_name = 'event' then -- force new line to make complete event a.s.a.p. visible in consuming session - self.print_xml_fragment(null); + self.print_xml_fragment(' '); end if; end print_end_node; From 17ed19824f6159731fa466673db7205fbcfa25bf Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 23:53:10 +0100 Subject: [PATCH 27/38] changed name and description to match new output structure --- test/core/reporters/test_realtime_reporter.pks | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/core/reporters/test_realtime_reporter.pks b/test/core/reporters/test_realtime_reporter.pks index fa5bbd3ac..7b5862b15 100644 --- a/test/core/reporters/test_realtime_reporter.pks +++ b/test/core/reporters/test_realtime_reporter.pks @@ -15,11 +15,11 @@ create or replace package test_realtime_reporter as --%test(Escape special characters in data such as the test suite description) procedure escaped_characters; - --%test(Provide a startTestEvent node before starting a test with testNumber and totalNumberOfTests) - procedure number_of_starttestevent_nodes; + --%test(Provide a node before starting a test with testNumber and totalNumberOfTests) + procedure pre_test_nodes; - --%test(Provide a endTestEvent node after completion of a test with test results) - procedure endtestevent_nodes; + --%test(Provide a node after completion of a test with test results) + procedure post_test_nodes; --%test(Provide expectation message for a failed test) procedure single_failed_message; From eef59388f36bea4d963967d039db29222547e64b Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sat, 29 Dec 2018 23:54:50 +0100 Subject: [PATCH 28/38] test 26 event-based XML documents produced by the revised reporter --- .../core/reporters/test_realtime_reporter.pkb | 240 +++++++++++------- 1 file changed, 143 insertions(+), 97 deletions(-) diff --git a/test/core/reporters/test_realtime_reporter.pkb b/test/core/reporters/test_realtime_reporter.pkb index 2eb7b2c21..bd1df040a 100644 --- a/test/core/reporters/test_realtime_reporter.pkb +++ b/test/core/reporters/test_realtime_reporter.pkb @@ -1,6 +1,6 @@ create or replace package body test_realtime_reporter as - g_actual_xml_report xmltype; + g_xml_reports test_xmltype_list := test_xmltype_list(); procedure create_test_suites_and_run is pragma autonomous_transaction; @@ -101,118 +101,157 @@ create or replace package body test_realtime_reporter as end;]'; <> - declare - l_results ut3.ut_varchar2_list; + declare + l_clob clob; begin - select * - bulk collect into l_results - from table(ut3.ut.run('ut3_tester:realtime_reporting', ut3.ut_realtime_reporter())); - g_actual_xml_report := xmltype(ut3.ut_utils.table_to_clob(l_results)); + g_xml_reports.delete; + <> + for r in ( + with + base as ( + select sum(case when column_value like ''); - ut3.ut_utils.append_to_list(l_expected_list, '%'); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% %'); - ut3.ut_utils.append_to_list(l_expected_list, '% %'); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% %'); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '% '); - ut3.ut_utils.append_to_list(l_expected_list, '%'); - l_expected := ut3.ut_utils.table_to_clob(l_expected_list, null); - ut.expect(l_actual).to_be_like(l_expected); + open l_actual for + select t.column_value.extract('/event/@type').getstringval() as event_type, + t.column_value.extract('/event/suite/@id|/event/test/@id').getstringval() as item_id + from table(g_xml_reports) t; + open l_expected for + select 'pre-run' as event_type, null as item_id from dual union all + select 'pre-suite' as event_type, 'realtime_reporting' as item_id from dual union all + select 'pre-suite' as event_type, 'realtime_reporting.check_realtime_reporting3' as item_id from dual union all + select 'pre-test' as event_type, 'realtime_reporting.check_realtime_reporting3.test_6_with_runtime_error' as item_id from dual union all + select 'post-test' as event_type, 'realtime_reporting.check_realtime_reporting3.test_6_with_runtime_error' as item_id from dual union all + select 'pre-test' as event_type, 'realtime_reporting.check_realtime_reporting3.test_7_with_serveroutput' as item_id from dual union all + select 'post-test' as event_type, 'realtime_reporting.check_realtime_reporting3.test_7_with_serveroutput' as item_id from dual union all + select 'post-suite' as event_type, 'realtime_reporting.check_realtime_reporting3' as item_id from dual union all + select 'pre-suite' as event_type, 'realtime_reporting.check_realtime_reporting2' as item_id from dual union all + select 'pre-test' as event_type, 'realtime_reporting.check_realtime_reporting2.test_3_ok' as item_id from dual union all + select 'post-test' as event_type, 'realtime_reporting.check_realtime_reporting2.test_3_ok' as item_id from dual union all + select 'pre-test' as event_type, 'realtime_reporting.check_realtime_reporting2.test_4_nok' as item_id from dual union all + select 'post-test' as event_type, 'realtime_reporting.check_realtime_reporting2.test_4_nok' as item_id from dual union all + select 'pre-test' as event_type, 'realtime_reporting.check_realtime_reporting2.test_5' as item_id from dual union all + select 'post-test' as event_type, 'realtime_reporting.check_realtime_reporting2.test_5' as item_id from dual union all + select 'post-suite' as event_type, 'realtime_reporting.check_realtime_reporting2' as item_id from dual union all + select 'pre-suite' as event_type, 'realtime_reporting.check_realtime_reporting1' as item_id from dual union all + select 'pre-suite' as event_type, 'realtime_reporting.check_realtime_reporting1.test context' as item_id from dual union all + select 'pre-test' as event_type, 'realtime_reporting.check_realtime_reporting1.test context.test_1_ok' as item_id from dual union all + select 'post-test' as event_type, 'realtime_reporting.check_realtime_reporting1.test context.test_1_ok' as item_id from dual union all + select 'pre-test' as event_type, 'realtime_reporting.check_realtime_reporting1.test context.test_2_nok' as item_id from dual union all + select 'post-test' as event_type, 'realtime_reporting.check_realtime_reporting1.test context.test_2_nok' as item_id from dual union all + select 'post-suite' as event_type, 'realtime_reporting.check_realtime_reporting1.test context' as item_id from dual union all + select 'post-suite' as event_type, 'realtime_reporting.check_realtime_reporting1' as item_id from dual union all + select 'post-suite' as event_type, 'realtime_reporting' as item_id from dual union all + select 'post-run' as event_type, null as item_id from dual; + ut.expect(l_actual).to_equal(l_expected); end xml_report_structure; procedure total_number_of_tests is l_actual integer; l_expected integer := 7; begin - l_actual := g_actual_xml_report.extract('/report/preRun/totalNumberOfTests/text()').getnumberval(); - ut.expect(l_actual).to_equal(l_expected); + select t.column_value.extract('/event/totalNumberOfTests/text()').getnumberval() + into l_actual + from table(g_xml_reports) t + where t.column_value.extract('/event/@type').getstringval() = 'pre-run'; end total_number_of_tests; procedure escaped_characters is l_actual varchar2(32767); l_expected varchar2(20) := 'suite <A>'; begin - l_actual := - g_actual_xml_report.extract( - '//suite[@id="realtime_reporting.check_realtime_reporting1"]/description/text()' - ).getstringval(); + select t.column_value.extract( + '//suite[@id="realtime_reporting.check_realtime_reporting1"]/description/text()' + ).getstringval() + into l_actual + from table(g_xml_reports) t + where t.column_value.extract('/event/@type').getstringval() = 'pre-run'; ut.expect(l_actual).to_equal(l_expected); end escaped_characters; - procedure number_of_starttestevent_nodes is - l_actual integer; - l_expected integer := 7; + procedure pre_test_nodes is + l_actual sys_refcursor; + l_expected sys_refcursor; begin - select count(*) - into l_actual - from xmltable( - '/report/runEvents/startTestEvent' - passing g_actual_xml_report - columns id varchar2(4000) path '@id', - test_number integer path 'testNumber', - total_number_of_tests integer path 'totalNumberOfTests' - ) - where id is not null - and test_number is not null - and total_number_of_tests is not null; - ut.expect(l_actual).to_equal(l_expected); - end number_of_starttestevent_nodes; + open l_actual for + select t.column_value.extract('//test/testNumber/text()') + .getnumberval() as test_number, + t.column_value.extract('//test/totalNumberOfTests/text()') + .getnumberval() as total_number_of_tests + from table(g_xml_reports) t + where t.column_value.extract('/event/@type').getstringval() = 'pre-test' + and t.column_value.extract('//test/@id').getstringval() is not null; + open l_expected for + select level as test_number, + 7 as total_number_of_tests + from dual + connect by level <= 7; + ut.expect(l_actual).to_equal(l_expected).unordered; + end pre_test_nodes; - procedure endtestevent_nodes is + procedure post_test_nodes is l_actual sys_refcursor; l_expected sys_refcursor; begin open l_actual for - select test_number, total_number_of_tests - from xmltable( - '/report/runEvents/endTestEvent' - passing g_actual_xml_report - columns id varchar2(4000) path '@id', - test_number integer path 'testNumber', - total_number_of_tests integer path 'totalNumberOfTests' - ) - where id is not null - and test_number is not null - and total_number_of_tests is not null; + select t.column_value.extract('//test/testNumber/text()') + .getnumberval() as test_number, + t.column_value.extract('//test/totalNumberOfTests/text()') + .getnumberval() as total_number_of_tests + from table(g_xml_reports) t + where t.column_value.extract('/event/@type').getstringval() = 'post-test' + and t.column_value.extract('//test/@id').getstringval() is not null + and t.column_value.extract('//test/startTime/text()').getstringval() is not null + and t.column_value.extract('//test/endTime/text()').getstringval() is not null + and t.column_value.extract('//test/executionTime/text()').getnumberval() is not null + and t.column_value.extract('//test/counter/disabled/text()').getnumberval() is not null + and t.column_value.extract('//test/counter/success/text()').getnumberval() is not null + and t.column_value.extract('//test/counter/failure/text()').getnumberval() is not null + and t.column_value.extract('//test/counter/error/text()').getnumberval() is not null + and t.column_value.extract('//test/counter/warning/text()').getnumberval() is not null; open l_expected for select level as test_number, 7 as total_number_of_tests from dual connect by level <= 7; ut.expect(l_actual).to_equal(l_expected).unordered; - end endtestevent_nodes; + end post_test_nodes; procedure single_failed_message is l_actual varchar2(32767); l_expected varchar2(80) := ''; begin - l_actual := - g_actual_xml_report.extract( - '/report/runEvents/endTestEvent[@id="realtime_reporting.check_realtime_reporting1.test context.test_2_nok"]/failedExpectations/expectation[1]/message/text()' - ).getstringval(); + select t.column_value.extract( + '/event/test/failedExpectations/expectation[1]/message/text()' + ).getstringval() + into l_actual + from table(g_xml_reports) t + where t.column_value.extract('/event[@type="post-test"]/test/@id').getstringval() + = 'realtime_reporting.check_realtime_reporting1.test context.test_2_nok'; ut.expect(l_actual).to_equal(l_expected); end single_failed_message; @@ -222,14 +261,17 @@ create or replace package body test_realtime_reporter as begin select count(*) into l_actual - from xmltable( - '/report/runEvents/endTestEvent[@id="realtime_reporting.check_realtime_reporting2.test_4_nok"]/failedExpectations/expectation' - passing g_actual_xml_report + from table(g_xml_reports) t, + xmltable( + '/event/test/failedExpectations/expectation' + passing t.column_value columns message clob path 'message', caller clob path 'caller' - ) - where message is not null - and caller is not null; + ) x + where t.column_value.extract('/event[@type="post-test"]/test/@id').getstringval() + = 'realtime_reporting.check_realtime_reporting2.test_4_nok' + and x.message is not null + and x.caller is not null; ut.expect(l_actual).to_equal(l_expected); end multiple_failed_messages; @@ -238,10 +280,11 @@ create or replace package body test_realtime_reporter as l_expected_list ut3.ut_varchar2_list; l_expected clob; begin - l_actual := - g_actual_xml_report.extract( - '/report/runEvents/endTestEvent[@id="realtime_reporting.check_realtime_reporting3.test_7_with_serveroutput"]/serverOutput/text()' - ).getclobval(); + select t.column_value.extract('//event/test/serverOutput/text()').getstringval() + into l_actual + from table(g_xml_reports) t + where t.column_value.extract('/event[@type="post-test"]/test/@id').getstringval() + = 'realtime_reporting.check_realtime_reporting3.test_7_with_serveroutput'; ut3.ut_utils.append_to_list(l_expected_list, ''); @@ -254,10 +297,11 @@ create or replace package body test_realtime_reporter as l_expected_list ut3.ut_varchar2_list; l_expected clob; begin - l_actual := - g_actual_xml_report.extract( - '/report/runEvents/endSuiteEvent[@id="realtime_reporting.check_realtime_reporting3"]/serverOutput/text()' - ).getclobval(); + select t.column_value.extract('//event/suite/serverOutput/text()').getstringval() + into l_actual + from table(g_xml_reports) t + where t.column_value.extract('/event[@type="post-suite"]/suite/@id').getstringval() + = 'realtime_reporting.check_realtime_reporting3'; ut3.ut_utils.append_to_list(l_expected_list, ''); @@ -287,10 +332,11 @@ create or replace package body test_realtime_reporter as l_expected_list ut3.ut_varchar2_list; l_expected clob; begin - l_actual := - g_actual_xml_report.extract( - '/report/runEvents/endSuiteEvent[@id="realtime_reporting.check_realtime_reporting3"]/errorStack/text()' - ).getclobval(); + select t.column_value.extract('//event/suite/errorStack/text()').getstringval() + into l_actual + from table(g_xml_reports) t + where t.column_value.extract('/event[@type="post-suite"]/suite/@id').getstringval() + = 'realtime_reporting.check_realtime_reporting3'; ut3.ut_utils.append_to_list(l_expected_list, ''); From eba2e9eee2801476dbd421a6a1423c644356aefc Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Sun, 30 Dec 2018 11:10:18 +0100 Subject: [PATCH 29/38] change comment to reflect new role of the member procedure --- source/reporters/ut_realtime_reporter.tps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/reporters/ut_realtime_reporter.tps b/source/reporters/ut_realtime_reporter.tps index 645351a17..5d8b315ec 100644 --- a/source/reporters/ut_realtime_reporter.tps +++ b/source/reporters/ut_realtime_reporter.tps @@ -58,7 +58,7 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( ), /** - * Provides closing tags. + * Indicates the end of the test run. */ overriding member procedure after_calling_run( self in out nocopy ut_realtime_reporter, From 8f5b73678a2821344f88c97f4e5538f17a30f0cf Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 30 Dec 2018 20:45:01 +0000 Subject: [PATCH 30/38] Added `item_type` attribute to output buffer. Converted `text` in output bugger to be CLOB. Refactored `ut.run` to continue providing output as text. --- source/api/ut.pkb | 114 +++++++++++------- .../output_buffers/ut_output_buffer_base.tps | 7 +- .../output_buffers/ut_output_buffer_tmp.sql | 5 +- .../output_buffers/ut_output_data_row.tps | 21 ++++ .../output_buffers/ut_output_data_rows.tps | 19 +++ .../output_buffers/ut_output_table_buffer.tpb | 80 ++++++------ .../output_buffers/ut_output_table_buffer.tps | 7 +- source/core/types/ut_output_reporter_base.tpb | 14 +-- source/core/types/ut_output_reporter_base.tps | 2 +- .../create_synonyms_and_grants_for_public.sql | 4 + source/create_user_grants.sql | 2 + source/create_user_synonyms.sql | 2 + source/install.sql | 2 + .../reporters/ut_documentation_reporter.tpb | 15 +++ .../reporters/ut_documentation_reporter.tps | 1 + test/core/test_output_buffer.pkb | 41 ++++--- test/core/test_output_buffer.pks | 2 +- 17 files changed, 229 insertions(+), 109 deletions(-) create mode 100644 source/core/output_buffers/ut_output_data_row.tps create mode 100644 source/core/output_buffers/ut_output_data_rows.tps diff --git a/source/api/ut.pkb b/source/api/ut.pkb index bb599704e..daa0b6df5 100644 --- a/source/api/ut.pkb +++ b/source/api/ut.pkb @@ -175,8 +175,10 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_lines sys_refcursor; - l_line varchar2(4000); + l_data sys_refcursor; + l_clob clob; + l_item_type varchar2(32767); + l_lines ut_varchar2_list; begin run_autonomous( ut_varchar2_list(), @@ -190,13 +192,16 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_lines into l_line; - exit when l_lines%notfound; - pipe row(l_line); + fetch l_data into l_clob, l_item_type; + exit when l_data%notfound; + l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); + for i in 1 .. l_lines.count loop + pipe row(l_lines(i)); + end loop; end loop; - close l_lines; + close l_data; end if; raise_if_packages_invalidated(); return; @@ -213,8 +218,10 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_lines sys_refcursor; - l_line varchar2(4000); + l_data sys_refcursor; + l_clob clob; + l_item_type varchar2(32767); + l_lines ut_varchar2_list; begin run_autonomous( ut_varchar2_list(), @@ -228,13 +235,16 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_lines into l_line; - exit when l_lines%notfound; - pipe row(l_line); + fetch l_data into l_clob, l_item_type; + exit when l_data%notfound; + l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); + for i in 1 .. l_lines.count loop + pipe row(l_lines(i)); + end loop; end loop; - close l_lines; + close l_data; end if; raise_if_packages_invalidated(); return; @@ -252,8 +262,10 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_lines sys_refcursor; - l_line varchar2(4000); + l_data sys_refcursor; + l_clob clob; + l_item_type varchar2(32767); + l_lines ut_varchar2_list; begin run_autonomous( a_paths, @@ -267,13 +279,16 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_lines into l_line; - exit when l_lines%notfound; - pipe row(l_line); + fetch l_data into l_clob, l_item_type; + exit when l_data%notfound; + l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); + for i in 1 .. l_lines.count loop + pipe row(l_lines(i)); + end loop; end loop; - close l_lines; + close l_data; end if; raise_if_packages_invalidated(); return; @@ -291,8 +306,10 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_lines sys_refcursor; - l_line varchar2(4000); + l_data sys_refcursor; + l_clob clob; + l_item_type varchar2(32767); + l_lines ut_varchar2_list; begin run_autonomous( a_paths, @@ -306,13 +323,16 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_lines into l_line; - exit when l_lines%notfound; - pipe row(l_line); + fetch l_data into l_clob, l_item_type; + exit when l_data%notfound; + l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); + for i in 1 .. l_lines.count loop + pipe row(l_lines(i)); + end loop; end loop; - close l_lines; + close l_data; end if; raise_if_packages_invalidated(); return; @@ -330,8 +350,10 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_lines sys_refcursor; - l_line varchar2(4000); + l_data sys_refcursor; + l_clob clob; + l_item_type varchar2(32767); + l_lines ut_varchar2_list; begin run_autonomous( ut_varchar2_list(a_path), @@ -345,13 +367,16 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_lines into l_line; - exit when l_lines%notfound; - pipe row(l_line); + fetch l_data into l_clob, l_item_type; + exit when l_data%notfound; + l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); + for i in 1 .. l_lines.count loop + pipe row(l_lines(i)); + end loop; end loop; - close l_lines; + close l_data; end if; raise_if_packages_invalidated(); return; @@ -369,8 +394,10 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_lines sys_refcursor; - l_line varchar2(4000); + l_data sys_refcursor; + l_clob clob; + l_item_type varchar2(32767); + l_lines ut_varchar2_list; begin run_autonomous( ut_varchar2_list(a_path), @@ -384,13 +411,16 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_lines := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_lines into l_line; - exit when l_lines%notfound; - pipe row(l_line); + fetch l_data into l_clob, l_item_type; + exit when l_data%notfound; + l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); + for i in 1 .. l_lines.count loop + pipe row(l_lines(i)); + end loop; end loop; - close l_lines; + close l_data; end if; raise_if_packages_invalidated(); return; diff --git a/source/core/output_buffers/ut_output_buffer_base.tps b/source/core/output_buffers/ut_output_buffer_base.tps index 6f69047d9..42c4a0d72 100644 --- a/source/core/output_buffers/ut_output_buffer_base.tps +++ b/source/core/output_buffers/ut_output_buffer_base.tps @@ -19,9 +19,10 @@ create or replace type ut_output_buffer_base authid definer as object( output_id raw(32), member procedure init(self in out nocopy ut_output_buffer_base), not instantiable member procedure close(self in ut_output_buffer_base), - not instantiable member procedure send_line(self in ut_output_buffer_base, a_text varchar2), - not instantiable member procedure send_lines(self in ut_output_buffer_base, a_text_list ut_varchar2_rows), - not instantiable member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_varchar2_rows pipelined, + not instantiable member procedure send_line(self in ut_output_buffer_base, a_text varchar2, a_item_type varchar2 := null), + not instantiable member procedure send_lines(self in ut_output_buffer_base, a_text_list ut_varchar2_rows, a_item_type varchar2 := null), + not instantiable member procedure send_clob(self in ut_output_buffer_base, a_text clob, a_item_type varchar2 := null), + not instantiable member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_output_data_rows pipelined, not instantiable member function get_lines_cursor(a_initial_timeout natural := null, a_timeout_sec natural := null) return sys_refcursor, not instantiable member procedure lines_to_dbms_output(self in ut_output_buffer_base, a_initial_timeout natural := null, a_timeout_sec natural := null) ) not final not instantiable diff --git a/source/core/output_buffers/ut_output_buffer_tmp.sql b/source/core/output_buffers/ut_output_buffer_tmp.sql index e8127e237..71f8d8178 100644 --- a/source/core/output_buffers/ut_output_buffer_tmp.sql +++ b/source/core/output_buffers/ut_output_buffer_tmp.sql @@ -19,12 +19,14 @@ create table ut_output_buffer_tmp$( */ output_id raw(32) not null, message_id number(38,0) not null, - text varchar2(4000), + text clob, + item_type varchar2(1000), is_finished number(1,0) default 0 not null, constraint ut_output_buffer_tmp_pk primary key(output_id, message_id), constraint ut_output_buffer_tmp_ck check(is_finished = 0 and text is not null or is_finished = 1 and text is null), constraint ut_output_buffer_fk1 foreign key (output_id) references ut_output_buffer_info_tmp$(output_id) ) organization index overflow nologging initrans 100 + lob(text) store as securefile ut_output_text(retention none) ; -- This is needed to be EBR ready as editioning view can only be created by edition enabled user @@ -58,6 +60,7 @@ limitations under the License. select output_id ,message_id ,text + ,item_type ,is_finished from ut_output_buffer_tmp$'; diff --git a/source/core/output_buffers/ut_output_data_row.tps b/source/core/output_buffers/ut_output_data_row.tps new file mode 100644 index 000000000..ddcb65710 --- /dev/null +++ b/source/core/output_buffers/ut_output_data_row.tps @@ -0,0 +1,21 @@ +create or replace type ut_output_data_row as object ( + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + text clob, + item_type varchar2(1000) +) +/ diff --git a/source/core/output_buffers/ut_output_data_rows.tps b/source/core/output_buffers/ut_output_data_rows.tps new file mode 100644 index 000000000..9575231ba --- /dev/null +++ b/source/core/output_buffers/ut_output_data_rows.tps @@ -0,0 +1,19 @@ +create or replace type ut_output_data_rows as + /* + utPLSQL - Version 3 + Copyright 2016 - 2018 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. + */ + table of ut_output_data_row +/ diff --git a/source/core/output_buffers/ut_output_table_buffer.tpb b/source/core/output_buffers/ut_output_table_buffer.tpb index e7045b9df..54adb0f97 100644 --- a/source/core/output_buffers/ut_output_table_buffer.tpb +++ b/source/core/output_buffers/ut_output_table_buffer.tpb @@ -46,38 +46,40 @@ create or replace type body ut_output_table_buffer is commit; end; - overriding member procedure send_line(self in ut_output_table_buffer, a_text varchar2) is + overriding member procedure send_line(self in ut_output_table_buffer, a_text varchar2, a_item_type varchar2 := null) is pragma autonomous_transaction; begin if a_text is not null then - if length(a_text) > ut_utils.gc_max_storage_varchar2_len then - self.send_lines( - ut_utils.convert_collection( - ut_utils.clob_to_table(a_text, ut_utils.gc_max_storage_varchar2_len) - ) - ); - else - insert into ut_output_buffer_tmp(output_id, message_id, text) - values (self.output_id, ut_message_id_seq.nextval, a_text); - end if; - commit; + insert into ut_output_buffer_tmp(output_id, message_id, text, item_type) + values (self.output_id, ut_message_id_seq.nextval, a_text, a_item_type); end if; + commit; end; - overriding member procedure send_lines(self in ut_output_table_buffer, a_text_list ut_varchar2_rows) is + overriding member procedure send_lines(self in ut_output_table_buffer, a_text_list ut_varchar2_rows, a_item_type varchar2 := null) is pragma autonomous_transaction; begin - insert into ut_output_buffer_tmp(output_id, message_id, text) - select self.output_id, ut_message_id_seq.nextval, t.column_value + insert into ut_output_buffer_tmp(output_id, message_id, text, item_type) + select self.output_id, ut_message_id_seq.nextval, t.column_value, a_item_type from table(a_text_list) t where t.column_value is not null; commit; end; + overriding member procedure send_clob(self in ut_output_table_buffer, a_text clob, a_item_type varchar2 := null) is + pragma autonomous_transaction; + begin + if a_text is not null and a_text != empty_clob() then + insert into ut_output_buffer_tmp(output_id, message_id, text, item_type) + values (self.output_id, ut_message_id_seq.nextval, a_text, a_item_type); + end if; + commit; + end; - overriding member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_varchar2_rows pipelined is - l_buffer_data ut_varchar2_rows; + overriding member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_output_data_rows pipelined is + l_buffer_data ut_output_data_rows; + l_message_ids ut_integer_list; l_already_waited_for number(10,2) := 0; l_finished boolean := false; lc_init_wait_sec constant naturaln := coalesce(a_initial_timeout, 60 * 60 * 4 ); -- 4 hours @@ -87,22 +89,24 @@ create or replace type body ut_output_table_buffer is lc_long_sleep_time constant number(1) := 1; --sleep for 1 s when waiting long lc_long_wait_time constant number(1) := 1; --waiting more than 1 sec l_sleep_time number(2,1) := lc_short_sleep_time; - function get_data_from_buffer return ut_varchar2_rows is - l_results ut_varchar2_rows; + + procedure remove_read_data(a_message_ids ut_integer_list) is pragma autonomous_transaction; begin - delete from ( - select * - from ut_output_buffer_tmp where output_id = self.output_id order by message_id - ) - returning text bulk collect into l_results; + delete from ut_output_buffer_tmp a + where a.output_id = self.output_id + and a.message_id in (select column_value from table(a_message_ids)); commit; - return l_results; end; begin loop - l_buffer_data := get_data_from_buffer(); + select a.message_id, ut_output_data_row(a.text, a.item_type) + bulk collect into l_message_ids, l_buffer_data + from ut_output_buffer_tmp a + where a.output_id = self.output_id + order by a.message_id; + --nothing fetched from output, wait and try again if l_buffer_data.count = 0 then dbms_lock.sleep(l_sleep_time); @@ -117,7 +121,7 @@ create or replace type body ut_output_table_buffer is l_already_waited_for := 0; l_sleep_time := lc_short_sleep_time; for i in 1 .. l_buffer_data.count loop - if l_buffer_data(i) is not null then + if l_buffer_data(i).text is not null then pipe row(l_buffer_data(i)); else l_finished := true; @@ -125,6 +129,7 @@ create or replace type body ut_output_table_buffer is end if; end loop; end if; + remove_read_data(l_message_ids); exit when l_already_waited_for >= l_wait_for or l_finished; end loop; return; @@ -134,22 +139,27 @@ create or replace type body ut_output_table_buffer is l_lines sys_refcursor; begin open l_lines for - select column_value as text + select text, item_type from table(self.get_lines(a_initial_timeout, a_timeout_sec)); return l_lines; end; overriding member procedure lines_to_dbms_output(self in ut_output_table_buffer, a_initial_timeout natural := null, a_timeout_sec natural := null) is - l_lines sys_refcursor; - l_line varchar2(32767); + l_data sys_refcursor; + l_clob clob; + l_item_type varchar2(32767); + l_lines ut_varchar2_list; begin - l_lines := self.get_lines_cursor(a_initial_timeout, a_timeout_sec); + l_data := self.get_lines_cursor(a_initial_timeout, a_timeout_sec); loop - fetch l_lines into l_line; - exit when l_lines%notfound; - dbms_output.put_line(l_line); + fetch l_data into l_clob, l_item_type; + exit when l_data%notfound; + l_lines := ut_utils.clob_to_table(l_clob); + for i in 1 .. l_lines.count loop + dbms_output.put_line(l_lines(i)); + end loop; end loop; - close l_lines; + close l_data; end; member procedure cleanup_buffer(self in ut_output_table_buffer, a_retention_time_sec natural := null) is diff --git a/source/core/output_buffers/ut_output_table_buffer.tps b/source/core/output_buffers/ut_output_table_buffer.tps index 0e6f83770..1c9acbd1d 100644 --- a/source/core/output_buffers/ut_output_table_buffer.tps +++ b/source/core/output_buffers/ut_output_table_buffer.tps @@ -19,10 +19,11 @@ create or replace type ut_output_table_buffer under ut_output_buffer_base ( start_date date, constructor function ut_output_table_buffer(self in out nocopy ut_output_table_buffer, a_output_id raw := null) return self as result, overriding member procedure init(self in out nocopy ut_output_table_buffer), - overriding member procedure send_line(self in ut_output_table_buffer, a_text varchar2), - overriding member procedure send_lines(self in ut_output_table_buffer, a_text_list ut_varchar2_rows), + overriding member procedure send_line(self in ut_output_table_buffer, a_text varchar2, a_item_type varchar2 := null), + overriding member procedure send_lines(self in ut_output_table_buffer, a_text_list ut_varchar2_rows, a_item_type varchar2 := null), + overriding member procedure send_clob(self in ut_output_table_buffer, a_text clob, a_item_type varchar2 := null), overriding member procedure close(self in ut_output_table_buffer), - overriding member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_varchar2_rows pipelined, + overriding member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_output_data_rows pipelined, overriding member function get_lines_cursor(a_initial_timeout natural := null, a_timeout_sec natural := null) return sys_refcursor, overriding member procedure lines_to_dbms_output(self in ut_output_table_buffer, a_initial_timeout natural := null, a_timeout_sec natural := null), member procedure cleanup_buffer(self in ut_output_table_buffer, a_retention_time_sec natural := null) diff --git a/source/core/types/ut_output_reporter_base.tpb b/source/core/types/ut_output_reporter_base.tpb index 3f62d6546..1dae9180b 100644 --- a/source/core/types/ut_output_reporter_base.tpb +++ b/source/core/types/ut_output_reporter_base.tpb @@ -51,10 +51,10 @@ create or replace type body ut_output_reporter_base is self.output_buffer.send_lines(a_text_lines); end; - final member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural) return ut_varchar2_rows pipelined is + final member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural) return ut_output_data_rows pipelined is begin - for i in (select column_value from table(self.output_buffer.get_lines(a_initial_timeout, a_timeout_sec))) loop - pipe row (i.column_value); + for i in (select value(x) val from table(self.output_buffer.get_lines(a_initial_timeout, a_timeout_sec)) x ) loop + pipe row (i.val); end loop; end; @@ -69,13 +69,11 @@ create or replace type body ut_output_reporter_base is end; member procedure print_clob(self in out nocopy ut_output_reporter_base, a_clob clob) is - l_lines ut_varchar2_list; begin if a_clob is not null and dbms_lob.getlength(a_clob) > 0 then - l_lines := ut_utils.clob_to_table(a_clob); - for i in 1 .. l_lines.count loop - self.print_text(l_lines(i)); - end loop; + self.print_text_lines( + ut_utils.convert_collection( ut_utils.clob_to_table( a_clob, ut_utils.gc_max_storage_varchar2_len ) ) + ); end if; end; diff --git a/source/core/types/ut_output_reporter_base.tps b/source/core/types/ut_output_reporter_base.tps index e23ac9273..6d9844493 100644 --- a/source/core/types/ut_output_reporter_base.tps +++ b/source/core/types/ut_output_reporter_base.tps @@ -25,7 +25,7 @@ create or replace type ut_output_reporter_base under ut_reporter_base( member procedure print_text_lines(self in out nocopy ut_output_reporter_base, a_text_lines ut_varchar2_rows), member procedure print_clob(self in out nocopy ut_output_reporter_base, a_clob clob), - final member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_varchar2_rows pipelined, + final member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_output_data_rows pipelined, final member function get_lines_cursor(a_initial_timeout natural := null, a_timeout_sec natural := null) return sys_refcursor, final member procedure lines_to_dbms_output(self in ut_output_reporter_base, a_initial_timeout natural := null, a_timeout_sec natural := null), overriding final member procedure on_finalize(self in out nocopy ut_output_reporter_base, a_run in ut_run) diff --git a/source/create_synonyms_and_grants_for_public.sql b/source/create_synonyms_and_grants_for_public.sql index 5bacdb60c..6eaaa669c 100644 --- a/source/create_synonyms_and_grants_for_public.sql +++ b/source/create_synonyms_and_grants_for_public.sql @@ -64,6 +64,8 @@ grant execute on &&ut3_owner..ut_varchar2_rows to public; grant execute on &&ut3_owner..ut_integer_list to public; grant execute on &&ut3_owner..ut_reporter_base to public; grant execute on &&ut3_owner..ut_output_reporter_base to public; +grant execute on &&ut3_owner..ut_output_data_row to public; +grant execute on &&ut3_owner..ut_output_data_rows to public; grant execute on &&ut3_owner..ut_coverage_reporter_base to public; grant execute on &&ut3_owner..ut_console_reporter_base to public; grant execute on &&ut3_owner..ut_coverage to public; @@ -144,6 +146,8 @@ create public synonym ut_varchar2_rows for &&ut3_owner..ut_varchar2_rows; create public synonym ut_integer_list for &&ut3_owner..ut_integer_list; create public synonym ut_reporter_base for &&ut3_owner..ut_reporter_base; create public synonym ut_output_reporter_base for &&ut3_owner..ut_output_reporter_base; +create public synonym ut_output_data_row for &&ut3_owner..ut_output_data_row; +create public synonym ut_output_data_rows for &&ut3_owner..ut_output_data_rows; create public synonym ut_coverage for &&ut3_owner..ut_coverage; create public synonym ut_coverage_options for &&ut3_owner..ut_coverage_options; create public synonym ut_coverage_helper for &&ut3_owner..ut_coverage_helper; diff --git a/source/create_user_grants.sql b/source/create_user_grants.sql index a8f3d5cb4..bf49e36f1 100644 --- a/source/create_user_grants.sql +++ b/source/create_user_grants.sql @@ -90,6 +90,8 @@ grant execute on &&ut3_owner..ut_coverage to &ut3_user; grant execute on &&ut3_owner..ut_coverage_options to &ut3_user; grant execute on &&ut3_owner..ut_coverage_helper to &ut3_user; grant execute on &&ut3_owner..ut_output_buffer_base to &ut3_user; +grant execute on &&ut3_owner..ut_output_data_row to &ut3_user; +grant execute on &&ut3_owner..ut_output_data_rows to &ut3_user; grant execute on &&ut3_owner..ut_output_table_buffer to &ut3_user; grant execute on &&ut3_owner..ut_file_mappings to &ut3_user; grant execute on &&ut3_owner..ut_file_mapping to &ut3_user; diff --git a/source/create_user_synonyms.sql b/source/create_user_synonyms.sql index 806f02e6e..97726b1bb 100644 --- a/source/create_user_synonyms.sql +++ b/source/create_user_synonyms.sql @@ -86,6 +86,8 @@ create or replace synonym &ut3_user..ut_varchar2_rows for &&ut3_owner..ut_varcha create or replace synonym &ut3_user..ut_integer_list for &&ut3_owner..ut_integer_list; create or replace synonym &ut3_user..ut_reporter_base for &&ut3_owner..ut_reporter_base; create or replace synonym &ut3_user..ut_output_reporter_base for &&ut3_owner..ut_output_reporter_base; +create or replace synonym &ut3_user..ut_output_data_row for &&ut3_owner..ut_output_data_row; +create or replace synonym &ut3_user..ut_output_data_rows for &&ut3_owner..ut_output_data_rows; create or replace synonym &ut3_user..ut_coverage for &&ut3_owner..ut_coverage; create or replace synonym &ut3_user..ut_coverage_options for &&ut3_owner..ut_coverage_options; create or replace synonym &ut3_user..ut_coverage_helper for &&ut3_owner..ut_coverage_helper; diff --git a/source/install.sql b/source/install.sql index a3a1dc715..e1478b536 100644 --- a/source/install.sql +++ b/source/install.sql @@ -80,6 +80,8 @@ alter session set current_schema = &&ut3_owner; @@install_component.sql 'core/types/ut_reporters.tps' --output buffer base api +@@install_component.sql 'core/output_buffers/ut_output_data_row.tps' +@@install_component.sql 'core/output_buffers/ut_output_data_rows.tps' @@install_component.sql 'core/output_buffers/ut_output_buffer_base.tps' --output buffer table @@install_component.sql 'core/output_buffers/ut_output_buffer_info_tmp.sql' diff --git a/source/reporters/ut_documentation_reporter.tpb b/source/reporters/ut_documentation_reporter.tpb index 73ac3bf1a..a17b2fb4e 100644 --- a/source/reporters/ut_documentation_reporter.tpb +++ b/source/reporters/ut_documentation_reporter.tpb @@ -29,6 +29,21 @@ create or replace type body ut_documentation_reporter is return rpad(' ', self.lvl * 2); end tab; + overriding member procedure print_clob(self in out nocopy ut_documentation_reporter, a_clob clob) is + l_lines ut_varchar2_list; + l_out_lines ut_varchar2_rows := ut_varchar2_rows(); + begin + if a_clob is not null and dbms_lob.getlength(a_clob) > 0 then + l_lines := ut_utils.clob_to_table(a_clob, ut_utils.gc_max_storage_varchar2_len - length(tab())); + for i in 1 .. l_lines.count loop + if l_lines(i) is not null then + ut_utils.append_to_list(l_out_lines, tab() || l_lines(i) ); + end if; + end loop; + (self as ut_output_reporter_base).print_text_lines(l_out_lines); + end if; + end; + overriding member procedure print_text(self in out nocopy ut_documentation_reporter, a_text varchar2) is l_lines ut_varchar2_list; begin diff --git a/source/reporters/ut_documentation_reporter.tps b/source/reporters/ut_documentation_reporter.tps index 717ab3cd7..b35cf081b 100644 --- a/source/reporters/ut_documentation_reporter.tps +++ b/source/reporters/ut_documentation_reporter.tps @@ -20,6 +20,7 @@ create or replace type ut_documentation_reporter under ut_console_reporter_base( constructor function ut_documentation_reporter(self in out nocopy ut_documentation_reporter) return self as result, member function tab(self in ut_documentation_reporter) return varchar2, + overriding member procedure print_clob(self in out nocopy ut_documentation_reporter, a_clob clob), overriding member procedure print_text(self in out nocopy ut_documentation_reporter, a_text varchar2), overriding member procedure before_calling_suite(self in out nocopy ut_documentation_reporter, a_suite ut_logical_suite), overriding member procedure after_calling_test(self in out nocopy ut_documentation_reporter, a_test ut_test), diff --git a/test/core/test_output_buffer.pkb b/test/core/test_output_buffer.pkb index a22f3772d..f7d3cbb8b 100644 --- a/test/core/test_output_buffer.pkb +++ b/test/core/test_output_buffer.pkb @@ -1,18 +1,30 @@ create or replace package body test_output_buffer is - procedure test_recieve is - l_result varchar2(4000); - l_remaining integer; - l_expected varchar2(4000); - l_buffer ut3.ut_output_buffer_base := ut3.ut_output_table_buffer(); + procedure test_receive is + l_actual_text clob; + l_actual_item_type varchar2(1000); + l_remaining integer; + l_expected_text clob; + l_expected_item_type varchar2(1000); + l_buffer ut3.ut_output_buffer_base; begin - --Act - l_expected := lpad('a text',4000,',a text'); - l_buffer.send_line(l_expected); + --Arrange + l_buffer := ut3.ut_output_table_buffer(); + l_expected_text := to_clob(lpad('a text', 31000, ',a text')) + || chr(10) || to_clob(lpad('a text', 31000, ',a text')) + || chr(13) || to_clob(lpad('a text', 31000, ',a text')) + || chr(13) || chr(10) || to_clob(lpad('a text', 31000, ',a text')) || to_clob(lpad('a text', 31000, ',a text')); + l_expected_item_type := lpad('some item type',1000,'-'); + --Act + l_buffer.send_clob(l_expected_text, l_expected_item_type); - select * into l_result from table(l_buffer.get_lines(0,0)); + select text, item_type + into l_actual_text, l_actual_item_type + from table(l_buffer.get_lines(0,0)); - ut.expect(l_result).to_equal(l_expected); + --Assert + ut.expect(l_actual_text).to_equal(l_expected_text); + ut.expect(l_actual_item_type).to_equal(l_expected_item_type); select count(1) into l_remaining from ut3.ut_output_buffer_tmp where output_id = l_buffer.output_id; @@ -45,18 +57,18 @@ create or replace package body test_output_buffer is end; procedure test_waiting_for_data is - l_result varchar2(4000); + l_result clob; l_remaining integer; - l_expected varchar2(4000); + l_expected clob; l_buffer ut3.ut_output_buffer_base := ut3.ut_output_table_buffer(); l_start timestamp; l_duration interval day to second; begin --Act - l_expected := lpad('a text',4000,',a text'); + l_expected := 'a text'; l_buffer.send_line(l_expected); l_start := localtimestamp; - select * into l_result from table(l_buffer.get_lines(1,1)); + select text into l_result from table(l_buffer.get_lines(1,1)); l_duration := localtimestamp - l_start; ut.expect(l_result).to_equal(l_expected); @@ -64,7 +76,6 @@ create or replace package body test_output_buffer is select count(1) into l_remaining from ut3.ut_output_buffer_tmp where output_id = l_buffer.output_id; ut.expect(l_remaining).to_equal(0); - end; end test_output_buffer; diff --git a/test/core/test_output_buffer.pks b/test/core/test_output_buffer.pks index 1392b39ad..417b1ce09 100644 --- a/test/core/test_output_buffer.pks +++ b/test/core/test_output_buffer.pks @@ -4,7 +4,7 @@ create or replace package test_output_buffer is --%suitepath(utplsql.core) --%test(Receives a line from buffer table and deletes) - procedure test_recieve; + procedure test_receive; --%test(Does not send line if null text given) procedure test_doesnt_send_on_null_text; From e02d238c2c2f271b63d785bd8f2d77ea8639dd1f Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 30 Dec 2018 21:07:31 +0000 Subject: [PATCH 31/38] Added `item_type` attribute to output reporters. Added missing items in uninstall. --- source/core/types/ut_output_reporter_base.tpb | 22 ++++++++----------- source/core/types/ut_output_reporter_base.tps | 6 ++--- .../reporters/ut_documentation_reporter.tpb | 8 +++---- .../reporters/ut_documentation_reporter.tps | 4 ++-- source/uninstall_objects.sql | 4 ++++ 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/source/core/types/ut_output_reporter_base.tpb b/source/core/types/ut_output_reporter_base.tpb index 1dae9180b..7b875c9e9 100644 --- a/source/core/types/ut_output_reporter_base.tpb +++ b/source/core/types/ut_output_reporter_base.tpb @@ -41,14 +41,19 @@ create or replace type body ut_output_reporter_base is l_output_table_buffer := treat(self.output_buffer as ut_output_table_buffer); end; - member procedure print_text(self in out nocopy ut_output_reporter_base, a_text varchar2) is + member procedure print_text(self in out nocopy ut_output_reporter_base, a_text varchar2, a_item_type varchar2 := null) is begin - self.output_buffer.send_line(a_text); + self.output_buffer.send_line(a_text, a_item_type); end; - member procedure print_text_lines(self in out nocopy ut_output_reporter_base, a_text_lines ut_varchar2_rows) is + member procedure print_text_lines(self in out nocopy ut_output_reporter_base, a_text_lines ut_varchar2_rows, a_item_type varchar2 := null) is begin - self.output_buffer.send_lines(a_text_lines); + self.output_buffer.send_lines(a_text_lines, a_item_type); + end; + + member procedure print_clob(self in out nocopy ut_output_reporter_base, a_clob clob, a_item_type varchar2 := null) is + begin + self.output_buffer.send_clob( a_clob, a_item_type ); end; final member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural) return ut_output_data_rows pipelined is @@ -68,15 +73,6 @@ create or replace type body ut_output_reporter_base is self.output_buffer.lines_to_dbms_output(a_initial_timeout, a_timeout_sec); end; - member procedure print_clob(self in out nocopy ut_output_reporter_base, a_clob clob) is - begin - if a_clob is not null and dbms_lob.getlength(a_clob) > 0 then - self.print_text_lines( - ut_utils.convert_collection( ut_utils.clob_to_table( a_clob, ut_utils.gc_max_storage_varchar2_len ) ) - ); - end if; - end; - overriding final member procedure on_finalize(self in out nocopy ut_output_reporter_base, a_run in ut_run) is begin self.output_buffer.close(); diff --git a/source/core/types/ut_output_reporter_base.tps b/source/core/types/ut_output_reporter_base.tps index 6d9844493..cb5c81ea5 100644 --- a/source/core/types/ut_output_reporter_base.tps +++ b/source/core/types/ut_output_reporter_base.tps @@ -21,9 +21,9 @@ create or replace type ut_output_reporter_base under ut_reporter_base( overriding member procedure set_reporter_id(self in out nocopy ut_output_reporter_base, a_reporter_id raw), overriding member procedure before_calling_run(self in out nocopy ut_output_reporter_base, a_run in ut_run), - member procedure print_text(self in out nocopy ut_output_reporter_base, a_text varchar2), - member procedure print_text_lines(self in out nocopy ut_output_reporter_base, a_text_lines ut_varchar2_rows), - member procedure print_clob(self in out nocopy ut_output_reporter_base, a_clob clob), + member procedure print_text(self in out nocopy ut_output_reporter_base, a_text varchar2, a_item_type varchar2 := null), + member procedure print_text_lines(self in out nocopy ut_output_reporter_base, a_text_lines ut_varchar2_rows, a_item_type varchar2 := null), + member procedure print_clob(self in out nocopy ut_output_reporter_base, a_clob clob, a_item_type varchar2 := null), final member function get_lines(a_initial_timeout natural := null, a_timeout_sec natural := null) return ut_output_data_rows pipelined, final member function get_lines_cursor(a_initial_timeout natural := null, a_timeout_sec natural := null) return sys_refcursor, diff --git a/source/reporters/ut_documentation_reporter.tpb b/source/reporters/ut_documentation_reporter.tpb index a17b2fb4e..ebb3cd262 100644 --- a/source/reporters/ut_documentation_reporter.tpb +++ b/source/reporters/ut_documentation_reporter.tpb @@ -29,7 +29,7 @@ create or replace type body ut_documentation_reporter is return rpad(' ', self.lvl * 2); end tab; - overriding member procedure print_clob(self in out nocopy ut_documentation_reporter, a_clob clob) is + overriding member procedure print_clob(self in out nocopy ut_documentation_reporter, a_clob clob, a_item_type varchar2 := null) is l_lines ut_varchar2_list; l_out_lines ut_varchar2_rows := ut_varchar2_rows(); begin @@ -40,17 +40,17 @@ create or replace type body ut_documentation_reporter is ut_utils.append_to_list(l_out_lines, tab() || l_lines(i) ); end if; end loop; - (self as ut_output_reporter_base).print_text_lines(l_out_lines); + (self as ut_output_reporter_base).print_text_lines(l_out_lines, a_item_type); end if; end; - overriding member procedure print_text(self in out nocopy ut_documentation_reporter, a_text varchar2) is + overriding member procedure print_text(self in out nocopy ut_documentation_reporter, a_text varchar2, a_item_type varchar2 := null) is l_lines ut_varchar2_list; begin if a_text is not null then l_lines := ut_utils.string_to_table(a_text); for i in 1 .. l_lines.count loop - (self as ut_output_reporter_base).print_text(tab || l_lines(i)); + (self as ut_output_reporter_base).print_text(tab || l_lines(i), a_item_type); end loop; end if; end; diff --git a/source/reporters/ut_documentation_reporter.tps b/source/reporters/ut_documentation_reporter.tps index b35cf081b..275408a35 100644 --- a/source/reporters/ut_documentation_reporter.tps +++ b/source/reporters/ut_documentation_reporter.tps @@ -20,8 +20,8 @@ create or replace type ut_documentation_reporter under ut_console_reporter_base( constructor function ut_documentation_reporter(self in out nocopy ut_documentation_reporter) return self as result, member function tab(self in ut_documentation_reporter) return varchar2, - overriding member procedure print_clob(self in out nocopy ut_documentation_reporter, a_clob clob), - overriding member procedure print_text(self in out nocopy ut_documentation_reporter, a_text varchar2), + overriding member procedure print_clob(self in out nocopy ut_documentation_reporter, a_clob clob, a_item_type varchar2 := null), + overriding member procedure print_text(self in out nocopy ut_documentation_reporter, a_text varchar2, a_item_type varchar2 := null), overriding member procedure before_calling_suite(self in out nocopy ut_documentation_reporter, a_suite ut_logical_suite), overriding member procedure after_calling_test(self in out nocopy ut_documentation_reporter, a_test ut_test), overriding member procedure after_calling_after_all (self in out nocopy ut_documentation_reporter, a_executable in ut_executable), diff --git a/source/uninstall_objects.sql b/source/uninstall_objects.sql index c20868079..f510acc2a 100644 --- a/source/uninstall_objects.sql +++ b/source/uninstall_objects.sql @@ -241,6 +241,10 @@ drop table ut_output_buffer_info_tmp$; drop sequence ut_message_id_seq; +drop type ut_output_data_rows force; + +drop type ut_output_data_row force; + drop type ut_results_counter force; drop type ut_expectation_results force; From fc0f0e99648a4a28b55a62b165b1715811bd94b9 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Sun, 30 Dec 2018 21:50:47 +0000 Subject: [PATCH 32/38] Fixed failing examples. --- examples/developer_examples/ut_custom_reporter.tpb | 4 ++-- examples/developer_examples/ut_custom_reporter.tps | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/developer_examples/ut_custom_reporter.tpb b/examples/developer_examples/ut_custom_reporter.tpb index 09991107c..48e8f4a96 100644 --- a/examples/developer_examples/ut_custom_reporter.tpb +++ b/examples/developer_examples/ut_custom_reporter.tpb @@ -16,9 +16,9 @@ create or replace type body ut_custom_reporter is return tab_str; end tab; - overriding member procedure print_text(a_text varchar2) is + overriding member procedure print_text(a_text varchar2, a_item_type varchar2 := null) is begin - (self as ut_documentation_reporter).print_text(tab || a_text); + (self as ut_documentation_reporter).print_text(tab || a_text, a_item_type); end; overriding member procedure before_calling_suite(self in out nocopy ut_custom_reporter, a_suite ut_logical_suite) as diff --git a/examples/developer_examples/ut_custom_reporter.tps b/examples/developer_examples/ut_custom_reporter.tps index aa68c03ad..cc7de666e 100644 --- a/examples/developer_examples/ut_custom_reporter.tps +++ b/examples/developer_examples/ut_custom_reporter.tps @@ -5,7 +5,7 @@ create or replace type ut_custom_reporter under ut_documentation_reporter -- Member functions and procedures constructor function ut_custom_reporter(a_tab_size integer default 4) return self as result, overriding member function tab(self in ut_custom_reporter) return varchar2, - overriding member procedure print_text(a_text varchar2), + overriding member procedure print_text(a_text varchar2, a_item_type varchar2 := null), overriding member procedure before_calling_suite(self in out nocopy ut_custom_reporter, a_suite ut_logical_suite), overriding member procedure before_calling_test(self in out nocopy ut_custom_reporter, a_test ut_test), overriding member procedure after_calling_test(self in out nocopy ut_custom_reporter, a_test ut_test), From fb965116444951b57838190eed70adac956a667d Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Mon, 31 Dec 2018 01:55:36 +0100 Subject: [PATCH 33/38] create object type and collection type for test_realtime_reporter --- test/helpers/test_event_list.tps | 2 ++ test/helpers/test_event_object.tps | 15 +++++++++++++++ test/helpers/test_xmltype_list.tps | 2 -- test/install_tests.sql | 3 ++- 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 test/helpers/test_event_list.tps create mode 100644 test/helpers/test_event_object.tps delete mode 100644 test/helpers/test_xmltype_list.tps diff --git a/test/helpers/test_event_list.tps b/test/helpers/test_event_list.tps new file mode 100644 index 000000000..8abf71b13 --- /dev/null +++ b/test/helpers/test_event_list.tps @@ -0,0 +1,2 @@ +create or replace type test_event_list as table of test_event_object; +/ diff --git a/test/helpers/test_event_object.tps b/test/helpers/test_event_object.tps new file mode 100644 index 000000000..da458d2c2 --- /dev/null +++ b/test/helpers/test_event_object.tps @@ -0,0 +1,15 @@ +declare + l_exists integer; +begin + select count(1) into l_exists from user_types where type_name = 'TEST_EVENT_OBJECT'; + if l_exists > 0 then + execute immediate 'drop type test_event_object force'; + end if; +end; +/ + +create or replace type test_event_object as object ( + event_type varchar2(1000), + event_doc xmltype +) +/ \ No newline at end of file diff --git a/test/helpers/test_xmltype_list.tps b/test/helpers/test_xmltype_list.tps deleted file mode 100644 index 9c1bd4445..000000000 --- a/test/helpers/test_xmltype_list.tps +++ /dev/null @@ -1,2 +0,0 @@ -create or replace type test_xmltype_list as table of xmltype; -/ diff --git a/test/install_tests.sql b/test/install_tests.sql index 3f758de3f..96d2702f8 100644 --- a/test/install_tests.sql +++ b/test/install_tests.sql @@ -13,7 +13,8 @@ alter session set plsql_optimize_level=0; @@helpers/other_dummy_object.tps @@helpers/test_dummy_object.tps @@helpers/test_dummy_object_list.tps -@@helpers/test_xmltype_list.tps +@@helpers/test_event_object.tps +@@helpers/test_event_list.tps --Install tests @@core.pks From 957e5c95bc25104cc46cc39e783c6ad498c0c1ab Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Mon, 31 Dec 2018 01:59:37 +0100 Subject: [PATCH 34/38] produce 1 row per event document using new output buffer --- source/reporters/ut_realtime_reporter.tpb | 27 +++-- source/reporters/ut_realtime_reporter.tps | 3 +- .../core/reporters/test_realtime_reporter.pkb | 106 ++++++++---------- 3 files changed, 62 insertions(+), 74 deletions(-) diff --git a/source/reporters/ut_realtime_reporter.tpb b/source/reporters/ut_realtime_reporter.tpb index 0e0b212fc..5d6d3eca5 100644 --- a/source/reporters/ut_realtime_reporter.tpb +++ b/source/reporters/ut_realtime_reporter.tpb @@ -78,7 +78,7 @@ create or replace type body ut_realtime_reporter is self.print_end_node('suites'); self.print_node('totalNumberOfTests', to_char(total_number_of_tests)); self.print_end_node('event'); - self.flush_print_buffer(); + self.flush_print_buffer('pre-run'); end before_calling_run; overriding member procedure after_calling_run( @@ -89,7 +89,7 @@ create or replace type body ut_realtime_reporter is self.print_xml_fragment(xml_header); self.print_start_node('event', 'type', 'post-run'); self.print_end_node('event'); - self.flush_print_buffer(); + self.flush_print_buffer('post-run'); end after_calling_run; overriding member procedure before_calling_suite( @@ -102,7 +102,7 @@ create or replace type body ut_realtime_reporter is self.print_start_node('suite', 'id', a_suite.path); self.print_end_node('suite'); self.print_end_node('event'); - self.flush_print_buffer(); + self.flush_print_buffer('pre-suite'); end before_calling_suite; overriding member procedure after_calling_suite( @@ -127,7 +127,7 @@ create or replace type body ut_realtime_reporter is self.print_cdata_node('serverOutput', a_suite.get_serveroutputs()); self.print_end_node('suite'); self.print_end_node('event'); - self.flush_print_buffer(); + self.flush_print_buffer('post-suite'); end after_calling_suite; overriding member procedure before_calling_test( @@ -143,7 +143,7 @@ create or replace type body ut_realtime_reporter is self.print_node('totalNumberOfTests', to_char(total_number_of_tests)); self.print_end_node('test'); self.print_end_node('event'); - self.flush_print_buffer(); + self.flush_print_buffer('pre-test'); end before_calling_test; overriding member procedure after_calling_test( @@ -182,7 +182,7 @@ create or replace type body ut_realtime_reporter is end if; self.print_end_node('test'); self.print_end_node('event'); - self.flush_print_buffer(); + self.flush_print_buffer('post-test'); end after_calling_test; overriding member function get_description return varchar2 is @@ -214,10 +214,6 @@ create or replace type body ut_realtime_reporter is ) is begin self.print_xml_fragment('', -1); - if a_name = 'event' then - -- force new line to make complete event a.s.a.p. visible in consuming session - self.print_xml_fragment(' '); - end if; end print_end_node; member procedure print_node( @@ -255,10 +251,17 @@ create or replace type body ut_realtime_reporter is end print_xml_fragment; member procedure flush_print_buffer( - self in out nocopy ut_realtime_reporter + self in out nocopy ut_realtime_reporter, + a_item_type in varchar2 ) is + l_doc clob; + l_rows integer := print_buffer.count; begin - self.print_text_lines(print_buffer); + for i in 1 .. l_rows loop + ut_utils.append_to_clob(l_doc, print_buffer(i)); + ut_utils.append_to_clob(l_doc, chr(10)); + end loop; + self.print_clob(l_doc, a_item_type); print_buffer.delete; end flush_print_buffer; diff --git a/source/reporters/ut_realtime_reporter.tps b/source/reporters/ut_realtime_reporter.tps index 5d8b315ec..49305b247 100644 --- a/source/reporters/ut_realtime_reporter.tps +++ b/source/reporters/ut_realtime_reporter.tps @@ -155,7 +155,8 @@ create or replace type ut_realtime_reporter force under ut_output_reporter_base( * Flushes the local print buffer to the output buffer. */ member procedure flush_print_buffer( - self in out nocopy ut_realtime_reporter + self in out nocopy ut_realtime_reporter, + a_item_type in varchar2 ) ) not final diff --git a/test/core/reporters/test_realtime_reporter.pkb b/test/core/reporters/test_realtime_reporter.pkb index bd1df040a..2ecc222dc 100644 --- a/test/core/reporters/test_realtime_reporter.pkb +++ b/test/core/reporters/test_realtime_reporter.pkb @@ -1,6 +1,6 @@ create or replace package body test_realtime_reporter as - g_xml_reports test_xmltype_list := test_xmltype_list(); + g_xml_reports test_event_list := test_event_list(); procedure create_test_suites_and_run is pragma autonomous_transaction; @@ -102,33 +102,17 @@ create or replace package body test_realtime_reporter as <> declare - l_clob clob; + l_reporter ut3.ut_realtime_reporter := ut3.ut_realtime_reporter(); begin - g_xml_reports.delete; - <> - for r in ( - with - base as ( - select sum(case when column_value like ' ut3.ut_varchar2_list(':realtime_reporting'), + a_reporters => ut3.ut_reporters(l_reporter) + ); + -- consume + select test_event_object(item_type, xmltype(text)) + bulk collect into g_xml_reports + from table(ut3.ut_output_table_buffer(l_reporter.output_buffer.output_id).get_lines()); end run_report_and_cache_result; end create_test_suites_and_run; @@ -137,8 +121,8 @@ create or replace package body test_realtime_reporter as l_expected sys_refcursor; begin open l_actual for - select t.column_value.extract('/event/@type').getstringval() as event_type, - t.column_value.extract('/event/suite/@id|/event/test/@id').getstringval() as item_id + select t.event_doc.extract('/event/@type').getstringval() as event_type, + t.event_doc.extract('/event/suite/@id|/event/test/@id').getstringval() as item_id from table(g_xml_reports) t; open l_expected for select 'pre-run' as event_type, null as item_id from dual union all @@ -174,22 +158,22 @@ create or replace package body test_realtime_reporter as l_actual integer; l_expected integer := 7; begin - select t.column_value.extract('/event/totalNumberOfTests/text()').getnumberval() + select t.event_doc.extract('/event/totalNumberOfTests/text()').getnumberval() into l_actual from table(g_xml_reports) t - where t.column_value.extract('/event/@type').getstringval() = 'pre-run'; + where t.event_type = 'pre-run'; end total_number_of_tests; procedure escaped_characters is l_actual varchar2(32767); l_expected varchar2(20) := 'suite <A>'; begin - select t.column_value.extract( + select t.event_doc.extract( '//suite[@id="realtime_reporting.check_realtime_reporting1"]/description/text()' ).getstringval() into l_actual from table(g_xml_reports) t - where t.column_value.extract('/event/@type').getstringval() = 'pre-run'; + where t.event_type = 'pre-run'; ut.expect(l_actual).to_equal(l_expected); end escaped_characters; @@ -198,13 +182,13 @@ create or replace package body test_realtime_reporter as l_expected sys_refcursor; begin open l_actual for - select t.column_value.extract('//test/testNumber/text()') + select t.event_doc.extract('//test/testNumber/text()') .getnumberval() as test_number, - t.column_value.extract('//test/totalNumberOfTests/text()') + t.event_doc.extract('//test/totalNumberOfTests/text()') .getnumberval() as total_number_of_tests from table(g_xml_reports) t - where t.column_value.extract('/event/@type').getstringval() = 'pre-test' - and t.column_value.extract('//test/@id').getstringval() is not null; + where t.event_type = 'pre-test' + and t.event_doc.extract('//test/@id').getstringval() is not null; open l_expected for select level as test_number, 7 as total_number_of_tests @@ -218,21 +202,21 @@ create or replace package body test_realtime_reporter as l_expected sys_refcursor; begin open l_actual for - select t.column_value.extract('//test/testNumber/text()') + select t.event_doc.extract('//test/testNumber/text()') .getnumberval() as test_number, - t.column_value.extract('//test/totalNumberOfTests/text()') + t.event_doc.extract('//test/totalNumberOfTests/text()') .getnumberval() as total_number_of_tests from table(g_xml_reports) t - where t.column_value.extract('/event/@type').getstringval() = 'post-test' - and t.column_value.extract('//test/@id').getstringval() is not null - and t.column_value.extract('//test/startTime/text()').getstringval() is not null - and t.column_value.extract('//test/endTime/text()').getstringval() is not null - and t.column_value.extract('//test/executionTime/text()').getnumberval() is not null - and t.column_value.extract('//test/counter/disabled/text()').getnumberval() is not null - and t.column_value.extract('//test/counter/success/text()').getnumberval() is not null - and t.column_value.extract('//test/counter/failure/text()').getnumberval() is not null - and t.column_value.extract('//test/counter/error/text()').getnumberval() is not null - and t.column_value.extract('//test/counter/warning/text()').getnumberval() is not null; + where t.event_type = 'post-test' + and t.event_doc.extract('//test/@id').getstringval() is not null + and t.event_doc.extract('//test/startTime/text()').getstringval() is not null + and t.event_doc.extract('//test/endTime/text()').getstringval() is not null + and t.event_doc.extract('//test/executionTime/text()').getnumberval() is not null + and t.event_doc.extract('//test/counter/disabled/text()').getnumberval() is not null + and t.event_doc.extract('//test/counter/success/text()').getnumberval() is not null + and t.event_doc.extract('//test/counter/failure/text()').getnumberval() is not null + and t.event_doc.extract('//test/counter/error/text()').getnumberval() is not null + and t.event_doc.extract('//test/counter/warning/text()').getnumberval() is not null; open l_expected for select level as test_number, 7 as total_number_of_tests @@ -245,12 +229,12 @@ create or replace package body test_realtime_reporter as l_actual varchar2(32767); l_expected varchar2(80) := ''; begin - select t.column_value.extract( + select t.event_doc.extract( '/event/test/failedExpectations/expectation[1]/message/text()' ).getstringval() into l_actual from table(g_xml_reports) t - where t.column_value.extract('/event[@type="post-test"]/test/@id').getstringval() + where t.event_doc.extract('/event[@type="post-test"]/test/@id').getstringval() = 'realtime_reporting.check_realtime_reporting1.test context.test_2_nok'; ut.expect(l_actual).to_equal(l_expected); end single_failed_message; @@ -264,11 +248,11 @@ create or replace package body test_realtime_reporter as from table(g_xml_reports) t, xmltable( '/event/test/failedExpectations/expectation' - passing t.column_value + passing t.event_doc columns message clob path 'message', caller clob path 'caller' ) x - where t.column_value.extract('/event[@type="post-test"]/test/@id').getstringval() + where t.event_doc.extract('/event[@type="post-test"]/test/@id').getstringval() = 'realtime_reporting.check_realtime_reporting2.test_4_nok' and x.message is not null and x.caller is not null; @@ -280,10 +264,10 @@ create or replace package body test_realtime_reporter as l_expected_list ut3.ut_varchar2_list; l_expected clob; begin - select t.column_value.extract('//event/test/serverOutput/text()').getstringval() + select t.event_doc.extract('//event/test/serverOutput/text()').getstringval() into l_actual from table(g_xml_reports) t - where t.column_value.extract('/event[@type="post-test"]/test/@id').getstringval() + where t.event_doc.extract('/event[@type="post-test"]/test/@id').getstringval() = 'realtime_reporting.check_realtime_reporting3.test_7_with_serveroutput'; ut3.ut_utils.append_to_list(l_expected_list, ' Date: Mon, 31 Dec 2018 02:22:44 +0100 Subject: [PATCH 35/38] renamed package persistent variable --- .../core/reporters/test_realtime_reporter.pkb | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/core/reporters/test_realtime_reporter.pkb b/test/core/reporters/test_realtime_reporter.pkb index 2ecc222dc..aec0faee2 100644 --- a/test/core/reporters/test_realtime_reporter.pkb +++ b/test/core/reporters/test_realtime_reporter.pkb @@ -1,6 +1,6 @@ create or replace package body test_realtime_reporter as - g_xml_reports test_event_list := test_event_list(); + g_events test_event_list := test_event_list(); procedure create_test_suites_and_run is pragma autonomous_transaction; @@ -111,7 +111,7 @@ create or replace package body test_realtime_reporter as ); -- consume select test_event_object(item_type, xmltype(text)) - bulk collect into g_xml_reports + bulk collect into g_events from table(ut3.ut_output_table_buffer(l_reporter.output_buffer.output_id).get_lines()); end run_report_and_cache_result; end create_test_suites_and_run; @@ -123,7 +123,7 @@ create or replace package body test_realtime_reporter as open l_actual for select t.event_doc.extract('/event/@type').getstringval() as event_type, t.event_doc.extract('/event/suite/@id|/event/test/@id').getstringval() as item_id - from table(g_xml_reports) t; + from table(g_events) t; open l_expected for select 'pre-run' as event_type, null as item_id from dual union all select 'pre-suite' as event_type, 'realtime_reporting' as item_id from dual union all @@ -160,7 +160,7 @@ create or replace package body test_realtime_reporter as begin select t.event_doc.extract('/event/totalNumberOfTests/text()').getnumberval() into l_actual - from table(g_xml_reports) t + from table(g_events) t where t.event_type = 'pre-run'; end total_number_of_tests; @@ -172,7 +172,7 @@ create or replace package body test_realtime_reporter as '//suite[@id="realtime_reporting.check_realtime_reporting1"]/description/text()' ).getstringval() into l_actual - from table(g_xml_reports) t + from table(g_events) t where t.event_type = 'pre-run'; ut.expect(l_actual).to_equal(l_expected); end escaped_characters; @@ -186,7 +186,7 @@ create or replace package body test_realtime_reporter as .getnumberval() as test_number, t.event_doc.extract('//test/totalNumberOfTests/text()') .getnumberval() as total_number_of_tests - from table(g_xml_reports) t + from table(g_events) t where t.event_type = 'pre-test' and t.event_doc.extract('//test/@id').getstringval() is not null; open l_expected for @@ -206,7 +206,7 @@ create or replace package body test_realtime_reporter as .getnumberval() as test_number, t.event_doc.extract('//test/totalNumberOfTests/text()') .getnumberval() as total_number_of_tests - from table(g_xml_reports) t + from table(g_events) t where t.event_type = 'post-test' and t.event_doc.extract('//test/@id').getstringval() is not null and t.event_doc.extract('//test/startTime/text()').getstringval() is not null @@ -233,7 +233,7 @@ create or replace package body test_realtime_reporter as '/event/test/failedExpectations/expectation[1]/message/text()' ).getstringval() into l_actual - from table(g_xml_reports) t + from table(g_events) t where t.event_doc.extract('/event[@type="post-test"]/test/@id').getstringval() = 'realtime_reporting.check_realtime_reporting1.test context.test_2_nok'; ut.expect(l_actual).to_equal(l_expected); @@ -245,7 +245,7 @@ create or replace package body test_realtime_reporter as begin select count(*) into l_actual - from table(g_xml_reports) t, + from table(g_events) t, xmltable( '/event/test/failedExpectations/expectation' passing t.event_doc @@ -266,7 +266,7 @@ create or replace package body test_realtime_reporter as begin select t.event_doc.extract('//event/test/serverOutput/text()').getstringval() into l_actual - from table(g_xml_reports) t + from table(g_events) t where t.event_doc.extract('/event[@type="post-test"]/test/@id').getstringval() = 'realtime_reporting.check_realtime_reporting3.test_7_with_serveroutput'; ut3.ut_utils.append_to_list(l_expected_list, ' Date: Mon, 31 Dec 2018 11:03:11 +0100 Subject: [PATCH 36/38] Fix crash due to null value. --- source/reporters/ut_documentation_reporter.tpb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/reporters/ut_documentation_reporter.tpb b/source/reporters/ut_documentation_reporter.tpb index ebb3cd262..df6c25ab0 100644 --- a/source/reporters/ut_documentation_reporter.tpb +++ b/source/reporters/ut_documentation_reporter.tpb @@ -34,7 +34,7 @@ create or replace type body ut_documentation_reporter is l_out_lines ut_varchar2_rows := ut_varchar2_rows(); begin if a_clob is not null and dbms_lob.getlength(a_clob) > 0 then - l_lines := ut_utils.clob_to_table(a_clob, ut_utils.gc_max_storage_varchar2_len - length(tab())); + l_lines := ut_utils.clob_to_table(a_clob, ut_utils.gc_max_storage_varchar2_len - length(nvl(tab(),0))); for i in 1 .. l_lines.count loop if l_lines(i) is not null then ut_utils.append_to_list(l_out_lines, tab() || l_lines(i) ); From 73669ebbff7fda715fc5e5a3b32f562a568c7089 Mon Sep 17 00:00:00 2001 From: Philipp Salvisberg Date: Tue, 1 Jan 2019 09:51:56 +0100 Subject: [PATCH 37/38] Fixed issues with nested runs Introduced a stack of suspended event managers to support tested test runs. --- source/core/events/ut_event_manager.pkb | 34 +++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/source/core/events/ut_event_manager.pkb b/source/core/events/ut_event_manager.pkb index 7ae0ad0b3..b48b6d7f4 100644 --- a/source/core/events/ut_event_manager.pkb +++ b/source/core/events/ut_event_manager.pkb @@ -21,15 +21,42 @@ create or replace package body ut_event_manager as type t_listener_numbers is table of boolean index by t_listener_number; type t_events_listeners is table of t_listener_numbers index by t_event_name; - g_event_listeners_index t_events_listeners; - g_listeners t_listeners; + type t_event_manager is record ( + event_listener_index t_events_listeners, + listeners t_listeners + ); + type t_event_managers is table of t_event_manager; + + g_event_listeners_index t_events_listeners; + g_listeners t_listeners; + g_suspended_event_managers t_event_managers; procedure initialize is begin + if g_listeners is not null and g_listeners.count > 0 then + if g_suspended_event_managers is null then + g_suspended_event_managers := t_event_managers(); + end if; + g_suspended_event_managers.extend; + g_suspended_event_managers(g_suspended_event_managers.count).event_listener_index := g_event_listeners_index; + g_suspended_event_managers(g_suspended_event_managers.count).listeners := g_listeners; + end if; g_event_listeners_index.delete; g_listeners := t_listeners(); end; + procedure dispose_listeners is + begin + if g_suspended_event_managers is not null and g_suspended_event_managers.count > 0 then + g_event_listeners_index := g_suspended_event_managers(g_suspended_event_managers.count).event_listener_index; + g_listeners := g_suspended_event_managers(g_suspended_event_managers.count).listeners; + g_suspended_event_managers.trim(1); + else + g_event_listeners_index.delete; + g_listeners := t_listeners(); + end if; + end; + procedure trigger_event( a_event_name t_event_name, a_event_object ut_event_item ) is begin if a_event_name is not null and g_event_listeners_index.exists(a_event_name) @@ -39,6 +66,9 @@ create or replace package body ut_event_manager as for listener_number in 1 .. g_event_listeners_index(a_event_name).count loop g_listeners(listener_number).on_event(a_event_name, a_event_object); end loop; + if a_event_name = ut_utils.gc_finalize then + dispose_listeners; + end if; end if; end; From cc3a7e4e23f0b4885c8db00706878e609189f4b1 Mon Sep 17 00:00:00 2001 From: Jacek Gebal Date: Tue, 1 Jan 2019 16:08:27 +0000 Subject: [PATCH 38/38] Extracted duplicated code from pipelined functions into `get_report_outputs` iterator function. --- source/api/ut.pkb | 126 +++++++++++++++++----------------------------- 1 file changed, 47 insertions(+), 79 deletions(-) diff --git a/source/api/ut.pkb b/source/api/ut.pkb index daa0b6df5..5710f78c4 100644 --- a/source/api/ut.pkb +++ b/source/api/ut.pkb @@ -20,6 +20,9 @@ create or replace package body ut is g_nls_date_format varchar2(4000); gc_fail_on_errors constant boolean := false; + g_result_line_no binary_integer; + g_result_lines ut_varchar2_list := ut_varchar2_list(); + function version return varchar2 is begin return ut_runner.version(); @@ -164,6 +167,31 @@ create or replace package body ut is rollback; end; + function get_report_outputs( a_cursor sys_refcursor ) return varchar2 is + l_clob clob; + l_item_type varchar2(32767); + l_result varchar2(4000); + begin + if g_result_line_no is null then + fetch a_cursor into l_clob, l_item_type; + if a_cursor%notfound then + close a_cursor; + g_result_line_no := null; + g_result_lines := ut_varchar2_list(); + raise_if_packages_invalidated(); + raise no_data_found; + end if; + g_result_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); + g_result_line_no := g_result_lines.first; + end if; + + if g_result_line_no is not null then + l_result := g_result_lines(g_result_line_no); + g_result_line_no := g_result_lines.next(g_result_line_no); + end if; + return l_result; + end; + function run( a_reporter ut_reporter_base := null, a_color_console integer := 0, @@ -175,10 +203,7 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_data sys_refcursor; - l_clob clob; - l_item_type varchar2(32767); - l_lines ut_varchar2_list; + l_results sys_refcursor; begin run_autonomous( ut_varchar2_list(), @@ -192,18 +217,11 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_data into l_clob, l_item_type; - exit when l_data%notfound; - l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); - for i in 1 .. l_lines.count loop - pipe row(l_lines(i)); - end loop; + pipe row( get_report_outputs( l_results ) ); end loop; - close l_data; end if; - raise_if_packages_invalidated(); return; end; @@ -218,10 +236,7 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_data sys_refcursor; - l_clob clob; - l_item_type varchar2(32767); - l_lines ut_varchar2_list; + l_results sys_refcursor; begin run_autonomous( ut_varchar2_list(), @@ -235,18 +250,11 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_data into l_clob, l_item_type; - exit when l_data%notfound; - l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); - for i in 1 .. l_lines.count loop - pipe row(l_lines(i)); - end loop; + pipe row( get_report_outputs( l_results ) ); end loop; - close l_data; end if; - raise_if_packages_invalidated(); return; end; @@ -262,10 +270,7 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_data sys_refcursor; - l_clob clob; - l_item_type varchar2(32767); - l_lines ut_varchar2_list; + l_results sys_refcursor; begin run_autonomous( a_paths, @@ -279,18 +284,11 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_data into l_clob, l_item_type; - exit when l_data%notfound; - l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); - for i in 1 .. l_lines.count loop - pipe row(l_lines(i)); - end loop; + pipe row( get_report_outputs( l_results ) ); end loop; - close l_data; end if; - raise_if_packages_invalidated(); return; end; @@ -306,10 +304,7 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_data sys_refcursor; - l_clob clob; - l_item_type varchar2(32767); - l_lines ut_varchar2_list; + l_results sys_refcursor; begin run_autonomous( a_paths, @@ -323,18 +318,11 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_data into l_clob, l_item_type; - exit when l_data%notfound; - l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); - for i in 1 .. l_lines.count loop - pipe row(l_lines(i)); - end loop; + pipe row( get_report_outputs( l_results ) ); end loop; - close l_data; end if; - raise_if_packages_invalidated(); return; end; @@ -349,11 +337,8 @@ create or replace package body ut is a_exclude_objects ut_varchar2_list := null, a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is - l_reporter ut_reporter_base := a_reporter; - l_data sys_refcursor; - l_clob clob; - l_item_type varchar2(32767); - l_lines ut_varchar2_list; + l_reporter ut_reporter_base := a_reporter; + l_results sys_refcursor; begin run_autonomous( ut_varchar2_list(a_path), @@ -367,18 +352,11 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_data into l_clob, l_item_type; - exit when l_data%notfound; - l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); - for i in 1 .. l_lines.count loop - pipe row(l_lines(i)); - end loop; + pipe row( get_report_outputs( l_results ) ); end loop; - close l_data; end if; - raise_if_packages_invalidated(); return; end; @@ -394,10 +372,7 @@ create or replace package body ut is a_client_character_set varchar2 := null ) return ut_varchar2_rows pipelined is l_reporter ut_reporter_base := a_reporter; - l_data sys_refcursor; - l_clob clob; - l_item_type varchar2(32767); - l_lines ut_varchar2_list; + l_results sys_refcursor; begin run_autonomous( ut_varchar2_list(a_path), @@ -411,18 +386,11 @@ create or replace package body ut is a_client_character_set ); if l_reporter is of (ut_output_reporter_base) then - l_data := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); + l_results := treat(l_reporter as ut_output_reporter_base).get_lines_cursor(); loop - fetch l_data into l_clob, l_item_type; - exit when l_data%notfound; - l_lines := ut_utils.clob_to_table(l_clob, ut_utils.gc_max_storage_varchar2_len); - for i in 1 .. l_lines.count loop - pipe row(l_lines(i)); - end loop; + pipe row( get_report_outputs( l_results ) ); end loop; - close l_data; end if; - raise_if_packages_invalidated(); return; end;