@mcp-abap-adt/adt-clients 37.0.0 → 37.1.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/README.md +23 -1
- package/dist/core/class/index.d.ts +1 -1
- package/dist/core/class/index.d.ts.map +1 -1
- package/dist/core/class/index.js +2 -1
- package/dist/core/class/run.d.ts +35 -0
- package/dist/core/class/run.d.ts.map +1 -1
- package/dist/core/class/run.js +88 -0
- package/dist/executors/class/ClassTestRunner.d.ts +27 -1
- package/dist/executors/class/ClassTestRunner.d.ts.map +1 -1
- package/dist/executors/class/ClassTestRunner.js +31 -0
- package/dist/executors/class/ClassTestRunnerLegacy.d.ts +6 -0
- package/dist/executors/class/ClassTestRunnerLegacy.d.ts.map +1 -1
- package/dist/executors/class/ClassTestRunnerLegacy.js +12 -5
- package/package.json +1 -1
- package/dist/core/class/runLegacy.d.ts +0 -42
- package/dist/core/class/runLegacy.d.ts.map +0 -1
- package/dist/core/class/runLegacy.js +0 -74
package/README.md
CHANGED
|
@@ -157,7 +157,7 @@ npm install @mcp-abap-adt/adt-clients
|
|
|
157
157
|
- Typed execution API based on `IExecutor`
|
|
158
158
|
- Executors:
|
|
159
159
|
- `getClassExecutor()` for `classrun`
|
|
160
|
-
- `getClassTestRunner()` for a class's ABAP Unit tests: `run`, `getStatus`, `getResult`
|
|
160
|
+
- `getClassTestRunner()` for a class's ABAP Unit tests: `run`, `getStatus`, `getResult` (asynchronous, the default), or `runSync` (synchronous)
|
|
161
161
|
- `getProgramTestRunner()` for a report's ABAP Unit tests, in its source or its includes
|
|
162
162
|
- `getFunctionGroupTestRunner()` / `getFunctionModuleTestRunner()` for a function group's tests, or the ones exercising one module
|
|
163
163
|
- `getProgramExecutor()` for `programrun` (on-premise systems)
|
|
@@ -440,6 +440,28 @@ const result = await runner.getResult(runId, { analyse: analyseUnitTest });
|
|
|
440
440
|
`{ containerClass, testClass }`. On a legacy system the runner's `run` answers
|
|
441
441
|
the finished result, and `getStatus`/`getResult` refuse without a request.
|
|
442
442
|
|
|
443
|
+
**The synchronous runner, `runSync`.** `run` starts a run on
|
|
444
|
+
`/sap/bc/adt/abapunit/runs`, which is then polled; that stays the default.
|
|
445
|
+
`runSync` is the other runner ADT has — one `POST /sap/bc/adt/abapunit/testruns`
|
|
446
|
+
answering the finished `aunit:runResult` — chosen explicitly by the caller.
|
|
447
|
+
Some systems have only this one (an on-prem S/4HANA 2023, SAP_BASIS 758, was
|
|
448
|
+
measured without `/abapunit/runs`); whether a system has `/runs` is in its
|
|
449
|
+
discovery, and reading that is the caller's — the library picks no runner by
|
|
450
|
+
release or by discovery.
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
const result = await runner.runSync('ZCL_UNDER_TEST', { analyse: analyseUnitTest });
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Its answer is read by the runner's `result` strategy, the one `getResult` uses:
|
|
457
|
+
on the measured systems (on premise and ABAP Cloud, 2026-10-22) both runners
|
|
458
|
+
answer the same document — `aunit:runResult` in `http://www.sap.com/adt/aunit`
|
|
459
|
+
— with the same methods and alerts. Two differences: the endpoint addresses
|
|
460
|
+
whole classes, so `{ containerClass, testClass }` targets run each distinct
|
|
461
|
+
container whole; and `title` and `context` are not sent. Scope, risk levels and
|
|
462
|
+
durations are, with `run`'s defaults. On a legacy system `runSync` is the
|
|
463
|
+
request `run` already sends there, read by `result`.
|
|
464
|
+
|
|
443
465
|
A report's tests are local classes in its source or in an include it pulls in —
|
|
444
466
|
written through `getProgram().update()` or `getInclude().update()` — and run
|
|
445
467
|
through `executor.getProgramTestRunner().run(programName)`, with the same
|
|
@@ -6,6 +6,6 @@ export { AdtLocalDefinitions, type ILocalDefinitionsConfig, } from './AdtLocalDe
|
|
|
6
6
|
export { AdtLocalMacros, type ILocalMacrosConfig } from './AdtLocalMacros';
|
|
7
7
|
export { AdtLocalTestClass, type ILocalTestClassConfig, } from './AdtLocalTestClass';
|
|
8
8
|
export { AdtLocalTypes, type ILocalTypesConfig } from './AdtLocalTypes';
|
|
9
|
-
export { getClassUnitTestResult, getClassUnitTestStatus, IClassUnitTestDefinition, IClassUnitTestRunOptions, startClassUnitTestRun, startClassUnitTestRunByObject, } from './run';
|
|
9
|
+
export { getClassUnitTestResult, getClassUnitTestStatus, IClassUnitTestDefinition, IClassUnitTestRunOptions, startClassUnitTestRun, startClassUnitTestRunByObject, startClassUnitTestRunSync, } from './run';
|
|
10
10
|
export * from './types';
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/class/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,6BAA6B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/class/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,6BAA6B,EAC7B,yBAAyB,GAC1B,MAAM,OAAO,CAAC;AACf,cAAc,SAAS,CAAC"}
|
package/dist/core/class/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
17
17
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.startClassUnitTestRunByObject = exports.startClassUnitTestRun = exports.getClassUnitTestStatus = exports.getClassUnitTestResult = exports.AdtLocalTypes = exports.AdtLocalTestClass = exports.AdtLocalMacros = exports.AdtLocalDefinitions = exports.AdtClass = void 0;
|
|
20
|
+
exports.startClassUnitTestRunSync = exports.startClassUnitTestRunByObject = exports.startClassUnitTestRun = exports.getClassUnitTestStatus = exports.getClassUnitTestResult = exports.AdtLocalTypes = exports.AdtLocalTestClass = exports.AdtLocalMacros = exports.AdtLocalDefinitions = exports.AdtClass = void 0;
|
|
21
21
|
var AdtClass_1 = require("./AdtClass");
|
|
22
22
|
Object.defineProperty(exports, "AdtClass", { enumerable: true, get: function () { return AdtClass_1.AdtClass; } });
|
|
23
23
|
var AdtLocalDefinitions_1 = require("./AdtLocalDefinitions");
|
|
@@ -33,4 +33,5 @@ Object.defineProperty(exports, "getClassUnitTestResult", { enumerable: true, get
|
|
|
33
33
|
Object.defineProperty(exports, "getClassUnitTestStatus", { enumerable: true, get: function () { return run_1.getClassUnitTestStatus; } });
|
|
34
34
|
Object.defineProperty(exports, "startClassUnitTestRun", { enumerable: true, get: function () { return run_1.startClassUnitTestRun; } });
|
|
35
35
|
Object.defineProperty(exports, "startClassUnitTestRunByObject", { enumerable: true, get: function () { return run_1.startClassUnitTestRunByObject; } });
|
|
36
|
+
Object.defineProperty(exports, "startClassUnitTestRunSync", { enumerable: true, get: function () { return run_1.startClassUnitTestRunSync; } });
|
|
36
37
|
__exportStar(require("./types"), exports);
|
package/dist/core/class/run.d.ts
CHANGED
|
@@ -61,4 +61,39 @@ export declare const getClassUnitTestResult: typeof getUnitTestRunResult;
|
|
|
61
61
|
* container runs without the caller naming one.
|
|
62
62
|
*/
|
|
63
63
|
export declare function startClassUnitTestRunByObject(connection: IAbapConnection, className: string, options?: IClassUnitTestRunOptions): Promise<IAdtWireResponse>;
|
|
64
|
+
/**
|
|
65
|
+
* Run the ABAP Unit tests of whole classes and answer the finished result —
|
|
66
|
+
* `POST /sap/bc/adt/abapunit/testruns`, one request, no run to poll.
|
|
67
|
+
*
|
|
68
|
+
* The one implementation of this endpoint: the regular runner's `runSync` and
|
|
69
|
+
* the legacy runner's `run` both send it.
|
|
70
|
+
*
|
|
71
|
+
* **Measured:** synchronous on a modern and a legacy on-prem system, over HTTP
|
|
72
|
+
* and over RFC — `<aunit:runResult>` in the POST's answer, no `Location` — and
|
|
73
|
+
* the typed and `application/xml` bodies byte-identical; the legacy system
|
|
74
|
+
* ignores a typed `Accept` and answers `application/xml` either way. Advertised
|
|
75
|
+
* (2026-10-22) by an on-prem system and an ABAP Cloud system alike, beside
|
|
76
|
+
* `/abapunit/runs`; and on an on-prem S/4HANA 2023 that has no `/runs` at all
|
|
77
|
+
* (fr0ster/mcp-abap-adt#286).
|
|
78
|
+
*
|
|
79
|
+
* **Reading the result: `kind` carries the distinction, `severity` does not.**
|
|
80
|
+
* A failed assertion and an uncaught exception both come back
|
|
81
|
+
* `severity="critical"`, so a parser classifying on severity reports a short
|
|
82
|
+
* dump as a failed test. `kind` separates them: `failedAssertion`,
|
|
83
|
+
* `exception`, `noTestClasses`.
|
|
84
|
+
*
|
|
85
|
+
* The format differs from `/runs`:
|
|
86
|
+
* - root `aunit:runConfiguration` in `http://www.sap.com/adt/aunit` (not
|
|
87
|
+
* `aunit:run` in `http://www.sap.com/adt/api/aunit`);
|
|
88
|
+
* - objects by URI in `adtcore:objectReferences` — so a run covers whole
|
|
89
|
+
* classes: the format has no way to name one test class inside its
|
|
90
|
+
* container;
|
|
91
|
+
* - `application/xml` for `Content-Type` and `Accept`.
|
|
92
|
+
*
|
|
93
|
+
* `options` absent sends no `<options>` element — the body the legacy runner
|
|
94
|
+
* has always sent, unchanged. Given, the scope, risk levels and durations go in
|
|
95
|
+
* `<options>` with the same defaults `/runs` gets; `title` and `context` have
|
|
96
|
+
* no place in this format and are not sent.
|
|
97
|
+
*/
|
|
98
|
+
export declare function startClassUnitTestRunSync(connection: IAbapConnection, classNames: string[], options?: IClassUnitTestRunOptions): Promise<IAdtWireResponse>;
|
|
64
99
|
//# sourceMappingURL=run.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/core/class/run.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/core/class/run.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAKjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,eAAe,EAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,OAAc,EACxB,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAoB3B;AAOD,YAAY,EACV,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AAMtC,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EAErB,MAAM,oBAAoB,CAAC;AAE5B,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,wBAAwB,EAAE,EACjC,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA6C3B;AAED,mFAAmF;AACnF,eAAO,MAAM,sBAAsB,6BAAuB,CAAC;AAE3D,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,6BAAuB,CAAC;AAE3D;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,UAAU,EAAE,eAAe,EAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CAM3B;AASD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA8B3B"}
|
package/dist/core/class/run.js
CHANGED
|
@@ -7,6 +7,8 @@ exports.getClassUnitTestResult = exports.getClassUnitTestStatus = void 0;
|
|
|
7
7
|
exports.runClass = runClass;
|
|
8
8
|
exports.startClassUnitTestRun = startClassUnitTestRun;
|
|
9
9
|
exports.startClassUnitTestRunByObject = startClassUnitTestRunByObject;
|
|
10
|
+
exports.startClassUnitTestRunSync = startClassUnitTestRunSync;
|
|
11
|
+
const objects_1 = require("../../endpoints/objects");
|
|
10
12
|
const passport_1 = require("../../runtime/debugger/passport");
|
|
11
13
|
const xml_1 = require("../../utils/xml");
|
|
12
14
|
/**
|
|
@@ -126,3 +128,89 @@ exports.getClassUnitTestResult = abapUnit_1.getUnitTestRunResult;
|
|
|
126
128
|
async function startClassUnitTestRunByObject(connection, className, options) {
|
|
127
129
|
return (0, abapUnit_1.startUnitTestRunByObject)(connection, { name: className, type: 'CLAS' }, options);
|
|
128
130
|
}
|
|
131
|
+
// =============================================================================
|
|
132
|
+
// The synchronous runner: /abapunit/testruns
|
|
133
|
+
// =============================================================================
|
|
134
|
+
const CT_TESTRUNS = 'application/xml';
|
|
135
|
+
const ACCEPT_TESTRUNS = 'application/xml';
|
|
136
|
+
/**
|
|
137
|
+
* Run the ABAP Unit tests of whole classes and answer the finished result —
|
|
138
|
+
* `POST /sap/bc/adt/abapunit/testruns`, one request, no run to poll.
|
|
139
|
+
*
|
|
140
|
+
* The one implementation of this endpoint: the regular runner's `runSync` and
|
|
141
|
+
* the legacy runner's `run` both send it.
|
|
142
|
+
*
|
|
143
|
+
* **Measured:** synchronous on a modern and a legacy on-prem system, over HTTP
|
|
144
|
+
* and over RFC — `<aunit:runResult>` in the POST's answer, no `Location` — and
|
|
145
|
+
* the typed and `application/xml` bodies byte-identical; the legacy system
|
|
146
|
+
* ignores a typed `Accept` and answers `application/xml` either way. Advertised
|
|
147
|
+
* (2026-10-22) by an on-prem system and an ABAP Cloud system alike, beside
|
|
148
|
+
* `/abapunit/runs`; and on an on-prem S/4HANA 2023 that has no `/runs` at all
|
|
149
|
+
* (fr0ster/mcp-abap-adt#286).
|
|
150
|
+
*
|
|
151
|
+
* **Reading the result: `kind` carries the distinction, `severity` does not.**
|
|
152
|
+
* A failed assertion and an uncaught exception both come back
|
|
153
|
+
* `severity="critical"`, so a parser classifying on severity reports a short
|
|
154
|
+
* dump as a failed test. `kind` separates them: `failedAssertion`,
|
|
155
|
+
* `exception`, `noTestClasses`.
|
|
156
|
+
*
|
|
157
|
+
* The format differs from `/runs`:
|
|
158
|
+
* - root `aunit:runConfiguration` in `http://www.sap.com/adt/aunit` (not
|
|
159
|
+
* `aunit:run` in `http://www.sap.com/adt/api/aunit`);
|
|
160
|
+
* - objects by URI in `adtcore:objectReferences` — so a run covers whole
|
|
161
|
+
* classes: the format has no way to name one test class inside its
|
|
162
|
+
* container;
|
|
163
|
+
* - `application/xml` for `Content-Type` and `Accept`.
|
|
164
|
+
*
|
|
165
|
+
* `options` absent sends no `<options>` element — the body the legacy runner
|
|
166
|
+
* has always sent, unchanged. Given, the scope, risk levels and durations go in
|
|
167
|
+
* `<options>` with the same defaults `/runs` gets; `title` and `context` have
|
|
168
|
+
* no place in this format and are not sent.
|
|
169
|
+
*/
|
|
170
|
+
async function startClassUnitTestRunSync(connection, classNames, options) {
|
|
171
|
+
const objectRefs = classNames
|
|
172
|
+
.map((name) => {
|
|
173
|
+
return ` <adtcore:objectReference adtcore:uri="${(0, xml_1.escapeXmlAttr)(objects_1.CLASS.uri(name))}"/>`;
|
|
174
|
+
})
|
|
175
|
+
.join('\n');
|
|
176
|
+
const xml = `<?xml version="1.0" encoding="UTF-8"?><aunit:runConfiguration xmlns:aunit="http://www.sap.com/adt/aunit">
|
|
177
|
+
<external>
|
|
178
|
+
<coverage active="false"/>
|
|
179
|
+
</external>
|
|
180
|
+
${options ? testRunsOptions(options) : ''} <adtcore:objectSets xmlns:adtcore="http://www.sap.com/adt/core">
|
|
181
|
+
<objectSet kind="inclusive">
|
|
182
|
+
<adtcore:objectReferences>
|
|
183
|
+
${objectRefs}
|
|
184
|
+
</adtcore:objectReferences>
|
|
185
|
+
</objectSet>
|
|
186
|
+
</adtcore:objectSets>
|
|
187
|
+
</aunit:runConfiguration>`;
|
|
188
|
+
return connection.makeAdtRequest({
|
|
189
|
+
url: '/sap/bc/adt/abapunit/testruns',
|
|
190
|
+
method: 'POST',
|
|
191
|
+
timeout: 0,
|
|
192
|
+
data: xml,
|
|
193
|
+
headers: {
|
|
194
|
+
'Content-Type': CT_TESTRUNS,
|
|
195
|
+
Accept: ACCEPT_TESTRUNS,
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* `<options>` of a `runConfiguration`, as Eclipse sends it. The scope's three
|
|
201
|
+
* flags are `testDeterminationStrategy`'s: own tests are `sameProgram`,
|
|
202
|
+
* foreign tests `assignedTests`, their preview `appendAssignedTestsPreview`.
|
|
203
|
+
*/
|
|
204
|
+
function testRunsOptions(options) {
|
|
205
|
+
const scope = options.scope ?? {};
|
|
206
|
+
const risk = options.riskLevel ?? {};
|
|
207
|
+
const duration = options.duration ?? {};
|
|
208
|
+
return ` <options>
|
|
209
|
+
<uriType value="semantic"/>
|
|
210
|
+
<testDeterminationStrategy sameProgram="${boolAttr(scope.ownTests, true)}" assignedTests="${boolAttr(scope.foreignTests, false)}" appendAssignedTestsPreview="${boolAttr(scope.addForeignTestsAsPreview, true)}"/>
|
|
211
|
+
<testRiskLevels harmless="${boolAttr(risk.harmless, true)}" dangerous="${boolAttr(risk.dangerous, true)}" critical="${boolAttr(risk.critical, true)}"/>
|
|
212
|
+
<testDurations short="${boolAttr(duration.short, true)}" medium="${boolAttr(duration.medium, true)}" long="${boolAttr(duration.long, true)}"/>
|
|
213
|
+
<withNavigationUri enabled="true"/>
|
|
214
|
+
</options>
|
|
215
|
+
`;
|
|
216
|
+
}
|
|
@@ -27,7 +27,12 @@ import { AbapUnitRunner, type IAbapUnitRunnerResults } from '../abapUnitRunner';
|
|
|
27
27
|
* whose every test class runs.
|
|
28
28
|
*/
|
|
29
29
|
export type IClassTestRunTarget = IClassUnitTestDefinition[] | string;
|
|
30
|
-
/**
|
|
30
|
+
/** The distinct containers a target names: what `/testruns` addresses. */
|
|
31
|
+
export declare function containersOf(target: IClassTestRunTarget): string[];
|
|
32
|
+
/**
|
|
33
|
+
* One strategy per distinct answer: starting a run, polling it, its result.
|
|
34
|
+
* `runSync` answers the result document itself, so it is read by `result`.
|
|
35
|
+
*/
|
|
31
36
|
export type IClassTestRunnerResults = IAbapUnitRunnerResults;
|
|
32
37
|
/** The shipped default: documents as they arrived. */
|
|
33
38
|
export declare const classTestRunnerDocuments: {
|
|
@@ -49,5 +54,26 @@ export declare class ClassTestRunner<R extends IClassTestRunnerResults = typeof
|
|
|
49
54
|
* read as a failure.
|
|
50
55
|
*/
|
|
51
56
|
run<E extends IAdtError = IAdtError>(target: IClassTestRunTarget, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['run']>, E>>;
|
|
57
|
+
/**
|
|
58
|
+
* Run the tests and answer the finished result. One POST, to
|
|
59
|
+
* `/sap/bc/adt/abapunit/testruns` — the synchronous runner, beside the
|
|
60
|
+
* asynchronous `run` + `getStatus` + `getResult`, which stays the default.
|
|
61
|
+
*
|
|
62
|
+
* An explicit choice of the caller's: nothing here asks the system which
|
|
63
|
+
* runner it has. A system without `/abapunit/runs` (an on-prem S/4HANA 2023
|
|
64
|
+
* was measured with `/testruns` alone) needs this one; whether a system has
|
|
65
|
+
* it is in its discovery, which is the caller's to read.
|
|
66
|
+
*
|
|
67
|
+
* The answer is the `aunit:runResult` document, so it is read by this
|
|
68
|
+
* runner's `result` strategy — the one `getResult` uses — and a failing test
|
|
69
|
+
* is in it as an `alert`; whether that is a failure is `options.analyse`'s
|
|
70
|
+
* (`analyseUnitTest` from @mcp-abap-adt/adt-strategies reads it so).
|
|
71
|
+
*
|
|
72
|
+
* Differences from `run`: the endpoint addresses whole classes, so a target
|
|
73
|
+
* of test definitions runs each distinct container whole, and `title` and
|
|
74
|
+
* `context` are not sent; scope, risk levels and durations are, with the
|
|
75
|
+
* same defaults.
|
|
76
|
+
*/
|
|
77
|
+
runSync<E extends IAdtError = IAdtError>(target: IClassTestRunTarget, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['result']>, E>>;
|
|
52
78
|
}
|
|
53
79
|
//# sourceMappingURL=ClassTestRunner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClassTestRunner.d.ts","sourceRoot":"","sources":["../../../src/executors/class/ClassTestRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EAChB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"ClassTestRunner.d.ts","sourceRoot":"","sources":["../../../src/executors/class/ClassTestRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EAChB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAM9D,OAAO,EACL,cAAc,EAEd,KAAK,sBAAsB,EAC5B,MAAM,mBAAmB,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,EAAE,GAAG,MAAM,CAAC;AAEtE,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAIlE;AAED;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,sBAAsB,CAAC;AAE7D,sDAAsD;AACtD,eAAO,MAAM,wBAAwB;;;;CAA0B,CAAC;AAEhE,qBAAa,eAAe,CACxB,CAAC,SAAS,uBAAuB,GAAG,OAAO,wBAAwB,CAErE,SAAQ,cAAc,CAAC,CAAC,CACxB,YACE,YAAY,CACV,mBAAmB,EACnB,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EACpB,wBAAwB,CACzB;gBAGD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAEhB,OAAO,GAAE,CAA4C;IAKvD;;;;;;;;;;OAUG;IACG,GAAG,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACvC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAWjD;;;;;;;;;;;;;;;;;;;OAmBG;IACG,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC3C,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAarD"}
|
|
@@ -21,9 +21,16 @@
|
|
|
21
21
|
*/
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.ClassTestRunner = exports.classTestRunnerDocuments = void 0;
|
|
24
|
+
exports.containersOf = containersOf;
|
|
24
25
|
const run_1 = require("../../core/class/run");
|
|
25
26
|
const adtResponse_1 = require("../../utils/adtResponse");
|
|
26
27
|
const abapUnitRunner_1 = require("../abapUnitRunner");
|
|
28
|
+
/** The distinct containers a target names: what `/testruns` addresses. */
|
|
29
|
+
function containersOf(target) {
|
|
30
|
+
return typeof target === 'string'
|
|
31
|
+
? [target]
|
|
32
|
+
: [...new Set(target.map((test) => test.containerClass))];
|
|
33
|
+
}
|
|
27
34
|
/** The shipped default: documents as they arrived. */
|
|
28
35
|
exports.classTestRunnerDocuments = abapUnitRunner_1.abapUnitRunnerDocuments;
|
|
29
36
|
class ClassTestRunner extends abapUnitRunner_1.AbapUnitRunner {
|
|
@@ -49,5 +56,29 @@ class ClassTestRunner extends abapUnitRunner_1.AbapUnitRunner {
|
|
|
49
56
|
}
|
|
50
57
|
return (0, adtResponse_1.answering)(() => (0, run_1.startClassUnitTestRun)(this.connection, target, options), this.results.run, options?.analyse);
|
|
51
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Run the tests and answer the finished result. One POST, to
|
|
61
|
+
* `/sap/bc/adt/abapunit/testruns` — the synchronous runner, beside the
|
|
62
|
+
* asynchronous `run` + `getStatus` + `getResult`, which stays the default.
|
|
63
|
+
*
|
|
64
|
+
* An explicit choice of the caller's: nothing here asks the system which
|
|
65
|
+
* runner it has. A system without `/abapunit/runs` (an on-prem S/4HANA 2023
|
|
66
|
+
* was measured with `/testruns` alone) needs this one; whether a system has
|
|
67
|
+
* it is in its discovery, which is the caller's to read.
|
|
68
|
+
*
|
|
69
|
+
* The answer is the `aunit:runResult` document, so it is read by this
|
|
70
|
+
* runner's `result` strategy — the one `getResult` uses — and a failing test
|
|
71
|
+
* is in it as an `alert`; whether that is a failure is `options.analyse`'s
|
|
72
|
+
* (`analyseUnitTest` from @mcp-abap-adt/adt-strategies reads it so).
|
|
73
|
+
*
|
|
74
|
+
* Differences from `run`: the endpoint addresses whole classes, so a target
|
|
75
|
+
* of test definitions runs each distinct container whole, and `title` and
|
|
76
|
+
* `context` are not sent; scope, risk levels and durations are, with the
|
|
77
|
+
* same defaults.
|
|
78
|
+
*/
|
|
79
|
+
async runSync(target, options) {
|
|
80
|
+
const { analyse, ...runOptions } = options ?? {};
|
|
81
|
+
return (0, adtResponse_1.answering)(() => (0, run_1.startClassUnitTestRunSync)(this.connection, containersOf(target), runOptions), this.results.result, analyse);
|
|
82
|
+
}
|
|
52
83
|
}
|
|
53
84
|
exports.ClassTestRunner = ClassTestRunner;
|
|
@@ -21,6 +21,12 @@ export declare class ClassTestRunnerLegacy<R extends IClassTestRunnerResults = t
|
|
|
21
21
|
* result document itself, not an id.
|
|
22
22
|
*/
|
|
23
23
|
run<E extends IAdtError = IAdtError>(target: IClassTestRunTarget, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['run']>, E>>;
|
|
24
|
+
/**
|
|
25
|
+
* The same request as `run` — on a legacy system `run` is already the
|
|
26
|
+
* synchronous one — answered through the `result` strategy, as the regular
|
|
27
|
+
* runner's `runSync` is.
|
|
28
|
+
*/
|
|
29
|
+
runSync<E extends IAdtError = IAdtError>(target: IClassTestRunTarget, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['result']>, E>>;
|
|
24
30
|
/**
|
|
25
31
|
* Refused without a request: a legacy system finishes a run before it
|
|
26
32
|
* answers and exposes no run to poll. `run`'s own answer is the result.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClassTestRunnerLegacy.d.ts","sourceRoot":"","sources":["../../../src/executors/class/ClassTestRunnerLegacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,wBAAwB,EAEzB,MAAM,8BAA8B,CAAC;AAItC,OAAO,EACL,eAAe,EACf,KAAK,wBAAwB,
|
|
1
|
+
{"version":3,"file":"ClassTestRunnerLegacy.d.ts","sourceRoot":"","sources":["../../../src/executors/class/ClassTestRunnerLegacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,wBAAwB,EAEzB,MAAM,8BAA8B,CAAC;AAItC,OAAO,EACL,eAAe,EACf,KAAK,wBAAwB,EAE7B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,qBAAqB,CAChC,CAAC,SAAS,uBAAuB,GAAG,OAAO,wBAAwB,CACnE,SAAQ,eAAe,CAAC,CAAC,CAAC;IAC1B;;;;;OAKG;IACY,GAAG,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAChD,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAUjD;;;;OAIG;IACY,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACpD,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAQpD;;;OAGG;IACY,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAClE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;IASD,0EAA0E;IAC3D,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAClE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;CAQF"}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.ClassTestRunnerLegacy = void 0;
|
|
17
17
|
const interfaces_adt_1 = require("@mcp-abap-adt/interfaces-adt");
|
|
18
|
-
const
|
|
18
|
+
const run_1 = require("../../core/class/run");
|
|
19
19
|
const adtResponse_1 = require("../../utils/adtResponse");
|
|
20
20
|
const ClassTestRunner_1 = require("./ClassTestRunner");
|
|
21
21
|
class ClassTestRunnerLegacy extends ClassTestRunner_1.ClassTestRunner {
|
|
@@ -26,10 +26,17 @@ class ClassTestRunnerLegacy extends ClassTestRunner_1.ClassTestRunner {
|
|
|
26
26
|
* result document itself, not an id.
|
|
27
27
|
*/
|
|
28
28
|
async run(target, options) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
// No options: the body a legacy system has always been sent — the
|
|
30
|
+
// `<options>` element `runSync` sends is unmeasured there.
|
|
31
|
+
return (0, adtResponse_1.answering)(() => (0, run_1.startClassUnitTestRunSync)(this.connection, (0, ClassTestRunner_1.containersOf)(target)), this.results.run, options?.analyse);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The same request as `run` — on a legacy system `run` is already the
|
|
35
|
+
* synchronous one — answered through the `result` strategy, as the regular
|
|
36
|
+
* runner's `runSync` is.
|
|
37
|
+
*/
|
|
38
|
+
async runSync(target, options) {
|
|
39
|
+
return (0, adtResponse_1.answering)(() => (0, run_1.startClassUnitTestRunSync)(this.connection, (0, ClassTestRunner_1.containersOf)(target)), this.results.result, options?.analyse);
|
|
33
40
|
}
|
|
34
41
|
/**
|
|
35
42
|
* Refused without a request: a legacy system finishes a run before it
|
package/package.json
CHANGED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ABAP Unit test run operations for legacy systems (BASIS < 7.50)
|
|
3
|
-
*
|
|
4
|
-
* Legacy systems use:
|
|
5
|
-
* - /sap/bc/adt/abapunit/testruns instead of /sap/bc/adt/abapunit/runs
|
|
6
|
-
* - application/xml for Content-Type and Accept (not versioned vnd.sap.adt.api.abapunit.* types)
|
|
7
|
-
*/
|
|
8
|
-
import type { IAbapConnection, IAdtWireResponse } from '@mcp-abap-adt/interfaces-adt-connection';
|
|
9
|
-
/**
|
|
10
|
-
* Start ABAP Unit test run on legacy systems
|
|
11
|
-
* Uses /sap/bc/adt/abapunit/testruns endpoint with aunit:runConfiguration format
|
|
12
|
-
*
|
|
13
|
-
* There is only a start here. `getClassUnitTestStatusLegacy` and
|
|
14
|
-
* `getClassUnitTestResultLegacy` polled `testruns/{runId}` and
|
|
15
|
-
* `testruns/{runId}/results`, and were removed once the endpoint was measured:
|
|
16
|
-
* the POST answers with the finished result, so there was never a run to poll.
|
|
17
|
-
* Nothing called them — `ClassTestRunnerLegacy` serves both from the response the
|
|
18
|
-
* POST returned — so they were an unmeasured contract kept alive by nobody
|
|
19
|
-
* looking.
|
|
20
|
-
*
|
|
21
|
-
* **Reading the result: `kind` carries the distinction, `severity` does not.** A
|
|
22
|
-
* failed assertion and an uncaught exception both come back
|
|
23
|
-
* `severity="critical"`, measured on one release — so a parser classifying on
|
|
24
|
-
* severity reports a short dump as a failed test. The field that separates them
|
|
25
|
-
* is `kind`: `failedAssertion`, `exception`, `noTestClasses`.
|
|
26
|
-
*
|
|
27
|
-
* Also measured: this endpoint is **synchronous** on both a modern and a legacy
|
|
28
|
-
* on-prem system, over HTTP and over RFC — `<aunit:runResult>` with no
|
|
29
|
-
* `Location`, and the typed and `application/xml` bodies byte-identical. The
|
|
30
|
-
* legacy system ignores the typed `Accept` altogether and answers
|
|
31
|
-
* `application/xml` either way.
|
|
32
|
-
*
|
|
33
|
-
* Legacy format differs from modern:
|
|
34
|
-
* - Root element: aunit:runConfiguration (not aunit:run)
|
|
35
|
-
* - Namespace: http://www.sap.com/adt/aunit (not http://www.sap.com/adt/api/aunit)
|
|
36
|
-
* - Objects via adtcore:objectReferences with URI (not aunit:tests with containerClass/class)
|
|
37
|
-
* — so a run covers whole classes: this format has no way to name one test
|
|
38
|
-
* class inside its container, and a caller's test class name is not sent.
|
|
39
|
-
* - Content-Type/Accept: application/xml (not versioned vnd.sap.adt.api.abapunit.*)
|
|
40
|
-
*/
|
|
41
|
-
export declare function startClassUnitTestRunLegacy(connection: IAbapConnection, classNames: string[]): Promise<IAdtWireResponse>;
|
|
42
|
-
//# sourceMappingURL=runLegacy.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runLegacy.d.ts","sourceRoot":"","sources":["../../../src/core/class/runLegacy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAMjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,gBAAgB,CAAC,CA8B3B"}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* ABAP Unit test run operations for legacy systems (BASIS < 7.50)
|
|
4
|
-
*
|
|
5
|
-
* Legacy systems use:
|
|
6
|
-
* - /sap/bc/adt/abapunit/testruns instead of /sap/bc/adt/abapunit/runs
|
|
7
|
-
* - application/xml for Content-Type and Accept (not versioned vnd.sap.adt.api.abapunit.* types)
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.startClassUnitTestRunLegacy = startClassUnitTestRunLegacy;
|
|
11
|
-
const objects_1 = require("../../endpoints/objects");
|
|
12
|
-
const CT_XML = 'application/xml';
|
|
13
|
-
const ACCEPT_XML = 'application/xml';
|
|
14
|
-
/**
|
|
15
|
-
* Start ABAP Unit test run on legacy systems
|
|
16
|
-
* Uses /sap/bc/adt/abapunit/testruns endpoint with aunit:runConfiguration format
|
|
17
|
-
*
|
|
18
|
-
* There is only a start here. `getClassUnitTestStatusLegacy` and
|
|
19
|
-
* `getClassUnitTestResultLegacy` polled `testruns/{runId}` and
|
|
20
|
-
* `testruns/{runId}/results`, and were removed once the endpoint was measured:
|
|
21
|
-
* the POST answers with the finished result, so there was never a run to poll.
|
|
22
|
-
* Nothing called them — `ClassTestRunnerLegacy` serves both from the response the
|
|
23
|
-
* POST returned — so they were an unmeasured contract kept alive by nobody
|
|
24
|
-
* looking.
|
|
25
|
-
*
|
|
26
|
-
* **Reading the result: `kind` carries the distinction, `severity` does not.** A
|
|
27
|
-
* failed assertion and an uncaught exception both come back
|
|
28
|
-
* `severity="critical"`, measured on one release — so a parser classifying on
|
|
29
|
-
* severity reports a short dump as a failed test. The field that separates them
|
|
30
|
-
* is `kind`: `failedAssertion`, `exception`, `noTestClasses`.
|
|
31
|
-
*
|
|
32
|
-
* Also measured: this endpoint is **synchronous** on both a modern and a legacy
|
|
33
|
-
* on-prem system, over HTTP and over RFC — `<aunit:runResult>` with no
|
|
34
|
-
* `Location`, and the typed and `application/xml` bodies byte-identical. The
|
|
35
|
-
* legacy system ignores the typed `Accept` altogether and answers
|
|
36
|
-
* `application/xml` either way.
|
|
37
|
-
*
|
|
38
|
-
* Legacy format differs from modern:
|
|
39
|
-
* - Root element: aunit:runConfiguration (not aunit:run)
|
|
40
|
-
* - Namespace: http://www.sap.com/adt/aunit (not http://www.sap.com/adt/api/aunit)
|
|
41
|
-
* - Objects via adtcore:objectReferences with URI (not aunit:tests with containerClass/class)
|
|
42
|
-
* — so a run covers whole classes: this format has no way to name one test
|
|
43
|
-
* class inside its container, and a caller's test class name is not sent.
|
|
44
|
-
* - Content-Type/Accept: application/xml (not versioned vnd.sap.adt.api.abapunit.*)
|
|
45
|
-
*/
|
|
46
|
-
async function startClassUnitTestRunLegacy(connection, classNames) {
|
|
47
|
-
const objectRefs = classNames
|
|
48
|
-
.map((name) => {
|
|
49
|
-
return ` <adtcore:objectReference adtcore:uri="${objects_1.CLASS.uri(name)}"/>`;
|
|
50
|
-
})
|
|
51
|
-
.join('\n');
|
|
52
|
-
const xml = `<?xml version="1.0" encoding="UTF-8"?><aunit:runConfiguration xmlns:aunit="http://www.sap.com/adt/aunit">
|
|
53
|
-
<external>
|
|
54
|
-
<coverage active="false"/>
|
|
55
|
-
</external>
|
|
56
|
-
<adtcore:objectSets xmlns:adtcore="http://www.sap.com/adt/core">
|
|
57
|
-
<objectSet kind="inclusive">
|
|
58
|
-
<adtcore:objectReferences>
|
|
59
|
-
${objectRefs}
|
|
60
|
-
</adtcore:objectReferences>
|
|
61
|
-
</objectSet>
|
|
62
|
-
</adtcore:objectSets>
|
|
63
|
-
</aunit:runConfiguration>`;
|
|
64
|
-
return connection.makeAdtRequest({
|
|
65
|
-
url: '/sap/bc/adt/abapunit/testruns',
|
|
66
|
-
method: 'POST',
|
|
67
|
-
timeout: 0,
|
|
68
|
-
data: xml,
|
|
69
|
-
headers: {
|
|
70
|
-
'Content-Type': CT_XML,
|
|
71
|
-
Accept: ACCEPT_XML,
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
}
|