Fix coverage with several contract classes; table annotation and file path checks; clean task dir on write

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aUaQeLnwbb1zTpN7kHeat
This commit is contained in:
Kral
2026-10-03 08:44:35 +02:00
parent fb576b0954
commit 03ab36149e
388 changed files with 28620 additions and 339 deletions

View File

@@ -0,0 +1,93 @@
CLASS {{p}}departure_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_stop TYPE c LENGTH 4.
TYPES ty_line TYPE c LENGTH 6.
TYPES ty_depot TYPE c LENGTH 4.
TYPES ty_time TYPE t.
TYPES:
BEGIN OF ty_departure,
stop TYPE ty_stop,
line TYPE ty_line,
depart TYPE ty_time,
depot TYPE ty_depot,
END OF ty_departure,
tt_departures TYPE STANDARD TABLE OF ty_departure WITH EMPTY KEY.
METHODS constructor.
METHODS add_depot
IMPORTING iv_depot TYPE ty_depot
it_departures TYPE tt_departures.
METHODS next_departure
IMPORTING iv_stop TYPE ty_stop
iv_from TYPE ty_time
RETURNING VALUE(rs_departure) TYPE ty_departure.
METHODS departures_at_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rt_departures) TYPE tt_departures.
METHODS count
RETURNING VALUE(rv_count) TYPE i.
PRIVATE SECTION.
TYPES tt_store TYPE SORTED TABLE OF ty_departure
WITH UNIQUE KEY stop depart line.
DATA mt_store TYPE tt_store.
METHODS first_index_of_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rv_index) TYPE i.
ENDCLASS.
CLASS {{p}}departure_planner IMPLEMENTATION.
METHOD constructor.
CLEAR mt_store.
ENDMETHOD.
METHOD add_depot.
LOOP AT it_departures INTO DATA(ls_departure).
DATA(ls_store) = ls_departure.
ls_store-depot = iv_depot.
INSERT ls_store INTO TABLE mt_store.
ENDLOOP.
ENDMETHOD.
METHOD next_departure.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start <> 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop <> iv_stop.
EXIT.
ENDIF.
IF ls_departure-depart >= iv_from.
rs_departure = ls_departure.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD departures_at_stop.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start = 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop <> iv_stop.
EXIT.
ENDIF.
APPEND ls_departure TO rt_departures.
ENDLOOP.
ENDMETHOD.
METHOD count.
rv_count = lines( mt_store ).
ENDMETHOD.
METHOD first_index_of_stop.
READ TABLE mt_store TRANSPORTING NO FIELDS WITH KEY stop = iv_stop.
IF sy-subrc = 0.
rv_index = sy-tabix.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,93 @@
CLASS {{p}}departure_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_stop TYPE c LENGTH 4.
TYPES ty_line TYPE c LENGTH 6.
TYPES ty_depot TYPE c LENGTH 4.
TYPES ty_time TYPE t.
TYPES:
BEGIN OF ty_departure,
stop TYPE ty_stop,
line TYPE ty_line,
depart TYPE ty_time,
depot TYPE ty_depot,
END OF ty_departure,
tt_departures TYPE STANDARD TABLE OF ty_departure WITH EMPTY KEY.
METHODS constructor.
METHODS add_depot
IMPORTING iv_depot TYPE ty_depot
it_departures TYPE tt_departures.
METHODS next_departure
IMPORTING iv_stop TYPE ty_stop
iv_from TYPE ty_time
RETURNING VALUE(rs_departure) TYPE ty_departure.
METHODS departures_at_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rt_departures) TYPE tt_departures.
METHODS count
RETURNING VALUE(rv_count) TYPE i.
PRIVATE SECTION.
TYPES tt_store TYPE SORTED TABLE OF ty_departure
WITH UNIQUE KEY stop depart line.
DATA mt_store TYPE tt_store.
METHODS first_index_of_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rv_index) TYPE i.
ENDCLASS.
CLASS {{p}}departure_planner IMPLEMENTATION.
METHOD constructor.
CLEAR mt_store.
ENDMETHOD.
METHOD add_depot.
LOOP AT it_departures INTO DATA(ls_departure).
DATA(ls_store) = ls_departure.
ls_store-depot = iv_depot.
INSERT ls_store INTO TABLE mt_store.
ENDLOOP.
ENDMETHOD.
METHOD next_departure.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start = 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop = iv_stop.
EXIT.
ENDIF.
IF ls_departure-depart >= iv_from.
rs_departure = ls_departure.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD departures_at_stop.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start = 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop <> iv_stop.
EXIT.
ENDIF.
APPEND ls_departure TO rt_departures.
ENDLOOP.
ENDMETHOD.
METHOD count.
rv_count = lines( mt_store ).
ENDMETHOD.
METHOD first_index_of_stop.
READ TABLE mt_store TRANSPORTING NO FIELDS WITH KEY stop = iv_stop.
IF sy-subrc = 0.
rv_index = sy-tabix.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,93 @@
CLASS {{p}}departure_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_stop TYPE c LENGTH 4.
TYPES ty_line TYPE c LENGTH 6.
TYPES ty_depot TYPE c LENGTH 4.
TYPES ty_time TYPE t.
TYPES:
BEGIN OF ty_departure,
stop TYPE ty_stop,
line TYPE ty_line,
depart TYPE ty_time,
depot TYPE ty_depot,
END OF ty_departure,
tt_departures TYPE STANDARD TABLE OF ty_departure WITH EMPTY KEY.
METHODS constructor.
METHODS add_depot
IMPORTING iv_depot TYPE ty_depot
it_departures TYPE tt_departures.
METHODS next_departure
IMPORTING iv_stop TYPE ty_stop
iv_from TYPE ty_time
RETURNING VALUE(rs_departure) TYPE ty_departure.
METHODS departures_at_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rt_departures) TYPE tt_departures.
METHODS count
RETURNING VALUE(rv_count) TYPE i.
PRIVATE SECTION.
TYPES tt_store TYPE SORTED TABLE OF ty_departure
WITH UNIQUE KEY stop depart line.
DATA mt_store TYPE tt_store.
METHODS first_index_of_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rv_index) TYPE i.
ENDCLASS.
CLASS {{p}}departure_planner IMPLEMENTATION.
METHOD constructor.
CLEAR mt_store.
ENDMETHOD.
METHOD add_depot.
LOOP AT it_departures INTO DATA(ls_departure).
DATA(ls_store) = ls_departure.
ls_store-depot = iv_depot.
INSERT ls_store INTO TABLE mt_store.
ENDLOOP.
ENDMETHOD.
METHOD next_departure.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start = 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop <> iv_stop.
EXIT.
ENDIF.
IF ls_departure-depart < iv_from.
rs_departure = ls_departure.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD departures_at_stop.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start = 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop <> iv_stop.
EXIT.
ENDIF.
APPEND ls_departure TO rt_departures.
ENDLOOP.
ENDMETHOD.
METHOD count.
rv_count = lines( mt_store ).
ENDMETHOD.
METHOD first_index_of_stop.
READ TABLE mt_store TRANSPORTING NO FIELDS WITH KEY stop = iv_stop.
IF sy-subrc = 0.
rv_index = sy-tabix.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,93 @@
CLASS {{p}}departure_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_stop TYPE c LENGTH 4.
TYPES ty_line TYPE c LENGTH 6.
TYPES ty_depot TYPE c LENGTH 4.
TYPES ty_time TYPE t.
TYPES:
BEGIN OF ty_departure,
stop TYPE ty_stop,
line TYPE ty_line,
depart TYPE ty_time,
depot TYPE ty_depot,
END OF ty_departure,
tt_departures TYPE STANDARD TABLE OF ty_departure WITH EMPTY KEY.
METHODS constructor.
METHODS add_depot
IMPORTING iv_depot TYPE ty_depot
it_departures TYPE tt_departures.
METHODS next_departure
IMPORTING iv_stop TYPE ty_stop
iv_from TYPE ty_time
RETURNING VALUE(rs_departure) TYPE ty_departure.
METHODS departures_at_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rt_departures) TYPE tt_departures.
METHODS count
RETURNING VALUE(rv_count) TYPE i.
PRIVATE SECTION.
TYPES tt_store TYPE SORTED TABLE OF ty_departure
WITH UNIQUE KEY stop depart line.
DATA mt_store TYPE tt_store.
METHODS first_index_of_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rv_index) TYPE i.
ENDCLASS.
CLASS {{p}}departure_planner IMPLEMENTATION.
METHOD constructor.
CLEAR mt_store.
ENDMETHOD.
METHOD add_depot.
LOOP AT it_departures INTO DATA(ls_departure).
DATA(ls_store) = ls_departure.
ls_store-depot = iv_depot.
INSERT ls_store INTO TABLE mt_store.
ENDLOOP.
ENDMETHOD.
METHOD next_departure.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start = 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop <> iv_stop.
EXIT.
ENDIF.
IF ls_departure-depart >= iv_from.
rs_departure = ls_departure.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD departures_at_stop.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start <> 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop <> iv_stop.
EXIT.
ENDIF.
APPEND ls_departure TO rt_departures.
ENDLOOP.
ENDMETHOD.
METHOD count.
rv_count = lines( mt_store ).
ENDMETHOD.
METHOD first_index_of_stop.
READ TABLE mt_store TRANSPORTING NO FIELDS WITH KEY stop = iv_stop.
IF sy-subrc = 0.
rv_index = sy-tabix.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,93 @@
CLASS {{p}}departure_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_stop TYPE c LENGTH 4.
TYPES ty_line TYPE c LENGTH 6.
TYPES ty_depot TYPE c LENGTH 4.
TYPES ty_time TYPE t.
TYPES:
BEGIN OF ty_departure,
stop TYPE ty_stop,
line TYPE ty_line,
depart TYPE ty_time,
depot TYPE ty_depot,
END OF ty_departure,
tt_departures TYPE STANDARD TABLE OF ty_departure WITH EMPTY KEY.
METHODS constructor.
METHODS add_depot
IMPORTING iv_depot TYPE ty_depot
it_departures TYPE tt_departures.
METHODS next_departure
IMPORTING iv_stop TYPE ty_stop
iv_from TYPE ty_time
RETURNING VALUE(rs_departure) TYPE ty_departure.
METHODS departures_at_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rt_departures) TYPE tt_departures.
METHODS count
RETURNING VALUE(rv_count) TYPE i.
PRIVATE SECTION.
TYPES tt_store TYPE SORTED TABLE OF ty_departure
WITH UNIQUE KEY stop depart line.
DATA mt_store TYPE tt_store.
METHODS first_index_of_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rv_index) TYPE i.
ENDCLASS.
CLASS {{p}}departure_planner IMPLEMENTATION.
METHOD constructor.
CLEAR mt_store.
ENDMETHOD.
METHOD add_depot.
LOOP AT it_departures INTO DATA(ls_departure).
DATA(ls_store) = ls_departure.
ls_store-depot = iv_depot.
INSERT ls_store INTO TABLE mt_store.
ENDLOOP.
ENDMETHOD.
METHOD next_departure.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start = 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop <> iv_stop.
EXIT.
ENDIF.
IF ls_departure-depart >= iv_from.
rs_departure = ls_departure.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD departures_at_stop.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start = 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop = iv_stop.
EXIT.
ENDIF.
APPEND ls_departure TO rt_departures.
ENDLOOP.
ENDMETHOD.
METHOD count.
rv_count = lines( mt_store ).
ENDMETHOD.
METHOD first_index_of_stop.
READ TABLE mt_store TRANSPORTING NO FIELDS WITH KEY stop = iv_stop.
IF sy-subrc = 0.
rv_index = sy-tabix.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,19 @@
{
"id": "G0116",
"pool": "eval",
"object_type": "CLAS",
"category": "C",
"attempts": [
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 5,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,133 @@
CLASS {{p}}t02_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}departure_planner.
METHODS setup.
METHODS empty_planner FOR TESTING.
METHODS add_counts FOR TESTING.
METHODS duplicate_ignored FOR TESTING.
METHODS duplicate_in_one_call FOR TESTING.
METHODS next_earliest FOR TESTING.
METHODS next_from_exact_time FOR TESTING.
METHODS next_after_last FOR TESTING.
METHODS next_unknown_stop FOR TESTING.
METHODS stop_list_sorted FOR TESTING.
METHODS stop_list_unknown FOR TESTING.
METHODS add_empty_no_change FOR TESTING.
METHODS departures_d1
RETURNING VALUE(rt_departures) TYPE {{p}}departure_planner=>tt_departures.
METHODS departures_d2
RETURNING VALUE(rt_departures) TYPE {{p}}departure_planner=>tt_departures.
ENDCLASS.
CLASS {{p}}t02_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}departure_planner( ).
ENDMETHOD.
METHOD departures_d1.
rt_departures = VALUE #( ( stop = 'A100' line = 'L10' depart = '080000' )
( stop = 'A100' line = 'L20' depart = '083000' )
( stop = 'B200' line = 'L10' depart = '090000' ) ).
ENDMETHOD.
METHOD departures_d2.
rt_departures = VALUE #( ( stop = 'A100' line = 'L10' depart = '080000' )
( stop = 'A100' line = 'L15' depart = '081500' )
( stop = 'A100' line = 'L30' depart = '081500' )
( stop = 'C300' line = 'L30' depart = '070000' ) ).
ENDMETHOD.
METHOD empty_planner.
cl_abap_unit_assert=>assert_equals( exp = 0 act = mo_cut->count( ) ).
DATA ls_next TYPE {{p}}departure_planner=>ty_departure.
ls_next = mo_cut->next_departure( iv_stop = 'A100' iv_from = '000000' ).
cl_abap_unit_assert=>assert_initial( act = ls_next-stop ).
cl_abap_unit_assert=>assert_equals( exp = 0
act = lines( mo_cut->departures_at_stop( 'A100' ) ) ).
ENDMETHOD.
METHOD add_counts.
mo_cut->add_depot( iv_depot = 'D1' it_departures = departures_d1( ) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = mo_cut->count( ) ).
ENDMETHOD.
METHOD duplicate_ignored.
mo_cut->add_depot( iv_depot = 'D1' it_departures = departures_d1( ) ).
mo_cut->add_depot( iv_depot = 'D2' it_departures = departures_d2( ) ).
cl_abap_unit_assert=>assert_equals( exp = 6 act = mo_cut->count( ) ).
DATA lt_stop TYPE {{p}}departure_planner=>tt_departures.
lt_stop = mo_cut->departures_at_stop( 'A100' ).
DATA ls_row TYPE {{p}}departure_planner=>ty_departure.
READ TABLE lt_stop INTO ls_row WITH KEY line = 'L10' depart = '080000'.
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = ls_row-depot ).
ENDMETHOD.
METHOD duplicate_in_one_call.
DATA lt_input TYPE {{p}}departure_planner=>tt_departures.
lt_input = departures_d1( ).
DATA ls_first TYPE {{p}}departure_planner=>ty_departure.
ls_first = lt_input[ 1 ].
APPEND ls_first TO lt_input.
mo_cut->add_depot( iv_depot = 'D1' it_departures = lt_input ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = mo_cut->count( ) ).
ENDMETHOD.
METHOD next_earliest.
mo_cut->add_depot( iv_depot = 'D1' it_departures = departures_d1( ) ).
DATA ls_next TYPE {{p}}departure_planner=>ty_departure.
ls_next = mo_cut->next_departure( iv_stop = 'A100' iv_from = '000000' ).
cl_abap_unit_assert=>assert_equals( exp = 'L10' act = ls_next-line ).
cl_abap_unit_assert=>assert_equals( exp = '080000' act = ls_next-depart ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = ls_next-depot ).
ENDMETHOD.
METHOD next_from_exact_time.
mo_cut->add_depot( iv_depot = 'D1' it_departures = departures_d1( ) ).
DATA ls_next TYPE {{p}}departure_planner=>ty_departure.
ls_next = mo_cut->next_departure( iv_stop = 'A100' iv_from = '083000' ).
cl_abap_unit_assert=>assert_equals( exp = 'L20' act = ls_next-line ).
cl_abap_unit_assert=>assert_equals( exp = '083000' act = ls_next-depart ).
ENDMETHOD.
METHOD next_after_last.
mo_cut->add_depot( iv_depot = 'D1' it_departures = departures_d1( ) ).
DATA ls_next TYPE {{p}}departure_planner=>ty_departure.
ls_next = mo_cut->next_departure( iv_stop = 'A100' iv_from = '083001' ).
cl_abap_unit_assert=>assert_initial( act = ls_next-stop ).
ENDMETHOD.
METHOD next_unknown_stop.
mo_cut->add_depot( iv_depot = 'D1' it_departures = departures_d1( ) ).
DATA ls_next TYPE {{p}}departure_planner=>ty_departure.
ls_next = mo_cut->next_departure( iv_stop = 'Z999' iv_from = '000000' ).
cl_abap_unit_assert=>assert_initial( act = ls_next-stop ).
ENDMETHOD.
METHOD stop_list_sorted.
mo_cut->add_depot( iv_depot = 'D1' it_departures = departures_d1( ) ).
mo_cut->add_depot( iv_depot = 'D2' it_departures = departures_d2( ) ).
DATA lt_stop TYPE {{p}}departure_planner=>tt_departures.
lt_stop = mo_cut->departures_at_stop( 'A100' ).
cl_abap_unit_assert=>assert_equals( exp = 4 act = lines( lt_stop ) ).
cl_abap_unit_assert=>assert_equals( exp = '080000' act = lt_stop[ 1 ]-depart ).
cl_abap_unit_assert=>assert_equals( exp = '081500' act = lt_stop[ 2 ]-depart ).
cl_abap_unit_assert=>assert_equals( exp = 'L15' act = lt_stop[ 2 ]-line ).
cl_abap_unit_assert=>assert_equals( exp = 'L30' act = lt_stop[ 3 ]-line ).
cl_abap_unit_assert=>assert_equals( exp = '083000' act = lt_stop[ 4 ]-depart ).
ENDMETHOD.
METHOD stop_list_unknown.
mo_cut->add_depot( iv_depot = 'D1' it_departures = departures_d1( ) ).
cl_abap_unit_assert=>assert_equals( exp = 0
act = lines( mo_cut->departures_at_stop( 'Z999' ) ) ).
ENDMETHOD.
METHOD add_empty_no_change.
mo_cut->add_depot( iv_depot = 'D1' it_departures = departures_d1( ) ).
DATA lt_empty TYPE {{p}}departure_planner=>tt_departures.
mo_cut->add_depot( iv_depot = 'D2' it_departures = lt_empty ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = mo_cut->count( ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,60 @@
{
"task": "G0116",
"mutants": [
{
"object": "{{P}}DEPARTURE_PLANNER",
"mutant": "line 56: = -> <> (eq)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"NEXT_EARLIEST",
"NEXT_FROM_EXACT_TIME"
]
},
{
"object": "{{P}}DEPARTURE_PLANNER",
"mutant": "line 60: <> -> = (rel)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"NEXT_EARLIEST",
"NEXT_FROM_EXACT_TIME"
]
},
{
"object": "{{P}}DEPARTURE_PLANNER",
"mutant": "line 63: >= -> < (rel)",
"status": "killed",
"hidden": "8/11",
"failed_tests": [
"NEXT_AFTER_LAST",
"NEXT_EARLIEST",
"NEXT_FROM_EXACT_TIME"
]
},
{
"object": "{{P}}DEPARTURE_PLANNER",
"mutant": "line 72: = -> <> (eq)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"DUPLICATE_IGNORED",
"STOP_LIST_SORTED"
]
},
{
"object": "{{P}}DEPARTURE_PLANNER",
"mutant": "line 76: <> -> = (rel)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"DUPLICATE_IGNORED",
"STOP_LIST_SORTED"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,93 @@
CLASS {{p}}departure_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_stop TYPE c LENGTH 4.
TYPES ty_line TYPE c LENGTH 6.
TYPES ty_depot TYPE c LENGTH 4.
TYPES ty_time TYPE t.
TYPES:
BEGIN OF ty_departure,
stop TYPE ty_stop,
line TYPE ty_line,
depart TYPE ty_time,
depot TYPE ty_depot,
END OF ty_departure,
tt_departures TYPE STANDARD TABLE OF ty_departure WITH EMPTY KEY.
METHODS constructor.
METHODS add_depot
IMPORTING iv_depot TYPE ty_depot
it_departures TYPE tt_departures.
METHODS next_departure
IMPORTING iv_stop TYPE ty_stop
iv_from TYPE ty_time
RETURNING VALUE(rs_departure) TYPE ty_departure.
METHODS departures_at_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rt_departures) TYPE tt_departures.
METHODS count
RETURNING VALUE(rv_count) TYPE i.
PRIVATE SECTION.
TYPES tt_store TYPE SORTED TABLE OF ty_departure
WITH UNIQUE KEY stop depart line.
DATA mt_store TYPE tt_store.
METHODS first_index_of_stop
IMPORTING iv_stop TYPE ty_stop
RETURNING VALUE(rv_index) TYPE i.
ENDCLASS.
CLASS {{p}}departure_planner IMPLEMENTATION.
METHOD constructor.
CLEAR mt_store.
ENDMETHOD.
METHOD add_depot.
LOOP AT it_departures INTO DATA(ls_departure).
DATA(ls_store) = ls_departure.
ls_store-depot = iv_depot.
INSERT ls_store INTO TABLE mt_store.
ENDLOOP.
ENDMETHOD.
METHOD next_departure.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start = 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop <> iv_stop.
EXIT.
ENDIF.
IF ls_departure-depart >= iv_from.
rs_departure = ls_departure.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD departures_at_stop.
DATA(lv_start) = first_index_of_stop( iv_stop ).
IF lv_start = 0.
RETURN.
ENDIF.
LOOP AT mt_store INTO DATA(ls_departure) FROM lv_start.
IF ls_departure-stop <> iv_stop.
EXIT.
ENDIF.
APPEND ls_departure TO rt_departures.
ENDLOOP.
ENDMETHOD.
METHOD count.
rv_count = lines( mt_store ).
ENDMETHOD.
METHOD first_index_of_stop.
READ TABLE mt_store TRANSPORTING NO FIELDS WITH KEY stop = iv_stop.
IF sy-subrc = 0.
rv_index = sy-tabix.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,73 @@
CLASS ltc_departure_planner DEFINITION FINAL FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}departure_planner.
METHODS setup.
METHODS stores_depot FOR TESTING.
METHODS ignores_duplicate FOR TESTING.
METHODS next_departure_ok FOR TESTING.
METHODS next_departure_none FOR TESTING.
METHODS stop_list_ok FOR TESTING.
METHODS empty_input_ok FOR TESTING.
ENDCLASS.
CLASS ltc_departure_planner IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}departure_planner( ).
ENDMETHOD.
METHOD stores_depot.
DATA lt_input TYPE {{p}}departure_planner=>tt_departures.
lt_input = VALUE #( ( stop = 'A100' line = 'L10' depart = '080000' ) ).
mo_cut->add_depot( iv_depot = 'D1' it_departures = lt_input ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = mo_cut->count( ) ).
DATA ls_next TYPE {{p}}departure_planner=>ty_departure.
ls_next = mo_cut->next_departure( iv_stop = 'A100' iv_from = '000000' ).
cl_abap_unit_assert=>assert_equals( exp = 'D1' act = ls_next-depot ).
ENDMETHOD.
METHOD ignores_duplicate.
DATA lt_input TYPE {{p}}departure_planner=>tt_departures.
lt_input = VALUE #( ( stop = 'A100' line = 'L10' depart = '080000' ) ).
mo_cut->add_depot( iv_depot = 'D1' it_departures = lt_input ).
mo_cut->add_depot( iv_depot = 'D2' it_departures = lt_input ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = mo_cut->count( ) ).
ENDMETHOD.
METHOD next_departure_ok.
DATA lt_input TYPE {{p}}departure_planner=>tt_departures.
lt_input = VALUE #( ( stop = 'A100' line = 'L10' depart = '080000' )
( stop = 'A100' line = 'L20' depart = '083000' ) ).
mo_cut->add_depot( iv_depot = 'D1' it_departures = lt_input ).
DATA ls_next TYPE {{p}}departure_planner=>ty_departure.
ls_next = mo_cut->next_departure( iv_stop = 'A100' iv_from = '080001' ).
cl_abap_unit_assert=>assert_equals( exp = 'L20' act = ls_next-line ).
ENDMETHOD.
METHOD next_departure_none.
DATA lt_input TYPE {{p}}departure_planner=>tt_departures.
lt_input = VALUE #( ( stop = 'A100' line = 'L10' depart = '080000' ) ).
mo_cut->add_depot( iv_depot = 'D1' it_departures = lt_input ).
DATA ls_next TYPE {{p}}departure_planner=>ty_departure.
ls_next = mo_cut->next_departure( iv_stop = 'A100' iv_from = '090000' ).
cl_abap_unit_assert=>assert_initial( act = ls_next-stop ).
ENDMETHOD.
METHOD stop_list_ok.
DATA lt_input TYPE {{p}}departure_planner=>tt_departures.
lt_input = VALUE #( ( stop = 'A100' line = 'L20' depart = '083000' )
( stop = 'A100' line = 'L10' depart = '080000' ) ).
mo_cut->add_depot( iv_depot = 'D1' it_departures = lt_input ).
DATA lt_stop TYPE {{p}}departure_planner=>tt_departures.
lt_stop = mo_cut->departures_at_stop( 'A100' ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_stop ) ).
cl_abap_unit_assert=>assert_equals( exp = '080000' act = lt_stop[ 1 ]-depart ).
ENDMETHOD.
METHOD empty_input_ok.
DATA lt_input TYPE {{p}}departure_planner=>tt_departures.
mo_cut->add_depot( iv_depot = 'D1' it_departures = lt_input ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = mo_cut->count( ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,68 @@
# 1. Goal
A regional bus company collects the departure timetables of its depots. The
planning office needs one class that stores the departures of all depots and
answers two questions: which departure comes next at a stop, and which
departures a stop has.
# 2. Open questions
None.
# 3. Context
- Package $TMP, client 001, SAP_BASIS 816.
- There are no seed objects. The class is new.
- A departure has a stop, a line, a departure time and the depot that reported
it.
# 4. Contract
Create the class {{P}}DEPARTURE_PLANNER in package $TMP.
The class is public and final. It has a public constructor without parameters.
The class declares these public types:
- TY_STOP: character, length 4.
- TY_LINE: character, length 6.
- TY_DEPOT: character, length 4.
- TY_TIME: a time of the system (type T, format HHMMSS).
- TY_DEPARTURE: a structure with the components STOP (TY_STOP), LINE (TY_LINE),
DEPART (TY_TIME) and DEPOT (TY_DEPOT), in this order.
- TT_DEPARTURES: a standard table of TY_DEPARTURE with an empty key.
The class has exactly these public methods:
- CONSTRUCTOR: no parameters.
- ADD_DEPOT: importing IV_DEPOT type TY_DEPOT and IT_DEPARTURES type
TT_DEPARTURES. No returning parameter.
- NEXT_DEPARTURE: importing IV_STOP type TY_STOP and IV_FROM type TY_TIME.
Returning RS_DEPARTURE type TY_DEPARTURE.
- DEPARTURES_AT_STOP: importing IV_STOP type TY_STOP. Returning RT_DEPARTURES
type TT_DEPARTURES.
- COUNT: no importing parameter. Returning RV_COUNT type I.
Do not add other public methods.
# 5. Business rules
1. ADD_DEPOT stores the departures of the given depot. The DEPOT component of
the input rows is not used. The class stores IV_DEPOT in the DEPOT component.
2. Two departures are equal if STOP, LINE and DEPART are equal. If an equal
departure is already stored, the new departure is ignored and the stored
departure does not change. This rule also applies to equal departures inside
one call of ADD_DEPOT.
3. COUNT returns the number of stored departures.
4. NEXT_DEPARTURE returns the stored departure of the given stop with the
smallest DEPART that is not before IV_FROM. "Not before" means
DEPART >= IV_FROM. If the stop has no such departure, the result is initial.
5. DEPARTURES_AT_STOP returns all stored departures of the given stop in
ascending order of DEPART. If two departures have the same DEPART, the
departure with the smaller LINE comes first. If the stop is not stored, the
result is empty.
6. An empty input table changes nothing.
# 6. Constraints
- Release target: 8.16.
- Coding standards: Clean ABAP. Method length below 40 statements. No global
variables. No comment that restates the code.
- Out of scope: no database access, no user interface, no change to other
objects.
# 7. Acceptance
- The class is active and has no syntax error.
- The hidden tests pass.
- Write your own ABAP Unit tests for the class.

View File

@@ -0,0 +1,42 @@
{
"id": "G0116",
"category": "C",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 40,
"max_activations": 10
},
"seed": [],
"contract": [
{
"type": "CLAS",
"name": "{{P}}DEPARTURE_PLANNER"
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T02_HIDDEN",
"file": "hidden/t02_hidden.clas.abap",
"description": "T02 hidden tests"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}DEPARTURE_PLANNER",
"file": "reference/departure_planner.clas.abap",
"description": "Departure planner with a keyed internal store",
"testclasses_file": "reference/departure_planner.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"table_kind",
"access_path"
]
}