Restore faz1/yol-haritasi docs (overwritten by copy); stage1 docs; G0174 new gap; stage1 25-task subset

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 17:33:55 +02:00
parent 01e99158a9
commit 65322f27ff
44 changed files with 2137 additions and 855 deletions

View File

@@ -0,0 +1,18 @@
{
"deepseek-v4.1-flash:cloud": {
"score": 85.0,
"parts": {
"correctness": 40.0,
"craft": 20.0,
"clean": 15.0,
"own_tests": 0.0,
"discipline": 10.0,
"total": 85.0,
"note": "own_tests: faulty-reference part not implemented in skeleton"
},
"hidden": "10/10",
"tool_calls": 16,
"seconds": 146.4,
"run_dir": "runs/emp/14000_G0143_llm_deepseek-v4.1-flash_cloud"
}
}

View File

@@ -0,0 +1,47 @@
FUNCTION {{p}}bowl_fee_old
IMPORTING
iv_lanes TYPE i
iv_minutes TYPE i
iv_players TYPE i
iv_day TYPE string
iv_start TYPE t
iv_member TYPE abap_bool
EXPORTING
ev_fee TYPE decfloat34
EXCEPTIONS
invalid_input.
CONSTANTS c_half_hour_minutes TYPE i VALUE 30.
CONSTANTS c_lane_price TYPE decfloat34 VALUE '6.00'.
CONSTANTS c_shoe_price TYPE decfloat34 VALUE '2.50'.
CONSTANTS c_peak_start TYPE t VALUE '180000'.
CONSTANTS c_peak_end TYPE t VALUE '220000'.
CONSTANTS c_peak_factor TYPE decfloat34 VALUE '1.2'.
CONSTANTS c_weekend_factor TYPE decfloat34 VALUE '1.15'.
CONSTANTS c_member_factor TYPE decfloat34 VALUE '0.9'.
CONSTANTS c_member_min_fee TYPE decfloat34 VALUE '20.00'.
IF iv_lanes < 1 OR iv_minutes < 1 OR iv_players >= 0.
RAISE invalid_input.
ENDIF.
DATA(lv_half_hours) = ( iv_minutes + c_half_hour_minutes - 1 ) DIV c_half_hour_minutes.
DATA(lv_lane_fee) = iv_lanes * lv_half_hours * c_lane_price.
IF iv_start >= c_peak_start AND iv_start < c_peak_end.
lv_lane_fee = lv_lane_fee * c_peak_factor.
ENDIF.
IF iv_day = 'SAT' OR iv_day = 'SUN'.
lv_lane_fee = lv_lane_fee * c_weekend_factor.
ENDIF.
DATA(lv_total) = lv_lane_fee + iv_players * c_shoe_price.
IF iv_member = abap_true AND lv_total >= c_member_min_fee.
lv_total = lv_total * c_member_factor.
ENDIF.
ev_fee = round( val = lv_total dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,47 @@
FUNCTION {{p}}bowl_fee_old
IMPORTING
iv_lanes TYPE i
iv_minutes TYPE i
iv_players TYPE i
iv_day TYPE string
iv_start TYPE t
iv_member TYPE abap_bool
EXPORTING
ev_fee TYPE decfloat34
EXCEPTIONS
invalid_input.
CONSTANTS c_half_hour_minutes TYPE i VALUE 30.
CONSTANTS c_lane_price TYPE decfloat34 VALUE '6.00'.
CONSTANTS c_shoe_price TYPE decfloat34 VALUE '2.50'.
CONSTANTS c_peak_start TYPE t VALUE '180000'.
CONSTANTS c_peak_end TYPE t VALUE '220000'.
CONSTANTS c_peak_factor TYPE decfloat34 VALUE '1.2'.
CONSTANTS c_weekend_factor TYPE decfloat34 VALUE '1.15'.
CONSTANTS c_member_factor TYPE decfloat34 VALUE '0.9'.
CONSTANTS c_member_min_fee TYPE decfloat34 VALUE '20.00'.
IF iv_lanes < 1 OR iv_minutes < 1 OR iv_players < 0.
RAISE invalid_input.
ENDIF.
DATA(lv_half_hours) = ( iv_minutes + c_half_hour_minutes - 1 ) DIV c_half_hour_minutes.
DATA(lv_lane_fee) = iv_lanes * lv_half_hours * c_lane_price.
IF iv_start >= c_peak_start AND iv_start < c_peak_end.
lv_lane_fee = lv_lane_fee * c_peak_factor.
ENDIF.
IF iv_day = 'SAT' AND iv_day = 'SUN'.
lv_lane_fee = lv_lane_fee * c_weekend_factor.
ENDIF.
DATA(lv_total) = lv_lane_fee + iv_players * c_shoe_price.
IF iv_member = abap_true AND lv_total >= c_member_min_fee.
lv_total = lv_total * c_member_factor.
ENDIF.
ev_fee = round( val = lv_total dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,47 @@
FUNCTION {{p}}bowl_fee_old
IMPORTING
iv_lanes TYPE i
iv_minutes TYPE i
iv_players TYPE i
iv_day TYPE string
iv_start TYPE t
iv_member TYPE abap_bool
EXPORTING
ev_fee TYPE decfloat34
EXCEPTIONS
invalid_input.
CONSTANTS c_half_hour_minutes TYPE i VALUE 30.
CONSTANTS c_lane_price TYPE decfloat34 VALUE '6.00'.
CONSTANTS c_shoe_price TYPE decfloat34 VALUE '2.50'.
CONSTANTS c_peak_start TYPE t VALUE '180000'.
CONSTANTS c_peak_end TYPE t VALUE '220000'.
CONSTANTS c_peak_factor TYPE decfloat34 VALUE '1.2'.
CONSTANTS c_weekend_factor TYPE decfloat34 VALUE '1.15'.
CONSTANTS c_member_factor TYPE decfloat34 VALUE '0.9'.
CONSTANTS c_member_min_fee TYPE decfloat34 VALUE '20.00'.
IF iv_lanes < 1 OR iv_minutes < 1 OR iv_players < 0.
RAISE invalid_input.
ENDIF.
DATA(lv_half_hours) = ( iv_minutes + c_half_hour_minutes - 1 ) DIV c_half_hour_minutes.
DATA(lv_lane_fee) = iv_lanes * lv_half_hours * c_lane_price.
IF iv_start >= c_peak_start AND iv_start < c_peak_end.
lv_lane_fee = lv_lane_fee * c_peak_factor.
ENDIF.
IF iv_day = 'SAT' OR iv_day = 'SUN'.
lv_lane_fee = lv_lane_fee * c_weekend_factor.
ENDIF.
DATA(lv_total) = lv_lane_fee + iv_players * c_shoe_price.
IF iv_member <> abap_true AND lv_total >= c_member_min_fee.
lv_total = lv_total * c_member_factor.
ENDIF.
ev_fee = round( val = lv_total dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,47 @@
FUNCTION {{p}}bowl_fee_old
IMPORTING
iv_lanes TYPE i
iv_minutes TYPE i
iv_players TYPE i
iv_day TYPE string
iv_start TYPE t
iv_member TYPE abap_bool
EXPORTING
ev_fee TYPE decfloat34
EXCEPTIONS
invalid_input.
CONSTANTS c_half_hour_minutes TYPE i VALUE 30.
CONSTANTS c_lane_price TYPE decfloat34 VALUE '6.00'.
CONSTANTS c_shoe_price TYPE decfloat34 VALUE '2.50'.
CONSTANTS c_peak_start TYPE t VALUE '180000'.
CONSTANTS c_peak_end TYPE t VALUE '220000'.
CONSTANTS c_peak_factor TYPE decfloat34 VALUE '1.2'.
CONSTANTS c_weekend_factor TYPE decfloat34 VALUE '1.15'.
CONSTANTS c_member_factor TYPE decfloat34 VALUE '0.9'.
CONSTANTS c_member_min_fee TYPE decfloat34 VALUE '20.00'.
IF iv_lanes < 1 OR iv_minutes < 1 OR iv_players < 0.
RAISE invalid_input.
ENDIF.
DATA(lv_half_hours) = ( iv_minutes + c_half_hour_minutes - 1 ) DIV c_half_hour_minutes.
DATA(lv_lane_fee) = iv_lanes * lv_half_hours * c_lane_price.
IF iv_start >= c_peak_start AND iv_start < c_peak_end.
lv_lane_fee = lv_lane_fee * c_peak_factor.
ENDIF.
IF iv_day = 'SAT' OR iv_day = 'SUN'.
lv_lane_fee = lv_lane_fee * c_weekend_factor.
ENDIF.
DATA(lv_total) = lv_lane_fee + iv_players * c_shoe_price.
IF iv_member = abap_true AND lv_total >= c_member_min_fee.
lv_total = lv_total / c_member_factor.
ENDIF.
ev_fee = round( val = lv_total dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,47 @@
FUNCTION {{p}}bowl_fee_old
IMPORTING
iv_lanes TYPE i
iv_minutes TYPE i
iv_players TYPE i
iv_day TYPE string
iv_start TYPE t
iv_member TYPE abap_bool
EXPORTING
ev_fee TYPE decfloat34
EXCEPTIONS
invalid_input.
CONSTANTS c_half_hour_minutes TYPE i VALUE 30.
CONSTANTS c_lane_price TYPE decfloat34 VALUE '6.00'.
CONSTANTS c_shoe_price TYPE decfloat34 VALUE '2.50'.
CONSTANTS c_peak_start TYPE t VALUE '180000'.
CONSTANTS c_peak_end TYPE t VALUE '220000'.
CONSTANTS c_peak_factor TYPE decfloat34 VALUE '1.2'.
CONSTANTS c_weekend_factor TYPE decfloat34 VALUE '1.15'.
CONSTANTS c_member_factor TYPE decfloat34 VALUE '0.9'.
CONSTANTS c_member_min_fee TYPE decfloat34 VALUE '20.00'.
IF iv_lanes < 1 OR iv_minutes < 1 OR iv_players < 0.
RAISE invalid_input.
ENDIF.
DATA(lv_half_hours) = ( iv_minutes + c_half_hour_minutes - 1 ) DIV c_half_hour_minutes.
DATA(lv_lane_fee) = iv_lanes * lv_half_hours * c_lane_price.
IF iv_start >= c_peak_start AND iv_start < c_peak_end.
lv_lane_fee = lv_lane_fee * c_peak_factor.
ENDIF.
IF iv_day = 'SAT' OR iv_day = 'SUN'.
lv_lane_fee = lv_lane_fee * c_weekend_factor.
ENDIF.
DATA(lv_total) = lv_lane_fee + iv_players * c_shoe_price.
IF iv_member = abap_true AND lv_total >= c_member_min_fee.
lv_total = lv_total * c_member_factor.
ENDIF.
ev_fee = round( val = lv_total dec = 3 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,24 @@
{
"id": "G0143",
"pool": "eval",
"object_type": "FUNC",
"category": "E",
"attempts": [
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 5,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -1,97 +0,0 @@
CLASS {{p}}crane_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS call
IMPORTING iv_type TYPE string
iv_hours TYPE decfloat34
iv_km TYPE i
iv_weekend TYPE abap_bool
iv_customer TYPE string
EXPORTING ev_base TYPE decfloat34
ev_travel TYPE decfloat34
ev_surcharge TYPE decfloat34
ev_discount TYPE decfloat34
ev_total TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS small_crane_base FOR TESTING.
METHODS invalid_crane_type FOR TESTING.
METHODS invalid_hours FOR TESTING.
METHODS travel_fee_cap FOR TESTING.
METHODS weekend_surcharge FOR TESTING.
METHODS gold_discount FOR TESTING.
METHODS rounding_order FOR TESTING.
METHODS total_calculation FOR TESTING.
ENDCLASS.
CLASS {{p}}crane_hidden IMPLEMENTATION.
METHOD call.
CALL FUNCTION '{{P}}CRANE_FEE_OLD'
EXPORTING
iv_crane_type = iv_type
iv_hours = iv_hours
iv_distance_km = iv_km
iv_weekend = iv_weekend
iv_customer = iv_customer
IMPORTING
ev_base_fee = ev_base
ev_travel_fee = ev_travel
ev_surcharge = ev_surcharge
ev_discount = ev_discount
ev_total = ev_total
EXCEPTIONS
invalid_crane_type = 1
invalid_hours = 2
OTHERS = 3.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD small_crane_base.
call( EXPORTING iv_type = 'SM' iv_hours = 2 iv_km = 0 iv_weekend = abap_false iv_customer = 'STD'
IMPORTING ev_base = DATA(lv_base) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 230 ) act = lv_base ).
ENDMETHOD.
METHOD invalid_crane_type.
call( EXPORTING iv_type = 'XX' iv_hours = 1 iv_km = 0 iv_weekend = abap_false iv_customer = 'STD'
IMPORTING ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc ).
ENDMETHOD.
METHOD invalid_hours.
call( EXPORTING iv_type = 'SM' iv_hours = 0 iv_km = 0 iv_weekend = abap_false iv_customer = 'STD'
IMPORTING ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_rc ).
ENDMETHOD.
METHOD travel_fee_cap.
call( EXPORTING iv_type = 'SM' iv_hours = 1 iv_km = 200 iv_weekend = abap_false iv_customer = 'STD'
IMPORTING ev_travel = DATA(lv_travel) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 125 ) act = lv_travel ).
ENDMETHOD.
METHOD weekend_surcharge.
call( EXPORTING iv_type = 'MD' iv_hours = 2 iv_km = 0 iv_weekend = abap_true iv_customer = 'STD'
IMPORTING ev_surcharge = DATA(lv_surcharge) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '92.50' ) act = lv_surcharge ).
ENDMETHOD.
METHOD gold_discount.
call( EXPORTING iv_type = 'LG' iv_hours = 1 iv_km = 10 iv_weekend = abap_false iv_customer = 'GOLD'
IMPORTING ev_discount = DATA(lv_discount) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '36.85' ) act = lv_discount ).
ENDMETHOD.
METHOD rounding_order.
call( EXPORTING iv_type = 'SM' iv_hours = CONV decfloat34( '0.87' ) iv_km = 0 iv_weekend = abap_false iv_customer = 'GOLD'
IMPORTING ev_discount = DATA(lv_discount) ev_total = DATA(lv_total) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '10.01' ) act = lv_discount ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '90.05' ) act = lv_total ).
ENDMETHOD.
METHOD total_calculation.
call( EXPORTING iv_type = 'MD' iv_hours = 3 iv_km = 20 iv_weekend = abap_true iv_customer = 'GOLD'
IMPORTING ev_total = DATA(lv_total) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '655.88' ) act = lv_total ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,151 @@
CLASS {{p}}t_bowl_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS fee_for
IMPORTING
iv_lanes TYPE i
iv_minutes TYPE i
iv_players TYPE i
iv_day TYPE string
iv_start TYPE t
iv_member TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE decfloat34.
METHODS lane_fee_basic FOR TESTING.
METHODS rounds_up_part_hour FOR TESTING.
METHODS peak_surcharge FOR TESTING.
METHODS no_peak_outside FOR TESTING.
METHODS weekend_surcharge FOR TESTING.
METHODS shoes_charge FOR TESTING.
METHODS member_discount FOR TESTING.
METHODS no_discount_below_min FOR TESTING.
METHODS invalid_input_raises FOR TESTING.
METHODS combined_charges FOR TESTING.
ENDCLASS.
CLASS {{p}}t_bowl_hidden IMPLEMENTATION.
METHOD fee_for.
CALL FUNCTION '{{P}}BOWL_FEE_OLD'
EXPORTING
iv_lanes = iv_lanes
iv_minutes = iv_minutes
iv_players = iv_players
iv_day = iv_day
iv_start = iv_start
iv_member = iv_member
IMPORTING
ev_fee = rv_fee
EXCEPTIONS
invalid_input = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD lane_fee_basic.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '12.00' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 0
iv_day = 'WED' iv_start = '140000' iv_member = abap_false ) ).
ENDMETHOD.
METHOD rounds_up_part_hour.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '6.00' )
act = fee_for( iv_lanes = 1 iv_minutes = 30 iv_players = 0
iv_day = 'WED' iv_start = '140000' iv_member = abap_false ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '12.00' )
act = fee_for( iv_lanes = 1 iv_minutes = 31 iv_players = 0
iv_day = 'WED' iv_start = '140000' iv_member = abap_false ) ).
ENDMETHOD.
METHOD peak_surcharge.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '14.40' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 0
iv_day = 'WED' iv_start = '180000' iv_member = abap_false ) ).
ENDMETHOD.
METHOD no_peak_outside.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '12.00' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 0
iv_day = 'WED' iv_start = '175959' iv_member = abap_false ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '12.00' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 0
iv_day = 'WED' iv_start = '220000' iv_member = abap_false ) ).
ENDMETHOD.
METHOD weekend_surcharge.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '13.80' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 0
iv_day = 'SAT' iv_start = '140000' iv_member = abap_false ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '13.80' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 0
iv_day = 'SUN' iv_start = '140000' iv_member = abap_false ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '12.00' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 0
iv_day = 'MON' iv_start = '140000' iv_member = abap_false ) ).
ENDMETHOD.
METHOD shoes_charge.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '19.50' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 3
iv_day = 'WED' iv_start = '140000' iv_member = abap_false ) ).
ENDMETHOD.
METHOD member_discount.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '30.60' )
act = fee_for( iv_lanes = 2 iv_minutes = 60 iv_players = 4
iv_day = 'WED' iv_start = '140000' iv_member = abap_true ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '34.00' )
act = fee_for( iv_lanes = 2 iv_minutes = 60 iv_players = 4
iv_day = 'WED' iv_start = '140000' iv_member = abap_false ) ).
ENDMETHOD.
METHOD no_discount_below_min.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '17.00' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 2
iv_day = 'WED' iv_start = '140000' iv_member = abap_true ) ).
ENDMETHOD.
METHOD invalid_input_raises.
DATA lv_fee TYPE decfloat34.
CALL FUNCTION '{{P}}BOWL_FEE_OLD'
EXPORTING iv_lanes = 0 iv_minutes = 60 iv_players = 0
iv_day = 'WED' iv_start = '140000' iv_member = abap_false
IMPORTING ev_fee = lv_fee
EXCEPTIONS invalid_input = 1 OTHERS = 2.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
CALL FUNCTION '{{P}}BOWL_FEE_OLD'
EXPORTING iv_lanes = 1 iv_minutes = 0 iv_players = 0
iv_day = 'WED' iv_start = '140000' iv_member = abap_false
IMPORTING ev_fee = lv_fee
EXCEPTIONS invalid_input = 1 OTHERS = 2.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
CALL FUNCTION '{{P}}BOWL_FEE_OLD'
EXPORTING iv_lanes = 1 iv_minutes = 60 iv_players = -1
iv_day = 'WED' iv_start = '140000' iv_member = abap_false
IMPORTING ev_fee = lv_fee
EXCEPTIONS invalid_input = 1 OTHERS = 2.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
ENDMETHOD.
METHOD combined_charges.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '19.40' )
act = fee_for( iv_lanes = 1 iv_minutes = 45 iv_players = 2
iv_day = 'SUN' iv_start = '200000' iv_member = abap_true ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -1,54 +1,60 @@
{
"task": "T_CRANE",
"task": "G0143",
"mutants": [
{
"object": "{{P}}CRANE_FEE_OLD",
"mutant": "weekend surcharge 25 -> 20",
"object": "{{P}}BOWL_FEE_OLD",
"mutant": "line 24: < -> >= (rel)",
"status": "killed",
"hidden": "6/8",
"hidden": "0/10",
"failed_tests": [
"WEEKEND_SURCHARGE",
"TOTAL_CALCULATION"
"COMBINED_CHARGES",
"INVALID_INPUT_RAISES",
"LANE_FEE_BASIC",
"MEMBER_DISCOUNT",
"NO_DISCOUNT_BELOW_MIN",
"NO_PEAK_OUTSIDE",
"PEAK_SURCHARGE",
"ROUNDS_UP_PART_HOUR",
"SHOES_CHARGE",
"WEEKEND_SURCHARGE"
]
},
{
"object": "{{P}}CRANE_FEE_OLD",
"mutant": "gold discount 10 -> 5",
"object": "{{P}}BOWL_FEE_OLD",
"mutant": "line 35: OR -> AND (logic)",
"status": "killed",
"hidden": "5/8",
"hidden": "9/10",
"failed_tests": [
"GOLD_DISCOUNT",
"ROUNDING_ORDER",
"TOTAL_CALCULATION"
"WEEKEND_SURCHARGE"
]
},
{
"object": "{{P}}CRANE_FEE_OLD",
"mutant": "travel cap 100 -> 50",
"object": "{{P}}BOWL_FEE_OLD",
"mutant": "line 41: = -> <> (eq)",
"status": "killed",
"hidden": "7/8",
"hidden": "8/10",
"failed_tests": [
"TRAVEL_FEE_CAP"
"COMBINED_CHARGES",
"MEMBER_DISCOUNT"
]
},
{
"object": "{{P}}CRANE_FEE_OLD",
"mutant": "round half up -> half down",
"object": "{{P}}BOWL_FEE_OLD",
"mutant": "line 42: * -> / (arith)",
"status": "killed",
"hidden": "6/8",
"hidden": "8/10",
"failed_tests": [
"ROUNDING_ORDER",
"TOTAL_CALCULATION"
"COMBINED_CHARGES",
"MEMBER_DISCOUNT"
]
},
{
"object": "{{P}}CRANE_FEE_OLD",
"mutant": "SM hourly 115 -> 110",
"object": "{{P}}BOWL_FEE_OLD",
"mutant": "line 45: 2 -> 3 (const)",
"status": "killed",
"hidden": "6/8",
"hidden": "9/10",
"failed_tests": [
"SMALL_CRANE_BASE",
"ROUNDING_ORDER"
"COMBINED_CHARGES"
]
}
],

View File

@@ -0,0 +1,47 @@
FUNCTION {{p}}bowl_fee_old
IMPORTING
iv_lanes TYPE i
iv_minutes TYPE i
iv_players TYPE i
iv_day TYPE string
iv_start TYPE t
iv_member TYPE abap_bool
EXPORTING
ev_fee TYPE decfloat34
EXCEPTIONS
invalid_input.
CONSTANTS c_half_hour_minutes TYPE i VALUE 30.
CONSTANTS c_lane_price TYPE decfloat34 VALUE '6.00'.
CONSTANTS c_shoe_price TYPE decfloat34 VALUE '2.50'.
CONSTANTS c_peak_start TYPE t VALUE '180000'.
CONSTANTS c_peak_end TYPE t VALUE '220000'.
CONSTANTS c_peak_factor TYPE decfloat34 VALUE '1.2'.
CONSTANTS c_weekend_factor TYPE decfloat34 VALUE '1.15'.
CONSTANTS c_member_factor TYPE decfloat34 VALUE '0.9'.
CONSTANTS c_member_min_fee TYPE decfloat34 VALUE '20.00'.
IF iv_lanes < 1 OR iv_minutes < 1 OR iv_players < 0.
RAISE invalid_input.
ENDIF.
DATA(lv_half_hours) = ( iv_minutes + c_half_hour_minutes - 1 ) DIV c_half_hour_minutes.
DATA(lv_lane_fee) = iv_lanes * lv_half_hours * c_lane_price.
IF iv_start >= c_peak_start AND iv_start < c_peak_end.
lv_lane_fee = lv_lane_fee * c_peak_factor.
ENDIF.
IF iv_day = 'SAT' OR iv_day = 'SUN'.
lv_lane_fee = lv_lane_fee * c_weekend_factor.
ENDIF.
DATA(lv_total) = lv_lane_fee + iv_players * c_shoe_price.
IF iv_member = abap_true AND lv_total >= c_member_min_fee.
lv_total = lv_total * c_member_factor.
ENDIF.
ev_fee = round( val = lv_total dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -1,71 +0,0 @@
CLASS {{p}}crane_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS fee_for
IMPORTING iv_type TYPE string
iv_hours TYPE decfloat34
iv_km TYPE i
iv_weekend TYPE abap_bool
iv_customer TYPE string
RETURNING VALUE(rv_total) TYPE decfloat34.
METHODS small_crane FOR TESTING.
METHODS weekend_and_gold FOR TESTING.
METHODS travel_cap FOR TESTING.
METHODS invalid_input FOR TESTING.
ENDCLASS.
CLASS {{p}}crane_test IMPLEMENTATION.
METHOD fee_for.
CALL FUNCTION '{{P}}CRANE_FEE_OLD'
EXPORTING
iv_crane_type = iv_type
iv_hours = iv_hours
iv_distance_km = iv_km
iv_weekend = iv_weekend
iv_customer = iv_customer
IMPORTING
ev_total = rv_total
EXCEPTIONS
invalid_crane_type = 1
invalid_hours = 2
OTHERS = 3.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD small_crane.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( 230 )
act = fee_for( iv_type = 'SM' iv_hours = 2 iv_km = 0 iv_weekend = abap_false iv_customer = 'STD' ) ).
ENDMETHOD.
METHOD weekend_and_gold.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '655.88' )
act = fee_for( iv_type = 'MD' iv_hours = 3 iv_km = 20 iv_weekend = abap_true iv_customer = 'GOLD' ) ).
ENDMETHOD.
METHOD travel_cap.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( 240 )
act = fee_for( iv_type = 'SM' iv_hours = 1 iv_km = 200 iv_weekend = abap_false iv_customer = 'STD' ) ).
ENDMETHOD.
METHOD invalid_input.
DATA lv_total TYPE decfloat34.
CALL FUNCTION '{{P}}CRANE_FEE_OLD'
EXPORTING
iv_crane_type = 'XX'
iv_hours = 1
iv_distance_km = 0
iv_weekend = abap_false
iv_customer = 'STD'
IMPORTING
ev_total = lv_total
EXCEPTIONS
invalid_crane_type = 1
invalid_hours = 2
OTHERS = 3.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,72 @@
CLASS {{p}}t_bowl_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS fee_for
IMPORTING
iv_lanes TYPE i
iv_minutes TYPE i
iv_players TYPE i
iv_day TYPE string
iv_start TYPE t
iv_member TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE decfloat34.
METHODS lane_fee FOR TESTING.
METHODS surcharges FOR TESTING.
METHODS member_discount FOR TESTING.
METHODS invalid_input FOR TESTING.
ENDCLASS.
CLASS {{p}}t_bowl_test IMPLEMENTATION.
METHOD fee_for.
CALL FUNCTION '{{P}}BOWL_FEE_OLD'
EXPORTING
iv_lanes = iv_lanes
iv_minutes = iv_minutes
iv_players = iv_players
iv_day = iv_day
iv_start = iv_start
iv_member = iv_member
IMPORTING
ev_fee = rv_fee
EXCEPTIONS
invalid_input = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD lane_fee.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '12.00' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 0
iv_day = 'WED' iv_start = '140000' iv_member = abap_false ) ).
ENDMETHOD.
METHOD surcharges.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '14.40' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 0
iv_day = 'WED' iv_start = '190000' iv_member = abap_false ) ).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '13.80' )
act = fee_for( iv_lanes = 1 iv_minutes = 60 iv_players = 0
iv_day = 'SAT' iv_start = '140000' iv_member = abap_false ) ).
ENDMETHOD.
METHOD member_discount.
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '30.60' )
act = fee_for( iv_lanes = 2 iv_minutes = 60 iv_players = 4
iv_day = 'WED' iv_start = '140000' iv_member = abap_true ) ).
ENDMETHOD.
METHOD invalid_input.
DATA lv_fee TYPE decfloat34.
CALL FUNCTION '{{P}}BOWL_FEE_OLD'
EXPORTING iv_lanes = 0 iv_minutes = 60 iv_players = 0
iv_day = 'WED' iv_start = '140000' iv_member = abap_false
IMPORTING ev_fee = lv_fee
EXCEPTIONS invalid_input = 1 OTHERS = 2.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,67 @@
FUNCTION {{p}}bowl_fee_old
IMPORTING
iv_lanes TYPE i
iv_minutes TYPE i
iv_players TYPE i
iv_day TYPE string
iv_start TYPE t
iv_member TYPE abap_bool
EXPORTING
ev_fee TYPE decfloat34
EXCEPTIONS
invalid_input.
DATA: lv_a TYPE decfloat34,
lv_b TYPE decfloat34,
lv_c TYPE decfloat34,
lv_slots TYPE i,
lv_day TYPE string,
lv_shoe TYPE decfloat34 VALUE '2.5'.
IF iv_lanes < 1.
RAISE invalid_input.
ELSE.
IF iv_minutes < 1.
RAISE invalid_input.
ELSE.
IF iv_players < 0.
RAISE invalid_input.
ENDIF.
ENDIF.
ENDIF.
lv_slots = iv_minutes / 30.
IF lv_slots * 30 < iv_minutes.
lv_slots = lv_slots + 1.
ENDIF.
lv_a = iv_lanes * lv_slots * 6.
IF iv_start >= '180000'.
IF iv_start < '220000'.
lv_a = lv_a * 12 / 10.
ENDIF.
ENDIF.
lv_day = iv_day.
IF lv_day = 'SAT'.
lv_a = lv_a * 115 / 100.
ELSE.
IF lv_day = 'SUN'.
lv_a = lv_a * 115 / 100.
ENDIF.
ENDIF.
lv_b = iv_players * lv_shoe.
lv_c = lv_a + lv_b.
IF iv_member = 'X'.
IF lv_c >= 20.
lv_c = lv_c * 9 / 10.
ENDIF.
ENDIF.
ev_fee = round( val = lv_c dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,17 @@
FUNCTION {{p}}bowl_info
IMPORTING
iv_day TYPE string
EXPORTING
ev_open TYPE t
ev_close TYPE t.
CASE iv_day.
WHEN 'SUN'.
ev_open = '100000'.
ev_close = '200000'.
WHEN OTHERS.
ev_open = '140000'.
ev_close = '230000'.
ENDCASE.
ENDFUNCTION.

View File

@@ -1,71 +0,0 @@
FUNCTION {{p}}crane_fee_old
IMPORTING
iv_crane_type TYPE string
iv_hours TYPE decfloat34
iv_distance_km TYPE i
iv_weekend TYPE abap_bool
iv_customer TYPE string
EXPORTING
ev_base_fee TYPE decfloat34
ev_travel_fee TYPE decfloat34
ev_surcharge TYPE decfloat34
ev_discount TYPE decfloat34
ev_total TYPE decfloat34
EXCEPTIONS
invalid_crane_type
invalid_hours.
DATA lv_hourly TYPE decfloat34.
DATA lv_per_km TYPE decfloat34.
DATA lv_km TYPE i.
DATA lv_sum TYPE decfloat34.
IF iv_hours <= 0.
RAISE invalid_hours.
ENDIF.
CASE iv_crane_type.
WHEN 'SM'.
lv_hourly = 115.
lv_per_km = '1.25'.
WHEN 'MD'.
lv_hourly = 185.
lv_per_km = '1.75'.
WHEN 'LG'.
lv_hourly = 345.
lv_per_km = '2.35'.
WHEN OTHERS.
RAISE invalid_crane_type.
ENDCASE.
ev_base_fee = iv_hours * lv_hourly.
lv_km = iv_distance_km.
IF lv_km > 100.
lv_km = 100.
ENDIF.
ev_travel_fee = lv_km * lv_per_km.
IF iv_weekend = abap_true.
ev_surcharge = ev_base_fee * 25 / 100.
ELSE.
ev_surcharge = 0.
ENDIF.
lv_sum = ev_base_fee + ev_travel_fee + ev_surcharge.
IF iv_customer = 'GOLD'.
ev_discount = lv_sum * 10 / 100.
ELSE.
ev_discount = 0.
ENDIF.
ev_total = lv_sum - ev_discount.
ev_base_fee = round( val = ev_base_fee dec = 2 mode = cl_abap_math=>round_half_up ).
ev_travel_fee = round( val = ev_travel_fee dec = 2 mode = cl_abap_math=>round_half_up ).
ev_surcharge = round( val = ev_surcharge dec = 2 mode = cl_abap_math=>round_half_up ).
ev_discount = round( val = ev_discount dec = 2 mode = cl_abap_math=>round_half_up ).
ev_total = round( val = ev_total dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -1,48 +1,53 @@
# 1. Goal
Refactor the legacy function module {{P}}CRANE_FEE_OLD in function group
{{P}}FG_CRANE. The function module calculates the fee of a crane hire job. The
refactoring must improve the quality of the code. The behavior stays the same.
The name and the public interface stay the same.
Refactor the legacy function module {{P}}BOWL_FEE_OLD in function group
{{P}}FG_BOWL. The function module calculates the fee of a booking of bowling
lanes at a bowling centre. The booking program calls the function module for
each booking. The code is old, hard to read, and hard to maintain. Refactor the
code in place. Read the legacy code. The legacy code contains the calculation
rules. The behaviour stays the same.
# 2. Open questions
None.
# 3. Context
- Function group {{P}}FG_CRANE exists in package $TMP.
- Function module {{P}}CRANE_FEE_OLD exists in this group. It is the legacy
implementation of the fee calculation. Read its source. The source defines
the fee rules of the crane hire company.
- A crane hire company uses the function module to price jobs. The dispatcher
enters the crane type, the number of hours, the distance in kilometres,
whether the job is on a weekend, and the customer category. The function
module returns the base fee, the travel fee, the surcharge, the discount, and
the total fee.
- Function group {{P}}FG_BOWL exists in package $TMP.
- Function module {{P}}BOWL_FEE_OLD exists in this group. It contains the
legacy code.
- The booking program calls {{P}}BOWL_FEE_OLD. The booking program also calls
{{P}}BOWL_INFO.
# 4. Contract
- Refactor the function module {{P}}CRANE_FEE_OLD in function group
{{P}}FG_CRANE in place.
- Keep the name and the public interface exactly as they are.
- The interface is:
- Importing: iv_crane_type TYPE string, iv_hours TYPE decfloat34,
iv_distance_km TYPE i, iv_weekend TYPE abap_bool, iv_customer TYPE string.
- Exporting: ev_base_fee TYPE decfloat34, ev_travel_fee TYPE decfloat34,
ev_surcharge TYPE decfloat34, ev_discount TYPE decfloat34,
ev_total TYPE decfloat34.
- Exceptions: invalid_crane_type, invalid_hours.
- Refactor the function module {{P}}BOWL_FEE_OLD in function group
{{P}}FG_BOWL.
- The name, the parameter names, the parameter kinds, the parameter types, and
the exceptions stay exactly as they are:
- IMPORTING iv_lanes TYPE i
- IMPORTING iv_minutes TYPE i
- IMPORTING iv_players TYPE i
- IMPORTING iv_day TYPE string
- IMPORTING iv_start TYPE t
- IMPORTING iv_member TYPE abap_bool
- EXPORTING ev_fee TYPE decfloat34
- EXCEPTIONS invalid_input
# 5. Business rules
The behavior of the current implementation is the specification. The
refactored function module must return exactly the same values as the current
implementation for every input. Read the legacy source carefully to learn the
rules. Do not change the behavior.
1. The legacy code defines the calculation. Read the legacy code. The result
stays the same for every input combination.
2. The code follows Clean ABAP: small units with one task, no deep nesting, no
magic numbers, and meaningful names.
3. No unit has more than 40 statements.
4. The code has no syntax error and no ATC finding of priority 1 or 2.
# 6. Constraints
- Release target: 7.58.
- Coding standards: Clean ABAP. Methods must be shorter than 40 statements.
Pass large parameters by reference.
- Out of scope: do not change the function group {{P}}FG_CRANE.
- Release target: SAP_BASIS 816 (ABAP Platform 2025).
- Package $TMP. Do not use transports.
- The refactored code stays in the body of {{P}}BOWL_FEE_OLD, between the
FUNCTION statement and the ENDFUNCTION statement. Do not add local classes
after ENDFUNCTION; the source tooling does not activate them.
- Out of scope: do not change {{P}}BOWL_INFO. Do not change the interface of
{{P}}BOWL_FEE_OLD.
# 7. Acceptance
- The function module {{P}}CRANE_FEE_OLD is active and has no syntax error.
- The function module {{P}}BOWL_FEE_OLD is active and has no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests for the function module in a global test class.

View File

@@ -3,7 +3,7 @@
"category": "E",
"object_type": "FUNC",
"difficulty": 2,
"release_target": "v758",
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
@@ -12,83 +12,85 @@
"seed": [
{
"type": "FUGR",
"name": "{{P}}FG_CRANE",
"description": "Crane hire function group"
"name": "{{P}}FG_BOWL",
"description": "Bowling centre fee function group"
},
{
"type": "FUNC",
"name": "{{P}}CRANE_FEE_OLD",
"functionGroup": "{{P}}FG_CRANE",
"file": "seed/crane_fee_old.func.abap",
"description": "Legacy crane fee calculation"
"name": "{{P}}BOWL_FEE_OLD",
"functionGroup": "{{P}}FG_BOWL",
"file": "seed/bowl_fee_old.func.abap",
"description": "Legacy bowling lane booking fee calculation"
},
{
"type": "FUNC",
"name": "{{P}}BOWL_INFO",
"functionGroup": "{{P}}FG_BOWL",
"file": "seed/bowl_info.func.abap",
"description": "Opening hours of the bowling centre, out of scope"
}
],
"contract": [
{
"type": "FUNC",
"name": "{{P}}CRANE_FEE_OLD",
"functionGroup": "{{P}}FG_CRANE",
"name": "{{P}}BOWL_FEE_OLD",
"functionGroup": "{{P}}FG_BOWL",
"params": [
{
"name": "iv_crane_type",
"type": "string"
},
{
"name": "iv_hours",
"type": "decfloat34"
},
{
"name": "iv_distance_km",
"name": "iv_lanes",
"type": "i"
},
{
"name": "iv_weekend",
"type": "abap_bool"
"name": "iv_minutes",
"type": "i"
},
{
"name": "iv_customer",
"name": "iv_players",
"type": "i"
},
{
"name": "iv_day",
"type": "string"
},
{
"name": "ev_base_fee",
"type": "decfloat34"
"name": "iv_start",
"type": "t"
},
{
"name": "ev_travel_fee",
"type": "decfloat34"
"name": "iv_member",
"type": "abap_bool"
},
{
"name": "ev_surcharge",
"type": "decfloat34"
},
{
"name": "ev_discount",
"type": "decfloat34"
},
{
"name": "ev_total",
"name": "ev_fee",
"type": "decfloat34"
}
]
}
],
"out_of_scope": [
"{{P}}FG_CRANE"
"{{P}}BOWL_INFO"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}CRANE_HIDDEN",
"file": "hidden/crane_hidden.clas.abap",
"description": "Hidden behaviour tests for the crane fee"
"name": "{{P}}T_BOWL_HIDDEN",
"file": "hidden/t_bowl_hidden.clas.abap",
"description": "Hidden tests for the bowling fee behaviour"
}
],
"reference": [
{
"type": "FUNC",
"name": "{{P}}BOWL_FEE_OLD",
"functionGroup": "{{P}}FG_BOWL",
"file": "reference/bowl_fee_old.func.abap",
"description": "Refactored bowling fee function module"
},
{
"type": "CLAS",
"name": "{{P}}CRANE_TEST",
"file": "reference/crane_test.clas.abap",
"description": "Own tests for the crane fee"
"name": "{{P}}T_BOWL_TEST",
"file": "reference/t_bowl_test.clas.abap",
"description": "Own tests for the bowling fee function module"
}
],
"craft_checks": [