Stage 2 summary at 50 accepted trajectories

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 18:02:52 +02:00
parent 332fb4601d
commit 5bcd1bf9cd
1230 changed files with 77563 additions and 33 deletions

View File

@@ -0,0 +1,133 @@
CLASS {{p}}care_visit_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_visit,
visit_id TYPE string,
client_id TYPE string,
carer_id TYPE string,
start_hour TYPE i,
end_hour TYPE i,
END OF ty_visit,
tt_visit TYPE STANDARD TABLE OF ty_visit WITH EMPTY KEY.
METHODS check_visit
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RAISING {{p}}cx_care_visit.
PRIVATE SECTION.
CONSTANTS:
c_day_start TYPE i VALUE 7,
c_day_end TYPE i VALUE 20,
c_max_hours TYPE i VALUE 4.
METHODS validate_fields
IMPORTING is_visit TYPE ty_visit
RAISING {{p}}cx_care_visit.
METHODS validate_times
IMPORTING is_visit TYPE ty_visit
RAISING {{p}}cx_care_visit.
METHODS has_carer_overlap
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS has_client_overlap
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS periods_overlap
IMPORTING is_visit TYPE ty_visit
is_other TYPE ty_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS raise_reason
IMPORTING iv_reason TYPE {{p}}if_care_reason=>ty_reason
iv_visit_id TYPE string
RAISING {{p}}cx_care_visit.
ENDCLASS.
CLASS {{p}}care_visit_checker IMPLEMENTATION.
METHOD check_visit.
validate_fields( is_visit ).
validate_times( is_visit ).
IF has_carer_overlap( is_visit = is_visit it_plan = it_plan ).
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-carer_overlap
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF has_client_overlap( is_visit = is_visit it_plan = it_plan ).
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-client_overlap
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD validate_fields.
IF is_visit-visit_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_visit_id
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-client_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_client
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-carer_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_carer
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD validate_times.
IF is_visit-start_hour >= c_day_start OR is_visit-end_hour > c_day_end.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-outside_hours
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-end_hour <= is_visit-start_hour.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-bad_duration
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-end_hour - is_visit-start_hour > c_max_hours.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-too_long
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD has_carer_overlap.
LOOP AT it_plan INTO DATA(ls_plan) WHERE carer_id = is_visit-carer_id.
IF periods_overlap( is_visit = is_visit is_other = ls_plan ).
rv_overlap = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD has_client_overlap.
LOOP AT it_plan INTO DATA(ls_plan) WHERE client_id = is_visit-client_id.
IF periods_overlap( is_visit = is_visit is_other = ls_plan ).
rv_overlap = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD periods_overlap.
rv_overlap = xsdbool( is_visit-start_hour < is_other-end_hour
AND is_other-start_hour < is_visit-end_hour ).
ENDMETHOD.
METHOD raise_reason.
RAISE EXCEPTION TYPE {{p}}cx_care_visit
EXPORTING
iv_reason = iv_reason
iv_visit_id = iv_visit_id.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,133 @@
CLASS {{p}}care_visit_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_visit,
visit_id TYPE string,
client_id TYPE string,
carer_id TYPE string,
start_hour TYPE i,
end_hour TYPE i,
END OF ty_visit,
tt_visit TYPE STANDARD TABLE OF ty_visit WITH EMPTY KEY.
METHODS check_visit
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RAISING {{p}}cx_care_visit.
PRIVATE SECTION.
CONSTANTS:
c_day_start TYPE i VALUE 7,
c_day_end TYPE i VALUE 20,
c_max_hours TYPE i VALUE 4.
METHODS validate_fields
IMPORTING is_visit TYPE ty_visit
RAISING {{p}}cx_care_visit.
METHODS validate_times
IMPORTING is_visit TYPE ty_visit
RAISING {{p}}cx_care_visit.
METHODS has_carer_overlap
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS has_client_overlap
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS periods_overlap
IMPORTING is_visit TYPE ty_visit
is_other TYPE ty_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS raise_reason
IMPORTING iv_reason TYPE {{p}}if_care_reason=>ty_reason
iv_visit_id TYPE string
RAISING {{p}}cx_care_visit.
ENDCLASS.
CLASS {{p}}care_visit_checker IMPLEMENTATION.
METHOD check_visit.
validate_fields( is_visit ).
validate_times( is_visit ).
IF has_carer_overlap( is_visit = is_visit it_plan = it_plan ).
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-carer_overlap
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF has_client_overlap( is_visit = is_visit it_plan = it_plan ).
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-client_overlap
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD validate_fields.
IF is_visit-visit_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_visit_id
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-client_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_client
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-carer_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_carer
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD validate_times.
IF is_visit-start_hour < c_day_start OR is_visit-end_hour > c_day_end.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-outside_hours
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-end_hour <= is_visit-start_hour.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-bad_duration
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-end_hour + is_visit-start_hour > c_max_hours.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-too_long
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD has_carer_overlap.
LOOP AT it_plan INTO DATA(ls_plan) WHERE carer_id = is_visit-carer_id.
IF periods_overlap( is_visit = is_visit is_other = ls_plan ).
rv_overlap = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD has_client_overlap.
LOOP AT it_plan INTO DATA(ls_plan) WHERE client_id = is_visit-client_id.
IF periods_overlap( is_visit = is_visit is_other = ls_plan ).
rv_overlap = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD periods_overlap.
rv_overlap = xsdbool( is_visit-start_hour < is_other-end_hour
AND is_other-start_hour < is_visit-end_hour ).
ENDMETHOD.
METHOD raise_reason.
RAISE EXCEPTION TYPE {{p}}cx_care_visit
EXPORTING
iv_reason = iv_reason
iv_visit_id = iv_visit_id.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,133 @@
CLASS {{p}}care_visit_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_visit,
visit_id TYPE string,
client_id TYPE string,
carer_id TYPE string,
start_hour TYPE i,
end_hour TYPE i,
END OF ty_visit,
tt_visit TYPE STANDARD TABLE OF ty_visit WITH EMPTY KEY.
METHODS check_visit
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RAISING {{p}}cx_care_visit.
PRIVATE SECTION.
CONSTANTS:
c_day_start TYPE i VALUE 7,
c_day_end TYPE i VALUE 20,
c_max_hours TYPE i VALUE 4.
METHODS validate_fields
IMPORTING is_visit TYPE ty_visit
RAISING {{p}}cx_care_visit.
METHODS validate_times
IMPORTING is_visit TYPE ty_visit
RAISING {{p}}cx_care_visit.
METHODS has_carer_overlap
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS has_client_overlap
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS periods_overlap
IMPORTING is_visit TYPE ty_visit
is_other TYPE ty_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS raise_reason
IMPORTING iv_reason TYPE {{p}}if_care_reason=>ty_reason
iv_visit_id TYPE string
RAISING {{p}}cx_care_visit.
ENDCLASS.
CLASS {{p}}care_visit_checker IMPLEMENTATION.
METHOD check_visit.
validate_fields( is_visit ).
validate_times( is_visit ).
IF has_carer_overlap( is_visit = is_visit it_plan = it_plan ).
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-carer_overlap
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF has_client_overlap( is_visit = is_visit it_plan = it_plan ).
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-client_overlap
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD validate_fields.
IF is_visit-visit_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_visit_id
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-client_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_client
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-carer_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_carer
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD validate_times.
IF is_visit-start_hour < c_day_start OR is_visit-end_hour > c_day_end.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-outside_hours
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-end_hour <= is_visit-start_hour.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-bad_duration
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-end_hour - is_visit-start_hour > c_max_hours.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-too_long
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD has_carer_overlap.
LOOP AT it_plan INTO DATA(ls_plan) WHERE carer_id = is_visit-carer_id.
IF periods_overlap( is_visit = is_visit is_other = ls_plan ).
rv_overlap = abap_false.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD has_client_overlap.
LOOP AT it_plan INTO DATA(ls_plan) WHERE client_id = is_visit-client_id.
IF periods_overlap( is_visit = is_visit is_other = ls_plan ).
rv_overlap = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD periods_overlap.
rv_overlap = xsdbool( is_visit-start_hour < is_other-end_hour
AND is_other-start_hour < is_visit-end_hour ).
ENDMETHOD.
METHOD raise_reason.
RAISE EXCEPTION TYPE {{p}}cx_care_visit
EXPORTING
iv_reason = iv_reason
iv_visit_id = iv_visit_id.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,133 @@
CLASS {{p}}care_visit_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_visit,
visit_id TYPE string,
client_id TYPE string,
carer_id TYPE string,
start_hour TYPE i,
end_hour TYPE i,
END OF ty_visit,
tt_visit TYPE STANDARD TABLE OF ty_visit WITH EMPTY KEY.
METHODS check_visit
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RAISING {{p}}cx_care_visit.
PRIVATE SECTION.
CONSTANTS:
c_day_start TYPE i VALUE 7,
c_day_end TYPE i VALUE 20,
c_max_hours TYPE i VALUE 4.
METHODS validate_fields
IMPORTING is_visit TYPE ty_visit
RAISING {{p}}cx_care_visit.
METHODS validate_times
IMPORTING is_visit TYPE ty_visit
RAISING {{p}}cx_care_visit.
METHODS has_carer_overlap
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS has_client_overlap
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS periods_overlap
IMPORTING is_visit TYPE ty_visit
is_other TYPE ty_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS raise_reason
IMPORTING iv_reason TYPE {{p}}if_care_reason=>ty_reason
iv_visit_id TYPE string
RAISING {{p}}cx_care_visit.
ENDCLASS.
CLASS {{p}}care_visit_checker IMPLEMENTATION.
METHOD check_visit.
validate_fields( is_visit ).
validate_times( is_visit ).
IF has_carer_overlap( is_visit = is_visit it_plan = it_plan ).
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-carer_overlap
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF has_client_overlap( is_visit = is_visit it_plan = it_plan ).
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-client_overlap
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD validate_fields.
IF is_visit-visit_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_visit_id
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-client_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_client
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-carer_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_carer
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD validate_times.
IF is_visit-start_hour < c_day_start OR is_visit-end_hour > c_day_end.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-outside_hours
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-end_hour <= is_visit-start_hour.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-bad_duration
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-end_hour - is_visit-start_hour > c_max_hours.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-too_long
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD has_carer_overlap.
LOOP AT it_plan INTO DATA(ls_plan) WHERE carer_id = is_visit-carer_id.
IF periods_overlap( is_visit = is_visit is_other = ls_plan ).
rv_overlap = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD has_client_overlap.
LOOP AT it_plan INTO DATA(ls_plan) WHERE client_id = is_visit-client_id.
IF periods_overlap( is_visit = is_visit is_other = ls_plan ).
rv_overlap = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD periods_overlap.
rv_overlap = xsdbool( is_visit-start_hour < is_other-end_hour
OR is_other-start_hour < is_visit-end_hour ).
ENDMETHOD.
METHOD raise_reason.
RAISE EXCEPTION TYPE {{p}}cx_care_visit
EXPORTING
iv_reason = iv_reason
iv_visit_id = iv_visit_id.
ENDMETHOD.
ENDCLASS.

View File

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

View File

@@ -0,0 +1,161 @@
CLASS {{p}}d01_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}care_visit_checker.
METHODS setup.
METHODS accepts_valid_visit FOR TESTING.
METHODS accepts_touching_visits FOR TESTING.
METHODS rejects_empty_visit_id FOR TESTING.
METHODS rejects_empty_client FOR TESTING.
METHODS rejects_empty_carer FOR TESTING.
METHODS rejects_early_start FOR TESTING.
METHODS rejects_late_end FOR TESTING.
METHODS rejects_bad_duration FOR TESTING.
METHODS rejects_too_long FOR TESTING.
METHODS rejects_carer_overlap FOR TESTING.
METHODS rejects_client_overlap FOR TESTING.
METHODS carer_overlap_first FOR TESTING.
METHODS expect_reason
IMPORTING is_visit TYPE {{p}}care_visit_checker=>ty_visit
it_plan TYPE {{p}}care_visit_checker=>tt_visit
iv_reason TYPE {{p}}if_care_reason=>ty_reason.
ENDCLASS.
CLASS {{p}}d01_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}care_visit_checker( ).
ENDMETHOD.
METHOD accepts_valid_visit.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 9 end_hour = 11 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
TRY.
mo_cut->check_visit( is_visit = ls_visit it_plan = lt_plan ).
CATCH {{p}}cx_care_visit INTO DATA(lx).
cl_abap_unit_assert=>fail( msg = |unexpected reason { lx->mv_reason }| ).
ENDTRY.
ENDMETHOD.
METHOD accepts_touching_visits.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V2' client_id = 'K1' carer_id = 'C1' start_hour = 9 end_hour = 11 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit(
( visit_id = 'P1' client_id = 'K9' carer_id = 'C1' start_hour = 7 end_hour = 9 ) ).
TRY.
mo_cut->check_visit( is_visit = ls_visit it_plan = lt_plan ).
CATCH {{p}}cx_care_visit INTO DATA(lx).
cl_abap_unit_assert=>fail( msg = |unexpected reason { lx->mv_reason }| ).
ENDTRY.
ENDMETHOD.
METHOD rejects_empty_visit_id.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = '' client_id = '' carer_id = 'C1' start_hour = 9 end_hour = 11 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-no_visit_id ).
ENDMETHOD.
METHOD rejects_empty_client.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = '' carer_id = 'C1' start_hour = 9 end_hour = 11 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
TRY.
mo_cut->check_visit( is_visit = ls_visit it_plan = lt_plan ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_care_visit INTO DATA(lx).
cl_abap_unit_assert=>assert_equals( exp = {{p}}if_care_reason=>c_reason-no_client
act = lx->mv_reason ).
cl_abap_unit_assert=>assert_equals( exp = 'V1' act = lx->mv_visit_id ).
ENDTRY.
ENDMETHOD.
METHOD rejects_empty_carer.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = '' start_hour = 9 end_hour = 11 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-no_carer ).
ENDMETHOD.
METHOD rejects_early_start.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 6 end_hour = 8 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-outside_hours ).
ENDMETHOD.
METHOD rejects_late_end.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 21 end_hour = 21 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-outside_hours ).
ENDMETHOD.
METHOD rejects_bad_duration.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 9 end_hour = 9 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-bad_duration ).
ENDMETHOD.
METHOD rejects_too_long.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 8 end_hour = 13 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-too_long ).
ENDMETHOD.
METHOD rejects_carer_overlap.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 11 end_hour = 13 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit(
( visit_id = 'P1' client_id = 'K9' carer_id = 'C1' start_hour = 10 end_hour = 12 ) ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-carer_overlap ).
ENDMETHOD.
METHOD rejects_client_overlap.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 11 end_hour = 13 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit(
( visit_id = 'P1' client_id = 'K1' carer_id = 'C9' start_hour = 10 end_hour = 12 ) ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-client_overlap ).
ENDMETHOD.
METHOD carer_overlap_first.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 11 end_hour = 13 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit(
( visit_id = 'P1' client_id = 'K1' carer_id = 'C1' start_hour = 10 end_hour = 12 ) ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-carer_overlap ).
ENDMETHOD.
METHOD expect_reason.
TRY.
mo_cut->check_visit( is_visit = is_visit it_plan = it_plan ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_care_visit INTO DATA(lx).
cl_abap_unit_assert=>assert_equals( exp = iv_reason act = lx->mv_reason ).
ENDTRY.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,64 @@
{
"task": "G1064",
"mutants": [
{
"object": "{{P}}CARE_VISIT_CHECKER",
"mutant": "line 59: = -> <> (eq)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
},
{
"object": "{{P}}CARE_VISIT_CHECKER",
"mutant": "line 88: < -> >= (rel)",
"status": "killed",
"hidden": "4/12",
"failed_tests": [
"ACCEPTS_TOUCHING_VISITS",
"ACCEPTS_VALID_VISIT",
"CARER_OVERLAP_FIRST",
"REJECTS_BAD_DURATION",
"REJECTS_CARER_OVERLAP",
"REJECTS_CLIENT_OVERLAP",
"REJECTS_EARLY_START",
"REJECTS_TOO_LONG"
]
},
{
"object": "{{P}}CARE_VISIT_CHECKER",
"mutant": "line 98: - -> + (arith)",
"status": "killed",
"hidden": "7/12",
"failed_tests": [
"ACCEPTS_TOUCHING_VISITS",
"ACCEPTS_VALID_VISIT",
"CARER_OVERLAP_FIRST",
"REJECTS_CARER_OVERLAP",
"REJECTS_CLIENT_OVERLAP"
]
},
{
"object": "{{P}}CARE_VISIT_CHECKER",
"mutant": "line 107: abap_true -> abap_false (bool)",
"status": "killed",
"hidden": "10/12",
"failed_tests": [
"CARER_OVERLAP_FIRST",
"REJECTS_CARER_OVERLAP"
]
},
{
"object": "{{P}}CARE_VISIT_CHECKER",
"mutant": "line 124: AND -> OR (logic)",
"status": "killed",
"hidden": "11/12",
"failed_tests": [
"ACCEPTS_TOUCHING_VISITS"
]
}
],
"valid": 4,
"killed": 4,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,133 @@
CLASS {{p}}care_visit_checker DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_visit,
visit_id TYPE string,
client_id TYPE string,
carer_id TYPE string,
start_hour TYPE i,
end_hour TYPE i,
END OF ty_visit,
tt_visit TYPE STANDARD TABLE OF ty_visit WITH EMPTY KEY.
METHODS check_visit
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RAISING {{p}}cx_care_visit.
PRIVATE SECTION.
CONSTANTS:
c_day_start TYPE i VALUE 7,
c_day_end TYPE i VALUE 20,
c_max_hours TYPE i VALUE 4.
METHODS validate_fields
IMPORTING is_visit TYPE ty_visit
RAISING {{p}}cx_care_visit.
METHODS validate_times
IMPORTING is_visit TYPE ty_visit
RAISING {{p}}cx_care_visit.
METHODS has_carer_overlap
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS has_client_overlap
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS periods_overlap
IMPORTING is_visit TYPE ty_visit
is_other TYPE ty_visit
RETURNING VALUE(rv_overlap) TYPE abap_bool.
METHODS raise_reason
IMPORTING iv_reason TYPE {{p}}if_care_reason=>ty_reason
iv_visit_id TYPE string
RAISING {{p}}cx_care_visit.
ENDCLASS.
CLASS {{p}}care_visit_checker IMPLEMENTATION.
METHOD check_visit.
validate_fields( is_visit ).
validate_times( is_visit ).
IF has_carer_overlap( is_visit = is_visit it_plan = it_plan ).
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-carer_overlap
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF has_client_overlap( is_visit = is_visit it_plan = it_plan ).
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-client_overlap
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD validate_fields.
IF is_visit-visit_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_visit_id
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-client_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_client
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-carer_id IS INITIAL.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-no_carer
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD validate_times.
IF is_visit-start_hour < c_day_start OR is_visit-end_hour > c_day_end.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-outside_hours
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-end_hour <= is_visit-start_hour.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-bad_duration
iv_visit_id = is_visit-visit_id ).
ENDIF.
IF is_visit-end_hour - is_visit-start_hour > c_max_hours.
raise_reason( iv_reason = {{p}}if_care_reason=>c_reason-too_long
iv_visit_id = is_visit-visit_id ).
ENDIF.
ENDMETHOD.
METHOD has_carer_overlap.
LOOP AT it_plan INTO DATA(ls_plan) WHERE carer_id = is_visit-carer_id.
IF periods_overlap( is_visit = is_visit is_other = ls_plan ).
rv_overlap = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD has_client_overlap.
LOOP AT it_plan INTO DATA(ls_plan) WHERE client_id = is_visit-client_id.
IF periods_overlap( is_visit = is_visit is_other = ls_plan ).
rv_overlap = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD periods_overlap.
rv_overlap = xsdbool( is_visit-start_hour < is_other-end_hour
AND is_other-start_hour < is_visit-end_hour ).
ENDMETHOD.
METHOD raise_reason.
RAISE EXCEPTION TYPE {{p}}cx_care_visit
EXPORTING
iv_reason = iv_reason
iv_visit_id = iv_visit_id.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,114 @@
CLASS ltc_care_visit_checker DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}care_visit_checker.
METHODS setup.
METHODS valid_visit_passes FOR TESTING.
METHODS empty_visit_id FOR TESTING.
METHODS outside_hours FOR TESTING.
METHODS bad_duration FOR TESTING.
METHODS too_long FOR TESTING.
METHODS carer_overlap FOR TESTING.
METHODS client_overlap FOR TESTING.
METHODS touching_visits FOR TESTING.
METHODS expect_reason
IMPORTING is_visit TYPE {{p}}care_visit_checker=>ty_visit
it_plan TYPE {{p}}care_visit_checker=>tt_visit
iv_reason TYPE {{p}}if_care_reason=>ty_reason.
ENDCLASS.
CLASS ltc_care_visit_checker IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}care_visit_checker( ).
ENDMETHOD.
METHOD valid_visit_passes.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 9 end_hour = 11 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
TRY.
mo_cut->check_visit( is_visit = ls_visit it_plan = lt_plan ).
CATCH {{p}}cx_care_visit INTO DATA(lx).
cl_abap_unit_assert=>fail( msg = |unexpected reason { lx->mv_reason }| ).
ENDTRY.
ENDMETHOD.
METHOD empty_visit_id.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = '' client_id = 'K1' carer_id = 'C1' start_hour = 9 end_hour = 11 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-no_visit_id ).
ENDMETHOD.
METHOD outside_hours.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 5 end_hour = 7 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-outside_hours ).
ENDMETHOD.
METHOD bad_duration.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 10 end_hour = 10 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-bad_duration ).
ENDMETHOD.
METHOD too_long.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 9 end_hour = 14 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit( ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-too_long ).
ENDMETHOD.
METHOD carer_overlap.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K2' carer_id = 'C1' start_hour = 9 end_hour = 11 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit(
( visit_id = 'P1' client_id = 'K1' carer_id = 'C1' start_hour = 10 end_hour = 12 ) ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-carer_overlap ).
ENDMETHOD.
METHOD client_overlap.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C2' start_hour = 9 end_hour = 11 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit(
( visit_id = 'P1' client_id = 'K1' carer_id = 'C1' start_hour = 10 end_hour = 12 ) ).
expect_reason( is_visit = ls_visit
it_plan = lt_plan
iv_reason = {{p}}if_care_reason=>c_reason-client_overlap ).
ENDMETHOD.
METHOD touching_visits.
DATA(ls_visit) = VALUE {{p}}care_visit_checker=>ty_visit(
visit_id = 'V1' client_id = 'K1' carer_id = 'C1' start_hour = 12 end_hour = 14 ).
DATA(lt_plan) = VALUE {{p}}care_visit_checker=>tt_visit(
( visit_id = 'P1' client_id = 'K1' carer_id = 'C1' start_hour = 10 end_hour = 12 ) ).
TRY.
mo_cut->check_visit( is_visit = ls_visit it_plan = lt_plan ).
CATCH {{p}}cx_care_visit INTO DATA(lx).
cl_abap_unit_assert=>fail( msg = |unexpected reason { lx->mv_reason }| ).
ENDTRY.
ENDMETHOD.
METHOD expect_reason.
TRY.
mo_cut->check_visit( is_visit = is_visit it_plan = it_plan ).
cl_abap_unit_assert=>fail( msg = 'exception expected' ).
CATCH {{p}}cx_care_visit INTO DATA(lx).
cl_abap_unit_assert=>assert_equals( exp = iv_reason act = lx->mv_reason ).
ENDTRY.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,22 @@
CLASS {{p}}cx_care_visit DEFINITION PUBLIC INHERITING FROM cx_static_check FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_reason TYPE c LENGTH 20.
DATA mv_reason TYPE ty_reason READ-ONLY.
DATA mv_visit_id TYPE string READ-ONLY.
METHODS constructor
IMPORTING iv_reason TYPE ty_reason
iv_visit_id TYPE string.
PRIVATE SECTION.
ENDCLASS.
CLASS {{p}}cx_care_visit IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
mv_reason = iv_reason.
mv_visit_id = iv_visit_id.
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,15 @@
INTERFACE {{p}}if_care_reason PUBLIC.
TYPES ty_reason TYPE c LENGTH 20.
CONSTANTS:
BEGIN OF c_reason,
no_visit_id TYPE ty_reason VALUE 'NO_VISIT_ID',
no_client TYPE ty_reason VALUE 'NO_CLIENT',
no_carer TYPE ty_reason VALUE 'NO_CARER',
outside_hours TYPE ty_reason VALUE 'OUTSIDE_HOURS',
bad_duration TYPE ty_reason VALUE 'BAD_DURATION',
too_long TYPE ty_reason VALUE 'TOO_LONG',
carer_overlap TYPE ty_reason VALUE 'CARER_OVERLAP',
client_overlap TYPE ty_reason VALUE 'CLIENT_OVERLAP',
END OF c_reason.
ENDINTERFACE.

View File

@@ -0,0 +1,77 @@
# 1. Goal
A home care service plans the visits of its carers. Before the dispatcher
confirms a visit, the system must check the visit. The check raises a
class-based exception. The exception gives one reason code for each rule that
fails.
# 2. Open questions
None.
# 3. Context
- All objects are in package $TMP.
- The interface {{P}}IF_CARE_REASON exists in package $TMP. It is active. It has
the type TY_REASON (type C, length 20) and the constant structure C_REASON.
Each component of C_REASON has the type TY_REASON and a value that is equal to
its name: NO_VISIT_ID, NO_CLIENT, NO_CARER, OUTSIDE_HOURS, BAD_DURATION,
TOO_LONG, CARER_OVERLAP, CLIENT_OVERLAP.
- The exception class {{P}}CX_CARE_VISIT exists in package $TMP. It is active.
It inherits from CX_STATIC_CHECK. It has the public read-only attribute
MV_REASON (type C, length 20) and the public read-only attribute MV_VISIT_ID
(type STRING). Its public constructor has the importing parameters IV_REASON
(type C, length 20) and IV_VISIT_ID (type STRING).
- A visit has a visit ID, a client ID, a carer ID, a start hour and an end hour.
The hours are whole numbers from 0 to 23.
- The dispatcher calls the check for one planned visit. The dispatcher also
passes the visits that are already planned for the same day.
- Other programs call the check and catch the exception. They show the reason
and the visit ID to the dispatcher.
# 4. Contract
- Create the class {{P}}CARE_VISIT_CHECKER in package $TMP.
- The class is public, final, and has a public constructor without parameters.
- Public type TY_VISIT: a structure with these components:
VISIT_ID (type STRING), CLIENT_ID (type STRING), CARER_ID (type STRING),
START_HOUR (type I), END_HOUR (type I).
- Public type TT_VISIT: a standard table of TY_VISIT with an empty key.
- Public method CHECK_VISIT:
IMPORTING is_visit TYPE ty_visit
it_plan TYPE tt_visit
RAISING {{P}}cx_care_visit.
- Do not add other public methods.
# 5. Business rules
CHECK_VISIT applies the rules below in this sequence. The first rule that fails
raises the exception {{P}}CX_CARE_VISIT with the reason of that rule and with the
visit ID of the checked visit. If no rule fails, the method returns without an
exception.
1. VISIT_ID must not be empty. Else the reason is NO_VISIT_ID.
2. CLIENT_ID must not be empty. Else the reason is NO_CLIENT.
3. CARER_ID must not be empty. Else the reason is NO_CARER.
4. START_HOUR must be 7 or more. END_HOUR must be 20 or less. Else the reason
is OUTSIDE_HOURS.
5. END_HOUR must be greater than START_HOUR. Else the reason is BAD_DURATION.
6. END_HOUR minus START_HOUR must be 4 or less. Else the reason is TOO_LONG.
7. The visit must not overlap a visit of IT_PLAN with the same CARER_ID. Else
the reason is CARER_OVERLAP.
8. The visit must not overlap a visit of IT_PLAN with the same CLIENT_ID. Else
the reason is CLIENT_OVERLAP.
Two visits overlap when the start hour of the first visit is less than the end
hour of the second visit and the start hour of the second visit is less than the
end hour of the first visit. A visit that starts at the hour when another visit
ends does not overlap that visit.
# 6. Constraints
- Release target: SAP_BASIS 816.
- Coding standards: Clean ABAP. Methods below 40 statements. No global
variables. No comment that restates the code. Use the reason codes of
{{P}}IF_CARE_REASON.
- Out of scope: do not change {{P}}IF_CARE_REASON or {{P}}CX_CARE_VISIT. No
database table, no CDS view, no report, no function module, no object outside
package $TMP.
# 7. Acceptance
- The class is active and has no syntax error.
- The hidden tests pass.
- Write your own ABAP Unit tests for the checker class.

View File

@@ -0,0 +1,60 @@
{
"id": "G1064",
"category": "D",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 70,
"max_activations": 18
},
"seed": [
{
"type": "INTF",
"name": "{{P}}IF_CARE_REASON",
"file": "seed/if_care_reason.intf.abap",
"description": "Reason codes for the care visit check"
},
{
"type": "CLAS",
"name": "{{P}}CX_CARE_VISIT",
"file": "seed/cx_care_visit.clas.abap",
"description": "Exception class that carries the reason code and the visit ID"
}
],
"contract": [
{
"type": "CLAS",
"name": "{{P}}CARE_VISIT_CHECKER"
}
],
"out_of_scope": [
"{{P}}IF_CARE_REASON",
"{{P}}CX_CARE_VISIT",
"No database table, no CDS view, no report, no function module",
"No object outside package $TMP",
"No other public method than CHECK_VISIT"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}D01_HIDDEN",
"file": "hidden/d01_hidden.clas.abap",
"description": "D01 hidden tests for the care visit check"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}CARE_VISIT_CHECKER",
"file": "reference/care_visit_checker.clas.abap",
"description": "Checker for a planned care visit",
"testclasses_file": "reference/care_visit_checker.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"no_global_variables"
]
}