Pipeline controller: plan 2 (hard +, error +50 %), backlog throttle, 2 trajectory workers, stop rules, summaries every 50; budget reserve

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 13:35:54 +02:00
parent 1c4667a0fc
commit 13360292dd
781 changed files with 50211 additions and 22 deletions

View File

@@ -0,0 +1,109 @@
CLASS {{p}}glasses_pricer DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_lens TYPE c LENGTH 1.
TYPES ty_coat TYPE c LENGTH 1.
METHODS price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_lens
iv_coat TYPE ty_coat
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_max_qty TYPE i VALUE 100,
c_discount_qty TYPE i VALUE 3,
c_discount_percent TYPE i VALUE 10,
c_lens_standard TYPE ty_amount VALUE '40.00',
c_lens_bifocal TYPE ty_amount VALUE '90.00',
c_lens_progressive TYPE ty_amount VALUE '150.00',
c_coat_simple TYPE ty_amount VALUE '25.00',
c_coat_premium TYPE ty_amount VALUE '35.00',
c_coat_none TYPE ty_amount VALUE '0.00'.
METHODS capped_qty
IMPORTING iv_qty TYPE i
RETURNING VALUE(rv_qty) TYPE i.
METHODS lens_surcharge
IMPORTING iv_lens TYPE ty_lens
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS coat_surcharge
IMPORTING iv_coat TYPE ty_coat
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS total_price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_amount
iv_coat TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS with_discount
IMPORTING iv_total TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}glasses_pricer IMPLEMENTATION.
METHOD price.
DATA(lv_qty) = capped_qty( iv_qty ).
IF lv_qty < 1.
RETURN.
ENDIF.
DATA(lv_total) = total_price( iv_frame = iv_frame
iv_lens = lens_surcharge( iv_lens )
iv_coat = coat_surcharge( iv_coat )
iv_qty = lv_qty ).
rv_price = with_discount( iv_total = lv_total
iv_qty = lv_qty ).
ENDMETHOD.
METHOD capped_qty.
rv_qty = iv_qty.
IF rv_qty > c_max_qty.
rv_qty = c_max_qty.
ENDIF.
ENDMETHOD.
METHOD lens_surcharge.
CASE iv_lens.
WHEN 'B'.
rv_amount = c_lens_bifocal.
WHEN 'P'.
rv_amount = c_lens_progressive.
WHEN OTHERS.
rv_amount = c_lens_standard.
ENDCASE.
ENDMETHOD.
METHOD coat_surcharge.
CASE iv_coat.
WHEN 'A'.
rv_amount = c_coat_simple.
WHEN 'B'.
rv_amount = c_coat_premium.
WHEN OTHERS.
rv_amount = c_coat_none.
ENDCASE.
ENDMETHOD.
METHOD total_price.
rv_total = iv_frame * iv_qty.
rv_total = rv_total + iv_lens / iv_qty.
rv_total = rv_total + iv_coat * iv_qty.
ENDMETHOD.
METHOD with_discount.
rv_price = iv_total.
IF iv_qty >= c_discount_qty.
rv_price = iv_total - iv_total * c_discount_percent / 100.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,109 @@
CLASS {{p}}glasses_pricer DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_lens TYPE c LENGTH 1.
TYPES ty_coat TYPE c LENGTH 1.
METHODS price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_lens
iv_coat TYPE ty_coat
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_max_qty TYPE i VALUE 100,
c_discount_qty TYPE i VALUE 3,
c_discount_percent TYPE i VALUE 10,
c_lens_standard TYPE ty_amount VALUE '40.00',
c_lens_bifocal TYPE ty_amount VALUE '90.00',
c_lens_progressive TYPE ty_amount VALUE '150.00',
c_coat_simple TYPE ty_amount VALUE '25.00',
c_coat_premium TYPE ty_amount VALUE '35.00',
c_coat_none TYPE ty_amount VALUE '0.00'.
METHODS capped_qty
IMPORTING iv_qty TYPE i
RETURNING VALUE(rv_qty) TYPE i.
METHODS lens_surcharge
IMPORTING iv_lens TYPE ty_lens
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS coat_surcharge
IMPORTING iv_coat TYPE ty_coat
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS total_price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_amount
iv_coat TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS with_discount
IMPORTING iv_total TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}glasses_pricer IMPLEMENTATION.
METHOD price.
DATA(lv_qty) = capped_qty( iv_qty ).
IF lv_qty < 1.
RETURN.
ENDIF.
DATA(lv_total) = total_price( iv_frame = iv_frame
iv_lens = lens_surcharge( iv_lens )
iv_coat = coat_surcharge( iv_coat )
iv_qty = lv_qty ).
rv_price = with_discount( iv_total = lv_total
iv_qty = lv_qty ).
ENDMETHOD.
METHOD capped_qty.
rv_qty = iv_qty.
IF rv_qty > c_max_qty.
rv_qty = c_max_qty.
ENDIF.
ENDMETHOD.
METHOD lens_surcharge.
CASE iv_lens.
WHEN 'B'.
rv_amount = c_lens_bifocal.
WHEN 'P'.
rv_amount = c_lens_progressive.
WHEN OTHERS.
rv_amount = c_lens_standard.
ENDCASE.
ENDMETHOD.
METHOD coat_surcharge.
CASE iv_coat.
WHEN 'A'.
rv_amount = c_coat_simple.
WHEN 'B'.
rv_amount = c_coat_premium.
WHEN OTHERS.
rv_amount = c_coat_none.
ENDCASE.
ENDMETHOD.
METHOD total_price.
rv_total = iv_frame * iv_qty.
rv_total = rv_total + iv_lens * iv_qty.
rv_total = rv_total - iv_coat * iv_qty.
ENDMETHOD.
METHOD with_discount.
rv_price = iv_total.
IF iv_qty >= c_discount_qty.
rv_price = iv_total - iv_total * c_discount_percent / 100.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,109 @@
CLASS {{p}}glasses_pricer DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_lens TYPE c LENGTH 1.
TYPES ty_coat TYPE c LENGTH 1.
METHODS price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_lens
iv_coat TYPE ty_coat
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_max_qty TYPE i VALUE 100,
c_discount_qty TYPE i VALUE 3,
c_discount_percent TYPE i VALUE 10,
c_lens_standard TYPE ty_amount VALUE '40.00',
c_lens_bifocal TYPE ty_amount VALUE '90.00',
c_lens_progressive TYPE ty_amount VALUE '150.00',
c_coat_simple TYPE ty_amount VALUE '25.00',
c_coat_premium TYPE ty_amount VALUE '35.00',
c_coat_none TYPE ty_amount VALUE '0.00'.
METHODS capped_qty
IMPORTING iv_qty TYPE i
RETURNING VALUE(rv_qty) TYPE i.
METHODS lens_surcharge
IMPORTING iv_lens TYPE ty_lens
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS coat_surcharge
IMPORTING iv_coat TYPE ty_coat
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS total_price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_amount
iv_coat TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS with_discount
IMPORTING iv_total TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}glasses_pricer IMPLEMENTATION.
METHOD price.
DATA(lv_qty) = capped_qty( iv_qty ).
IF lv_qty < 1.
RETURN.
ENDIF.
DATA(lv_total) = total_price( iv_frame = iv_frame
iv_lens = lens_surcharge( iv_lens )
iv_coat = coat_surcharge( iv_coat )
iv_qty = lv_qty ).
rv_price = with_discount( iv_total = lv_total
iv_qty = lv_qty ).
ENDMETHOD.
METHOD capped_qty.
rv_qty = iv_qty.
IF rv_qty > c_max_qty.
rv_qty = c_max_qty.
ENDIF.
ENDMETHOD.
METHOD lens_surcharge.
CASE iv_lens.
WHEN 'B'.
rv_amount = c_lens_bifocal.
WHEN 'P'.
rv_amount = c_lens_progressive.
WHEN OTHERS.
rv_amount = c_lens_standard.
ENDCASE.
ENDMETHOD.
METHOD coat_surcharge.
CASE iv_coat.
WHEN 'A'.
rv_amount = c_coat_simple.
WHEN 'B'.
rv_amount = c_coat_premium.
WHEN OTHERS.
rv_amount = c_coat_none.
ENDCASE.
ENDMETHOD.
METHOD total_price.
rv_total = iv_frame * iv_qty.
rv_total = rv_total + iv_lens * iv_qty.
rv_total = rv_total + iv_coat / iv_qty.
ENDMETHOD.
METHOD with_discount.
rv_price = iv_total.
IF iv_qty >= c_discount_qty.
rv_price = iv_total - iv_total * c_discount_percent / 100.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,109 @@
CLASS {{p}}glasses_pricer DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_lens TYPE c LENGTH 1.
TYPES ty_coat TYPE c LENGTH 1.
METHODS price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_lens
iv_coat TYPE ty_coat
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_max_qty TYPE i VALUE 100,
c_discount_qty TYPE i VALUE 3,
c_discount_percent TYPE i VALUE 10,
c_lens_standard TYPE ty_amount VALUE '40.00',
c_lens_bifocal TYPE ty_amount VALUE '90.00',
c_lens_progressive TYPE ty_amount VALUE '150.00',
c_coat_simple TYPE ty_amount VALUE '25.00',
c_coat_premium TYPE ty_amount VALUE '35.00',
c_coat_none TYPE ty_amount VALUE '0.00'.
METHODS capped_qty
IMPORTING iv_qty TYPE i
RETURNING VALUE(rv_qty) TYPE i.
METHODS lens_surcharge
IMPORTING iv_lens TYPE ty_lens
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS coat_surcharge
IMPORTING iv_coat TYPE ty_coat
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS total_price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_amount
iv_coat TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS with_discount
IMPORTING iv_total TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}glasses_pricer IMPLEMENTATION.
METHOD price.
DATA(lv_qty) = capped_qty( iv_qty ).
IF lv_qty < 1.
RETURN.
ENDIF.
DATA(lv_total) = total_price( iv_frame = iv_frame
iv_lens = lens_surcharge( iv_lens )
iv_coat = coat_surcharge( iv_coat )
iv_qty = lv_qty ).
rv_price = with_discount( iv_total = lv_total
iv_qty = lv_qty ).
ENDMETHOD.
METHOD capped_qty.
rv_qty = iv_qty.
IF rv_qty > c_max_qty.
rv_qty = c_max_qty.
ENDIF.
ENDMETHOD.
METHOD lens_surcharge.
CASE iv_lens.
WHEN 'B'.
rv_amount = c_lens_bifocal.
WHEN 'P'.
rv_amount = c_lens_progressive.
WHEN OTHERS.
rv_amount = c_lens_standard.
ENDCASE.
ENDMETHOD.
METHOD coat_surcharge.
CASE iv_coat.
WHEN 'A'.
rv_amount = c_coat_simple.
WHEN 'B'.
rv_amount = c_coat_premium.
WHEN OTHERS.
rv_amount = c_coat_none.
ENDCASE.
ENDMETHOD.
METHOD total_price.
rv_total = iv_frame * iv_qty.
rv_total = rv_total + iv_lens * iv_qty.
rv_total = rv_total + iv_coat * iv_qty.
ENDMETHOD.
METHOD with_discount.
rv_price = iv_total.
IF iv_qty < c_discount_qty.
rv_price = iv_total - iv_total * c_discount_percent / 100.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,109 @@
CLASS {{p}}glasses_pricer DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_lens TYPE c LENGTH 1.
TYPES ty_coat TYPE c LENGTH 1.
METHODS price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_lens
iv_coat TYPE ty_coat
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_max_qty TYPE i VALUE 100,
c_discount_qty TYPE i VALUE 3,
c_discount_percent TYPE i VALUE 10,
c_lens_standard TYPE ty_amount VALUE '40.00',
c_lens_bifocal TYPE ty_amount VALUE '90.00',
c_lens_progressive TYPE ty_amount VALUE '150.00',
c_coat_simple TYPE ty_amount VALUE '25.00',
c_coat_premium TYPE ty_amount VALUE '35.00',
c_coat_none TYPE ty_amount VALUE '0.00'.
METHODS capped_qty
IMPORTING iv_qty TYPE i
RETURNING VALUE(rv_qty) TYPE i.
METHODS lens_surcharge
IMPORTING iv_lens TYPE ty_lens
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS coat_surcharge
IMPORTING iv_coat TYPE ty_coat
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS total_price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_amount
iv_coat TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS with_discount
IMPORTING iv_total TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}glasses_pricer IMPLEMENTATION.
METHOD price.
DATA(lv_qty) = capped_qty( iv_qty ).
IF lv_qty < 1.
RETURN.
ENDIF.
DATA(lv_total) = total_price( iv_frame = iv_frame
iv_lens = lens_surcharge( iv_lens )
iv_coat = coat_surcharge( iv_coat )
iv_qty = lv_qty ).
rv_price = with_discount( iv_total = lv_total
iv_qty = lv_qty ).
ENDMETHOD.
METHOD capped_qty.
rv_qty = iv_qty.
IF rv_qty > c_max_qty.
rv_qty = c_max_qty.
ENDIF.
ENDMETHOD.
METHOD lens_surcharge.
CASE iv_lens.
WHEN 'B'.
rv_amount = c_lens_bifocal.
WHEN 'P'.
rv_amount = c_lens_progressive.
WHEN OTHERS.
rv_amount = c_lens_standard.
ENDCASE.
ENDMETHOD.
METHOD coat_surcharge.
CASE iv_coat.
WHEN 'A'.
rv_amount = c_coat_simple.
WHEN 'B'.
rv_amount = c_coat_premium.
WHEN OTHERS.
rv_amount = c_coat_none.
ENDCASE.
ENDMETHOD.
METHOD total_price.
rv_total = iv_frame * iv_qty.
rv_total = rv_total + iv_lens * iv_qty.
rv_total = rv_total + iv_coat * iv_qty.
ENDMETHOD.
METHOD with_discount.
rv_price = iv_total.
IF iv_qty >= c_discount_qty.
rv_price = iv_total + iv_total * c_discount_percent / 100.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

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

View File

@@ -0,0 +1,100 @@
CLASS {{p}}glasses_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CONSTANTS c_frame TYPE {{p}}glasses_pricer=>ty_amount VALUE '100.00'.
DATA mo_cut TYPE REF TO {{p}}glasses_pricer.
METHODS setup.
METHODS zero_qty_is_free FOR TESTING.
METHODS negative_qty_is_free FOR TESTING.
METHODS single_vision_price FOR TESTING.
METHODS bifocal_with_coating FOR TESTING.
METHODS progressive_blue_filter FOR TESTING.
METHODS unknown_lens_defaults FOR TESTING.
METHODS unknown_coat_is_free FOR TESTING.
METHODS discount_from_three FOR TESTING.
METHODS no_discount_for_two FOR TESTING.
METHODS qty_capped_at_hundred FOR TESTING.
METHODS discount_on_total FOR TESTING.
ENDCLASS.
CLASS {{p}}glasses_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}glasses_pricer( ).
ENDMETHOD.
METHOD zero_qty_is_free.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '0.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'A' iv_qty = 0 ) ).
ENDMETHOD.
METHOD negative_qty_is_free.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '0.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'P' iv_coat = 'B' iv_qty = -2 ) ).
ENDMETHOD.
METHOD single_vision_price.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '140.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'N' iv_qty = 1 ) ).
ENDMETHOD.
METHOD bifocal_with_coating.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '430.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'B' iv_coat = 'A' iv_qty = 2 ) ).
ENDMETHOD.
METHOD progressive_blue_filter.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '235.00' )
act = mo_cut->price( iv_frame = CONV {{p}}glasses_pricer=>ty_amount( '50.00' )
iv_lens = 'P' iv_coat = 'B' iv_qty = 1 ) ).
ENDMETHOD.
METHOD unknown_lens_defaults.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '140.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'Z' iv_coat = 'N' iv_qty = 1 ) ).
ENDMETHOD.
METHOD unknown_coat_is_free.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '140.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'X' iv_qty = 1 ) ).
ENDMETHOD.
METHOD discount_from_three.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '378.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'N' iv_qty = 3 ) ).
ENDMETHOD.
METHOD no_discount_for_two.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '280.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'N' iv_qty = 2 ) ).
ENDMETHOD.
METHOD qty_capped_at_hundred.
DATA(lv_capped) = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'N' iv_qty = 100 ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '12600.00' )
act = lv_capped ).
cl_abap_unit_assert=>assert_equals(
exp = lv_capped
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'N' iv_qty = 150 ) ).
ENDMETHOD.
METHOD discount_on_total.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '499.50' )
act = mo_cut->price( iv_frame = CONV {{p}}glasses_pricer=>ty_amount( '0.00' )
iv_lens = 'P' iv_coat = 'B' iv_qty = 3 ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,71 @@
{
"task": "G1002",
"mutants": [
{
"object": "{{P}}GLASSES_PRICER",
"mutant": "line 99: * -> / (arith)",
"status": "killed",
"hidden": "6/11",
"failed_tests": [
"BIFOCAL_WITH_COATING",
"DISCOUNT_FROM_THREE",
"DISCOUNT_ON_TOTAL",
"NO_DISCOUNT_FOR_TWO",
"QTY_CAPPED_AT_HUNDRED"
]
},
{
"object": "{{P}}GLASSES_PRICER",
"mutant": "line 100: + -> - (arith)",
"status": "killed",
"hidden": "8/11",
"failed_tests": [
"BIFOCAL_WITH_COATING",
"DISCOUNT_ON_TOTAL",
"PROGRESSIVE_BLUE_FILTER"
]
},
{
"object": "{{P}}GLASSES_PRICER",
"mutant": "line 100: * -> / (arith)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"BIFOCAL_WITH_COATING",
"DISCOUNT_ON_TOTAL"
]
},
{
"object": "{{P}}GLASSES_PRICER",
"mutant": "line 105: >= -> < (rel)",
"status": "killed",
"hidden": "2/11",
"failed_tests": [
"BIFOCAL_WITH_COATING",
"DISCOUNT_FROM_THREE",
"DISCOUNT_ON_TOTAL",
"NO_DISCOUNT_FOR_TWO",
"PROGRESSIVE_BLUE_FILTER",
"QTY_CAPPED_AT_HUNDRED",
"SINGLE_VISION_PRICE",
"UNKNOWN_COAT_IS_FREE",
"UNKNOWN_LENS_DEFAULTS"
]
},
{
"object": "{{P}}GLASSES_PRICER",
"mutant": "line 106: - -> + (arith)",
"status": "killed",
"hidden": "8/11",
"failed_tests": [
"DISCOUNT_FROM_THREE",
"DISCOUNT_ON_TOTAL",
"QTY_CAPPED_AT_HUNDRED"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,109 @@
CLASS {{p}}glasses_pricer DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2.
TYPES ty_lens TYPE c LENGTH 1.
TYPES ty_coat TYPE c LENGTH 1.
METHODS price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_lens
iv_coat TYPE ty_coat
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_max_qty TYPE i VALUE 100,
c_discount_qty TYPE i VALUE 3,
c_discount_percent TYPE i VALUE 10,
c_lens_standard TYPE ty_amount VALUE '40.00',
c_lens_bifocal TYPE ty_amount VALUE '90.00',
c_lens_progressive TYPE ty_amount VALUE '150.00',
c_coat_simple TYPE ty_amount VALUE '25.00',
c_coat_premium TYPE ty_amount VALUE '35.00',
c_coat_none TYPE ty_amount VALUE '0.00'.
METHODS capped_qty
IMPORTING iv_qty TYPE i
RETURNING VALUE(rv_qty) TYPE i.
METHODS lens_surcharge
IMPORTING iv_lens TYPE ty_lens
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS coat_surcharge
IMPORTING iv_coat TYPE ty_coat
RETURNING VALUE(rv_amount) TYPE ty_amount.
METHODS total_price
IMPORTING iv_frame TYPE ty_amount
iv_lens TYPE ty_amount
iv_coat TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS with_discount
IMPORTING iv_total TYPE ty_amount
iv_qty TYPE i
RETURNING VALUE(rv_price) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}glasses_pricer IMPLEMENTATION.
METHOD price.
DATA(lv_qty) = capped_qty( iv_qty ).
IF lv_qty < 1.
RETURN.
ENDIF.
DATA(lv_total) = total_price( iv_frame = iv_frame
iv_lens = lens_surcharge( iv_lens )
iv_coat = coat_surcharge( iv_coat )
iv_qty = lv_qty ).
rv_price = with_discount( iv_total = lv_total
iv_qty = lv_qty ).
ENDMETHOD.
METHOD capped_qty.
rv_qty = iv_qty.
IF rv_qty > c_max_qty.
rv_qty = c_max_qty.
ENDIF.
ENDMETHOD.
METHOD lens_surcharge.
CASE iv_lens.
WHEN 'B'.
rv_amount = c_lens_bifocal.
WHEN 'P'.
rv_amount = c_lens_progressive.
WHEN OTHERS.
rv_amount = c_lens_standard.
ENDCASE.
ENDMETHOD.
METHOD coat_surcharge.
CASE iv_coat.
WHEN 'A'.
rv_amount = c_coat_simple.
WHEN 'B'.
rv_amount = c_coat_premium.
WHEN OTHERS.
rv_amount = c_coat_none.
ENDCASE.
ENDMETHOD.
METHOD total_price.
rv_total = iv_frame * iv_qty.
rv_total = rv_total + iv_lens * iv_qty.
rv_total = rv_total + iv_coat * iv_qty.
ENDMETHOD.
METHOD with_discount.
rv_price = iv_total.
IF iv_qty >= c_discount_qty.
rv_price = iv_total - iv_total * c_discount_percent / 100.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,83 @@
CLASS ltc_glasses_pricer DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CONSTANTS c_frame TYPE {{p}}glasses_pricer=>ty_amount VALUE '100.00'.
DATA mo_cut TYPE REF TO {{p}}glasses_pricer.
METHODS setup.
METHODS single_vision FOR TESTING.
METHODS bifocal_with_coating FOR TESTING.
METHODS progressive_with_blue FOR TESTING.
METHODS unknown_lens_defaults FOR TESTING.
METHODS unknown_coat_is_free FOR TESTING.
METHODS discount_from_three FOR TESTING.
METHODS no_discount_for_two FOR TESTING.
METHODS zero_qty_is_free FOR TESTING.
METHODS qty_capped_at_hundred FOR TESTING.
ENDCLASS.
CLASS ltc_glasses_pricer IMPLEMENTATION.
METHOD setup.
mo_cut = NEW #( ).
ENDMETHOD.
METHOD single_vision.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '140.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'N' iv_qty = 1 ) ).
ENDMETHOD.
METHOD bifocal_with_coating.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '430.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'B' iv_coat = 'A' iv_qty = 2 ) ).
ENDMETHOD.
METHOD progressive_with_blue.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '235.00' )
act = mo_cut->price( iv_frame = CONV {{p}}glasses_pricer=>ty_amount( '50.00' )
iv_lens = 'P' iv_coat = 'B' iv_qty = 1 ) ).
ENDMETHOD.
METHOD unknown_lens_defaults.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '140.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'Z' iv_coat = 'N' iv_qty = 1 ) ).
ENDMETHOD.
METHOD unknown_coat_is_free.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '140.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'X' iv_qty = 1 ) ).
ENDMETHOD.
METHOD discount_from_three.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '378.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'N' iv_qty = 3 ) ).
ENDMETHOD.
METHOD no_discount_for_two.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '280.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'N' iv_qty = 2 ) ).
ENDMETHOD.
METHOD zero_qty_is_free.
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '0.00' )
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'A' iv_qty = 0 ) ).
ENDMETHOD.
METHOD qty_capped_at_hundred.
DATA(lv_capped) = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'N' iv_qty = 100 ).
cl_abap_unit_assert=>assert_equals(
exp = CONV {{p}}glasses_pricer=>ty_amount( '12600.00' )
act = lv_capped ).
cl_abap_unit_assert=>assert_equals(
exp = lv_capped
act = mo_cut->price( iv_frame = c_frame iv_lens = 'S' iv_coat = 'N' iv_qty = 150 ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,75 @@
CLASS {{p}}glasses_pricer DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES ty_amount TYPE p LENGTH 9 DECIMALS 2 .
TYPES ty_lens TYPE c LENGTH 1 .
TYPES ty_coat TYPE c LENGTH 1 .
METHODS price
IMPORTING
iv_frame TYPE ty_amount
iv_lens TYPE ty_lens
iv_coat TYPE ty_coat
iv_qty TYPE i
RETURNING
VALUE(rv_price) TYPE ty_amount .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS {{p}}glasses_pricer IMPLEMENTATION.
METHOD price.
DATA lv_qty TYPE i .
DATA lv_frame TYPE ty_amount .
DATA lv_lens TYPE ty_amount .
DATA lv_coat TYPE ty_amount .
DATA lv_total TYPE ty_amount .
lv_qty = iv_qty .
IF lv_qty > 100 .
lv_qty = 100 .
ENDIF .
IF lv_qty < 1 .
rv_price = 0 .
RETURN .
ENDIF .
lv_frame = iv_frame * lv_qty .
IF iv_lens = 'S' .
lv_lens = 40 .
ELSEIF iv_lens = 'B' .
lv_lens = 90 .
ELSEIF iv_lens = 'P' .
lv_lens = 150 .
ELSE .
lv_lens = 40 .
ENDIF .
lv_lens = lv_lens * lv_qty .
CASE iv_coat .
WHEN 'A' .
lv_coat = 25 .
WHEN 'B' .
lv_coat = 35 .
WHEN OTHERS .
lv_coat = 0 .
ENDCASE .
lv_coat = lv_coat * lv_qty .
lv_total = lv_frame + lv_lens + lv_coat .
IF lv_qty >= 3 .
lv_total = lv_total - lv_total * 10 / 100 .
ENDIF .
rv_price = lv_total .
ENDMETHOD .
ENDCLASS.

View File

@@ -0,0 +1,12 @@
REPORT {{p}}optic_quote_rpt.
DATA lo_pricer TYPE REF TO {{p}}glasses_pricer.
DATA lv_price TYPE {{p}}glasses_pricer=>ty_amount.
lo_pricer = NEW #( ).
lv_price = lo_pricer->price( iv_frame = CONV {{p}}glasses_pricer=>ty_amount( '120.00' )
iv_lens = 'P'
iv_coat = 'A'
iv_qty = 2 ).
WRITE: / 'Quotation:', lv_price.

View File

@@ -0,0 +1,51 @@
# 1. Goal
The optician shop uses the class {{P}}GLASSES_PRICER to calculate the price of a
glasses order. A sales program calls the class for each quotation. The class is
legacy code. It is hard to read and hard to test. Refactor the class. The
behavior must stay the same.
# 2. Open questions
None.
# 3. Context
- The class {{P}}GLASSES_PRICER exists in package $TMP. It is active.
- The class is public and final. It has a public constructor without parameters.
- The public interface of the class is:
- the type TY_AMOUNT (packed number, length 9, 2 decimals),
- the type TY_LENS (character, length 1),
- the type TY_COAT (character, length 1),
- the method PRICE with the importing parameters IV_FRAME (TY_AMOUNT),
IV_LENS (TY_LENS), IV_COAT (TY_COAT), IV_QTY (TYPE i) and the returning
parameter RV_PRICE (TY_AMOUNT).
- The program {{P}}OPTIC_QUOTE_RPT calls the class.
- The legacy implementation is the specification of the behavior.
# 4. Contract
- Refactor the class {{P}}GLASSES_PRICER in package $TMP. The name stays the same.
- The class stays public and final and keeps its public constructor without
parameters.
- Keep the public types TY_AMOUNT, TY_LENS and TY_COAT.
- Keep the method PRICE with the same parameter names, the same parameter types
and the same sequence.
- Do not add public methods or public attributes.
- Do not create other objects.
# 5. Business rules
- The behavior of the class must not change. For every input, PRICE must return
the same value as the legacy method.
- The legacy code holds all rules, including its limits and its default values.
- Do not add a rule. Do not remove a rule. Do not correct a rule.
- PRICE returns a price in the currency of the order.
# 6. Constraints
- Release target: ABAP Platform 2025 (SAP_BASIS 816).
- Coding standards: Clean ABAP. One method does one thing. Method length below
40 statements. No deep nesting. No magic numbers: use constants. No duplicated
code. No dead code. No global variables. No comment that restates the code.
- Out of scope: do not change the program {{P}}OPTIC_QUOTE_RPT. Do not change
the public interface of the class.
# 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,57 @@
{
"id": "G1002",
"category": "E",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 70,
"max_activations": 18
},
"seed": [
{
"type": "CLAS",
"name": "{{P}}GLASSES_PRICER",
"file": "seed/glasses_pricer.clas.abap",
"description": "Legacy price calculator for glasses orders"
},
{
"type": "PROG",
"name": "{{P}}OPTIC_QUOTE_RPT",
"file": "seed/optic_quote_rpt.prog.abap",
"description": "Report that calls the legacy class"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}GLASSES_PRICER"
}
],
"out_of_scope": [
"{{P}}OPTIC_QUOTE_RPT"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}GLASSES_HIDDEN",
"file": "hidden/glasses_hidden.clas.abap",
"description": "Hidden behavior tests for the refactored class"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}GLASSES_PRICER",
"file": "reference/glasses_pricer.clas.abap",
"description": "Refactored glasses price calculator",
"testclasses_file": "reference/glasses_pricer.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"nesting_depth",
"magic_numbers"
]
}