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,42 @@
{
"id": "G1093",
"pool": "train",
"object_type": "FUNC",
"category": "C",
"attempts": [
{
"stage": "bundle",
"errors": [
"reference/mix_test.clas.abap line 52: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"reference/mix_test.clas.abap line 52: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"5\"",
"hidden/mix_hidden.clas.abap line 52: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/mix_hidden.clas.abap line 52: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"5\"",
"hidden/mix_hidden.clas.abap line 63: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/mix_hidden.clas.abap line 63: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"5\"",
"hidden/mix_hidden.clas.abap line 100: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/mix_hidden.clas.abap line 100: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"5\"",
"hidden/mix_hidden.clas.abap line 119: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\"",
"hidden/mix_hidden.clas.abap line 119: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"5\""
],
"by_check": {
"abaplint": 10
}
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 0,
"null": 0
}
],
"accepted": false
}

View File

@@ -0,0 +1,121 @@
CLASS {{p}}mix_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS call
IMPORTING it_tints TYPE {{P}}PAINT_MIX=>TY_TINTS
EXPORTING ev_volume TYPE decfloat34
ev_price TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS empty_table FOR TESTING.
METHODS single_tint FOR TESTING.
METHODS duplicate_tints FOR TESTING.
METHODS two_tints FOR TESTING.
METHODS zero_quantity FOR TESTING.
METHODS negative_quantity FOR TESTING.
METHODS unknown_tint FOR TESTING.
METHODS rounding FOR TESTING.
METHODS quantity_checked_first FOR TESTING.
METHODS fee_per_distinct_tint FOR TESTING.
ENDCLASS.
CLASS {{p}}mix_hidden IMPLEMENTATION.
METHOD call.
CALL FUNCTION '{{P}}MIX_PRICE'
EXPORTING
it_tints = it_tints
IMPORTING
ev_volume = ev_volume
ev_price = ev_price
EXCEPTIONS
no_components = 1
invalid_quantity = 2
unknown_tint = 3
OTHERS = 4.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD empty_table.
DATA lt_tints TYPE {{P}}PAINT_MIX=>TY_TINTS.
call( EXPORTING it_tints = lt_tints
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_subrc ).
ENDMETHOD.
METHOD single_tint.
call( EXPORTING it_tints = VALUE #( ( tint_id = 'WHIT' quantity_ml = 1000 ) )
IMPORTING ev_volume = DATA(lv_volume)
ev_price = DATA(lv_price)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 1000 ) act = lv_volume ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '21.5' ) act = lv_price ).
ENDMETHOD.
METHOD duplicate_tints.
call( EXPORTING it_tints = VALUE #( ( tint_id = 'WHIT' quantity_ml = 1000 )
( tint_id = 'WHIT' quantity_ml = 500 ) )
IMPORTING ev_volume = DATA(lv_volume)
ev_price = DATA(lv_price)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 1500 ) act = lv_volume ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '31.5' ) act = lv_price ).
ENDMETHOD.
METHOD two_tints.
call( EXPORTING it_tints = VALUE #( ( tint_id = 'WHIT' quantity_ml = 1000 )
( tint_id = 'BLUE' quantity_ml = 200 ) )
IMPORTING ev_volume = DATA(lv_volume)
ev_price = DATA(lv_price)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 1200 ) act = lv_volume ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 32 ) act = lv_price ).
ENDMETHOD.
METHOD zero_quantity.
call( EXPORTING it_tints = VALUE #( ( tint_id = 'WHIT' quantity_ml = 0 ) )
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_subrc ).
ENDMETHOD.
METHOD negative_quantity.
call( EXPORTING it_tints = VALUE #( ( tint_id = 'BLUE' quantity_ml = -5 ) )
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_subrc ).
ENDMETHOD.
METHOD unknown_tint.
call( EXPORTING it_tints = VALUE #( ( tint_id = 'XXXX' quantity_ml = 100 ) )
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lv_subrc ).
ENDMETHOD.
METHOD rounding.
call( EXPORTING it_tints = VALUE #( ( tint_id = 'BLUE' quantity_ml = 111 ) )
IMPORTING ev_price = DATA(lv_price)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '6.5' ) act = lv_price ).
ENDMETHOD.
METHOD quantity_checked_first.
call( EXPORTING it_tints = VALUE #( ( tint_id = 'XXXX' quantity_ml = 100 )
( tint_id = 'WHIT' quantity_ml = 0 ) )
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_subrc ).
ENDMETHOD.
METHOD fee_per_distinct_tint.
call( EXPORTING it_tints = VALUE #( ( tint_id = 'WHIT' quantity_ml = 100 )
( tint_id = 'WHIT' quantity_ml = 100 )
( tint_id = 'BLUE' quantity_ml = 100 ) )
IMPORTING ev_volume = DATA(lv_volume)
ev_price = DATA(lv_price)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 300 ) act = lv_volume ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '11.5' ) act = lv_price ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,65 @@
{
"task": "T_C_MIX",
"mutants": [
{
"object": "{{P}}MIX_PRICE",
"mutant": "line 33: <= -> < (rel)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"ZERO_QUANTITY"
]
},
{
"object": "{{P}}MIX_PRICE",
"mutant": "line 53: + -> - (arith)",
"status": "killed",
"hidden": "6/10",
"failed_tests": [
"SINGLE_TINT",
"DUPLICATE_TINTS",
"TWO_TINTS",
"FEE_PER_DISTINCT_TINT"
]
},
{
"object": "{{P}}MIX_PRICE",
"mutant": "line 53: * -> + (arith)",
"status": "killed",
"hidden": "5/10",
"failed_tests": [
"SINGLE_TINT",
"DUPLICATE_TINTS",
"TWO_TINTS",
"ROUNDING",
"FEE_PER_DISTINCT_TINT"
]
},
{
"object": "{{P}}MIX_PRICE",
"mutant": "line 56: c_mix_fee 1.5 -> 1.6 (const)",
"status": "killed",
"hidden": "5/10",
"failed_tests": [
"SINGLE_TINT",
"DUPLICATE_TINTS",
"TWO_TINTS",
"ROUNDING",
"FEE_PER_DISTINCT_TINT"
]
},
{
"object": "{{P}}MIX_PRICE",
"mutant": "line 57: round_half_up -> round_half_down (mode)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"ROUNDING"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,57 @@
FUNCTION {{P}}MIX_PRICE
IMPORTING
it_tints TYPE {{P}}PAINT_MIX=>TY_TINTS
EXPORTING
ev_volume TYPE decfloat34
ev_price TYPE decfloat34
EXCEPTIONS
no_components
invalid_quantity
unknown_tint.
CONSTANTS c_mix_fee TYPE decfloat34 VALUE '1.5'.
TYPES: ty_id TYPE c LENGTH 4,
ty_ids TYPE SORTED TABLE OF ty_id WITH UNIQUE KEY table_line,
BEGIN OF ty_price,
tint_id TYPE c LENGTH 4,
price_ml TYPE p LENGTH 13 DECIMALS 3,
END OF ty_price,
ty_prices TYPE SORTED TABLE OF ty_price WITH UNIQUE KEY tint_id.
IF it_tints IS INITIAL.
RAISE no_components.
ENDIF.
DATA lt_ids TYPE ty_ids.
LOOP AT it_tints INTO DATA(ls_tint).
IF ls_tint-quantity_ml <= 0.
RAISE invalid_quantity.
ENDIF.
INSERT VALUE #( table_line = ls_tint-tint_id ) INTO TABLE lt_ids.
ENDLOOP.
DATA lt_prices TYPE ty_prices.
SELECT tint_id, price_ml FROM {{P}}TINTPR
WHERE tint_id IN @lt_ids
ORDER BY tint_id
INTO TABLE @lt_prices.
LOOP AT lt_ids INTO DATA(lv_id).
READ TABLE lt_prices WITH TABLE KEY tint_id = lv_id TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
RAISE unknown_tint.
ENDIF.
ENDLOOP.
DATA lv_material TYPE decfloat34.
LOOP AT it_tints INTO DATA(ls_item).
READ TABLE lt_prices INTO DATA(ls_price) WITH TABLE KEY tint_id = ls_item-tint_id.
ev_volume = ev_volume + ls_item-quantity_ml.
lv_material = lv_material + ls_item-quantity_ml * ls_price-price_ml.
ENDLOOP.
ev_price = round( val = lv_material + lines( lt_ids ) * c_mix_fee
dec = 2 mode = cl_abap_math=>round_half_up ).
ENDFUNCTION.

View File

@@ -0,0 +1,73 @@
CLASS {{p}}mix_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS price_of
IMPORTING it_tints TYPE {{P}}PAINT_MIX=>TY_TINTS
EXPORTING ev_volume TYPE decfloat34
ev_price TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS two_tints FOR TESTING.
METHODS repeated_tint FOR TESTING.
METHODS empty_order FOR TESTING.
METHODS bad_quantity FOR TESTING.
METHODS unknown_tint FOR TESTING.
ENDCLASS.
CLASS {{p}}mix_test IMPLEMENTATION.
METHOD price_of.
CALL FUNCTION '{{P}}MIX_PRICE'
EXPORTING
it_tints = it_tints
IMPORTING
ev_volume = ev_volume
ev_price = ev_price
EXCEPTIONS
no_components = 1
invalid_quantity = 2
unknown_tint = 3
OTHERS = 4.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD two_tints.
price_of( EXPORTING it_tints = VALUE #( ( tint_id = 'WHIT' quantity_ml = 1000 )
( tint_id = 'BLUE' quantity_ml = 200 ) )
IMPORTING ev_volume = DATA(lv_volume)
ev_price = DATA(lv_price)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 1200 ) act = lv_volume ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 32 ) act = lv_price ).
ENDMETHOD.
METHOD repeated_tint.
price_of( EXPORTING it_tints = VALUE #( ( tint_id = 'GREY' quantity_ml = 200 )
( tint_id = 'GREY' quantity_ml = 300 ) )
IMPORTING ev_volume = DATA(lv_volume)
ev_price = DATA(lv_price)
ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 500 ) act = lv_volume ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '16.5' ) act = lv_price ).
ENDMETHOD.
METHOD empty_order.
DATA lt_tints TYPE {{P}}PAINT_MIX=>TY_TINTS.
price_of( EXPORTING it_tints = lt_tints
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_subrc ).
ENDMETHOD.
METHOD bad_quantity.
price_of( EXPORTING it_tints = VALUE #( ( tint_id = 'GOLD' quantity_ml = -1 ) )
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_subrc ).
ENDMETHOD.
METHOD unknown_tint.
price_of( EXPORTING it_tints = VALUE #( ( tint_id = 'ZZZZ' quantity_ml = 10 ) )
IMPORTING ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lv_subrc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,17 @@
FUNCTION {{P}}MIX_SAMPLE
IMPORTING
it_tints TYPE {{P}}PAINT_MIX=>TY_TINTS
EXPORTING
ev_volume TYPE decfloat34
EXCEPTIONS
no_components.
IF it_tints IS INITIAL.
RAISE no_components.
ENDIF.
LOOP AT it_tints INTO DATA(ls_tint).
ev_volume = ev_volume + ls_tint-quantity_ml.
ENDLOOP.
ENDFUNCTION.

View File

@@ -0,0 +1,28 @@
CLASS {{p}}paint_mix DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_tint,
tint_id TYPE c LENGTH 4,
quantity_ml TYPE i,
END OF ty_tint,
ty_tints TYPE STANDARD TABLE OF ty_tint WITH EMPTY KEY.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS {{p}}paint_mix IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA lt_prices TYPE STANDARD TABLE OF {{p}}tintpr WITH EMPTY KEY.
lt_prices = VALUE #(
( tint_id = 'WHIT' price_ml = '0.020' )
( tint_id = 'BLUE' price_ml = '0.045' )
( tint_id = 'GREY' price_ml = '0.030' )
( tint_id = 'GOLD' price_ml = '0.250' ) ).
DELETE FROM {{p}}tintpr.
INSERT {{p}}tintpr FROM TABLE @lt_prices.
out->write( |Tint prices seeded: { lines( lt_prices ) }| ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,10 @@
@EndUserText.label : 'Tint prices'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}tintpr {
key client : abap.clnt not null;
key tint_id : abap.char(4) not null;
price_ml : abap.dec(13,3) not null;
}

View File

@@ -0,0 +1,73 @@
# 1. Goal
A paint shop mixes custom paint colours. A customer order contains one or more
tint components. The checkout program calls one function module for each order.
The function module returns the total volume and the price of the mix.
# 2. Open questions
None.
# 3. Context
- The class {{P}}PAINT_MIX exists in package $TMP. It contains the public types
ty_tint and ty_tints. The checkout program and the function module use these
types.
- The table {{P}}TINTPR exists in package $TMP. It contains the price of one
millilitre of each tint. The class {{P}}PAINT_MIX fills this table.
- The function group {{P}}FG_PAINT exists in package $TMP.
- The function module {{P}}MIX_SAMPLE exists in this function group. It is a
sample. It shows the interface that the checkout program uses.
# 4. Contract
- Create the function module {{P}}MIX_PRICE in function group {{P}}FG_PAINT.
- Use exactly this interface:
IMPORTING
it_tints TYPE {{P}}PAINT_MIX=>TY_TINTS
EXPORTING
ev_volume TYPE decfloat34
ev_price TYPE decfloat34
EXCEPTIONS
no_components
invalid_quantity
unknown_tint
- The type {{P}}PAINT_MIX=>ty_tint has these components:
tint_id type c, length 4
quantity_ml type i
- The type {{P}}PAINT_MIX=>ty_tints is a table of ty_tint.
- The table {{P}}TINTPR has these fields:
tint_id type c, length 4
price_ml type packed number, 13 digits, 3 decimals
- The table {{P}}TINTPR contains this data:
WHIT 0.020
BLUE 0.045
GREY 0.030
GOLD 0.250
# 5. Business rules
1. The component quantity_ml is a volume in millilitres.
2. If it_tints is empty, raise the exception NO_COMPONENTS.
3. If a component has a quantity_ml of zero or less, raise the exception
INVALID_QUANTITY.
4. If a component has a tint_id that is not in the table {{P}}TINTPR, raise the
exception UNKNOWN_TINT.
5. Check rule 2 first. Then check rule 3 for all components. Then check rule 4
for all components. Raise only the first exception that occurs.
6. ev_volume is the sum of the quantity_ml of all components. If the same
tint_id occurs more than once, all its quantities count.
7. The material price of a component is its quantity_ml multiplied by the
price_ml of its tint.
8. The mixing fee is 1.50 for each different tint_id in the order. A tint_id
that occurs more than once counts once.
9. ev_price is the sum of the material prices of all components plus the mixing
fee. Round ev_price half up to 2 decimals.
# 6. Constraints
- Release target: 7.58 (the system runs SAP_BASIS 816).
- Use Clean ABAP. Keep each method below 40 statements.
- Out of scope: do not change the class {{P}}PAINT_MIX, the table {{P}}TINTPR,
and the function module {{P}}MIX_SAMPLE.
# 7. Acceptance
- The function module {{P}}MIX_PRICE 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

@@ -0,0 +1,91 @@
{
"id": "G1093",
"category": "C",
"object_type": "FUNC",
"difficulty": 2,
"release_target": "v758",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "TABL",
"name": "{{P}}TINTPR",
"file": "seed/tintpr.tabl.abap",
"description": "Price of one millilitre of each tint"
},
{
"type": "CLAS",
"name": "{{P}}PAINT_MIX",
"file": "seed/paint_mix.clas.abap",
"description": "Component types and tint price seed data",
"run": true
},
{
"type": "FUGR",
"name": "{{P}}FG_PAINT",
"description": "Paint mixing"
},
{
"type": "FUNC",
"name": "{{P}}MIX_SAMPLE",
"functionGroup": "{{P}}FG_PAINT",
"file": "seed/mix_sample.func.abap",
"description": "Sample module that shows the interface"
}
],
"contract": [
{
"type": "FUNC",
"name": "{{P}}MIX_PRICE",
"functionGroup": "{{P}}FG_PAINT",
"params": [
{
"name": "it_tints",
"type": "{{P}}PAINT_MIX=>TY_TINTS"
},
{
"name": "ev_volume",
"type": "decfloat34"
},
{
"name": "ev_price",
"type": "decfloat34"
}
]
}
],
"out_of_scope": [
"{{P}}PAINT_MIX",
"{{P}}TINTPR",
"{{P}}MIX_SAMPLE"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}MIX_HIDDEN",
"file": "hidden/mix_hidden.clas.abap",
"description": "Hidden tests for the paint mix price"
}
],
"reference": [
{
"type": "FUNC",
"name": "{{P}}MIX_PRICE",
"functionGroup": "{{P}}FG_PAINT",
"file": "reference/mix_price.func.abap",
"description": "Paint mix price"
},
{
"type": "CLAS",
"name": "{{P}}MIX_TEST",
"file": "reference/mix_test.clas.abap",
"description": "Own tests for the paint mix price"
}
],
"craft_checks": [
"method_length"
]
}