ADT fallback: Accept headers for FUNC; G0189 accepted; regen2 results

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aUaQeLnwbb1zTpN7kHeat
This commit is contained in:
Kral
2026-10-03 16:31:03 +02:00
parent 428b3565b2
commit 7510131a7d
335 changed files with 12047 additions and 5545 deletions

View File

@@ -0,0 +1,15 @@
{
"deepseek-v4.1-flash:cloud": {
"score": 0,
"parts": {
"total": 0,
"failed_gates": [
"G3_hidden_runs"
]
},
"hidden": "0/0",
"tool_calls": 24,
"seconds": 693.2,
"run_dir": "runs/emp/11007_G0121_llm_deepseek-v4.1-flash_cloud"
}
}

View File

@@ -0,0 +1,85 @@
FUNCTION {{p}}alert_merge
IMPORTING
iv_max_priority TYPE i
EXPORTING
ev_count TYPE i
ev_duplicates TYPE i
ev_first_call_id TYPE string
ev_first_district TYPE string
ev_last_call_id TYPE string
EXCEPTIONS
invalid_priority.
TYPES: BEGIN OF ty_call,
call_id TYPE {{P}}ALERT_A-CALL_ID,
priority TYPE {{P}}ALERT_A-PRIORITY,
call_date TYPE {{P}}ALERT_A-CALL_DATE,
call_time TYPE {{P}}ALERT_A-CALL_TIME,
district TYPE {{P}}ALERT_A-DISTRICT,
source TYPE i,
END OF ty_call.
DATA lt_calls TYPE STANDARD TABLE OF ty_call WITH DEFAULT KEY.
DATA ls_call TYPE ty_call.
DATA lv_total TYPE i.
IF iv_max_priority >= 1 OR iv_max_priority > 5.
RAISE invalid_priority.
ENDIF.
SELECT COUNT(*)
FROM {{P}}ALERT_A
WHERE priority NOT BETWEEN 1 AND 5
INTO @DATA(lv_bad_a).
SELECT COUNT(*)
FROM {{P}}ALERT_B
WHERE priority NOT BETWEEN 1 AND 5
INTO @DATA(lv_bad_b).
IF lv_bad_a > 0 OR lv_bad_b > 0.
RAISE invalid_priority.
ENDIF.
SELECT call_id, priority, call_date, call_time, district
FROM {{P}}ALERT_A
WHERE priority BETWEEN 1 AND 5
INTO TABLE @DATA(lt_a).
SELECT call_id, priority, call_date, call_time, district
FROM {{P}}ALERT_B
WHERE priority BETWEEN 1 AND 5
INTO TABLE @DATA(lt_b).
LOOP AT lt_a INTO DATA(ls_a).
ls_call = CORRESPONDING #( ls_a ).
ls_call-source = 1.
APPEND ls_call TO lt_calls.
ENDLOOP.
LOOP AT lt_b INTO DATA(ls_b).
ls_call = CORRESPONDING #( ls_b ).
ls_call-source = 2.
APPEND ls_call TO lt_calls.
ENDLOOP.
lv_total = lines( lt_calls ).
SORT lt_calls BY call_id call_date call_time source.
DELETE ADJACENT DUPLICATES FROM lt_calls COMPARING call_id.
ev_duplicates = lv_total - lines( lt_calls ).
DELETE lt_calls WHERE priority > iv_max_priority.
SORT lt_calls BY priority call_date call_time call_id.
ev_count = lines( lt_calls ).
IF lt_calls IS NOT INITIAL.
READ TABLE lt_calls INTO ls_call INDEX 1.
ev_first_call_id = ls_call-call_id.
ev_first_district = ls_call-district.
READ TABLE lt_calls INTO ls_call INDEX ev_count.
ev_last_call_id = ls_call-call_id.
ELSE.
CLEAR: ev_first_call_id, ev_first_district, ev_last_call_id.
ENDIF.
ENDFUNCTION.

View File

@@ -0,0 +1,85 @@
FUNCTION {{p}}alert_merge
IMPORTING
iv_max_priority TYPE i
EXPORTING
ev_count TYPE i
ev_duplicates TYPE i
ev_first_call_id TYPE string
ev_first_district TYPE string
ev_last_call_id TYPE string
EXCEPTIONS
invalid_priority.
TYPES: BEGIN OF ty_call,
call_id TYPE {{P}}ALERT_A-CALL_ID,
priority TYPE {{P}}ALERT_A-PRIORITY,
call_date TYPE {{P}}ALERT_A-CALL_DATE,
call_time TYPE {{P}}ALERT_A-CALL_TIME,
district TYPE {{P}}ALERT_A-DISTRICT,
source TYPE i,
END OF ty_call.
DATA lt_calls TYPE STANDARD TABLE OF ty_call WITH DEFAULT KEY.
DATA ls_call TYPE ty_call.
DATA lv_total TYPE i.
IF iv_max_priority < 1 OR iv_max_priority > 5.
RAISE invalid_priority.
ENDIF.
SELECT COUNT(*)
FROM {{P}}ALERT_A
WHERE priority NOT BETWEEN 2 AND 5
INTO @DATA(lv_bad_a).
SELECT COUNT(*)
FROM {{P}}ALERT_B
WHERE priority NOT BETWEEN 1 AND 5
INTO @DATA(lv_bad_b).
IF lv_bad_a > 0 OR lv_bad_b > 0.
RAISE invalid_priority.
ENDIF.
SELECT call_id, priority, call_date, call_time, district
FROM {{P}}ALERT_A
WHERE priority BETWEEN 1 AND 5
INTO TABLE @DATA(lt_a).
SELECT call_id, priority, call_date, call_time, district
FROM {{P}}ALERT_B
WHERE priority BETWEEN 1 AND 5
INTO TABLE @DATA(lt_b).
LOOP AT lt_a INTO DATA(ls_a).
ls_call = CORRESPONDING #( ls_a ).
ls_call-source = 1.
APPEND ls_call TO lt_calls.
ENDLOOP.
LOOP AT lt_b INTO DATA(ls_b).
ls_call = CORRESPONDING #( ls_b ).
ls_call-source = 2.
APPEND ls_call TO lt_calls.
ENDLOOP.
lv_total = lines( lt_calls ).
SORT lt_calls BY call_id call_date call_time source.
DELETE ADJACENT DUPLICATES FROM lt_calls COMPARING call_id.
ev_duplicates = lv_total - lines( lt_calls ).
DELETE lt_calls WHERE priority > iv_max_priority.
SORT lt_calls BY priority call_date call_time call_id.
ev_count = lines( lt_calls ).
IF lt_calls IS NOT INITIAL.
READ TABLE lt_calls INTO ls_call INDEX 1.
ev_first_call_id = ls_call-call_id.
ev_first_district = ls_call-district.
READ TABLE lt_calls INTO ls_call INDEX ev_count.
ev_last_call_id = ls_call-call_id.
ELSE.
CLEAR: ev_first_call_id, ev_first_district, ev_last_call_id.
ENDIF.
ENDFUNCTION.

View File

@@ -0,0 +1,85 @@
FUNCTION {{p}}alert_merge
IMPORTING
iv_max_priority TYPE i
EXPORTING
ev_count TYPE i
ev_duplicates TYPE i
ev_first_call_id TYPE string
ev_first_district TYPE string
ev_last_call_id TYPE string
EXCEPTIONS
invalid_priority.
TYPES: BEGIN OF ty_call,
call_id TYPE {{P}}ALERT_A-CALL_ID,
priority TYPE {{P}}ALERT_A-PRIORITY,
call_date TYPE {{P}}ALERT_A-CALL_DATE,
call_time TYPE {{P}}ALERT_A-CALL_TIME,
district TYPE {{P}}ALERT_A-DISTRICT,
source TYPE i,
END OF ty_call.
DATA lt_calls TYPE STANDARD TABLE OF ty_call WITH DEFAULT KEY.
DATA ls_call TYPE ty_call.
DATA lv_total TYPE i.
IF iv_max_priority < 1 OR iv_max_priority > 5.
RAISE invalid_priority.
ENDIF.
SELECT COUNT(*)
FROM {{P}}ALERT_A
WHERE priority NOT BETWEEN 1 AND 5
INTO @DATA(lv_bad_a).
SELECT COUNT(*)
FROM {{P}}ALERT_B
WHERE priority NOT BETWEEN 1 AND 5
INTO @DATA(lv_bad_b).
IF lv_bad_a > 0 OR lv_bad_b > 0.
RAISE invalid_priority.
ENDIF.
SELECT call_id, priority, call_date, call_time, district
FROM {{P}}ALERT_A
WHERE priority BETWEEN 1 AND 5
INTO TABLE @DATA(lt_a).
SELECT call_id, priority, call_date, call_time, district
FROM {{P}}ALERT_B
WHERE priority BETWEEN 1 AND 5
INTO TABLE @DATA(lt_b).
LOOP AT lt_a INTO DATA(ls_a).
ls_call = CORRESPONDING #( ls_a ).
ls_call-source = 1.
APPEND ls_call TO lt_calls.
ENDLOOP.
LOOP AT lt_b INTO DATA(ls_b).
ls_call = CORRESPONDING #( ls_b ).
ls_call-source = 2.
APPEND ls_call TO lt_calls.
ENDLOOP.
lv_total = lines( lt_calls ).
SORT lt_calls BY call_id call_date call_time source.
DELETE ADJACENT DUPLICATES FROM lt_calls COMPARING call_id.
ev_duplicates = lv_total + lines( lt_calls ).
DELETE lt_calls WHERE priority > iv_max_priority.
SORT lt_calls BY priority call_date call_time call_id.
ev_count = lines( lt_calls ).
IF lt_calls IS NOT INITIAL.
READ TABLE lt_calls INTO ls_call INDEX 1.
ev_first_call_id = ls_call-call_id.
ev_first_district = ls_call-district.
READ TABLE lt_calls INTO ls_call INDEX ev_count.
ev_last_call_id = ls_call-call_id.
ELSE.
CLEAR: ev_first_call_id, ev_first_district, ev_last_call_id.
ENDIF.
ENDFUNCTION.

View File

@@ -0,0 +1,39 @@
{
"id": "G0121",
"pool": "eval",
"object_type": "FUNC",
"category": "C",
"attempts": [
{
"stage": "bundle",
"errors": [
"seed/alert.tabl.abap: a table needs the annotation @AbapCatalog.tableCategory (for example #TRANSPARENT, #A)",
"seed/alert.tabl.abap: a table needs the annotation @AbapCatalog.deliveryClass (for example #TRANSPARENT, #A)"
],
"by_check": {
"static": 2
}
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 90.0,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 4,
"killed": 3,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -1,220 +0,0 @@
CLASS {{p}}t14_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_orders TYPE STANDARD TABLE OF {{p}}roasts.
TYPES ty_totals TYPE STANDARD TABLE OF {{p}}blends.
METHODS run
IMPORTING it_orders TYPE ty_orders
EXPORTING et_totals TYPE ty_totals
ev_grand_total TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS sums_per_blend FOR TESTING.
METHODS sorted_by_total FOR TESTING.
METHODS tie_break_by_blend FOR TESTING.
METHODS ignores_zero FOR TESTING.
METHODS ignores_negative FOR TESTING.
METHODS empty_input FOR TESTING.
METHODS no_production_line FOR TESTING.
METHODS grand_total FOR TESTING.
METHODS single_line FOR TESTING.
METHODS one_blend_many_lines FOR TESTING.
ENDCLASS.
CLASS {{p}}t14_hidden IMPLEMENTATION.
METHOD run.
CLEAR: et_totals, ev_grand_total.
CALL FUNCTION '{{P}}ROAST_SUM'
EXPORTING
it_orders = it_orders
IMPORTING
et_totals = et_totals
ev_grand_total = ev_grand_total
EXCEPTIONS
OTHERS = 1.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD sums_per_blend.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'PILS' quantity_kg = '10.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'PILS' quantity_kg = '5.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000003' blend = 'WEIZ' quantity_kg = '7.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_totals ) ).
DATA ls_tot TYPE {{p}}blends.
READ TABLE lt_totals INTO ls_tot INDEX 1.
cl_abap_unit_assert=>assert_equals( exp = 'PILS' act = ls_tot-blend ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 15 ) act = CONV decfloat34( ls_tot-total_kg ) ).
READ TABLE lt_totals INTO ls_tot INDEX 2.
cl_abap_unit_assert=>assert_equals( exp = 'WEIZ' act = ls_tot-blend ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 7 ) act = CONV decfloat34( ls_tot-total_kg ) ).
ENDMETHOD.
METHOD sorted_by_total.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'ARAB' quantity_kg = '5.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'ROBU' quantity_kg = '30.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000003' blend = 'KONA' quantity_kg = '12.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lines( lt_totals ) ).
DATA ls_tot TYPE {{p}}blends.
READ TABLE lt_totals INTO ls_tot INDEX 1.
cl_abap_unit_assert=>assert_equals( exp = 'ROBU' act = ls_tot-blend ).
READ TABLE lt_totals INTO ls_tot INDEX 2.
cl_abap_unit_assert=>assert_equals( exp = 'KONA' act = ls_tot-blend ).
READ TABLE lt_totals INTO ls_tot INDEX 3.
cl_abap_unit_assert=>assert_equals( exp = 'ARAB' act = ls_tot-blend ).
ENDMETHOD.
METHOD tie_break_by_blend.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'ROBU' quantity_kg = '6.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'ARAB' quantity_kg = '6.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_totals ) ).
DATA ls_tot TYPE {{p}}blends.
READ TABLE lt_totals INTO ls_tot INDEX 1.
cl_abap_unit_assert=>assert_equals( exp = 'ARAB' act = ls_tot-blend ).
READ TABLE lt_totals INTO ls_tot INDEX 2.
cl_abap_unit_assert=>assert_equals( exp = 'ROBU' act = ls_tot-blend ).
ENDMETHOD.
METHOD ignores_zero.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'PILS' quantity_kg = '0.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'WEIZ' quantity_kg = '4.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_totals ) ).
DATA ls_tot TYPE {{p}}blends.
READ TABLE lt_totals INTO ls_tot INDEX 1.
cl_abap_unit_assert=>assert_equals( exp = 'WEIZ' act = ls_tot-blend ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 4 ) act = CONV decfloat34( ls_tot-total_kg ) ).
ENDMETHOD.
METHOD ignores_negative.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'PILS' quantity_kg = '-3.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'WEIZ' quantity_kg = '4.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_totals ) ).
DATA ls_tot TYPE {{p}}blends.
READ TABLE lt_totals INTO ls_tot INDEX 1.
cl_abap_unit_assert=>assert_equals( exp = 'WEIZ' act = ls_tot-blend ).
ENDMETHOD.
METHOD empty_input.
DATA lt_orders TYPE ty_orders.
DATA lt_totals TYPE ty_totals.
DATA lv_grand TYPE decfloat34 VALUE 99.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_grand_total = lv_grand ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_totals ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_grand ).
ENDMETHOD.
METHOD no_production_line.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'PILS' quantity_kg = '0.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'WEIZ' quantity_kg = '-8.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
DATA lv_grand TYPE decfloat34.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_grand_total = lv_grand ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_totals ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_grand ).
ENDMETHOD.
METHOD grand_total.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'PILS' quantity_kg = '10.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'WEIZ' quantity_kg = '2.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000003' blend = 'KOLS' quantity_kg = '8.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000004' blend = 'PILS' quantity_kg = '5.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
DATA lv_grand TYPE decfloat34.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_grand_total = lv_grand ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 25 ) act = lv_grand ).
ENDMETHOD.
METHOD single_line.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'KONA' quantity_kg = '3.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_totals ) ).
DATA ls_tot TYPE {{p}}blends.
READ TABLE lt_totals INTO ls_tot INDEX 1.
cl_abap_unit_assert=>assert_equals( exp = 'KONA' act = ls_tot-blend ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 3 ) act = CONV decfloat34( ls_tot-total_kg ) ).
ENDMETHOD.
METHOD one_blend_many_lines.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'PILS' quantity_kg = '1.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'PILS' quantity_kg = '2.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000003' blend = 'PILS' quantity_kg = '3.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000004' blend = 'PILS' quantity_kg = '4.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_totals ) ).
DATA ls_tot TYPE {{p}}blends.
READ TABLE lt_totals INTO ls_tot INDEX 1.
cl_abap_unit_assert=>assert_equals( exp = 'PILS' act = ls_tot-blend ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 10 ) act = CONV decfloat34( ls_tot-total_kg ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,208 @@
CLASS {{p}}t41_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS setup.
METHODS call
IMPORTING
iv_max_priority TYPE i
EXPORTING
ev_count TYPE i
ev_duplicates TYPE i
ev_first_call_id TYPE string
ev_first_district TYPE string
ev_last_call_id TYPE string
ev_subrc TYPE sysubrc.
METHODS add_a
IMPORTING
iv_id TYPE {{P}}ALERT_A-CALL_ID
iv_prio TYPE {{P}}ALERT_A-PRIORITY
iv_date TYPE {{P}}ALERT_A-CALL_DATE
iv_time TYPE {{P}}ALERT_A-CALL_TIME
iv_district TYPE {{P}}ALERT_A-DISTRICT.
METHODS add_b
IMPORTING
iv_id TYPE {{P}}ALERT_B-CALL_ID
iv_prio TYPE {{P}}ALERT_B-PRIORITY
iv_date TYPE {{P}}ALERT_B-CALL_DATE
iv_time TYPE {{P}}ALERT_B-CALL_TIME
iv_district TYPE {{P}}ALERT_B-DISTRICT.
METHODS merges_both_tables FOR TESTING.
METHODS keeps_earliest_call FOR TESTING.
METHODS keeps_a_on_tie FOR TESTING.
METHODS sorts_by_priority FOR TESTING.
METHODS sorts_by_time FOR TESTING.
METHODS sorts_by_call_id FOR TESTING.
METHODS filters_by_priority FOR TESTING.
METHODS counts_duplicates FOR TESTING.
METHODS empty_tables FOR TESTING.
METHODS rejects_bad_max FOR TESTING.
METHODS rejects_bad_priority FOR TESTING.
ENDCLASS.
CLASS {{p}}t41_hidden IMPLEMENTATION.
METHOD setup.
DELETE FROM {{P}}ALERT_A.
DELETE FROM {{P}}ALERT_B.
ENDMETHOD.
METHOD call.
CALL FUNCTION '{{P}}ALERT_MERGE'
EXPORTING
iv_max_priority = iv_max_priority
IMPORTING
ev_count = ev_count
ev_duplicates = ev_duplicates
ev_first_call_id = ev_first_call_id
ev_first_district = ev_first_district
ev_last_call_id = ev_last_call_id
EXCEPTIONS
invalid_priority = 1
OTHERS = 2.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD add_a.
DATA ls_call TYPE {{P}}ALERT_A.
ls_call-call_id = iv_id.
ls_call-priority = iv_prio.
ls_call-call_date = iv_date.
ls_call-call_time = iv_time.
ls_call-district = iv_district.
MODIFY {{P}}ALERT_A FROM @ls_call.
ENDMETHOD.
METHOD add_b.
DATA ls_call TYPE {{P}}ALERT_B.
ls_call-call_id = iv_id.
ls_call-priority = iv_prio.
ls_call-call_date = iv_date.
ls_call-call_time = iv_time.
ls_call-district = iv_district.
MODIFY {{P}}ALERT_B FROM @ls_call.
ENDMETHOD.
METHOD merges_both_tables.
add_a( iv_id = 'C1' iv_prio = 2 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
add_b( iv_id = 'C2' iv_prio = 1 iv_date = '20240101' iv_time = '090000' iv_district = 'SUED' ).
call( EXPORTING iv_max_priority = 5
IMPORTING ev_count = DATA(lv_count)
ev_first_call_id = DATA(lv_first)
ev_last_call_id = DATA(lv_last) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 'C2' act = lv_first ).
cl_abap_unit_assert=>assert_equals( exp = 'C1' act = lv_last ).
ENDMETHOD.
METHOD keeps_earliest_call.
add_a( iv_id = 'C1' iv_prio = 2 iv_date = '20240101' iv_time = '100000' iv_district = 'NORD' ).
add_b( iv_id = 'C1' iv_prio = 2 iv_date = '20240101' iv_time = '090000' iv_district = 'SUED' ).
call( EXPORTING iv_max_priority = 5
IMPORTING ev_count = DATA(lv_count)
ev_duplicates = DATA(lv_dup)
ev_first_district = DATA(lv_district) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_dup ).
cl_abap_unit_assert=>assert_equals( exp = 'SUED' act = lv_district ).
ENDMETHOD.
METHOD keeps_a_on_tie.
add_a( iv_id = 'C1' iv_prio = 2 iv_date = '20240101' iv_time = '090000' iv_district = 'NORD' ).
add_b( iv_id = 'C1' iv_prio = 3 iv_date = '20240101' iv_time = '090000' iv_district = 'SUED' ).
call( EXPORTING iv_max_priority = 5
IMPORTING ev_count = DATA(lv_count)
ev_first_call_id = DATA(lv_first)
ev_first_district = DATA(lv_district) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 'C1' act = lv_first ).
cl_abap_unit_assert=>assert_equals( exp = 'NORD' act = lv_district ).
ENDMETHOD.
METHOD sorts_by_priority.
add_a( iv_id = 'C3' iv_prio = 3 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
add_a( iv_id = 'C1' iv_prio = 1 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
add_a( iv_id = 'C2' iv_prio = 2 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
call( EXPORTING iv_max_priority = 5
IMPORTING ev_count = DATA(lv_count)
ev_first_call_id = DATA(lv_first)
ev_last_call_id = DATA(lv_last) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 'C1' act = lv_first ).
cl_abap_unit_assert=>assert_equals( exp = 'C3' act = lv_last ).
ENDMETHOD.
METHOD sorts_by_time.
add_a( iv_id = 'C1' iv_prio = 1 iv_date = '20240102' iv_time = '080000' iv_district = 'NORD' ).
add_a( iv_id = 'C2' iv_prio = 1 iv_date = '20240101' iv_time = '120000' iv_district = 'NORD' ).
add_a( iv_id = 'C3' iv_prio = 1 iv_date = '20240101' iv_time = '060000' iv_district = 'NORD' ).
call( EXPORTING iv_max_priority = 5
IMPORTING ev_first_call_id = DATA(lv_first)
ev_last_call_id = DATA(lv_last) ).
cl_abap_unit_assert=>assert_equals( exp = 'C3' act = lv_first ).
cl_abap_unit_assert=>assert_equals( exp = 'C1' act = lv_last ).
ENDMETHOD.
METHOD sorts_by_call_id.
add_a( iv_id = 'C9' iv_prio = 1 iv_date = '20240101' iv_time = '060000' iv_district = 'NORD' ).
add_a( iv_id = 'C0' iv_prio = 1 iv_date = '20240101' iv_time = '060000' iv_district = 'NORD' ).
call( EXPORTING iv_max_priority = 5
IMPORTING ev_first_call_id = DATA(lv_first)
ev_last_call_id = DATA(lv_last) ).
cl_abap_unit_assert=>assert_equals( exp = 'C0' act = lv_first ).
cl_abap_unit_assert=>assert_equals( exp = 'C9' act = lv_last ).
ENDMETHOD.
METHOD filters_by_priority.
add_a( iv_id = 'C1' iv_prio = 1 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
add_a( iv_id = 'C2' iv_prio = 2 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
add_a( iv_id = 'C3' iv_prio = 3 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
call( EXPORTING iv_max_priority = 2
IMPORTING ev_count = DATA(lv_count)
ev_duplicates = DATA(lv_dup)
ev_last_call_id = DATA(lv_last) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_dup ).
cl_abap_unit_assert=>assert_equals( exp = 'C2' act = lv_last ).
ENDMETHOD.
METHOD counts_duplicates.
add_a( iv_id = 'C1' iv_prio = 1 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
add_a( iv_id = 'C2' iv_prio = 2 iv_date = '20240102' iv_time = '080000' iv_district = 'NORD' ).
add_b( iv_id = 'C2' iv_prio = 2 iv_date = '20240101' iv_time = '080000' iv_district = 'SUED' ).
add_b( iv_id = 'C3' iv_prio = 3 iv_date = '20240103' iv_time = '080000' iv_district = 'NORD' ).
call( EXPORTING iv_max_priority = 5
IMPORTING ev_count = DATA(lv_count)
ev_duplicates = DATA(lv_dup)
ev_first_call_id = DATA(lv_first)
ev_last_call_id = DATA(lv_last) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_dup ).
cl_abap_unit_assert=>assert_equals( exp = 'C1' act = lv_first ).
cl_abap_unit_assert=>assert_equals( exp = 'C3' act = lv_last ).
ENDMETHOD.
METHOD empty_tables.
call( EXPORTING iv_max_priority = 5
IMPORTING ev_count = DATA(lv_count)
ev_duplicates = DATA(lv_dup)
ev_first_call_id = DATA(lv_first)
ev_last_call_id = DATA(lv_last) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_dup ).
cl_abap_unit_assert=>assert_initial( act = lv_first ).
cl_abap_unit_assert=>assert_initial( act = lv_last ).
ENDMETHOD.
METHOD rejects_bad_max.
call( EXPORTING iv_max_priority = 0 IMPORTING ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc ).
call( EXPORTING iv_max_priority = 6 IMPORTING ev_subrc = DATA(lv_rc6) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc6 ).
ENDMETHOD.
METHOD rejects_bad_priority.
add_a( iv_id = 'C1' iv_prio = 9 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
call( EXPORTING iv_max_priority = 5 IMPORTING ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,64 @@
{
"task": "G0121",
"mutants": [
{
"object": "{{P}}ALERT_MERGE",
"mutant": "line 26: < -> >= (rel)",
"status": "killed",
"hidden": "2/11",
"failed_tests": [
"COUNTS_DUPLICATES",
"FILTERS_BY_PRIORITY",
"KEEPS_A_ON_TIE",
"KEEPS_EARLIEST_CALL",
"MERGES_BOTH_TABLES",
"REJECTS_BAD_MAX",
"SORTS_BY_CALL_ID",
"SORTS_BY_PRIORITY",
"SORTS_BY_TIME"
]
},
{
"object": "{{P}}ALERT_MERGE",
"mutant": "line 32: 1 -> 2 (const)",
"status": "killed",
"hidden": "6/11",
"failed_tests": [
"COUNTS_DUPLICATES",
"FILTERS_BY_PRIORITY",
"SORTS_BY_CALL_ID",
"SORTS_BY_PRIORITY",
"SORTS_BY_TIME"
]
},
{
"object": "{{P}}ALERT_MERGE",
"mutant": "line 32: 5 -> 6 (const)",
"status": "survived",
"hidden": "11/11",
"failed_tests": []
},
{
"object": "{{P}}ALERT_MERGE",
"mutant": "line 51: AND -> OR (logic)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
},
{
"object": "{{P}}ALERT_MERGE",
"mutant": "line 69: - -> + (arith)",
"status": "killed",
"hidden": "8/11",
"failed_tests": [
"COUNTS_DUPLICATES",
"FILTERS_BY_PRIORITY",
"KEEPS_EARLIEST_CALL"
]
}
],
"valid": 4,
"killed": 3,
"kill_rate": 0.75,
"ok": true
}

View File

@@ -0,0 +1,85 @@
FUNCTION {{p}}alert_merge
IMPORTING
iv_max_priority TYPE i
EXPORTING
ev_count TYPE i
ev_duplicates TYPE i
ev_first_call_id TYPE string
ev_first_district TYPE string
ev_last_call_id TYPE string
EXCEPTIONS
invalid_priority.
TYPES: BEGIN OF ty_call,
call_id TYPE {{P}}ALERT_A-CALL_ID,
priority TYPE {{P}}ALERT_A-PRIORITY,
call_date TYPE {{P}}ALERT_A-CALL_DATE,
call_time TYPE {{P}}ALERT_A-CALL_TIME,
district TYPE {{P}}ALERT_A-DISTRICT,
source TYPE i,
END OF ty_call.
DATA lt_calls TYPE STANDARD TABLE OF ty_call WITH DEFAULT KEY.
DATA ls_call TYPE ty_call.
DATA lv_total TYPE i.
IF iv_max_priority < 1 OR iv_max_priority > 5.
RAISE invalid_priority.
ENDIF.
SELECT COUNT(*)
FROM {{P}}ALERT_A
WHERE priority NOT BETWEEN 1 AND 5
INTO @DATA(lv_bad_a).
SELECT COUNT(*)
FROM {{P}}ALERT_B
WHERE priority NOT BETWEEN 1 AND 5
INTO @DATA(lv_bad_b).
IF lv_bad_a > 0 OR lv_bad_b > 0.
RAISE invalid_priority.
ENDIF.
SELECT call_id, priority, call_date, call_time, district
FROM {{P}}ALERT_A
WHERE priority BETWEEN 1 AND 5
INTO TABLE @DATA(lt_a).
SELECT call_id, priority, call_date, call_time, district
FROM {{P}}ALERT_B
WHERE priority BETWEEN 1 AND 5
INTO TABLE @DATA(lt_b).
LOOP AT lt_a INTO DATA(ls_a).
ls_call = CORRESPONDING #( ls_a ).
ls_call-source = 1.
APPEND ls_call TO lt_calls.
ENDLOOP.
LOOP AT lt_b INTO DATA(ls_b).
ls_call = CORRESPONDING #( ls_b ).
ls_call-source = 2.
APPEND ls_call TO lt_calls.
ENDLOOP.
lv_total = lines( lt_calls ).
SORT lt_calls BY call_id call_date call_time source.
DELETE ADJACENT DUPLICATES FROM lt_calls COMPARING call_id.
ev_duplicates = lv_total - lines( lt_calls ).
DELETE lt_calls WHERE priority > iv_max_priority.
SORT lt_calls BY priority call_date call_time call_id.
ev_count = lines( lt_calls ).
IF lt_calls IS NOT INITIAL.
READ TABLE lt_calls INTO ls_call INDEX 1.
ev_first_call_id = ls_call-call_id.
ev_first_district = ls_call-district.
READ TABLE lt_calls INTO ls_call INDEX ev_count.
ev_last_call_id = ls_call-call_id.
ELSE.
CLEAR: ev_first_call_id, ev_first_district, ev_last_call_id.
ENDIF.
ENDFUNCTION.

View File

@@ -1,45 +0,0 @@
FUNCTION {{p}}roast_sum
IMPORTING
it_orders TYPE STANDARD TABLE OF {{p}}roasts
EXPORTING
et_totals TYPE STANDARD TABLE OF {{p}}blends
ev_grand_total TYPE decfloat34.
TYPES: BEGIN OF ty_sum,
blend TYPE {{p}}blends-blend,
total_kg TYPE {{p}}blends-total_kg,
END OF ty_sum.
DATA lt_sum TYPE HASHED TABLE OF ty_sum WITH UNIQUE KEY blend.
DATA ls_ord TYPE {{p}}roasts.
DATA ls_sum TYPE ty_sum.
DATA ls_tot TYPE {{p}}blends.
CLEAR: et_totals, ev_grand_total.
LOOP AT it_orders INTO ls_ord.
IF ls_ord-quantity_kg <= 0.
CONTINUE.
ENDIF.
READ TABLE lt_sum INTO ls_sum WITH TABLE KEY blend = ls_ord-blend.
IF sy-subrc = 0.
ls_sum-total_kg = ls_sum-total_kg + ls_ord-quantity_kg.
MODIFY TABLE lt_sum FROM ls_sum.
ELSE.
ls_sum-blend = ls_ord-blend.
ls_sum-total_kg = ls_ord-quantity_kg.
INSERT ls_sum INTO TABLE lt_sum.
ENDIF.
ENDLOOP.
LOOP AT lt_sum INTO ls_sum.
ls_tot-blend = ls_sum-blend.
ls_tot-total_kg = ls_sum-total_kg.
ev_grand_total = ev_grand_total + ls_sum-total_kg.
APPEND ls_tot TO et_totals.
ENDLOOP.
SORT et_totals BY total_kg DESCENDING blend ASCENDING.
ENDFUNCTION.

View File

@@ -1,109 +0,0 @@
CLASS {{p}}t14_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_orders TYPE STANDARD TABLE OF {{p}}roasts.
TYPES ty_totals TYPE STANDARD TABLE OF {{p}}blends.
METHODS run
IMPORTING it_orders TYPE ty_orders
EXPORTING et_totals TYPE ty_totals
ev_grand_total TYPE decfloat34
ev_subrc TYPE sysubrc.
METHODS sums_per_blend FOR TESTING.
METHODS ignores_non_positive FOR TESTING.
METHODS sorted_by_total FOR TESTING.
METHODS tie_break FOR TESTING.
METHODS empty_input FOR TESTING.
ENDCLASS.
CLASS {{p}}t14_test IMPLEMENTATION.
METHOD run.
CLEAR: et_totals, ev_grand_total.
CALL FUNCTION '{{P}}ROAST_SUM'
EXPORTING
it_orders = it_orders
IMPORTING
et_totals = et_totals
ev_grand_total = ev_grand_total
EXCEPTIONS
OTHERS = 1.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD sums_per_blend.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'PILS' quantity_kg = '10.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'PILS' quantity_kg = '5.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_totals ) ).
DATA ls_tot TYPE {{p}}blends.
READ TABLE lt_totals INTO ls_tot INDEX 1.
cl_abap_unit_assert=>assert_equals( exp = 'PILS' act = ls_tot-blend ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 15 ) act = CONV decfloat34( ls_tot-total_kg ) ).
ENDMETHOD.
METHOD ignores_non_positive.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'PILS' quantity_kg = '0.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'WEIZ' quantity_kg = '-4.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_totals ) ).
ENDMETHOD.
METHOD sorted_by_total.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'ARAB' quantity_kg = '5.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'ROBU' quantity_kg = '30.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
DATA ls_tot TYPE {{p}}blends.
READ TABLE lt_totals INTO ls_tot INDEX 1.
cl_abap_unit_assert=>assert_equals( exp = 'ROBU' act = ls_tot-blend ).
ENDMETHOD.
METHOD tie_break.
DATA lt_orders TYPE ty_orders.
APPEND VALUE #( order_id = '0000000001' blend = 'ROBU' quantity_kg = '6.000' ) TO lt_orders.
APPEND VALUE #( order_id = '0000000002' blend = 'ARAB' quantity_kg = '6.000' ) TO lt_orders.
DATA lt_totals TYPE ty_totals.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
DATA ls_tot TYPE {{p}}blends.
READ TABLE lt_totals INTO ls_tot INDEX 1.
cl_abap_unit_assert=>assert_equals( exp = 'ARAB' act = ls_tot-blend ).
ENDMETHOD.
METHOD empty_input.
DATA lt_orders TYPE ty_orders.
DATA lt_totals TYPE ty_totals.
DATA lv_grand TYPE decfloat34 VALUE 99.
run( EXPORTING it_orders = lt_orders
IMPORTING et_totals = lt_totals ev_grand_total = lv_grand ev_subrc = DATA(lv_subrc) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_subrc ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_totals ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( 0 ) act = lv_grand ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,134 @@
CLASS {{p}}t41_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
METHODS setup.
METHODS call
IMPORTING
iv_max_priority TYPE i
EXPORTING
ev_count TYPE i
ev_duplicates TYPE i
ev_first_call_id TYPE string
ev_last_call_id TYPE string
ev_subrc TYPE sysubrc.
METHODS add_a
IMPORTING
iv_id TYPE {{P}}ALERT_A-CALL_ID
iv_prio TYPE {{P}}ALERT_A-PRIORITY
iv_date TYPE {{P}}ALERT_A-CALL_DATE
iv_time TYPE {{P}}ALERT_A-CALL_TIME
iv_district TYPE {{P}}ALERT_A-DISTRICT.
METHODS add_b
IMPORTING
iv_id TYPE {{P}}ALERT_B-CALL_ID
iv_prio TYPE {{P}}ALERT_B-PRIORITY
iv_date TYPE {{P}}ALERT_B-CALL_DATE
iv_time TYPE {{P}}ALERT_B-CALL_TIME
iv_district TYPE {{P}}ALERT_B-DISTRICT.
METHODS merges_and_sorts FOR TESTING.
METHODS keeps_earliest FOR TESTING.
METHODS counts_duplicates FOR TESTING.
METHODS filters_by_priority FOR TESTING.
METHODS empty_tables FOR TESTING.
METHODS rejects_bad_priority FOR TESTING.
ENDCLASS.
CLASS {{p}}t41_test IMPLEMENTATION.
METHOD setup.
DELETE FROM {{P}}ALERT_A.
DELETE FROM {{P}}ALERT_B.
ENDMETHOD.
METHOD call.
CALL FUNCTION '{{P}}ALERT_MERGE'
EXPORTING
iv_max_priority = iv_max_priority
IMPORTING
ev_count = ev_count
ev_duplicates = ev_duplicates
ev_first_call_id = ev_first_call_id
ev_last_call_id = ev_last_call_id
EXCEPTIONS
invalid_priority = 1
OTHERS = 2.
ev_subrc = sy-subrc.
ENDMETHOD.
METHOD add_a.
DATA ls_call TYPE {{P}}ALERT_A.
ls_call-call_id = iv_id.
ls_call-priority = iv_prio.
ls_call-call_date = iv_date.
ls_call-call_time = iv_time.
ls_call-district = iv_district.
MODIFY {{P}}ALERT_A FROM @ls_call.
ENDMETHOD.
METHOD add_b.
DATA ls_call TYPE {{P}}ALERT_B.
ls_call-call_id = iv_id.
ls_call-priority = iv_prio.
ls_call-call_date = iv_date.
ls_call-call_time = iv_time.
ls_call-district = iv_district.
MODIFY {{P}}ALERT_B FROM @ls_call.
ENDMETHOD.
METHOD merges_and_sorts.
add_a( iv_id = 'C1' iv_prio = 3 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
add_b( iv_id = 'C2' iv_prio = 1 iv_date = '20240102' iv_time = '080000' iv_district = 'SUED' ).
call( EXPORTING iv_max_priority = 5
IMPORTING ev_count = DATA(lv_count)
ev_first_call_id = DATA(lv_first) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 'C2' act = lv_first ).
ENDMETHOD.
METHOD keeps_earliest.
add_a( iv_id = 'C1' iv_prio = 1 iv_date = '20240101' iv_time = '100000' iv_district = 'NORD' ).
add_b( iv_id = 'C1' iv_prio = 1 iv_date = '20240101' iv_time = '090000' iv_district = 'SUED' ).
call( EXPORTING iv_max_priority = 5
IMPORTING ev_count = DATA(lv_count)
ev_first_call_id = DATA(lv_first) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 'C1' act = lv_first ).
ENDMETHOD.
METHOD counts_duplicates.
add_a( iv_id = 'C1' iv_prio = 1 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
add_b( iv_id = 'C1' iv_prio = 1 iv_date = '20240101' iv_time = '080000' iv_district = 'SUED' ).
add_b( iv_id = 'C2' iv_prio = 2 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
call( EXPORTING iv_max_priority = 5
IMPORTING ev_count = DATA(lv_count)
ev_duplicates = DATA(lv_dup) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_dup ).
ENDMETHOD.
METHOD filters_by_priority.
add_a( iv_id = 'C1' iv_prio = 1 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
add_a( iv_id = 'C2' iv_prio = 4 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
call( EXPORTING iv_max_priority = 2
IMPORTING ev_count = DATA(lv_count)
ev_last_call_id = DATA(lv_last) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 'C1' act = lv_last ).
ENDMETHOD.
METHOD empty_tables.
call( EXPORTING iv_max_priority = 5
IMPORTING ev_count = DATA(lv_count)
ev_duplicates = DATA(lv_dup)
ev_first_call_id = DATA(lv_first) ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_count ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lv_dup ).
cl_abap_unit_assert=>assert_initial( act = lv_first ).
ENDMETHOD.
METHOD rejects_bad_priority.
add_a( iv_id = 'C1' iv_prio = 7 iv_date = '20240101' iv_time = '080000' iv_district = 'NORD' ).
call( EXPORTING iv_max_priority = 5 IMPORTING ev_subrc = DATA(lv_rc) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_rc ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,11 @@
@EndUserText.label: 'Emergency calls of centre A'
@AbapCatalog.enhancement.category: #NOT_EXTENSIBLE
@AbapCatalog.tableCategory: #TRANSPARENT
@AbapCatalog.deliveryClass: #A
define table {{p}}alert_a {
key call_id : abap.char(10) not null;
priority : abap.int1 not null;
call_date : abap.dats not null;
call_time : abap.tims not null;
district : abap.char(4) not null;
}

View File

@@ -0,0 +1,11 @@
@EndUserText.label: 'Emergency calls of centre B'
@AbapCatalog.enhancement.category: #NOT_EXTENSIBLE
@AbapCatalog.tableCategory: #TRANSPARENT
@AbapCatalog.deliveryClass: #A
define table {{p}}alert_b {
key call_id : abap.char(10) not null;
priority : abap.int1 not null;
call_date : abap.dats not null;
call_time : abap.tims not null;
district : abap.char(4) not null;
}

View File

@@ -1,7 +0,0 @@
@EndUserText.label : 'Roast total per blend'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define table {{p}}blends {
key client : abap.clnt not null;
key blend : abap.char(4) not null;
total_kg : abap.dec(15,3);
}

View File

@@ -1,28 +0,0 @@
CLASS {{p}}roast_seed DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS {{p}}roast_seed IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA lt_lines TYPE STANDARD TABLE OF {{p}}roasts.
lt_lines = VALUE #(
( client = sy-mandt order_id = '0000000001' blend = 'PILS' quantity_kg = '120.500' )
( client = sy-mandt order_id = '0000000002' blend = 'WEIZ' quantity_kg = '80.000' )
( client = sy-mandt order_id = '0000000003' blend = 'PILS' quantity_kg = '60.250' )
( client = sy-mandt order_id = '0000000004' blend = 'KOLS' quantity_kg = '45.000' )
( client = sy-mandt order_id = '0000000005' blend = 'PILS' quantity_kg = '0.000' )
( client = sy-mandt order_id = '0000000006' blend = 'WEIZ' quantity_kg = '20.000' )
).
DELETE FROM {{p}}roasts.
INSERT {{p}}roasts FROM TABLE @lt_lines.
out->write( |{ sy-dbcnt } roast lines inserted| ).
ENDMETHOD.
ENDCLASS.

View File

@@ -1,8 +0,0 @@
@EndUserText.label : 'Roast order line'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define table {{p}}roasts {
key client : abap.clnt not null;
key order_id : abap.numc(10) not null;
blend : abap.char(4);
quantity_kg : abap.dec(15,3);
}

View File

@@ -1,52 +1,71 @@
# 1. Goal
A coffee roastery plans its daily production. A planning program calls one
function module for each production day. The function module groups the roast
order lines of the day by coffee blend and returns the total green coffee
quantity of each blend. The planning program shows the blend with the largest
quantity first.
A regional emergency control centre collects the open emergency calls of two
control centres. The dispatch program calls one function module for each
dispatch run. The function module must merge the calls of both control centres
and must return the figures of the dispatch list.
# 2. Open questions
None.
# 3. Context
- Function group {{P}}FG_ROAST exists in package $TMP.
- Table {{P}}ROASTS exists in package $TMP. It stores the roast order lines of
a production day.
- Table {{P}}BLENDS exists in package $TMP. It is the line type of the result
- Function group {{P}}FG_ALERT exists in package $TMP.
- The database table {{P}}ALERT_A exists in package $TMP. It contains the open
emergency calls of control centre A.
- The database table {{P}}ALERT_B exists in package $TMP. It contains the open
emergency calls of control centre B.
- Both tables have the same fields:
- CALL_ID: the call number, 10 characters.
- PRIORITY: the urgency. 1 is the highest urgency, 5 is the lowest urgency.
- CALL_DATE: the date on which the call was reported.
- CALL_TIME: the time at which the call was reported.
- DISTRICT: the district of the caller, 4 characters.
- CALL_ID is the key of each table. A call ID occurs at most one time in each
table.
- The class {{P}}ROAST_SEED fills {{P}}ROASTS with sample data. Run it to get
test data.
# 4. Contract
- Create the function module {{P}}ROAST_SUM in function group {{P}}FG_ROAST.
- Interface of {{P}}ROAST_SUM:
- IMPORTING it_orders TYPE STANDARD TABLE OF {{P}}ROASTS
- EXPORTING et_totals TYPE STANDARD TABLE OF {{P}}BLENDS
- EXPORTING ev_grand_total TYPE decfloat34
- The function module has no exceptions.
- Create the function module {{P}}ALERT_MERGE in function group {{P}}FG_ALERT.
- The function module has this interface:
- Importing parameter IV_MAX_PRIORITY, type i.
- Exporting parameter EV_COUNT, type i.
- Exporting parameter EV_DUPLICATES, type i.
- Exporting parameter EV_FIRST_CALL_ID, type string.
- Exporting parameter EV_FIRST_DISTRICT, type string.
- Exporting parameter EV_LAST_CALL_ID, type string.
- Exception INVALID_PRIORITY.
# 5. Business rules
1. A line of it_orders is a production line if its quantity is greater than 0.
A line with a quantity of 0 or less is not a production line.
2. et_totals has exactly one line for each blend that has at least one
production line in it_orders.
3. The total quantity of a blend is the sum of the quantities of all its
production lines.
4. Sort et_totals by total quantity. The largest total quantity comes first.
5. If two blends have the same total quantity, the blend that is smaller in the
character order comes first.
6. ev_grand_total is the sum of the total quantities of all lines of et_totals.
7. If it_orders is empty, or if it_orders has no production line, et_totals is
empty and ev_grand_total is 0.
1. The function module reads the open calls of both control centres from the
tables {{P}}ALERT_A and {{P}}ALERT_B.
2. The dispatch list contains each call ID at most one time.
3. If one call ID is in both tables, the dispatch list contains the call with
the earlier report time. The report time is CALL_DATE first and CALL_TIME
second.
4. If both calls with the same call ID have the same report time, the dispatch
list contains the call from {{P}}ALERT_A.
5. The dispatch list contains only calls with a PRIORITY that is at most
IV_MAX_PRIORITY.
6. The dispatch list is sorted by PRIORITY in ascending order. Lines with the
same PRIORITY are sorted by CALL_DATE in ascending order, then by CALL_TIME
in ascending order, then by CALL_ID in ascending order.
7. EV_COUNT is the number of lines in the dispatch list.
8. EV_DUPLICATES is the number of call IDs that are in both tables. Rule 5
does not change EV_DUPLICATES.
9. EV_FIRST_CALL_ID and EV_FIRST_DISTRICT are the call ID and the district of
the first line of the dispatch list. EV_LAST_CALL_ID is the call ID of the
last line of the dispatch list. If the dispatch list is empty, these three
parameters are empty strings.
10. If IV_MAX_PRIORITY is smaller than 1 or larger than 5, raise the exception
INVALID_PRIORITY.
11. If a call in {{P}}ALERT_A or in {{P}}ALERT_B has a PRIORITY that is smaller
than 1 or larger than 5, raise the exception INVALID_PRIORITY.
# 6. Constraints
- Release target: 7.58.
- Package: $TMP. Do not use transports.
- Coding standard: Clean ABAP. Keep the function module short. Choose the
internal table kind and the access path that fit the task.
- Out of scope: do not change {{P}}ROASTS, {{P}}BLENDS, {{P}}ROAST_SEED.
- Apply the coding standards of Clean ABAP.
- Out of scope: do not change the tables {{P}}ALERT_A and {{P}}ALERT_B and the
function group {{P}}FG_ALERT.
# 7. Acceptance
- The function module {{P}}ROAST_SUM is active and has no syntax error.
- The function module is active and has no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests for the function module in a global test class.

View File

@@ -10,83 +10,85 @@
"max_activations": 15
},
"seed": [
{
"type": "TABL",
"name": "{{P}}ALERT_A",
"file": "seed/alert_a.tabl.abap",
"description": "Emergency calls of control centre A"
},
{
"type": "TABL",
"name": "{{P}}ALERT_B",
"file": "seed/alert_b.tabl.abap",
"description": "Emergency calls of control centre B"
},
{
"type": "FUGR",
"name": "{{P}}FG_ROAST",
"description": "Roast production"
},
{
"type": "TABL",
"name": "{{P}}ROASTS",
"file": "seed/roasts.tabl.abap",
"description": "Roast order lines of a production day"
},
{
"type": "TABL",
"name": "{{P}}BLENDS",
"file": "seed/blends.tabl.abap",
"description": "Line type of the result table"
},
{
"type": "CLAS",
"name": "{{P}}ROAST_SEED",
"file": "seed/roast_seed.clas.abap",
"description": "Sample data for {{P}}ROASTS",
"run": true
"name": "{{P}}FG_ALERT",
"description": "Emergency alert processing"
}
],
"contract": [
{
"type": "FUNC",
"name": "{{P}}ROAST_SUM",
"functionGroup": "{{P}}FG_ROAST",
"name": "{{P}}ALERT_MERGE",
"functionGroup": "{{P}}FG_ALERT",
"params": [
{
"name": "it_orders",
"type": "STANDARD TABLE OF {{P}}ROASTS"
"name": "iv_max_priority",
"type": "i"
},
{
"name": "et_totals",
"type": "STANDARD TABLE OF {{P}}BLENDS"
"name": "ev_count",
"type": "i"
},
{
"name": "ev_grand_total",
"type": "decfloat34"
"name": "ev_duplicates",
"type": "i"
},
{
"name": "ev_first_call_id",
"type": "string"
},
{
"name": "ev_first_district",
"type": "string"
},
{
"name": "ev_last_call_id",
"type": "string"
}
]
}
],
"out_of_scope": [
"{{P}}ROASTS",
"{{P}}BLENDS",
"{{P}}ROAST_SEED"
"{{P}}ALERT_A",
"{{P}}ALERT_B"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T14_HIDDEN",
"file": "hidden/t14_hidden.clas.abap",
"description": "T14 hidden tests"
"name": "{{P}}T41_HIDDEN",
"file": "hidden/t41_hidden.clas.abap",
"description": "T41 hidden tests"
}
],
"reference": [
{
"type": "FUNC",
"name": "{{P}}ROAST_SUM",
"functionGroup": "{{P}}FG_ROAST",
"file": "reference/roast_sum.func.abap",
"description": "Roast sum module"
"name": "{{P}}ALERT_MERGE",
"functionGroup": "{{P}}FG_ALERT",
"file": "reference/alert_merge.func.abap",
"description": "Alert merge module"
},
{
"type": "CLAS",
"name": "{{P}}T14_TEST",
"file": "reference/t14_test.clas.abap",
"description": "T14 own tests"
"name": "{{P}}T41_TEST",
"file": "reference/t41_test.clas.abap",
"description": "T41 own tests"
}
],
"craft_checks": [
"method_length",
"table_kind",
"access_path"
"method_length"
]
}