diff --git a/examples/RunExampleComplexSuiteWithCustomDBMSOutputReporter.sql b/examples/RunExampleComplexSuiteWithCustomDBMSOutputReporter.sql index 370b949e3..2bbad89ab 100644 --- a/examples/RunExampleComplexSuiteWithCustomDBMSOutputReporter.sql +++ b/examples/RunExampleComplexSuiteWithCustomDBMSOutputReporter.sql @@ -43,6 +43,6 @@ begin end; / ---drop type ut_custom_reporter; +drop type ut_custom_reporter; drop package ut_exampletest; drop package ut_exampletest2; diff --git a/examples/ut_custom_reporter.tpb b/examples/ut_custom_reporter.tpb index cf552b111..fda5e2467 100644 --- a/examples/ut_custom_reporter.tpb +++ b/examples/ut_custom_reporter.tpb @@ -32,10 +32,10 @@ create or replace type body ut_custom_reporter is lvl := lvl + 1; end; - overriding member procedure on_assert(self in out nocopy ut_custom_reporter, an_assert ut_object) is + overriding member procedure on_assert(self in out nocopy ut_custom_reporter, a_assert ut_object) is begin lvl := lvl + 1; - (self as ut_dbms_output_suite_reporter).on_assert(an_assert); + (self as ut_dbms_output_suite_reporter).on_assert(a_assert); lvl := lvl - 1; end; diff --git a/examples/ut_custom_reporter.tps b/examples/ut_custom_reporter.tps index 7c078c339..7034693d3 100644 --- a/examples/ut_custom_reporter.tps +++ b/examples/ut_custom_reporter.tps @@ -9,7 +9,7 @@ create or replace type ut_custom_reporter under ut_dbms_output_suite_reporter overriding member procedure print(msg varchar2), overriding member procedure begin_suite(self in out nocopy ut_custom_reporter, a_suite ut_object), overriding member procedure begin_test(self in out nocopy ut_custom_reporter, a_test ut_object), - overriding member procedure on_assert(self in out nocopy ut_custom_reporter, an_assert ut_object), + overriding member procedure on_assert(self in out nocopy ut_custom_reporter, a_assert ut_object), overriding member procedure end_test(self in out nocopy ut_custom_reporter, a_test ut_object), overriding member procedure end_suite(self in out nocopy ut_custom_reporter, a_suite ut_object) ) diff --git a/source/install.sql b/source/install.sql index a6dc56c6a..cffd8972a 100644 --- a/source/install.sql +++ b/source/install.sql @@ -17,6 +17,7 @@ @@ut_utils.pkb @@types/ut_assert_result.tpb +@@types/ut_suite_reporter.tpb @@types/ut_object.tpb @@types/ut_composite_object.tpb @@types/ut_test.tpb diff --git a/source/types/ut_composite_object.tpb b/source/types/ut_composite_object.tpb index a036e93d4..5b64eb80c 100644 --- a/source/types/ut_composite_object.tpb +++ b/source/types/ut_composite_object.tpb @@ -1,4 +1,5 @@ create or replace type body ut_composite_object is + member procedure calc_execution_result(self in out nocopy ut_composite_object) is l_result integer(1) := ut_utils.tr_success; begin @@ -9,5 +10,28 @@ create or replace type body ut_composite_object is self.result := l_result; end; + -- Member procedures and functions + member function item_index(a_object_name varchar2) return pls_integer is + l_item_index pls_integer := self.items.first; + c_lowered_obj_name constant varchar2(4000 char) := lower(trim(a_object_name)); + l_result pls_integer; + begin + while l_item_index is not null loop + if self.items(l_item_index) is of(ut_test_object) and treat(self.items(l_item_index) as ut_test_object) + .object_name = c_lowered_obj_name then + l_result := l_item_index; + exit; + end if; + l_item_index := self.items.next(l_item_index); + end loop; + return l_result; + end item_index; + + member procedure add_item(self in out nocopy ut_composite_object, a_item ut_object) is + begin + self.items.extend; + self.items(self.items.last) := a_item; + end add_item; + end; / diff --git a/source/types/ut_composite_object.tps b/source/types/ut_composite_object.tps index 8f1891df6..e891fca46 100644 --- a/source/types/ut_composite_object.tps +++ b/source/types/ut_composite_object.tps @@ -2,6 +2,8 @@ create or replace type ut_composite_object force under ut_object ( items ut_objects_list, - member procedure calc_execution_result(self in out nocopy ut_composite_object) + member procedure calc_execution_result(self in out nocopy ut_composite_object), + member function item_index(a_object_name varchar2) return pls_integer, + member procedure add_item(self in out nocopy ut_composite_object, a_item ut_object) ) not final not instantiable / diff --git a/source/types/ut_suite_reporter.tpb b/source/types/ut_suite_reporter.tpb new file mode 100644 index 000000000..d09380357 --- /dev/null +++ b/source/types/ut_suite_reporter.tpb @@ -0,0 +1,30 @@ +create or replace type body ut_suite_reporter is + + -- Member procedures and functions + member procedure begin_suite(self in out nocopy ut_suite_reporter, a_suite in ut_object) is + begin + null; + end begin_suite; + + member procedure begin_test(self in out nocopy ut_suite_reporter, a_test in ut_object) is + begin + null; + end begin_test; + + member procedure on_assert(self in out nocopy ut_suite_reporter, a_assert in ut_object) is + begin + null; + end on_assert; + + member procedure end_test(self in out nocopy ut_suite_reporter, a_test in ut_object) is + begin + null; + end end_test; + + member procedure end_suite(self in out nocopy ut_suite_reporter, a_suite in ut_object) is + begin + null; + end end_suite; + +end; +/ diff --git a/source/types/ut_suite_reporter.tps b/source/types/ut_suite_reporter.tps index b8e052c4e..69778937a 100644 --- a/source/types/ut_suite_reporter.tps +++ b/source/types/ut_suite_reporter.tps @@ -2,11 +2,11 @@ create or replace type ut_suite_reporter force as object ( name varchar2(250 char), - not instantiable member procedure begin_suite(self in out nocopy ut_suite_reporter, a_suite in ut_object), - not instantiable member procedure begin_test(self in out nocopy ut_suite_reporter, a_test in ut_object), - not instantiable member procedure on_assert(self in out nocopy ut_suite_reporter, a_assert in ut_object), - not instantiable member procedure end_test(self in out nocopy ut_suite_reporter, a_test in ut_object), - not instantiable member procedure end_suite(self in out nocopy ut_suite_reporter, a_suite in ut_object) + member procedure begin_suite(self in out nocopy ut_suite_reporter, a_suite in ut_object), + member procedure begin_test(self in out nocopy ut_suite_reporter, a_test in ut_object), + member procedure on_assert(self in out nocopy ut_suite_reporter, a_assert in ut_object), + member procedure end_test(self in out nocopy ut_suite_reporter, a_test in ut_object), + member procedure end_suite(self in out nocopy ut_suite_reporter, a_suite in ut_object) ) not instantiable not final diff --git a/source/types/ut_test.tpb b/source/types/ut_test.tpb index f023805e6..08c23e90b 100644 --- a/source/types/ut_test.tpb +++ b/source/types/ut_test.tpb @@ -5,28 +5,29 @@ create or replace type body ut_test is begin self.name := a_test_name; self.object_type := 1; + self.object_name := lower(trim(a_test_procedure)); self.test := ut_executable(object_name => trim(a_object_name) - ,procedure_name => trim(a_test_procedure) - ,owner_name => trim(a_owner_name)); + ,procedure_name => trim(a_test_procedure) + ,owner_name => trim(a_owner_name)); if a_setup_procedure is not null then self.setup := ut_executable(object_name => trim(a_object_name) - ,procedure_name => trim(a_setup_procedure) - ,owner_name => trim(a_owner_name)); + ,procedure_name => trim(a_setup_procedure) + ,owner_name => trim(a_owner_name)); end if; if a_teardown_procedure is not null then self.teardown := ut_executable(object_name => trim(a_object_name) - ,procedure_name => trim(a_teardown_procedure) - ,owner_name => trim(a_owner_name)); + ,procedure_name => trim(a_teardown_procedure) + ,owner_name => trim(a_owner_name)); end if; return; end ut_test; - member function is_valid(self in ut_test) return boolean is + member function is_valid return boolean is begin - return test.is_valid('test') and (setup is null or setup.is_valid('setup')) and - (teardown is null or teardown.is_valid('teardown')); + return test.is_valid('test') and(setup is null or setup.is_valid('setup')) and(teardown is null or + teardown.is_valid('teardown')); end is_valid; overriding member procedure execute(self in out nocopy ut_test, a_reporter ut_suite_reporter) is @@ -66,7 +67,7 @@ create or replace type body ut_test is $end ut_assert.report_error(sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_backtrace); end; - + if self.teardown is not null then self.teardown.execute; end if; diff --git a/source/types/ut_test.tps b/source/types/ut_test.tps index 5cad074f9..3c3b78a32 100644 --- a/source/types/ut_test.tps +++ b/source/types/ut_test.tps @@ -1,13 +1,13 @@ create or replace type ut_test force under ut_test_object ( - setup ut_executable, - test ut_executable, - teardown ut_executable, + setup ut_executable, + test ut_executable, + teardown ut_executable, constructor function ut_test(a_object_name varchar2, a_test_procedure varchar2, a_test_name in varchar2 default null, a_owner_name varchar2 default null, a_setup_procedure varchar2 default null, a_teardown_procedure varchar2 default null) return self as result, - member function is_valid(self in ut_test) return boolean, + member function is_valid return boolean, overriding member procedure execute(self in out nocopy ut_test, a_reporter ut_suite_reporter), overriding member function execute(self in out nocopy ut_test, a_reporter ut_suite_reporter) return ut_suite_reporter, diff --git a/source/types/ut_test_object.tps b/source/types/ut_test_object.tps index 047797f6a..808c5df9e 100644 --- a/source/types/ut_test_object.tps +++ b/source/types/ut_test_object.tps @@ -1,10 +1,12 @@ create or replace type ut_test_object force under ut_composite_object ( - start_time timestamp with time zone, - end_time timestamp with time zone, - not instantiable member procedure execute(self in out nocopy ut_test_object, a_reporter ut_suite_reporter), - not instantiable member function execute(self in out nocopy ut_test_object, a_reporter ut_suite_reporter) return ut_suite_reporter, - not instantiable member procedure execute(self in out nocopy ut_test_object) + start_time timestamp with time zone, + end_time timestamp with time zone, + object_name varchar2(32), + not instantiable member procedure execute(self in out nocopy ut_test_object, a_reporter ut_suite_reporter), + not instantiable member function execute(self in out nocopy ut_test_object, a_reporter ut_suite_reporter) + return ut_suite_reporter, + not instantiable member procedure execute(self in out nocopy ut_test_object) ) not instantiable not final / diff --git a/source/types/ut_test_suite.tpb b/source/types/ut_test_suite.tpb index 462457cda..bc2128d68 100644 --- a/source/types/ut_test_suite.tpb +++ b/source/types/ut_test_suite.tpb @@ -1,19 +1,37 @@ create or replace type body ut_test_suite is - constructor function ut_test_suite(a_suite_name varchar2, a_items ut_objects_list default ut_objects_list()) + constructor function ut_test_suite(a_suite_name varchar2, a_object_name varchar2 default null, a_items ut_objects_list default ut_objects_list()) return self as result is begin - self.name := a_suite_name; - self.object_type := 2; - self.items := a_items; + self.name := a_suite_name; + self.object_type := 2; + self.items := a_items; + self.object_name := lower(trim(a_object_name)); return; end ut_test_suite; - member procedure add_item(self in out nocopy ut_test_suite, a_item ut_test_object) is + member procedure set_suite_setup(self in out nocopy ut_test_suite, a_object_name in varchar2, a_proc_name in varchar2, a_owner_name varchar2 default null) is begin - self.items.extend; - self.items(self.items.last) := a_item; - end add_item; + self.setup := ut_executable(object_name => trim(a_object_name) + ,procedure_name => trim(a_proc_name) + ,owner_name => trim(a_owner_name)); + end; + + member procedure set_suite_teardown(self in out nocopy ut_test_suite, a_object_name in varchar2, a_proc_name in varchar2, a_owner_name varchar2 default null) is + begin + self.teardown := ut_executable(object_name => trim(a_object_name) + ,procedure_name => trim(a_proc_name) + ,owner_name => trim(a_owner_name)); + end; + + member function is_valid return boolean is + l_is_valid boolean; + begin + l_is_valid := (setup is null or setup.is_valid('suitesetup')) and + (teardown is null or teardown.is_valid('suiteteardown')); + + return l_is_valid; + end is_valid; overriding member procedure execute(self in out nocopy ut_test_suite, a_reporter ut_suite_reporter) is l_reporter ut_suite_reporter := a_reporter; @@ -21,8 +39,9 @@ create or replace type body ut_test_suite is l_reporter := execute(l_reporter); end; - overriding member function execute(self in out nocopy ut_test_suite, a_reporter ut_suite_reporter) return ut_suite_reporter is - l_reporter ut_suite_reporter := a_reporter; + overriding member function execute(self in out nocopy ut_test_suite, a_reporter ut_suite_reporter) + return ut_suite_reporter is + l_reporter ut_suite_reporter := a_reporter; l_test_object ut_test_object; begin if l_reporter is not null then @@ -35,15 +54,28 @@ create or replace type body ut_test_suite is self.start_time := current_timestamp; - for i in self.items.first .. self.items.last loop - l_test_object := treat(self.items(i) as ut_test_object); - l_reporter := l_test_object.execute(a_reporter => l_reporter); - self.items(i) := l_test_object; - end loop; + if self.is_valid() then + + if self.setup is not null then + self.setup.execute; + end if; + + for i in self.items.first .. self.items.last loop + l_test_object := treat(self.items(i) as ut_test_object); + l_reporter := l_test_object.execute(a_reporter => l_reporter); + self.items(i) := l_test_object; + end loop; + + if self.setup is not null then + self.teardown.execute; + end if; + + self.calc_execution_result; + else + self.result := ut_utils.tr_error; + end if; self.end_time := current_timestamp; - - self.calc_execution_result; if l_reporter is not null then l_reporter.end_suite(self); @@ -52,7 +84,7 @@ create or replace type body ut_test_suite is end; overriding member procedure execute(self in out nocopy ut_test_suite) is - l_null_reporter ut_suite_reporter; + l_null_reporter ut_suite_reporter; begin self.execute(l_null_reporter); end; diff --git a/source/types/ut_test_suite.tps b/source/types/ut_test_suite.tps index 2125aac3a..29caccdc4 100644 --- a/source/types/ut_test_suite.tps +++ b/source/types/ut_test_suite.tps @@ -1,11 +1,20 @@ create or replace type ut_test_suite force under ut_test_object ( - constructor function ut_test_suite(a_suite_name varchar2, a_items ut_objects_list default ut_objects_list()) return self as result, - member procedure add_item(self in out nocopy ut_test_suite, a_item ut_test_object), + setup ut_executable, + teardown ut_executable, + + constructor function ut_test_suite(a_suite_name varchar2, a_object_name varchar2 default null, a_items ut_objects_list default ut_objects_list()) + return self as result, + + member procedure set_suite_setup(self in out nocopy ut_test_suite, a_object_name in varchar2, a_proc_name in varchar2, a_owner_name varchar2 default null), + + member procedure set_suite_teardown(self in out nocopy ut_test_suite, a_object_name in varchar2, a_proc_name in varchar2, a_owner_name varchar2 default null), + member function is_valid return boolean, overriding member procedure execute(self in out nocopy ut_test_suite, a_reporter ut_suite_reporter), - overriding member function execute(self in out nocopy ut_test_suite, a_reporter ut_suite_reporter) return ut_suite_reporter, + overriding member function execute(self in out nocopy ut_test_suite, a_reporter ut_suite_reporter) + return ut_suite_reporter, overriding member procedure execute(self in out nocopy ut_test_suite) ) not final