@@ -919,5 +919,150 @@ procedure test_windows_newline_lines
919919 ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
920920 end;
921921
922+ procedure test_multiline_proc_header_lines is
923+ l_source dbms_preprocessor.source_lines_t;
924+ l_actual ut3_develop.ut_annotations;
925+ l_expected ut3_develop.ut_annotations;
926+ begin
927+ --Arrange
928+ -- procedure header spans multiple lines before terminating ;
929+ l_source := make_source(ut_varchar2_list(
930+ 'PACKAGE test_tt AS' || chr(10),
931+ ' -- %suite' || chr(10),
932+ '' || chr(10),
933+ ' --%test' || chr(10),
934+ ' procedure foo(' || chr(10),
935+ ' a_param1 varchar2' || chr(10),
936+ ' ,a_param2 number default null' || chr(10),
937+ ' );' || chr(10),
938+ ' END;' || chr(10)
939+ ));
940+
941+ --Act
942+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
943+
944+ --Assert
945+ l_expected := ut3_develop.ut_annotations(
946+ ut3_develop.ut_annotation( 2, 'suite', null, null ),
947+ ut3_develop.ut_annotation( 4, 'test', null, 'foo' )
948+ );
949+
950+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
951+ end;
952+
953+ procedure test_non_comment_line_resets_block_lines is
954+ l_source dbms_preprocessor.source_lines_t;
955+ l_actual ut3_develop.ut_annotations;
956+ l_expected ut3_develop.ut_annotations;
957+ begin
958+ --Arrange
959+ -- a non-comment non-proc line between annotation and procedure breaks the association
960+ -- %test becomes a floating top-level annotation with no subobject
961+ l_source := make_source(ut_varchar2_list(
962+ 'PACKAGE test_tt AS' || chr(10),
963+ ' -- %suite' || chr(10),
964+ '' || chr(10),
965+ ' --%test' || chr(10),
966+ ' pragma serially_reusable;' || chr(10), -- resets accumulator
967+ ' procedure foo;' || chr(10),
968+ ' END;' || chr(10)
969+ ));
970+
971+ --Act
972+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
973+
974+ --Assert
975+ -- %test is NOT associated with foo — accumulator was reset by pragma line
976+ -- it surfaces as a top-level annotation with no subobject_name
977+ l_expected := ut3_develop.ut_annotations(
978+ ut3_develop.ut_annotation( 2, 'suite', null, null ),
979+ ut3_develop.ut_annotation( 4, 'test', null, null )
980+ );
981+
982+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
983+ end;
984+
985+ procedure test_annotation_not_at_line_start_ignored_lines is
986+ l_source dbms_preprocessor.source_lines_t;
987+ l_actual ut3_develop.ut_annotations;
988+ l_expected ut3_develop.ut_annotations;
989+ begin
990+ --Arrange
991+ -- % appears in line but comment is not at start of line — should be ignored
992+ l_source := make_source(ut_varchar2_list(
993+ 'PACKAGE test_tt AS' || chr(10),
994+ ' -- %suite' || chr(10),
995+ ' x := ''value%with%percent'';' || chr(10), -- % present but -- not at line start
996+ ' procedure foo;' || chr(10),
997+ ' END;' || chr(10)
998+ ));
999+
1000+ --Act
1001+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
1002+
1003+ --Assert
1004+ l_expected := ut3_develop.ut_annotations(
1005+ ut3_develop.ut_annotation( 2, 'suite', null, null )
1006+ );
1007+
1008+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
1009+ end;
1010+
1011+ procedure test_space_between_dashes_and_qualifier_lines is
1012+ l_source dbms_preprocessor.source_lines_t;
1013+ l_actual ut3_develop.ut_annotations;
1014+ l_expected ut3_develop.ut_annotations;
1015+ begin
1016+ --Arrange
1017+ -- spaces between -- and % are skipped and annotation is still recognised
1018+ -- annotations are not adjacent to a procedure so they are top-level
1019+ l_source := make_source(ut_varchar2_list(
1020+ 'PACKAGE test_tt AS' || chr(10),
1021+ ' -- %suite' || chr(10), -- multiple spaces between -- and %
1022+ ' -- %displayname(my suite)' || chr(10),
1023+ '' || chr(10), -- blank line breaks association with foo
1024+ ' procedure foo;' || chr(10),
1025+ ' END;' || chr(10)
1026+ ));
1027+
1028+ --Act
1029+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
1030+
1031+ --Assert
1032+ l_expected := ut3_develop.ut_annotations(
1033+ ut3_develop.ut_annotation( 2, 'suite', null, null ),
1034+ ut3_develop.ut_annotation( 3, 'displayname', 'my suite', null )
1035+ );
1036+
1037+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
1038+ end;
1039+
1040+ procedure test_percent_not_after_dashes_ignored_lines is
1041+ l_source dbms_preprocessor.source_lines_t;
1042+ l_actual ut3_develop.ut_annotations;
1043+ l_expected ut3_develop.ut_annotations;
1044+ begin
1045+ --Arrange
1046+ -- -- present and % present on line but % is not immediately after --
1047+ -- e.g. a regular comment that happens to mention 100%
1048+ l_source := make_source(ut_varchar2_list(
1049+ 'PACKAGE test_tt AS' || chr(10),
1050+ ' -- %suite' || chr(10),
1051+ ' -- coverage is 100% on this module' || chr(10), -- % after text, not annotation
1052+ ' procedure foo;' || chr(10),
1053+ ' END;' || chr(10)
1054+ ));
1055+
1056+ --Act
1057+ l_actual := ut3_develop.ut_annotation_parser.parse_object_annotations(l_source, 'PACKAGE');
1058+
1059+ --Assert
1060+ l_expected := ut3_develop.ut_annotations(
1061+ ut3_develop.ut_annotation( 2, 'suite', null, null )
1062+ );
1063+
1064+ ut.expect(anydata.convertCollection(l_actual)).to_equal(anydata.convertCollection(l_expected));
1065+ end;
1066+
9221067end test_annotation_parser;
9231068/
0 commit comments