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,137 @@
CLASS {{p}}sample_batcher DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_test_type TYPE c LENGTH 4,
ty_sample_id TYPE c LENGTH 10,
ty_priority TYPE i.
TYPES:
BEGIN OF ty_batch,
test_type TYPE ty_test_type,
total TYPE i,
urgent TYPE i,
END OF ty_batch.
TYPES tt_batches TYPE STANDARD TABLE OF ty_batch WITH EMPTY KEY.
METHODS add_sample
IMPORTING iv_sample_id TYPE ty_sample_id
iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority
RETURNING VALUE(rv_added) TYPE abap_bool.
METHODS get_batches
RETURNING VALUE(rt_batches) TYPE tt_batches.
METHODS get_batch
IMPORTING iv_test_type TYPE ty_test_type
RETURNING VALUE(rs_batch) TYPE ty_batch.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_priority,
urgent TYPE ty_priority VALUE 1,
normal TYPE ty_priority VALUE 2,
routine TYPE ty_priority VALUE 3,
END OF c_priority.
TYPES:
BEGIN OF ty_sample_entry,
sample_id TYPE ty_sample_id,
END OF ty_sample_entry.
TYPES:
tt_batch_index TYPE SORTED TABLE OF ty_batch WITH UNIQUE KEY test_type,
tt_sample_index TYPE HASHED TABLE OF ty_sample_entry WITH UNIQUE KEY sample_id.
DATA mt_batches TYPE tt_batch_index.
DATA mt_samples TYPE tt_sample_index.
METHODS normalize_id
IMPORTING iv_id TYPE ty_sample_id
RETURNING VALUE(rv_id) TYPE ty_sample_id.
METHODS normalize_type
IMPORTING iv_type TYPE ty_test_type
RETURNING VALUE(rv_type) TYPE ty_test_type.
METHODS is_valid_priority
IMPORTING iv_priority TYPE ty_priority
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS count_sample
IMPORTING iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority.
ENDCLASS.
CLASS {{p}}sample_batcher IMPLEMENTATION.
METHOD add_sample.
DATA(lv_sample_id) = normalize_id( iv_sample_id ).
DATA(lv_test_type) = normalize_type( iv_test_type ).
IF lv_sample_id IS INITIAL
OR lv_test_type IS INITIAL
OR is_valid_priority( iv_priority ) <> abap_false
OR line_exists( mt_samples[ sample_id = lv_sample_id ] ).
RETURN.
ENDIF.
INSERT VALUE #( sample_id = lv_sample_id ) INTO TABLE mt_samples.
count_sample( iv_test_type = lv_test_type
iv_priority = iv_priority ).
rv_added = abap_true.
ENDMETHOD.
METHOD get_batches.
rt_batches = mt_batches.
SORT rt_batches BY test_type.
ENDMETHOD.
METHOD get_batch.
DATA(lv_test_type) = normalize_type( iv_test_type ).
READ TABLE mt_batches INTO rs_batch WITH TABLE KEY test_type = lv_test_type.
IF sy-subrc <> 0.
rs_batch = VALUE #( test_type = lv_test_type ).
ENDIF.
ENDMETHOD.
METHOD normalize_id.
rv_id = to_upper( replace( val = iv_id sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD normalize_type.
rv_type = to_upper( replace( val = iv_type sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD is_valid_priority.
rv_valid = xsdbool( iv_priority = c_priority-urgent
OR iv_priority = c_priority-normal
OR iv_priority = c_priority-routine ).
ENDMETHOD.
METHOD count_sample.
READ TABLE mt_batches ASSIGNING FIELD-SYMBOL(<ls_batch>)
WITH TABLE KEY test_type = iv_test_type.
IF sy-subrc <> 0.
INSERT VALUE #( test_type = iv_test_type ) INTO TABLE mt_batches
ASSIGNING <ls_batch>.
ENDIF.
<ls_batch>-total = <ls_batch>-total + 1.
IF iv_priority = c_priority-urgent.
<ls_batch>-urgent = <ls_batch>-urgent + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,137 @@
CLASS {{p}}sample_batcher DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_test_type TYPE c LENGTH 4,
ty_sample_id TYPE c LENGTH 10,
ty_priority TYPE i.
TYPES:
BEGIN OF ty_batch,
test_type TYPE ty_test_type,
total TYPE i,
urgent TYPE i,
END OF ty_batch.
TYPES tt_batches TYPE STANDARD TABLE OF ty_batch WITH EMPTY KEY.
METHODS add_sample
IMPORTING iv_sample_id TYPE ty_sample_id
iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority
RETURNING VALUE(rv_added) TYPE abap_bool.
METHODS get_batches
RETURNING VALUE(rt_batches) TYPE tt_batches.
METHODS get_batch
IMPORTING iv_test_type TYPE ty_test_type
RETURNING VALUE(rs_batch) TYPE ty_batch.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_priority,
urgent TYPE ty_priority VALUE 1,
normal TYPE ty_priority VALUE 2,
routine TYPE ty_priority VALUE 3,
END OF c_priority.
TYPES:
BEGIN OF ty_sample_entry,
sample_id TYPE ty_sample_id,
END OF ty_sample_entry.
TYPES:
tt_batch_index TYPE SORTED TABLE OF ty_batch WITH UNIQUE KEY test_type,
tt_sample_index TYPE HASHED TABLE OF ty_sample_entry WITH UNIQUE KEY sample_id.
DATA mt_batches TYPE tt_batch_index.
DATA mt_samples TYPE tt_sample_index.
METHODS normalize_id
IMPORTING iv_id TYPE ty_sample_id
RETURNING VALUE(rv_id) TYPE ty_sample_id.
METHODS normalize_type
IMPORTING iv_type TYPE ty_test_type
RETURNING VALUE(rv_type) TYPE ty_test_type.
METHODS is_valid_priority
IMPORTING iv_priority TYPE ty_priority
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS count_sample
IMPORTING iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority.
ENDCLASS.
CLASS {{p}}sample_batcher IMPLEMENTATION.
METHOD add_sample.
DATA(lv_sample_id) = normalize_id( iv_sample_id ).
DATA(lv_test_type) = normalize_type( iv_test_type ).
IF lv_sample_id IS INITIAL
OR lv_test_type IS INITIAL
OR is_valid_priority( iv_priority ) = abap_false
AND line_exists( mt_samples[ sample_id = lv_sample_id ] ).
RETURN.
ENDIF.
INSERT VALUE #( sample_id = lv_sample_id ) INTO TABLE mt_samples.
count_sample( iv_test_type = lv_test_type
iv_priority = iv_priority ).
rv_added = abap_true.
ENDMETHOD.
METHOD get_batches.
rt_batches = mt_batches.
SORT rt_batches BY test_type.
ENDMETHOD.
METHOD get_batch.
DATA(lv_test_type) = normalize_type( iv_test_type ).
READ TABLE mt_batches INTO rs_batch WITH TABLE KEY test_type = lv_test_type.
IF sy-subrc <> 0.
rs_batch = VALUE #( test_type = lv_test_type ).
ENDIF.
ENDMETHOD.
METHOD normalize_id.
rv_id = to_upper( replace( val = iv_id sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD normalize_type.
rv_type = to_upper( replace( val = iv_type sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD is_valid_priority.
rv_valid = xsdbool( iv_priority = c_priority-urgent
OR iv_priority = c_priority-normal
OR iv_priority = c_priority-routine ).
ENDMETHOD.
METHOD count_sample.
READ TABLE mt_batches ASSIGNING FIELD-SYMBOL(<ls_batch>)
WITH TABLE KEY test_type = iv_test_type.
IF sy-subrc <> 0.
INSERT VALUE #( test_type = iv_test_type ) INTO TABLE mt_batches
ASSIGNING <ls_batch>.
ENDIF.
<ls_batch>-total = <ls_batch>-total + 1.
IF iv_priority = c_priority-urgent.
<ls_batch>-urgent = <ls_batch>-urgent + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,137 @@
CLASS {{p}}sample_batcher DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_test_type TYPE c LENGTH 4,
ty_sample_id TYPE c LENGTH 10,
ty_priority TYPE i.
TYPES:
BEGIN OF ty_batch,
test_type TYPE ty_test_type,
total TYPE i,
urgent TYPE i,
END OF ty_batch.
TYPES tt_batches TYPE STANDARD TABLE OF ty_batch WITH EMPTY KEY.
METHODS add_sample
IMPORTING iv_sample_id TYPE ty_sample_id
iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority
RETURNING VALUE(rv_added) TYPE abap_bool.
METHODS get_batches
RETURNING VALUE(rt_batches) TYPE tt_batches.
METHODS get_batch
IMPORTING iv_test_type TYPE ty_test_type
RETURNING VALUE(rs_batch) TYPE ty_batch.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_priority,
urgent TYPE ty_priority VALUE 1,
normal TYPE ty_priority VALUE 2,
routine TYPE ty_priority VALUE 3,
END OF c_priority.
TYPES:
BEGIN OF ty_sample_entry,
sample_id TYPE ty_sample_id,
END OF ty_sample_entry.
TYPES:
tt_batch_index TYPE SORTED TABLE OF ty_batch WITH UNIQUE KEY test_type,
tt_sample_index TYPE HASHED TABLE OF ty_sample_entry WITH UNIQUE KEY sample_id.
DATA mt_batches TYPE tt_batch_index.
DATA mt_samples TYPE tt_sample_index.
METHODS normalize_id
IMPORTING iv_id TYPE ty_sample_id
RETURNING VALUE(rv_id) TYPE ty_sample_id.
METHODS normalize_type
IMPORTING iv_type TYPE ty_test_type
RETURNING VALUE(rv_type) TYPE ty_test_type.
METHODS is_valid_priority
IMPORTING iv_priority TYPE ty_priority
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS count_sample
IMPORTING iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority.
ENDCLASS.
CLASS {{p}}sample_batcher IMPLEMENTATION.
METHOD add_sample.
DATA(lv_sample_id) = normalize_id( iv_sample_id ).
DATA(lv_test_type) = normalize_type( iv_test_type ).
IF lv_sample_id IS INITIAL
OR lv_test_type IS INITIAL
OR is_valid_priority( iv_priority ) = abap_false
OR line_exists( mt_samples[ sample_id = lv_sample_id ] ).
RETURN.
ENDIF.
INSERT VALUE #( sample_id = lv_sample_id ) INTO TABLE mt_samples.
count_sample( iv_test_type = lv_test_type
iv_priority = iv_priority ).
rv_added = abap_false.
ENDMETHOD.
METHOD get_batches.
rt_batches = mt_batches.
SORT rt_batches BY test_type.
ENDMETHOD.
METHOD get_batch.
DATA(lv_test_type) = normalize_type( iv_test_type ).
READ TABLE mt_batches INTO rs_batch WITH TABLE KEY test_type = lv_test_type.
IF sy-subrc <> 0.
rs_batch = VALUE #( test_type = lv_test_type ).
ENDIF.
ENDMETHOD.
METHOD normalize_id.
rv_id = to_upper( replace( val = iv_id sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD normalize_type.
rv_type = to_upper( replace( val = iv_type sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD is_valid_priority.
rv_valid = xsdbool( iv_priority = c_priority-urgent
OR iv_priority = c_priority-normal
OR iv_priority = c_priority-routine ).
ENDMETHOD.
METHOD count_sample.
READ TABLE mt_batches ASSIGNING FIELD-SYMBOL(<ls_batch>)
WITH TABLE KEY test_type = iv_test_type.
IF sy-subrc <> 0.
INSERT VALUE #( test_type = iv_test_type ) INTO TABLE mt_batches
ASSIGNING <ls_batch>.
ENDIF.
<ls_batch>-total = <ls_batch>-total + 1.
IF iv_priority = c_priority-urgent.
<ls_batch>-urgent = <ls_batch>-urgent + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,137 @@
CLASS {{p}}sample_batcher DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_test_type TYPE c LENGTH 4,
ty_sample_id TYPE c LENGTH 10,
ty_priority TYPE i.
TYPES:
BEGIN OF ty_batch,
test_type TYPE ty_test_type,
total TYPE i,
urgent TYPE i,
END OF ty_batch.
TYPES tt_batches TYPE STANDARD TABLE OF ty_batch WITH EMPTY KEY.
METHODS add_sample
IMPORTING iv_sample_id TYPE ty_sample_id
iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority
RETURNING VALUE(rv_added) TYPE abap_bool.
METHODS get_batches
RETURNING VALUE(rt_batches) TYPE tt_batches.
METHODS get_batch
IMPORTING iv_test_type TYPE ty_test_type
RETURNING VALUE(rs_batch) TYPE ty_batch.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_priority,
urgent TYPE ty_priority VALUE 1,
normal TYPE ty_priority VALUE 2,
routine TYPE ty_priority VALUE 3,
END OF c_priority.
TYPES:
BEGIN OF ty_sample_entry,
sample_id TYPE ty_sample_id,
END OF ty_sample_entry.
TYPES:
tt_batch_index TYPE SORTED TABLE OF ty_batch WITH UNIQUE KEY test_type,
tt_sample_index TYPE HASHED TABLE OF ty_sample_entry WITH UNIQUE KEY sample_id.
DATA mt_batches TYPE tt_batch_index.
DATA mt_samples TYPE tt_sample_index.
METHODS normalize_id
IMPORTING iv_id TYPE ty_sample_id
RETURNING VALUE(rv_id) TYPE ty_sample_id.
METHODS normalize_type
IMPORTING iv_type TYPE ty_test_type
RETURNING VALUE(rv_type) TYPE ty_test_type.
METHODS is_valid_priority
IMPORTING iv_priority TYPE ty_priority
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS count_sample
IMPORTING iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority.
ENDCLASS.
CLASS {{p}}sample_batcher IMPLEMENTATION.
METHOD add_sample.
DATA(lv_sample_id) = normalize_id( iv_sample_id ).
DATA(lv_test_type) = normalize_type( iv_test_type ).
IF lv_sample_id IS INITIAL
OR lv_test_type IS INITIAL
OR is_valid_priority( iv_priority ) = abap_false
OR line_exists( mt_samples[ sample_id = lv_sample_id ] ).
RETURN.
ENDIF.
INSERT VALUE #( sample_id = lv_sample_id ) INTO TABLE mt_samples.
count_sample( iv_test_type = lv_test_type
iv_priority = iv_priority ).
rv_added = abap_true.
ENDMETHOD.
METHOD get_batches.
rt_batches = mt_batches.
SORT rt_batches BY test_type.
ENDMETHOD.
METHOD get_batch.
DATA(lv_test_type) = normalize_type( iv_test_type ).
READ TABLE mt_batches INTO rs_batch WITH TABLE KEY test_type = lv_test_type.
IF sy-subrc <> 0.
rs_batch = VALUE #( test_type = lv_test_type ).
ENDIF.
ENDMETHOD.
METHOD normalize_id.
rv_id = to_upper( replace( val = iv_id sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD normalize_type.
rv_type = to_upper( replace( val = iv_type sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD is_valid_priority.
rv_valid = xsdbool( iv_priority = c_priority-urgent
OR iv_priority = c_priority-normal
AND iv_priority = c_priority-routine ).
ENDMETHOD.
METHOD count_sample.
READ TABLE mt_batches ASSIGNING FIELD-SYMBOL(<ls_batch>)
WITH TABLE KEY test_type = iv_test_type.
IF sy-subrc <> 0.
INSERT VALUE #( test_type = iv_test_type ) INTO TABLE mt_batches
ASSIGNING <ls_batch>.
ENDIF.
<ls_batch>-total = <ls_batch>-total + 1.
IF iv_priority = c_priority-urgent.
<ls_batch>-urgent = <ls_batch>-urgent + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,137 @@
CLASS {{p}}sample_batcher DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_test_type TYPE c LENGTH 4,
ty_sample_id TYPE c LENGTH 10,
ty_priority TYPE i.
TYPES:
BEGIN OF ty_batch,
test_type TYPE ty_test_type,
total TYPE i,
urgent TYPE i,
END OF ty_batch.
TYPES tt_batches TYPE STANDARD TABLE OF ty_batch WITH EMPTY KEY.
METHODS add_sample
IMPORTING iv_sample_id TYPE ty_sample_id
iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority
RETURNING VALUE(rv_added) TYPE abap_bool.
METHODS get_batches
RETURNING VALUE(rt_batches) TYPE tt_batches.
METHODS get_batch
IMPORTING iv_test_type TYPE ty_test_type
RETURNING VALUE(rs_batch) TYPE ty_batch.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_priority,
urgent TYPE ty_priority VALUE 1,
normal TYPE ty_priority VALUE 2,
routine TYPE ty_priority VALUE 3,
END OF c_priority.
TYPES:
BEGIN OF ty_sample_entry,
sample_id TYPE ty_sample_id,
END OF ty_sample_entry.
TYPES:
tt_batch_index TYPE SORTED TABLE OF ty_batch WITH UNIQUE KEY test_type,
tt_sample_index TYPE HASHED TABLE OF ty_sample_entry WITH UNIQUE KEY sample_id.
DATA mt_batches TYPE tt_batch_index.
DATA mt_samples TYPE tt_sample_index.
METHODS normalize_id
IMPORTING iv_id TYPE ty_sample_id
RETURNING VALUE(rv_id) TYPE ty_sample_id.
METHODS normalize_type
IMPORTING iv_type TYPE ty_test_type
RETURNING VALUE(rv_type) TYPE ty_test_type.
METHODS is_valid_priority
IMPORTING iv_priority TYPE ty_priority
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS count_sample
IMPORTING iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority.
ENDCLASS.
CLASS {{p}}sample_batcher IMPLEMENTATION.
METHOD add_sample.
DATA(lv_sample_id) = normalize_id( iv_sample_id ).
DATA(lv_test_type) = normalize_type( iv_test_type ).
IF lv_sample_id IS INITIAL
OR lv_test_type IS INITIAL
OR is_valid_priority( iv_priority ) = abap_false
OR line_exists( mt_samples[ sample_id = lv_sample_id ] ).
RETURN.
ENDIF.
INSERT VALUE #( sample_id = lv_sample_id ) INTO TABLE mt_samples.
count_sample( iv_test_type = lv_test_type
iv_priority = iv_priority ).
rv_added = abap_true.
ENDMETHOD.
METHOD get_batches.
rt_batches = mt_batches.
SORT rt_batches BY test_type.
ENDMETHOD.
METHOD get_batch.
DATA(lv_test_type) = normalize_type( iv_test_type ).
READ TABLE mt_batches INTO rs_batch WITH TABLE KEY test_type = lv_test_type.
IF sy-subrc <> 0.
rs_batch = VALUE #( test_type = lv_test_type ).
ENDIF.
ENDMETHOD.
METHOD normalize_id.
rv_id = to_upper( replace( val = iv_id sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD normalize_type.
rv_type = to_upper( replace( val = iv_type sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD is_valid_priority.
rv_valid = xsdbool( iv_priority = c_priority-urgent
OR iv_priority = c_priority-normal
OR iv_priority = c_priority-routine ).
ENDMETHOD.
METHOD count_sample.
READ TABLE mt_batches ASSIGNING FIELD-SYMBOL(<ls_batch>)
WITH TABLE KEY test_type = iv_test_type.
IF sy-subrc <> 0.
INSERT VALUE #( test_type = iv_test_type ) INTO TABLE mt_batches
ASSIGNING <ls_batch>.
ENDIF.
<ls_batch>-total = <ls_batch>-total - 1.
IF iv_priority = c_priority-urgent.
<ls_batch>-urgent = <ls_batch>-urgent + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,29 @@
{
"id": "G0113",
"pool": "eval",
"object_type": "CLAS",
"category": "C",
"attempts": [
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 67.0,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 5,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,143 @@
CLASS {{p}}t02_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}sample_batcher.
METHODS setup.
METHODS adds_sample FOR TESTING.
METHODS counts_urgent FOR TESTING.
METHODS rejects_empty_id FOR TESTING.
METHODS rejects_empty_type FOR TESTING.
METHODS rejects_duplicate FOR TESTING.
METHODS rejects_bad_priority FOR TESTING.
METHODS normalizes_input FOR TESTING.
METHODS batches_sorted FOR TESTING.
METHODS one_row_per_type FOR TESTING.
METHODS get_batch_known FOR TESTING.
METHODS get_batch_unknown FOR TESTING.
ENDCLASS.
CLASS {{p}}t02_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}sample_batcher( ).
ENDMETHOD.
METHOD adds_sample.
cl_abap_unit_assert=>assert_equals(
exp = abap_true
act = mo_cut->add_sample( iv_sample_id = 'S0000001'
iv_test_type = 'GLU'
iv_priority = 2 ) ).
DATA(lt_batches) = mo_cut->get_batches( ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_batches ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lt_batches[ 1 ]-total ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lt_batches[ 1 ]-urgent ).
ENDMETHOD.
METHOD counts_urgent.
mo_cut->add_sample( iv_sample_id = 'S1' iv_test_type = 'K' iv_priority = 1 ).
mo_cut->add_sample( iv_sample_id = 'S2' iv_test_type = 'K' iv_priority = 3 ).
mo_cut->add_sample( iv_sample_id = 'S3' iv_test_type = 'K' iv_priority = 1 ).
DATA(ls_batch) = mo_cut->get_batch( 'K' ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = ls_batch-total ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_batch-urgent ).
ENDMETHOD.
METHOD rejects_empty_id.
cl_abap_unit_assert=>assert_equals(
exp = abap_false
act = mo_cut->add_sample( iv_sample_id = ''
iv_test_type = 'GLU'
iv_priority = 2 ) ).
DATA(lt_batches) = mo_cut->get_batches( ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_batches ) ).
ENDMETHOD.
METHOD rejects_empty_type.
cl_abap_unit_assert=>assert_equals(
exp = abap_false
act = mo_cut->add_sample( iv_sample_id = 'S1'
iv_test_type = ' '
iv_priority = 2 ) ).
DATA(lt_batches) = mo_cut->get_batches( ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_batches ) ).
ENDMETHOD.
METHOD rejects_duplicate.
mo_cut->add_sample( iv_sample_id = 'S1' iv_test_type = 'GLU' iv_priority = 2 ).
cl_abap_unit_assert=>assert_equals(
exp = abap_false
act = mo_cut->add_sample( iv_sample_id = 's1'
iv_test_type = 'NA'
iv_priority = 2 ) ).
DATA(lt_batches) = mo_cut->get_batches( ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_batches ) ).
cl_abap_unit_assert=>assert_equals( exp = 'GLU' act = lt_batches[ 1 ]-test_type ).
ENDMETHOD.
METHOD rejects_bad_priority.
cl_abap_unit_assert=>assert_equals(
exp = abap_false
act = mo_cut->add_sample( iv_sample_id = 'S1'
iv_test_type = 'GLU'
iv_priority = 4 ) ).
cl_abap_unit_assert=>assert_equals(
exp = abap_false
act = mo_cut->add_sample( iv_sample_id = 'S2'
iv_test_type = 'GLU'
iv_priority = 0 ) ).
DATA(lt_batches) = mo_cut->get_batches( ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = lines( lt_batches ) ).
ENDMETHOD.
METHOD normalizes_input.
cl_abap_unit_assert=>assert_equals(
exp = abap_true
act = mo_cut->add_sample( iv_sample_id = ' s0000001 '
iv_test_type = 'glu'
iv_priority = 2 ) ).
DATA(lt_batches) = mo_cut->get_batches( ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_batches ) ).
cl_abap_unit_assert=>assert_equals( exp = 'GLU' act = lt_batches[ 1 ]-test_type ).
ENDMETHOD.
METHOD batches_sorted.
mo_cut->add_sample( iv_sample_id = 'S1' iv_test_type = 'NA' iv_priority = 2 ).
mo_cut->add_sample( iv_sample_id = 'S2' iv_test_type = 'GLU' iv_priority = 2 ).
mo_cut->add_sample( iv_sample_id = 'S3' iv_test_type = 'K' iv_priority = 2 ).
DATA(lt_batches) = mo_cut->get_batches( ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lines( lt_batches ) ).
cl_abap_unit_assert=>assert_equals( exp = 'GLU' act = lt_batches[ 1 ]-test_type ).
cl_abap_unit_assert=>assert_equals( exp = 'K' act = lt_batches[ 2 ]-test_type ).
cl_abap_unit_assert=>assert_equals( exp = 'NA' act = lt_batches[ 3 ]-test_type ).
ENDMETHOD.
METHOD one_row_per_type.
mo_cut->add_sample( iv_sample_id = 'S1' iv_test_type = 'GLU' iv_priority = 1 ).
mo_cut->add_sample( iv_sample_id = 'S2' iv_test_type = 'GLU' iv_priority = 2 ).
mo_cut->add_sample( iv_sample_id = 'S3' iv_test_type = 'GLU' iv_priority = 3 ).
DATA(lt_batches) = mo_cut->get_batches( ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lines( lt_batches ) ).
cl_abap_unit_assert=>assert_equals( exp = 3 act = lt_batches[ 1 ]-total ).
ENDMETHOD.
METHOD get_batch_known.
mo_cut->add_sample( iv_sample_id = 'S1' iv_test_type = 'GLU' iv_priority = 1 ).
mo_cut->add_sample( iv_sample_id = 'S2' iv_test_type = 'NA' iv_priority = 2 ).
DATA(ls_batch) = mo_cut->get_batch( 'GLU' ).
cl_abap_unit_assert=>assert_equals( exp = 'GLU' act = ls_batch-test_type ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_batch-total ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_batch-urgent ).
ENDMETHOD.
METHOD get_batch_unknown.
DATA(ls_batch) = mo_cut->get_batch( 'XXX' ).
cl_abap_unit_assert=>assert_equals( exp = 'XXX' act = ls_batch-test_type ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = ls_batch-total ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = ls_batch-urgent ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,71 @@
{
"task": "G0113",
"mutants": [
{
"object": "{{P}}SAMPLE_BATCHER",
"mutant": "line 80: = -> <> (eq)",
"status": "killed",
"hidden": "3/11",
"failed_tests": [
"ADDS_SAMPLE",
"BATCHES_SORTED",
"COUNTS_URGENT",
"GET_BATCH_KNOWN",
"NORMALIZES_INPUT",
"ONE_ROW_PER_TYPE",
"REJECTS_BAD_PRIORITY",
"REJECTS_DUPLICATE"
]
},
{
"object": "{{P}}SAMPLE_BATCHER",
"mutant": "line 81: OR -> AND (logic)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"REJECTS_BAD_PRIORITY",
"REJECTS_DUPLICATE"
]
},
{
"object": "{{P}}SAMPLE_BATCHER",
"mutant": "line 88: abap_true -> abap_false (bool)",
"status": "killed",
"hidden": "9/11",
"failed_tests": [
"ADDS_SAMPLE",
"NORMALIZES_INPUT"
]
},
{
"object": "{{P}}SAMPLE_BATCHER",
"mutant": "line 120: OR -> AND (logic)",
"status": "killed",
"hidden": "5/11",
"failed_tests": [
"ADDS_SAMPLE",
"BATCHES_SORTED",
"COUNTS_URGENT",
"NORMALIZES_INPUT",
"ONE_ROW_PER_TYPE",
"REJECTS_DUPLICATE"
]
},
{
"object": "{{P}}SAMPLE_BATCHER",
"mutant": "line 131: + -> - (arith)",
"status": "killed",
"hidden": "7/11",
"failed_tests": [
"ADDS_SAMPLE",
"COUNTS_URGENT",
"GET_BATCH_KNOWN",
"ONE_ROW_PER_TYPE"
]
}
],
"valid": 5,
"killed": 5,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,137 @@
CLASS {{p}}sample_batcher DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
ty_test_type TYPE c LENGTH 4,
ty_sample_id TYPE c LENGTH 10,
ty_priority TYPE i.
TYPES:
BEGIN OF ty_batch,
test_type TYPE ty_test_type,
total TYPE i,
urgent TYPE i,
END OF ty_batch.
TYPES tt_batches TYPE STANDARD TABLE OF ty_batch WITH EMPTY KEY.
METHODS add_sample
IMPORTING iv_sample_id TYPE ty_sample_id
iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority
RETURNING VALUE(rv_added) TYPE abap_bool.
METHODS get_batches
RETURNING VALUE(rt_batches) TYPE tt_batches.
METHODS get_batch
IMPORTING iv_test_type TYPE ty_test_type
RETURNING VALUE(rs_batch) TYPE ty_batch.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_priority,
urgent TYPE ty_priority VALUE 1,
normal TYPE ty_priority VALUE 2,
routine TYPE ty_priority VALUE 3,
END OF c_priority.
TYPES:
BEGIN OF ty_sample_entry,
sample_id TYPE ty_sample_id,
END OF ty_sample_entry.
TYPES:
tt_batch_index TYPE SORTED TABLE OF ty_batch WITH UNIQUE KEY test_type,
tt_sample_index TYPE HASHED TABLE OF ty_sample_entry WITH UNIQUE KEY sample_id.
DATA mt_batches TYPE tt_batch_index.
DATA mt_samples TYPE tt_sample_index.
METHODS normalize_id
IMPORTING iv_id TYPE ty_sample_id
RETURNING VALUE(rv_id) TYPE ty_sample_id.
METHODS normalize_type
IMPORTING iv_type TYPE ty_test_type
RETURNING VALUE(rv_type) TYPE ty_test_type.
METHODS is_valid_priority
IMPORTING iv_priority TYPE ty_priority
RETURNING VALUE(rv_valid) TYPE abap_bool.
METHODS count_sample
IMPORTING iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority.
ENDCLASS.
CLASS {{p}}sample_batcher IMPLEMENTATION.
METHOD add_sample.
DATA(lv_sample_id) = normalize_id( iv_sample_id ).
DATA(lv_test_type) = normalize_type( iv_test_type ).
IF lv_sample_id IS INITIAL
OR lv_test_type IS INITIAL
OR is_valid_priority( iv_priority ) = abap_false
OR line_exists( mt_samples[ sample_id = lv_sample_id ] ).
RETURN.
ENDIF.
INSERT VALUE #( sample_id = lv_sample_id ) INTO TABLE mt_samples.
count_sample( iv_test_type = lv_test_type
iv_priority = iv_priority ).
rv_added = abap_true.
ENDMETHOD.
METHOD get_batches.
rt_batches = mt_batches.
SORT rt_batches BY test_type.
ENDMETHOD.
METHOD get_batch.
DATA(lv_test_type) = normalize_type( iv_test_type ).
READ TABLE mt_batches INTO rs_batch WITH TABLE KEY test_type = lv_test_type.
IF sy-subrc <> 0.
rs_batch = VALUE #( test_type = lv_test_type ).
ENDIF.
ENDMETHOD.
METHOD normalize_id.
rv_id = to_upper( replace( val = iv_id sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD normalize_type.
rv_type = to_upper( replace( val = iv_type sub = ` ` with = `` occ = 0 ) ).
ENDMETHOD.
METHOD is_valid_priority.
rv_valid = xsdbool( iv_priority = c_priority-urgent
OR iv_priority = c_priority-normal
OR iv_priority = c_priority-routine ).
ENDMETHOD.
METHOD count_sample.
READ TABLE mt_batches ASSIGNING FIELD-SYMBOL(<ls_batch>)
WITH TABLE KEY test_type = iv_test_type.
IF sy-subrc <> 0.
INSERT VALUE #( test_type = iv_test_type ) INTO TABLE mt_batches
ASSIGNING <ls_batch>.
ENDIF.
<ls_batch>-total = <ls_batch>-total + 1.
IF iv_priority = c_priority-urgent.
<ls_batch>-urgent = <ls_batch>-urgent + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,88 @@
CLASS ltc_sample_batcher DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}sample_batcher.
METHODS setup.
METHODS counts_samples FOR TESTING.
METHODS counts_urgent FOR TESTING.
METHODS rejects_empty_id FOR TESTING.
METHODS rejects_duplicate FOR TESTING.
METHODS rejects_bad_priority FOR TESTING.
METHODS normalizes_input FOR TESTING.
METHODS batches_sorted FOR TESTING.
METHODS unknown_type_is_zero FOR TESTING.
ENDCLASS.
CLASS ltc_sample_batcher IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}sample_batcher( ).
ENDMETHOD.
METHOD counts_samples.
mo_cut->add_sample( iv_sample_id = 'S1' iv_test_type = 'GLU' iv_priority = 2 ).
mo_cut->add_sample( iv_sample_id = 'S2' iv_test_type = 'GLU' iv_priority = 3 ).
DATA(ls_batch) = mo_cut->get_batch( 'GLU' ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_batch-total ).
ENDMETHOD.
METHOD counts_urgent.
mo_cut->add_sample( iv_sample_id = 'S1' iv_test_type = 'K' iv_priority = 1 ).
mo_cut->add_sample( iv_sample_id = 'S2' iv_test_type = 'K' iv_priority = 2 ).
DATA(ls_batch) = mo_cut->get_batch( 'K' ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = ls_batch-total ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = ls_batch-urgent ).
ENDMETHOD.
METHOD rejects_empty_id.
cl_abap_unit_assert=>assert_equals(
exp = abap_false
act = mo_cut->add_sample( iv_sample_id = ''
iv_test_type = 'GLU'
iv_priority = 2 ) ).
ENDMETHOD.
METHOD rejects_duplicate.
mo_cut->add_sample( iv_sample_id = 'S1' iv_test_type = 'GLU' iv_priority = 2 ).
cl_abap_unit_assert=>assert_equals(
exp = abap_false
act = mo_cut->add_sample( iv_sample_id = 'S1'
iv_test_type = 'NA'
iv_priority = 2 ) ).
ENDMETHOD.
METHOD rejects_bad_priority.
cl_abap_unit_assert=>assert_equals(
exp = abap_false
act = mo_cut->add_sample( iv_sample_id = 'S1'
iv_test_type = 'GLU'
iv_priority = 9 ) ).
ENDMETHOD.
METHOD normalizes_input.
cl_abap_unit_assert=>assert_equals(
exp = abap_true
act = mo_cut->add_sample( iv_sample_id = 's1'
iv_test_type = 'glu'
iv_priority = 2 ) ).
DATA(lt_batches) = mo_cut->get_batches( ).
cl_abap_unit_assert=>assert_equals( exp = 'GLU' act = lt_batches[ 1 ]-test_type ).
ENDMETHOD.
METHOD batches_sorted.
mo_cut->add_sample( iv_sample_id = 'S1' iv_test_type = 'NA' iv_priority = 2 ).
mo_cut->add_sample( iv_sample_id = 'S2' iv_test_type = 'GLU' iv_priority = 2 ).
DATA(lt_batches) = mo_cut->get_batches( ).
cl_abap_unit_assert=>assert_equals( exp = 'GLU' act = lt_batches[ 1 ]-test_type ).
cl_abap_unit_assert=>assert_equals( exp = 'NA' act = lt_batches[ 2 ]-test_type ).
ENDMETHOD.
METHOD unknown_type_is_zero.
DATA(ls_batch) = mo_cut->get_batch( 'XXX' ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = ls_batch-total ).
cl_abap_unit_assert=>assert_equals( exp = 0 act = ls_batch-urgent ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,77 @@
# 1. Goal
A laboratory receives blood samples. Each sample has a sample ID, a test type and a
priority. The laboratory groups the samples into batches. One batch belongs to each
test type. A laboratory program adds the samples one by one. Then it reads the
batches.
Create the class {{P}}SAMPLE_BATCHER. The class collects the samples and gives the
batches.
# 2. Open questions
None.
# 3. Context
- The class is new. It is in package $TMP.
- No other object is necessary.
- A laboratory program creates one instance of the class. It adds all samples of a
shift. Then it reads the batches.
# 4. Contract
Class {{P}}SAMPLE_BATCHER. The class is public and final. It can be created without
parameters.
Public types:
- ty_test_type TYPE c LENGTH 4
- ty_sample_id TYPE c LENGTH 10
- ty_priority TYPE i
- ty_batch with the components test_type (TYPE ty_test_type), total (TYPE i) and
urgent (TYPE i)
- tt_batches TYPE STANDARD TABLE OF ty_batch WITH EMPTY KEY
Public methods:
- add_sample
IMPORTING iv_sample_id TYPE ty_sample_id
iv_test_type TYPE ty_test_type
iv_priority TYPE ty_priority
RETURNING VALUE(rv_added) TYPE abap_bool
- get_batches
RETURNING VALUE(rt_batches) TYPE tt_batches
- get_batch
IMPORTING iv_test_type TYPE ty_test_type
RETURNING VALUE(rs_batch) TYPE ty_batch
Do not add other public methods.
# 5. Business rules
add_sample
1. Normalize the sample ID and the test type. Remove all spaces. Convert all letters
to upper case.
2. Reject the sample and return abap_false if one of these conditions is true:
- the normalized sample ID is empty, or
- the normalized test type is empty, or
- the priority is not 1, 2 or 3, or
- the normalized sample ID was already added.
The state of the object does not change.
3. Else accept the sample and return abap_true. The batch of the test type gets one
more sample. If the priority is 1, the batch also gets one more urgent sample.
get_batches
4. Return one row for each test type that has at least one sample.
5. Sort the rows by the test type in ascending order.
get_batch
6. Normalize the test type in the same way as in rule 1.
7. If the test type has at least one sample, return its row.
8. Else return a row with this test type, total = 0 and urgent = 0.
# 6. Constraints
- Release target: 8.16.
- Coding standards: Clean ABAP. Methods below 40 statements. No global variables. No
comment that restates the code.
- Out of scope: no other object is part of this task.
# 7. Acceptance
- The class is active and has no syntax error.
- The hidden tests pass.
- Write your own ABAP Unit tests for the class.

View File

@@ -0,0 +1,42 @@
{
"id": "G0113",
"category": "C",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 40,
"max_activations": 10
},
"seed": [],
"contract": [
{
"type": "CLAS",
"name": "{{P}}SAMPLE_BATCHER"
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T02_HIDDEN",
"file": "hidden/t02_hidden.clas.abap",
"description": "T02 hidden tests for the sample batcher"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}SAMPLE_BATCHER",
"file": "reference/sample_batcher.clas.abap",
"description": "Sample batcher",
"testclasses_file": "reference/sample_batcher.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"linear_search_in_loop",
"sorted_or_hashed_table"
]
}