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,108 @@
CLASS {{p}}pallet_allocator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_category TYPE c LENGTH 2.
TYPES ty_weight TYPE i.
TYPES ty_height TYPE i.
TYPES:
BEGIN OF ty_slot,
aisle TYPE c LENGTH 2,
rack TYPE i,
temp_zone TYPE c LENGTH 2,
is_valid TYPE abap_bool,
END OF ty_slot.
METHODS constructor.
METHODS allocate
IMPORTING
iv_category TYPE ty_category
iv_weight_kg TYPE ty_weight
iv_height_cm TYPE ty_height
RETURNING
VALUE(rs_slot) TYPE ty_slot.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_zone,
category TYPE ty_category,
aisle TYPE c LENGTH 2,
temp TYPE c LENGTH 2,
END OF ty_zone,
tt_zone TYPE HASHED TABLE OF ty_zone WITH UNIQUE KEY category.
CONSTANTS:
c_min_weight TYPE ty_weight VALUE 20,
c_max_weight TYPE ty_weight VALUE 800,
c_min_height TYPE ty_height VALUE 40,
c_base_height TYPE ty_height VALUE 120,
c_height_step TYPE ty_height VALUE 40,
c_max_rack TYPE i VALUE 4.
METHODS zones
RETURNING VALUE(rt_zone) TYPE tt_zone.
METHODS normalized_category
IMPORTING iv_category TYPE ty_category
RETURNING VALUE(rv_category) TYPE ty_category.
METHODS rack_for_height
IMPORTING iv_height_cm TYPE ty_height
RETURNING VALUE(rv_rack) TYPE i.
METHODS is_weight_valid
IMPORTING iv_weight_kg TYPE ty_weight
RETURNING VALUE(rv_valid) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}pallet_allocator IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD allocate.
DATA(lv_category) = normalized_category( iv_category ).
DATA(lt_zone) = zones( ).
IF NOT line_exists( lt_zone[ category = lv_category ] )
OR is_weight_valid( iv_weight_kg ) <> abap_false
OR iv_height_cm < c_min_height.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(lv_rack) = rack_for_height( iv_height_cm ).
IF lv_rack > c_max_rack.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(ls_zone) = lt_zone[ category = lv_category ].
rs_slot = VALUE #( aisle = ls_zone-aisle
rack = lv_rack
temp_zone = ls_zone-temp
is_valid = abap_true ).
ENDMETHOD.
METHOD zones.
rt_zone = VALUE #( ( category = 'F' aisle = 'A1' temp = 'FZ' )
( category = 'C' aisle = 'B2' temp = 'CZ' )
( category = 'D' aisle = 'D4' temp = 'DZ' ) ).
ENDMETHOD.
METHOD normalized_category.
rv_category = to_upper( replace( val = iv_category sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD rack_for_height.
IF iv_height_cm <= c_base_height.
rv_rack = 1.
RETURN.
ENDIF.
rv_rack = 1 + ( iv_height_cm - c_base_height + c_height_step - 1 ) DIV c_height_step.
ENDMETHOD.
METHOD is_weight_valid.
rv_valid = xsdbool( iv_weight_kg >= c_min_weight AND iv_weight_kg <= c_max_weight ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,108 @@
CLASS {{p}}pallet_allocator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_category TYPE c LENGTH 2.
TYPES ty_weight TYPE i.
TYPES ty_height TYPE i.
TYPES:
BEGIN OF ty_slot,
aisle TYPE c LENGTH 2,
rack TYPE i,
temp_zone TYPE c LENGTH 2,
is_valid TYPE abap_bool,
END OF ty_slot.
METHODS constructor.
METHODS allocate
IMPORTING
iv_category TYPE ty_category
iv_weight_kg TYPE ty_weight
iv_height_cm TYPE ty_height
RETURNING
VALUE(rs_slot) TYPE ty_slot.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_zone,
category TYPE ty_category,
aisle TYPE c LENGTH 2,
temp TYPE c LENGTH 2,
END OF ty_zone,
tt_zone TYPE HASHED TABLE OF ty_zone WITH UNIQUE KEY category.
CONSTANTS:
c_min_weight TYPE ty_weight VALUE 20,
c_max_weight TYPE ty_weight VALUE 800,
c_min_height TYPE ty_height VALUE 40,
c_base_height TYPE ty_height VALUE 120,
c_height_step TYPE ty_height VALUE 40,
c_max_rack TYPE i VALUE 4.
METHODS zones
RETURNING VALUE(rt_zone) TYPE tt_zone.
METHODS normalized_category
IMPORTING iv_category TYPE ty_category
RETURNING VALUE(rv_category) TYPE ty_category.
METHODS rack_for_height
IMPORTING iv_height_cm TYPE ty_height
RETURNING VALUE(rv_rack) TYPE i.
METHODS is_weight_valid
IMPORTING iv_weight_kg TYPE ty_weight
RETURNING VALUE(rv_valid) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}pallet_allocator IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD allocate.
DATA(lv_category) = normalized_category( iv_category ).
DATA(lt_zone) = zones( ).
IF NOT line_exists( lt_zone[ category = lv_category ] )
OR is_weight_valid( iv_weight_kg ) = abap_false
AND iv_height_cm < c_min_height.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(lv_rack) = rack_for_height( iv_height_cm ).
IF lv_rack > c_max_rack.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(ls_zone) = lt_zone[ category = lv_category ].
rs_slot = VALUE #( aisle = ls_zone-aisle
rack = lv_rack
temp_zone = ls_zone-temp
is_valid = abap_true ).
ENDMETHOD.
METHOD zones.
rt_zone = VALUE #( ( category = 'F' aisle = 'A1' temp = 'FZ' )
( category = 'C' aisle = 'B2' temp = 'CZ' )
( category = 'D' aisle = 'D4' temp = 'DZ' ) ).
ENDMETHOD.
METHOD normalized_category.
rv_category = to_upper( replace( val = iv_category sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD rack_for_height.
IF iv_height_cm <= c_base_height.
rv_rack = 1.
RETURN.
ENDIF.
rv_rack = 1 + ( iv_height_cm - c_base_height + c_height_step - 1 ) DIV c_height_step.
ENDMETHOD.
METHOD is_weight_valid.
rv_valid = xsdbool( iv_weight_kg >= c_min_weight AND iv_weight_kg <= c_max_weight ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,108 @@
CLASS {{p}}pallet_allocator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_category TYPE c LENGTH 2.
TYPES ty_weight TYPE i.
TYPES ty_height TYPE i.
TYPES:
BEGIN OF ty_slot,
aisle TYPE c LENGTH 2,
rack TYPE i,
temp_zone TYPE c LENGTH 2,
is_valid TYPE abap_bool,
END OF ty_slot.
METHODS constructor.
METHODS allocate
IMPORTING
iv_category TYPE ty_category
iv_weight_kg TYPE ty_weight
iv_height_cm TYPE ty_height
RETURNING
VALUE(rs_slot) TYPE ty_slot.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_zone,
category TYPE ty_category,
aisle TYPE c LENGTH 2,
temp TYPE c LENGTH 2,
END OF ty_zone,
tt_zone TYPE HASHED TABLE OF ty_zone WITH UNIQUE KEY category.
CONSTANTS:
c_min_weight TYPE ty_weight VALUE 20,
c_max_weight TYPE ty_weight VALUE 800,
c_min_height TYPE ty_height VALUE 40,
c_base_height TYPE ty_height VALUE 120,
c_height_step TYPE ty_height VALUE 40,
c_max_rack TYPE i VALUE 4.
METHODS zones
RETURNING VALUE(rt_zone) TYPE tt_zone.
METHODS normalized_category
IMPORTING iv_category TYPE ty_category
RETURNING VALUE(rv_category) TYPE ty_category.
METHODS rack_for_height
IMPORTING iv_height_cm TYPE ty_height
RETURNING VALUE(rv_rack) TYPE i.
METHODS is_weight_valid
IMPORTING iv_weight_kg TYPE ty_weight
RETURNING VALUE(rv_valid) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}pallet_allocator IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD allocate.
DATA(lv_category) = normalized_category( iv_category ).
DATA(lt_zone) = zones( ).
IF NOT line_exists( lt_zone[ category = lv_category ] )
OR is_weight_valid( iv_weight_kg ) = abap_false
OR iv_height_cm < c_min_height.
rs_slot = VALUE #( is_valid = abap_true ).
RETURN.
ENDIF.
DATA(lv_rack) = rack_for_height( iv_height_cm ).
IF lv_rack > c_max_rack.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(ls_zone) = lt_zone[ category = lv_category ].
rs_slot = VALUE #( aisle = ls_zone-aisle
rack = lv_rack
temp_zone = ls_zone-temp
is_valid = abap_true ).
ENDMETHOD.
METHOD zones.
rt_zone = VALUE #( ( category = 'F' aisle = 'A1' temp = 'FZ' )
( category = 'C' aisle = 'B2' temp = 'CZ' )
( category = 'D' aisle = 'D4' temp = 'DZ' ) ).
ENDMETHOD.
METHOD normalized_category.
rv_category = to_upper( replace( val = iv_category sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD rack_for_height.
IF iv_height_cm <= c_base_height.
rv_rack = 1.
RETURN.
ENDIF.
rv_rack = 1 + ( iv_height_cm - c_base_height + c_height_step - 1 ) DIV c_height_step.
ENDMETHOD.
METHOD is_weight_valid.
rv_valid = xsdbool( iv_weight_kg >= c_min_weight AND iv_weight_kg <= c_max_weight ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,108 @@
CLASS {{p}}pallet_allocator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_category TYPE c LENGTH 2.
TYPES ty_weight TYPE i.
TYPES ty_height TYPE i.
TYPES:
BEGIN OF ty_slot,
aisle TYPE c LENGTH 2,
rack TYPE i,
temp_zone TYPE c LENGTH 2,
is_valid TYPE abap_bool,
END OF ty_slot.
METHODS constructor.
METHODS allocate
IMPORTING
iv_category TYPE ty_category
iv_weight_kg TYPE ty_weight
iv_height_cm TYPE ty_height
RETURNING
VALUE(rs_slot) TYPE ty_slot.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_zone,
category TYPE ty_category,
aisle TYPE c LENGTH 2,
temp TYPE c LENGTH 2,
END OF ty_zone,
tt_zone TYPE HASHED TABLE OF ty_zone WITH UNIQUE KEY category.
CONSTANTS:
c_min_weight TYPE ty_weight VALUE 20,
c_max_weight TYPE ty_weight VALUE 800,
c_min_height TYPE ty_height VALUE 40,
c_base_height TYPE ty_height VALUE 120,
c_height_step TYPE ty_height VALUE 40,
c_max_rack TYPE i VALUE 4.
METHODS zones
RETURNING VALUE(rt_zone) TYPE tt_zone.
METHODS normalized_category
IMPORTING iv_category TYPE ty_category
RETURNING VALUE(rv_category) TYPE ty_category.
METHODS rack_for_height
IMPORTING iv_height_cm TYPE ty_height
RETURNING VALUE(rv_rack) TYPE i.
METHODS is_weight_valid
IMPORTING iv_weight_kg TYPE ty_weight
RETURNING VALUE(rv_valid) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}pallet_allocator IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD allocate.
DATA(lv_category) = normalized_category( iv_category ).
DATA(lt_zone) = zones( ).
IF NOT line_exists( lt_zone[ category = lv_category ] )
OR is_weight_valid( iv_weight_kg ) = abap_false
OR iv_height_cm < c_min_height.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(lv_rack) = rack_for_height( iv_height_cm ).
IF lv_rack <= c_max_rack.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(ls_zone) = lt_zone[ category = lv_category ].
rs_slot = VALUE #( aisle = ls_zone-aisle
rack = lv_rack
temp_zone = ls_zone-temp
is_valid = abap_true ).
ENDMETHOD.
METHOD zones.
rt_zone = VALUE #( ( category = 'F' aisle = 'A1' temp = 'FZ' )
( category = 'C' aisle = 'B2' temp = 'CZ' )
( category = 'D' aisle = 'D4' temp = 'DZ' ) ).
ENDMETHOD.
METHOD normalized_category.
rv_category = to_upper( replace( val = iv_category sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD rack_for_height.
IF iv_height_cm <= c_base_height.
rv_rack = 1.
RETURN.
ENDIF.
rv_rack = 1 + ( iv_height_cm - c_base_height + c_height_step - 1 ) DIV c_height_step.
ENDMETHOD.
METHOD is_weight_valid.
rv_valid = xsdbool( iv_weight_kg >= c_min_weight AND iv_weight_kg <= c_max_weight ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,108 @@
CLASS {{p}}pallet_allocator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_category TYPE c LENGTH 2.
TYPES ty_weight TYPE i.
TYPES ty_height TYPE i.
TYPES:
BEGIN OF ty_slot,
aisle TYPE c LENGTH 2,
rack TYPE i,
temp_zone TYPE c LENGTH 2,
is_valid TYPE abap_bool,
END OF ty_slot.
METHODS constructor.
METHODS allocate
IMPORTING
iv_category TYPE ty_category
iv_weight_kg TYPE ty_weight
iv_height_cm TYPE ty_height
RETURNING
VALUE(rs_slot) TYPE ty_slot.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_zone,
category TYPE ty_category,
aisle TYPE c LENGTH 2,
temp TYPE c LENGTH 2,
END OF ty_zone,
tt_zone TYPE HASHED TABLE OF ty_zone WITH UNIQUE KEY category.
CONSTANTS:
c_min_weight TYPE ty_weight VALUE 20,
c_max_weight TYPE ty_weight VALUE 800,
c_min_height TYPE ty_height VALUE 40,
c_base_height TYPE ty_height VALUE 120,
c_height_step TYPE ty_height VALUE 40,
c_max_rack TYPE i VALUE 4.
METHODS zones
RETURNING VALUE(rt_zone) TYPE tt_zone.
METHODS normalized_category
IMPORTING iv_category TYPE ty_category
RETURNING VALUE(rv_category) TYPE ty_category.
METHODS rack_for_height
IMPORTING iv_height_cm TYPE ty_height
RETURNING VALUE(rv_rack) TYPE i.
METHODS is_weight_valid
IMPORTING iv_weight_kg TYPE ty_weight
RETURNING VALUE(rv_valid) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}pallet_allocator IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD allocate.
DATA(lv_category) = normalized_category( iv_category ).
DATA(lt_zone) = zones( ).
IF NOT line_exists( lt_zone[ category = lv_category ] )
OR is_weight_valid( iv_weight_kg ) = abap_false
OR iv_height_cm < c_min_height.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(lv_rack) = rack_for_height( iv_height_cm ).
IF lv_rack > c_max_rack.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(ls_zone) = lt_zone[ category = lv_category ].
rs_slot = VALUE #( aisle = ls_zone-aisle
rack = lv_rack
temp_zone = ls_zone-temp
is_valid = abap_true ).
ENDMETHOD.
METHOD zones.
rt_zone = VALUE #( ( category = 'F' aisle = 'A1' temp = 'FZ' )
( category = 'C' aisle = 'B2' temp = 'CZ' )
( category = 'D' aisle = 'D4' temp = 'DZ' ) ).
ENDMETHOD.
METHOD normalized_category.
rv_category = to_upper( replace( val = iv_category sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD rack_for_height.
IF iv_height_cm <= c_base_height.
rv_rack = 1.
RETURN.
ENDIF.
rv_rack = 1 - ( iv_height_cm - c_base_height + c_height_step - 1 ) DIV c_height_step.
ENDMETHOD.
METHOD is_weight_valid.
rv_valid = xsdbool( iv_weight_kg >= c_min_weight AND iv_weight_kg <= c_max_weight ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,31 @@
{
"id": "G1074",
"pool": "train",
"object_type": "CLAS",
"category": "E",
"attempts": [
{
"stage": "bundle",
"errors": [
"reference/courier_pricer.clas.abap line 47: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"METHODS\"",
"reference/courier_pricer.clas.abap line 50: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"METHODS\"",
"Too close to task G1050 (similarity spec 0.79, rules 0.52, names 0.33). Choose a different business topic and different object names."
],
"by_check": {
"abaplint": 2,
"extra": 1
}
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 5,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,121 @@
CLASS {{p}}pallet_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}pallet_allocator.
METHODS setup.
METHODS frozen_pallet_ok FOR TESTING.
METHODS chilled_pallet_ok FOR TESTING.
METHODS dry_pallet_ok FOR TESTING.
METHODS lower_case_and_blanks FOR TESTING.
METHODS rack_boundaries FOR TESTING.
METHODS height_too_high_invalid FOR TESTING.
METHODS height_too_low_invalid FOR TESTING.
METHODS weight_limits FOR TESTING.
METHODS unknown_category_invalid FOR TESTING.
METHODS blank_category_invalid FOR TESTING.
ENDCLASS.
CLASS {{p}}pallet_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}pallet_allocator( ).
ENDMETHOD.
METHOD frozen_pallet_ok.
DATA(ls_slot) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 100 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true act = ls_slot-is_valid ).
cl_abap_unit_assert=>assert_equals( exp = 'A1' act = ls_slot-aisle ).
cl_abap_unit_assert=>assert_equals( exp = 'FZ' act = ls_slot-temp_zone ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_slot-rack ).
ENDMETHOD.
METHOD chilled_pallet_ok.
DATA(ls_slot) = mo_cut->allocate( iv_category = 'C' iv_weight_kg = 500 iv_height_cm = 200 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true act = ls_slot-is_valid ).
cl_abap_unit_assert=>assert_equals( exp = 'B2' act = ls_slot-aisle ).
cl_abap_unit_assert=>assert_equals( exp = 'CZ' act = ls_slot-temp_zone ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = ls_slot-rack ).
ENDMETHOD.
METHOD dry_pallet_ok.
DATA(ls_slot) = mo_cut->allocate( iv_category = 'D' iv_weight_kg = 20 iv_height_cm = 40 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true act = ls_slot-is_valid ).
cl_abap_unit_assert=>assert_equals( exp = 'D4' act = ls_slot-aisle ).
cl_abap_unit_assert=>assert_equals( exp = 'DZ' act = ls_slot-temp_zone ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_slot-rack ).
ENDMETHOD.
METHOD lower_case_and_blanks.
DATA(ls_lower) = mo_cut->allocate( iv_category = 'f' iv_weight_kg = 50 iv_height_cm = 121 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true act = ls_lower-is_valid ).
cl_abap_unit_assert=>assert_equals( exp = 'A1' act = ls_lower-aisle ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_lower-rack ).
DATA(ls_blank) = mo_cut->allocate( iv_category = ' c' iv_weight_kg = 50 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true act = ls_blank-is_valid ).
cl_abap_unit_assert=>assert_equals( exp = 'B2' act = ls_blank-aisle ).
ENDMETHOD.
METHOD rack_boundaries.
DATA(ls_base) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 100 iv_height_cm = 120 ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_base-rack msg = `120` ).
DATA(ls_step) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 100 iv_height_cm = 121 ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_step-rack msg = `121` ).
DATA(ls_max) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 100 iv_height_cm = 240 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true act = ls_max-is_valid msg = `240 valid` ).
cl_abap_unit_assert=>assert_equals( exp = 4 act = ls_max-rack msg = `240` ).
ENDMETHOD.
METHOD height_too_high_invalid.
DATA(ls_slot) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 100 iv_height_cm = 241 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_slot-is_valid ).
cl_abap_unit_assert=>assert_initial( act = ls_slot-aisle ).
cl_abap_unit_assert=>assert_initial( act = ls_slot-temp_zone ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = ls_slot-rack ).
ENDMETHOD.
METHOD height_too_low_invalid.
DATA(ls_slot) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 100 iv_height_cm = 39 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_slot-is_valid ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = ls_slot-rack ).
ENDMETHOD.
METHOD weight_limits.
DATA(ls_light) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 19 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_light-is_valid msg = `19` ).
DATA(ls_min) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 20 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true act = ls_min-is_valid msg = `20` ).
DATA(ls_max) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 800 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true act = ls_max-is_valid msg = `800` ).
DATA(ls_heavy) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 801 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_heavy-is_valid msg = `801` ).
ENDMETHOD.
METHOD unknown_category_invalid.
DATA(ls_slot) = mo_cut->allocate( iv_category = 'X' iv_weight_kg = 100 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_slot-is_valid ).
cl_abap_unit_assert=>assert_initial( act = ls_slot-aisle ).
cl_abap_unit_assert=>assert_initial( act = ls_slot-temp_zone ).
ENDMETHOD.
METHOD blank_category_invalid.
DATA(ls_slot) = mo_cut->allocate( iv_category = ' ' iv_weight_kg = 100 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_slot-is_valid ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = ls_slot-rack ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,72 @@
{
"task": "G1074",
"mutants": [
{
"object": "{{P}}PALLET_ALLOCATOR",
"mutant": "line 68: = -> <> (eq)",
"status": "killed",
"hidden": "4/10",
"failed_tests": [
"CHILLED_PALLET_OK",
"DRY_PALLET_OK",
"FROZEN_PALLET_OK",
"LOWER_CASE_AND_BLANKS",
"RACK_BOUNDARIES",
"WEIGHT_LIMITS"
]
},
{
"object": "{{P}}PALLET_ALLOCATOR",
"mutant": "line 69: OR -> AND (logic)",
"status": "killed",
"hidden": "8/10",
"failed_tests": [
"HEIGHT_TOO_LOW_INVALID",
"WEIGHT_LIMITS"
]
},
{
"object": "{{P}}PALLET_ALLOCATOR",
"mutant": "line 70: abap_false -> abap_true (bool)",
"status": "killed",
"hidden": "6/10",
"failed_tests": [
"BLANK_CATEGORY_INVALID",
"HEIGHT_TOO_LOW_INVALID",
"UNKNOWN_CATEGORY_INVALID",
"WEIGHT_LIMITS"
]
},
{
"object": "{{P}}PALLET_ALLOCATOR",
"mutant": "line 75: > -> <= (rel)",
"status": "killed",
"hidden": "3/10",
"failed_tests": [
"CHILLED_PALLET_OK",
"DRY_PALLET_OK",
"FROZEN_PALLET_OK",
"HEIGHT_TOO_HIGH_INVALID",
"LOWER_CASE_AND_BLANKS",
"RACK_BOUNDARIES",
"WEIGHT_LIMITS"
]
},
{
"object": "{{P}}PALLET_ALLOCATOR",
"mutant": "line 102: + -> - (arith)",
"status": "killed",
"hidden": "6/10",
"failed_tests": [
"CHILLED_PALLET_OK",
"HEIGHT_TOO_HIGH_INVALID",
"LOWER_CASE_AND_BLANKS",
"RACK_BOUNDARIES"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,108 @@
CLASS {{p}}pallet_allocator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_category TYPE c LENGTH 2.
TYPES ty_weight TYPE i.
TYPES ty_height TYPE i.
TYPES:
BEGIN OF ty_slot,
aisle TYPE c LENGTH 2,
rack TYPE i,
temp_zone TYPE c LENGTH 2,
is_valid TYPE abap_bool,
END OF ty_slot.
METHODS constructor.
METHODS allocate
IMPORTING
iv_category TYPE ty_category
iv_weight_kg TYPE ty_weight
iv_height_cm TYPE ty_height
RETURNING
VALUE(rs_slot) TYPE ty_slot.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_zone,
category TYPE ty_category,
aisle TYPE c LENGTH 2,
temp TYPE c LENGTH 2,
END OF ty_zone,
tt_zone TYPE HASHED TABLE OF ty_zone WITH UNIQUE KEY category.
CONSTANTS:
c_min_weight TYPE ty_weight VALUE 20,
c_max_weight TYPE ty_weight VALUE 800,
c_min_height TYPE ty_height VALUE 40,
c_base_height TYPE ty_height VALUE 120,
c_height_step TYPE ty_height VALUE 40,
c_max_rack TYPE i VALUE 4.
METHODS zones
RETURNING VALUE(rt_zone) TYPE tt_zone.
METHODS normalized_category
IMPORTING iv_category TYPE ty_category
RETURNING VALUE(rv_category) TYPE ty_category.
METHODS rack_for_height
IMPORTING iv_height_cm TYPE ty_height
RETURNING VALUE(rv_rack) TYPE i.
METHODS is_weight_valid
IMPORTING iv_weight_kg TYPE ty_weight
RETURNING VALUE(rv_valid) TYPE abap_bool.
ENDCLASS.
CLASS {{p}}pallet_allocator IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD allocate.
DATA(lv_category) = normalized_category( iv_category ).
DATA(lt_zone) = zones( ).
IF NOT line_exists( lt_zone[ category = lv_category ] )
OR is_weight_valid( iv_weight_kg ) = abap_false
OR iv_height_cm < c_min_height.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(lv_rack) = rack_for_height( iv_height_cm ).
IF lv_rack > c_max_rack.
rs_slot = VALUE #( is_valid = abap_false ).
RETURN.
ENDIF.
DATA(ls_zone) = lt_zone[ category = lv_category ].
rs_slot = VALUE #( aisle = ls_zone-aisle
rack = lv_rack
temp_zone = ls_zone-temp
is_valid = abap_true ).
ENDMETHOD.
METHOD zones.
rt_zone = VALUE #( ( category = 'F' aisle = 'A1' temp = 'FZ' )
( category = 'C' aisle = 'B2' temp = 'CZ' )
( category = 'D' aisle = 'D4' temp = 'DZ' ) ).
ENDMETHOD.
METHOD normalized_category.
rv_category = to_upper( replace( val = iv_category sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD rack_for_height.
IF iv_height_cm <= c_base_height.
rv_rack = 1.
RETURN.
ENDIF.
rv_rack = 1 + ( iv_height_cm - c_base_height + c_height_step - 1 ) DIV c_height_step.
ENDMETHOD.
METHOD is_weight_valid.
rv_valid = xsdbool( iv_weight_kg >= c_min_weight AND iv_weight_kg <= c_max_weight ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,67 @@
CLASS ltc_pallet_allocator DEFINITION FINAL FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}pallet_allocator.
METHODS setup.
METHODS frozen_pallet FOR TESTING.
METHODS chilled_pallet FOR TESTING.
METHODS dry_pallet FOR TESTING.
METHODS unknown_category FOR TESTING.
METHODS weight_out_of_range FOR TESTING.
METHODS height_out_of_range FOR TESTING.
ENDCLASS.
CLASS ltc_pallet_allocator IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}pallet_allocator( ).
ENDMETHOD.
METHOD frozen_pallet.
DATA(ls_slot) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 100 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_true act = ls_slot-is_valid ).
cl_abap_unit_assert=>assert_equals( exp = 'A1' act = ls_slot-aisle ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_slot-rack ).
ENDMETHOD.
METHOD chilled_pallet.
DATA(ls_slot) = mo_cut->allocate( iv_category = 'C' iv_weight_kg = 500 iv_height_cm = 200 ).
cl_abap_unit_assert=>assert_equals( exp = 'B2' act = ls_slot-aisle ).
cl_abap_unit_assert=>assert_equals( exp = 'CZ' act = ls_slot-temp_zone ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = ls_slot-rack ).
ENDMETHOD.
METHOD dry_pallet.
DATA(ls_slot) = mo_cut->allocate( iv_category = 'D' iv_weight_kg = 20 iv_height_cm = 40 ).
cl_abap_unit_assert=>assert_equals( exp = 'D4' act = ls_slot-aisle ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_slot-rack ).
ENDMETHOD.
METHOD unknown_category.
DATA(ls_slot) = mo_cut->allocate( iv_category = 'X' iv_weight_kg = 100 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_slot-is_valid ).
ENDMETHOD.
METHOD weight_out_of_range.
DATA(ls_light) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 19 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_light-is_valid ).
DATA(ls_heavy) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 801 iv_height_cm = 100 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_heavy-is_valid ).
ENDMETHOD.
METHOD height_out_of_range.
DATA(ls_low) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 100 iv_height_cm = 39 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_low-is_valid ).
DATA(ls_high) = mo_cut->allocate( iv_category = 'F' iv_weight_kg = 100 iv_height_cm = 241 ).
cl_abap_unit_assert=>assert_equals( exp = abap_false act = ls_high-is_valid ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,96 @@
CLASS {{p}}pallet_allocator DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_category TYPE c LENGTH 2.
TYPES ty_weight TYPE i.
TYPES ty_height TYPE i.
TYPES:
BEGIN OF ty_slot,
aisle TYPE c LENGTH 2,
rack TYPE i,
temp_zone TYPE c LENGTH 2,
is_valid TYPE abap_bool,
END OF ty_slot.
METHODS constructor.
METHODS allocate
IMPORTING
iv_category TYPE ty_category
iv_weight_kg TYPE ty_weight
iv_height_cm TYPE ty_height
RETURNING
VALUE(rs_slot) TYPE ty_slot.
ENDCLASS.
CLASS {{p}}pallet_allocator IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD allocate.
DATA: lv_cat TYPE ty_category,
lv_aisle TYPE c LENGTH 2,
lv_zone TYPE c LENGTH 2,
lv_rack TYPE i,
lv_h TYPE i,
lv_ok TYPE c LENGTH 1.
CLEAR rs_slot.
lv_cat = iv_category.
TRANSLATE lv_cat TO UPPER CASE.
CONDENSE lv_cat NO-GAPS.
lv_ok = 'X'.
IF lv_cat = 'F'.
lv_aisle = 'A1'.
lv_zone = 'FZ'.
ELSEIF lv_cat = 'C'.
lv_aisle = 'B2'.
lv_zone = 'CZ'.
ELSEIF lv_cat = 'D'.
lv_aisle = 'D4'.
lv_zone = 'DZ'.
ELSE.
lv_ok = ' '.
ENDIF.
IF iv_weight_kg < 20.
lv_ok = ' '.
ENDIF.
IF iv_weight_kg > 800.
lv_ok = ' '.
ENDIF.
IF iv_height_cm < 40.
lv_ok = ' '.
ENDIF.
IF lv_ok = 'X'.
lv_rack = 1.
lv_h = iv_height_cm.
WHILE lv_h > 120.
lv_rack = lv_rack + 1.
lv_h = lv_h - 40.
ENDWHILE.
IF lv_rack > 4.
lv_ok = ' '.
ENDIF.
ENDIF.
IF lv_ok = 'X'.
rs_slot-aisle = lv_aisle.
rs_slot-rack = lv_rack.
rs_slot-temp_zone = lv_zone.
rs_slot-is_valid = abap_true.
ELSE.
CLEAR rs_slot.
rs_slot-is_valid = abap_false.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,59 @@
# 1. Goal
A cold-storage warehouse stores pallets of food. The gate system calls the class
{{P}}PALLET_ALLOCATOR in package $TMP for each incoming pallet. The class decides
the storage aisle, the rack, and the temperature zone of the pallet.
The class is active. Its implementation is legacy code. The method ALLOCATE is
long, it uses many literal values and nested IF blocks, and it is hard to
maintain. Users report that the class is hard to test.
Refactor the class in place. The class name and the public interface stay the
same. The behavior stays the same.
# 2. Open questions
None.
# 3. Context
- The class {{P}}PALLET_ALLOCATOR exists in package $TMP. It is active.
- The class is public, final, and has a public constructor without parameters.
- The class has one public method, ALLOCATE. The legacy implementation of
ALLOCATE contains the storage rules of the warehouse.
- The gate system calls ALLOCATE for each pallet and prints the result on the
pallet label. The result must not change.
# 4. Contract
- The class {{P}}PALLET_ALLOCATOR stays in package $TMP. The class name does not
change.
- The class stays public and final. The public constructor stays without
parameters.
- The public types do not change:
- TY_CATEGORY (CHAR 2)
- TY_WEIGHT (INT)
- TY_HEIGHT (INT)
- TY_SLOT with the components AISLE (CHAR 2), RACK (INT), TEMP_ZONE (CHAR 2)
and IS_VALID (ABAP_BOOL).
- The public method does not change:
ALLOCATE
IMPORTING iv_category TYPE ty_category
iv_weight_kg TYPE ty_weight
iv_height_cm TYPE ty_height
RETURNING VALUE(rs_slot) TYPE ty_slot.
- Do not add other public methods or public attributes.
# 5. Business rules
The legacy implementation of ALLOCATE is the specification. Read the legacy
code. The class must return the same result for every input. Do not change the
behavior.
# 6. Constraints
- Release target: SAP_BASIS 816 (ABAP Platform 2025).
- Coding standards: Clean ABAP. Method length below 40 statements. No global
variables. Use constants and small helper methods. No comment that restates
the code.
- Out of scope: do not change the public interface of the class.
# 7. Acceptance
- The class is active and has no syntax error.
- The behavior of the class is unchanged.
- The hidden tests pass.
- Write your own ABAP Unit tests for the class.

View File

@@ -0,0 +1,48 @@
{
"id": "G1074",
"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}}PALLET_ALLOCATOR",
"file": "seed/pallet_allocator.clas.abap",
"description": "Legacy cold-storage pallet allocation class with the storage rules"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}PALLET_ALLOCATOR"
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}PALLET_HIDDEN",
"file": "hidden/pallet_hidden.clas.abap",
"description": "Behavior tests for the refactored pallet allocator"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}PALLET_ALLOCATOR",
"file": "reference/pallet_allocator.clas.abap",
"description": "Refactored cold-storage pallet allocator",
"testclasses_file": "reference/pallet_allocator.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"db_operation_in_loop"
]
}