Fix coverage with several contract classes; table annotation and file path checks; clean task dir on write

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 08:44:35 +02:00
parent fb576b0954
commit 03ab36149e
388 changed files with 28620 additions and 339 deletions

View File

@@ -0,0 +1,186 @@
REPORT {{p}}flight_sum.
DATA gv_dest TYPE {{p}}flight-dest.
PARAMETERS p_from TYPE d OBLIGATORY.
SELECT-OPTIONS s_dest FOR gv_dest.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
dest TYPE {{p}}flight-dest,
name TYPE {{p}}airport-name,
flights TYPE i,
pax TYPE {{p}}flight-pax,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_dest TYPE RANGE OF {{p}}flight-dest.
METHODS select_lines
IMPORTING iv_from TYPE d
it_dest TYPE tt_dest
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_total,
dest TYPE {{p}}flight-dest,
flight_count TYPE i,
pax_sum TYPE {{p}}flight-pax,
END OF ty_total,
tt_total TYPE STANDARD TABLE OF ty_total WITH EMPTY KEY.
TYPES:
BEGIN OF ty_name,
airport TYPE {{p}}airport-airport,
name TYPE {{p}}airport-name,
END OF ty_name,
tt_name TYPE SORTED TABLE OF ty_name WITH UNIQUE KEY airport.
METHODS read_totals
IMPORTING iv_from TYPE d
it_dest TYPE tt_dest
RETURNING VALUE(rt_totals) TYPE tt_total.
METHODS read_names
IMPORTING it_dest TYPE tt_dest
RETURNING VALUE(rt_names) TYPE tt_name.
METHODS build_lines
IMPORTING it_totals TYPE tt_total
it_names TYPE tt_name
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_lines.
DATA(lt_totals) = read_totals( iv_from = iv_from it_dest = it_dest ).
rt_lines = build_lines( it_totals = lt_totals it_names = read_names( it_dest = it_dest ) ).
ENDMETHOD.
METHOD read_totals.
SELECT dest, COUNT( * ) AS flight_count, SUM( pax ) AS pax_sum
FROM {{p}}flight
WHERE dest IN @it_dest
OR flight_date >= @iv_from
GROUP BY dest
ORDER BY pax_sum DESCENDING, dest ASCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_totals.
ENDMETHOD.
METHOD read_names.
SELECT airport, name
FROM {{p}}airport
WHERE airport IN @it_dest
INTO CORRESPONDING FIELDS OF TABLE @rt_names.
ENDMETHOD.
METHOD build_lines.
LOOP AT it_totals INTO DATA(ls_total).
DATA(ls_line) = VALUE ty_line( dest = ls_total-dest
flights = ls_total-flight_count
pax = ls_total-pax_sum ).
READ TABLE it_names WITH TABLE KEY airport = ls_total-dest INTO DATA(ls_name).
IF sy-subrc = 0.
ls_line-name = ls_name-name.
ELSE.
ls_line-name = 'UNKNOWN'.
ENDIF.
APPEND ls_line TO rt_lines.
ENDLOOP.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_lines( iv_from = p_from it_dest = s_dest[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS totals_per_dest FOR TESTING.
METHODS sorted_by_pax FOR TESTING.
METHODS tie_break_by_dest FOR TESTING.
METHODS airport_names FOR TESTING.
METHODS unknown_name FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS dest_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}FLIGHT' ) ( '{{P}}AIRPORT' ) ) ).
DATA lt_flight TYPE STANDARD TABLE OF {{p}}flight WITH EMPTY KEY.
lt_flight = VALUE #( ( flight_id = 1 dest = 'AAA' flight_date = '20260110' pax = 100 )
( flight_id = 2 dest = 'AAA' flight_date = '20260210' pax = 50 )
( flight_id = 3 dest = 'BBB' flight_date = '20260115' pax = 300 )
( flight_id = 4 dest = 'CCC' flight_date = '20260120' pax = 150 ) ).
go_env->insert_test_data( lt_flight ).
DATA lt_airport TYPE STANDARD TABLE OF {{p}}airport WITH EMPTY KEY.
lt_airport = VALUE #( ( airport = 'AAA' name = 'ALPHA' ) ).
go_env->insert_test_data( lt_airport ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_dest.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'BBB' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_lines[ 1 ]-flights ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}flight-pax( 300 ) act = lt_lines[ 1 ]-pax ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 2 ]-flights ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}flight-pax( 150 ) act = lt_lines[ 2 ]-pax ).
ENDMETHOD.
METHOD sorted_by_pax.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'BBB' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 'CCC' act = lt_lines[ 3 ]-dest ).
ENDMETHOD.
METHOD tie_break_by_dest.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'AAA' act = lt_lines[ 2 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 'CCC' act = lt_lines[ 3 ]-dest ).
ENDMETHOD.
METHOD airport_names.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'ALPHA' act = lt_lines[ 2 ]-name ).
ENDMETHOD.
METHOD unknown_name.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'UNKNOWN' act = lt_lines[ 1 ]-name ).
cl_abap_unit_assert=>assert_equals( exp = 'UNKNOWN' act = lt_lines[ 3 ]-name ).
ENDMETHOD.
METHOD date_filter.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260201' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'AAA' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}flight-pax( 50 ) act = lt_lines[ 1 ]-pax ).
ENDMETHOD.
METHOD dest_filter.
DATA(lt_lines) = NEW lcl_report( )->select_lines(
iv_from = '20260101' it_dest = VALUE #( ( sign = 'I' option = 'EQ' low = 'AAA' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'AAA' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-flights ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,186 @@
REPORT {{p}}flight_sum.
DATA gv_dest TYPE {{p}}flight-dest.
PARAMETERS p_from TYPE d OBLIGATORY.
SELECT-OPTIONS s_dest FOR gv_dest.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
dest TYPE {{p}}flight-dest,
name TYPE {{p}}airport-name,
flights TYPE i,
pax TYPE {{p}}flight-pax,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_dest TYPE RANGE OF {{p}}flight-dest.
METHODS select_lines
IMPORTING iv_from TYPE d
it_dest TYPE tt_dest
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_total,
dest TYPE {{p}}flight-dest,
flight_count TYPE i,
pax_sum TYPE {{p}}flight-pax,
END OF ty_total,
tt_total TYPE STANDARD TABLE OF ty_total WITH EMPTY KEY.
TYPES:
BEGIN OF ty_name,
airport TYPE {{p}}airport-airport,
name TYPE {{p}}airport-name,
END OF ty_name,
tt_name TYPE SORTED TABLE OF ty_name WITH UNIQUE KEY airport.
METHODS read_totals
IMPORTING iv_from TYPE d
it_dest TYPE tt_dest
RETURNING VALUE(rt_totals) TYPE tt_total.
METHODS read_names
IMPORTING it_dest TYPE tt_dest
RETURNING VALUE(rt_names) TYPE tt_name.
METHODS build_lines
IMPORTING it_totals TYPE tt_total
it_names TYPE tt_name
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_lines.
DATA(lt_totals) = read_totals( iv_from = iv_from it_dest = it_dest ).
rt_lines = build_lines( it_totals = lt_totals it_names = read_names( it_dest = it_dest ) ).
ENDMETHOD.
METHOD read_totals.
SELECT dest, COUNT( * ) AS flight_count, SUM( pax ) AS pax_sum
FROM {{p}}flight
WHERE dest IN @it_dest
AND flight_date < @iv_from
GROUP BY dest
ORDER BY pax_sum DESCENDING, dest ASCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_totals.
ENDMETHOD.
METHOD read_names.
SELECT airport, name
FROM {{p}}airport
WHERE airport IN @it_dest
INTO CORRESPONDING FIELDS OF TABLE @rt_names.
ENDMETHOD.
METHOD build_lines.
LOOP AT it_totals INTO DATA(ls_total).
DATA(ls_line) = VALUE ty_line( dest = ls_total-dest
flights = ls_total-flight_count
pax = ls_total-pax_sum ).
READ TABLE it_names WITH TABLE KEY airport = ls_total-dest INTO DATA(ls_name).
IF sy-subrc = 0.
ls_line-name = ls_name-name.
ELSE.
ls_line-name = 'UNKNOWN'.
ENDIF.
APPEND ls_line TO rt_lines.
ENDLOOP.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_lines( iv_from = p_from it_dest = s_dest[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS totals_per_dest FOR TESTING.
METHODS sorted_by_pax FOR TESTING.
METHODS tie_break_by_dest FOR TESTING.
METHODS airport_names FOR TESTING.
METHODS unknown_name FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS dest_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}FLIGHT' ) ( '{{P}}AIRPORT' ) ) ).
DATA lt_flight TYPE STANDARD TABLE OF {{p}}flight WITH EMPTY KEY.
lt_flight = VALUE #( ( flight_id = 1 dest = 'AAA' flight_date = '20260110' pax = 100 )
( flight_id = 2 dest = 'AAA' flight_date = '20260210' pax = 50 )
( flight_id = 3 dest = 'BBB' flight_date = '20260115' pax = 300 )
( flight_id = 4 dest = 'CCC' flight_date = '20260120' pax = 150 ) ).
go_env->insert_test_data( lt_flight ).
DATA lt_airport TYPE STANDARD TABLE OF {{p}}airport WITH EMPTY KEY.
lt_airport = VALUE #( ( airport = 'AAA' name = 'ALPHA' ) ).
go_env->insert_test_data( lt_airport ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_dest.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'BBB' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_lines[ 1 ]-flights ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}flight-pax( 300 ) act = lt_lines[ 1 ]-pax ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 2 ]-flights ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}flight-pax( 150 ) act = lt_lines[ 2 ]-pax ).
ENDMETHOD.
METHOD sorted_by_pax.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'BBB' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 'CCC' act = lt_lines[ 3 ]-dest ).
ENDMETHOD.
METHOD tie_break_by_dest.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'AAA' act = lt_lines[ 2 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 'CCC' act = lt_lines[ 3 ]-dest ).
ENDMETHOD.
METHOD airport_names.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'ALPHA' act = lt_lines[ 2 ]-name ).
ENDMETHOD.
METHOD unknown_name.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'UNKNOWN' act = lt_lines[ 1 ]-name ).
cl_abap_unit_assert=>assert_equals( exp = 'UNKNOWN' act = lt_lines[ 3 ]-name ).
ENDMETHOD.
METHOD date_filter.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260201' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'AAA' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}flight-pax( 50 ) act = lt_lines[ 1 ]-pax ).
ENDMETHOD.
METHOD dest_filter.
DATA(lt_lines) = NEW lcl_report( )->select_lines(
iv_from = '20260101' it_dest = VALUE #( ( sign = 'I' option = 'EQ' low = 'AAA' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'AAA' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-flights ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,29 @@
{
"id": "G0125",
"pool": "eval",
"object_type": "PROG",
"category": "C",
"attempts": [
{
"stage": "validate",
"oracle": 95.0,
"null": 0
},
{
"stage": "validate",
"oracle": 95.0,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 2,
"killed": 2,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,99 @@
CLASS {{p}}flight_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES tt_dest TYPE RANGE OF {{p}}flight-dest.
METHODS run
IMPORTING iv_from TYPE d
it_dest TYPE tt_dest OPTIONAL
RETURNING VALUE(rr_data) TYPE REF TO data.
METHODS value_of
IMPORTING ir_data TYPE REF TO data
iv_row TYPE i
iv_col TYPE string
RETURNING VALUE(rv_value) TYPE string.
METHODS lines_of
IMPORTING ir_data TYPE REF TO data
RETURNING VALUE(rv_lines) TYPE i.
METHODS all_destinations FOR TESTING.
METHODS sorted_by_pax FOR TESTING.
METHODS tie_break_by_dest FOR TESTING.
METHODS counts_and_sums FOR TESTING.
METHODS airport_names FOR TESTING.
METHODS unknown_airport FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS dest_filter FOR TESTING.
ENDCLASS.
CLASS {{p}}flight_hidden IMPLEMENTATION.
METHOD run.
cl_salv_bs_runtime_info=>set( display = abap_false metadata = abap_false data = abap_true ).
SUBMIT {{p}}flight_sum WITH p_from = iv_from WITH s_dest IN it_dest AND RETURN.
TRY.
cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = rr_data ).
CATCH cx_salv_bs_sc_runtime_info.
ENDTRY.
cl_salv_bs_runtime_info=>clear_all( ).
ENDMETHOD.
METHOD lines_of.
FIELD-SYMBOLS <lt_data> TYPE STANDARD TABLE.
IF ir_data IS BOUND.
ASSIGN ir_data->* TO <lt_data>.
rv_lines = lines( <lt_data> ).
ENDIF.
ENDMETHOD.
METHOD value_of.
FIELD-SYMBOLS <lt_data> TYPE STANDARD TABLE.
ASSIGN ir_data->* TO <lt_data>.
ASSIGN <lt_data>[ iv_row ] TO FIELD-SYMBOL(<ls_line>).
ASSIGN COMPONENT iv_col OF STRUCTURE <ls_line> TO FIELD-SYMBOL(<lv_value>).
cl_abap_unit_assert=>assert_subrc( exp = 0 msg = |Column { iv_col } missing| ).
rv_value = condense( CONV string( <lv_value> ) ).
ENDMETHOD.
METHOD all_destinations.
cl_abap_unit_assert=>assert_equals( exp = 4 act = lines_of( run( '20260101' ) ) ).
ENDMETHOD.
METHOD sorted_by_pax.
DATA(lr_data) = run( '20260101' ).
cl_abap_unit_assert=>assert_equals( exp = `BBB` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `DEST` ) ).
cl_abap_unit_assert=>assert_equals( exp = `CCC` act = value_of( ir_data = lr_data iv_row = 4 iv_col = `DEST` ) ).
ENDMETHOD.
METHOD tie_break_by_dest.
DATA(lr_data) = run( '20260101' ).
cl_abap_unit_assert=>assert_equals( exp = `AAA` act = value_of( ir_data = lr_data iv_row = 2 iv_col = `DEST` ) ).
cl_abap_unit_assert=>assert_equals( exp = `DDD` act = value_of( ir_data = lr_data iv_row = 3 iv_col = `DEST` ) ).
ENDMETHOD.
METHOD counts_and_sums.
DATA(lr_data) = run( '20260101' ).
cl_abap_unit_assert=>assert_equals( exp = `BBB` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `DEST` ) ).
cl_abap_unit_assert=>assert_equals( exp = `2` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `FLIGHTS` ) ).
cl_abap_unit_assert=>assert_equals( exp = `400` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `PAX` ) ).
ENDMETHOD.
METHOD airport_names.
DATA(lr_data) = run( '20260101' ).
cl_abap_unit_assert=>assert_equals( exp = `ALPHA` act = value_of( ir_data = lr_data iv_row = 2 iv_col = `NAME` ) ).
ENDMETHOD.
METHOD unknown_airport.
DATA(lr_data) = run( '20260101' ).
cl_abap_unit_assert=>assert_equals( exp = `UNKNOWN` act = value_of( ir_data = lr_data iv_row = 4 iv_col = `NAME` ) ).
ENDMETHOD.
METHOD date_filter.
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines_of( run( '20260201' ) ) ).
ENDMETHOD.
METHOD dest_filter.
DATA(lr_data) = run( iv_from = '20260101'
it_dest = VALUE #( ( sign = 'I' option = 'EQ' low = 'BBB' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines_of( lr_data ) ).
cl_abap_unit_assert=>assert_equals( exp = `400` act = value_of( ir_data = lr_data iv_row = 1 iv_col = `PAX` ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,40 @@
{
"task": "G0125",
"mutants": [
{
"object": "{{P}}FLIGHT_SUM",
"mutant": "line 62: AND -> OR (logic)",
"status": "killed",
"hidden": "1/8",
"failed_tests": [
"AIRPORT_NAMES",
"COUNTS_AND_SUMS",
"DATE_FILTER",
"DEST_FILTER",
"SORTED_BY_PAX",
"TIE_BREAK_BY_DEST",
"UNKNOWN_AIRPORT"
]
},
{
"object": "{{P}}FLIGHT_SUM",
"mutant": "line 62: >= -> < (rel)",
"status": "killed",
"hidden": "0/8",
"failed_tests": [
"AIRPORT_NAMES",
"ALL_DESTINATIONS",
"COUNTS_AND_SUMS",
"DATE_FILTER",
"DEST_FILTER",
"SORTED_BY_PAX",
"TIE_BREAK_BY_DEST",
"UNKNOWN_AIRPORT"
]
}
],
"valid": 2,
"killed": 2,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,186 @@
REPORT {{p}}flight_sum.
DATA gv_dest TYPE {{p}}flight-dest.
PARAMETERS p_from TYPE d OBLIGATORY.
SELECT-OPTIONS s_dest FOR gv_dest.
CLASS lcl_report DEFINITION FINAL.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_line,
dest TYPE {{p}}flight-dest,
name TYPE {{p}}airport-name,
flights TYPE i,
pax TYPE {{p}}flight-pax,
END OF ty_line,
tt_line TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
TYPES tt_dest TYPE RANGE OF {{p}}flight-dest.
METHODS select_lines
IMPORTING iv_from TYPE d
it_dest TYPE tt_dest
RETURNING VALUE(rt_lines) TYPE tt_line.
METHODS display
CHANGING ct_lines TYPE tt_line.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_total,
dest TYPE {{p}}flight-dest,
flight_count TYPE i,
pax_sum TYPE {{p}}flight-pax,
END OF ty_total,
tt_total TYPE STANDARD TABLE OF ty_total WITH EMPTY KEY.
TYPES:
BEGIN OF ty_name,
airport TYPE {{p}}airport-airport,
name TYPE {{p}}airport-name,
END OF ty_name,
tt_name TYPE SORTED TABLE OF ty_name WITH UNIQUE KEY airport.
METHODS read_totals
IMPORTING iv_from TYPE d
it_dest TYPE tt_dest
RETURNING VALUE(rt_totals) TYPE tt_total.
METHODS read_names
IMPORTING it_dest TYPE tt_dest
RETURNING VALUE(rt_names) TYPE tt_name.
METHODS build_lines
IMPORTING it_totals TYPE tt_total
it_names TYPE tt_name
RETURNING VALUE(rt_lines) TYPE tt_line.
ENDCLASS.
CLASS lcl_report IMPLEMENTATION.
METHOD select_lines.
DATA(lt_totals) = read_totals( iv_from = iv_from it_dest = it_dest ).
rt_lines = build_lines( it_totals = lt_totals it_names = read_names( it_dest = it_dest ) ).
ENDMETHOD.
METHOD read_totals.
SELECT dest, COUNT( * ) AS flight_count, SUM( pax ) AS pax_sum
FROM {{p}}flight
WHERE dest IN @it_dest
AND flight_date >= @iv_from
GROUP BY dest
ORDER BY pax_sum DESCENDING, dest ASCENDING
INTO CORRESPONDING FIELDS OF TABLE @rt_totals.
ENDMETHOD.
METHOD read_names.
SELECT airport, name
FROM {{p}}airport
WHERE airport IN @it_dest
INTO CORRESPONDING FIELDS OF TABLE @rt_names.
ENDMETHOD.
METHOD build_lines.
LOOP AT it_totals INTO DATA(ls_total).
DATA(ls_line) = VALUE ty_line( dest = ls_total-dest
flights = ls_total-flight_count
pax = ls_total-pax_sum ).
READ TABLE it_names WITH TABLE KEY airport = ls_total-dest INTO DATA(ls_name).
IF sy-subrc = 0.
ls_line-name = ls_name-name.
ELSE.
ls_line-name = 'UNKNOWN'.
ENDIF.
APPEND ls_line TO rt_lines.
ENDLOOP.
ENDMETHOD.
METHOD display.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
CHANGING t_table = ct_lines ).
lo_alv->display( ).
CATCH cx_salv_msg INTO DATA(lx_error).
MESSAGE lx_error TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA(go_report) = NEW lcl_report( ).
DATA(gt_lines) = go_report->select_lines( iv_from = p_from it_dest = s_dest[] ).
go_report->display( CHANGING ct_lines = gt_lines ).
CLASS ltc_report DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS totals_per_dest FOR TESTING.
METHODS sorted_by_pax FOR TESTING.
METHODS tie_break_by_dest FOR TESTING.
METHODS airport_names FOR TESTING.
METHODS unknown_name FOR TESTING.
METHODS date_filter FOR TESTING.
METHODS dest_filter FOR TESTING.
ENDCLASS.
CLASS ltc_report IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create(
i_dependency_list = VALUE #( ( '{{P}}FLIGHT' ) ( '{{P}}AIRPORT' ) ) ).
DATA lt_flight TYPE STANDARD TABLE OF {{p}}flight WITH EMPTY KEY.
lt_flight = VALUE #( ( flight_id = 1 dest = 'AAA' flight_date = '20260110' pax = 100 )
( flight_id = 2 dest = 'AAA' flight_date = '20260210' pax = 50 )
( flight_id = 3 dest = 'BBB' flight_date = '20260115' pax = 300 )
( flight_id = 4 dest = 'CCC' flight_date = '20260120' pax = 150 ) ).
go_env->insert_test_data( lt_flight ).
DATA lt_airport TYPE STANDARD TABLE OF {{p}}airport WITH EMPTY KEY.
lt_airport = VALUE #( ( airport = 'AAA' name = 'ALPHA' ) ).
go_env->insert_test_data( lt_airport ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD totals_per_dest.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'BBB' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_lines[ 1 ]-flights ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}flight-pax( 300 ) act = lt_lines[ 1 ]-pax ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 2 ]-flights ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}flight-pax( 150 ) act = lt_lines[ 2 ]-pax ).
ENDMETHOD.
METHOD sorted_by_pax.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'BBB' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 'CCC' act = lt_lines[ 3 ]-dest ).
ENDMETHOD.
METHOD tie_break_by_dest.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'AAA' act = lt_lines[ 2 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 'CCC' act = lt_lines[ 3 ]-dest ).
ENDMETHOD.
METHOD airport_names.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'ALPHA' act = lt_lines[ 2 ]-name ).
ENDMETHOD.
METHOD unknown_name.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260101' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 'UNKNOWN' act = lt_lines[ 1 ]-name ).
cl_abap_unit_assert=>assert_equals( exp = 'UNKNOWN' act = lt_lines[ 3 ]-name ).
ENDMETHOD.
METHOD date_filter.
DATA(lt_lines) = NEW lcl_report( )->select_lines( iv_from = '20260201' it_dest = VALUE #( ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'AAA' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = CONV {{p}}flight-pax( 50 ) act = lt_lines[ 1 ]-pax ).
ENDMETHOD.
METHOD dest_filter.
DATA(lt_lines) = NEW lcl_report( )->select_lines(
iv_from = '20260101' it_dest = VALUE #( ( sign = 'I' option = 'EQ' low = 'AAA' ) ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_lines ) ).
cl_abap_unit_assert=>assert_equals( exp = 'AAA' act = lt_lines[ 1 ]-dest ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lt_lines[ 1 ]-flights ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,10 @@
@EndUserText.label : 'Airport'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}airport {
key client : abap.clnt not null;
key airport : abap.char(3) not null;
name : abap.char(40);
}

View File

@@ -0,0 +1,12 @@
@EndUserText.label : 'Flight movement'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}flight {
key client : abap.clnt not null;
key dest : abap.char(3) not null;
key flight_date : abap.dats not null;
key flight_id : abap.int4 not null;
pax : abap.int4;
}

View File

@@ -0,0 +1,24 @@
CLASS {{p}}flight_seed DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS {{p}}flight_seed IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DELETE FROM {{p}}flight.
DELETE FROM {{p}}airport.
INSERT {{p}}airport FROM TABLE @( VALUE #(
( airport = 'AAA' name = 'ALPHA' )
( airport = 'BBB' name = 'BETA' )
( airport = 'DDD' name = 'DELTA' ) ) ).
INSERT {{p}}flight FROM TABLE @( VALUE #(
( flight_id = 1 dest = 'AAA' flight_date = '20260110' pax = 100 )
( flight_id = 2 dest = 'AAA' flight_date = '20260210' pax = 50 )
( flight_id = 3 dest = 'BBB' flight_date = '20260115' pax = 300 )
( flight_id = 4 dest = 'CCC' flight_date = '20251231' pax = 500 )
( flight_id = 5 dest = 'CCC' flight_date = '20260301' pax = 20 )
( flight_id = 6 dest = 'BBB' flight_date = '20260120' pax = 100 )
( flight_id = 7 dest = 'DDD' flight_date = '20260125' pax = 150 ) ) ).
out->write( sy-dbcnt ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,43 @@
# 1. Goal
A regional airport collects the movements of its flights. The operations team
needs a report that shows, for each destination, how many flights went there
and how many passengers they carried.
# 2. Open questions
None.
# 3. Context
- Table {{P}}FLIGHT exists in package $TMP. It contains data.
Fields: FLIGHT_ID (INT4, key), DEST (CHAR 3), FLIGHT_DATE (DATS), PAX (INT4).
- Table {{P}}AIRPORT exists in package $TMP. It contains data.
Fields: AIRPORT (CHAR 3, key), NAME (CHAR 40).
# 4. Contract
- Create the executable program {{P}}FLIGHT_SUM in package $TMP.
- Selection screen:
- Parameter P_FROM, type DATS, mandatory: the first flight date to include.
- Select-option S_DEST for the destination.
- Show the result with CL_SALV_TABLE. The output table has these columns, with
these names: DEST, NAME, FLIGHTS (number of flights), PAX (sum of the
passengers).
# 5. Business rules
1. Include a flight only if FLIGHT_DATE is on or after P_FROM and DEST is in
S_DEST.
2. Show one line for each destination that has at least one included flight.
3. NAME is the airport name of the destination from {{P}}AIRPORT. If the
destination has no entry in {{P}}AIRPORT, NAME is 'UNKNOWN'.
4. FLIGHTS is the number of included flights of the destination. PAX is the sum
of the passengers of the included flights.
5. Sort the lines by PAX, the highest first. If two lines have the same PAX,
sort them by DEST in ascending order.
# 6. Constraints
- Release target: 8.16.
- Coding standards: Clean ABAP.
- Out of scope: do not change {{P}}FLIGHT and {{P}}AIRPORT.
# 7. Acceptance
- The program is active and has no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests as local test classes in the program.

View File

@@ -0,0 +1,67 @@
{
"id": "G0125",
"category": "C",
"object_type": "PROG",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 40,
"max_activations": 10
},
"seed": [
{
"type": "TABL",
"name": "{{P}}FLIGHT",
"file": "seed/flight.tabl.asabap",
"description": "Flight movements of the airport"
},
{
"type": "TABL",
"name": "{{P}}AIRPORT",
"file": "seed/airport.tabl.asabap",
"description": "Airport master data"
},
{
"type": "CLAS",
"name": "{{P}}FLIGHT_SEED",
"file": "seed/flight_seed.clas.abap",
"description": "Flight and airport seed data",
"run": true
}
],
"contract": [
{
"type": "PROG",
"name": "{{P}}FLIGHT_SUM",
"parameters": [
"p_from",
"s_dest"
]
}
],
"out_of_scope": [
"{{P}}FLIGHT",
"{{P}}AIRPORT"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}FLIGHT_HIDDEN",
"file": "hidden/flight_hidden.clas.abap",
"description": "Hidden tests for the flight report"
}
],
"reference": [
{
"type": "PROG",
"name": "{{P}}FLIGHT_SUM",
"file": "reference/flight_sum.prog.abap",
"description": "Flights and passengers per destination"
}
],
"craft_checks": [
"db_operation_in_loop",
"method_length"
]
}