Snapshot: new training tasks (balanced generation), docs

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 22:08:59 +02:00
parent eb13453097
commit 6984fc7917
572 changed files with 30024 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Rental fee'
define view entity {{P}}I_RENTAL_FEE
as select from {{p}}rental as rental
{
key rental.rental_id as rental_id,
rental.car_group as car_group,
rental.rental_days as rental_days,
cast(
case rental.car_group
when 'C' then case rental.season when 'H' then 96 else 80 end
when 'B' then case rental.season when 'Z' then 60 else 50 end
else case rental.season when 'H' then 36 else 30 end
end
* case when rental.rental_days >= 7 then rental.rental_days - 1 else rental.rental_days end
+ case rental.car_group
when 'C' then 25
when 'B' then 15
else 10
end
as abap.dec( 15, 2 ) ) as fee
}

View File

@@ -0,0 +1,22 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Rental fee'
define view entity {{P}}I_RENTAL_FEE
as select from {{p}}rental as rental
{
key rental.rental_id as rental_id,
rental.car_group as car_group,
rental.rental_days as rental_days,
cast(
case rental.car_group
when 'C' then case rental.season when 'H' then 96 else 80 end
when 'B' then case rental.season when 'H' then 60 else 50 end
else case rental.season when 'H' then 36 else 30 end
end
* case when rental.rental_days >= 8 then rental.rental_days - 1 else rental.rental_days end
+ case rental.car_group
when 'C' then 25
when 'B' then 15
else 10
end
as abap.dec( 15, 2 ) ) as fee
}

View File

@@ -0,0 +1,22 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Rental fee'
define view entity {{P}}I_RENTAL_FEE
as select from {{p}}rental as rental
{
key rental.rental_id as rental_id,
rental.car_group as car_group,
rental.rental_days as rental_days,
cast(
case rental.car_group
when 'C' then case rental.season when 'H' then 96 else 80 end
when 'B' then case rental.season when 'H' then 60 else 50 end
else case rental.season when 'H' then 36 else 30 end
end
* case when rental.rental_days >= 7 then rental.rental_days - 1 else rental.rental_days end
- case rental.car_group
when 'C' then 25
when 'B' then 15
else 10
end
as abap.dec( 15, 2 ) ) as fee
}

View File

@@ -0,0 +1,22 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Rental fee'
define view entity {{P}}I_RENTAL_FEE
as select from {{p}}rental as rental
{
key rental.rental_id as rental_id,
rental.car_group as car_group,
rental.rental_days as rental_days,
cast(
case rental.car_group
when 'C' then case rental.season when 'H' then 96 else 80 end
when 'B' then case rental.season when 'H' then 60 else 50 end
else case rental.season when 'H' then 36 else 30 end
end
* case when rental.rental_days >= 7 then rental.rental_days - 1 else rental.rental_days end
+ case rental.car_group
when 'Z' then 25
when 'B' then 15
else 10
end
as abap.dec( 15, 2 ) ) as fee
}

View File

@@ -0,0 +1,22 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Rental fee'
define view entity {{P}}I_RENTAL_FEE
as select from {{p}}rental as rental
{
key rental.rental_id as rental_id,
rental.car_group as car_group,
rental.rental_days as rental_days,
cast(
case rental.car_group
when 'C' then case rental.season when 'H' then 96 else 80 end
when 'B' then case rental.season when 'H' then 60 else 50 end
else case rental.season when 'H' then 36 else 30 end
end
* case when rental.rental_days >= 7 then rental.rental_days - 1 else rental.rental_days end
+ case rental.car_group
when 'C' then 25
when 'B' then 15
else 11
end
as abap.dec( 15, 2 ) ) as fee
}

View File

@@ -0,0 +1,28 @@
{
"id": "G1931",
"pool": "train",
"object_type": "DDLS",
"category": "E",
"attempts": [
{
"stage": "bundle",
"errors": [
"seed/rental.tabl.asabap: field name days is a reserved word; choose another name"
],
"by_check": {
"static": 1
}
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 5,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,131 @@
CLASS {{p}}e_rental_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_cds_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS setup.
METHODS short_low_season FOR TESTING.
METHODS short_high_season FOR TESTING.
METHODS free_day_at_seven FOR TESTING.
METHODS free_day_group_a FOR TESTING.
METHODS six_days_no_free FOR TESTING.
METHODS long_group_c FOR TESTING.
METHODS unknown_group FOR TESTING.
METHODS unknown_season FOR TESTING.
METHODS seven_days_group_b FOR TESTING.
METHODS columns_shown FOR TESTING.
METHODS all_rows_shown FOR TESTING.
ENDCLASS.
CLASS {{p}}e_rental_hidden IMPLEMENTATION.
METHOD class_setup.
go_env = cl_cds_test_environment=>create( i_for_entity = '{{P}}I_RENTAL_FEE' ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD setup.
DATA lt_rental TYPE STANDARD TABLE OF {{p}}rental WITH EMPTY KEY.
go_env->clear_doubles( ).
lt_rental = VALUE #(
( rental_id = 'R01' car_group = 'A' season = 'L' rental_days = 3 )
( rental_id = 'R02' car_group = 'B' season = 'H' rental_days = 2 )
( rental_id = 'R03' car_group = 'C' season = 'L' rental_days = 7 )
( rental_id = 'R04' car_group = 'A' season = 'H' rental_days = 10 )
( rental_id = 'R05' car_group = 'B' season = 'L' rental_days = 6 )
( rental_id = 'R06' car_group = 'C' season = 'H' rental_days = 14 )
( rental_id = 'R07' car_group = 'X' season = 'L' rental_days = 1 )
( rental_id = 'R08' car_group = 'A' season = 'X' rental_days = 1 )
( rental_id = 'R09' car_group = 'B' season = 'H' rental_days = 7 ) ).
go_env->insert_test_data( lt_rental ).
ENDMETHOD.
METHOD short_low_season.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'R01' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '100.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD short_high_season.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'R02' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '135.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD free_day_at_seven.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'R03' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '505.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD free_day_group_a.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'R04' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '334.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD six_days_no_free.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'R05' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '315.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD long_group_c.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'R06' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '1273.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD unknown_group.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'R07' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '40.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD unknown_season.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'R08' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '40.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD seven_days_group_b.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'R09' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '375.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD columns_shown.
SELECT SINGLE rental_id, car_group, rental_days FROM {{p}}i_rental_fee
WHERE rental_id = 'R01' INTO @DATA(ls_row).
cl_abap_unit_assert=>assert_equals( exp = 'R01' act = ls_row-rental_id ).
cl_abap_unit_assert=>assert_equals( exp = 'A' act = ls_row-car_group ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = ls_row-rental_days ).
ENDMETHOD.
METHOD all_rows_shown.
SELECT COUNT(*) FROM {{p}}i_rental_fee INTO @DATA(lv_rows).
cl_abap_unit_assert=>assert_equals( exp = 9 act = lv_rows ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,68 @@
{
"task": "G1931",
"mutants": [
{
"object": "{{P}}I_RENTAL_FEE",
"mutant": "line 12: 'H' -> 'Z' (lit)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"SEVEN_DAYS_GROUP_B",
"SHORT_HIGH_SEASON"
]
},
{
"object": "{{P}}I_RENTAL_FEE",
"mutant": "line 15: 7 -> 8 (const)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"FREE_DAY_AT_SEVEN",
"SEVEN_DAYS_GROUP_B"
]
},
{
"object": "{{P}}I_RENTAL_FEE",
"mutant": "line 16: + -> - (arith)",
"status": "killed",
"hidden": "2/11",
"failed_tests": [
"FREE_DAY_AT_SEVEN",
"FREE_DAY_GROUP_A",
"LONG_GROUP_C",
"SEVEN_DAYS_GROUP_B",
"SHORT_HIGH_SEASON",
"SHORT_LOW_SEASON",
"SIX_DAYS_NO_FREE",
"UNKNOWN_GROUP",
"UNKNOWN_SEASON"
]
},
{
"object": "{{P}}I_RENTAL_FEE",
"mutant": "line 17: 'C' -> 'Z' (lit)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"FREE_DAY_AT_SEVEN",
"LONG_GROUP_C"
]
},
{
"object": "{{P}}I_RENTAL_FEE",
"mutant": "line 19: 10 -> 11 (const)",
"status": "killed",
"hidden": "7/11",
"failed_tests": [
"FREE_DAY_GROUP_A",
"SHORT_LOW_SEASON",
"UNKNOWN_GROUP",
"UNKNOWN_SEASON"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,56 @@
CLASS {{p}}e_rental_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_cds_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS setup.
METHODS short_rental_fee FOR TESTING.
METHODS long_rental_fee FOR TESTING.
METHODS default_group FOR TESTING.
ENDCLASS.
CLASS {{p}}e_rental_test IMPLEMENTATION.
METHOD class_setup.
go_env = cl_cds_test_environment=>create( i_for_entity = '{{P}}I_RENTAL_FEE' ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD setup.
DATA lt_rental TYPE STANDARD TABLE OF {{p}}rental WITH EMPTY KEY.
go_env->clear_doubles( ).
lt_rental = VALUE #(
( rental_id = 'A1' car_group = 'A' season = 'L' rental_days = 2 )
( rental_id = 'B1' car_group = 'B' season = 'H' rental_days = 9 )
( rental_id = 'Z1' car_group = 'Z' season = 'H' rental_days = 1 ) ).
go_env->insert_test_data( lt_rental ).
ENDMETHOD.
METHOD short_rental_fee.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'A1' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '70.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD long_rental_fee.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'B1' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '495.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
METHOD default_group.
SELECT SINGLE fee FROM {{p}}i_rental_fee
WHERE rental_id = 'Z1' INTO @DATA(lv_fee).
cl_abap_unit_assert=>assert_equals(
exp = CONV decfloat34( '46.00' )
act = CONV decfloat34( lv_fee ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,22 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Rental fee'
define view entity {{P}}I_RENTAL_FEE
as select from {{p}}rental as rental
{
key rental.rental_id as rental_id,
rental.car_group as car_group,
rental.rental_days as rental_days,
cast(
case rental.car_group
when 'C' then case rental.season when 'H' then 96 else 80 end
when 'B' then case rental.season when 'H' then 60 else 50 end
else case rental.season when 'H' then 36 else 30 end
end
* case when rental.rental_days >= 7 then rental.rental_days - 1 else rental.rental_days end
+ case rental.car_group
when 'C' then 25
when 'B' then 15
else 10
end
as abap.dec( 15, 2 ) ) as fee
}

View File

@@ -0,0 +1,29 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Rental fee'
define view entity {{P}}I_RENTAL_FEE
as select from {{p}}rental as rental
{
key rental.rental_id as rental_id,
rental.car_group as car_group,
rental.rental_days as rental_days,
cast(
case when rental.rental_days >= 7
then case when rental.car_group = 'C' then case when rental.season = 'H' then 96 else 80 end
when rental.car_group = 'B' then case when rental.season = 'H' then 60 else 50 end
else case when rental.season = 'H' then 36 else 30 end
end * ( rental.rental_days - 1 )
+ case when rental.car_group = 'C' then 25
when rental.car_group = 'B' then 15
else 10
end
else case when rental.car_group = 'C' then case when rental.season = 'H' then 96 else 80 end
when rental.car_group = 'B' then case when rental.season = 'H' then 60 else 50 end
else case when rental.season = 'H' then 36 else 30 end
end * rental.rental_days
+ case when rental.car_group = 'C' then 25
when rental.car_group = 'B' then 15
else 10
end
end
as abap.dec( 15, 2 ) ) as fee
}

View File

@@ -0,0 +1,12 @@
@EndUserText.label : 'Rental'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}rental {
key client : abap.clnt not null;
key rental_id : abap.char(10) not null;
car_group : abap.char(1);
season : abap.char(1);
rental_days : abap.int4;
}

View File

@@ -0,0 +1,44 @@
# 1. Goal
The CDS view entity {{P}}I_RENTAL_FEE in package $TMP shows the fee of each
rental of a car rental company. The view returns correct data, but its source
is long and hard to read. Refactor the view in place. The behavior must stay
the same.
# 2. Open questions
None.
# 3. Context
- Table {{P}}RENTAL, package $TMP. One row for each rental.
Key: RENTAL_ID (CHAR 10).
Fields: CAR_GROUP (CHAR 1), SEASON (CHAR 1), RENTAL_DAYS (INT4).
- The CDS view entity {{P}}I_RENTAL_FEE already exists in package $TMP. The
view is active. It reads the table {{P}}RENTAL.
- The source of the view is the only specification of the fee. Read the
source before you change it.
# 4. Contract
- Refactor the CDS view entity {{P}}I_RENTAL_FEE in package $TMP. The name
stays the same. Do not create a second view.
- Elements, with these names and this order: RENTAL_ID (key), CAR_GROUP,
RENTAL_DAYS, FEE.
- The view keeps the annotation @AccessControl.authorizationCheck:
#NOT_REQUIRED.
- The view shows one row for each row of the table {{P}}RENTAL.
# 5. Business rules
1. The behavior of the view stays the same. The FEE of each row must not
change.
2. Rule 1 holds for all values of CAR_GROUP, SEASON and RENTAL_DAYS. This
includes values that the source does not name.
3. The element names and the element order stay the same.
# 6. Constraints
- Release target: 8.16.
- Coding standards: clean ABAP. The refactored source must be easy to read.
Remove the deep nesting and the repeated logic. Keep the expressions short.
- Out of scope: do not change the table {{P}}RENTAL.
# 7. Acceptance
- The view {{P}}I_RENTAL_FEE is active and has no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests with CL_CDS_TEST_ENVIRONMENT in a global test class.

View File

@@ -0,0 +1,64 @@
{
"id": "G1931",
"category": "E",
"object_type": "DDLS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "TABL",
"name": "{{P}}RENTAL",
"file": "seed/rental.tabl.asabap",
"description": "Rental record of the car rental company"
},
{
"type": "DDLS",
"name": "{{P}}I_RENTAL_FEE",
"file": "seed/i_rental_fee.ddls.asddls",
"description": "Legacy rental fee view with deeply nested CASE expressions"
}
],
"contract": [
{
"type": "DDLS",
"name": "{{P}}I_RENTAL_FEE",
"fields": [
"RENTAL_ID",
"CAR_GROUP",
"RENTAL_DAYS",
"FEE"
]
}
],
"out_of_scope": [
"{{P}}RENTAL"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}E_RENTAL_HIDDEN",
"file": "hidden/e_rental_hidden.clas.abap",
"description": "Hidden tests for the unchanged behavior of the rental fee view"
}
],
"reference": [
{
"type": "DDLS",
"name": "{{P}}I_RENTAL_FEE",
"file": "reference/i_rental_fee.ddls.asddls",
"description": "Clean rental fee view entity"
},
{
"type": "CLAS",
"name": "{{P}}E_RENTAL_TEST",
"file": "reference/e_rental_test.clas.abap",
"description": "Own tests for the rental fee view"
}
],
"craft_checks": []
}