Snapshot: new training tasks (balanced generation), docs

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 22:08:59 +02:00
parent eb13453097
commit 6984fc7917
572 changed files with 30024 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
{
"id": "G1943",
"pool": "train",
"object_type": "STRU",
"category": "B",
"attempts": [
{
"stage": "bundle",
"errors": [
"Too close to task G1903 (similarity spec 0.36, rules 0.42, names 1.00). Choose a different business topic and different object names."
],
"by_check": {
"extra": 1
}
},
{
"stage": "bundle",
"errors": [
"reference/game_stru_test.clas.abap line 60: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"cl_abap_unit_assert\""
],
"by_check": {
"abaplint": 1
}
},
{
"stage": "bundle",
"errors": [
"reference/game_stru_test.clas.abap line 15: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"CLASS\"",
"hidden/game_stru_hidden.clas.abap line 15: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"CLASS\"",
"hidden/game_stru_hidden.clas.abap line 17: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"CLASS\""
],
"by_check": {
"abaplint": 3
}
},
{
"stage": "validate",
"oracle": 0,
"null": 0
}
],
"accepted": false
}

View File

@@ -0,0 +1,159 @@
CLASS {{p}}game_stru_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES: BEGIN OF ty_comp,
name TYPE string,
type TYPE REF TO cl_abap_datadescr,
END OF ty_comp,
ty_comps TYPE STANDARD TABLE OF ty_comp WITH DEFAULT KEY.
CLASS-DATA go_line TYPE REF TO cl_abap_structdescr.
CLASS-METHODS class_setup.
CLASS-METHODS flat_components RETURNING VALUE(rt_comp) TYPE ty_comps.
METHODS structure_exists FOR TESTING.
METHODS field_count FOR TESTING.
METHODS field_names FOR TESTING.
METHODS text_lengths FOR TESTING.
METHODS numc_field FOR TESTING.
METHODS packed_decimals FOR TESTING.
METHODS type_kinds FOR TESTING.
METHODS stamp_structure FOR TESTING.
METHODS stamp_at_end FOR TESTING.
ENDCLASS.
CLASS {{p}}game_stru_hidden IMPLEMENTATION.
METHOD class_setup.
go_line = CAST cl_abap_structdescr(
cl_abap_typedescr=>describe_by_name( '{{P}}GAME_ROUND' ) ).
ENDMETHOD.
METHOD flat_components.
DATA(lt_comp) = go_line->get_components( ).
LOOP AT lt_comp INTO DATA(ls_comp).
TRY.
DATA(lo_sub) = CAST cl_abap_structdescr( ls_comp-type ).
DATA(lt_sub) = lo_sub->get_components( ).
LOOP AT lt_sub INTO DATA(ls_sub).
APPEND VALUE #( name = ls_sub-name type = ls_sub-type ) TO rt_comp.
ENDLOOP.
CATCH cx_sy_move_cast_error.
APPEND VALUE #( name = ls_comp-name type = ls_comp-type ) TO rt_comp.
ENDTRY.
ENDLOOP.
ENDMETHOD.
METHOD structure_exists.
cl_abap_unit_assert=>assert_equals(
exp = abap_true
act = contains( val = to_upper( go_line->absolute_name )
sub = `GAME_ROUND` ) ).
ENDMETHOD.
METHOD field_count.
DATA(lt_comp) = flat_components( ).
cl_abap_unit_assert=>assert_equals( exp = 10 act = lines( lt_comp ) ).
ENDMETHOD.
METHOD field_names.
DATA(lt_comp) = flat_components( ).
DATA(lt_exp) = VALUE string_table(
( `ROUND_ID` ) ( `PLAY_DATE` ) ( `FIELD_NO` ) ( `TEAM_NAME` )
( `PLAYER_COUNT` ) ( `PAINTBALLS` ) ( `ROUND_FEE` ) ( `REFEREE` )
( `LAST_EDITOR` ) ( `LAST_EDIT_ON` ) ).
cl_abap_unit_assert=>assert_equals( exp = lines( lt_exp ) act = lines( lt_comp ) ).
DATA(lv_index) = 0.
LOOP AT lt_comp INTO DATA(ls_comp).
lv_index = lv_index + 1.
cl_abap_unit_assert=>assert_equals(
exp = lt_exp[ lv_index ]
act = to_upper( ls_comp-name )
msg = |Field { lv_index }| ).
ENDLOOP.
ENDMETHOD.
METHOD text_lengths.
DATA(lt_comp) = flat_components( ).
LOOP AT lt_comp INTO DATA(ls_comp).
DATA(lo_elem) = CAST cl_abap_elemdescr( ls_comp-type ).
CASE to_upper( ls_comp-name ).
WHEN 'ROUND_ID'.
cl_abap_unit_assert=>assert_equals( exp = 20 act = lo_elem->length ).
WHEN 'TEAM_NAME'.
cl_abap_unit_assert=>assert_equals( exp = 40 act = lo_elem->length ).
WHEN 'REFEREE'.
cl_abap_unit_assert=>assert_equals( exp = 30 act = lo_elem->length ).
WHEN 'LAST_EDITOR'.
cl_abap_unit_assert=>assert_equals( exp = 24 act = lo_elem->length ).
ENDCASE.
ENDLOOP.
ENDMETHOD.
METHOD numc_field.
DATA(lt_comp) = flat_components( ).
LOOP AT lt_comp INTO DATA(ls_comp).
IF to_upper( ls_comp-name ) = 'FIELD_NO'.
DATA(lo_elem) = CAST cl_abap_elemdescr( ls_comp-type ).
cl_abap_unit_assert=>assert_equals(
exp = `N` act = CONV string( lo_elem->type_kind ) ).
cl_abap_unit_assert=>assert_equals( exp = 4 act = lo_elem->length ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD packed_decimals.
DATA(lt_comp) = flat_components( ).
LOOP AT lt_comp INTO DATA(ls_comp).
IF to_upper( ls_comp-name ) = 'ROUND_FEE'.
DATA(lo_elem) = CAST cl_abap_elemdescr( ls_comp-type ).
cl_abap_unit_assert=>assert_equals(
exp = `P` act = CONV string( lo_elem->type_kind ) ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lo_elem->decimals ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD type_kinds.
DATA(lt_comp) = flat_components( ).
DATA(lt_exp) = VALUE string_table(
( `C` ) ( `D` ) ( `N` ) ( `C` ) ( `I` ) ( `I` ) ( `P` ) ( `C` )
( `C` ) ( `D` ) ).
cl_abap_unit_assert=>assert_equals( exp = lines( lt_exp ) act = lines( lt_comp ) ).
DATA(lv_index) = 0.
LOOP AT lt_comp INTO DATA(ls_comp).
lv_index = lv_index + 1.
cl_abap_unit_assert=>assert_equals(
exp = lt_exp[ lv_index ]
act = CONV string( ls_comp-type->type_kind )
msg = |Type kind of field { lv_index }| ).
ENDLOOP.
ENDMETHOD.
METHOD stamp_structure.
DATA(lo_stamp) = CAST cl_abap_structdescr(
cl_abap_typedescr=>describe_by_name( '{{P}}EDIT_STAMP' ) ).
DATA(lt_comp) = lo_stamp->get_components( ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_comp ) ).
cl_abap_unit_assert=>assert_equals(
exp = `LAST_EDITOR` act = to_upper( lt_comp[ 1 ]-name ) ).
cl_abap_unit_assert=>assert_equals(
exp = `LAST_EDIT_ON` act = to_upper( lt_comp[ 2 ]-name ) ).
DATA(lo_editor) = CAST cl_abap_elemdescr( lt_comp[ 1 ]-type ).
cl_abap_unit_assert=>assert_equals( exp = 24 act = lo_editor->length ).
DATA(lo_edit_on) = CAST cl_abap_elemdescr( lt_comp[ 2 ]-type ).
cl_abap_unit_assert=>assert_equals(
exp = `D` act = CONV string( lo_edit_on->type_kind ) ).
ENDMETHOD.
METHOD stamp_at_end.
DATA(lt_comp) = flat_components( ).
DATA(lv_lines) = lines( lt_comp ).
cl_abap_unit_assert=>assert_equals( exp = 10 act = lv_lines ).
DATA(lv_index) = lv_lines - 1.
DATA(ls_editor) = lt_comp[ lv_index ].
cl_abap_unit_assert=>assert_equals(
exp = `LAST_EDITOR` act = to_upper( ls_editor-name ) ).
DATA(ls_edit_on) = lt_comp[ lv_lines ].
cl_abap_unit_assert=>assert_equals(
exp = `LAST_EDIT_ON` act = to_upper( ls_edit_on-name ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,6 @@
@EndUserText.label : 'Last edit of a game round'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure {{p}}edit_stamp {
last_editor : abap.char(12);
last_edit_on : abap.dats;
}

View File

@@ -0,0 +1,13 @@
@EndUserText.label : 'Line type of the round report'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure {{p}}game_round {
round_id : abap.char(10);
play_date : abap.dats;
field_no : abap.numc(2);
team_name : abap.char(20);
player_count : abap.int4;
paintballs : abap.int4;
round_fee : abap.dec(9,2);
referee : abap.char(15);
include {{p}}edit_stamp;
}

View File

@@ -0,0 +1,77 @@
CLASS {{p}}game_stru_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES: BEGIN OF ty_comp,
name TYPE string,
type TYPE REF TO cl_abap_datadescr,
END OF ty_comp,
ty_comps TYPE STANDARD TABLE OF ty_comp WITH DEFAULT KEY.
CLASS-DATA go_line TYPE REF TO cl_abap_structdescr.
CLASS-METHODS class_setup.
CLASS-METHODS flat_components RETURNING VALUE(rt_comp) TYPE ty_comps.
METHODS ten_fields FOR TESTING.
METHODS field_order FOR TESTING.
METHODS fee_decimals FOR TESTING.
METHODS stamp_structure FOR TESTING.
ENDCLASS.
CLASS {{p}}game_stru_test IMPLEMENTATION.
METHOD class_setup.
go_line = CAST cl_abap_structdescr(
cl_abap_typedescr=>describe_by_name( '{{P}}GAME_ROUND' ) ).
ENDMETHOD.
METHOD flat_components.
DATA(lt_comp) = go_line->get_components( ).
LOOP AT lt_comp INTO DATA(ls_comp).
TRY.
DATA(lo_sub) = CAST cl_abap_structdescr( ls_comp-type ).
DATA(lt_sub) = lo_sub->get_components( ).
LOOP AT lt_sub INTO DATA(ls_sub).
APPEND VALUE #( name = ls_sub-name type = ls_sub-type ) TO rt_comp.
ENDLOOP.
CATCH cx_sy_move_cast_error.
APPEND VALUE #( name = ls_comp-name type = ls_comp-type ) TO rt_comp.
ENDTRY.
ENDLOOP.
ENDMETHOD.
METHOD ten_fields.
DATA(lt_comp) = flat_components( ).
cl_abap_unit_assert=>assert_equals( exp = 10 act = lines( lt_comp ) ).
ENDMETHOD.
METHOD field_order.
DATA(lt_comp) = flat_components( ).
cl_abap_unit_assert=>assert_equals(
exp = `ROUND_ID` act = to_upper( lt_comp[ 1 ]-name ) ).
cl_abap_unit_assert=>assert_equals(
exp = `FIELD_NO` act = to_upper( lt_comp[ 3 ]-name ) ).
cl_abap_unit_assert=>assert_equals(
exp = `LAST_EDIT_ON` act = to_upper( lt_comp[ 10 ]-name ) ).
ENDMETHOD.
METHOD fee_decimals.
DATA(lt_comp) = flat_components( ).
LOOP AT lt_comp INTO DATA(ls_comp).
IF to_upper( ls_comp-name ) = 'ROUND_FEE'.
DATA(lo_elem) = CAST cl_abap_elemdescr( ls_comp-type ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lo_elem->decimals ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD stamp_structure.
DATA(lo_stamp) = CAST cl_abap_structdescr(
cl_abap_typedescr=>describe_by_name( '{{P}}EDIT_STAMP' ) ).
DATA(lt_comp) = lo_stamp->get_components( ).
cl_abap_unit_assert=>assert_equals( exp = 2 act = lines( lt_comp ) ).
cl_abap_unit_assert=>assert_equals(
exp = `LAST_EDITOR` act = to_upper( lt_comp[ 1 ]-name ) ).
cl_abap_unit_assert=>assert_equals(
exp = `LAST_EDIT_ON` act = to_upper( lt_comp[ 2 ]-name ) ).
DATA(lo_editor) = CAST cl_abap_elemdescr( lt_comp[ 1 ]-type ).
cl_abap_unit_assert=>assert_equals( exp = 24 act = lo_editor->length ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,61 @@
# 1. Goal
A paintball arena records each game round that is played on its fields. A round
report and an OData service must show the same line for a round. Both use one
line type. Create this line type as a DDIC structure.
# 2. Open questions
None.
# 3. Context
- The arena plays rounds on numbered fields.
- A round has a round number, a play date, the number of the field, the name of
the visiting team, the number of players, the number of paintballs that the
team used, the fee of the round, and the referee.
- The report and the OData service also show who edited the round last and on
which date.
- All objects are in package $TMP.
# 4. Contract
- Create the DDIC structure {{P}}GAME_ROUND in package $TMP.
- Create the DDIC structure {{P}}EDIT_STAMP in package $TMP.
- {{P}}GAME_ROUND has these fields, in this order:
ROUND_ID, PLAY_DATE, FIELD_NO, TEAM_NAME, PLAYER_COUNT, PAINTBALLS,
ROUND_FEE, REFEREE, LAST_EDITOR, LAST_EDIT_ON.
- The fields LAST_EDITOR and LAST_EDIT_ON also exist on their own in
{{P}}EDIT_STAMP.
# 5. Business rules
1. {{P}}GAME_ROUND is a structure. It has exactly ten fields.
2. ROUND_ID is a character field. Its length is 10.
3. PLAY_DATE is a date field. Its type is DATS.
4. FIELD_NO is a numeric text field. Its length is 2.
5. TEAM_NAME is a character field. Its length is 20.
6. PLAYER_COUNT is an integer field. Its type is INT4.
7. PAINTBALLS is an integer field. Its type is INT4.
8. ROUND_FEE is a packed number. It has 9 digits and 2 decimal places.
9. REFEREE is a character field. Its length is 15.
10. LAST_EDITOR and LAST_EDIT_ON are the last two fields of {{P}}GAME_ROUND.
11. LAST_EDITOR is a character field. Its length is 12.
12. LAST_EDIT_ON is a date field. Its type is DATS.
13. {{P}}EDIT_STAMP is a structure. It has exactly two fields: LAST_EDITOR
(character, length 12) and LAST_EDIT_ON (date, type DATS).
14. {{P}}GAME_ROUND contains the fields of {{P}}EDIT_STAMP at the end. The
fields LAST_EDITOR and LAST_EDIT_ON must not be defined twice.
# 6. Constraints
- Release target: ABAP Platform 2025 (SAP_BASIS 816).
- Coding standards: Clean ABAP.
- Out of scope: no other objects in package $TMP.
# 7. Acceptance
- Both structures are active and have no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests in a global test class. The tests check the two
structures with RTTI.

View File

@@ -0,0 +1,69 @@
{
"id": "G1943",
"category": "B",
"object_type": "STRU",
"difficulty": 3,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [],
"contract": [
{
"type": "STRU",
"name": "{{P}}GAME_ROUND",
"fields": [
"round_id",
"play_date",
"field_no",
"team_name",
"player_count",
"paintballs",
"round_fee",
"referee",
"last_editor",
"last_edit_on"
]
},
{
"type": "STRU",
"name": "{{P}}EDIT_STAMP",
"fields": [
"last_editor",
"last_edit_on"
]
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}GAME_STRU_HIDDEN",
"file": "hidden/game_stru_hidden.clas.abap",
"description": "RTTI checks for the game round structure and the edit stamp structure"
}
],
"reference": [
{
"type": "STRU",
"name": "{{P}}EDIT_STAMP",
"file": "reference/edit_stamp.stru.asabap",
"description": "Last edit of a game round"
},
{
"type": "STRU",
"name": "{{P}}GAME_ROUND",
"file": "reference/game_round.stru.asabap",
"description": "Line type of the round report"
},
{
"type": "CLAS",
"name": "{{P}}GAME_STRU_TEST",
"file": "reference/game_stru_test.clas.abap",
"description": "Own tests for the two structures"
}
],
"craft_checks": []
}