Step F first pass: 81/92 accepted; budget floor 60 calls; rejected slots moved for regeneration

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 12:10:52 +02:00
parent d3250acfb8
commit 39769afce8
741 changed files with 40573 additions and 317 deletions

View File

@@ -0,0 +1,83 @@
CLASS {{p}}pool_fee DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_ticket TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS calculate_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_minutes TYPE i
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_ticket_adult TYPE ty_ticket VALUE 'A',
c_ticket_child TYPE ty_ticket VALUE 'C',
c_ticket_senior TYPE ty_ticket VALUE 'S',
c_ticket_family TYPE ty_ticket VALUE 'F'.
CONSTANTS:
c_base_adult TYPE ty_amount VALUE '6.50',
c_base_child TYPE ty_amount VALUE '3.50',
c_base_senior TYPE ty_amount VALUE '4.50',
c_base_family TYPE ty_amount VALUE '15.00',
c_block_fee TYPE ty_amount VALUE '1.00',
c_sauna_fee TYPE ty_amount VALUE '5.00',
c_sauna_family TYPE ty_amount VALUE '8.00'.
CONSTANTS:
c_free_minutes TYPE i VALUE 60,
c_block_minutes TYPE i VALUE 30.
METHODS base_fee
IMPORTING iv_ticket TYPE ty_ticket
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS duration_fee
IMPORTING iv_minutes TYPE i
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS sauna_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}pool_fee IMPLEMENTATION.
METHOD calculate_fee.
rv_fee = base_fee( iv_ticket )
+ duration_fee( iv_minutes )
+ sauna_fee( iv_ticket = iv_ticket iv_sauna = iv_sauna ).
ENDMETHOD.
METHOD base_fee.
CASE iv_ticket.
WHEN c_ticket_adult.
rv_fee = c_base_adult.
WHEN c_ticket_child.
rv_fee = c_base_child.
WHEN c_ticket_senior.
rv_fee = c_base_senior.
WHEN c_ticket_family.
rv_fee = c_base_family.
WHEN OTHERS.
rv_fee = 0.
ENDCASE.
ENDMETHOD.
METHOD duration_fee.
DATA(lv_minutes) = nmax( val1 = iv_minutes val2 = 0 ).
IF lv_minutes > c_free_minutes.
RETURN.
ENDIF.
DATA(lv_blocks) = ( lv_minutes - c_free_minutes + c_block_minutes - 1 ) DIV c_block_minutes.
rv_fee = lv_blocks * c_block_fee.
ENDMETHOD.
METHOD sauna_fee.
IF iv_sauna <> abap_true OR iv_ticket = c_ticket_child.
RETURN.
ENDIF.
IF iv_ticket = c_ticket_family.
rv_fee = c_sauna_family.
ELSE.
rv_fee = c_sauna_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,83 @@
CLASS {{p}}pool_fee DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_ticket TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS calculate_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_minutes TYPE i
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_ticket_adult TYPE ty_ticket VALUE 'A',
c_ticket_child TYPE ty_ticket VALUE 'C',
c_ticket_senior TYPE ty_ticket VALUE 'S',
c_ticket_family TYPE ty_ticket VALUE 'F'.
CONSTANTS:
c_base_adult TYPE ty_amount VALUE '6.50',
c_base_child TYPE ty_amount VALUE '3.50',
c_base_senior TYPE ty_amount VALUE '4.50',
c_base_family TYPE ty_amount VALUE '15.00',
c_block_fee TYPE ty_amount VALUE '1.00',
c_sauna_fee TYPE ty_amount VALUE '5.00',
c_sauna_family TYPE ty_amount VALUE '8.00'.
CONSTANTS:
c_free_minutes TYPE i VALUE 60,
c_block_minutes TYPE i VALUE 30.
METHODS base_fee
IMPORTING iv_ticket TYPE ty_ticket
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS duration_fee
IMPORTING iv_minutes TYPE i
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS sauna_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}pool_fee IMPLEMENTATION.
METHOD calculate_fee.
rv_fee = base_fee( iv_ticket )
+ duration_fee( iv_minutes )
+ sauna_fee( iv_ticket = iv_ticket iv_sauna = iv_sauna ).
ENDMETHOD.
METHOD base_fee.
CASE iv_ticket.
WHEN c_ticket_adult.
rv_fee = c_base_adult.
WHEN c_ticket_child.
rv_fee = c_base_child.
WHEN c_ticket_senior.
rv_fee = c_base_senior.
WHEN c_ticket_family.
rv_fee = c_base_family.
WHEN OTHERS.
rv_fee = 0.
ENDCASE.
ENDMETHOD.
METHOD duration_fee.
DATA(lv_minutes) = nmax( val1 = iv_minutes val2 = 0 ).
IF lv_minutes <= c_free_minutes.
RETURN.
ENDIF.
DATA(lv_blocks) = ( lv_minutes - c_free_minutes + c_block_minutes - 1 ) DIV c_block_minutes.
rv_fee = lv_blocks * c_block_fee.
ENDMETHOD.
METHOD sauna_fee.
IF iv_sauna <> abap_false OR iv_ticket = c_ticket_child.
RETURN.
ENDIF.
IF iv_ticket = c_ticket_family.
rv_fee = c_sauna_family.
ELSE.
rv_fee = c_sauna_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,83 @@
CLASS {{p}}pool_fee DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_ticket TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS calculate_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_minutes TYPE i
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_ticket_adult TYPE ty_ticket VALUE 'A',
c_ticket_child TYPE ty_ticket VALUE 'C',
c_ticket_senior TYPE ty_ticket VALUE 'S',
c_ticket_family TYPE ty_ticket VALUE 'F'.
CONSTANTS:
c_base_adult TYPE ty_amount VALUE '6.50',
c_base_child TYPE ty_amount VALUE '3.50',
c_base_senior TYPE ty_amount VALUE '4.50',
c_base_family TYPE ty_amount VALUE '15.00',
c_block_fee TYPE ty_amount VALUE '1.00',
c_sauna_fee TYPE ty_amount VALUE '5.00',
c_sauna_family TYPE ty_amount VALUE '8.00'.
CONSTANTS:
c_free_minutes TYPE i VALUE 60,
c_block_minutes TYPE i VALUE 30.
METHODS base_fee
IMPORTING iv_ticket TYPE ty_ticket
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS duration_fee
IMPORTING iv_minutes TYPE i
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS sauna_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}pool_fee IMPLEMENTATION.
METHOD calculate_fee.
rv_fee = base_fee( iv_ticket )
+ duration_fee( iv_minutes )
+ sauna_fee( iv_ticket = iv_ticket iv_sauna = iv_sauna ).
ENDMETHOD.
METHOD base_fee.
CASE iv_ticket.
WHEN c_ticket_adult.
rv_fee = c_base_adult.
WHEN c_ticket_child.
rv_fee = c_base_child.
WHEN c_ticket_senior.
rv_fee = c_base_senior.
WHEN c_ticket_family.
rv_fee = c_base_family.
WHEN OTHERS.
rv_fee = 0.
ENDCASE.
ENDMETHOD.
METHOD duration_fee.
DATA(lv_minutes) = nmax( val1 = iv_minutes val2 = 0 ).
IF lv_minutes <= c_free_minutes.
RETURN.
ENDIF.
DATA(lv_blocks) = ( lv_minutes - c_free_minutes + c_block_minutes - 1 ) DIV c_block_minutes.
rv_fee = lv_blocks * c_block_fee.
ENDMETHOD.
METHOD sauna_fee.
IF iv_sauna <> abap_true AND iv_ticket = c_ticket_child.
RETURN.
ENDIF.
IF iv_ticket = c_ticket_family.
rv_fee = c_sauna_family.
ELSE.
rv_fee = c_sauna_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,83 @@
CLASS {{p}}pool_fee DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_ticket TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS calculate_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_minutes TYPE i
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_ticket_adult TYPE ty_ticket VALUE 'A',
c_ticket_child TYPE ty_ticket VALUE 'C',
c_ticket_senior TYPE ty_ticket VALUE 'S',
c_ticket_family TYPE ty_ticket VALUE 'F'.
CONSTANTS:
c_base_adult TYPE ty_amount VALUE '6.50',
c_base_child TYPE ty_amount VALUE '3.50',
c_base_senior TYPE ty_amount VALUE '4.50',
c_base_family TYPE ty_amount VALUE '15.00',
c_block_fee TYPE ty_amount VALUE '1.00',
c_sauna_fee TYPE ty_amount VALUE '5.00',
c_sauna_family TYPE ty_amount VALUE '8.00'.
CONSTANTS:
c_free_minutes TYPE i VALUE 60,
c_block_minutes TYPE i VALUE 30.
METHODS base_fee
IMPORTING iv_ticket TYPE ty_ticket
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS duration_fee
IMPORTING iv_minutes TYPE i
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS sauna_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}pool_fee IMPLEMENTATION.
METHOD calculate_fee.
rv_fee = base_fee( iv_ticket )
+ duration_fee( iv_minutes )
+ sauna_fee( iv_ticket = iv_ticket iv_sauna = iv_sauna ).
ENDMETHOD.
METHOD base_fee.
CASE iv_ticket.
WHEN c_ticket_adult.
rv_fee = c_base_adult.
WHEN c_ticket_child.
rv_fee = c_base_child.
WHEN c_ticket_senior.
rv_fee = c_base_senior.
WHEN c_ticket_family.
rv_fee = c_base_family.
WHEN OTHERS.
rv_fee = 0.
ENDCASE.
ENDMETHOD.
METHOD duration_fee.
DATA(lv_minutes) = nmax( val1 = iv_minutes val2 = 0 ).
IF lv_minutes <= c_free_minutes.
RETURN.
ENDIF.
DATA(lv_blocks) = ( lv_minutes - c_free_minutes + c_block_minutes - 1 ) DIV c_block_minutes.
rv_fee = lv_blocks * c_block_fee.
ENDMETHOD.
METHOD sauna_fee.
IF iv_sauna <> abap_true OR iv_ticket = c_ticket_child.
RETURN.
ENDIF.
IF iv_ticket <> c_ticket_family.
rv_fee = c_sauna_family.
ELSE.
rv_fee = c_sauna_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

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

View File

@@ -0,0 +1,89 @@
CLASS {{p}}pool_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}pool_fee.
METHODS setup.
METHODS assert_fee
IMPORTING iv_expected TYPE {{p}}pool_fee=>ty_amount
iv_ticket TYPE {{p}}pool_fee=>ty_ticket
iv_minutes TYPE i
iv_sauna TYPE abap_bool.
METHODS adult_basic FOR TESTING.
METHODS child_basic FOR TESTING.
METHODS senior_basic FOR TESTING.
METHODS family_basic FOR TESTING.
METHODS unknown_ticket FOR TESTING.
METHODS unknown_with_duration FOR TESTING.
METHODS duration_first_block FOR TESTING.
METHODS duration_two_blocks FOR TESTING.
METHODS negative_minutes FOR TESTING.
METHODS sauna_adult FOR TESTING.
METHODS sauna_child_ignored FOR TESTING.
METHODS sauna_family FOR TESTING.
ENDCLASS.
CLASS {{p}}pool_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}pool_fee( ).
ENDMETHOD.
METHOD assert_fee.
DATA(lv_actual) = mo_cut->calculate_fee(
iv_ticket = iv_ticket
iv_minutes = iv_minutes
iv_sauna = iv_sauna ).
cl_abap_unit_assert=>assert_equals(
exp = iv_expected
act = lv_actual
msg = |ticket { iv_ticket }, { iv_minutes } minutes, sauna { iv_sauna }| ).
ENDMETHOD.
METHOD adult_basic.
assert_fee( iv_expected = '6.50' iv_ticket = 'A' iv_minutes = 45 iv_sauna = abap_false ).
ENDMETHOD.
METHOD child_basic.
assert_fee( iv_expected = '3.50' iv_ticket = 'C' iv_minutes = 30 iv_sauna = abap_false ).
ENDMETHOD.
METHOD senior_basic.
assert_fee( iv_expected = '4.50' iv_ticket = 'S' iv_minutes = 60 iv_sauna = abap_false ).
ENDMETHOD.
METHOD family_basic.
assert_fee( iv_expected = '15.00' iv_ticket = 'F' iv_minutes = 20 iv_sauna = abap_false ).
ENDMETHOD.
METHOD unknown_ticket.
assert_fee( iv_expected = '0.00' iv_ticket = 'X' iv_minutes = 45 iv_sauna = abap_false ).
ENDMETHOD.
METHOD unknown_with_duration.
assert_fee( iv_expected = '2.00' iv_ticket = 'X' iv_minutes = 95 iv_sauna = abap_false ).
ENDMETHOD.
METHOD duration_first_block.
assert_fee( iv_expected = '7.50' iv_ticket = 'A' iv_minutes = 61 iv_sauna = abap_false ).
ENDMETHOD.
METHOD duration_two_blocks.
assert_fee( iv_expected = '8.50' iv_ticket = 'A' iv_minutes = 91 iv_sauna = abap_false ).
ENDMETHOD.
METHOD negative_minutes.
assert_fee( iv_expected = '6.50' iv_ticket = 'A' iv_minutes = -5 iv_sauna = abap_false ).
ENDMETHOD.
METHOD sauna_adult.
assert_fee( iv_expected = '11.50' iv_ticket = 'A' iv_minutes = 45 iv_sauna = abap_true ).
ENDMETHOD.
METHOD sauna_child_ignored.
assert_fee( iv_expected = '3.50' iv_ticket = 'C' iv_minutes = 45 iv_sauna = abap_true ).
ENDMETHOD.
METHOD sauna_family.
assert_fee( iv_expected = '23.00' iv_ticket = 'F' iv_minutes = 0 iv_sauna = abap_true ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,76 @@
{
"task": "G0135",
"mutants": [
{
"object": "{{P}}POOL_FEE",
"mutant": "line 66: <= -> > (rel)",
"status": "killed",
"hidden": "5/12",
"failed_tests": [
"CHILD_BASIC",
"DURATION_FIRST_BLOCK",
"DURATION_TWO_BLOCKS",
"FAMILY_BASIC",
"NEGATIVE_MINUTES",
"SAUNA_FAMILY",
"UNKNOWN_WITH_DURATION"
]
},
{
"object": "{{P}}POOL_FEE",
"mutant": "line 70: * -> / (arith)",
"status": "survived",
"hidden": "12/12",
"failed_tests": []
},
{
"object": "{{P}}POOL_FEE",
"mutant": "line 74: abap_true -> abap_false (bool)",
"status": "killed",
"hidden": "2/12",
"failed_tests": [
"ADULT_BASIC",
"DURATION_FIRST_BLOCK",
"DURATION_TWO_BLOCKS",
"FAMILY_BASIC",
"NEGATIVE_MINUTES",
"SAUNA_ADULT",
"SAUNA_FAMILY",
"SENIOR_BASIC",
"UNKNOWN_TICKET",
"UNKNOWN_WITH_DURATION"
]
},
{
"object": "{{P}}POOL_FEE",
"mutant": "line 74: OR -> AND (logic)",
"status": "killed",
"hidden": "3/12",
"failed_tests": [
"ADULT_BASIC",
"DURATION_FIRST_BLOCK",
"DURATION_TWO_BLOCKS",
"FAMILY_BASIC",
"NEGATIVE_MINUTES",
"SAUNA_CHILD_IGNORED",
"SENIOR_BASIC",
"UNKNOWN_TICKET",
"UNKNOWN_WITH_DURATION"
]
},
{
"object": "{{P}}POOL_FEE",
"mutant": "line 77: = -> <> (eq)",
"status": "killed",
"hidden": "10/12",
"failed_tests": [
"SAUNA_ADULT",
"SAUNA_FAMILY"
]
}
],
"valid": 5,
"killed": 4,
"kill_rate": 0.8,
"ok": true
}

View File

@@ -0,0 +1,83 @@
CLASS {{p}}pool_fee DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_ticket TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS calculate_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_minutes TYPE i
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_ticket_adult TYPE ty_ticket VALUE 'A',
c_ticket_child TYPE ty_ticket VALUE 'C',
c_ticket_senior TYPE ty_ticket VALUE 'S',
c_ticket_family TYPE ty_ticket VALUE 'F'.
CONSTANTS:
c_base_adult TYPE ty_amount VALUE '6.50',
c_base_child TYPE ty_amount VALUE '3.50',
c_base_senior TYPE ty_amount VALUE '4.50',
c_base_family TYPE ty_amount VALUE '15.00',
c_block_fee TYPE ty_amount VALUE '1.00',
c_sauna_fee TYPE ty_amount VALUE '5.00',
c_sauna_family TYPE ty_amount VALUE '8.00'.
CONSTANTS:
c_free_minutes TYPE i VALUE 60,
c_block_minutes TYPE i VALUE 30.
METHODS base_fee
IMPORTING iv_ticket TYPE ty_ticket
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS duration_fee
IMPORTING iv_minutes TYPE i
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS sauna_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}pool_fee IMPLEMENTATION.
METHOD calculate_fee.
rv_fee = base_fee( iv_ticket )
+ duration_fee( iv_minutes )
+ sauna_fee( iv_ticket = iv_ticket iv_sauna = iv_sauna ).
ENDMETHOD.
METHOD base_fee.
CASE iv_ticket.
WHEN c_ticket_adult.
rv_fee = c_base_adult.
WHEN c_ticket_child.
rv_fee = c_base_child.
WHEN c_ticket_senior.
rv_fee = c_base_senior.
WHEN c_ticket_family.
rv_fee = c_base_family.
WHEN OTHERS.
rv_fee = 0.
ENDCASE.
ENDMETHOD.
METHOD duration_fee.
DATA(lv_minutes) = nmax( val1 = iv_minutes val2 = 0 ).
IF lv_minutes <= c_free_minutes.
RETURN.
ENDIF.
DATA(lv_blocks) = ( lv_minutes - c_free_minutes + c_block_minutes - 1 ) DIV c_block_minutes.
rv_fee = lv_blocks * c_block_fee.
ENDMETHOD.
METHOD sauna_fee.
IF iv_sauna <> abap_true OR iv_ticket = c_ticket_child.
RETURN.
ENDIF.
IF iv_ticket = c_ticket_family.
rv_fee = c_sauna_family.
ELSE.
rv_fee = c_sauna_fee.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,61 @@
CLASS ltc_pool_fee DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}pool_fee.
METHODS setup.
METHODS assert_fee
IMPORTING iv_expected TYPE {{p}}pool_fee=>ty_amount
iv_ticket TYPE {{p}}pool_fee=>ty_ticket
iv_minutes TYPE i
iv_sauna TYPE abap_bool.
METHODS adult_basic FOR TESTING.
METHODS child_basic FOR TESTING.
METHODS family_basic FOR TESTING.
METHODS unknown_ticket FOR TESTING.
METHODS duration_surcharge FOR TESTING.
METHODS sauna_adult FOR TESTING.
METHODS sauna_child_ignored FOR TESTING.
ENDCLASS.
CLASS ltc_pool_fee IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}pool_fee( ).
ENDMETHOD.
METHOD assert_fee.
DATA(lv_actual) = mo_cut->calculate_fee(
iv_ticket = iv_ticket
iv_minutes = iv_minutes
iv_sauna = iv_sauna ).
cl_abap_unit_assert=>assert_equals( exp = iv_expected act = lv_actual ).
ENDMETHOD.
METHOD adult_basic.
assert_fee( iv_expected = '6.50' iv_ticket = 'A' iv_minutes = 45 iv_sauna = abap_false ).
ENDMETHOD.
METHOD child_basic.
assert_fee( iv_expected = '3.50' iv_ticket = 'C' iv_minutes = 30 iv_sauna = abap_false ).
ENDMETHOD.
METHOD family_basic.
assert_fee( iv_expected = '15.00' iv_ticket = 'F' iv_minutes = 20 iv_sauna = abap_false ).
ENDMETHOD.
METHOD unknown_ticket.
assert_fee( iv_expected = '0.00' iv_ticket = 'X' iv_minutes = 45 iv_sauna = abap_false ).
ENDMETHOD.
METHOD duration_surcharge.
assert_fee( iv_expected = '7.50' iv_ticket = 'A' iv_minutes = 61 iv_sauna = abap_false ).
assert_fee( iv_expected = '8.50' iv_ticket = 'A' iv_minutes = 91 iv_sauna = abap_false ).
ENDMETHOD.
METHOD sauna_adult.
assert_fee( iv_expected = '11.50' iv_ticket = 'A' iv_minutes = 45 iv_sauna = abap_true ).
ENDMETHOD.
METHOD sauna_child_ignored.
assert_fee( iv_expected = '3.50' iv_ticket = 'C' iv_minutes = 45 iv_sauna = abap_true ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,68 @@
CLASS {{p}}pool_fee DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_ticket TYPE c LENGTH 1.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS calculate_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_minutes TYPE i
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}pool_fee IMPLEMENTATION.
METHOD calculate_fee.
DATA: lv_fee TYPE ty_amount,
lv_base TYPE ty_amount,
lv_min TYPE i,
lv_blocks TYPE i,
lv_i TYPE i,
lv_help TYPE ty_amount.
" Eintrittspreis berechnen
CLEAR lv_fee.
lv_min = iv_minutes.
IF lv_min < 0.
lv_min = 0.
ENDIF.
" Grundpreis je Ticketart
IF iv_ticket = 'A'.
lv_base = '6.50'.
ELSEIF iv_ticket = 'C'.
lv_base = '3.50'.
ELSEIF iv_ticket = 'S'.
lv_base = '4.50'.
ELSEIF iv_ticket = 'F'.
lv_base = '15.00'.
ELSE.
CLEAR lv_base.
ENDIF.
lv_fee = lv_base.
" Die ersten 60 Minuten sind frei
IF lv_min > 60.
CLEAR lv_blocks.
lv_i = 60.
WHILE lv_i < lv_min.
lv_i = lv_i + 30.
lv_blocks = lv_blocks + 1.
ENDWHILE.
lv_help = lv_blocks * 1.
lv_fee = lv_fee + lv_help.
ENDIF.
" Sauna
IF iv_sauna = 'X'.
IF iv_ticket = 'C'.
" Kinder zahlen keine Sauna
ELSEIF iv_ticket = 'F'.
lv_fee = lv_fee + 8.
ELSE.
lv_fee = lv_fee + 5.
ENDIF.
ENDIF.
rv_fee = lv_fee.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,49 @@
# 1. Goal
A leisure centre sells swim tickets at its pool. A checkout program calls the
class {{P}}POOL_FEE to get the fee of one ticket. The class works, but the code
is hard to read and hard to maintain. Refactor the class. The behaviour stays
the same.
# 2. Open questions
None.
# 3. Context
- The class {{P}}POOL_FEE exists in package $TMP and is active.
- The class is the only object that you change.
- A checkout program calls the public method CALCULATE_FEE. The signature and
the result of the method must not change.
- The current implementation holds the business rules. Read it before you
change it.
# 4. Contract
- Refactor the class {{P}}POOL_FEE in package $TMP. Keep the name.
- The class stays public and final. The constructor stays public and has no
parameters.
- Keep the public interface exactly as it is:
- TYPES ty_ticket TYPE c LENGTH 1.
- TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
- METHOD calculate_fee
IMPORTING iv_ticket TYPE ty_ticket
iv_minutes TYPE i
iv_sauna TYPE abap_bool
RETURNING VALUE(rv_fee) TYPE ty_amount.
- Do not add other public methods, types or attributes.
# 5. Business rules
The behaviour of the class stays exactly the same. The rules are in the
current implementation of the class. Read the legacy code. Keep every rule,
including the rules for unusual input. Do not add a rule and do not remove a
rule.
# 6. Constraints
- Release target: SAP_BASIS 816.
- Coding standards: Clean ABAP. Methods below 40 statements. Nesting depth at
most 3. No magic numbers, use constants. No unused variables. No comment that
restates the code. No global variables.
- Out of scope: do not change any other object. Do not create new objects.
# 7. Acceptance
- The class {{P}}POOL_FEE is active and has no syntax error.
- The public interface of the class is unchanged.
- The hidden tests pass.
- Write your own ABAP Unit tests as local test classes in the class.

View File

@@ -0,0 +1,48 @@
{
"id": "G0135",
"category": "E",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "CLAS",
"name": "{{P}}POOL_FEE",
"file": "seed/pool_fee.clas.abap",
"description": "Legacy class that calculates the fee of one swim ticket"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}POOL_FEE"
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}POOL_HIDDEN",
"file": "hidden/pool_hidden.clas.abap",
"description": "Behaviour tests for the refactored pool fee class"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}POOL_FEE",
"file": "reference/pool_fee.clas.abap",
"description": "Refactored pool fee class",
"testclasses_file": "reference/pool_fee.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"nesting_depth"
]
}