Stage 2 summary at 50 accepted trajectories

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 18:02:52 +02:00
parent 332fb4601d
commit 5bcd1bf9cd
1230 changed files with 77563 additions and 33 deletions

View File

@@ -0,0 +1,43 @@
FUNCTION {{p}}lib_fee
IMPORTING
iv_media_type TYPE string
iv_days_late TYPE i
iv_value TYPE decfloat34
EXPORTING
ev_blocked TYPE abap_bool
CHANGING
cv_fee TYPE decfloat34
EXCEPTIONS
invalid_days.
DATA lv_fee TYPE decfloat34.
DATA lv_rate TYPE decfloat34.
ev_blocked = abap_true.
IF iv_days_late < 0.
RAISE invalid_days.
ENDIF.
CASE iv_media_type.
WHEN 'BOOK'.
lv_fee = iv_value * iv_days_late * 5 / 1000.
cv_fee = round( val = lv_fee dec = 2 ).
IF cv_fee > 5.
cv_fee = 5.
ENDIF.
WHEN 'DVD'.
lv_fee = iv_value * iv_days_late / 100.
cv_fee = round( val = lv_fee dec = 2 ).
IF cv_fee > 12.
cv_fee = 12.
ENDIF.
WHEN 'MAG'.
lv_rate = '0.30'.
cv_fee = iv_days_late * lv_rate.
WHEN 'REF'.
ev_blocked = abap_true.
WHEN OTHERS.
cv_fee = 0.
ENDCASE.
ENDFUNCTION.

View File

@@ -0,0 +1,43 @@
FUNCTION {{p}}lib_fee
IMPORTING
iv_media_type TYPE string
iv_days_late TYPE i
iv_value TYPE decfloat34
EXPORTING
ev_blocked TYPE abap_bool
CHANGING
cv_fee TYPE decfloat34
EXCEPTIONS
invalid_days.
DATA lv_fee TYPE decfloat34.
DATA lv_rate TYPE decfloat34.
ev_blocked = abap_false.
IF iv_days_late >= 0.
RAISE invalid_days.
ENDIF.
CASE iv_media_type.
WHEN 'BOOK'.
lv_fee = iv_value * iv_days_late * 5 / 1000.
cv_fee = round( val = lv_fee dec = 2 ).
IF cv_fee > 5.
cv_fee = 5.
ENDIF.
WHEN 'DVD'.
lv_fee = iv_value * iv_days_late / 100.
cv_fee = round( val = lv_fee dec = 2 ).
IF cv_fee > 12.
cv_fee = 12.
ENDIF.
WHEN 'MAG'.
lv_rate = '0.30'.
cv_fee = iv_days_late * lv_rate.
WHEN 'REF'.
ev_blocked = abap_true.
WHEN OTHERS.
cv_fee = 0.
ENDCASE.
ENDFUNCTION.

View File

@@ -0,0 +1,43 @@
FUNCTION {{p}}lib_fee
IMPORTING
iv_media_type TYPE string
iv_days_late TYPE i
iv_value TYPE decfloat34
EXPORTING
ev_blocked TYPE abap_bool
CHANGING
cv_fee TYPE decfloat34
EXCEPTIONS
invalid_days.
DATA lv_fee TYPE decfloat34.
DATA lv_rate TYPE decfloat34.
ev_blocked = abap_false.
IF iv_days_late < 0.
RAISE invalid_days.
ENDIF.
CASE iv_media_type.
WHEN 'BOOK'.
lv_fee = iv_value * iv_days_late / 5 / 1000.
cv_fee = round( val = lv_fee dec = 2 ).
IF cv_fee > 5.
cv_fee = 5.
ENDIF.
WHEN 'DVD'.
lv_fee = iv_value * iv_days_late / 100.
cv_fee = round( val = lv_fee dec = 2 ).
IF cv_fee > 12.
cv_fee = 12.
ENDIF.
WHEN 'MAG'.
lv_rate = '0.30'.
cv_fee = iv_days_late * lv_rate.
WHEN 'REF'.
ev_blocked = abap_true.
WHEN OTHERS.
cv_fee = 0.
ENDCASE.
ENDFUNCTION.

View File

@@ -0,0 +1,43 @@
FUNCTION {{p}}lib_fee
IMPORTING
iv_media_type TYPE string
iv_days_late TYPE i
iv_value TYPE decfloat34
EXPORTING
ev_blocked TYPE abap_bool
CHANGING
cv_fee TYPE decfloat34
EXCEPTIONS
invalid_days.
DATA lv_fee TYPE decfloat34.
DATA lv_rate TYPE decfloat34.
ev_blocked = abap_false.
IF iv_days_late < 0.
RAISE invalid_days.
ENDIF.
CASE iv_media_type.
WHEN 'BOOK'.
lv_fee = iv_value * iv_days_late * 5 / 1000.
cv_fee = round( val = lv_fee dec = 2 ).
IF cv_fee > 5.
cv_fee = 5.
ENDIF.
WHEN 'DVD'.
lv_fee = iv_value / iv_days_late / 100.
cv_fee = round( val = lv_fee dec = 2 ).
IF cv_fee > 12.
cv_fee = 12.
ENDIF.
WHEN 'MAG'.
lv_rate = '0.30'.
cv_fee = iv_days_late * lv_rate.
WHEN 'REF'.
ev_blocked = abap_true.
WHEN OTHERS.
cv_fee = 0.
ENDCASE.
ENDFUNCTION.

View File

@@ -0,0 +1,19 @@
{
"id": "G1066",
"pool": "train",
"object_type": "FUNC",
"category": "G",
"attempts": [
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 4,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,135 @@
CLASS {{p}}t41_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS get_fee
IMPORTING iv_type TYPE string
iv_days TYPE i
iv_value TYPE decfloat34
iv_fee TYPE decfloat34 DEFAULT 0
EXPORTING ev_blocked TYPE abap_bool
ev_fee TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS book_percent FOR TESTING.
METHODS book_maximum FOR TESTING.
METHODS book_rounding FOR TESTING.
METHODS book_zero_days FOR TESTING.
METHODS book_not_blocked FOR TESTING.
METHODS dvd_percent FOR TESTING.
METHODS dvd_maximum FOR TESTING.
METHODS magazine_daily FOR TESTING.
METHODS reference_blocked FOR TESTING.
METHODS other_type_zero FOR TESTING.
METHODS negative_days FOR TESTING.
ENDCLASS.
CLASS {{p}}t41_hidden IMPLEMENTATION.
METHOD get_fee.
ev_fee = iv_fee.
CALL FUNCTION '{{P}}LIB_FEE'
EXPORTING
iv_media_type = iv_type
iv_days_late = iv_days
iv_value = iv_value
IMPORTING
ev_blocked = ev_blocked
CHANGING
cv_fee = ev_fee
EXCEPTIONS
invalid_days = 1
OTHERS = 2.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD book_percent.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34 VALUE '1.50'.
get_fee( EXPORTING iv_type = 'BOOK' iv_days = 3 iv_value = 100
IMPORTING ev_fee = lv_fee ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD book_maximum.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34 VALUE '5.00'.
get_fee( EXPORTING iv_type = 'BOOK' iv_days = 2 iv_value = 1000
IMPORTING ev_fee = lv_fee ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD book_rounding.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34 VALUE '1.67'.
get_fee( EXPORTING iv_type = 'BOOK' iv_days = 1 iv_value = 333
IMPORTING ev_fee = lv_fee ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD book_zero_days.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34 VALUE '0.00'.
DATA lv_rc TYPE sysubrc.
get_fee( EXPORTING iv_type = 'BOOK' iv_days = 0 iv_value = 100
IMPORTING ev_fee = lv_fee ev_subrc = lv_rc ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_rc ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD book_not_blocked.
DATA lv_blocked TYPE abap_bool.
get_fee( EXPORTING iv_type = 'BOOK' iv_days = 1 iv_value = 100
IMPORTING ev_blocked = lv_blocked ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = lv_blocked ).
ENDMETHOD.
METHOD dvd_percent.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34 VALUE '4.00'.
get_fee( EXPORTING iv_type = 'DVD' iv_days = 2 iv_value = 200
IMPORTING ev_fee = lv_fee ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD dvd_maximum.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34 VALUE '12.00'.
get_fee( EXPORTING iv_type = 'DVD' iv_days = 3 iv_value = 1000
IMPORTING ev_fee = lv_fee ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD magazine_daily.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34 VALUE '1.20'.
get_fee( EXPORTING iv_type = 'MAG' iv_days = 4 iv_value = 50
IMPORTING ev_fee = lv_fee ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD reference_blocked.
DATA lv_fee TYPE decfloat34.
DATA lv_blocked TYPE abap_bool.
DATA lv_exp TYPE decfloat34 VALUE '7.00'.
get_fee( EXPORTING iv_type = 'REF' iv_days = 2 iv_value = 100 iv_fee = 7
IMPORTING ev_blocked = lv_blocked ev_fee = lv_fee ).
cl_abap_unit_assert=>assert_equals( exp = abap_true act = lv_blocked ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD other_type_zero.
DATA lv_fee TYPE decfloat34.
DATA lv_blocked TYPE abap_bool.
DATA lv_exp TYPE decfloat34 VALUE '0.00'.
get_fee( EXPORTING iv_type = 'XX' iv_days = 2 iv_value = 100
IMPORTING ev_blocked = lv_blocked ev_fee = lv_fee ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = lv_blocked ).
ENDMETHOD.
METHOD negative_days.
DATA lv_rc TYPE sysubrc.
get_fee( EXPORTING iv_type = 'BOOK' iv_days = -1 iv_value = 100
IMPORTING ev_subrc = lv_rc ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,64 @@
{
"task": "G1066",
"mutants": [
{
"object": "{{P}}LIB_FEE",
"mutant": "line 16: abap_false -> abap_true (bool)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"BOOK_NOT_BLOCKED",
"OTHER_TYPE_ZERO"
]
},
{
"object": "{{P}}LIB_FEE",
"mutant": "line 17: < -> >= (rel)",
"status": "killed",
"hidden": "2/11",
"failed_tests": [
"BOOK_MAXIMUM",
"BOOK_PERCENT",
"BOOK_ROUNDING",
"BOOK_ZERO_DAYS",
"DVD_MAXIMUM",
"DVD_PERCENT",
"MAGAZINE_DAILY",
"NEGATIVE_DAYS",
"REFERENCE_BLOCKED"
]
},
{
"object": "{{P}}LIB_FEE",
"mutant": "line 23: * -> / (arith)",
"status": "killed",
"hidden": "8/11",
"failed_tests": [
"BOOK_MAXIMUM",
"BOOK_PERCENT",
"BOOK_ROUNDING"
]
},
{
"object": "{{P}}LIB_FEE",
"mutant": "line 29: * -> / (arith)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"DVD_MAXIMUM",
"DVD_PERCENT"
]
},
{
"object": "{{P}}LIB_FEE",
"mutant": "line 30: 2 -> 3 (const)",
"status": "survived",
"hidden": "11/11",
"failed_tests": []
}
],
"valid": 5,
"killed": 4,
"kill_rate": 0.8,
"ok": true
}

View File

@@ -0,0 +1,43 @@
FUNCTION {{p}}lib_fee
IMPORTING
iv_media_type TYPE string
iv_days_late TYPE i
iv_value TYPE decfloat34
EXPORTING
ev_blocked TYPE abap_bool
CHANGING
cv_fee TYPE decfloat34
EXCEPTIONS
invalid_days.
DATA lv_fee TYPE decfloat34.
DATA lv_rate TYPE decfloat34.
ev_blocked = abap_false.
IF iv_days_late < 0.
RAISE invalid_days.
ENDIF.
CASE iv_media_type.
WHEN 'BOOK'.
lv_fee = iv_value * iv_days_late * 5 / 1000.
cv_fee = round( val = lv_fee dec = 2 ).
IF cv_fee > 5.
cv_fee = 5.
ENDIF.
WHEN 'DVD'.
lv_fee = iv_value * iv_days_late / 100.
cv_fee = round( val = lv_fee dec = 2 ).
IF cv_fee > 12.
cv_fee = 12.
ENDIF.
WHEN 'MAG'.
lv_rate = '0.30'.
cv_fee = iv_days_late * lv_rate.
WHEN 'REF'.
ev_blocked = abap_true.
WHEN OTHERS.
cv_fee = 0.
ENDCASE.
ENDFUNCTION.

View File

@@ -0,0 +1,81 @@
CLASS {{p}}t41_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS fee_for
IMPORTING iv_type TYPE string
iv_days TYPE i
iv_value TYPE decfloat34
RETURNING VALUE(rv_fee) TYPE decfloat34.
METHODS book_fee FOR TESTING.
METHODS dvd_fee FOR TESTING.
METHODS fee_limits FOR TESTING.
METHODS magazine_fee FOR TESTING.
METHODS negative_days FOR TESTING.
ENDCLASS.
CLASS {{p}}t41_test IMPLEMENTATION.
METHOD fee_for.
DATA lv_blocked TYPE abap_bool.
CALL FUNCTION '{{P}}LIB_FEE'
EXPORTING
iv_media_type = iv_type
iv_days_late = iv_days
iv_value = iv_value
IMPORTING
ev_blocked = lv_blocked
CHANGING
cv_fee = rv_fee
EXCEPTIONS
invalid_days = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_subrc( exp = 0 ).
ENDMETHOD.
METHOD book_fee.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34 VALUE '1.50'.
lv_fee = fee_for( iv_type = 'BOOK' iv_days = 3 iv_value = 100 ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD dvd_fee.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34 VALUE '4.00'.
lv_fee = fee_for( iv_type = 'DVD' iv_days = 2 iv_value = 200 ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD fee_limits.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34.
lv_exp = '5.00'.
lv_fee = fee_for( iv_type = 'BOOK' iv_days = 2 iv_value = 1000 ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
lv_exp = '12.00'.
lv_fee = fee_for( iv_type = 'DVD' iv_days = 3 iv_value = 1000 ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD magazine_fee.
DATA lv_fee TYPE decfloat34.
DATA lv_exp TYPE decfloat34 VALUE '1.20'.
lv_fee = fee_for( iv_type = 'MAG' iv_days = 4 iv_value = 50 ).
cl_abap_unit_assert=>assert_equals( exp = lv_exp act = lv_fee ).
ENDMETHOD.
METHOD negative_days.
DATA lv_fee TYPE decfloat34.
CALL FUNCTION '{{P}}LIB_FEE'
EXPORTING
iv_media_type = 'BOOK'
iv_days_late = -1
iv_value = 100
CHANGING
cv_fee = lv_fee
EXCEPTIONS
invalid_days = 1
OTHERS = 2.
cl_abap_unit_assert=>assert_equals( exp = 1 act = sy-subrc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,15 @@
FUNCTION {{p}}lib_sample
IMPORTING
iv_media_type TYPE string
iv_days_late TYPE i
iv_value TYPE decfloat34
EXPORTING
ev_blocked TYPE abap_bool
CHANGING
cv_fee TYPE decfloat34
EXCEPTIONS
invalid_days.
ev_blocked = abap_false.
ENDFUNCTION.

View File

@@ -0,0 +1,47 @@
# 1. Goal
A municipal library charges a fee when a borrower returns a media item after
the due date. The returns desk calls one function module for each returned
item. The function module must have the same interface as the sample function
module, because the returns desk calls all fee modules in the same way.
# 2. Open questions
None.
# 3. Context
- Function group {{P}}FG_LIB exists in package $TMP.
- Function module {{P}}LIB_SAMPLE exists in this group. It is the sample fee
module. Its interface is the interface that all fee modules must use.
# 4. Contract
- Create the function module {{P}}LIB_FEE in function group {{P}}FG_LIB.
- Use exactly the interface of {{P}}LIB_SAMPLE: the same parameter names,
kinds, types, and exceptions.
- The parameters have this meaning:
- iv_media_type: the media type of the returned item.
- iv_days_late: the number of days between the due date and the return date.
- iv_value: the replacement value of the item in euro.
- ev_blocked: the borrower is blocked when this flag is true.
- cv_fee: the fee in euro. The caller can pass an initial value.
# 5. Business rules
1. If iv_days_late is less than 0, raise the exception INVALID_DAYS.
2. Set ev_blocked to false, except in rule 6.
3. Media type BOOK: the fee is iv_value * iv_days_late * 0.5 / 100. Round the
fee half up to 2 decimals. The maximum fee is 5.00.
4. Media type DVD: the fee is iv_value * iv_days_late * 1 / 100. Round the fee
half up to 2 decimals. The maximum fee is 12.00.
5. Media type MAG: the fee is 0.30 for each day late. There is no maximum.
6. Media type REF: set ev_blocked to true. Do not change cv_fee.
7. Any other media type: the fee is 0.
# 6. Constraints
- Release target: 7.02. Use only ABAP syntax that release 7.02 supports.
- Follow Clean ABAP. Keep every method below 40 statements.
- Out of scope: do not change {{P}}LIB_SAMPLE.
- Do not use application tables.
- Write ABAP Unit tests for the function module in a global test class.
# 7. Acceptance
- The function module {{P}}LIB_FEE is active and has no syntax error.
- The hidden tests pass.
- Your ABAP Unit tests pass.

View File

@@ -0,0 +1,84 @@
{
"id": "G1066",
"category": "G",
"object_type": "FUNC",
"difficulty": 2,
"release_target": "v702",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "FUGR",
"name": "{{P}}FG_LIB",
"description": "Function group for library fee modules"
},
{
"type": "FUNC",
"name": "{{P}}LIB_SAMPLE",
"functionGroup": "{{P}}FG_LIB",
"file": "seed/lib_sample.func.abap",
"description": "Sample fee module that fixes the interface"
}
],
"contract": [
{
"type": "FUNC",
"name": "{{P}}LIB_FEE",
"functionGroup": "{{P}}FG_LIB",
"params": [
{
"name": "iv_media_type",
"type": "string"
},
{
"name": "iv_days_late",
"type": "i"
},
{
"name": "iv_value",
"type": "decfloat34"
},
{
"name": "ev_blocked",
"type": "abap_bool"
},
{
"name": "cv_fee",
"type": "decfloat34"
}
]
}
],
"out_of_scope": [
"{{P}}LIB_SAMPLE"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T41_HIDDEN",
"file": "hidden/t41_hidden.clas.abap",
"description": "T41 hidden tests"
}
],
"reference": [
{
"type": "FUNC",
"name": "{{P}}LIB_FEE",
"functionGroup": "{{P}}FG_LIB",
"file": "reference/lib_fee.func.abap",
"description": "Library overdue fee module"
},
{
"type": "CLAS",
"name": "{{P}}T41_TEST",
"file": "reference/t41_test.clas.abap",
"description": "T41 own tests"
}
],
"craft_checks": [
"method_length"
]
}