abapgit-agent 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.abapGitAgent.example +11 -0
- package/API.md +271 -0
- package/CLAUDE.md +445 -0
- package/CLAUDE_MEM.md +88 -0
- package/ERROR_HANDLING.md +30 -0
- package/INSTALL.md +160 -0
- package/README.md +127 -0
- package/abap/CLAUDE.md +492 -0
- package/abap/package.devc.xml +10 -0
- package/abap/zcl_abgagt_agent.clas.abap +769 -0
- package/abap/zcl_abgagt_agent.clas.xml +15 -0
- package/abap/zcl_abgagt_cmd_factory.clas.abap +43 -0
- package/abap/zcl_abgagt_cmd_factory.clas.xml +15 -0
- package/abap/zcl_abgagt_command_inspect.clas.abap +192 -0
- package/abap/zcl_abgagt_command_inspect.clas.testclasses.abap +121 -0
- package/abap/zcl_abgagt_command_inspect.clas.xml +16 -0
- package/abap/zcl_abgagt_command_pull.clas.abap +80 -0
- package/abap/zcl_abgagt_command_pull.clas.testclasses.abap +87 -0
- package/abap/zcl_abgagt_command_pull.clas.xml +16 -0
- package/abap/zcl_abgagt_command_unit.clas.abap +297 -0
- package/abap/zcl_abgagt_command_unit.clas.xml +15 -0
- package/abap/zcl_abgagt_resource_health.clas.abap +25 -0
- package/abap/zcl_abgagt_resource_health.clas.xml +15 -0
- package/abap/zcl_abgagt_resource_inspect.clas.abap +62 -0
- package/abap/zcl_abgagt_resource_inspect.clas.xml +15 -0
- package/abap/zcl_abgagt_resource_pull.clas.abap +71 -0
- package/abap/zcl_abgagt_resource_pull.clas.xml +15 -0
- package/abap/zcl_abgagt_resource_unit.clas.abap +64 -0
- package/abap/zcl_abgagt_resource_unit.clas.xml +15 -0
- package/abap/zcl_abgagt_rest_handler.clas.abap +27 -0
- package/abap/zcl_abgagt_rest_handler.clas.xml +15 -0
- package/abap/zcl_abgagt_util.clas.abap +93 -0
- package/abap/zcl_abgagt_util.clas.testclasses.abap +84 -0
- package/abap/zcl_abgagt_util.clas.xml +16 -0
- package/abap/zif_abgagt_agent.intf.abap +134 -0
- package/abap/zif_abgagt_agent.intf.xml +15 -0
- package/abap/zif_abgagt_cmd_factory.intf.abap +7 -0
- package/abap/zif_abgagt_cmd_factory.intf.xml +15 -0
- package/abap/zif_abgagt_command.intf.abap +21 -0
- package/abap/zif_abgagt_command.intf.xml +15 -0
- package/abap/zif_abgagt_util.intf.abap +28 -0
- package/abap/zif_abgagt_util.intf.xml +15 -0
- package/bin/abapgit-agent +902 -0
- package/img/claude.png +0 -0
- package/package.json +31 -0
- package/scripts/claude-integration.js +351 -0
- package/scripts/test-integration.js +139 -0
- package/src/abap-client.js +314 -0
- package/src/agent.js +119 -0
- package/src/config.js +66 -0
- package/src/index.js +48 -0
- package/src/logger.js +39 -0
- package/src/server.js +116 -0
package/abap/CLAUDE.md
ADDED
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
# ABAP Project Guidelines - Template
|
|
2
|
+
|
|
3
|
+
This file provides guidelines for **generating ABAP code** in abapGit repositories.
|
|
4
|
+
|
|
5
|
+
**Use this file as a template**: Copy it to your ABAP repository root when setting up new projects with Claude Code.
|
|
6
|
+
|
|
7
|
+
## ABAP Syntax Validation
|
|
8
|
+
|
|
9
|
+
This is an ABAP project. **Do not attempt local syntax validation** - ABAP code can only be validated in an SAP system.
|
|
10
|
+
|
|
11
|
+
**To validate ABAP code:**
|
|
12
|
+
|
|
13
|
+
1. After generating code, push changes to git
|
|
14
|
+
2. Pull only changed files (fast):
|
|
15
|
+
```bash
|
|
16
|
+
abapgit-agent pull --files abap/zcl_my_class.clas.abap
|
|
17
|
+
```
|
|
18
|
+
Or pull all files:
|
|
19
|
+
```bash
|
|
20
|
+
abapgit-agent pull
|
|
21
|
+
```
|
|
22
|
+
3. Review activation results carefully
|
|
23
|
+
4. **"Error updating where-used list" = SYNTAX ERROR** - This is NOT a warning!
|
|
24
|
+
5. If Failed Objects > 0, there are syntax errors - fix them before proceeding
|
|
25
|
+
|
|
26
|
+
## Fast Iteration Workflow
|
|
27
|
+
|
|
28
|
+
For quick ABAP code changes:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# 1. Make small change to ABAP file
|
|
32
|
+
# 2. Commit and push
|
|
33
|
+
git add abap/zcl_my_class.clas.abap
|
|
34
|
+
git commit -m "fix: ..."
|
|
35
|
+
git push
|
|
36
|
+
|
|
37
|
+
# 3. Pull only changed file (seconds, not minutes)
|
|
38
|
+
abapgit-agent pull --files abap/zcl_my_class.clas.abap
|
|
39
|
+
|
|
40
|
+
# 4. Check for syntax errors (if pull shows "Error updating where-used list")
|
|
41
|
+
abapgit-agent inspect --files abap/zcl_my_class.clas.abap
|
|
42
|
+
|
|
43
|
+
# 5. Repeat until done
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Transport Request Support
|
|
47
|
+
|
|
48
|
+
When working with development packages that require transport requests:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Pull with specific transport request
|
|
52
|
+
abapgit-agent pull --files abap/zcl_my_class.clas.abap --transport DEVK900001
|
|
53
|
+
|
|
54
|
+
# Pull all files with transport request
|
|
55
|
+
abapgit-agent pull --transport DEVK900001
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
If `--transport` is not specified, abapGit will use its default behavior (create a new transport or use the default transport for the user).
|
|
59
|
+
|
|
60
|
+
**Important:** Only run `abapgit-agent pull` when ABAP code has actually changed. If you're only modifying JavaScript, JSON, or markdown files, skip the pull step.
|
|
61
|
+
|
|
62
|
+
**Syntax Check Command:**
|
|
63
|
+
When pull shows "Error updating where-used list", use:
|
|
64
|
+
```bash
|
|
65
|
+
abapgit-agent inspect --files abap/zcl_my_class.clas.abap
|
|
66
|
+
```
|
|
67
|
+
This will show detailed syntax errors including line numbers and error messages.
|
|
68
|
+
|
|
69
|
+
## JSON Handling - ALWAYS Use /ui2/cl_json
|
|
70
|
+
|
|
71
|
+
**CRITICAL**: Always use `/ui2/cl_json` for JSON serialization and deserialization.
|
|
72
|
+
|
|
73
|
+
**Correct:**
|
|
74
|
+
```abap
|
|
75
|
+
" Deserialize JSON to ABAP structure
|
|
76
|
+
DATA ls_data TYPE ty_request.
|
|
77
|
+
ls_data = /ui2/cl_json=>deserialize( json = lv_json ).
|
|
78
|
+
|
|
79
|
+
" Serialize ABAP structure to JSON
|
|
80
|
+
lv_json = /ui2/cl_json=>serialize( data = ls_response ).
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Never use**:
|
|
84
|
+
- Manual string operations (CONCATENATE, SPLIT, etc.)
|
|
85
|
+
- String templates for complex structures
|
|
86
|
+
- Direct assignment without /ui2/cl_json
|
|
87
|
+
|
|
88
|
+
This is enforced by ABAP - manual string operations for JSON parsing will cause type conflicts.
|
|
89
|
+
|
|
90
|
+
## ABAP Class Definition - Must Use PUBLIC
|
|
91
|
+
|
|
92
|
+
**CRITICAL**: Global ABAP classes MUST use `PUBLIC` in the class definition:
|
|
93
|
+
|
|
94
|
+
```abap
|
|
95
|
+
" Correct - global class
|
|
96
|
+
CLASS zcl_my_class DEFINITION PUBLIC.
|
|
97
|
+
...
|
|
98
|
+
ENDCLASS.
|
|
99
|
+
|
|
100
|
+
" Wrong - treated as local class, will fail activation
|
|
101
|
+
CLASS zcl_my_class DEFINITION.
|
|
102
|
+
...
|
|
103
|
+
ENDCLASS.
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Error symptom**: `Error updating where-used list for CLAS ZCL_MY_CLASS`
|
|
107
|
+
|
|
108
|
+
**Fix**: Add `PUBLIC` keyword:
|
|
109
|
+
```abap
|
|
110
|
+
CLASS zcl_my_class DEFINITION PUBLIC. " <- PUBLIC required
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Interface Method Implementation
|
|
114
|
+
|
|
115
|
+
When implementing interface methods in ABAP classes, use the interface prefix:
|
|
116
|
+
|
|
117
|
+
```abap
|
|
118
|
+
" Interface definition
|
|
119
|
+
INTERFACE zif_my_interface PUBLIC.
|
|
120
|
+
METHODS do_something IMPORTING iv_param TYPE string.
|
|
121
|
+
ENDINTERFACE.
|
|
122
|
+
|
|
123
|
+
" Class implementation - use interface prefix
|
|
124
|
+
CLASS zcl_my_class DEFINITION PUBLIC.
|
|
125
|
+
PUBLIC SECTION.
|
|
126
|
+
INTERFACES zif_my_interface.
|
|
127
|
+
ENDCLASS.
|
|
128
|
+
|
|
129
|
+
CLASS zcl_my_class IMPLEMENTATION.
|
|
130
|
+
METHOD zif_my_interface~do_something. " <- Use interface prefix
|
|
131
|
+
" Implementation here
|
|
132
|
+
ENDMETHOD.
|
|
133
|
+
ENDCLASS.
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Wrong**: `METHOD do_something.` - parameter `iv_param` will be unknown
|
|
137
|
+
**Correct**: `METHOD zif_my_interface~do_something.` - parameters recognized
|
|
138
|
+
|
|
139
|
+
## Creating New ABAP Objects - XML Metadata Required
|
|
140
|
+
|
|
141
|
+
**IMPORTANT**: When creating new ABAP objects in abapGit format, you MUST create XML metadata files alongside the `.clas.abap` and `.intf.abap` files.
|
|
142
|
+
|
|
143
|
+
### XML Metadata Format for CLAS
|
|
144
|
+
|
|
145
|
+
For `zcl_abgagt_util.clas.abap`, create `zcl_abgagt_util.clas.xml`:
|
|
146
|
+
|
|
147
|
+
```xml
|
|
148
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
149
|
+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
|
|
150
|
+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
151
|
+
<asx:values>
|
|
152
|
+
<VSEOCLASS>
|
|
153
|
+
<CLSNAME>ZCL_ABGAGT_UTIL</CLSNAME>
|
|
154
|
+
<LANGU>E</LANGU>
|
|
155
|
+
<DESCRIPT>Description</DESCRIPT>
|
|
156
|
+
<EXPOSURE>2</EXPOSURE>
|
|
157
|
+
<STATE>1</STATE>
|
|
158
|
+
<UNICODE>X</UNICODE>
|
|
159
|
+
</VSEOCLASS>
|
|
160
|
+
</asx:values>
|
|
161
|
+
</asx:abap>
|
|
162
|
+
</abapGit>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### XML Metadata Format for INTF
|
|
166
|
+
|
|
167
|
+
For `zif_abgagt_util.intf.abap`, create `zif_abgagt_util.intf.xml`:
|
|
168
|
+
|
|
169
|
+
```xml
|
|
170
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
171
|
+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
|
|
172
|
+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
173
|
+
<asx:values>
|
|
174
|
+
<VSEOINTERF>
|
|
175
|
+
<CLSNAME>ZIF_ABGAGT_UTIL</CLSNAME>
|
|
176
|
+
<LANGU>E</LANGU>
|
|
177
|
+
<DESCRIPT>Description</DESCRIPT>
|
|
178
|
+
<EXPOSURE>2</EXPOSURE>
|
|
179
|
+
<STATE>1</STATE>
|
|
180
|
+
<UNICODE>X</UNICODE>
|
|
181
|
+
</VSEOINTERF>
|
|
182
|
+
</asx:values>
|
|
183
|
+
</asx:abap>
|
|
184
|
+
</abapGit>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Without XML files**, abapGit will NOT recognize the objects during pull, and they won't be activated in the ABAP system.
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# After making changes to ABAP files
|
|
191
|
+
git add .
|
|
192
|
+
git commit -m "Describe changes"
|
|
193
|
+
git push
|
|
194
|
+
|
|
195
|
+
# Validate in ABAP system (single file - fast)
|
|
196
|
+
abapgit-agent pull --files abap/zcl_my_class.clas.abap
|
|
197
|
+
|
|
198
|
+
# Or validate all files
|
|
199
|
+
abapgit-agent pull
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Handling Persistent Syntax Errors
|
|
203
|
+
|
|
204
|
+
When fixing ABAP syntax errors using the commit-pull-commit loop:
|
|
205
|
+
|
|
206
|
+
1. **First 2-3 attempts**: Analyze the error message and try to fix based on the error details
|
|
207
|
+
2. **If errors persist after 2-3 iterations**:
|
|
208
|
+
- Stop repeating the same fix attempts
|
|
209
|
+
- Search the web for the specific ABAP error message or syntax issue
|
|
210
|
+
- Use keywords like "ABAP", the error code, and relevant context
|
|
211
|
+
- Examples: "ABAP error 'XXXX' CLAS", "ABAP syntax MESSAGE is not a declaration"
|
|
212
|
+
3. **After finding information**:
|
|
213
|
+
- Apply the correct fix based on documentation
|
|
214
|
+
- Test again with `abapgit-agent pull`
|
|
215
|
+
|
|
216
|
+
**Never guess** - ABAP syntax is strict. If you're unsure, search first.
|
|
217
|
+
|
|
218
|
+
## Understanding abapgit-agent Output
|
|
219
|
+
|
|
220
|
+
**Critical: Never ignore these messages!**
|
|
221
|
+
|
|
222
|
+
| Message | Meaning | Action Required |
|
|
223
|
+
|---------|---------|-----------------|
|
|
224
|
+
| `Error updating where-used list` | **SYNTAX ERROR** - object has errors | Fix the syntax error |
|
|
225
|
+
| `Failed Objects (N) > 0` | Objects failed to activate | Fix syntax errors |
|
|
226
|
+
| `Success: X` with all objects checked | All good | Proceed |
|
|
227
|
+
|
|
228
|
+
**Example error flow:**
|
|
229
|
+
```
|
|
230
|
+
❌ Pull completed with errors!
|
|
231
|
+
⚠️ Failed Objects (1):
|
|
232
|
+
✗ CLAS ZCL_MY_CLASS: Error updating where-used list
|
|
233
|
+
|
|
234
|
+
Action: The class has syntax errors. Use inspect to get details.
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Check Local Implementation First
|
|
238
|
+
|
|
239
|
+
When implementing new features or fixing issues:
|
|
240
|
+
|
|
241
|
+
1. **Always check local implementations first** - This project already contains working examples of:
|
|
242
|
+
- REST handlers (e.g., `zcl_abgagt_resource_pull`, `zcl_abgagt_resource_inspect`)
|
|
243
|
+
- JSON serialization using `/ui2/cl_json`
|
|
244
|
+
- ABAP object activation patterns
|
|
245
|
+
- Error handling approaches
|
|
246
|
+
|
|
247
|
+
2. **Before inventing something new:**
|
|
248
|
+
- Search the `abap/` folder for similar implementations
|
|
249
|
+
- Look at existing patterns in the codebase
|
|
250
|
+
- Reuse existing helper classes and methods
|
|
251
|
+
- Follow the established code style
|
|
252
|
+
|
|
253
|
+
3. **Examples:**
|
|
254
|
+
- Need to create a new REST endpoint? → Study `zcl_abgagt_resource_pull.clas.abap`
|
|
255
|
+
- Need to serialize JSON? → Use `/ui2/cl_json` as shown in existing handlers
|
|
256
|
+
- Need to query TADIR? → Check how other classes do it
|
|
257
|
+
|
|
258
|
+
**Don't guess patterns** - The codebase has proven implementations. Reuse them.
|
|
259
|
+
|
|
260
|
+
**Common mistakes to avoid:**
|
|
261
|
+
- Using wrong method parameter names (e.g., `set_string_data( iv_data = x )` should be `set_string_data( x )`)
|
|
262
|
+
- Forgetting to use `/ui2/cl_json` for JSON operations
|
|
263
|
+
- Using inline DATA declarations incorrectly
|
|
264
|
+
|
|
265
|
+
## Local Code Reference (Offline Support)
|
|
266
|
+
|
|
267
|
+
When network issues prevent accessing online resources, you can maintain a local folder with ABAP code examples for reference.
|
|
268
|
+
|
|
269
|
+
**Setup:**
|
|
270
|
+
|
|
271
|
+
1. Configure the reference folder path in `.abapGitAgent`:
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"referenceFolder": "<path-to-reference-folder>"
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
2. Clone ABAP repositories for reference into this folder:
|
|
279
|
+
```bash
|
|
280
|
+
# abapGit itself - best reference for ABAP patterns
|
|
281
|
+
git clone https://github.com/abapGit/abapGit.git
|
|
282
|
+
|
|
283
|
+
# ABAP coding style guides (Clean ABAP, code review)
|
|
284
|
+
git clone https://github.com/SAP/styleguides.git
|
|
285
|
+
|
|
286
|
+
# ABAP cheat sheets with code snippets for various topics
|
|
287
|
+
git clone https://github.com/SAP/abap-cheat-sheets.git
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Usage:**
|
|
291
|
+
|
|
292
|
+
- When Claude needs to reference ABAP patterns, read files from the folder configured in `.abapGitAgent` (`referenceFolder`)
|
|
293
|
+
- Useful for offline development or when network is unreliable
|
|
294
|
+
- Keep commonly used ABAP utilities, class patterns, and examples
|
|
295
|
+
|
|
296
|
+
## ABAP Object Types
|
|
297
|
+
|
|
298
|
+
Common object types in this project:
|
|
299
|
+
- `CLAS` - Classes
|
|
300
|
+
- `PROG` - Programs
|
|
301
|
+
- `FUGR` - Function Groups
|
|
302
|
+
- `INTF` - Interfaces
|
|
303
|
+
- `TABL` - Tables
|
|
304
|
+
- `DDLS` - Data Definitions
|
|
305
|
+
|
|
306
|
+
## Naming Conventions
|
|
307
|
+
|
|
308
|
+
- Use `Z_` or `Y_` prefix for custom objects
|
|
309
|
+
- Class names: `ZCL_<NAME>`
|
|
310
|
+
- Interface names: `ZIF_<NAME>`
|
|
311
|
+
- Programs: `Z<NAME>`
|
|
312
|
+
- Package: `$<PROJECT_NAME>`
|
|
313
|
+
|
|
314
|
+
## Command Factory Pattern
|
|
315
|
+
|
|
316
|
+
### Command Class Naming
|
|
317
|
+
Command implementations should follow the naming convention:
|
|
318
|
+
- `ZCL_ABGAGT_COMMAND_<COMMAND>` where `<COMMAND>` is PULL, INSPECT, UNIT, etc.
|
|
319
|
+
|
|
320
|
+
Example:
|
|
321
|
+
```abap
|
|
322
|
+
CLASS zcl_abgagt_command_pull DEFINITION PUBLIC FINAL CREATE PUBLIC.
|
|
323
|
+
PUBLIC SECTION.
|
|
324
|
+
INTERFACES zif_abgagt_command.
|
|
325
|
+
ENDCLASS.
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Command Interface
|
|
329
|
+
Commands implement `ZIF_ABGAGT_COMMAND` with constants:
|
|
330
|
+
|
|
331
|
+
```abap
|
|
332
|
+
INTERFACE zif_abgagt_command PUBLIC.
|
|
333
|
+
CONSTANTS:
|
|
334
|
+
gc_pull TYPE string VALUE 'PULL',
|
|
335
|
+
gc_inspect TYPE string VALUE 'INSPECT',
|
|
336
|
+
gc_unit TYPE string VALUE 'UNIT'.
|
|
337
|
+
|
|
338
|
+
METHODS get_name RETURNING VALUE(rv_name) TYPE string.
|
|
339
|
+
METHODS execute IMPORTING it_files TYPE string_table
|
|
340
|
+
RETURNING VALUE(rv_result) TYPE string.
|
|
341
|
+
ENDINTERFACE.
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Factory with Dynamic Object Creation
|
|
345
|
+
Use dynamic object creation to avoid syntax errors in one command affecting others:
|
|
346
|
+
|
|
347
|
+
```abap
|
|
348
|
+
CLASS zcl_abgagt_cmd_factory DEFINITION PUBLIC CREATE PRIVATE.
|
|
349
|
+
PUBLIC SECTION.
|
|
350
|
+
INTERFACES zif_abgagt_cmd_factory.
|
|
351
|
+
CLASS-METHODS get_instance
|
|
352
|
+
RETURNING VALUE(ro_factory) TYPE REF TO zif_abgagt_cmd_factory.
|
|
353
|
+
PRIVATE SECTION.
|
|
354
|
+
TYPES: BEGIN OF ty_command_map,
|
|
355
|
+
command TYPE string,
|
|
356
|
+
class_name TYPE string,
|
|
357
|
+
END OF ty_command_map.
|
|
358
|
+
DATA mt_command_map TYPE TABLE OF ty_command_map.
|
|
359
|
+
ENDCLASS.
|
|
360
|
+
|
|
361
|
+
CLASS zcl_abgagt_cmd_factory IMPLEMENTATION.
|
|
362
|
+
METHOD constructor.
|
|
363
|
+
mt_command_map = VALUE #(
|
|
364
|
+
( command = zif_abgagt_command=>gc_pull class_name = 'ZCL_ABGAGT_COMMAND_PULL' )
|
|
365
|
+
( command = zif_abgagt_command=>gc_inspect class_name = 'ZCL_ABGAGT_COMMAND_INSPECT' )
|
|
366
|
+
( command = zif_abgagt_command=>gc_unit class_name = 'ZCL_ABGAGT_COMMAND_UNIT' )
|
|
367
|
+
).
|
|
368
|
+
ENDMETHOD.
|
|
369
|
+
|
|
370
|
+
METHOD zif_abgagt_cmd_factory~get_command.
|
|
371
|
+
READ TABLE mt_command_map WITH KEY command = iv_command
|
|
372
|
+
ASSIGNING FIELD-SYMBOL(<ls_map>).
|
|
373
|
+
IF sy-subrc = 0.
|
|
374
|
+
CREATE OBJECT ro_command TYPE (<ls_map>-class_name).
|
|
375
|
+
ENDIF.
|
|
376
|
+
ENDMETHOD.
|
|
377
|
+
ENDCLASS.
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
**Benefits:**
|
|
381
|
+
- Factory class activates independently of command classes
|
|
382
|
+
- Syntax errors in one command don't affect others
|
|
383
|
+
- Add new commands by updating the mapping table
|
|
384
|
+
|
|
385
|
+
## Best Practices
|
|
386
|
+
|
|
387
|
+
### Always Return Interface Types, Not Class Types
|
|
388
|
+
|
|
389
|
+
When defining factory methods or creating objects, return the interface type, not the class type:
|
|
390
|
+
|
|
391
|
+
```abap
|
|
392
|
+
" WRONG - returns concrete class
|
|
393
|
+
CLASS-METHODS get_instance
|
|
394
|
+
RETURNING VALUE(ro_factory) TYPE REF TO zcl_abgagt_cmd_factory.
|
|
395
|
+
|
|
396
|
+
" CORRECT - returns interface type
|
|
397
|
+
CLASS-METHODS get_instance
|
|
398
|
+
RETURNING VALUE(ro_factory) TYPE REF TO zif_abgagt_cmd_factory.
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
**Why?** Interface types provide better abstraction, easier testing, and follow the dependency inversion principle. Callers depend on the interface (abstraction), not the concrete class.
|
|
402
|
+
|
|
403
|
+
## Unit Testing with Local Test Classes
|
|
404
|
+
|
|
405
|
+
### File Structure
|
|
406
|
+
|
|
407
|
+
For ABAP local unit tests, use a **separate file** with `.testclasses.abap` extension:
|
|
408
|
+
|
|
409
|
+
```
|
|
410
|
+
abap/
|
|
411
|
+
zcl_my_class.clas.abap <- Main class (no test code)
|
|
412
|
+
zcl_my_class.clas.testclasses.abap <- Local test class
|
|
413
|
+
zcl_my_class.clas.xml <- XML with WITH_UNIT_TESTS = X
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Required Elements
|
|
417
|
+
|
|
418
|
+
1. **Test class file** (`zcl_my_class.clas.testclasses.abap`):
|
|
419
|
+
```abap
|
|
420
|
+
*"* use this source file for your test class implementation
|
|
421
|
+
*"* local test class
|
|
422
|
+
CLASS ltcl_zcl_my_class DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
|
|
423
|
+
PRIVATE SECTION.
|
|
424
|
+
DATA mo_cut TYPE REF TO zcl_my_class.
|
|
425
|
+
METHODS setup.
|
|
426
|
+
METHODS test_method1 FOR TESTING.
|
|
427
|
+
METHODS test_method2 FOR TESTING.
|
|
428
|
+
ENDCLASS.
|
|
429
|
+
|
|
430
|
+
CLASS ltcl_zcl_my_class IMPLEMENTATION.
|
|
431
|
+
METHOD setup.
|
|
432
|
+
CREATE OBJECT mo_cut.
|
|
433
|
+
ENDMETHOD.
|
|
434
|
+
METHOD test_method1.
|
|
435
|
+
" Test code using cl_abap_unit_assert
|
|
436
|
+
ENDMETHOD.
|
|
437
|
+
ENDCLASS.
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
2. **XML metadata** (`zcl_my_class.clas.xml`):
|
|
441
|
+
```xml
|
|
442
|
+
<VSEOCLASS>
|
|
443
|
+
...
|
|
444
|
+
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
|
|
445
|
+
</VSEOCLASS>
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Naming Conventions
|
|
449
|
+
|
|
450
|
+
- Test class name: `LTCL_ZCL_<CLASSNAME>` (e.g., `LTCL_ZCL_COMMAND_PULL`)
|
|
451
|
+
- Test methods: `TEST_<methodname> FOR TESTING` or simply `test_method FOR TESTING`
|
|
452
|
+
- Test file: `<classname>.clas.testclasses.abap`
|
|
453
|
+
|
|
454
|
+
### CRITICAL: Method Name Length Limit
|
|
455
|
+
|
|
456
|
+
**Test method names MUST NOT exceed 30 characters!**
|
|
457
|
+
|
|
458
|
+
```abap
|
|
459
|
+
" WRONG - 34 characters (syntax error)
|
|
460
|
+
METHODS test_execute_with_minimal_params FOR TESTING.
|
|
461
|
+
|
|
462
|
+
" CORRECT - 18 characters
|
|
463
|
+
METHODS test_exec_minimal FOR TESTING.
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Examples of compliant names:
|
|
467
|
+
- `test_get_name` (13 chars)
|
|
468
|
+
- `test_exec_minimal` (18 chars)
|
|
469
|
+
- `test_exec_files` (16 chars)
|
|
470
|
+
- `test_interface` (15 chars)
|
|
471
|
+
|
|
472
|
+
### Common Assertions
|
|
473
|
+
|
|
474
|
+
```abap
|
|
475
|
+
cl_abap_unit_assert=>assert_equals( act = lv_actual exp = lv_expected msg = 'Error message' ).
|
|
476
|
+
cl_abap_unit_assert=>assert_not_initial( act = lv_data msg = 'Should not be initial' ).
|
|
477
|
+
cl_abap_unit_assert=>assert_bound( act = lo_ref msg = 'Should be bound' ).
|
|
478
|
+
cl_abap_unit_assert=>assert_true( act = lv_bool msg = 'Should be true' ).
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### What NOT To Do
|
|
482
|
+
|
|
483
|
+
- ❌ Don't add test methods directly in the main `.clas.abap` file
|
|
484
|
+
- ❌ Don't use `CLASS ... DEFINITION ...` without the special comment header
|
|
485
|
+
- ❌ Don't reference `<TESTCLASS>` in XML - abapGit auto-detects `.testclasses.abap`
|
|
486
|
+
- ❌ Don't use nested local classes inside the main class definition
|
|
487
|
+
|
|
488
|
+
### Running Tests
|
|
489
|
+
|
|
490
|
+
In ABAP: SE24 → Test → Execute Unit Tests
|
|
491
|
+
|
|
492
|
+
Or via abapGit: Pull the files and run tests in the ABAP system.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DEVC" serializer_version="v1.0.0">
|
|
3
|
+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
4
|
+
<asx:values>
|
|
5
|
+
<DEVC>
|
|
6
|
+
<CTEXT>ABAP AI Bridge - Package for git pull and activate agent</CTEXT>
|
|
7
|
+
</DEVC>
|
|
8
|
+
</asx:values>
|
|
9
|
+
</asx:abap>
|
|
10
|
+
</abapGit>
|