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,33 @@
{
"id": "G1952",
"pool": "train",
"object_type": "TABL",
"category": "B",
"attempts": [
{
"stage": "bundle",
"errors": [
"hidden/t16_hidden.clas.abap line 70: syntax error for release v758 (abaplint): Statement does not exist in the configured ABAP version(or a parser error), \"DATA\""
],
"by_check": {
"abaplint": 1
}
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 69.0,
"null": 0
},
{
"stage": "validate",
"oracle": 85.0,
"null": 0
}
],
"accepted": false
}

View File

@@ -0,0 +1,212 @@
CLASS {{p}}t16_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
TYPES ty_fields TYPE STANDARD TABLE OF dfies WITH EMPTY KEY.
TYPES ty_fieldname TYPE c LENGTH 30.
TYPES ty_datatype TYPE c LENGTH 4.
TYPES ty_flag TYPE c LENGTH 1.
CLASS-DATA go_env TYPE REF TO if_osql_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS setup.
METHODS field_names FOR TESTING.
METHODS key_fields FOR TESTING.
METHODS field_attributes FOR TESTING.
METHODS insert_and_read FOR TESTING.
METHODS read_by_date FOR TESTING.
METHODS get_fields RETURNING VALUE(rt_fields) TYPE ty_fields.
METHODS get_field
IMPORTING it_fields TYPE ty_fields
iv_name TYPE ty_fieldname
RETURNING VALUE(rs_field) TYPE dfies.
METHODS assert_present
IMPORTING it_fields TYPE ty_fields
iv_name TYPE ty_fieldname.
METHODS assert_key
IMPORTING it_fields TYPE ty_fields
iv_name TYPE ty_fieldname
iv_key TYPE ty_flag.
METHODS assert_field
IMPORTING it_fields TYPE ty_fields
iv_name TYPE ty_fieldname
iv_type TYPE ty_datatype
iv_leng TYPE i
iv_decimals TYPE i.
METHODS to_struct_descr
IMPORTING io_descr TYPE REF TO cl_abap_typedescr
RETURNING VALUE(ro_struct) TYPE REF TO cl_abap_structdescr.
ENDCLASS.
CLASS {{p}}t16_hidden IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}SESS' ) ) ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD setup.
go_env->clear_doubles( ).
ENDMETHOD.
METHOD get_fields.
DATA lo_struct TYPE REF TO cl_abap_structdescr.
lo_struct = to_struct_descr( cl_abap_typedescr=>describe_by_name( '{{P}}SESS' ) ).
rt_fields = lo_struct->get_ddic_field_list( ).
ENDMETHOD.
METHOD to_struct_descr.
DATA lo_table TYPE REF TO cl_abap_tabledescr.
TRY.
ro_struct = CAST cl_abap_structdescr( io_descr ).
CATCH cx_sy_move_cast_error.
lo_table = CAST cl_abap_tabledescr( io_descr ).
ro_struct = CAST cl_abap_structdescr( lo_table->get_table_line_type( ) ).
ENDTRY.
ENDMETHOD.
METHOD get_field.
READ TABLE it_fields INTO rs_field WITH KEY fieldname = iv_name.
cl_abap_unit_assert=>assert_equals(
exp = 0
act = sy-subrc
msg = |Field { iv_name } is missing in table {{P}}SESS| ).
ENDMETHOD.
METHOD assert_present.
DATA ls_field TYPE dfies.
READ TABLE it_fields INTO ls_field WITH KEY fieldname = iv_name.
cl_abap_unit_assert=>assert_equals(
exp = 0
act = sy-subrc
msg = |Field { iv_name } is missing in table {{P}}SESS| ).
ENDMETHOD.
METHOD assert_key.
DATA ls_field TYPE dfies.
DATA lv_flag TYPE ty_flag.
ls_field = get_field( it_fields = it_fields iv_name = iv_name ).
lv_flag = ls_field-keyflag.
cl_abap_unit_assert=>assert_equals(
exp = iv_key
act = lv_flag
msg = |Wrong key flag of field { iv_name }| ).
ENDMETHOD.
METHOD assert_field.
DATA ls_field TYPE dfies.
DATA lv_leng TYPE i.
DATA lv_decimals TYPE i.
ls_field = get_field( it_fields = it_fields iv_name = iv_name ).
lv_leng = ls_field-leng.
lv_decimals = ls_field-decimals.
cl_abap_unit_assert=>assert_equals( exp = iv_leng act = lv_leng
msg = |Wrong length of { iv_name }| ).
cl_abap_unit_assert=>assert_equals( exp = iv_decimals act = lv_decimals
msg = |Wrong decimals of { iv_name }| ).
cl_abap_unit_assert=>assert_equals( exp = iv_type act = ls_field-datatype
msg = |Wrong type of { iv_name }| ).
ENDMETHOD.
METHOD field_names.
DATA lt_fields TYPE ty_fields.
lt_fields = get_fields( ).
cl_abap_unit_assert=>assert_equals( exp = 10 act = lines( lt_fields )
msg = 'Wrong number of fields in {{P}}SESS' ).
assert_present( it_fields = lt_fields iv_name = 'CLIENT' ).
assert_present( it_fields = lt_fields iv_name = 'STUDIO_ID' ).
assert_present( it_fields = lt_fields iv_name = 'SESSION_NO' ).
assert_present( it_fields = lt_fields iv_name = 'CUSTOMER' ).
assert_present( it_fields = lt_fields iv_name = 'SESSION_DATE' ).
assert_present( it_fields = lt_fields iv_name = 'BOOKED_HOURS' ).
assert_present( it_fields = lt_fields iv_name = 'RATE_MODE' ).
assert_present( it_fields = lt_fields iv_name = 'TARIFF_GROUP' ).
assert_present( it_fields = lt_fields iv_name = 'TRACK_COUNT' ).
assert_present( it_fields = lt_fields iv_name = 'SESSION_VALUE' ).
ENDMETHOD.
METHOD key_fields.
DATA lt_fields TYPE ty_fields.
lt_fields = get_fields( ).
assert_key( it_fields = lt_fields iv_name = 'CLIENT' iv_key = 'X' ).
assert_key( it_fields = lt_fields iv_name = 'STUDIO_ID' iv_key = 'X' ).
assert_key( it_fields = lt_fields iv_name = 'SESSION_NO' iv_key = 'X' ).
assert_key( it_fields = lt_fields iv_name = 'CUSTOMER' iv_key = ' ' ).
assert_key( it_fields = lt_fields iv_name = 'SESSION_DATE' iv_key = ' ' ).
assert_key( it_fields = lt_fields iv_name = 'BOOKED_HOURS' iv_key = ' ' ).
assert_key( it_fields = lt_fields iv_name = 'RATE_MODE' iv_key = ' ' ).
assert_key( it_fields = lt_fields iv_name = 'TARIFF_GROUP' iv_key = ' ' ).
assert_key( it_fields = lt_fields iv_name = 'TRACK_COUNT' iv_key = ' ' ).
assert_key( it_fields = lt_fields iv_name = 'SESSION_VALUE' iv_key = ' ' ).
ENDMETHOD.
METHOD field_attributes.
DATA lt_fields TYPE ty_fields.
lt_fields = get_fields( ).
assert_field( it_fields = lt_fields iv_name = 'CLIENT' iv_type = 'CLNT'
iv_leng = 3 iv_decimals = 0 ).
assert_field( it_fields = lt_fields iv_name = 'STUDIO_ID' iv_type = 'CHAR'
iv_leng = 4 iv_decimals = 0 ).
assert_field( it_fields = lt_fields iv_name = 'SESSION_NO' iv_type = 'NUMC'
iv_leng = 6 iv_decimals = 0 ).
assert_field( it_fields = lt_fields iv_name = 'CUSTOMER' iv_type = 'CHAR'
iv_leng = 10 iv_decimals = 0 ).
assert_field( it_fields = lt_fields iv_name = 'SESSION_DATE' iv_type = 'DATS'
iv_leng = 8 iv_decimals = 0 ).
assert_field( it_fields = lt_fields iv_name = 'BOOKED_HOURS' iv_type = 'DEC'
iv_leng = 5 iv_decimals = 2 ).
assert_field( it_fields = lt_fields iv_name = 'RATE_MODE' iv_type = 'CHAR'
iv_leng = 4 iv_decimals = 0 ).
assert_field( it_fields = lt_fields iv_name = 'TARIFF_GROUP' iv_type = 'CHAR'
iv_leng = 4 iv_decimals = 0 ).
assert_field( it_fields = lt_fields iv_name = 'TRACK_COUNT' iv_type = 'INT4'
iv_leng = 10 iv_decimals = 0 ).
assert_field( it_fields = lt_fields iv_name = 'SESSION_VALUE' iv_type = 'DEC'
iv_leng = 15 iv_decimals = 2 ).
ENDMETHOD.
METHOD insert_and_read.
DATA lt_sess TYPE STANDARD TABLE OF {{p}}sess WITH EMPTY KEY.
DATA lv_day TYPE d.
lv_day = '20250110'.
lt_sess = VALUE #(
( client = sy-mandt studio_id = 'R1' session_no = '000001'
customer = 'CUST01' session_date = lv_day booked_hours = '3.50'
rate_mode = 'STD' tariff_group = 'A' track_count = 8
session_value = '450.00' ) ).
go_env->insert_test_data( lt_sess ).
SELECT SINGLE * FROM {{p}}sess WHERE studio_id = 'R1' AND session_no = '000001'
INTO @DATA(ls_read).
cl_abap_unit_assert=>assert_equals( exp = 0 act = sy-subrc ).
cl_abap_unit_assert=>assert_equals( exp = 'CUST01' act = ls_read-customer ).
cl_abap_unit_assert=>assert_equals( exp = lv_day act = ls_read-session_date ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '3.50' )
act = CONV decfloat34( ls_read-booked_hours ) ).
cl_abap_unit_assert=>assert_equals( exp = 'STD' act = ls_read-rate_mode ).
cl_abap_unit_assert=>assert_equals( exp = 'A' act = ls_read-tariff_group ).
cl_abap_unit_assert=>assert_equals( exp = 8 act = ls_read-track_count ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '450.00' )
act = CONV decfloat34( ls_read-session_value ) ).
ENDMETHOD.
METHOD read_by_date.
DATA lt_sess TYPE STANDARD TABLE OF {{p}}sess WITH EMPTY KEY.
DATA lv_day TYPE d.
lv_day = '20250301'.
lt_sess = VALUE #(
( client = sy-mandt studio_id = 'R1' session_no = '000010'
customer = 'CUST10' session_date = lv_day booked_hours = '1.00'
rate_mode = 'STD' tariff_group = 'A' track_count = 1
session_value = '80.00' )
( client = sy-mandt studio_id = 'R2' session_no = '000011'
customer = 'CUST11' session_date = '20250302' booked_hours = '2.00'
rate_mode = 'STD' tariff_group = 'A' track_count = 2
session_value = '160.00' ) ).
go_env->insert_test_data( lt_sess ).
SELECT COUNT(*) FROM {{p}}sess WHERE session_date = @lv_day INTO @DATA(lv_count).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_count ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,17 @@
@EndUserText.label : 'Recording session'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}sess {
key client : abap.clnt not null;
key studio_id : abap.char(4) not null;
key session_no : abap.numc(6) not null;
customer : abap.char(10);
session_date : abap.dats;
booked_hours : abap.dec(5,2);
rate_mode : abap.char(4);
tariff_group : abap.char(4);
track_count : abap.int4;
session_value : abap.dec(15,2);
}

View File

@@ -0,0 +1,75 @@
CLASS {{p}}t16_test DEFINITION PUBLIC FINAL CREATE PUBLIC
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 setup.
METHODS stores_and_reads FOR TESTING.
METHODS rejects_duplicate FOR TESTING.
METHODS counts_by_date FOR TESTING.
ENDCLASS.
CLASS {{p}}t16_test IMPLEMENTATION.
METHOD class_setup.
go_env = cl_osql_test_environment=>create( i_dependency_list = VALUE #( ( '{{P}}SESS' ) ) ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD setup.
go_env->clear_doubles( ).
ENDMETHOD.
METHOD stores_and_reads.
DATA lt_sess TYPE STANDARD TABLE OF {{p}}sess WITH EMPTY KEY.
lt_sess = VALUE #(
( client = sy-mandt studio_id = 'R1' session_no = '000001'
customer = 'CUST01' session_date = '20250110' booked_hours = '3.50'
rate_mode = 'STD' tariff_group = 'A' track_count = 8
session_value = '450.00' ) ).
go_env->insert_test_data( lt_sess ).
SELECT SINGLE * FROM {{p}}sess WHERE studio_id = 'R1' AND session_no = '000001'
INTO @DATA(ls_read).
cl_abap_unit_assert=>assert_equals( exp = 0 act = sy-subrc ).
cl_abap_unit_assert=>assert_equals( exp = 'CUST01' act = ls_read-customer ).
cl_abap_unit_assert=>assert_equals( exp = 8 act = ls_read-track_count ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '3.50' )
act = CONV decfloat34( ls_read-booked_hours ) ).
ENDMETHOD.
METHOD rejects_duplicate.
DATA lt_sess TYPE STANDARD TABLE OF {{p}}sess WITH EMPTY KEY.
lt_sess = VALUE #(
( client = sy-mandt studio_id = 'R9' session_no = '000009'
customer = 'CUST09' session_date = '20250401' booked_hours = '1.00'
rate_mode = 'STD' tariff_group = 'A' track_count = 1
session_value = '80.00' ) ).
INSERT {{p}}sess FROM TABLE @lt_sess.
cl_abap_unit_assert=>assert_equals( exp = 0 act = sy-subrc ).
INSERT {{p}}sess FROM TABLE @lt_sess.
cl_abap_unit_assert=>assert_equals( exp = 4 act = sy-subrc ).
ENDMETHOD.
METHOD counts_by_date.
DATA lt_sess TYPE STANDARD TABLE OF {{p}}sess WITH EMPTY KEY.
DATA lv_day TYPE d.
lv_day = '20250301'.
lt_sess = VALUE #(
( client = sy-mandt studio_id = 'R1' session_no = '000010'
customer = 'CUST10' session_date = lv_day booked_hours = '1.00'
rate_mode = 'STD' tariff_group = 'A' track_count = 1
session_value = '80.00' )
( client = sy-mandt studio_id = 'R2' session_no = '000011'
customer = 'CUST11' session_date = '20250302' booked_hours = '2.00'
rate_mode = 'STD' tariff_group = 'A' track_count = 2
session_value = '160.00' ) ).
go_env->insert_test_data( lt_sess ).
SELECT COUNT(*) FROM {{p}}sess WHERE session_date = @lv_day INTO @DATA(lv_count).
cl_abap_unit_assert=>assert_equals( exp = 1 act = lv_count ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,59 @@
# 1. Goal
The recording studio "Blue Room" rents its rooms to customers by the hour. Store
every recording session in one database table. The booking desk, an invoicing
program and an OData service read the same table.
# 2. Open questions
None.
# 3. Context
- The studio has several rooms. Each room has a room code of 4 characters.
- A customer books a session in a room. The studio numbers the sessions of a
room from 000001.
- For each session the studio records the date, the booked hours, the rate mode,
the tariff group, the number of recorded tracks and the value of the session.
- The table is client-dependent. The client field is the first key field.
- The table is in package $TMP.
# 4. Contract
- Create the transparent database table {{P}}SESS in package $TMP.
- The table has these fields, in this order: client, studio_id, session_no,
customer, session_date, booked_hours, rate_mode, tariff_group, track_count,
session_value.
- The key fields are client, studio_id and session_no.
- The table has no other fields.
# 5. Business rules
1. The fields have the names, the types and the lengths of this table:
| Field | Type | Length | Decimals | Key |
| --- | --- | --- | --- | --- |
| client | abap.clnt | 3 | 0 | yes |
| studio_id | abap.char | 4 | 0 | yes |
| session_no | abap.numc | 6 | 0 | yes |
| customer | abap.char | 10 | 0 | no |
| session_date | abap.dats | 8 | 0 | no |
| booked_hours | abap.dec | 5 | 2 | no |
| rate_mode | abap.char | 4 | 0 | no |
| tariff_group | abap.char | 4 | 0 | no |
| track_count | abap.int4 | 10 | 0 | no |
| session_value | abap.dec | 15 | 2 | no |
2. The combination of client, studio_id and session_no is the key of the table.
This combination occurs at most once in the table.
3. booked_hours is the number of booked hours with 2 decimal places.
4. session_value is the value of one session with 2 decimal places.
5. The field names are not ABAP SQL reserved words. Words such as HOURS, MODE,
ORDER, DATE, COUNT, GROUP and VALUE are not permitted as field names. Use the
names of the contract.
# 6. Constraints
- Release target: SAP_BASIS 816 (ABAP Platform 2025).
- Package $TMP. Do not use transports.
- Use Clean ABAP.
- Out of scope: do not create or change other objects.
# 7. Acceptance
- The table is active and has no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests in a global test class. Use CL_OSQL_TEST_ENVIRONMENT.

View File

@@ -0,0 +1,55 @@
{
"id": "G1952",
"category": "B",
"object_type": "TABL",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [],
"contract": [
{
"type": "TABL",
"name": "{{P}}SESS",
"fields": [
"client",
"studio_id",
"session_no",
"customer",
"session_date",
"booked_hours",
"rate_mode",
"tariff_group",
"track_count",
"session_value"
]
}
],
"out_of_scope": [],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T16_HIDDEN",
"file": "hidden/t16_hidden.clas.abap",
"description": "RTTI checks on {{P}}SESS and CL_OSQL_TEST_ENVIRONMENT checks"
}
],
"reference": [
{
"type": "TABL",
"name": "{{P}}SESS",
"file": "reference/sess.tabl.asabap",
"description": "Recording sessions of the studio"
},
{
"type": "CLAS",
"name": "{{P}}T16_TEST",
"file": "reference/t16_test.clas.abap",
"description": "Own tests for {{P}}SESS"
}
],
"craft_checks": []
}