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,102 @@
CLASS {{p}}canteen_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_canteen_plan.
PRIVATE SECTION.
TYPES tt_demand TYPE SORTED TABLE OF {{p}}if_canteen_plan=>ty_order
WITH UNIQUE KEY ingredient.
TYPES tt_master TYPE HASHED TABLE OF {{p}}if_canteen_plan=>ty_master
WITH UNIQUE KEY ingredient.
METHODS collect_orders
IMPORTING it_orders TYPE {{p}}if_canteen_plan=>tt_order
CHANGING ct_demand TYPE tt_demand.
METHODS collect_demand
IMPORTING it_orders TYPE {{p}}if_canteen_plan=>tt_order
RETURNING VALUE(rt_demand) TYPE tt_demand.
METHODS to_master
IMPORTING it_catalogue TYPE {{p}}if_canteen_plan=>tt_master
RETURNING VALUE(rt_master) TYPE tt_master.
METHODS packs_needed
IMPORTING iv_quantity TYPE {{p}}if_canteen_plan=>ty_quantity
iv_pack_size TYPE {{p}}if_canteen_plan=>ty_quantity
RETURNING VALUE(rv_packs) TYPE i.
ENDCLASS.
CLASS {{p}}canteen_planner IMPLEMENTATION.
METHOD {{p}}if_canteen_plan~merge_orders.
DATA(lt_demand) = collect_demand( it_orders_a ).
collect_orders( EXPORTING it_orders = it_orders_b
CHANGING ct_demand = lt_demand ).
rt_demand = lt_demand.
ENDMETHOD.
METHOD {{p}}if_canteen_plan~pack_requirement.
DATA(lt_master) = to_master( it_catalogue ).
DATA(lt_demand) = collect_demand( it_demand ).
DATA ls_master TYPE {{p}}if_canteen_plan=>ty_master.
LOOP AT lt_demand INTO DATA(ls_demand).
IF NOT line_exists( lt_master[ ingredient = ls_demand-ingredient ] ).
CONTINUE.
ENDIF.
ls_master = lt_master[ ingredient = ls_demand-ingredient ].
INSERT VALUE #( ingredient = ls_demand-ingredient
packs = packs_needed( iv_quantity = ls_demand-quantity
iv_pack_size = ls_master-pack_size ) )
INTO TABLE rt_packs.
ENDLOOP.
ENDMETHOD.
METHOD {{p}}if_canteen_plan~missing_ingredients.
DATA(lt_master) = to_master( it_catalogue ).
DATA(lt_demand) = collect_demand( it_demand ).
LOOP AT lt_demand INTO DATA(ls_demand).
IF NOT line_exists( lt_master[ ingredient = ls_demand-ingredient ] ).
APPEND ls_demand-ingredient TO rt_missing.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD collect_orders.
LOOP AT it_orders INTO DATA(ls_order).
IF ls_order-quantity > 0.
CONTINUE.
ENDIF.
READ TABLE ct_demand ASSIGNING FIELD-SYMBOL(<ls_demand>)
WITH TABLE KEY ingredient = ls_order-ingredient.
IF sy-subrc = 0.
<ls_demand>-quantity = <ls_demand>-quantity + ls_order-quantity.
ELSE.
INSERT VALUE #( ingredient = ls_order-ingredient
quantity = ls_order-quantity ) INTO TABLE ct_demand.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD collect_demand.
DATA(lt_demand) = VALUE tt_demand( ).
collect_orders( EXPORTING it_orders = it_orders
CHANGING ct_demand = lt_demand ).
rt_demand = lt_demand.
ENDMETHOD.
METHOD to_master.
LOOP AT it_catalogue INTO DATA(ls_catalogue).
INSERT VALUE #( ingredient = ls_catalogue-ingredient
pack_size = ls_catalogue-pack_size ) INTO TABLE rt_master.
ENDLOOP.
ENDMETHOD.
METHOD packs_needed.
rv_packs = iv_quantity DIV iv_pack_size.
IF iv_quantity MOD iv_pack_size <> 0.
rv_packs = rv_packs + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,102 @@
CLASS {{p}}canteen_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_canteen_plan.
PRIVATE SECTION.
TYPES tt_demand TYPE SORTED TABLE OF {{p}}if_canteen_plan=>ty_order
WITH UNIQUE KEY ingredient.
TYPES tt_master TYPE HASHED TABLE OF {{p}}if_canteen_plan=>ty_master
WITH UNIQUE KEY ingredient.
METHODS collect_orders
IMPORTING it_orders TYPE {{p}}if_canteen_plan=>tt_order
CHANGING ct_demand TYPE tt_demand.
METHODS collect_demand
IMPORTING it_orders TYPE {{p}}if_canteen_plan=>tt_order
RETURNING VALUE(rt_demand) TYPE tt_demand.
METHODS to_master
IMPORTING it_catalogue TYPE {{p}}if_canteen_plan=>tt_master
RETURNING VALUE(rt_master) TYPE tt_master.
METHODS packs_needed
IMPORTING iv_quantity TYPE {{p}}if_canteen_plan=>ty_quantity
iv_pack_size TYPE {{p}}if_canteen_plan=>ty_quantity
RETURNING VALUE(rv_packs) TYPE i.
ENDCLASS.
CLASS {{p}}canteen_planner IMPLEMENTATION.
METHOD {{p}}if_canteen_plan~merge_orders.
DATA(lt_demand) = collect_demand( it_orders_a ).
collect_orders( EXPORTING it_orders = it_orders_b
CHANGING ct_demand = lt_demand ).
rt_demand = lt_demand.
ENDMETHOD.
METHOD {{p}}if_canteen_plan~pack_requirement.
DATA(lt_master) = to_master( it_catalogue ).
DATA(lt_demand) = collect_demand( it_demand ).
DATA ls_master TYPE {{p}}if_canteen_plan=>ty_master.
LOOP AT lt_demand INTO DATA(ls_demand).
IF NOT line_exists( lt_master[ ingredient = ls_demand-ingredient ] ).
CONTINUE.
ENDIF.
ls_master = lt_master[ ingredient = ls_demand-ingredient ].
INSERT VALUE #( ingredient = ls_demand-ingredient
packs = packs_needed( iv_quantity = ls_demand-quantity
iv_pack_size = ls_master-pack_size ) )
INTO TABLE rt_packs.
ENDLOOP.
ENDMETHOD.
METHOD {{p}}if_canteen_plan~missing_ingredients.
DATA(lt_master) = to_master( it_catalogue ).
DATA(lt_demand) = collect_demand( it_demand ).
LOOP AT lt_demand INTO DATA(ls_demand).
IF NOT line_exists( lt_master[ ingredient = ls_demand-ingredient ] ).
APPEND ls_demand-ingredient TO rt_missing.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD collect_orders.
LOOP AT it_orders INTO DATA(ls_order).
IF ls_order-quantity <= 0.
CONTINUE.
ENDIF.
READ TABLE ct_demand ASSIGNING FIELD-SYMBOL(<ls_demand>)
WITH TABLE KEY ingredient = ls_order-ingredient.
IF sy-subrc = 0.
<ls_demand>-quantity = <ls_demand>-quantity - ls_order-quantity.
ELSE.
INSERT VALUE #( ingredient = ls_order-ingredient
quantity = ls_order-quantity ) INTO TABLE ct_demand.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD collect_demand.
DATA(lt_demand) = VALUE tt_demand( ).
collect_orders( EXPORTING it_orders = it_orders
CHANGING ct_demand = lt_demand ).
rt_demand = lt_demand.
ENDMETHOD.
METHOD to_master.
LOOP AT it_catalogue INTO DATA(ls_catalogue).
INSERT VALUE #( ingredient = ls_catalogue-ingredient
pack_size = ls_catalogue-pack_size ) INTO TABLE rt_master.
ENDLOOP.
ENDMETHOD.
METHOD packs_needed.
rv_packs = iv_quantity DIV iv_pack_size.
IF iv_quantity MOD iv_pack_size <> 0.
rv_packs = rv_packs + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,102 @@
CLASS {{p}}canteen_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_canteen_plan.
PRIVATE SECTION.
TYPES tt_demand TYPE SORTED TABLE OF {{p}}if_canteen_plan=>ty_order
WITH UNIQUE KEY ingredient.
TYPES tt_master TYPE HASHED TABLE OF {{p}}if_canteen_plan=>ty_master
WITH UNIQUE KEY ingredient.
METHODS collect_orders
IMPORTING it_orders TYPE {{p}}if_canteen_plan=>tt_order
CHANGING ct_demand TYPE tt_demand.
METHODS collect_demand
IMPORTING it_orders TYPE {{p}}if_canteen_plan=>tt_order
RETURNING VALUE(rt_demand) TYPE tt_demand.
METHODS to_master
IMPORTING it_catalogue TYPE {{p}}if_canteen_plan=>tt_master
RETURNING VALUE(rt_master) TYPE tt_master.
METHODS packs_needed
IMPORTING iv_quantity TYPE {{p}}if_canteen_plan=>ty_quantity
iv_pack_size TYPE {{p}}if_canteen_plan=>ty_quantity
RETURNING VALUE(rv_packs) TYPE i.
ENDCLASS.
CLASS {{p}}canteen_planner IMPLEMENTATION.
METHOD {{p}}if_canteen_plan~merge_orders.
DATA(lt_demand) = collect_demand( it_orders_a ).
collect_orders( EXPORTING it_orders = it_orders_b
CHANGING ct_demand = lt_demand ).
rt_demand = lt_demand.
ENDMETHOD.
METHOD {{p}}if_canteen_plan~pack_requirement.
DATA(lt_master) = to_master( it_catalogue ).
DATA(lt_demand) = collect_demand( it_demand ).
DATA ls_master TYPE {{p}}if_canteen_plan=>ty_master.
LOOP AT lt_demand INTO DATA(ls_demand).
IF NOT line_exists( lt_master[ ingredient = ls_demand-ingredient ] ).
CONTINUE.
ENDIF.
ls_master = lt_master[ ingredient = ls_demand-ingredient ].
INSERT VALUE #( ingredient = ls_demand-ingredient
packs = packs_needed( iv_quantity = ls_demand-quantity
iv_pack_size = ls_master-pack_size ) )
INTO TABLE rt_packs.
ENDLOOP.
ENDMETHOD.
METHOD {{p}}if_canteen_plan~missing_ingredients.
DATA(lt_master) = to_master( it_catalogue ).
DATA(lt_demand) = collect_demand( it_demand ).
LOOP AT lt_demand INTO DATA(ls_demand).
IF NOT line_exists( lt_master[ ingredient = ls_demand-ingredient ] ).
APPEND ls_demand-ingredient TO rt_missing.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD collect_orders.
LOOP AT it_orders INTO DATA(ls_order).
IF ls_order-quantity <= 0.
CONTINUE.
ENDIF.
READ TABLE ct_demand ASSIGNING FIELD-SYMBOL(<ls_demand>)
WITH TABLE KEY ingredient = ls_order-ingredient.
IF sy-subrc = 0.
<ls_demand>-quantity = <ls_demand>-quantity + ls_order-quantity.
ELSE.
INSERT VALUE #( ingredient = ls_order-ingredient
quantity = ls_order-quantity ) INTO TABLE ct_demand.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD collect_demand.
DATA(lt_demand) = VALUE tt_demand( ).
collect_orders( EXPORTING it_orders = it_orders
CHANGING ct_demand = lt_demand ).
rt_demand = lt_demand.
ENDMETHOD.
METHOD to_master.
LOOP AT it_catalogue INTO DATA(ls_catalogue).
INSERT VALUE #( ingredient = ls_catalogue-ingredient
pack_size = ls_catalogue-pack_size ) INTO TABLE rt_master.
ENDLOOP.
ENDMETHOD.
METHOD packs_needed.
rv_packs = iv_quantity DIV iv_pack_size.
IF iv_quantity MOD iv_pack_size = 0.
rv_packs = rv_packs + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,102 @@
CLASS {{p}}canteen_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_canteen_plan.
PRIVATE SECTION.
TYPES tt_demand TYPE SORTED TABLE OF {{p}}if_canteen_plan=>ty_order
WITH UNIQUE KEY ingredient.
TYPES tt_master TYPE HASHED TABLE OF {{p}}if_canteen_plan=>ty_master
WITH UNIQUE KEY ingredient.
METHODS collect_orders
IMPORTING it_orders TYPE {{p}}if_canteen_plan=>tt_order
CHANGING ct_demand TYPE tt_demand.
METHODS collect_demand
IMPORTING it_orders TYPE {{p}}if_canteen_plan=>tt_order
RETURNING VALUE(rt_demand) TYPE tt_demand.
METHODS to_master
IMPORTING it_catalogue TYPE {{p}}if_canteen_plan=>tt_master
RETURNING VALUE(rt_master) TYPE tt_master.
METHODS packs_needed
IMPORTING iv_quantity TYPE {{p}}if_canteen_plan=>ty_quantity
iv_pack_size TYPE {{p}}if_canteen_plan=>ty_quantity
RETURNING VALUE(rv_packs) TYPE i.
ENDCLASS.
CLASS {{p}}canteen_planner IMPLEMENTATION.
METHOD {{p}}if_canteen_plan~merge_orders.
DATA(lt_demand) = collect_demand( it_orders_a ).
collect_orders( EXPORTING it_orders = it_orders_b
CHANGING ct_demand = lt_demand ).
rt_demand = lt_demand.
ENDMETHOD.
METHOD {{p}}if_canteen_plan~pack_requirement.
DATA(lt_master) = to_master( it_catalogue ).
DATA(lt_demand) = collect_demand( it_demand ).
DATA ls_master TYPE {{p}}if_canteen_plan=>ty_master.
LOOP AT lt_demand INTO DATA(ls_demand).
IF NOT line_exists( lt_master[ ingredient = ls_demand-ingredient ] ).
CONTINUE.
ENDIF.
ls_master = lt_master[ ingredient = ls_demand-ingredient ].
INSERT VALUE #( ingredient = ls_demand-ingredient
packs = packs_needed( iv_quantity = ls_demand-quantity
iv_pack_size = ls_master-pack_size ) )
INTO TABLE rt_packs.
ENDLOOP.
ENDMETHOD.
METHOD {{p}}if_canteen_plan~missing_ingredients.
DATA(lt_master) = to_master( it_catalogue ).
DATA(lt_demand) = collect_demand( it_demand ).
LOOP AT lt_demand INTO DATA(ls_demand).
IF NOT line_exists( lt_master[ ingredient = ls_demand-ingredient ] ).
APPEND ls_demand-ingredient TO rt_missing.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD collect_orders.
LOOP AT it_orders INTO DATA(ls_order).
IF ls_order-quantity <= 0.
CONTINUE.
ENDIF.
READ TABLE ct_demand ASSIGNING FIELD-SYMBOL(<ls_demand>)
WITH TABLE KEY ingredient = ls_order-ingredient.
IF sy-subrc = 0.
<ls_demand>-quantity = <ls_demand>-quantity + ls_order-quantity.
ELSE.
INSERT VALUE #( ingredient = ls_order-ingredient
quantity = ls_order-quantity ) INTO TABLE ct_demand.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD collect_demand.
DATA(lt_demand) = VALUE tt_demand( ).
collect_orders( EXPORTING it_orders = it_orders
CHANGING ct_demand = lt_demand ).
rt_demand = lt_demand.
ENDMETHOD.
METHOD to_master.
LOOP AT it_catalogue INTO DATA(ls_catalogue).
INSERT VALUE #( ingredient = ls_catalogue-ingredient
pack_size = ls_catalogue-pack_size ) INTO TABLE rt_master.
ENDLOOP.
ENDMETHOD.
METHOD packs_needed.
rv_packs = iv_quantity DIV iv_pack_size.
IF iv_quantity MOD iv_pack_size <> 0.
rv_packs = rv_packs - 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

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

View File

@@ -0,0 +1,231 @@
CLASS {{p}}canteen_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}if_canteen_plan.
METHODS setup.
METHODS assert_quantity
IMPORTING iv_expected TYPE {{p}}if_canteen_plan=>ty_quantity
iv_actual TYPE {{p}}if_canteen_plan=>ty_quantity.
METHODS quantity_of
IMPORTING it_demand TYPE {{p}}if_canteen_plan=>tt_order
iv_ingredient TYPE {{p}}if_canteen_plan=>ty_ingredient
RETURNING VALUE(rv_quantity) TYPE {{p}}if_canteen_plan=>ty_quantity.
METHODS packs_of
IMPORTING it_packs TYPE {{p}}if_canteen_plan=>tt_pack
iv_ingredient TYPE {{p}}if_canteen_plan=>ty_ingredient
RETURNING VALUE(rv_packs) TYPE i.
METHODS ingredient_list
IMPORTING it_demand TYPE {{p}}if_canteen_plan=>tt_order
RETURNING VALUE(rv_list) TYPE string.
METHODS merges_and_sums FOR TESTING.
METHODS result_is_sorted FOR TESTING.
METHODS ignores_non_positive FOR TESTING.
METHODS empty_inputs FOR TESTING.
METHODS duplicate_in_one_list FOR TESTING.
METHODS packs_round_up FOR TESTING.
METHODS packs_skip_unknown FOR TESTING.
METHODS packs_sorted FOR TESTING.
METHODS missing_lists_unknown FOR TESTING.
METHODS missing_none FOR TESTING.
ENDCLASS.
CLASS {{p}}canteen_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}canteen_planner( ).
ENDMETHOD.
METHOD assert_quantity.
cl_abap_unit_assert=>assert_equals( exp = iv_expected act = iv_actual ).
ENDMETHOD.
METHOD quantity_of.
LOOP AT it_demand INTO DATA(ls_demand) WHERE ingredient = iv_ingredient.
rv_quantity = rv_quantity + ls_demand-quantity.
ENDLOOP.
ENDMETHOD.
METHOD packs_of.
LOOP AT it_packs INTO DATA(ls_pack) WHERE ingredient = iv_ingredient.
rv_packs = rv_packs + ls_pack-packs.
ENDLOOP.
ENDMETHOD.
METHOD ingredient_list.
LOOP AT it_demand INTO DATA(ls_demand).
rv_list = rv_list && ls_demand-ingredient && `|`.
ENDLOOP.
ENDMETHOD.
METHOD merges_and_sums.
DATA(lt_a) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'FLOUR' quantity = 5 )
( ingredient = 'SUGAR' quantity = 2 ) ).
DATA(lt_b) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'FLOUR' quantity = 3 )
( ingredient = 'BUTTER' quantity = 1 ) ).
DATA(lt_demand) = mo_cut->merge_orders( it_orders_a = lt_a
it_orders_b = lt_b ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lines( lt_demand ) ).
assert_quantity( iv_expected = 8
iv_actual = quantity_of( it_demand = lt_demand
iv_ingredient = 'FLOUR' ) ).
assert_quantity( iv_expected = 2
iv_actual = quantity_of( it_demand = lt_demand
iv_ingredient = 'SUGAR' ) ).
assert_quantity( iv_expected = 1
iv_actual = quantity_of( it_demand = lt_demand
iv_ingredient = 'BUTTER' ) ).
ENDMETHOD.
METHOD result_is_sorted.
DATA(lt_a) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'SUGAR' quantity = 2 )
( ingredient = 'FLOUR' quantity = 1 ) ).
DATA(lt_b) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'BUTTER' quantity = 1 ) ).
DATA(lt_demand) = mo_cut->merge_orders( it_orders_a = lt_a
it_orders_b = lt_b ).
cl_abap_unit_assert=>assert_equals( exp = `BUTTER|FLOUR|SUGAR|`
act = ingredient_list( lt_demand ) ).
ENDMETHOD.
METHOD ignores_non_positive.
DATA(lt_a) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'FLOUR' quantity = 5 )
( ingredient = 'SUGAR' quantity = 0 ) ).
DATA(lt_b) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'BUTTER' quantity = -2 )
( ingredient = 'FLOUR' quantity = 1 ) ).
DATA(lt_demand) = mo_cut->merge_orders( it_orders_a = lt_a
it_orders_b = lt_b ).
cl_abap_unit_assert=>assert_equals( exp = `FLOUR|`
act = ingredient_list( lt_demand ) ).
assert_quantity( iv_expected = 6
iv_actual = quantity_of( it_demand = lt_demand
iv_ingredient = 'FLOUR' ) ).
ENDMETHOD.
METHOD empty_inputs.
DATA(lt_demand) = mo_cut->merge_orders(
it_orders_a = VALUE {{p}}if_canteen_plan=>tt_order( )
it_orders_b = VALUE {{p}}if_canteen_plan=>tt_order( ) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_demand ) ).
ENDMETHOD.
METHOD duplicate_in_one_list.
DATA(lt_a) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'FLOUR' quantity = 2 )
( ingredient = 'FLOUR' quantity = 3 ) ).
DATA(lt_demand) = mo_cut->merge_orders(
it_orders_a = lt_a
it_orders_b = VALUE {{p}}if_canteen_plan=>tt_order( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_demand ) ).
assert_quantity( iv_expected = 5
iv_actual = quantity_of( it_demand = lt_demand
iv_ingredient = 'FLOUR' ) ).
ENDMETHOD.
METHOD packs_round_up.
DATA(lt_demand) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'FLOUR' quantity = 25 )
( ingredient = 'SUGAR' quantity = 7 )
( ingredient = 'BUTTER' quantity = 3 ) ).
DATA(lt_catalogue) = VALUE {{p}}if_canteen_plan=>tt_master(
( ingredient = 'FLOUR' pack_size = 10 )
( ingredient = 'SUGAR' pack_size = 5 )
( ingredient = 'BUTTER' pack_size = 1 ) ).
DATA(lt_packs) = mo_cut->pack_requirement( it_demand = lt_demand
it_catalogue = lt_catalogue ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lines( lt_packs ) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = packs_of( it_packs = lt_packs
iv_ingredient = 'FLOUR' ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = packs_of( it_packs = lt_packs
iv_ingredient = 'SUGAR' ) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = packs_of( it_packs = lt_packs
iv_ingredient = 'BUTTER' ) ).
ENDMETHOD.
METHOD packs_skip_unknown.
DATA(lt_demand) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'FLOUR' quantity = 10 )
( ingredient = 'COCOA' quantity = 5 ) ).
DATA(lt_catalogue) = VALUE {{p}}if_canteen_plan=>tt_master(
( ingredient = 'FLOUR' pack_size = 10 ) ).
DATA(lt_packs) = mo_cut->pack_requirement( it_demand = lt_demand
it_catalogue = lt_catalogue ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_packs ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = packs_of( it_packs = lt_packs
iv_ingredient = 'FLOUR' ) ).
ENDMETHOD.
METHOD packs_sorted.
DATA(lt_demand) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'SUGAR' quantity = 11 )
( ingredient = 'FLOUR' quantity = 21 )
( ingredient = 'BUTTER' quantity = 4 ) ).
DATA(lt_catalogue) = VALUE {{p}}if_canteen_plan=>tt_master(
( ingredient = 'SUGAR' pack_size = 5 )
( ingredient = 'FLOUR' pack_size = 10 )
( ingredient = 'BUTTER' pack_size = 1 ) ).
DATA(lt_packs) = mo_cut->pack_requirement( it_demand = lt_demand
it_catalogue = lt_catalogue ).
DATA lv_order TYPE string.
LOOP AT lt_packs INTO DATA(ls_pack).
lv_order = lv_order && ls_pack-ingredient && `|`.
ENDLOOP.
cl_abap_unit_assert=>assert_equals( exp = `BUTTER|FLOUR|SUGAR|` act = lv_order ).
ENDMETHOD.
METHOD missing_lists_unknown.
DATA(lt_demand) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'SUGAR' quantity = 5 )
( ingredient = 'COCOA' quantity = 1 )
( ingredient = 'FLOUR' quantity = 2 )
( ingredient = 'COCOA' quantity = 3 ) ).
DATA(lt_catalogue) = VALUE {{p}}if_canteen_plan=>tt_master(
( ingredient = 'FLOUR' pack_size = 10 )
( ingredient = 'SUGAR' pack_size = 5 ) ).
DATA(lt_missing) = mo_cut->missing_ingredients( it_demand = lt_demand
it_catalogue = lt_catalogue ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_missing ) ).
LOOP AT lt_missing INTO DATA(lv_ingredient).
cl_abap_unit_assert=>assert_equals( exp = 'COCOA' act = lv_ingredient ).
ENDLOOP.
ENDMETHOD.
METHOD missing_none.
DATA(lt_demand) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'FLOUR' quantity = 1 ) ).
DATA(lt_catalogue) = VALUE {{p}}if_canteen_plan=>tt_master(
( ingredient = 'FLOUR' pack_size = 10 ) ).
DATA(lt_missing) = mo_cut->missing_ingredients( it_demand = lt_demand
it_catalogue = lt_catalogue ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_missing ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,62 @@
{
"task": "G0118",
"mutants": [
{
"object": "{{P}}CANTEEN_PLANNER",
"mutant": "line 44: = -> <> (eq)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
},
{
"object": "{{P}}CANTEEN_PLANNER",
"mutant": "line 68: <= -> > (rel)",
"status": "killed",
"hidden": "2/10",
"failed_tests": [
"DUPLICATE_IN_ONE_LIST",
"IGNORES_NON_POSITIVE",
"MERGES_AND_SUMS",
"MISSING_LISTS_UNKNOWN",
"PACKS_ROUND_UP",
"PACKS_SKIP_UNKNOWN",
"PACKS_SORTED",
"RESULT_IS_SORTED"
]
},
{
"object": "{{P}}CANTEEN_PLANNER",
"mutant": "line 74: + -> - (arith)",
"status": "killed",
"hidden": "7/10",
"failed_tests": [
"DUPLICATE_IN_ONE_LIST",
"IGNORES_NON_POSITIVE",
"MERGES_AND_SUMS"
]
},
{
"object": "{{P}}CANTEEN_PLANNER",
"mutant": "line 98: <> -> = (rel)",
"status": "killed",
"hidden": "8/10",
"failed_tests": [
"PACKS_ROUND_UP",
"PACKS_SKIP_UNKNOWN"
]
},
{
"object": "{{P}}CANTEEN_PLANNER",
"mutant": "line 99: + -> - (arith)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"PACKS_ROUND_UP"
]
}
],
"valid": 4,
"killed": 4,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,102 @@
CLASS {{p}}canteen_planner DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES {{p}}if_canteen_plan.
PRIVATE SECTION.
TYPES tt_demand TYPE SORTED TABLE OF {{p}}if_canteen_plan=>ty_order
WITH UNIQUE KEY ingredient.
TYPES tt_master TYPE HASHED TABLE OF {{p}}if_canteen_plan=>ty_master
WITH UNIQUE KEY ingredient.
METHODS collect_orders
IMPORTING it_orders TYPE {{p}}if_canteen_plan=>tt_order
CHANGING ct_demand TYPE tt_demand.
METHODS collect_demand
IMPORTING it_orders TYPE {{p}}if_canteen_plan=>tt_order
RETURNING VALUE(rt_demand) TYPE tt_demand.
METHODS to_master
IMPORTING it_catalogue TYPE {{p}}if_canteen_plan=>tt_master
RETURNING VALUE(rt_master) TYPE tt_master.
METHODS packs_needed
IMPORTING iv_quantity TYPE {{p}}if_canteen_plan=>ty_quantity
iv_pack_size TYPE {{p}}if_canteen_plan=>ty_quantity
RETURNING VALUE(rv_packs) TYPE i.
ENDCLASS.
CLASS {{p}}canteen_planner IMPLEMENTATION.
METHOD {{p}}if_canteen_plan~merge_orders.
DATA(lt_demand) = collect_demand( it_orders_a ).
collect_orders( EXPORTING it_orders = it_orders_b
CHANGING ct_demand = lt_demand ).
rt_demand = lt_demand.
ENDMETHOD.
METHOD {{p}}if_canteen_plan~pack_requirement.
DATA(lt_master) = to_master( it_catalogue ).
DATA(lt_demand) = collect_demand( it_demand ).
DATA ls_master TYPE {{p}}if_canteen_plan=>ty_master.
LOOP AT lt_demand INTO DATA(ls_demand).
IF NOT line_exists( lt_master[ ingredient = ls_demand-ingredient ] ).
CONTINUE.
ENDIF.
ls_master = lt_master[ ingredient = ls_demand-ingredient ].
INSERT VALUE #( ingredient = ls_demand-ingredient
packs = packs_needed( iv_quantity = ls_demand-quantity
iv_pack_size = ls_master-pack_size ) )
INTO TABLE rt_packs.
ENDLOOP.
ENDMETHOD.
METHOD {{p}}if_canteen_plan~missing_ingredients.
DATA(lt_master) = to_master( it_catalogue ).
DATA(lt_demand) = collect_demand( it_demand ).
LOOP AT lt_demand INTO DATA(ls_demand).
IF NOT line_exists( lt_master[ ingredient = ls_demand-ingredient ] ).
APPEND ls_demand-ingredient TO rt_missing.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD collect_orders.
LOOP AT it_orders INTO DATA(ls_order).
IF ls_order-quantity <= 0.
CONTINUE.
ENDIF.
READ TABLE ct_demand ASSIGNING FIELD-SYMBOL(<ls_demand>)
WITH TABLE KEY ingredient = ls_order-ingredient.
IF sy-subrc = 0.
<ls_demand>-quantity = <ls_demand>-quantity + ls_order-quantity.
ELSE.
INSERT VALUE #( ingredient = ls_order-ingredient
quantity = ls_order-quantity ) INTO TABLE ct_demand.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD collect_demand.
DATA(lt_demand) = VALUE tt_demand( ).
collect_orders( EXPORTING it_orders = it_orders
CHANGING ct_demand = lt_demand ).
rt_demand = lt_demand.
ENDMETHOD.
METHOD to_master.
LOOP AT it_catalogue INTO DATA(ls_catalogue).
INSERT VALUE #( ingredient = ls_catalogue-ingredient
pack_size = ls_catalogue-pack_size ) INTO TABLE rt_master.
ENDLOOP.
ENDMETHOD.
METHOD packs_needed.
rv_packs = iv_quantity DIV iv_pack_size.
IF iv_quantity MOD iv_pack_size <> 0.
rv_packs = rv_packs + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,73 @@
CLASS ltc_canteen_planner DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}if_canteen_plan.
METHODS setup.
METHODS merges_two_lists FOR TESTING.
METHODS sorts_by_ingredient FOR TESTING.
METHODS rounds_packs_up FOR TESTING.
METHODS lists_unknown FOR TESTING.
ENDCLASS.
CLASS ltc_canteen_planner IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}canteen_planner( ).
ENDMETHOD.
METHOD merges_two_lists.
DATA(lt_a) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'FLOUR' quantity = 2 ) ).
DATA(lt_b) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'FLOUR' quantity = 3 ) ).
DATA(lt_demand) = mo_cut->merge_orders( it_orders_a = lt_a
it_orders_b = lt_b ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_demand ) ).
DATA lv_expected TYPE {{p}}if_canteen_plan=>ty_quantity.
lv_expected = 5.
cl_abap_unit_assert=>assert_equals( exp = lv_expected
act = lt_demand[ 1 ]-quantity ).
ENDMETHOD.
METHOD sorts_by_ingredient.
DATA(lt_a) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'SUGAR' quantity = 1 )
( ingredient = 'FLOUR' quantity = 1 ) ).
DATA(lt_demand) = mo_cut->merge_orders(
it_orders_a = lt_a
it_orders_b = VALUE {{p}}if_canteen_plan=>tt_order( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'FLOUR'
act = lt_demand[ 1 ]-ingredient ).
cl_abap_unit_assert=>assert_equals( exp = 'SUGAR'
act = lt_demand[ 2 ]-ingredient ).
ENDMETHOD.
METHOD rounds_packs_up.
DATA(lt_demand) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'FLOUR' quantity = 25 ) ).
DATA(lt_catalogue) = VALUE {{p}}if_canteen_plan=>tt_master(
( ingredient = 'FLOUR' pack_size = 10 ) ).
DATA(lt_packs) = mo_cut->pack_requirement( it_demand = lt_demand
it_catalogue = lt_catalogue ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_packs ) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lt_packs[ 1 ]-packs ).
ENDMETHOD.
METHOD lists_unknown.
DATA(lt_demand) = VALUE {{p}}if_canteen_plan=>tt_order(
( ingredient = 'COCOA' quantity = 1 ) ).
DATA(lt_catalogue) = VALUE {{p}}if_canteen_plan=>tt_master(
( ingredient = 'FLOUR' pack_size = 10 ) ).
DATA(lt_missing) = mo_cut->missing_ingredients( it_demand = lt_demand
it_catalogue = lt_catalogue ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_missing ) ).
cl_abap_unit_assert=>assert_equals( exp = 'COCOA' act = lt_missing[ 1 ] ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,42 @@
INTERFACE {{p}}if_canteen_plan PUBLIC.
TYPES ty_ingredient TYPE c LENGTH 10.
TYPES ty_quantity TYPE p LENGTH 13 DECIMALS 3.
TYPES:
BEGIN OF ty_order,
ingredient TYPE ty_ingredient,
quantity TYPE ty_quantity,
END OF ty_order.
TYPES tt_order TYPE STANDARD TABLE OF ty_order WITH EMPTY KEY.
TYPES:
BEGIN OF ty_master,
ingredient TYPE ty_ingredient,
pack_size TYPE ty_quantity,
END OF ty_master.
TYPES tt_master TYPE STANDARD TABLE OF ty_master WITH EMPTY KEY.
TYPES:
BEGIN OF ty_pack,
ingredient TYPE ty_ingredient,
packs TYPE i,
END OF ty_pack.
TYPES tt_pack TYPE STANDARD TABLE OF ty_pack WITH EMPTY KEY.
TYPES tt_ingredient TYPE STANDARD TABLE OF ty_ingredient WITH EMPTY KEY.
METHODS merge_orders
IMPORTING it_orders_a TYPE tt_order
it_orders_b TYPE tt_order
RETURNING VALUE(rt_demand) TYPE tt_order.
METHODS pack_requirement
IMPORTING it_demand TYPE tt_order
it_catalogue TYPE tt_master
RETURNING VALUE(rt_packs) TYPE tt_pack.
METHODS missing_ingredients
IMPORTING it_demand TYPE tt_order
it_catalogue TYPE tt_master
RETURNING VALUE(rt_missing) TYPE tt_ingredient.
ENDINTERFACE.

View File

@@ -0,0 +1,87 @@
# 1. Goal
A catering company runs two canteens. Each canteen sends a list of ingredient
orders for the next day. The purchasing team needs one demand list for both
canteens, the number of packs to order for each ingredient, and the ingredients
that the ingredient master data does not contain.
# 2. Open questions
None.
# 3. Context
- The interface {{P}}IF_CANTEEN_PLAN exists in package $TMP. It is active.
- The interface declares these data types:
- TY_INGREDIENT: an ingredient ID, character 10.
- TY_QUANTITY: a quantity, packed number with 3 decimals.
- TY_ORDER: a structure with the components INGREDIENT (TYPE TY_INGREDIENT)
and QUANTITY (TYPE TY_QUANTITY).
- TT_ORDER: a table type with the line type TY_ORDER.
- TY_MASTER: a structure with the components INGREDIENT (TYPE TY_INGREDIENT)
and PACK_SIZE (TYPE TY_QUANTITY).
- TT_MASTER: a table type with the line type TY_MASTER.
- TY_PACK: a structure with the components INGREDIENT (TYPE TY_INGREDIENT)
and PACKS (TYPE i).
- TT_PACK: a table type with the line type TY_PACK.
- TT_INGREDIENT: a table type with the line type TY_INGREDIENT.
- The interface declares these methods:
- MERGE_ORDERS: importing IT_ORDERS_A and IT_ORDERS_B (TYPE TT_ORDER),
returning RT_DEMAND (TYPE TT_ORDER).
- PACK_REQUIREMENT: importing IT_DEMAND (TYPE TT_ORDER) and IT_CATALOGUE
(TYPE TT_MASTER), returning RT_PACKS (TYPE TT_PACK).
- MISSING_INGREDIENTS: importing IT_DEMAND (TYPE TT_ORDER) and IT_CATALOGUE
(TYPE TT_MASTER), returning RT_MISSING (TYPE TT_INGREDIENT).
- An order list is a table of TY_ORDER. A line has an ingredient ID and a
quantity.
- The ingredient master data is a table of TY_MASTER. A line has an ingredient
ID and the pack size of one pack of this ingredient.
# 4. Contract
- Create the class {{P}}CANTEEN_PLANNER in package $TMP.
- The class is public and final and has a public constructor without parameters.
- The class implements {{P}}IF_CANTEEN_PLAN.
- Do not add other public methods.
# 5. Business rules
Apply the rules in this sequence.
MERGE_ORDERS
1. Read the two order lists. Ignore every line whose quantity is zero or less.
2. The result contains one line per ingredient that occurs in at least one of
the two order lists after rule 1.
3. The quantity of an ingredient in the result is the sum of all its quantities
in both order lists.
4. The result is sorted in ascending order of the ingredient ID.
5. If no line remains after rule 1, the result is empty.
PACK_REQUIREMENT
6. If an ingredient occurs more than once in the demand list, add its quantities
first.
7. The pack size of an ingredient is always greater than zero.
8. For each ingredient of the demand list, look for the ingredient in the
catalogue.
9. If the catalogue contains the ingredient, the number of packs is the demand
quantity divided by the pack size, rounded up to the next whole number.
10. The result contains one line per demand ingredient that the catalogue
contains. The line has the ingredient ID and the number of packs.
11. The result is sorted in ascending order of the ingredient ID.
12. If the demand list is empty, the result is empty.
MISSING_INGREDIENTS
13. The result contains the ingredient IDs of the demand list that the
catalogue does not contain.
14. Each ingredient ID occurs at most once in the result.
15. The result is sorted in ascending order of the ingredient ID.
16. If the catalogue contains every ingredient of the demand list, the result
is empty.
The catalogue contains each ingredient at most once.
# 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: do not change {{P}}IF_CANTEEN_PLAN.
# 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,52 @@
{
"id": "G0118",
"category": "C",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "INTF",
"name": "{{P}}IF_CANTEEN_PLAN",
"file": "seed/if_canteen_plan.intf.abap",
"description": "Contract of the canteen demand planner: data types and the three methods"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}CANTEEN_PLANNER",
"implements": "{{P}}IF_CANTEEN_PLAN"
}
],
"out_of_scope": [
"{{P}}IF_CANTEEN_PLAN"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}CANTEEN_HIDDEN",
"file": "hidden/canteen_hidden.clas.abap",
"description": "Hidden ABAP Unit tests for the canteen demand planner"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}CANTEEN_PLANNER",
"file": "reference/canteen_planner.clas.abap",
"description": "Canteen demand planner with sorted demand table and hashed catalogue lookup",
"testclasses_file": "reference/canteen_planner.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"table_kind",
"access_path"
]
}