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,75 @@
CLASS {{p}}seed_lot_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_lot,
lot_no TYPE c LENGTH 10,
germination TYPE i,
moisture TYPE p LENGTH 4 DECIMALS 1,
harvest_date TYPE d,
END OF ty_lot.
METHODS check_lot
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
PRIVATE SECTION.
CONSTANTS:
c_min_germination TYPE i VALUE 85,
c_max_moisture TYPE p LENGTH 4 DECIMALS 1 VALUE '12.0',
c_max_age_days TYPE i VALUE 365.
METHODS check_lot_no
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_harvest_date
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
METHODS check_germination
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_moisture
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
ENDCLASS.
CLASS {{p}}seed_lot_checker IMPLEMENTATION.
METHOD check_lot.
check_lot_no( is_lot ).
check_harvest_date( is_lot = is_lot iv_check_date = iv_check_date ).
check_germination( is_lot ).
check_moisture( is_lot ).
ENDMETHOD.
METHOD check_lot_no.
DATA(lv_letters) = substring( val = is_lot-lot_no len = 4 ).
DATA(lv_digits) = substring( val = is_lot-lot_no off = 4 len = 6 ).
IF lv_letters CN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' AND lv_digits CN '0123456789'.
RAISE EXCEPTION TYPE {{p}}cx_lot_format.
ENDIF.
ENDMETHOD.
METHOD check_harvest_date.
IF is_lot-harvest_date IS INITIAL.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
DATA(lv_age_in_days) = iv_check_date - is_lot-harvest_date.
IF lv_age_in_days < 0 OR lv_age_in_days > c_max_age_days.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
ENDMETHOD.
METHOD check_germination.
IF is_lot-germination < c_min_germination.
RAISE EXCEPTION TYPE {{p}}cx_lot_germination.
ENDIF.
ENDMETHOD.
METHOD check_moisture.
IF is_lot-moisture > c_max_moisture.
RAISE EXCEPTION TYPE {{p}}cx_lot_moisture.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,75 @@
CLASS {{p}}seed_lot_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_lot,
lot_no TYPE c LENGTH 10,
germination TYPE i,
moisture TYPE p LENGTH 4 DECIMALS 1,
harvest_date TYPE d,
END OF ty_lot.
METHODS check_lot
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
PRIVATE SECTION.
CONSTANTS:
c_min_germination TYPE i VALUE 85,
c_max_moisture TYPE p LENGTH 4 DECIMALS 1 VALUE '12.0',
c_max_age_days TYPE i VALUE 365.
METHODS check_lot_no
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_harvest_date
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
METHODS check_germination
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_moisture
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
ENDCLASS.
CLASS {{p}}seed_lot_checker IMPLEMENTATION.
METHOD check_lot.
check_lot_no( is_lot ).
check_harvest_date( is_lot = is_lot iv_check_date = iv_check_date ).
check_germination( is_lot ).
check_moisture( is_lot ).
ENDMETHOD.
METHOD check_lot_no.
DATA(lv_letters) = substring( val = is_lot-lot_no len = 4 ).
DATA(lv_digits) = substring( val = is_lot-lot_no off = 4 len = 6 ).
IF lv_letters CN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' OR lv_digits CN '0123456789'.
RAISE EXCEPTION TYPE {{p}}cx_lot_format.
ENDIF.
ENDMETHOD.
METHOD check_harvest_date.
IF is_lot-harvest_date IS INITIAL.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
DATA(lv_age_in_days) = iv_check_date - is_lot-harvest_date.
IF lv_age_in_days >= 0 OR lv_age_in_days > c_max_age_days.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
ENDMETHOD.
METHOD check_germination.
IF is_lot-germination < c_min_germination.
RAISE EXCEPTION TYPE {{p}}cx_lot_germination.
ENDIF.
ENDMETHOD.
METHOD check_moisture.
IF is_lot-moisture > c_max_moisture.
RAISE EXCEPTION TYPE {{p}}cx_lot_moisture.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,75 @@
CLASS {{p}}seed_lot_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_lot,
lot_no TYPE c LENGTH 10,
germination TYPE i,
moisture TYPE p LENGTH 4 DECIMALS 1,
harvest_date TYPE d,
END OF ty_lot.
METHODS check_lot
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
PRIVATE SECTION.
CONSTANTS:
c_min_germination TYPE i VALUE 85,
c_max_moisture TYPE p LENGTH 4 DECIMALS 1 VALUE '12.0',
c_max_age_days TYPE i VALUE 365.
METHODS check_lot_no
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_harvest_date
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
METHODS check_germination
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_moisture
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
ENDCLASS.
CLASS {{p}}seed_lot_checker IMPLEMENTATION.
METHOD check_lot.
check_lot_no( is_lot ).
check_harvest_date( is_lot = is_lot iv_check_date = iv_check_date ).
check_germination( is_lot ).
check_moisture( is_lot ).
ENDMETHOD.
METHOD check_lot_no.
DATA(lv_letters) = substring( val = is_lot-lot_no len = 4 ).
DATA(lv_digits) = substring( val = is_lot-lot_no off = 4 len = 6 ).
IF lv_letters CN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' OR lv_digits CN '0123456789'.
RAISE EXCEPTION TYPE {{p}}cx_lot_format.
ENDIF.
ENDMETHOD.
METHOD check_harvest_date.
IF is_lot-harvest_date IS INITIAL.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
DATA(lv_age_in_days) = iv_check_date - is_lot-harvest_date.
IF lv_age_in_days < 0 AND lv_age_in_days > c_max_age_days.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
ENDMETHOD.
METHOD check_germination.
IF is_lot-germination < c_min_germination.
RAISE EXCEPTION TYPE {{p}}cx_lot_germination.
ENDIF.
ENDMETHOD.
METHOD check_moisture.
IF is_lot-moisture > c_max_moisture.
RAISE EXCEPTION TYPE {{p}}cx_lot_moisture.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,75 @@
CLASS {{p}}seed_lot_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_lot,
lot_no TYPE c LENGTH 10,
germination TYPE i,
moisture TYPE p LENGTH 4 DECIMALS 1,
harvest_date TYPE d,
END OF ty_lot.
METHODS check_lot
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
PRIVATE SECTION.
CONSTANTS:
c_min_germination TYPE i VALUE 85,
c_max_moisture TYPE p LENGTH 4 DECIMALS 1 VALUE '12.0',
c_max_age_days TYPE i VALUE 365.
METHODS check_lot_no
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_harvest_date
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
METHODS check_germination
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_moisture
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
ENDCLASS.
CLASS {{p}}seed_lot_checker IMPLEMENTATION.
METHOD check_lot.
check_lot_no( is_lot ).
check_harvest_date( is_lot = is_lot iv_check_date = iv_check_date ).
check_germination( is_lot ).
check_moisture( is_lot ).
ENDMETHOD.
METHOD check_lot_no.
DATA(lv_letters) = substring( val = is_lot-lot_no len = 4 ).
DATA(lv_digits) = substring( val = is_lot-lot_no off = 4 len = 6 ).
IF lv_letters CN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' OR lv_digits CN '0123456789'.
RAISE EXCEPTION TYPE {{p}}cx_lot_format.
ENDIF.
ENDMETHOD.
METHOD check_harvest_date.
IF is_lot-harvest_date IS INITIAL.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
DATA(lv_age_in_days) = iv_check_date - is_lot-harvest_date.
IF lv_age_in_days < 0 OR lv_age_in_days <= c_max_age_days.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
ENDMETHOD.
METHOD check_germination.
IF is_lot-germination < c_min_germination.
RAISE EXCEPTION TYPE {{p}}cx_lot_germination.
ENDIF.
ENDMETHOD.
METHOD check_moisture.
IF is_lot-moisture > c_max_moisture.
RAISE EXCEPTION TYPE {{p}}cx_lot_moisture.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,75 @@
CLASS {{p}}seed_lot_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_lot,
lot_no TYPE c LENGTH 10,
germination TYPE i,
moisture TYPE p LENGTH 4 DECIMALS 1,
harvest_date TYPE d,
END OF ty_lot.
METHODS check_lot
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
PRIVATE SECTION.
CONSTANTS:
c_min_germination TYPE i VALUE 85,
c_max_moisture TYPE p LENGTH 4 DECIMALS 1 VALUE '12.0',
c_max_age_days TYPE i VALUE 365.
METHODS check_lot_no
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_harvest_date
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
METHODS check_germination
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_moisture
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
ENDCLASS.
CLASS {{p}}seed_lot_checker IMPLEMENTATION.
METHOD check_lot.
check_lot_no( is_lot ).
check_harvest_date( is_lot = is_lot iv_check_date = iv_check_date ).
check_germination( is_lot ).
check_moisture( is_lot ).
ENDMETHOD.
METHOD check_lot_no.
DATA(lv_letters) = substring( val = is_lot-lot_no len = 4 ).
DATA(lv_digits) = substring( val = is_lot-lot_no off = 4 len = 6 ).
IF lv_letters CN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' OR lv_digits CN '0123456789'.
RAISE EXCEPTION TYPE {{p}}cx_lot_format.
ENDIF.
ENDMETHOD.
METHOD check_harvest_date.
IF is_lot-harvest_date IS INITIAL.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
DATA(lv_age_in_days) = iv_check_date - is_lot-harvest_date.
IF lv_age_in_days < 0 OR lv_age_in_days > c_max_age_days.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
ENDMETHOD.
METHOD check_germination.
IF is_lot-germination < c_min_germination.
RAISE EXCEPTION TYPE {{p}}cx_lot_germination.
ENDIF.
ENDMETHOD.
METHOD check_moisture.
IF is_lot-moisture <= c_max_moisture.
RAISE EXCEPTION TYPE {{p}}cx_lot_moisture.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,24 @@
{
"id": "G1084",
"pool": "train",
"object_type": "CLAS",
"category": "D",
"attempts": [
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 5,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,210 @@
CLASS {{p}}seed_lot_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CONSTANTS c_check_date TYPE d VALUE '20250601'.
DATA mo_cut TYPE REF TO {{p}}seed_lot_checker.
METHODS setup.
METHODS valid_lot
RETURNING VALUE(rs_lot) TYPE {{p}}seed_lot_checker=>ty_lot.
METHODS releases_valid_lot FOR TESTING.
METHODS rejects_bad_lot_no FOR TESTING.
METHODS rejects_lower_case_lot_no FOR TESTING.
METHODS rejects_initial_harvest FOR TESTING.
METHODS rejects_future_harvest FOR TESTING.
METHODS rejects_old_harvest FOR TESTING.
METHODS rejects_low_germination FOR TESTING.
METHODS rejects_high_moisture FOR TESTING.
METHODS accepts_limit_values FOR TESTING.
METHODS format_before_quality FOR TESTING.
METHODS date_before_quality FOR TESTING.
METHODS germination_before_moisture FOR TESTING.
ENDCLASS.
CLASS {{p}}seed_lot_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}seed_lot_checker( ).
ENDMETHOD.
METHOD valid_lot.
rs_lot = VALUE #( lot_no = 'WHEA123456'
germination = 90
moisture = '11.0'
harvest_date = '20250501' ).
ENDMETHOD.
METHOD releases_valid_lot.
TRY.
mo_cut->check_lot( is_lot = valid_lot( ) iv_check_date = c_check_date ).
CATCH {{p}}cx_seed_lot INTO DATA(lo_ex).
cl_abap_unit_assert=>fail( msg = lo_ex->get_message( ) ).
ENDTRY.
ENDMETHOD.
METHOD rejects_bad_lot_no.
DATA(ls_lot) = valid_lot( ).
ls_lot-lot_no = 'AB12345678'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_FORMAT expected` ).
CATCH {{p}}cx_lot_format INTO DATA(lo_format).
cl_abap_unit_assert=>assert_equals(
exp = 'The lot number has an invalid format.'
act = lo_format->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_FORMAT expected` ).
ENDTRY.
ENDMETHOD.
METHOD rejects_lower_case_lot_no.
DATA(ls_lot) = valid_lot( ).
ls_lot-lot_no = 'whea123456'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_FORMAT expected` ).
CATCH {{p}}cx_lot_format INTO DATA(lo_format).
cl_abap_unit_assert=>assert_equals(
exp = 'The lot number has an invalid format.'
act = lo_format->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_FORMAT expected` ).
ENDTRY.
ENDMETHOD.
METHOD rejects_initial_harvest.
DATA(ls_lot) = valid_lot( ).
CLEAR ls_lot-harvest_date.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_DATE expected` ).
CATCH {{p}}cx_lot_date INTO DATA(lo_date).
cl_abap_unit_assert=>assert_equals(
exp = 'The harvest date is not valid for the release check.'
act = lo_date->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_DATE expected` ).
ENDTRY.
ENDMETHOD.
METHOD rejects_future_harvest.
DATA(ls_lot) = valid_lot( ).
ls_lot-harvest_date = '20250602'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_DATE expected` ).
CATCH {{p}}cx_lot_date INTO DATA(lo_date).
cl_abap_unit_assert=>assert_equals(
exp = 'The harvest date is not valid for the release check.'
act = lo_date->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_DATE expected` ).
ENDTRY.
ENDMETHOD.
METHOD rejects_old_harvest.
DATA(ls_lot) = valid_lot( ).
ls_lot-harvest_date = '20240531'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_DATE expected` ).
CATCH {{p}}cx_lot_date INTO DATA(lo_date).
cl_abap_unit_assert=>assert_equals(
exp = 'The harvest date is not valid for the release check.'
act = lo_date->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_DATE expected` ).
ENDTRY.
ENDMETHOD.
METHOD rejects_low_germination.
DATA(ls_lot) = valid_lot( ).
ls_lot-germination = 84.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_GERMINATION expected` ).
CATCH {{p}}cx_lot_germination INTO DATA(lo_germ).
cl_abap_unit_assert=>assert_equals(
exp = 'The germination rate is below the minimum of 85 percent.'
act = lo_germ->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_GERMINATION expected` ).
ENDTRY.
ENDMETHOD.
METHOD rejects_high_moisture.
DATA(ls_lot) = valid_lot( ).
ls_lot-moisture = '12.1'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_MOISTURE expected` ).
CATCH {{p}}cx_lot_moisture INTO DATA(lo_moist).
cl_abap_unit_assert=>assert_equals(
exp = 'The moisture is above the maximum of 12.0 percent.'
act = lo_moist->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_MOISTURE expected` ).
ENDTRY.
ENDMETHOD.
METHOD accepts_limit_values.
DATA(ls_lot) = valid_lot( ).
ls_lot-germination = 85.
ls_lot-moisture = '12.0'.
ls_lot-harvest_date = '20240601'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
CATCH {{p}}cx_seed_lot INTO DATA(lo_ex).
cl_abap_unit_assert=>fail( msg = lo_ex->get_message( ) ).
ENDTRY.
ENDMETHOD.
METHOD format_before_quality.
DATA(ls_lot) = valid_lot( ).
ls_lot-lot_no = '1234567890'.
ls_lot-germination = 10.
ls_lot-moisture = '20.0'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_FORMAT expected` ).
CATCH {{p}}cx_lot_format INTO DATA(lo_format).
cl_abap_unit_assert=>assert_equals(
exp = 'The lot number has an invalid format.'
act = lo_format->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_FORMAT expected` ).
ENDTRY.
ENDMETHOD.
METHOD date_before_quality.
DATA(ls_lot) = valid_lot( ).
ls_lot-harvest_date = '20240531'.
ls_lot-germination = 10.
ls_lot-moisture = '20.0'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_DATE expected` ).
CATCH {{p}}cx_lot_date INTO DATA(lo_date).
cl_abap_unit_assert=>assert_equals(
exp = 'The harvest date is not valid for the release check.'
act = lo_date->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_DATE expected` ).
ENDTRY.
ENDMETHOD.
METHOD germination_before_moisture.
DATA(ls_lot) = valid_lot( ).
ls_lot-germination = 10.
ls_lot-moisture = '20.0'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_GERMINATION expected` ).
CATCH {{p}}cx_lot_germination INTO DATA(lo_germ).
cl_abap_unit_assert=>assert_equals(
exp = 'The germination rate is below the minimum of 85 percent.'
act = lo_germ->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_GERMINATION expected` ).
ENDTRY.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,71 @@
{
"task": "G1084",
"mutants": [
{
"object": "{{P}}SEED_LOT_CHECKER",
"mutant": "line 49: OR -> AND (logic)",
"status": "killed",
"hidden": "9/12",
"failed_tests": [
"FORMAT_BEFORE_QUALITY",
"REJECTS_BAD_LOT_NO",
"REJECTS_LOWER_CASE_LOT_NO"
]
},
{
"object": "{{P}}SEED_LOT_CHECKER",
"mutant": "line 59: < -> >= (rel)",
"status": "killed",
"hidden": "6/12",
"failed_tests": [
"ACCEPTS_LIMIT_VALUES",
"GERMINATION_BEFORE_MOISTURE",
"REJECTS_FUTURE_HARVEST",
"REJECTS_HIGH_MOISTURE",
"REJECTS_LOW_GERMINATION",
"RELEASES_VALID_LOT"
]
},
{
"object": "{{P}}SEED_LOT_CHECKER",
"mutant": "line 59: OR -> AND (logic)",
"status": "killed",
"hidden": "9/12",
"failed_tests": [
"DATE_BEFORE_QUALITY",
"REJECTS_FUTURE_HARVEST",
"REJECTS_OLD_HARVEST"
]
},
{
"object": "{{P}}SEED_LOT_CHECKER",
"mutant": "line 59: > -> <= (rel)",
"status": "killed",
"hidden": "5/12",
"failed_tests": [
"ACCEPTS_LIMIT_VALUES",
"DATE_BEFORE_QUALITY",
"GERMINATION_BEFORE_MOISTURE",
"REJECTS_HIGH_MOISTURE",
"REJECTS_LOW_GERMINATION",
"REJECTS_OLD_HARVEST",
"RELEASES_VALID_LOT"
]
},
{
"object": "{{P}}SEED_LOT_CHECKER",
"mutant": "line 71: > -> <= (rel)",
"status": "killed",
"hidden": "9/12",
"failed_tests": [
"ACCEPTS_LIMIT_VALUES",
"REJECTS_HIGH_MOISTURE",
"RELEASES_VALID_LOT"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,75 @@
CLASS {{p}}seed_lot_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_lot,
lot_no TYPE c LENGTH 10,
germination TYPE i,
moisture TYPE p LENGTH 4 DECIMALS 1,
harvest_date TYPE d,
END OF ty_lot.
METHODS check_lot
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
PRIVATE SECTION.
CONSTANTS:
c_min_germination TYPE i VALUE 85,
c_max_moisture TYPE p LENGTH 4 DECIMALS 1 VALUE '12.0',
c_max_age_days TYPE i VALUE 365.
METHODS check_lot_no
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_harvest_date
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{p}}cx_seed_lot.
METHODS check_germination
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
METHODS check_moisture
IMPORTING is_lot TYPE ty_lot
RAISING {{p}}cx_seed_lot.
ENDCLASS.
CLASS {{p}}seed_lot_checker IMPLEMENTATION.
METHOD check_lot.
check_lot_no( is_lot ).
check_harvest_date( is_lot = is_lot iv_check_date = iv_check_date ).
check_germination( is_lot ).
check_moisture( is_lot ).
ENDMETHOD.
METHOD check_lot_no.
DATA(lv_letters) = substring( val = is_lot-lot_no len = 4 ).
DATA(lv_digits) = substring( val = is_lot-lot_no off = 4 len = 6 ).
IF lv_letters CN 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' OR lv_digits CN '0123456789'.
RAISE EXCEPTION TYPE {{p}}cx_lot_format.
ENDIF.
ENDMETHOD.
METHOD check_harvest_date.
IF is_lot-harvest_date IS INITIAL.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
DATA(lv_age_in_days) = iv_check_date - is_lot-harvest_date.
IF lv_age_in_days < 0 OR lv_age_in_days > c_max_age_days.
RAISE EXCEPTION TYPE {{p}}cx_lot_date.
ENDIF.
ENDMETHOD.
METHOD check_germination.
IF is_lot-germination < c_min_germination.
RAISE EXCEPTION TYPE {{p}}cx_lot_germination.
ENDIF.
ENDMETHOD.
METHOD check_moisture.
IF is_lot-moisture > c_max_moisture.
RAISE EXCEPTION TYPE {{p}}cx_lot_moisture.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,109 @@
CLASS ltc_seed_lot_checker DEFINITION FINAL FOR TESTING
DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CONSTANTS c_check_date TYPE d VALUE '20250601'.
DATA mo_cut TYPE REF TO {{p}}seed_lot_checker.
METHODS setup.
METHODS valid_lot
RETURNING VALUE(rs_lot) TYPE {{p}}seed_lot_checker=>ty_lot.
METHODS releases_valid_lot FOR TESTING.
METHODS rejects_bad_lot_no FOR TESTING.
METHODS rejects_old_harvest FOR TESTING.
METHODS rejects_low_germination FOR TESTING.
METHODS rejects_high_moisture FOR TESTING.
METHODS accepts_limit_values FOR TESTING.
ENDCLASS.
CLASS ltc_seed_lot_checker IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}seed_lot_checker( ).
ENDMETHOD.
METHOD valid_lot.
rs_lot = VALUE #( lot_no = 'WHEA123456'
germination = 90
moisture = '11.0'
harvest_date = '20250501' ).
ENDMETHOD.
METHOD releases_valid_lot.
TRY.
mo_cut->check_lot( is_lot = valid_lot( ) iv_check_date = c_check_date ).
CATCH {{p}}cx_seed_lot INTO DATA(lo_ex).
cl_abap_unit_assert=>fail( msg = lo_ex->get_message( ) ).
ENDTRY.
ENDMETHOD.
METHOD rejects_bad_lot_no.
DATA(ls_lot) = valid_lot( ).
ls_lot-lot_no = 'AB12345678'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_FORMAT expected` ).
CATCH {{p}}cx_lot_format INTO DATA(lo_format).
cl_abap_unit_assert=>assert_equals(
exp = 'The lot number has an invalid format.'
act = lo_format->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_FORMAT expected` ).
ENDTRY.
ENDMETHOD.
METHOD rejects_old_harvest.
DATA(ls_lot) = valid_lot( ).
ls_lot-harvest_date = '20240531'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_DATE expected` ).
CATCH {{p}}cx_lot_date INTO DATA(lo_date).
cl_abap_unit_assert=>assert_equals(
exp = 'The harvest date is not valid for the release check.'
act = lo_date->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_DATE expected` ).
ENDTRY.
ENDMETHOD.
METHOD rejects_low_germination.
DATA(ls_lot) = valid_lot( ).
ls_lot-germination = 84.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_GERMINATION expected` ).
CATCH {{p}}cx_lot_germination INTO DATA(lo_germ).
cl_abap_unit_assert=>assert_equals(
exp = 'The germination rate is below the minimum of 85 percent.'
act = lo_germ->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_GERMINATION expected` ).
ENDTRY.
ENDMETHOD.
METHOD rejects_high_moisture.
DATA(ls_lot) = valid_lot( ).
ls_lot-moisture = '12.1'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
cl_abap_unit_assert=>fail( msg = `CX_LOT_MOISTURE expected` ).
CATCH {{p}}cx_lot_moisture INTO DATA(lo_moist).
cl_abap_unit_assert=>assert_equals(
exp = 'The moisture is above the maximum of 12.0 percent.'
act = lo_moist->get_message( ) ).
CATCH {{p}}cx_seed_lot.
cl_abap_unit_assert=>fail( msg = `CX_LOT_MOISTURE expected` ).
ENDTRY.
ENDMETHOD.
METHOD accepts_limit_values.
DATA(ls_lot) = valid_lot( ).
ls_lot-germination = 85.
ls_lot-moisture = '12.0'.
ls_lot-harvest_date = '20240601'.
TRY.
mo_cut->check_lot( is_lot = ls_lot iv_check_date = c_check_date ).
CATCH {{p}}cx_seed_lot INTO DATA(lo_ex).
cl_abap_unit_assert=>fail( msg = lo_ex->get_message( ) ).
ENDTRY.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,13 @@
CLASS {{p}}cx_lot_date DEFINITION PUBLIC INHERITING FROM {{p}}cx_seed_lot CREATE PUBLIC.
PUBLIC SECTION.
CONSTANTS c_text TYPE string VALUE 'The harvest date is not valid for the release check.'.
METHODS constructor.
PRIVATE SECTION.
ENDCLASS.
CLASS {{p}}cx_lot_date IMPLEMENTATION.
METHOD constructor.
super->constructor( iv_text = c_text ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,13 @@
CLASS {{p}}cx_lot_format DEFINITION PUBLIC INHERITING FROM {{p}}cx_seed_lot CREATE PUBLIC.
PUBLIC SECTION.
CONSTANTS c_text TYPE string VALUE 'The lot number has an invalid format.'.
METHODS constructor.
PRIVATE SECTION.
ENDCLASS.
CLASS {{p}}cx_lot_format IMPLEMENTATION.
METHOD constructor.
super->constructor( iv_text = c_text ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,13 @@
CLASS {{p}}cx_lot_germination DEFINITION PUBLIC INHERITING FROM {{p}}cx_seed_lot CREATE PUBLIC.
PUBLIC SECTION.
CONSTANTS c_text TYPE string VALUE 'The germination rate is below the minimum of 85 percent.'.
METHODS constructor.
PRIVATE SECTION.
ENDCLASS.
CLASS {{p}}cx_lot_germination IMPLEMENTATION.
METHOD constructor.
super->constructor( iv_text = c_text ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,13 @@
CLASS {{p}}cx_lot_moisture DEFINITION PUBLIC INHERITING FROM {{p}}cx_seed_lot CREATE PUBLIC.
PUBLIC SECTION.
CONSTANTS c_text TYPE string VALUE 'The moisture is above the maximum of 12.0 percent.'.
METHODS constructor.
PRIVATE SECTION.
ENDCLASS.
CLASS {{p}}cx_lot_moisture IMPLEMENTATION.
METHOD constructor.
super->constructor( iv_text = c_text ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,21 @@
CLASS {{p}}cx_seed_lot DEFINITION PUBLIC INHERITING FROM cx_static_check CREATE PUBLIC.
PUBLIC SECTION.
METHODS constructor
IMPORTING iv_text TYPE string.
METHODS get_message
RETURNING VALUE(rv_text) TYPE string.
PRIVATE SECTION.
DATA mv_text TYPE string.
ENDCLASS.
CLASS {{p}}cx_seed_lot IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
mv_text = iv_text.
ENDMETHOD.
METHOD get_message.
rv_text = mv_text.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,60 @@
# 1. Goal
A seed company releases seed lots from its warehouse. Before the warehouse
releases a lot, it calls a check for that lot and for one check date. The check
raises a class-based exception with a message when the lot must not be released.
# 2. Open questions
None.
# 3. Context
- The exception classes exist in package $TMP and are active:
- {{P}}CX_SEED_LOT is the superclass of the other four classes. It inherits
from CX_STATIC_CHECK. It has the public method GET_MESSAGE that returns the
message text of the exception.
- {{P}}CX_LOT_FORMAT, {{P}}CX_LOT_DATE, {{P}}CX_LOT_GERMINATION and
{{P}}CX_LOT_MOISTURE inherit from {{P}}CX_SEED_LOT. Each of them has a
constant C_TEXT with its message text and a constructor without parameters.
- The warehouse terminal calls the check for one lot and for one check date.
# 4. Contract
- Create the class {{P}}SEED_LOT_CHECKER in package $TMP.
- The class is public, final and has a public constructor without parameters.
- The class has this public type:
TYPES: BEGIN OF ty_lot,
lot_no TYPE c LENGTH 10,
germination TYPE i,
moisture TYPE p LENGTH 4 DECIMALS 1,
harvest_date TYPE d,
END OF ty_lot.
- The class has this public method:
METHODS check_lot
IMPORTING is_lot TYPE ty_lot
iv_check_date TYPE d
RAISING {{P}}CX_SEED_LOT.
- Do not add other public methods.
# 5. Business rules
Apply the rules in this sequence. Raise the exception of the first rule that
fails. If no rule fails, the method ends normally and the lot is released.
1. Lot number: positions 1 to 4 must be the letters A to Z. Positions 5 to 10
must be the digits 0 to 9. If not, raise {{P}}CX_LOT_FORMAT.
2. Harvest date: the harvest date must not be initial. The harvest date must
not be later than the check date. The harvest date must not be earlier than
the check date minus 365 days. If one of these conditions is not true, raise
{{P}}CX_LOT_DATE.
3. Germination: the germination rate must be at least 85. If not, raise
{{P}}CX_LOT_GERMINATION.
4. Moisture: the moisture must be at most 12.0. If not, raise
{{P}}CX_LOT_MOISTURE.
# 6. Constraints
- Release target: SAP_BASIS 816 (ABAP Platform 2025).
- Coding standards: Clean ABAP. Method length below 40 statements. No global
variables. No comment that restates the code.
- Out of scope: do not change {{P}}CX_SEED_LOT, {{P}}CX_LOT_FORMAT,
{{P}}CX_LOT_DATE, {{P}}CX_LOT_GERMINATION or {{P}}CX_LOT_MOISTURE.
# 7. Acceptance
- The class is active and has no syntax error.
- The hidden tests pass.
- Write your own ABAP Unit tests for the class.

View File

@@ -0,0 +1,78 @@
{
"id": "G1084",
"category": "D",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [
{
"type": "CLAS",
"name": "{{P}}CX_SEED_LOT",
"file": "seed/cx_seed_lot.clas.abap",
"description": "Exception superclass with the message text"
},
{
"type": "CLAS",
"name": "{{P}}CX_LOT_FORMAT",
"file": "seed/cx_lot_format.clas.abap",
"description": "Exception: the lot number has an invalid format"
},
{
"type": "CLAS",
"name": "{{P}}CX_LOT_DATE",
"file": "seed/cx_lot_date.clas.abap",
"description": "Exception: the harvest date is not valid"
},
{
"type": "CLAS",
"name": "{{P}}CX_LOT_GERMINATION",
"file": "seed/cx_lot_germination.clas.abap",
"description": "Exception: the germination rate is too low"
},
{
"type": "CLAS",
"name": "{{P}}CX_LOT_MOISTURE",
"file": "seed/cx_lot_moisture.clas.abap",
"description": "Exception: the moisture is too high"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}SEED_LOT_CHECKER"
}
],
"out_of_scope": [
"{{P}}CX_SEED_LOT",
"{{P}}CX_LOT_FORMAT",
"{{P}}CX_LOT_DATE",
"{{P}}CX_LOT_GERMINATION",
"{{P}}CX_LOT_MOISTURE"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}SEED_LOT_HIDDEN",
"file": "hidden/seed_lot_hidden.clas.abap",
"description": "Hidden tests for the seed lot release check"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}SEED_LOT_CHECKER",
"file": "reference/seed_lot_checker.clas.abap",
"description": "Seed lot release check",
"testclasses_file": "reference/seed_lot_checker.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"db_operation_in_loop"
]
}