@mcp-abap-adt/adt-clients 3.6.0 → 3.7.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/dist/core/unitTest/AdtUnitTestLegacy.d.ts +19 -9
- package/dist/core/unitTest/AdtUnitTestLegacy.d.ts.map +1 -1
- package/dist/core/unitTest/AdtUnitTestLegacy.js +45 -52
- package/dist/core/unitTest/runLegacy.d.ts +8 -2
- package/dist/core/unitTest/runLegacy.d.ts.map +1 -1
- package/dist/core/unitTest/runLegacy.js +26 -33
- package/package.json +1 -1
|
@@ -4,31 +4,41 @@
|
|
|
4
4
|
* Extends AdtUnitTest and overrides run/status/result to use legacy endpoints:
|
|
5
5
|
* - /sap/bc/adt/abapunit/testruns instead of /sap/bc/adt/abapunit/runs
|
|
6
6
|
* - application/xml content types instead of versioned vnd.sap.adt.api.abapunit.* types
|
|
7
|
+
*
|
|
8
|
+
* Key difference: Legacy systems return results synchronously (aunit:runResult)
|
|
9
|
+
* from the POST to /testruns — no run ID, no async polling needed.
|
|
7
10
|
*/
|
|
8
11
|
import type { IAdtResponse as AxiosResponse, IAbapConnection, IAdtOperationOptions, ILogger } from '@mcp-abap-adt/interfaces';
|
|
9
12
|
import { AdtUnitTest } from './AdtUnitTest';
|
|
10
|
-
import type { IUnitTestConfig, IUnitTestState } from './types';
|
|
13
|
+
import type { IClassUnitTestDefinition, IClassUnitTestRunOptions, IUnitTestConfig, IUnitTestState } from './types';
|
|
11
14
|
export declare class AdtUnitTestLegacy extends AdtUnitTest {
|
|
12
15
|
constructor(connection: IAbapConnection, logger?: ILogger);
|
|
13
16
|
/**
|
|
14
|
-
* Create unit test run using legacy endpoint
|
|
17
|
+
* Create unit test run using legacy endpoint.
|
|
18
|
+
* Legacy returns results synchronously — no run ID or polling needed.
|
|
15
19
|
*/
|
|
16
20
|
create(config: IUnitTestConfig, _options?: IAdtOperationOptions): Promise<IUnitTestState>;
|
|
17
21
|
/**
|
|
18
|
-
*
|
|
22
|
+
* Run unit tests — legacy returns results synchronously.
|
|
23
|
+
*/
|
|
24
|
+
run(tests: IClassUnitTestDefinition[], options?: IClassUnitTestRunOptions): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Get unit test status — legacy returns results synchronously,
|
|
27
|
+
* so this returns the cached response from create().
|
|
19
28
|
*/
|
|
20
|
-
getStatus(
|
|
29
|
+
getStatus(_runId: string, _withLongPolling?: boolean): Promise<AxiosResponse>;
|
|
21
30
|
/**
|
|
22
|
-
* Get unit test result
|
|
31
|
+
* Get unit test result — legacy returns results synchronously,
|
|
32
|
+
* so this returns the cached response from create().
|
|
23
33
|
*/
|
|
24
|
-
getResult(
|
|
34
|
+
getResult(_runId: string, _options?: {
|
|
25
35
|
withNavigationUris?: boolean;
|
|
26
36
|
format?: 'abapunit' | 'junit';
|
|
27
37
|
}): Promise<AxiosResponse>;
|
|
28
38
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
39
|
+
* Read unit test — legacy returns results synchronously,
|
|
40
|
+
* so this returns the cached result from create().
|
|
31
41
|
*/
|
|
32
|
-
|
|
42
|
+
read(_config: Partial<IUnitTestConfig>, _version?: 'active' | 'inactive'): Promise<IUnitTestState | undefined>;
|
|
33
43
|
}
|
|
34
44
|
//# sourceMappingURL=AdtUnitTestLegacy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdtUnitTestLegacy.d.ts","sourceRoot":"","sources":["../../../src/core/unitTest/AdtUnitTestLegacy.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"AdtUnitTestLegacy.d.ts","sourceRoot":"","sources":["../../../src/core/unitTest/AdtUnitTestLegacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EACf,oBAAoB,EACpB,OAAO,EACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EACf,cAAc,EACf,MAAM,SAAS,CAAC;AAKjB,qBAAa,iBAAkB,SAAQ,WAAW;gBACpC,UAAU,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,OAAO;IAIzD;;;OAGG;IACY,MAAM,CACnB,MAAM,EAAE,eAAe,EACvB,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,cAAc,CAAC;IAkC1B;;OAEG;IACY,GAAG,CAChB,KAAK,EAAE,wBAAwB,EAAE,EACjC,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,MAAM,CAAC;IAKlB;;;OAGG;IACY,SAAS,CACtB,MAAM,EAAE,MAAM,EACd,gBAAgB,GAAE,OAAc,GAC/B,OAAO,CAAC,aAAa,CAAC;IASzB;;;OAGG;IACY,SAAS,CACtB,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE;QAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAA;KAAE,GACzE,OAAO,CAAC,aAAa,CAAC;IASzB;;;OAGG;IACY,IAAI,CACjB,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,EACjC,QAAQ,GAAE,QAAQ,GAAG,UAAqB,GACzC,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;CAWvC"}
|
|
@@ -5,18 +5,23 @@
|
|
|
5
5
|
* Extends AdtUnitTest and overrides run/status/result to use legacy endpoints:
|
|
6
6
|
* - /sap/bc/adt/abapunit/testruns instead of /sap/bc/adt/abapunit/runs
|
|
7
7
|
* - application/xml content types instead of versioned vnd.sap.adt.api.abapunit.* types
|
|
8
|
+
*
|
|
9
|
+
* Key difference: Legacy systems return results synchronously (aunit:runResult)
|
|
10
|
+
* from the POST to /testruns — no run ID, no async polling needed.
|
|
8
11
|
*/
|
|
9
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
13
|
exports.AdtUnitTestLegacy = void 0;
|
|
11
|
-
const internalUtils_1 = require("../../utils/internalUtils");
|
|
12
14
|
const AdtUnitTest_1 = require("./AdtUnitTest");
|
|
13
15
|
const runLegacy_1 = require("./runLegacy");
|
|
16
|
+
/** Synthetic run ID for legacy synchronous results */
|
|
17
|
+
const LEGACY_SYNC_RUN_ID = 'legacy-sync';
|
|
14
18
|
class AdtUnitTestLegacy extends AdtUnitTest_1.AdtUnitTest {
|
|
15
19
|
constructor(connection, logger) {
|
|
16
20
|
super(connection, logger);
|
|
17
21
|
}
|
|
18
22
|
/**
|
|
19
|
-
* Create unit test run using legacy endpoint
|
|
23
|
+
* Create unit test run using legacy endpoint.
|
|
24
|
+
* Legacy returns results synchronously — no run ID or polling needed.
|
|
20
25
|
*/
|
|
21
26
|
async create(config, _options) {
|
|
22
27
|
if (!config.tests || config.tests.length === 0) {
|
|
@@ -26,16 +31,15 @@ class AdtUnitTestLegacy extends AdtUnitTest_1.AdtUnitTest {
|
|
|
26
31
|
this.logger?.info?.('Starting unit test run (legacy)');
|
|
27
32
|
const response = await (0, runLegacy_1.startClassUnitTestRunLegacy)(this.connection, config.tests, config.options);
|
|
28
33
|
this.logger?.debug?.('Unit test run response status:', response.status);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.logger?.info?.('Unit test run started (legacy), run ID:', runId);
|
|
35
|
-
this.lastRunId = runId;
|
|
34
|
+
// Legacy returns results synchronously — store as both status and result
|
|
35
|
+
this.lastStatusResponse = response;
|
|
36
|
+
this.lastResultResponse = response;
|
|
37
|
+
this.lastRunId = LEGACY_SYNC_RUN_ID;
|
|
38
|
+
this.logger?.info?.('Unit test run completed (legacy, synchronous)');
|
|
36
39
|
return {
|
|
37
40
|
createResult: response,
|
|
38
|
-
runId,
|
|
41
|
+
runId: LEGACY_SYNC_RUN_ID,
|
|
42
|
+
runResult: response.data,
|
|
39
43
|
errors: [],
|
|
40
44
|
};
|
|
41
45
|
}
|
|
@@ -45,57 +49,46 @@ class AdtUnitTestLegacy extends AdtUnitTest_1.AdtUnitTest {
|
|
|
45
49
|
}
|
|
46
50
|
}
|
|
47
51
|
/**
|
|
48
|
-
*
|
|
52
|
+
* Run unit tests — legacy returns results synchronously.
|
|
49
53
|
*/
|
|
50
|
-
async
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return response;
|
|
54
|
+
async run(tests, options) {
|
|
55
|
+
await this.create({ tests, options });
|
|
56
|
+
return LEGACY_SYNC_RUN_ID;
|
|
54
57
|
}
|
|
55
58
|
/**
|
|
56
|
-
* Get unit test
|
|
59
|
+
* Get unit test status — legacy returns results synchronously,
|
|
60
|
+
* so this returns the cached response from create().
|
|
57
61
|
*/
|
|
58
|
-
async
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
async getStatus(_runId, _withLongPolling = true) {
|
|
63
|
+
if (this.lastStatusResponse) {
|
|
64
|
+
return this.lastStatusResponse;
|
|
65
|
+
}
|
|
66
|
+
throw new Error('No status available. Legacy systems return results synchronously via create().');
|
|
62
67
|
}
|
|
63
68
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
69
|
+
* Get unit test result — legacy returns results synchronously,
|
|
70
|
+
* so this returns the cached response from create().
|
|
66
71
|
*/
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
(0, internalUtils_1.headerValueToString)(response.headers?.['content-location']) ||
|
|
71
|
-
(0, internalUtils_1.headerValueToString)(response.headers?.['sap-adt-location']);
|
|
72
|
-
if (locationHeader) {
|
|
73
|
-
const match = locationHeader.match(/\/testruns\/([^/]+)/) ||
|
|
74
|
-
locationHeader.match(/\/runs\/([^/]+)/);
|
|
75
|
-
if (match) {
|
|
76
|
-
return match[1];
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// Fallback: parse from response body (XML)
|
|
80
|
-
const data = response.data;
|
|
81
|
-
if (typeof data === 'string') {
|
|
82
|
-
const uriMatch = data.match(/uri="([^"]+)"/);
|
|
83
|
-
if (uriMatch) {
|
|
84
|
-
const uri = uriMatch[1];
|
|
85
|
-
const match = uri.match(/\/testruns\/([^/]+)/) || uri.match(/\/runs\/([^/]+)/);
|
|
86
|
-
if (match) {
|
|
87
|
-
return match[1];
|
|
88
|
-
}
|
|
89
|
-
}
|
|
72
|
+
async getResult(_runId, _options) {
|
|
73
|
+
if (this.lastResultResponse) {
|
|
74
|
+
return this.lastResultResponse;
|
|
90
75
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
76
|
+
throw new Error('No result available. Legacy systems return results synchronously via create().');
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Read unit test — legacy returns results synchronously,
|
|
80
|
+
* so this returns the cached result from create().
|
|
81
|
+
*/
|
|
82
|
+
async read(_config, _version = 'active') {
|
|
83
|
+
if (!this.lastResultResponse) {
|
|
84
|
+
return undefined;
|
|
97
85
|
}
|
|
98
|
-
return
|
|
86
|
+
return {
|
|
87
|
+
runId: LEGACY_SYNC_RUN_ID,
|
|
88
|
+
runStatus: this.lastStatusResponse?.data,
|
|
89
|
+
runResult: this.lastResultResponse.data,
|
|
90
|
+
errors: [],
|
|
91
|
+
};
|
|
99
92
|
}
|
|
100
93
|
}
|
|
101
94
|
exports.AdtUnitTestLegacy = AdtUnitTestLegacy;
|
|
@@ -9,9 +9,15 @@ import type { IAdtResponse as AxiosResponse, IAbapConnection } from '@mcp-abap-a
|
|
|
9
9
|
import type { IClassUnitTestDefinition, IClassUnitTestRunOptions } from './types';
|
|
10
10
|
/**
|
|
11
11
|
* Start ABAP Unit test run on legacy systems
|
|
12
|
-
* Uses /sap/bc/adt/abapunit/testruns endpoint with
|
|
12
|
+
* Uses /sap/bc/adt/abapunit/testruns endpoint with aunit:runConfiguration format
|
|
13
|
+
*
|
|
14
|
+
* Legacy format differs from modern:
|
|
15
|
+
* - Root element: aunit:runConfiguration (not aunit:run)
|
|
16
|
+
* - Namespace: http://www.sap.com/adt/aunit (not http://www.sap.com/adt/api/aunit)
|
|
17
|
+
* - Objects via adtcore:objectReferences with URI (not aunit:tests with containerClass/class)
|
|
18
|
+
* - Content-Type/Accept: application/xml (not versioned vnd.sap.adt.api.abapunit.*)
|
|
13
19
|
*/
|
|
14
|
-
export declare function startClassUnitTestRunLegacy(connection: IAbapConnection, tests: IClassUnitTestDefinition[],
|
|
20
|
+
export declare function startClassUnitTestRunLegacy(connection: IAbapConnection, tests: IClassUnitTestDefinition[], _options?: IClassUnitTestRunOptions): Promise<AxiosResponse>;
|
|
15
21
|
export declare function getClassUnitTestStatusLegacy(connection: IAbapConnection, runId: string, withLongPolling?: boolean): Promise<AxiosResponse>;
|
|
16
22
|
export declare function getClassUnitTestResultLegacy(connection: IAbapConnection, runId: string, options?: {
|
|
17
23
|
withNavigationUris?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runLegacy.d.ts","sourceRoot":"","sources":["../../../src/core/unitTest/runLegacy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"runLegacy.d.ts","sourceRoot":"","sources":["../../../src/core/unitTest/runLegacy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,YAAY,IAAI,aAAa,EAC7B,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAKjB;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,wBAAwB,EAAE,EACjC,QAAQ,CAAC,EAAE,wBAAwB,GAClC,OAAO,CAAC,aAAa,CAAC,CAmCxB;AAED,wBAAsB,4BAA4B,CAChD,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC,aAAa,CAAC,CAaxB;AAED,wBAAsB,4BAA4B,CAChD,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,GACzC,OAAO,CAAC,aAAa,CAAC,CAkBxB"}
|
|
@@ -14,45 +14,38 @@ const internalUtils_1 = require("../../utils/internalUtils");
|
|
|
14
14
|
const timeouts_1 = require("../../utils/timeouts");
|
|
15
15
|
const CT_XML = 'application/xml';
|
|
16
16
|
const ACCEPT_XML = 'application/xml';
|
|
17
|
-
function boolAttr(value, fallback) {
|
|
18
|
-
return (value ?? fallback) ? 'true' : 'false';
|
|
19
|
-
}
|
|
20
17
|
/**
|
|
21
18
|
* Start ABAP Unit test run on legacy systems
|
|
22
|
-
* Uses /sap/bc/adt/abapunit/testruns endpoint with
|
|
19
|
+
* Uses /sap/bc/adt/abapunit/testruns endpoint with aunit:runConfiguration format
|
|
20
|
+
*
|
|
21
|
+
* Legacy format differs from modern:
|
|
22
|
+
* - Root element: aunit:runConfiguration (not aunit:run)
|
|
23
|
+
* - Namespace: http://www.sap.com/adt/aunit (not http://www.sap.com/adt/api/aunit)
|
|
24
|
+
* - Objects via adtcore:objectReferences with URI (not aunit:tests with containerClass/class)
|
|
25
|
+
* - Content-Type/Accept: application/xml (not versioned vnd.sap.adt.api.abapunit.*)
|
|
23
26
|
*/
|
|
24
|
-
async function startClassUnitTestRunLegacy(connection, tests,
|
|
27
|
+
async function startClassUnitTestRunLegacy(connection, tests, _options) {
|
|
25
28
|
if (!tests.length) {
|
|
26
29
|
throw new Error('At least one test definition is required');
|
|
27
30
|
}
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const xml = `<?xml version="1.0" encoding="UTF-8"?><aunit:run xmlns:aunit="http://www.sap.com/adt/api/aunit" title="${options?.title || tests[0].testClass}" context="${options?.context || 'MCP ABAP ADT Client'}">
|
|
47
|
-
<aunit:options>
|
|
48
|
-
<aunit:scope ownTests="${boolAttr(scope.ownTests, true)}" foreignTests="${boolAttr(scope.foreignTests, false)}" addForeignTestsAsPreview="${boolAttr(scope.addForeignTestsAsPreview, true)}"/>
|
|
49
|
-
<aunit:riskLevel harmless="${boolAttr(risk.harmless, true)}" dangerous="${boolAttr(risk.dangerous, true)}" critical="${boolAttr(risk.critical, true)}"/>
|
|
50
|
-
<aunit:duration short="${boolAttr(duration.short, true)}" medium="${boolAttr(duration.medium, true)}" long="${boolAttr(duration.long, true)}"/>
|
|
51
|
-
</aunit:options>
|
|
52
|
-
<aunit:tests>
|
|
53
|
-
${testsXml}
|
|
54
|
-
</aunit:tests>
|
|
55
|
-
</aunit:run>`;
|
|
31
|
+
const objectRefs = tests
|
|
32
|
+
.map((test) => {
|
|
33
|
+
const className = (0, internalUtils_1.encodeSapObjectName)(test.containerClass).toLowerCase();
|
|
34
|
+
return ` <adtcore:objectReference adtcore:uri="/sap/bc/adt/oo/classes/${className}"/>`;
|
|
35
|
+
})
|
|
36
|
+
.join('\n');
|
|
37
|
+
const xml = `<?xml version="1.0" encoding="UTF-8"?><aunit:runConfiguration xmlns:aunit="http://www.sap.com/adt/aunit">
|
|
38
|
+
<external>
|
|
39
|
+
<coverage active="false"/>
|
|
40
|
+
</external>
|
|
41
|
+
<adtcore:objectSets xmlns:adtcore="http://www.sap.com/adt/core">
|
|
42
|
+
<objectSet kind="inclusive">
|
|
43
|
+
<adtcore:objectReferences>
|
|
44
|
+
${objectRefs}
|
|
45
|
+
</adtcore:objectReferences>
|
|
46
|
+
</objectSet>
|
|
47
|
+
</adtcore:objectSets>
|
|
48
|
+
</aunit:runConfiguration>`;
|
|
56
49
|
return connection.makeAdtRequest({
|
|
57
50
|
url: '/sap/bc/adt/abapunit/testruns',
|
|
58
51
|
method: 'POST',
|