Hard batch G0022-G0026: 5/5 accepted; budget floor, CDS checks, mutation check
- generator: budget floor (2x oracle activations, 3x calls), static checks for CDS $parameters and UNION annotation - harness/mutation.py: deterministic mutants of the reference; hidden tests must fail - G0022 revalidated with harness fixes: oracle 100, null 0 - results in docs/faz1-tasarim.md 11f Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
43
tasks_gen/eval/G0022/generation.json
Normal file
43
tasks_gen/eval/G0022/generation.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"id": "G0022",
|
||||
"pool": "eval",
|
||||
"object_type": "CLAS",
|
||||
"category": "D",
|
||||
"attempts": [
|
||||
{
|
||||
"stage": "validate",
|
||||
"oracle": 0,
|
||||
"null": 0
|
||||
},
|
||||
{
|
||||
"stage": "validate",
|
||||
"oracle": 0,
|
||||
"null": 0
|
||||
},
|
||||
{
|
||||
"stage": "validate",
|
||||
"oracle": 0,
|
||||
"null": 0
|
||||
},
|
||||
{
|
||||
"stage": "validate",
|
||||
"oracle": 0,
|
||||
"null": 0
|
||||
},
|
||||
{
|
||||
"stage": "revalidate",
|
||||
"by": "harness fix 2026-10-03",
|
||||
"change": "G6 ignores unknown standard superclass (abaplint); reference in dependency order. Bundle not changed.",
|
||||
"oracle": 95.0,
|
||||
"null": 0
|
||||
},
|
||||
{
|
||||
"stage": "revalidate",
|
||||
"by": "harness fix 2026-10-03",
|
||||
"change": "budget floor: max_activations 12 -> 14 (reference alone needs 13).",
|
||||
"oracle": 100.0,
|
||||
"null": 0
|
||||
}
|
||||
],
|
||||
"accepted": true
|
||||
}
|
||||
223
tasks_gen/eval/G0022/hidden/d01_hidden.clas.abap
Normal file
223
tasks_gen/eval/G0022/hidden/d01_hidden.clas.abap
Normal file
@@ -0,0 +1,223 @@
|
||||
CLASS {{p}}d01_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
|
||||
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
|
||||
|
||||
PRIVATE SECTION.
|
||||
TYPES ty_amount TYPE {{p}}if_expense_claim=>ty_amount.
|
||||
|
||||
DATA mo_cut TYPE REF TO {{p}}expense_validator.
|
||||
|
||||
METHODS setup.
|
||||
METHODS valid_claim_passes FOR TESTING.
|
||||
METHODS zero_amount_rejected FOR TESTING.
|
||||
METHODS negative_amount_rejected FOR TESTING.
|
||||
METHODS unknown_currency_rejected FOR TESTING.
|
||||
METHODS future_date_rejected FOR TESTING.
|
||||
METHODS today_is_accepted FOR TESTING.
|
||||
METHODS receipt_required FOR TESTING.
|
||||
METHODS receipt_not_required_below FOR TESTING.
|
||||
METHODS cost_center_required FOR TESTING.
|
||||
METHODS cost_center_not_required FOR TESTING.
|
||||
METHODS amount_rule_has_priority FOR TESTING.
|
||||
METHODS receipt_rule_has_priority FOR TESTING.
|
||||
|
||||
METHODS build_claim
|
||||
IMPORTING iv_amount TYPE ty_amount
|
||||
iv_currency TYPE {{p}}if_expense_claim=>ty_currency
|
||||
iv_date TYPE d
|
||||
iv_cc TYPE {{p}}if_expense_claim=>ty_cost_center
|
||||
iv_receipt TYPE abap_bool
|
||||
RETURNING VALUE(rs_claim) TYPE {{p}}if_expense_claim=>ty_claim.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
CLASS {{p}}d01_hidden IMPLEMENTATION.
|
||||
METHOD setup.
|
||||
mo_cut = NEW {{p}}expense_validator( ).
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD build_claim.
|
||||
rs_claim = VALUE #( amount = iv_amount
|
||||
currency = iv_currency
|
||||
claim_date = iv_date
|
||||
cost_center = iv_cc
|
||||
has_receipt = iv_receipt ).
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD valid_claim_passes.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '250.00' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx).
|
||||
cl_abap_unit_assert=>fail( msg = lx->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD zero_amount_rejected.
|
||||
DATA(ls_claim) = build_claim( iv_amount = 0 iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_amount INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = CONV ty_amount( '0.00' )
|
||||
act = lx->mv_amount ).
|
||||
cl_abap_unit_assert=>assert_equals( exp = 'Amount must be positive'
|
||||
act = lx->get_message( ) ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD negative_amount_rejected.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '-50.00' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_amount INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = CONV ty_amount( '-50.00' )
|
||||
act = lx->mv_amount ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD unknown_currency_rejected.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '250.00' iv_currency = 'JPY'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_currency INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = 'JPY'
|
||||
act = lx->mv_currency ).
|
||||
cl_abap_unit_assert=>assert_equals( exp = 'Currency is not supported'
|
||||
act = lx->get_message( ) ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD future_date_rejected.
|
||||
DATA lv_tomorrow TYPE d.
|
||||
lv_tomorrow = sy-datum + 1.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '250.00' iv_currency = 'EUR'
|
||||
iv_date = lv_tomorrow iv_cc = 'CC1000'
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_date INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = lv_tomorrow
|
||||
act = lx->mv_claim_date ).
|
||||
cl_abap_unit_assert=>assert_equals( exp = 'Claim date is in the future'
|
||||
act = lx->get_message( ) ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD today_is_accepted.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '250.00' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx).
|
||||
cl_abap_unit_assert=>fail( msg = lx->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD receipt_required.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '250.00' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_false ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_receipt INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = CONV ty_amount( '250.00' )
|
||||
act = lx->mv_amount ).
|
||||
cl_abap_unit_assert=>assert_equals( exp = 'Receipt is required'
|
||||
act = lx->get_message( ) ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD receipt_not_required_below.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '99.99' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_false ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx).
|
||||
cl_abap_unit_assert=>fail( msg = lx->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD cost_center_required.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '1500.00' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = ''
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_costcenter INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = CONV ty_amount( '1500.00' )
|
||||
act = lx->mv_amount ).
|
||||
cl_abap_unit_assert=>assert_equals( exp = 'Cost center is required'
|
||||
act = lx->get_message( ) ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD cost_center_not_required.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '999.99' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = ''
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx).
|
||||
cl_abap_unit_assert=>fail( msg = lx->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD amount_rule_has_priority.
|
||||
DATA lv_future TYPE d.
|
||||
lv_future = sy-datum + 1.
|
||||
DATA(ls_claim) = build_claim( iv_amount = 0 iv_currency = 'JPY'
|
||||
iv_date = lv_future iv_cc = ''
|
||||
iv_receipt = abap_false ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_amount INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = CONV ty_amount( '0.00' )
|
||||
act = lx->mv_amount ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD receipt_rule_has_priority.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '1500.00' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = ''
|
||||
iv_receipt = abap_false ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_receipt INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = CONV ty_amount( '1500.00' )
|
||||
act = lx->mv_amount ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
ENDCLASS.
|
||||
20
tasks_gen/eval/G0022/reference/cx_claim_amount.clas.abap
Normal file
20
tasks_gen/eval/G0022/reference/cx_claim_amount.clas.abap
Normal file
@@ -0,0 +1,20 @@
|
||||
CLASS {{p}}cx_claim_amount DEFINITION
|
||||
PUBLIC
|
||||
INHERITING FROM {{p}}cx_claim_error
|
||||
FINAL
|
||||
CREATE PUBLIC.
|
||||
|
||||
PUBLIC SECTION.
|
||||
DATA mv_amount TYPE {{p}}if_expense_claim=>ty_amount READ-ONLY.
|
||||
|
||||
METHODS constructor
|
||||
IMPORTING iv_amount TYPE {{p}}if_expense_claim=>ty_amount.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
CLASS {{p}}cx_claim_amount IMPLEMENTATION.
|
||||
METHOD constructor.
|
||||
super->constructor( iv_message = 'Amount must be positive' ).
|
||||
mv_amount = iv_amount.
|
||||
ENDMETHOD.
|
||||
ENDCLASS.
|
||||
20
tasks_gen/eval/G0022/reference/cx_claim_costcenter.clas.abap
Normal file
20
tasks_gen/eval/G0022/reference/cx_claim_costcenter.clas.abap
Normal file
@@ -0,0 +1,20 @@
|
||||
CLASS {{p}}cx_claim_costcenter DEFINITION
|
||||
PUBLIC
|
||||
INHERITING FROM {{p}}cx_claim_error
|
||||
FINAL
|
||||
CREATE PUBLIC.
|
||||
|
||||
PUBLIC SECTION.
|
||||
DATA mv_amount TYPE {{p}}if_expense_claim=>ty_amount READ-ONLY.
|
||||
|
||||
METHODS constructor
|
||||
IMPORTING iv_amount TYPE {{p}}if_expense_claim=>ty_amount.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
CLASS {{p}}cx_claim_costcenter IMPLEMENTATION.
|
||||
METHOD constructor.
|
||||
super->constructor( iv_message = 'Cost center is required' ).
|
||||
mv_amount = iv_amount.
|
||||
ENDMETHOD.
|
||||
ENDCLASS.
|
||||
20
tasks_gen/eval/G0022/reference/cx_claim_currency.clas.abap
Normal file
20
tasks_gen/eval/G0022/reference/cx_claim_currency.clas.abap
Normal file
@@ -0,0 +1,20 @@
|
||||
CLASS {{p}}cx_claim_currency DEFINITION
|
||||
PUBLIC
|
||||
INHERITING FROM {{p}}cx_claim_error
|
||||
FINAL
|
||||
CREATE PUBLIC.
|
||||
|
||||
PUBLIC SECTION.
|
||||
DATA mv_currency TYPE {{p}}if_expense_claim=>ty_currency READ-ONLY.
|
||||
|
||||
METHODS constructor
|
||||
IMPORTING iv_currency TYPE {{p}}if_expense_claim=>ty_currency.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
CLASS {{p}}cx_claim_currency IMPLEMENTATION.
|
||||
METHOD constructor.
|
||||
super->constructor( iv_message = 'Currency is not supported' ).
|
||||
mv_currency = iv_currency.
|
||||
ENDMETHOD.
|
||||
ENDCLASS.
|
||||
20
tasks_gen/eval/G0022/reference/cx_claim_date.clas.abap
Normal file
20
tasks_gen/eval/G0022/reference/cx_claim_date.clas.abap
Normal file
@@ -0,0 +1,20 @@
|
||||
CLASS {{p}}cx_claim_date DEFINITION
|
||||
PUBLIC
|
||||
INHERITING FROM {{p}}cx_claim_error
|
||||
FINAL
|
||||
CREATE PUBLIC.
|
||||
|
||||
PUBLIC SECTION.
|
||||
DATA mv_claim_date TYPE d READ-ONLY.
|
||||
|
||||
METHODS constructor
|
||||
IMPORTING iv_claim_date TYPE d.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
CLASS {{p}}cx_claim_date IMPLEMENTATION.
|
||||
METHOD constructor.
|
||||
super->constructor( iv_message = 'Claim date is in the future' ).
|
||||
mv_claim_date = iv_claim_date.
|
||||
ENDMETHOD.
|
||||
ENDCLASS.
|
||||
20
tasks_gen/eval/G0022/reference/cx_claim_receipt.clas.abap
Normal file
20
tasks_gen/eval/G0022/reference/cx_claim_receipt.clas.abap
Normal file
@@ -0,0 +1,20 @@
|
||||
CLASS {{p}}cx_claim_receipt DEFINITION
|
||||
PUBLIC
|
||||
INHERITING FROM {{p}}cx_claim_error
|
||||
FINAL
|
||||
CREATE PUBLIC.
|
||||
|
||||
PUBLIC SECTION.
|
||||
DATA mv_amount TYPE {{p}}if_expense_claim=>ty_amount READ-ONLY.
|
||||
|
||||
METHODS constructor
|
||||
IMPORTING iv_amount TYPE {{p}}if_expense_claim=>ty_amount.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
CLASS {{p}}cx_claim_receipt IMPLEMENTATION.
|
||||
METHOD constructor.
|
||||
super->constructor( iv_message = 'Receipt is required' ).
|
||||
mv_amount = iv_amount.
|
||||
ENDMETHOD.
|
||||
ENDCLASS.
|
||||
85
tasks_gen/eval/G0022/reference/expense_validator.clas.abap
Normal file
85
tasks_gen/eval/G0022/reference/expense_validator.clas.abap
Normal file
@@ -0,0 +1,85 @@
|
||||
CLASS {{p}}expense_validator DEFINITION
|
||||
PUBLIC
|
||||
FINAL
|
||||
CREATE PUBLIC.
|
||||
|
||||
PUBLIC SECTION.
|
||||
METHODS validate
|
||||
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
|
||||
RAISING {{p}}cx_claim_error.
|
||||
|
||||
PRIVATE SECTION.
|
||||
CONSTANTS:
|
||||
c_receipt_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '100.00',
|
||||
c_cc_limit TYPE {{p}}if_expense_claim=>ty_amount VALUE '1000.00'.
|
||||
|
||||
METHODS check_amount
|
||||
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
|
||||
RAISING {{p}}cx_claim_error.
|
||||
METHODS check_currency
|
||||
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
|
||||
RAISING {{p}}cx_claim_error.
|
||||
METHODS check_date
|
||||
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
|
||||
RAISING {{p}}cx_claim_error.
|
||||
METHODS check_receipt
|
||||
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
|
||||
RAISING {{p}}cx_claim_error.
|
||||
METHODS check_cost_center
|
||||
IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
|
||||
RAISING {{p}}cx_claim_error.
|
||||
METHODS is_supported_currency
|
||||
IMPORTING iv_currency TYPE {{p}}if_expense_claim=>ty_currency
|
||||
RETURNING VALUE(rv_supported) TYPE abap_bool.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
CLASS {{p}}expense_validator IMPLEMENTATION.
|
||||
METHOD validate.
|
||||
check_amount( is_claim ).
|
||||
check_currency( is_claim ).
|
||||
check_date( is_claim ).
|
||||
check_receipt( is_claim ).
|
||||
check_cost_center( is_claim ).
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD check_amount.
|
||||
IF is_claim-amount <= 0.
|
||||
RAISE EXCEPTION TYPE {{p}}cx_claim_amount
|
||||
EXPORTING iv_amount = is_claim-amount.
|
||||
ENDIF.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD check_currency.
|
||||
IF is_supported_currency( is_claim-currency ) = abap_false.
|
||||
RAISE EXCEPTION TYPE {{p}}cx_claim_currency
|
||||
EXPORTING iv_currency = is_claim-currency.
|
||||
ENDIF.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD check_date.
|
||||
IF is_claim-claim_date > sy-datum.
|
||||
RAISE EXCEPTION TYPE {{p}}cx_claim_date
|
||||
EXPORTING iv_claim_date = is_claim-claim_date.
|
||||
ENDIF.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD check_receipt.
|
||||
IF is_claim-amount >= c_receipt_limit AND is_claim-has_receipt = abap_false.
|
||||
RAISE EXCEPTION TYPE {{p}}cx_claim_receipt
|
||||
EXPORTING iv_amount = is_claim-amount.
|
||||
ENDIF.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD check_cost_center.
|
||||
IF is_claim-amount >= c_cc_limit AND is_claim-cost_center IS INITIAL.
|
||||
RAISE EXCEPTION TYPE {{p}}cx_claim_costcenter
|
||||
EXPORTING iv_amount = is_claim-amount.
|
||||
ENDIF.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD is_supported_currency.
|
||||
rv_supported = xsdbool( iv_currency = 'EUR' OR iv_currency = 'USD'
|
||||
OR iv_currency = 'GBP' OR iv_currency = 'CHF' ).
|
||||
ENDMETHOD.
|
||||
ENDCLASS.
|
||||
@@ -0,0 +1,127 @@
|
||||
CLASS ltc_expense_validator DEFINITION FINAL FOR TESTING
|
||||
DURATION SHORT RISK LEVEL HARMLESS.
|
||||
|
||||
PRIVATE SECTION.
|
||||
TYPES ty_amount TYPE {{p}}if_expense_claim=>ty_amount.
|
||||
|
||||
DATA mo_cut TYPE REF TO {{p}}expense_validator.
|
||||
|
||||
METHODS setup.
|
||||
METHODS valid_claim FOR TESTING.
|
||||
METHODS zero_amount FOR TESTING.
|
||||
METHODS unknown_currency FOR TESTING.
|
||||
METHODS future_date FOR TESTING.
|
||||
METHODS receipt_missing FOR TESTING.
|
||||
METHODS cost_center_missing FOR TESTING.
|
||||
|
||||
METHODS build_claim
|
||||
IMPORTING iv_amount TYPE ty_amount
|
||||
iv_currency TYPE {{p}}if_expense_claim=>ty_currency
|
||||
iv_date TYPE d
|
||||
iv_cc TYPE {{p}}if_expense_claim=>ty_cost_center
|
||||
iv_receipt TYPE abap_bool
|
||||
RETURNING VALUE(rs_claim) TYPE {{p}}if_expense_claim=>ty_claim.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
CLASS ltc_expense_validator IMPLEMENTATION.
|
||||
METHOD setup.
|
||||
mo_cut = NEW {{p}}expense_validator( ).
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD build_claim.
|
||||
rs_claim = VALUE #( amount = iv_amount
|
||||
currency = iv_currency
|
||||
claim_date = iv_date
|
||||
cost_center = iv_cc
|
||||
has_receipt = iv_receipt ).
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD valid_claim.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '250.00' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx).
|
||||
cl_abap_unit_assert=>fail( msg = lx->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD zero_amount.
|
||||
DATA(ls_claim) = build_claim( iv_amount = 0 iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_amount INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = CONV ty_amount( '0.00' )
|
||||
act = lx->mv_amount ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD unknown_currency.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '250.00' iv_currency = 'JPY'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_currency INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = 'JPY'
|
||||
act = lx->mv_currency ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD future_date.
|
||||
DATA lv_future TYPE d.
|
||||
lv_future = sy-datum + 1.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '250.00' iv_currency = 'EUR'
|
||||
iv_date = lv_future iv_cc = 'CC1000'
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_date INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = lv_future
|
||||
act = lx->mv_claim_date ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD receipt_missing.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '250.00' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = 'CC1000'
|
||||
iv_receipt = abap_false ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_receipt INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = 'Receipt is required'
|
||||
act = lx->get_message( ) ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD cost_center_missing.
|
||||
DATA(ls_claim) = build_claim( iv_amount = '1500.00' iv_currency = 'EUR'
|
||||
iv_date = sy-datum iv_cc = ''
|
||||
iv_receipt = abap_true ).
|
||||
TRY.
|
||||
mo_cut->validate( ls_claim ).
|
||||
cl_abap_unit_assert=>fail( msg = 'Exception expected' ).
|
||||
CATCH {{p}}cx_claim_costcenter INTO DATA(lx).
|
||||
cl_abap_unit_assert=>assert_equals( exp = 'Cost center is required'
|
||||
act = lx->get_message( ) ).
|
||||
CATCH {{p}}cx_claim_error INTO DATA(lx_other).
|
||||
cl_abap_unit_assert=>fail( msg = lx_other->get_message( ) ).
|
||||
ENDTRY.
|
||||
ENDMETHOD.
|
||||
ENDCLASS.
|
||||
27
tasks_gen/eval/G0022/seed/cx_claim_error.clas.abap
Normal file
27
tasks_gen/eval/G0022/seed/cx_claim_error.clas.abap
Normal file
@@ -0,0 +1,27 @@
|
||||
CLASS {{p}}cx_claim_error DEFINITION
|
||||
PUBLIC
|
||||
INHERITING FROM cx_static_check
|
||||
CREATE PUBLIC.
|
||||
|
||||
PUBLIC SECTION.
|
||||
METHODS constructor
|
||||
IMPORTING iv_message TYPE string.
|
||||
|
||||
METHODS get_message
|
||||
RETURNING VALUE(rv_message) TYPE string.
|
||||
|
||||
PRIVATE SECTION.
|
||||
DATA mv_message TYPE string.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
CLASS {{p}}cx_claim_error IMPLEMENTATION.
|
||||
METHOD constructor.
|
||||
super->constructor( ).
|
||||
mv_message = iv_message.
|
||||
ENDMETHOD.
|
||||
|
||||
METHOD get_message.
|
||||
rv_message = mv_message.
|
||||
ENDMETHOD.
|
||||
ENDCLASS.
|
||||
14
tasks_gen/eval/G0022/seed/if_expense_claim.intf.abap
Normal file
14
tasks_gen/eval/G0022/seed/if_expense_claim.intf.abap
Normal file
@@ -0,0 +1,14 @@
|
||||
INTERFACE {{p}}if_expense_claim PUBLIC.
|
||||
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
|
||||
TYPES ty_currency TYPE c LENGTH 3.
|
||||
TYPES ty_cost_center TYPE c LENGTH 10.
|
||||
|
||||
TYPES:
|
||||
BEGIN OF ty_claim,
|
||||
amount TYPE ty_amount,
|
||||
currency TYPE ty_currency,
|
||||
claim_date TYPE d,
|
||||
cost_center TYPE ty_cost_center,
|
||||
has_receipt TYPE abap_bool,
|
||||
END OF ty_claim.
|
||||
ENDINTERFACE.
|
||||
72
tasks_gen/eval/G0022/spec.md
Normal file
72
tasks_gen/eval/G0022/spec.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# 1. Goal
|
||||
Validate an employee expense claim before it is posted to accounting. The check
|
||||
reports the first rule that fails as a class-based exception. Each exception
|
||||
carries the value that caused the failure and a short message.
|
||||
|
||||
# 2. Open questions
|
||||
None.
|
||||
|
||||
# 3. Context
|
||||
- The interface {{P}}IF_EXPENSE_CLAIM exists in package $TMP and is active. It
|
||||
contains types only and has no methods:
|
||||
- TY_AMOUNT, a packed number with length 8 and 2 decimals.
|
||||
- TY_CURRENCY, a character field with length 3.
|
||||
- TY_COST_CENTER, a character field with length 10.
|
||||
- TY_CLAIM, a structure with the components AMOUNT (TY_AMOUNT), CURRENCY
|
||||
(TY_CURRENCY), CLAIM_DATE (type D), COST_CENTER (TY_COST_CENTER) and
|
||||
HAS_RECEIPT (ABAP_BOOL).
|
||||
- The class {{P}}CX_CLAIM_ERROR exists in package $TMP and is active. It is a
|
||||
direct subclass of CX_STATIC_CHECK. Its constructor has the importing
|
||||
parameter IV_MESSAGE (TYPE string). The method GET_MESSAGE returns this text
|
||||
(TYPE string).
|
||||
|
||||
# 4. Contract
|
||||
- Create the class {{P}}EXPENSE_VALIDATOR in package $TMP.
|
||||
- The class is public and final and has a public constructor without parameters.
|
||||
- The class has exactly one public method:
|
||||
VALIDATE IMPORTING is_claim TYPE {{p}}if_expense_claim=>ty_claim
|
||||
RAISING {{p}}cx_claim_error.
|
||||
- Create these exception classes in package $TMP. Each one inherits from
|
||||
{{P}}CX_CLAIM_ERROR, is final and has a public constructor.
|
||||
- {{P}}CX_CLAIM_AMOUNT: constructor parameter IV_AMOUNT of type TY_AMOUNT of
|
||||
{{P}}IF_EXPENSE_CLAIM. Public read-only attribute MV_AMOUNT of the same
|
||||
type. Message: Amount must be positive
|
||||
- {{P}}CX_CLAIM_CURRENCY: constructor parameter IV_CURRENCY of type
|
||||
TY_CURRENCY. Public read-only attribute MV_CURRENCY of the same type.
|
||||
Message: Currency is not supported
|
||||
- {{P}}CX_CLAIM_DATE: constructor parameter IV_CLAIM_DATE of type D. Public
|
||||
read-only attribute MV_CLAIM_DATE of type D. Message: Claim date is in the
|
||||
future
|
||||
- {{P}}CX_CLAIM_RECEIPT: constructor parameter IV_AMOUNT of type TY_AMOUNT.
|
||||
Public read-only attribute MV_AMOUNT of the same type. Message: Receipt is
|
||||
required
|
||||
- {{P}}CX_CLAIM_COSTCENTER: constructor parameter IV_AMOUNT of type TY_AMOUNT.
|
||||
Public read-only attribute MV_AMOUNT of the same type. Message: Cost center
|
||||
is required
|
||||
- GET_MESSAGE returns the message of the exception.
|
||||
- Do not add other public methods or attributes.
|
||||
|
||||
# 5. Business rules
|
||||
Check the claim in this sequence. Raise the exception of the first rule that
|
||||
fails. If no rule fails, the method ends without an exception.
|
||||
1. AMOUNT must be greater than zero. Else raise {{P}}CX_CLAIM_AMOUNT with
|
||||
IV_AMOUNT = AMOUNT.
|
||||
2. CURRENCY must be one of EUR, USD, GBP, CHF. Else raise
|
||||
{{P}}CX_CLAIM_CURRENCY with IV_CURRENCY = CURRENCY.
|
||||
3. CLAIM_DATE must not be later than the current date. Else raise
|
||||
{{P}}CX_CLAIM_DATE with IV_CLAIM_DATE = CLAIM_DATE.
|
||||
4. If AMOUNT is 100.00 or more, HAS_RECEIPT must be true. Else raise
|
||||
{{P}}CX_CLAIM_RECEIPT with IV_AMOUNT = AMOUNT.
|
||||
5. If AMOUNT is 1000.00 or more, COST_CENTER must not be initial. Else raise
|
||||
{{P}}CX_CLAIM_COSTCENTER with IV_AMOUNT = AMOUNT.
|
||||
|
||||
# 6. Constraints
|
||||
- Release target: 8.16.
|
||||
- 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}}IF_EXPENSE_CLAIM and {{P}}CX_CLAIM_ERROR.
|
||||
|
||||
# 7. Acceptance
|
||||
- All objects are active and have no syntax error.
|
||||
- The hidden tests pass.
|
||||
- Write your own ABAP Unit tests for {{P}}EXPENSE_VALIDATOR.
|
||||
107
tasks_gen/eval/G0022/task.json
Normal file
107
tasks_gen/eval/G0022/task.json
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"id": "G0022",
|
||||
"category": "D",
|
||||
"object_type": "CLAS",
|
||||
"difficulty": 2,
|
||||
"release_target": "v816",
|
||||
"expected_outcome": "implement",
|
||||
"budget": {
|
||||
"max_tool_calls": 45,
|
||||
"max_activations": 14
|
||||
},
|
||||
"seed": [
|
||||
{
|
||||
"type": "INTF",
|
||||
"name": "{{P}}IF_EXPENSE_CLAIM",
|
||||
"file": "seed/if_expense_claim.intf.abap",
|
||||
"description": "Types for an expense claim"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_ERROR",
|
||||
"file": "seed/cx_claim_error.clas.abap",
|
||||
"description": "Base exception that carries a message text"
|
||||
}
|
||||
],
|
||||
"contract": [
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_AMOUNT"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_CURRENCY"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_DATE"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_RECEIPT"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_COSTCENTER"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}EXPENSE_VALIDATOR"
|
||||
}
|
||||
],
|
||||
"out_of_scope": [
|
||||
"{{P}}IF_EXPENSE_CLAIM",
|
||||
"{{P}}CX_CLAIM_ERROR"
|
||||
],
|
||||
"hidden_tests": [
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}D01_HIDDEN",
|
||||
"file": "hidden/d01_hidden.clas.abap",
|
||||
"description": "Hidden tests for the expense claim validation"
|
||||
}
|
||||
],
|
||||
"reference": [
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_AMOUNT",
|
||||
"file": "reference/cx_claim_amount.clas.abap",
|
||||
"description": "Exception for a non positive amount"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_CURRENCY",
|
||||
"file": "reference/cx_claim_currency.clas.abap",
|
||||
"description": "Exception for an unsupported currency"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_DATE",
|
||||
"file": "reference/cx_claim_date.clas.abap",
|
||||
"description": "Exception for a claim date in the future"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_RECEIPT",
|
||||
"file": "reference/cx_claim_receipt.clas.abap",
|
||||
"description": "Exception for a missing receipt"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}CX_CLAIM_COSTCENTER",
|
||||
"file": "reference/cx_claim_costcenter.clas.abap",
|
||||
"description": "Exception for a missing cost center"
|
||||
},
|
||||
{
|
||||
"type": "CLAS",
|
||||
"name": "{{P}}EXPENSE_VALIDATOR",
|
||||
"file": "reference/expense_validator.clas.abap",
|
||||
"description": "Validates an expense claim and raises class-based exceptions",
|
||||
"testclasses_file": "reference/expense_validator.testclasses.abap"
|
||||
}
|
||||
],
|
||||
"craft_checks": [
|
||||
"method_length",
|
||||
"exception_design"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user