diff --git a/examples/RunAllExamples.sql b/examples/RunAllExamples.sql new file mode 100644 index 000000000..29e3faafc --- /dev/null +++ b/examples/RunAllExamples.sql @@ -0,0 +1,23 @@ +Clear Screen +set echo off +set feedback off +prompt RunExampleComplexSuiteWithCustomDBMSOutputReporter +@@RunExampleComplexSuiteWithCustomDBMSOutputReporter.sql +prompt RunExampleTestSuite +@@RunExampleTestSuite.sql +prompt RunExampleTestSuiteWithCustomDBMSOutputReporter +@@RunExampleTestSuiteWithCustomDBMSOutputReporter.sql +prompt RunExampleTestSuiteWithDBMSOutputReporter +@@RunExampleTestSuiteWithDBMSOutputReporter.sql +prompt RunExampleTestThroughBaseClass +@@RunExampleTestThroughBaseClass.sql +prompt TestPackageName +@@TestPackageName.sql +prompt TestProcedureName +@@TestProcedureName.sql +prompt TestOwnerName +@@TestOwnerName.sql +prompt TestSetupProcedureName +@@TestSetupProcedureName.sql +prompt TestTeardownProcedureName +@@TestTeardownProcedureName.sql diff --git a/examples/RunExampleComplexSuiteWithCustomDBMSOutputReporter.sql b/examples/RunExampleComplexSuiteWithCustomDBMSOutputReporter.sql index 2bf7a4a8a..370b949e3 100644 --- a/examples/RunExampleComplexSuiteWithCustomDBMSOutputReporter.sql +++ b/examples/RunExampleComplexSuiteWithCustomDBMSOutputReporter.sql @@ -1,7 +1,7 @@ --Shows how to create a test suite with the default reporter which is dbms_output --No tables are used for this. --Suite Management packages are when developed will make this easier. -Clear Screen +--Clear Screen Set Serveroutput On Size Unlimited format truncated set echo off --install the example unit test packages @@ -36,11 +36,13 @@ begin suite2.add_item(testtoexecute); - suite_complex := ut_test_suite(a_suite_name => 'Complex Test Suite', a_items => ut_test_objects_list(suite1, suite2)); + suite_complex := ut_test_suite(a_suite_name => 'Complex Test Suite', a_items => ut_objects_list(suite1, suite2)); -- provide a reporter to process results suite_complex.execute(ut_custom_reporter(a_tab_size => 2)); end; / -drop type ut_custom_reporter; +--drop type ut_custom_reporter; +drop package ut_exampletest; +drop package ut_exampletest2; diff --git a/examples/RunExampleTestSuite.sql b/examples/RunExampleTestSuite.sql index 9361b3398..50a9855bd 100644 --- a/examples/RunExampleTestSuite.sql +++ b/examples/RunExampleTestSuite.sql @@ -1,7 +1,7 @@ --Shows how to create a test suite in code and call the test runner. --No tables are used for this. --Suite Management packages are when developed will make this easier. -Clear Screen +--Clear Screen Set Serveroutput On Size Unlimited format truncated set echo off --install the example unit test packages @@ -14,6 +14,7 @@ declare suite ut_test_suite; testtoexecute ut_test; test_item ut_test; + assert ut_assert_result; begin suite := ut_test_suite(a_suite_name => 'Test Suite Name' /*,a_items => ut_test_objects_list()*/); @@ -36,14 +37,18 @@ begin for test_idx in suite.items.first .. suite.items.last loop test_item := treat(suite.items(test_idx) as ut_test); dbms_output.put_line('---------------------------------------------------'); - dbms_output.put_line('Test:' || test_item.call_params.object_name || '.' || test_item.call_params.test_procedure); - dbms_output.put_line('Result: ' || test_item.execution_result.result_to_char); + dbms_output.put_line('Test:' || test_item.test.form_name); + dbms_output.put_line('Result: ' || test_item.result_to_char); dbms_output.put_line('Assert Results:'); - for i in test_item.assert_results.first .. test_item.assert_results.last loop - dbms_output.put_line(i || ' - result: ' || test_item.assert_results(i).result_to_char); - dbms_output.put_line(i || ' - Message: ' || test_item.assert_results(i).message); + for i in test_item.items.first .. test_item.items.last loop + assert := treat(test_item.items(i) as ut_assert_result); + dbms_output.put_line(i || ' - result: ' || assert.result_to_char); + dbms_output.put_line(i || ' - Message: ' || assert.message); end loop; end loop; dbms_output.put_line('---------------------------------------------------'); end; / + +drop package ut_exampletest; +drop package ut_exampletest2; diff --git a/examples/RunExampleTestSuiteWithCustomDBMSOutputReporter.sql b/examples/RunExampleTestSuiteWithCustomDBMSOutputReporter.sql index a021b46af..dec74a3a8 100644 --- a/examples/RunExampleTestSuiteWithCustomDBMSOutputReporter.sql +++ b/examples/RunExampleTestSuiteWithCustomDBMSOutputReporter.sql @@ -1,8 +1,9 @@ --Shows how to create a test suite with the default reporter which is dbms_output --No tables are used for this. --Suite Management packages are when developed will make this easier. -Clear Screen -Set Serveroutput On Size Unlimited format truncated --http://stackoverflow.com/questions/2584492/how-to-prevent-dbms-output-put-line-from-trimming-leading-whitespace +--Clear Screen +--http://stackoverflow.com/questions/2584492/how-to-prevent-dbms-output-put-line-from-trimming-leading-whitespace +Set Serveroutput On Size Unlimited format truncated set echo off --install the example unit test packages @@ut_exampletest.pks @@ -40,4 +41,7 @@ end; / -drop type ut_custom_reporter; +--FIXME this drop is causing issues when executing script several times within single session +--drop type ut_custom_reporter; +drop package ut_exampletest; +drop package ut_exampletest2; diff --git a/examples/RunExampleTestSuiteWithDBMSOutputReporter.sql b/examples/RunExampleTestSuiteWithDBMSOutputReporter.sql index ba352461b..633b168d9 100644 --- a/examples/RunExampleTestSuiteWithDBMSOutputReporter.sql +++ b/examples/RunExampleTestSuiteWithDBMSOutputReporter.sql @@ -1,7 +1,7 @@ --Shows how to create a test suite with the default reporter which is dbms_output --No tables are used for this. --Suite Management packages are when developed will make this easier. -Clear Screen +--Clear Screen Set Serveroutput On Size Unlimited format truncated set echo off --install the example unit test packages @@ -34,3 +34,6 @@ begin suite.execute(ut_dbms_output_suite_reporter); end; / + +drop package ut_exampletest; +drop package ut_exampletest2; diff --git a/examples/RunExampleTestThroughBaseClass.sql b/examples/RunExampleTestThroughBaseClass.sql index 64617eea5..80f969d70 100644 --- a/examples/RunExampleTestThroughBaseClass.sql +++ b/examples/RunExampleTestThroughBaseClass.sql @@ -1,6 +1,6 @@ --This shows how the interna test engine works to test a single package. --No tables are used for this and exceptions are handled better. -Clear Screen +--Clear Screen Set Serveroutput On Size Unlimited format truncated set echo off --install the example unit test packages @@ -23,3 +23,5 @@ begin simple_test.execute(reporter); end; / + +drop package ut_exampletest; diff --git a/examples/TestOwnerName.sql b/examples/TestOwnerName.sql new file mode 100644 index 000000000..164696c7f --- /dev/null +++ b/examples/TestOwnerName.sql @@ -0,0 +1,54 @@ +--This shows how the interna test engine works to test a single package. +--No tables are used for this and exceptions are handled better. +--Clear Screen +Set Serveroutput On Size Unlimited format truncated +set echo off + +--Arrange +@@ut_exampletest.pks +@@ut_exampletest.pkb + +PROMPT Does not report error when test owner name for a test is null +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => 'ut_exampletest' + ,a_test_procedure => 'ut_exampletest' + ,a_owner_name => null); + + simple_test.execute(); + +--Assert + if simple_test.result != ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +PROMPT Reports error when test owner name for a test is invalid +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => 'ut_exampletest' + ,a_test_procedure => 'ut_exampletest' + ,a_owner_name => 'invalid owner name'); + + simple_test.execute(); + +--Assert + if simple_test.result = ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +--Cleanup +drop package ut_exampletest; diff --git a/examples/TestPackageName.sql b/examples/TestPackageName.sql new file mode 100644 index 000000000..7af811478 --- /dev/null +++ b/examples/TestPackageName.sql @@ -0,0 +1,81 @@ +--Clear Screen +Set Serveroutput On Size Unlimited format truncated +set echo off + +--Arrange +PROMPT Reports error when unit test package name for a test is null +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => null, a_test_procedure => 'ut_exampletest'); + + simple_test.execute(); + +--Assert + if simple_test.result = ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +--Arrange +PROMPT Reports error when unit test package name for a test is invalid +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => 'invalid test package name', a_test_procedure => 'ut_exampletest'); + + simple_test.execute(); + +--Assert + if simple_test.result = ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +--Arrange +PROMPT Reports error when unit test package for a test is in invalid state +begin + execute immediate + 'create or replace package invalid_package is + v_variable non_existing_type; + procedure ut_exampletest; + end;'; +exception when others then + if sqlcode = - 24344 then + dbms_output.put_line(' Invalid package created'); + else + raise; + end if; +end; +/ + +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => 'invalid_package', a_test_procedure => 'ut_exampletest'); + + simple_test.execute(); + +--Assert + if simple_test.result = ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +--Cleanup +drop package invalid_package; diff --git a/examples/TestProcedureName.sql b/examples/TestProcedureName.sql new file mode 100644 index 000000000..01b0b67ed --- /dev/null +++ b/examples/TestProcedureName.sql @@ -0,0 +1,52 @@ +--This shows how the interna test engine works to test a single package. +--No tables are used for this and exceptions are handled better. +--Clear Screen +Set Serveroutput On Size Unlimited format truncated +set echo off + +--Arrange +@@ut_exampletest.pks +@@ut_exampletest.pkb + +PROMPT Reports error when test procedure name for a test is null +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => 'ut_exampletest' + ,a_test_procedure => null); + + simple_test.execute(); + +--Assert + if simple_test.result = ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +PROMPT Reports error when test procedure name for a test is invalid +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => 'ut_exampletest' + ,a_test_procedure => 'invalid procedure name'); + + simple_test.execute(); + +--Assert + if simple_test.result = ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +--Cleanup +drop package ut_exampletest; diff --git a/examples/TestSetupProcedureName.sql b/examples/TestSetupProcedureName.sql new file mode 100644 index 000000000..c2d686bf6 --- /dev/null +++ b/examples/TestSetupProcedureName.sql @@ -0,0 +1,54 @@ +--This shows how the interna test engine works to test a single package. +--No tables are used for this and exceptions are handled better. +--Clear Screen +Set Serveroutput On Size Unlimited format truncated +set echo off + +--Arrange +@@ut_exampletest.pks +@@ut_exampletest.pkb + +PROMPT Does not report error when test setup procedure name for a test is null +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => 'ut_exampletest' + ,a_test_procedure => 'ut_exampletest' + ,a_setup_procedure => null); + + simple_test.execute(); + +--Assert + if simple_test.result != ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +PROMPT Reports error when test setup procedure name for a test is invalid +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => 'ut_exampletest' + ,a_test_procedure => 'ut_exampletest' + ,a_setup_procedure => 'invalid setup name'); + + simple_test.execute(); + +--Assert + if simple_test.result = ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +--Cleanup +drop package ut_exampletest; diff --git a/examples/TestTeardownProcedureName.sql b/examples/TestTeardownProcedureName.sql new file mode 100644 index 000000000..12ee60757 --- /dev/null +++ b/examples/TestTeardownProcedureName.sql @@ -0,0 +1,54 @@ +--This shows how the interna test engine works to test a single package. +--No tables are used for this and exceptions are handled better. +--Clear Screen +Set Serveroutput On Size Unlimited format truncated +set echo off + +--Arrange +@@ut_exampletest.pks +@@ut_exampletest.pkb + +PROMPT Does not report error when test teardown procedure name for a test is null +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => 'ut_exampletest' + ,a_test_procedure => 'ut_exampletest' + ,a_teardown_procedure => null); + + simple_test.execute(); + +--Assert + if simple_test.result != ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +PROMPT Reports error when test teardown procedure name for a test is invalid +declare + simple_test ut_test; +begin + +--Act + simple_test := ut_test(a_object_name => 'ut_exampletest' + ,a_test_procedure => 'ut_exampletest' + ,a_teardown_procedure => 'invalid teardown name'); + + simple_test.execute(); + +--Assert + if simple_test.result = ut_utils.tr_error then + dbms_output.put_line(' Success'); + else + dbms_output.put_line(' Failure'); + end if; +end; +/ + +--Cleanup +drop package ut_exampletest; diff --git a/examples/ut_custom_reporter.tpb b/examples/ut_custom_reporter.tpb index 664867649..cf552b111 100644 --- a/examples/ut_custom_reporter.tpb +++ b/examples/ut_custom_reporter.tpb @@ -20,28 +20,35 @@ create or replace type body ut_custom_reporter is (self as ut_dbms_output_suite_reporter).print(tab || msg); end print; - overriding member procedure begin_suite(self in out nocopy ut_custom_reporter, a_suite_name in varchar2) as + overriding member procedure begin_suite(self in out nocopy ut_custom_reporter, a_suite ut_object) as begin - (self as ut_dbms_output_suite_reporter).begin_suite(a_suite_name); + (self as ut_dbms_output_suite_reporter).begin_suite(a_suite); lvl := lvl + 1; end; - overriding member procedure end_suite(self in out nocopy ut_custom_reporter, a_suite_name in varchar2, a_suite_execution_result in ut_execution_result) as + overriding member procedure begin_test(self in out nocopy ut_custom_reporter, a_test ut_object) as begin - lvl := lvl - 1; - (self as ut_dbms_output_suite_reporter).end_suite(a_suite_name,a_suite_execution_result); + (self as ut_dbms_output_suite_reporter).begin_test(a_test); + lvl := lvl + 1; end; + + overriding member procedure on_assert(self in out nocopy ut_custom_reporter, an_assert ut_object) is + begin + lvl := lvl + 1; + (self as ut_dbms_output_suite_reporter).on_assert(an_assert); + lvl := lvl - 1; + end; - overriding member procedure begin_test(self in out nocopy ut_custom_reporter, a_test_name in varchar2, a_test_call_params in ut_test_call_params) as + overriding member procedure end_test(self in out nocopy ut_custom_reporter, a_test ut_object) as begin - (self as ut_dbms_output_suite_reporter).begin_test(a_test_name,a_test_call_params); - lvl := lvl + 1; + lvl := lvl - 1; + (self as ut_dbms_output_suite_reporter).end_test(a_test); end; - overriding member procedure end_test(self in out nocopy ut_custom_reporter, a_test_name in varchar2, a_test_call_params in ut_test_call_params, a_execution_result in ut_execution_result, a_assert_list in ut_assert_list) as + overriding member procedure end_suite(self in out nocopy ut_custom_reporter, a_suite ut_object) as begin lvl := lvl - 1; - (self as ut_dbms_output_suite_reporter).end_test(a_test_name, a_test_call_params, a_execution_result, a_assert_list); + (self as ut_dbms_output_suite_reporter).end_suite(a_suite); end; end; diff --git a/examples/ut_custom_reporter.tps b/examples/ut_custom_reporter.tps index ed78a1cf6..7c078c339 100644 --- a/examples/ut_custom_reporter.tps +++ b/examples/ut_custom_reporter.tps @@ -7,10 +7,11 @@ create or replace type ut_custom_reporter under ut_dbms_output_suite_reporter constructor function ut_custom_reporter(a_tab_size integer default 4) return self as result, member function tab(self in ut_custom_reporter) return varchar2, overriding member procedure print(msg varchar2), - overriding member procedure begin_suite(self in out nocopy ut_custom_reporter, a_suite_name in varchar2), - overriding member procedure end_suite(self in out nocopy ut_custom_reporter, a_suite_name in varchar2, a_suite_execution_result in ut_execution_result), - overriding member procedure begin_test(self in out nocopy ut_custom_reporter, a_test_name in varchar2, a_test_call_params in ut_test_call_params), - overriding member procedure end_test(self in out nocopy ut_custom_reporter, a_test_name in varchar2, a_test_call_params in ut_test_call_params, a_execution_result in ut_execution_result, a_assert_list in ut_assert_list) + 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 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) ) not final / diff --git a/source/install.sql b/source/install.sql index 41e72700c..a6dc56c6a 100644 --- a/source/install.sql +++ b/source/install.sql @@ -1,23 +1,28 @@ -@@types/ut_test_call_params.tps +@@types/ut_object.tps +@@types/ut_objects_list.tps +@@types/ut_composite_object.tps +@@types/ut_executable.tps @@types/ut_assert_result.tps -@@types/ut_assert_list.tps @@ut_metadata.pks @@ut_assert.pks -@@types/ut_execution_result.tps @@types/ut_suite_reporter.tps +@@types/ut_reporters_list.tps +@@types/ut_composite_reporter.tps @@types/ut_test_object.tps -@@types/ut_test_objects_list.tps @@types/ut_test.tps @@types/ut_test_suite.tps @@types/ut_reporter_decorator.tps @@types/ut_dbms_output_suite_reporter.tps @@ut_utils.pks + @@ut_utils.pkb @@types/ut_assert_result.tpb -@@types/ut_execution_result.tpb +@@types/ut_object.tpb +@@types/ut_composite_object.tpb @@types/ut_test.tpb @@types/ut_test_suite.tpb -@@types/ut_test_call_params.tpb +@@types/ut_executable.tpb +@@types/ut_composite_reporter.tpb @@types/ut_reporter_decorator.tpb @@types/ut_dbms_output_suite_reporter.tpb @@ut_metadata.pkb diff --git a/source/types/ut_assert_result.tpb b/source/types/ut_assert_result.tpb index d3455b947..40ffc0441 100644 --- a/source/types/ut_assert_result.tpb +++ b/source/types/ut_assert_result.tpb @@ -1,9 +1,14 @@ create or replace type body ut_assert_result is - - member function result_to_char(self in ut_assert_result) return varchar2 is + + constructor function ut_assert_result(a_result varchar2, a_message varchar2, a_name varchar2 default null) + return self as result is begin - return ut_utils.test_result_to_char(result); - end; - + self.name := a_name; + self.object_type := 0; + self.result := a_result; + self.message := a_message; + return; + end ut_assert_result; + end; / diff --git a/source/types/ut_assert_result.tps b/source/types/ut_assert_result.tps index 85441af8a..1e22e3271 100644 --- a/source/types/ut_assert_result.tps +++ b/source/types/ut_assert_result.tps @@ -1,9 +1,9 @@ -create or replace type ut_assert_result as object +create or replace type ut_assert_result force under ut_object ( - result integer(1), message varchar2(4000 char), - member function result_to_char(self in ut_assert_result) return varchar2 + constructor function ut_assert_result(a_result varchar2, a_message varchar2, a_name varchar2 default null) + return self as result ) not final / diff --git a/source/types/ut_composite_object.tpb b/source/types/ut_composite_object.tpb new file mode 100644 index 000000000..2fe28100e --- /dev/null +++ b/source/types/ut_composite_object.tpb @@ -0,0 +1,13 @@ +create or replace type body ut_composite_object is + member procedure calc_execution_result(self in out nocopy ut_composite_object) is + v_result integer(1) := ut_utils.tr_success; + begin + for i in 1 .. self.items.count loop + v_result := greatest(self.items(i).result, v_result); + exit when v_result = ut_utils.tr_error; + end loop; + self.result := v_result; + end; + +end; +/ diff --git a/source/types/ut_composite_object.tps b/source/types/ut_composite_object.tps new file mode 100644 index 000000000..8f1891df6 --- /dev/null +++ b/source/types/ut_composite_object.tps @@ -0,0 +1,7 @@ +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) +) not final not instantiable +/ diff --git a/source/types/ut_composite_reporter.tpb b/source/types/ut_composite_reporter.tpb new file mode 100644 index 000000000..56b5590b1 --- /dev/null +++ b/source/types/ut_composite_reporter.tpb @@ -0,0 +1,57 @@ +create or replace type body ut_composite_reporter is + + constructor function ut_composite_reporter(the_reporters ut_reporters_list default ut_reporters_list()) + return self as result is + begin + self.name := $$plsql_unit; + return; + end; + + member procedure add_reporter(self in out nocopy ut_composite_reporter, a_reporter ut_suite_reporter) is + begin + self.reporters.extend(1); + self.reporters(self.reporters.last) := a_reporter; + end; + member procedure remove_reporter(self in out nocopy ut_composite_reporter, an_index pls_integer) is + begin + for i in an_index + 1 .. self.reporters.last loop + self.reporters(i - 1) := self.reporters(i); + end loop; + + self.reporters.delete(self.reporters.last); + + end; + + overriding member procedure begin_suite(self in out nocopy ut_composite_reporter, a_suite ut_object) is + begin + for i in 1 .. self.reporters.count loop + self.reporters(i).begin_suite(a_suite => a_suite); + end loop; + end; + overriding member procedure begin_test(self in out nocopy ut_composite_reporter, a_test ut_object) is + begin + for i in 1 .. self.reporters.count loop + self.reporters(i).begin_test(a_test => a_test); + end loop; + end; + overriding member procedure on_assert(self in out nocopy ut_composite_reporter, an_assert ut_object) is + begin + for i in 1 .. self.reporters.count loop + self.reporters(i).on_assert(an_assert => an_assert); + end loop; + end; + overriding member procedure end_test(self in out nocopy ut_composite_reporter, a_test ut_object) is + begin + for i in 1 .. self.reporters.count loop + self.reporters(i).end_test(a_test => a_test); + end loop; + end; + overriding member procedure end_suite(self in out nocopy ut_composite_reporter, a_suite ut_object) is + begin + for i in 1 .. self.reporters.count loop + self.reporters(i).end_suite(a_suite => a_suite); + end loop; + end; + +end; +/ diff --git a/source/types/ut_composite_reporter.tps b/source/types/ut_composite_reporter.tps new file mode 100644 index 000000000..26f34f03a --- /dev/null +++ b/source/types/ut_composite_reporter.tps @@ -0,0 +1,18 @@ +create or replace type ut_composite_reporter under ut_suite_reporter +( + reporters ut_reporters_list, + + constructor function ut_composite_reporter(the_reporters ut_reporters_list default ut_reporters_list()) + return self as result, + member procedure add_reporter(self in out nocopy ut_composite_reporter, a_reporter ut_suite_reporter), + member procedure remove_reporter(self in out nocopy ut_composite_reporter, an_index pls_integer), + + overriding member procedure begin_suite(self in out nocopy ut_composite_reporter, a_suite in ut_object), + overriding member procedure begin_test(self in out nocopy ut_composite_reporter, a_test ut_object), + overriding member procedure on_assert(self in out nocopy ut_composite_reporter, an_assert ut_object), + overriding member procedure end_test(self in out nocopy ut_composite_reporter, a_test ut_object), + overriding member procedure end_suite(self in out nocopy ut_composite_reporter, a_suite ut_object) + +) +not final +/ diff --git a/source/types/ut_dbms_output_suite_reporter.tpb b/source/types/ut_dbms_output_suite_reporter.tpb index 2740f62e1..1728a66bf 100644 --- a/source/types/ut_dbms_output_suite_reporter.tpb +++ b/source/types/ut_dbms_output_suite_reporter.tpb @@ -2,7 +2,7 @@ create or replace type body ut_dbms_output_suite_reporter is static function c_dashed_line return varchar2 is begin - return lpad('-',80,'-'); + return lpad('-', 80, '-'); end; constructor function ut_dbms_output_suite_reporter return self as result is @@ -16,41 +16,46 @@ create or replace type body ut_dbms_output_suite_reporter is dbms_output.put_line(msg); end print; - overriding member procedure begin_suite(self in out nocopy ut_dbms_output_suite_reporter, a_suite_name in varchar2) as + overriding member procedure begin_suite(self in out nocopy ut_dbms_output_suite_reporter, a_suite ut_object) as begin print(ut_dbms_output_suite_reporter.c_dashed_line); - print('suite "' || a_suite_name || '" started.'); + print('suite "' || a_suite.name || '" started.'); end; - overriding member procedure end_suite(self in out nocopy ut_dbms_output_suite_reporter, a_suite_name in varchar2, a_suite_execution_result in ut_execution_result) as + overriding member procedure end_suite(self in out nocopy ut_dbms_output_suite_reporter, a_suite ut_object) as begin --todo: report total suite result here with pretty message print(ut_dbms_output_suite_reporter.c_dashed_line); - print('suite "' || a_suite_name || '" ended.'); + print('suite "' || a_suite.name || '" ended.'); print(ut_dbms_output_suite_reporter.c_dashed_line); end; - overriding member procedure begin_test(self in out nocopy ut_dbms_output_suite_reporter, a_test_name in varchar2, a_test_call_params in ut_test_call_params) as + overriding member procedure on_assert(self in out nocopy ut_dbms_output_suite_reporter, an_assert ut_object) as + begin + --todo: report total suite result here with pretty message + null; + end; + + overriding member procedure begin_test(self in out nocopy ut_dbms_output_suite_reporter, a_test ut_object) as + test ut_test := treat(a_test as ut_test); begin print(ut_dbms_output_suite_reporter.c_dashed_line); - if a_test_name is not null then - print('test ' || a_test_name || ' (' || - ut_metadata.form_name(a_test_call_params.owner_name - ,a_test_call_params.object_name - ,a_test_call_params.test_procedure) || ')'); + if a_test.name is not null then + print('test ' || test.name || ' (' || test.test.form_name || ')'); else - print('test ' || ut_metadata.form_name(a_test_call_params.owner_name - ,a_test_call_params.object_name - ,a_test_call_params.test_procedure)); + print('test ' || test.test.form_name); end if; end; - overriding member procedure end_test(self in out nocopy ut_dbms_output_suite_reporter, a_test_name in varchar2, a_test_call_params in ut_test_call_params, a_execution_result in ut_execution_result, a_assert_list in ut_assert_list) as + overriding member procedure end_test(self in out nocopy ut_dbms_output_suite_reporter, a_test ut_object) as + test ut_test := treat(a_test as ut_test); + assert ut_assert_result; begin - print('result: ' || a_execution_result.result_to_char); + print('result: ' || test.result_to_char); print('asserts'); - for i in a_assert_list.first .. a_assert_list.last loop - print('assert ' || i || ' ' || a_assert_list(i).result_to_char || ' message: ' || a_assert_list(i).message); + for i in test.items.first .. test.items.last loop + assert := treat(test.items(i) as ut_assert_result); + print('assert ' || i || ' ' || assert.result_to_char || ' message: ' || assert.message); end loop; end; diff --git a/source/types/ut_dbms_output_suite_reporter.tps b/source/types/ut_dbms_output_suite_reporter.tps index 23457cef5..1eaa85a8b 100644 --- a/source/types/ut_dbms_output_suite_reporter.tps +++ b/source/types/ut_dbms_output_suite_reporter.tps @@ -1,17 +1,17 @@ create or replace type ut_dbms_output_suite_reporter force under ut_suite_reporter ( + constructor function ut_dbms_output_suite_reporter return self as result, - constructor function ut_dbms_output_suite_reporter - return self as result, + static function c_dashed_line return varchar2, + member procedure print(msg varchar2), - static function c_dashed_line return varchar2, - member procedure print(msg varchar2), - - overriding member procedure begin_suite(self in out nocopy ut_dbms_output_suite_reporter, a_suite_name in varchar2), - overriding member procedure begin_test(self in out nocopy ut_dbms_output_suite_reporter, a_test_name in varchar2, a_test_call_params in ut_test_call_params), - overriding member procedure end_test(self in out nocopy ut_dbms_output_suite_reporter, a_test_name in varchar2, a_test_call_params in ut_test_call_params, a_execution_result in ut_execution_result, a_assert_list in ut_assert_list), - overriding member procedure end_suite(self in out nocopy ut_dbms_output_suite_reporter, a_suite_name in varchar2, a_suite_execution_result in ut_execution_result) + overriding member procedure begin_suite(self in out nocopy ut_dbms_output_suite_reporter, a_suite ut_object), + overriding member procedure begin_test(self in out nocopy ut_dbms_output_suite_reporter, a_test ut_object), + overriding member procedure on_assert(self in out nocopy ut_dbms_output_suite_reporter, an_assert ut_object), + overriding member procedure end_test(self in out nocopy ut_dbms_output_suite_reporter, a_test ut_object), + overriding member procedure end_suite(self in out nocopy ut_dbms_output_suite_reporter, a_suite ut_object) -) not final +) +not final / diff --git a/source/types/ut_executable.tpb b/source/types/ut_executable.tpb new file mode 100644 index 000000000..ca2ff7e9f --- /dev/null +++ b/source/types/ut_executable.tpb @@ -0,0 +1,76 @@ +create or replace type body ut_executable is + + static procedure execute_call(a_owner varchar2, a_object varchar2, a_procedure_name varchar2) is + stmt varchar2(200); + i number; + c number; + + owner varchar2(200) := a_owner; + object_name varchar2(200) := a_object; + procedure_name varchar2(200) := a_procedure_name; + + begin + + ut_metadata.do_resolve(the_owner => owner, the_object => object_name, a_procedure_name => procedure_name); + + stmt := 'begin ' || ut_metadata.form_name(owner, object_name, procedure_name) || '; end;'; + + $if $$ut_trace $then + dbms_output.put_line('ut_executable.execute_call stmt:' || stmt); + $end + + i := dbms_sql.open_cursor; + dbms_sql.parse(c => i, statement => stmt, language_flag => dbms_sql.native); + c := dbms_sql.execute(i); + dbms_sql.close_cursor(i); + exception + when others then + if i is not null and dbms_sql.is_open(i) then + dbms_sql.close_cursor(i); + end if; + raise; + end; + + member function is_valid(a_proc_type varchar2) return boolean is + a_result boolean := true; + begin + + if self.object_name is null then + a_result := false; + ut_assert.report_error('Call params for ' || a_proc_type || ' are not valid: package is not defined'); + end if; + + if self.procedure_name is null then + a_result := false; + ut_assert.report_error('Call params for ' || a_proc_type || ' are not valid: procedure is not defined'); + end if; + + if a_result and not ut_metadata.package_valid(self.owner_name, self.object_name) then + a_result := false; + ut_assert.report_error('Call params for ' || a_proc_type || + ' are not valid: package does not exist or is invalid: ' || + nvl(self.object_name, '')); + end if; + + if a_result and not ut_metadata.procedure_exists(self.owner_name, self.object_name, self.procedure_name) then + a_result := false; + ut_assert.report_error('Call params for ' || a_proc_type || ' are not valid: package missing ' || a_proc_type || + ' procedure ' || self.object_name || '.' || + nvl(self.procedure_name, '')); + end if; + + return a_result; + end is_valid; + + member function form_name return varchar2 is + begin + return ut_metadata.form_name(owner_name, object_name, procedure_name); + end; + + member procedure execute(self in ut_executable) is + begin + ut_executable.execute_call(self.owner_name, self.object_name, self.procedure_name); + end execute; + +end; +/ diff --git a/source/types/ut_executable.tps b/source/types/ut_executable.tps new file mode 100644 index 000000000..9388464e5 --- /dev/null +++ b/source/types/ut_executable.tps @@ -0,0 +1,12 @@ +create or replace type ut_executable force as object +( + owner_name varchar2(32 char), + object_name varchar2(32 char), + procedure_name varchar2(32 char), + + static procedure execute_call(a_owner varchar2, a_object varchar2, a_procedure_name varchar2), + member function is_valid(a_proc_type varchar2) return boolean, + member function form_name return varchar2, + member procedure execute(self in ut_executable) +) final +/ diff --git a/source/types/ut_execution_result.tpb b/source/types/ut_execution_result.tpb deleted file mode 100644 index cc40b0981..000000000 --- a/source/types/ut_execution_result.tpb +++ /dev/null @@ -1,17 +0,0 @@ -create or replace type body ut_execution_result is - - constructor function ut_execution_result(a_start_time timestamp with time zone default current_timestamp) - return self as result is - begin - self.start_time := a_start_time; - self.result := ut_utils.tr_success; - return; - end ut_execution_result; - - member function result_to_char(self in ut_execution_result) return varchar2 is - begin - return ut_utils.test_result_to_char(self.result); - end result_to_char; - -end; -/ diff --git a/source/types/ut_execution_result.tps b/source/types/ut_execution_result.tps deleted file mode 100644 index 6e1bad6bf..000000000 --- a/source/types/ut_execution_result.tps +++ /dev/null @@ -1,12 +0,0 @@ -create or replace type ut_execution_result as object -( - - start_time timestamp with time zone, - end_time timestamp with time zone, - result integer(1), - - constructor function ut_execution_result(a_start_time timestamp with time zone default current_timestamp) return self as result, - member function result_to_char(self in ut_execution_result) return varchar2 -) -not final -/ diff --git a/source/types/ut_object.tpb b/source/types/ut_object.tpb new file mode 100644 index 000000000..c254ee753 --- /dev/null +++ b/source/types/ut_object.tpb @@ -0,0 +1,9 @@ +create or replace type body ut_object is + + member function result_to_char return varchar2 is + begin + return ut_utils.test_result_to_char(self.result); + end; + +end; +/ diff --git a/source/types/ut_object.tps b/source/types/ut_object.tps new file mode 100644 index 000000000..44aee60ac --- /dev/null +++ b/source/types/ut_object.tps @@ -0,0 +1,10 @@ +create or replace type ut_object as object +( + name varchar2(250 char), + --execution_result ut_execution_result, + result integer(1), + object_type integer(1), --0 - assert, 1 -- test, 2 -- suite + + member function result_to_char return varchar2 +) not final not instantiable +/ diff --git a/source/types/ut_objects_list.tps b/source/types/ut_objects_list.tps new file mode 100644 index 000000000..f814dff2f --- /dev/null +++ b/source/types/ut_objects_list.tps @@ -0,0 +1,2 @@ +create or replace type ut_objects_list is table of ut_object; +/ diff --git a/source/types/ut_reporter_decorator.tps b/source/types/ut_reporter_decorator.tps index b4eb4d722..72efdec38 100644 --- a/source/types/ut_reporter_decorator.tps +++ b/source/types/ut_reporter_decorator.tps @@ -1,15 +1,9 @@ create or replace type ut_reporter_decorator under ut_suite_reporter ( - -- Author : PAZZZ - -- Created : 20.07.2016 23:31:07 - -- Purpose : - - -- Attributes decorated_reporter ut_suite_reporter, - -- Member functions and procedures constructor function ut_reporter_decorator(a_decorated_reporter ut_suite_reporter) return self as result, - member procedure init(self in out nocopy ut_reporter_decorator, a_decorated_reporter ut_suite_reporter) + member procedure init(self in out nocopy ut_reporter_decorator, a_decorated_reporter ut_suite_reporter) ) not final not instantiable / diff --git a/source/types/ut_reporters_list.tps b/source/types/ut_reporters_list.tps new file mode 100644 index 000000000..05b34cfd1 --- /dev/null +++ b/source/types/ut_reporters_list.tps @@ -0,0 +1,2 @@ +create or replace type ut_reporters_list as table of ut_suite_reporter; +/ diff --git a/source/types/ut_suite_reporter.tps b/source/types/ut_suite_reporter.tps index 2277aa409..d23730886 100644 --- a/source/types/ut_suite_reporter.tps +++ b/source/types/ut_suite_reporter.tps @@ -2,10 +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_name in varchar2), - not instantiable member procedure begin_test(self in out nocopy ut_suite_reporter, a_test_name in varchar2, a_test_call_params in ut_test_call_params), - not instantiable member procedure end_test(self in out nocopy ut_suite_reporter, a_test_name in varchar2, a_test_call_params in ut_test_call_params, a_execution_result in ut_execution_result, a_assert_list in ut_assert_list), - not instantiable member procedure end_suite(self in out nocopy ut_suite_reporter, a_suite_name in varchar2, a_suite_execution_result in ut_execution_result) + 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, an_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) ) not instantiable not final diff --git a/source/types/ut_test.tpb b/source/types/ut_test.tpb index 9e5df6827..f61f0deb2 100644 --- a/source/types/ut_test.tpb +++ b/source/types/ut_test.tpb @@ -4,43 +4,44 @@ create or replace type body ut_test is return self as result is begin self.name := a_test_name; - self.call_params := ut_test_call_params(object_name => trim(a_object_name) - ,test_procedure => trim(a_test_procedure) - ,owner_name => trim(a_owner_name) - ,setup_procedure => trim(a_setup_procedure) - ,teardown_procedure => trim(a_teardown_procedure)); + self.object_type := 1; + self.test := ut_executable(object_name => trim(a_object_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)); + 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)); + end if; return; end ut_test; member function is_valid(self in ut_test) return boolean is + v_is_valid boolean; begin - if call_params.test_procedure is null then - return false; - end if; - - if not ut_metadata.resolvable(call_params.owner_name, call_params.object_name, call_params.test_procedure) then - return false; - end if; - - if call_params.setup_procedure is not null and - not ut_metadata.resolvable(call_params.owner_name, call_params.object_name, call_params.setup_procedure) then - return false; - end if; + v_is_valid := test.is_valid('test') and (setup is null or setup.is_valid('setup')) and + (teardown is null or teardown.is_valid('teardown')); - if call_params.teardown_procedure is not null and - not ut_metadata.resolvable(call_params.owner_name, call_params.object_name, call_params.teardown_procedure) then - return false; - end if; - - return true; + return v_is_valid; end is_valid; overriding member procedure execute(self in out nocopy ut_test, a_reporter ut_suite_reporter) is - params_valid boolean; + reporter ut_suite_reporter := a_reporter; + begin + reporter := execute(reporter); + end; + overriding member function execute(self in out nocopy ut_test, a_reporter ut_suite_reporter) return ut_suite_reporter is reporter ut_suite_reporter := a_reporter; begin if reporter is not null then - reporter.begin_test(a_test_name => self.name, a_test_call_params => self.call_params); + reporter.begin_test(self); end if; begin @@ -48,14 +49,15 @@ create or replace type body ut_test is dbms_output.put_line('ut_test.execute'); $end - self.execution_result := ut_execution_result(); + self.start_time := current_timestamp; - self.call_params.validate_params(params_valid); - - if params_valid then - self.call_params.setup; + if self.is_valid() then + if self.setup is not null then + self.setup.execute; + end if; + begin - self.call_params.run_test; + self.test.execute; exception when others then -- dbms_utility.format_error_backtrace is 10g or later @@ -67,12 +69,15 @@ create or replace type body ut_test is $end ut_assert.report_error(sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_backtrace); end; - self.call_params.teardown; + + if self.teardown is not null then + self.teardown.execute; + end if; end if; - self.execution_result.end_time := current_timestamp; + self.end_time := current_timestamp; - ut_assert.process_asserts(self.assert_results, self.execution_result.result); + ut_assert.process_asserts(self.items); exception when others then @@ -87,20 +92,24 @@ create or replace type body ut_test is -- most likely occured in setup or teardown if here. ut_assert.report_error(sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_stack); ut_assert.report_error(sqlerrm(sqlcode) || ' ' || dbms_utility.format_error_backtrace); - self.execution_result.end_time := current_timestamp; - ut_assert.process_asserts(self.assert_results, self.execution_result.result); + self.end_time := current_timestamp; + ut_assert.process_asserts(self.items); end; + self.calc_execution_result; + if reporter is not null then - reporter.end_test(a_test_name => self.name - ,a_test_call_params => self.call_params - ,a_execution_result => self.execution_result - ,a_assert_list => self.assert_results); + for i in 1 .. self.items.count loop + reporter.on_assert(treat(self.items(i) as ut_assert_result)); + end loop; + reporter.end_test(self); end if; + + return reporter; end; overriding member procedure execute(self in out nocopy ut_test) is - v_null_reporter ut_suite_reporter; + v_null_reporter ut_suite_reporter; begin self.execute(v_null_reporter); end execute; diff --git a/source/types/ut_test.tps b/source/types/ut_test.tps index 42013620e..5cad074f9 100644 --- a/source/types/ut_test.tps +++ b/source/types/ut_test.tps @@ -1,15 +1,8 @@ create or replace type ut_test force under ut_test_object ( - - /* - object_name varchar2(32 char), - test_procedure varchar2(32 char), - owner_name varchar2(32 char), - setup_procedure varchar2(32 char), - teardown_procedure varchar2(32 char), - */ - call_params ut_test_call_params, - assert_results ut_assert_list, + 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, @@ -17,6 +10,7 @@ create or replace type ut_test force under ut_test_object member function is_valid(self in ut_test) 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, overriding member procedure execute(self in out nocopy ut_test) ) diff --git a/source/types/ut_test_call_params.tpb b/source/types/ut_test_call_params.tpb deleted file mode 100644 index f465db854..000000000 --- a/source/types/ut_test_call_params.tpb +++ /dev/null @@ -1,122 +0,0 @@ -create or replace type body ut_test_call_params is - - static procedure execute_call(a_owner varchar2, a_object varchar2, a_procedure_name varchar2) is - stmt varchar2(200); - i number; - c number; - - owner varchar2(200) := a_owner; - object_name varchar2(200) := a_object; - procedure_name varchar2(200) := a_procedure_name; - - begin - - ut_metadata.do_resolve(the_owner => owner, the_object => object_name, a_procedure_name => procedure_name); - - stmt := 'begin ' || ut_metadata.form_name(owner, object_name, procedure_name) || '; end;'; - - $if $$ut_trace $then - dbms_output.put_line('ut_test_call_params.execute_call stmt:' || stmt); - $end - - i := dbms_sql.open_cursor; - dbms_sql.parse(c => i, statement => stmt, language_flag => dbms_sql.native); - c := dbms_sql.execute(i); - dbms_sql.close_cursor(i); - exception - when others then - if i is not null and dbms_sql.is_open(i) then - dbms_sql.close_cursor(i); - end if; - raise; - end; - - /* - member function is_valid(self in ut_test_call_params) return boolean is - begin - if self.test_procedure is null then - return false; - end if; - - if not ut_metadata.do_resolve(self.owner_name, self.object_name, self.test_procedure) then - return false; - end if; - - if self.setup_procedure is not null and - not ut_metadata.do_resolve(self.owner_name, self.object_name, self.setup_procedure) then - return false; - end if; - - if self.teardown_procedure is not null and - not ut_metadata.do_resolve(self.owner_name, self.object_name, self.teardown_procedure) then - return false; - end if; - - return true; - end is_valid; - */ - - member procedure validate_params(self in ut_test_call_params, a_result out boolean) is - begin - a_result := true; - - if self.object_name is null then - a_result := false; - ut_assert.report_error('Test is not invalid: test package is not defined'); - end if; - - if self.test_procedure is null then - a_result := false; - ut_assert.report_error('Test is not invalid: test procedure is not defined'); - end if; - - if a_result and not ut_metadata.package_valid(self.owner_name, self.object_name) then - a_result := false; - ut_assert.report_error('package does not exist or is invalid: ' || - nvl(self.object_name, '')); - end if; - - if a_result then - if not ut_metadata.procedure_exists(self.owner_name, self.object_name, self.test_procedure) then - ut_assert.report_error('package missing test method ' || self.object_name || '.' || - nvl(self.test_procedure, '')); - end if; - - if self.setup_procedure is not null and - not ut_metadata.procedure_exists(self.owner_name, self.object_name, self.setup_procedure) then - ut_assert.report_error('package missing setup method ' || self.object_name || '.' || - nvl(self.setup_procedure, '')); - end if; - - if self.teardown_procedure is not null and - not ut_metadata.procedure_exists(self.owner_name, self.object_name, self.teardown_procedure) then - ut_assert.report_error('package missing teardown method ' || self.object_name || '.' || - nvl(self.teardown_procedure, '')); - end if; - end if; - - end validate_params; - - member procedure setup(self in ut_test_call_params) is - begin - if self.setup_procedure is not null and self.object_name is not null then - ut_test_call_params.execute_call(self.owner_name, self.object_name, self.setup_procedure); - end if; - end setup; - - member procedure run_test(self in ut_test_call_params) is - begin - if self.test_procedure is not null and self.object_name is not null then - ut_test_call_params.execute_call(self.owner_name, self.object_name, self.test_procedure); - end if; - end; - - member procedure teardown(self in ut_test_call_params) is - begin - if self.teardown_procedure is not null and self.object_name is not null then - ut_test_call_params.execute_call(self.owner_name, self.object_name, self.teardown_procedure); - end if; - end; - -end; -/ diff --git a/source/types/ut_test_call_params.tps b/source/types/ut_test_call_params.tps deleted file mode 100644 index 5722b16f3..000000000 --- a/source/types/ut_test_call_params.tps +++ /dev/null @@ -1,16 +0,0 @@ -create or replace type ut_test_call_params force as object -( - object_name varchar2(32 char), - test_procedure varchar2(32 char), - owner_name varchar2(32 char), - setup_procedure varchar2(32 char), - teardown_procedure varchar2(32 char), - - static procedure execute_call(a_owner varchar2, a_object varchar2, a_procedure_name varchar2), - --member function is_valid(self in ut_test_call_params) return boolean, - member procedure validate_params(self in ut_test_call_params, a_result out boolean), - member procedure setup(self in ut_test_call_params), - member procedure run_test(self in ut_test_call_params), - member procedure teardown(self in ut_test_call_params) -) final -/ diff --git a/source/types/ut_test_object.tps b/source/types/ut_test_object.tps index 70d4730e5..047797f6a 100644 --- a/source/types/ut_test_object.tps +++ b/source/types/ut_test_object.tps @@ -1,14 +1,10 @@ -create or replace type ut_test_object force as object +create or replace type ut_test_object force under ut_composite_object ( - name varchar2(250 char), - execution_result ut_execution_result, - - --not instantiable member procedure run(self in out ut_test_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) - --not instantiable member procedure execute(self in out nocopy ut_test_object, a_reporters in ut_suite_reporters), - --not instantiable member procedure execute(self in out nocopy ut_test_object, a_reporter in ut_abstract_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_objects_list.tps b/source/types/ut_test_objects_list.tps deleted file mode 100644 index ce23de622..000000000 --- a/source/types/ut_test_objects_list.tps +++ /dev/null @@ -1,2 +0,0 @@ -create or replace type ut_test_objects_list is table of ut_test_object; -/ diff --git a/source/types/ut_test_suite.tpb b/source/types/ut_test_suite.tpb index 86beb1abf..061a7cf36 100644 --- a/source/types/ut_test_suite.tpb +++ b/source/types/ut_test_suite.tpb @@ -1,9 +1,10 @@ create or replace type body ut_test_suite is - constructor function ut_test_suite(a_suite_name varchar2, a_items ut_test_objects_list default ut_test_objects_list()) + constructor function ut_test_suite(a_suite_name varchar2, 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; return; end ut_test_suite; @@ -16,37 +17,38 @@ create or replace type body ut_test_suite is overriding member procedure execute(self in out nocopy ut_test_suite, a_reporter ut_suite_reporter) is reporter ut_suite_reporter := a_reporter; + begin + reporter := execute(reporter); + end; + + overriding member function execute(self in out nocopy ut_test_suite, a_reporter ut_suite_reporter) return ut_suite_reporter is + reporter ut_suite_reporter := a_reporter; + test_object ut_test_object; begin if reporter is not null then - reporter.begin_suite(self.name); + reporter.begin_suite(self); end if; $if $$ut_trace $then dbms_output.put_line('ut_test_suite.execute'); $end - self.execution_result := ut_execution_result; + self.start_time := current_timestamp; for i in self.items.first .. self.items.last loop - self.items(i).execute(a_reporter => reporter); + test_object := treat(self.items(i) as ut_test_object); + reporter := test_object.execute(a_reporter => reporter); + self.items(i) := test_object; end loop; - self.execution_result.end_time := current_timestamp; - - for i in self.items.first .. self.items.last loop - if (self.execution_result.result = ut_utils.tr_success and self.items(i) - .execution_result.result in (ut_utils.tr_failure, ut_utils.tr_error)) or - (self.execution_result.result = ut_utils.tr_failure and self.items(i) - .execution_result.result = ut_utils.tr_error) then - self.execution_result.result := self.items(i).execution_result.result; - end if; - - exit when self.execution_result.result = ut_utils.tr_error; - end loop; + self.end_time := current_timestamp; + + self.calc_execution_result; if reporter is not null then - reporter.end_suite(self.name, self.execution_result); + reporter.end_suite(self); end if; + return reporter; end; overriding member procedure execute(self in out nocopy ut_test_suite) is diff --git a/source/types/ut_test_suite.tps b/source/types/ut_test_suite.tps index f6c8e3841..2125aac3a 100644 --- a/source/types/ut_test_suite.tps +++ b/source/types/ut_test_suite.tps @@ -1,12 +1,11 @@ create or replace type ut_test_suite force under ut_test_object ( - items ut_test_objects_list, - constructor function ut_test_suite(a_suite_name varchar2, a_items ut_test_objects_list default ut_test_objects_list()) return self as result, + 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), - --overriding member procedure run(self in out nocopy ut_test_suite), 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 procedure execute(self in out nocopy ut_test_suite) ) not final diff --git a/source/uninstall.sql b/source/uninstall.sql index f7dd0cbad..03d6bc4da 100644 --- a/source/uninstall.sql +++ b/source/uninstall.sql @@ -10,18 +10,22 @@ drop type ut_reporter_decorator; drop type ut_test_suite; -drop type ut_test_objects_list; - drop type ut_test; drop type ut_test_object; -drop type ut_suite_reporter force; +drop type ut_composite_reporter; -drop type ut_execution_result; +drop type ut_reporters_list; -drop type ut_assert_list; +drop type ut_suite_reporter force; drop type ut_assert_result; -drop type ut_test_call_params; +drop type ut_executable; + +drop type ut_composite_object; + +drop type ut_objects_list; + +drop type ut_object; diff --git a/source/ut_assert.pkb b/source/ut_assert.pkb index b4670bbc0..bcc85c359 100644 --- a/source/ut_assert.pkb +++ b/source/ut_assert.pkb @@ -1,6 +1,6 @@ create or replace package body ut_assert is - current_asserts_called ut_assert_list := ut_assert_list(); + current_asserts_called ut_objects_list := ut_objects_list(); function current_assert_test_result return integer is begin @@ -11,8 +11,9 @@ create or replace package body ut_assert is return get_assert_list_final_result(current_asserts_called); end; - function get_assert_list_final_result(a_assert_list in ut_assert_list) return integer is + function get_assert_list_final_result(a_assert_list in ut_objects_list) return integer is v_result integer; + assert ut_assert_result; begin $if $$ut_trace $then dbms_output.put_line('ut_assert.get_assert_list_final_result'); @@ -22,11 +23,12 @@ create or replace package body ut_assert is v_result := ut_utils.tr_success; for i in a_assert_list.first .. a_assert_list.last loop - if a_assert_list(i).result = ut_utils.tr_failure then + assert := treat(a_assert_list(i) as ut_assert_result); + if assert.result = ut_utils.tr_failure then v_result := ut_utils.tr_failure; end if; - if a_assert_list(i).result = ut_utils.tr_error then + if assert.result = ut_utils.tr_error then v_result := ut_utils.tr_error; exit; end if; @@ -45,13 +47,13 @@ create or replace package body ut_assert is current_asserts_called.delete; end; - procedure process_asserts(newtable out ut_assert_list, result out integer) is + procedure process_asserts(newtable out ut_objects_list) is begin $if $$ut_trace $then dbms_output.put_line('ut_assert.copy_called_asserts'); $end - newtable := ut_assert_list(); -- make sure new table is empty + newtable := ut_objects_list(); -- make sure new table is empty newtable.extend(current_asserts_called.last); for i in current_asserts_called.first .. current_asserts_called.last loop $if $$ut_trace $then @@ -65,8 +67,6 @@ create or replace package body ut_assert is $end end loop; - result := get_assert_list_final_result(newtable); - clear_asserts; end process_asserts; diff --git a/source/ut_assert.pks b/source/ut_assert.pks index 870b06574..9f6814ff2 100644 --- a/source/ut_assert.pks +++ b/source/ut_assert.pks @@ -1,10 +1,10 @@ create or replace package ut_assert authid current_user as - function get_assert_list_final_result(a_assert_list in ut_assert_list) return integer; + function get_assert_list_final_result(a_assert_list in ut_objects_list) return integer; function current_assert_test_result return integer; procedure clear_asserts; procedure report_error(message in varchar2); - procedure process_asserts(newtable out ut_assert_list, result out integer); + procedure process_asserts(newtable out ut_objects_list); /* Just need something to play with for now */ procedure are_equal(expected in number, actual in number); diff --git a/source/ut_metadata.pkb b/source/ut_metadata.pkb index ed9be8bca..7a24066b3 100644 --- a/source/ut_metadata.pkb +++ b/source/ut_metadata.pkb @@ -36,7 +36,7 @@ create or replace package body ut_metadata as end form_name; function package_valid(a_owner_name varchar2, a_package_name in varchar2) return boolean as - v_cnt number; + v_prc number; name varchar2(200); schema varchar2(200); part1 varchar2(200); @@ -51,16 +51,18 @@ create or replace package body ut_metadata as do_resolve(schema, part1, part2); - select count(*) - into v_cnt + select count(decode(status, 'VALID', 1, null)) / count(*) + into v_prc from all_objects where owner = schema and object_name = part1 - and object_type in ('PACKAGE', 'PACKAGE BODY') - and status = 'VALID'; + and object_type in ('PACKAGE', 'PACKAGE BODY'); -- expect both package and body to be valid - return v_cnt = 2; + return v_prc = 1; + exception + when others then + return false; end; function procedure_exists(a_owner_name varchar2, a_package_name in varchar2, a_procedure_name in varchar2) @@ -90,6 +92,9 @@ create or replace package body ut_metadata as --expect one method only for the package with that name. return v_cnt = 1; + exception + when others then + return false; end; function resolvable(the_owner in varchar2, the_object in varchar2, a_procedurename in varchar2) return boolean is diff --git a/source/ut_utils.pkb b/source/ut_utils.pkb index cf2926bb5..c64596e07 100644 --- a/source/ut_utils.pkb +++ b/source/ut_utils.pkb @@ -1,20 +1,13 @@ create or replace package body ut_utils is function test_result_to_char(a_test_result integer) return varchar2 as - v_result varchar2(250); begin - - v_result := case a_test_result - when tr_success then - 'Success' - when tr_failure then - 'Failure' - when tr_error then - 'Error' - else - 'Unknown(' || a_test_result || ')' + return case a_test_result + when tr_success then tr_success_char + when tr_failure then tr_failure_char + when tr_error then tr_error_char + else 'Unknown(' || coalesce(to_char(a_test_result),'NULL') || ')' end; - return v_result; end test_result_to_char; end ut_utils; diff --git a/source/ut_utils.pks b/source/ut_utils.pks index e69f9609c..05ad26617 100644 --- a/source/ut_utils.pks +++ b/source/ut_utils.pks @@ -15,6 +15,9 @@ create or replace package ut_utils is tr_failure constant number(1) := 2; -- one or more asserts failed tr_error constant number(1) := 3; -- exception was raised + tr_success_char constant varchar2(7) := 'Success'; -- test passed + tr_failure_char constant varchar2(7) := 'Failure'; -- one or more asserts failed + tr_error_char constant varchar2(5) := 'Error'; -- exception was raised /* Function: test_result_to_char returns a string representation of a test_result.