apextestlist 1.4.1 → 1.5.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/CHANGELOG.md +31 -0
- package/lib/commands/apextests/list.d.ts +0 -5
- package/lib/commands/apextests/list.js +23 -104
- package/lib/commands/apextests/list.js.map +1 -1
- package/lib/helpers/formatters.d.ts +2 -0
- package/lib/helpers/formatters.js +18 -0
- package/lib/helpers/formatters.js.map +1 -0
- package/lib/helpers/getPackageDirectories.js +4 -3
- package/lib/helpers/getPackageDirectories.js.map +1 -1
- package/lib/helpers/getRepoRoot.js.map +1 -1
- package/lib/helpers/parsers.d.ts +4 -0
- package/lib/helpers/parsers.js +63 -0
- package/lib/helpers/parsers.js.map +1 -0
- package/lib/helpers/readers.d.ts +19 -0
- package/lib/helpers/readers.js +120 -0
- package/lib/helpers/readers.js.map +1 -0
- package/lib/helpers/types.d.ts +4 -0
- package/oclif.lock +16 -16
- package/oclif.manifest.json +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<!-- markdownlint-disable MD024 MD025 -->
|
|
2
|
+
<!-- markdown-link-check-disable -->
|
|
3
|
+
|
|
4
|
+
# Changelog
|
|
5
|
+
|
|
6
|
+
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
7
|
+
|
|
8
|
+
## [1.4.2](https://github.com/renatoliveira/apex-test-list/compare/v1.4.1...v1.4.2) (2024-10-15)
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
- ignores case sensitivity on the line cleanup too ([c41056f](https://github.com/renatoliveira/apex-test-list/commit/c41056faedd6476f2bc223a1ea4f05a5a05ae35e))
|
|
13
|
+
- ignores case sensitivity when reading tests and test suites names on files ([c737d0e](https://github.com/renatoliveira/apex-test-list/commit/c737d0e62eec36d95a1bcd0e69f83e7cf42b694e))
|
|
14
|
+
|
|
15
|
+
## [1.4.1](https://github.com/renatoliveira/apex-test-list/compare/v1.4.0...v1.4.1) (2024-10-07)
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
- **deps:** bump @oclif/core from 4.0.22 to 4.0.27 ([a3e7502](https://github.com/renatoliveira/apex-test-list/commit/a3e750201e23cdf1bf8a17652cd1d2854cc38007))
|
|
20
|
+
- **deps:** bump @salesforce/core from 8.5.7 to 8.6.1 ([efac530](https://github.com/renatoliveira/apex-test-list/commit/efac530945c589605a70363a777ba0c7b5aabed5))
|
|
21
|
+
|
|
22
|
+
## [1.4.0](https://github.com/renatoliveira/apex-test-list/compare/v1.1.0...v1.4.0) (2024-09-20)
|
|
23
|
+
|
|
24
|
+
### Features
|
|
25
|
+
|
|
26
|
+
- read sfdx-project.json for package directories ([fc58565](https://github.com/renatoliveira/apex-test-list/commit/fc58565a7e7d036393bb667de4447daca6f976f3))
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
- convert to set to remove duplicate test methods ([3385541](https://github.com/renatoliveira/apex-test-list/commit/3385541b86d9570a89bb4a33a771baecc824c826))
|
|
31
|
+
- reverts Yarn version in packageManager to 1.22.22 ([7ec0c02](https://github.com/renatoliveira/apex-test-list/commit/7ec0c02b52ae7b9f98052cd1dc7c81573f449dbb))
|
|
@@ -12,10 +12,5 @@ export default class ApextestsList extends SfCommand<ApextestsListResult> {
|
|
|
12
12
|
manifest: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
13
|
'ignore-missing-tests': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
14
|
};
|
|
15
|
-
protected static getConcurrencyThreshold(): number;
|
|
16
|
-
private static parseTestsNames;
|
|
17
|
-
private static searchTestClasses;
|
|
18
|
-
private static formatList;
|
|
19
|
-
private static extractClassNamesFromManifestFile;
|
|
20
15
|
run(): Promise<ApextestsListResult>;
|
|
21
16
|
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
1
2
|
'use strict';
|
|
2
3
|
/* eslint-disable no-await-in-loop */
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
|
-
import { availableParallelism } from 'node:os';
|
|
5
4
|
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
6
5
|
import { Messages } from '@salesforce/core';
|
|
7
|
-
import { queue } from 'async';
|
|
8
|
-
import { Parser } from 'xml2js';
|
|
9
6
|
import { getPackageDirectories } from '../../helpers/getPackageDirectories.js';
|
|
10
7
|
import { validateTests } from '../../helpers/validateTests.js';
|
|
8
|
+
import { extractTypeNamesFromManifestFile } from '../../helpers/parsers.js';
|
|
9
|
+
import { formatList } from '../../helpers/formatters.js';
|
|
10
|
+
import { searchDirectoryForTestClasses, searchDirectoryForTestNamesInTestSuites } from '../../helpers/readers.js';
|
|
11
11
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
12
12
|
const messages = Messages.loadMessages('apextestlist', 'apextests.list');
|
|
13
|
-
const TEST_NAME_REGEX = /(@(Tests|TestSuites)).+/g;
|
|
14
13
|
export default class ApextestsList extends SfCommand {
|
|
15
14
|
static summary = messages.getMessage('summary');
|
|
16
15
|
static description = messages.getMessage('description');
|
|
@@ -36,98 +35,6 @@ export default class ApextestsList extends SfCommand {
|
|
|
36
35
|
default: false,
|
|
37
36
|
}),
|
|
38
37
|
};
|
|
39
|
-
static getConcurrencyThreshold() {
|
|
40
|
-
const AVAILABLE_PARALLELISM = availableParallelism ? availableParallelism() : Infinity;
|
|
41
|
-
return Math.min(AVAILABLE_PARALLELISM, 6);
|
|
42
|
-
}
|
|
43
|
-
static parseTestsNames(testNames) {
|
|
44
|
-
if (!testNames || testNames.length === 0) {
|
|
45
|
-
return [];
|
|
46
|
-
}
|
|
47
|
-
// remove the prefix @Tests or @TestSuites
|
|
48
|
-
return testNames
|
|
49
|
-
.join(',')
|
|
50
|
-
.split(',')
|
|
51
|
-
.map((line) => line.replace(/(@Tests|@TestSuites):/, ''))
|
|
52
|
-
.map((line) => line.trim())
|
|
53
|
-
.filter((line) => line);
|
|
54
|
-
}
|
|
55
|
-
static async searchTestClasses(directory, names) {
|
|
56
|
-
const testMethodsNames = [];
|
|
57
|
-
let readDir;
|
|
58
|
-
try {
|
|
59
|
-
readDir = fs.readdirSync(directory, { recursive: true });
|
|
60
|
-
}
|
|
61
|
-
catch (error) {
|
|
62
|
-
throw new Error('Invalid directory.');
|
|
63
|
-
}
|
|
64
|
-
const localFiles = readDir.filter((file) => {
|
|
65
|
-
if (!file.endsWith('.cls') && !file.endsWith('.trigger')) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
const fileFullName = file.split('/').pop()?.split('.');
|
|
69
|
-
if (!names) {
|
|
70
|
-
return fileFullName;
|
|
71
|
-
}
|
|
72
|
-
if (fileFullName && fileFullName.length > 0) {
|
|
73
|
-
const formattedName = `${fileFullName[1] === 'cls' ? 'ApexClass' : 'ApexTrigger'}:${fileFullName[0]}`;
|
|
74
|
-
return names.includes(formattedName);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
const handler = (fileName) => {
|
|
78
|
-
const path = `${directory}/${fileName}`;
|
|
79
|
-
const data = fs.readFileSync(path, 'utf-8');
|
|
80
|
-
const testMethods = data.match(TEST_NAME_REGEX);
|
|
81
|
-
testMethodsNames.push(...ApextestsList.parseTestsNames(testMethods));
|
|
82
|
-
};
|
|
83
|
-
const processor = queue((f, cb) => {
|
|
84
|
-
handler(f);
|
|
85
|
-
cb();
|
|
86
|
-
}, this.getConcurrencyThreshold());
|
|
87
|
-
await processor.push(localFiles);
|
|
88
|
-
if (processor.length() > 0) {
|
|
89
|
-
await processor.drain();
|
|
90
|
-
}
|
|
91
|
-
return testMethodsNames.sort();
|
|
92
|
-
}
|
|
93
|
-
static formatList(format, tests) {
|
|
94
|
-
switch (format) {
|
|
95
|
-
case 'sf':
|
|
96
|
-
return Promise.resolve({
|
|
97
|
-
tests,
|
|
98
|
-
command: '--tests ' + tests.join(' '),
|
|
99
|
-
});
|
|
100
|
-
case 'csv':
|
|
101
|
-
return Promise.resolve({
|
|
102
|
-
tests,
|
|
103
|
-
command: tests.join(','),
|
|
104
|
-
});
|
|
105
|
-
default:
|
|
106
|
-
throw new Error('Invalid format.');
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
static async extractClassNamesFromManifestFile(manifestFile) {
|
|
110
|
-
const result = [];
|
|
111
|
-
if (!manifestFile || !fs.existsSync(manifestFile)) {
|
|
112
|
-
return result;
|
|
113
|
-
}
|
|
114
|
-
const xmlParser = new Parser();
|
|
115
|
-
await xmlParser
|
|
116
|
-
.parseStringPromise(fs.readFileSync(manifestFile, 'utf-8'))
|
|
117
|
-
.then((parsed) => {
|
|
118
|
-
parsed.Package.types.forEach((type) => {
|
|
119
|
-
if (type.name.includes('ApexClass') || type.name.includes('ApexTrigger')) {
|
|
120
|
-
type.members.forEach((member) => {
|
|
121
|
-
result.push(`${type.name}:${member}`);
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
})
|
|
126
|
-
.catch((error) => {
|
|
127
|
-
throw error;
|
|
128
|
-
});
|
|
129
|
-
return result.sort((a, b) => a.localeCompare(b));
|
|
130
|
-
}
|
|
131
38
|
async run() {
|
|
132
39
|
const { flags } = await this.parse(ApextestsList);
|
|
133
40
|
const format = flags.format ?? 'sf';
|
|
@@ -135,19 +42,31 @@ export default class ApextestsList extends SfCommand {
|
|
|
135
42
|
const ignoreMissingTests = flags['ignore-missing-tests'] ?? false;
|
|
136
43
|
let result = null;
|
|
137
44
|
let testClassesNames = null;
|
|
138
|
-
|
|
45
|
+
const testSuitesNames = [];
|
|
46
|
+
// Get package directories full paths
|
|
139
47
|
const packageDirectories = await getPackageDirectories();
|
|
140
48
|
if (manifest) {
|
|
141
|
-
|
|
49
|
+
const manifesMetadata = await extractTypeNamesFromManifestFile(manifest);
|
|
50
|
+
testClassesNames = manifesMetadata.filter((name) => !name.endsWith('testSuite-meta.xml'));
|
|
142
51
|
}
|
|
143
|
-
const
|
|
52
|
+
const allTestClasses = [];
|
|
144
53
|
// Loop through each directory and search for test classes
|
|
145
54
|
for (const directory of packageDirectories) {
|
|
146
|
-
const
|
|
147
|
-
|
|
55
|
+
const searchResult = await searchDirectoryForTestClasses(directory, testClassesNames);
|
|
56
|
+
const testClassesInDir = searchResult.classes;
|
|
57
|
+
const testSuitesMentioned = searchResult.testSuites;
|
|
58
|
+
allTestClasses.push(...testClassesInDir);
|
|
59
|
+
testSuitesNames.push(...testSuitesMentioned);
|
|
60
|
+
}
|
|
61
|
+
if (testSuitesNames.length > 0) {
|
|
62
|
+
// read the testSuite directory again to get the classes listed on them
|
|
63
|
+
for (const directory of packageDirectories.filter((dir) => dir.includes('testSuites'))) {
|
|
64
|
+
const testNames = await searchDirectoryForTestNamesInTestSuites(directory);
|
|
65
|
+
allTestClasses.push(...testNames);
|
|
66
|
+
}
|
|
148
67
|
}
|
|
149
68
|
// Ensure all test methods are unique by using a Set
|
|
150
|
-
let finalTestMethods = Array.from(new Set(
|
|
69
|
+
let finalTestMethods = Array.from(new Set(allTestClasses.map((test) => test.trim())));
|
|
151
70
|
// If ignore-missing-tests is true, validate the test methods
|
|
152
71
|
if (ignoreMissingTests) {
|
|
153
72
|
const { validatedTests, warnings } = await validateTests(finalTestMethods, packageDirectories);
|
|
@@ -166,7 +85,7 @@ export default class ApextestsList extends SfCommand {
|
|
|
166
85
|
}
|
|
167
86
|
finalTestMethods.sort((a, b) => a.localeCompare(b));
|
|
168
87
|
if (finalTestMethods.length > 0) {
|
|
169
|
-
result =
|
|
88
|
+
result = formatList(format, finalTestMethods);
|
|
170
89
|
}
|
|
171
90
|
else {
|
|
172
91
|
throw new Error('No test methods found');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/apextests/list.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,qCAAqC;AAErC,OAAO,
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/apextests/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
export async function formatList(format, tests) {
|
|
3
|
+
switch (format) {
|
|
4
|
+
case 'sf':
|
|
5
|
+
return Promise.resolve({
|
|
6
|
+
tests,
|
|
7
|
+
command: '--tests ' + tests.join(' '),
|
|
8
|
+
});
|
|
9
|
+
case 'csv':
|
|
10
|
+
return Promise.resolve({
|
|
11
|
+
tests,
|
|
12
|
+
command: tests.join(','),
|
|
13
|
+
});
|
|
14
|
+
default:
|
|
15
|
+
throw new Error('Invalid format.');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=formatters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../src/helpers/formatters.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAGb,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc,EAAE,KAAe;IAC9D,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,IAAI;YACP,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,KAAK;gBACL,OAAO,EAAE,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;aACtC,CAAC,CAAC;QACL,KAAK,KAAK;YACR,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,KAAK;gBACL,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;aACzB,CAAC,CAAC;QACL;YACE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACvC,CAAC;AACH,CAAC"}
|
|
@@ -5,6 +5,7 @@ import { resolve, join } from 'node:path';
|
|
|
5
5
|
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
6
6
|
import { SFDX_PROJECT_FILE_NAME } from './constants.js';
|
|
7
7
|
import { getRepoRoot } from './getRepoRoot.js';
|
|
8
|
+
const SEARCHABLE_METADATA_FOLDERS = ['classes', 'triggers', 'testSuites'];
|
|
8
9
|
export async function getPackageDirectories() {
|
|
9
10
|
const repoRoot = await getRepoRoot();
|
|
10
11
|
process.chdir(repoRoot);
|
|
@@ -17,9 +18,9 @@ export async function getPackageDirectories() {
|
|
|
17
18
|
const packageDirectories = sfdxProject.packageDirectories.map((directory) => resolve(repoRoot, directory.path));
|
|
18
19
|
const metadataPaths = [];
|
|
19
20
|
for (const directory of packageDirectories) {
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
metadataPaths.push(...
|
|
21
|
+
const mdPath = await searchForSubFolders(directory, SEARCHABLE_METADATA_FOLDERS);
|
|
22
|
+
if (mdPath.length > 0) {
|
|
23
|
+
metadataPaths.push(...mdPath);
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
return metadataPaths;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPackageDirectories.js","sourceRoot":"","sources":["../../src/helpers/getPackageDirectories.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,qCAAqC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"getPackageDirectories.js","sourceRoot":"","sources":["../../src/helpers/getPackageDirectories.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,qCAAqC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,MAAM,2BAA2B,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AAE1E,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAC;IAErC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAExB,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;IAE/D,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,0DAA0D,YAAY,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,cAAc,GAAW,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACrE,MAAM,WAAW,GAAgB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAgB,CAAC;IAC3E,MAAM,kBAAkB,GAAG,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAChH,MAAM,aAAa,GAAa,EAAE,CAAC;IAEnC,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,SAAS,EAAE,2BAA2B,CAAC,CAAC;QAEjF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,aAAa,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,WAAmB,EAAE,iBAA2B;IACjF,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;IAEzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEnC,+DAA+D;QAC/D,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5D,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QACD,oEAAoE;aAC/D,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;YACtE,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRepoRoot.js","sourceRoot":"","sources":["../../src/helpers/getRepoRoot.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,GAAG,MAAM,gBAAgB,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"getRepoRoot.js","sourceRoot":"","sources":["../../src/helpers/getRepoRoot.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,GAAG,MAAM,gBAAgB,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAE7D,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC;QAClC,EAAE;QACF,QAAQ,EAAE,OAAO,CAAC,GAAG,EAAE;KACxB,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function extractTypeNamesFromManifestFile(manifestFile: string): Promise<string[]>;
|
|
2
|
+
export declare function parseTestSuiteFile(data: string): string[];
|
|
3
|
+
export declare function parseTestsNames(testNames: string[] | null): string[];
|
|
4
|
+
export declare function parseTestSuitesNames(testSuitesNames: string[] | null): string[];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { Parser } from 'xml2js';
|
|
4
|
+
export async function extractTypeNamesFromManifestFile(manifestFile) {
|
|
5
|
+
const result = [];
|
|
6
|
+
if (!manifestFile || !existsSync(manifestFile)) {
|
|
7
|
+
return result;
|
|
8
|
+
}
|
|
9
|
+
await new Parser()
|
|
10
|
+
.parseStringPromise(readFileSync(manifestFile, 'utf-8'))
|
|
11
|
+
.then((parsed) => {
|
|
12
|
+
parsed.Package.types.forEach((type) => {
|
|
13
|
+
if (type.name.includes('ApexClass') ||
|
|
14
|
+
type.name.includes('ApexTrigger') ||
|
|
15
|
+
type.name.includes('ApexTestSuite')) {
|
|
16
|
+
type.members.forEach((member) => {
|
|
17
|
+
result.push(`${type.name}:${member}`);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
})
|
|
22
|
+
.catch((error) => {
|
|
23
|
+
throw error;
|
|
24
|
+
});
|
|
25
|
+
return result.sort((a, b) => a.localeCompare(b));
|
|
26
|
+
}
|
|
27
|
+
export function parseTestSuiteFile(data) {
|
|
28
|
+
const result = [];
|
|
29
|
+
new Parser().parseString(data, (error, parsed) => {
|
|
30
|
+
if (error) {
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
parsed.ApexTestSuite.testClassName.forEach((testSuite) => {
|
|
34
|
+
result.push(testSuite);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
return result.sort();
|
|
38
|
+
}
|
|
39
|
+
export function parseTestsNames(testNames) {
|
|
40
|
+
if (!testNames || testNames.length === 0) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
// remove the prefix @Tests or @TestSuites
|
|
44
|
+
return testNames
|
|
45
|
+
.join(',')
|
|
46
|
+
.split(',')
|
|
47
|
+
.map((line) => line.replace(/(@Tests):/, ''))
|
|
48
|
+
.map((line) => line.trim())
|
|
49
|
+
.filter((line) => line);
|
|
50
|
+
}
|
|
51
|
+
export function parseTestSuitesNames(testSuitesNames) {
|
|
52
|
+
if (!testSuitesNames || testSuitesNames.length === 0) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
// return [];
|
|
56
|
+
return testSuitesNames
|
|
57
|
+
.join(',')
|
|
58
|
+
.split(',')
|
|
59
|
+
.map((line) => line.replace(/(@TestSuites):/, ''))
|
|
60
|
+
.map((line) => line.trim())
|
|
61
|
+
.filter((line) => line);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=parsers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsers.js","sourceRoot":"","sources":["../../src/helpers/parsers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SearchResult } from './types.js';
|
|
2
|
+
export declare function getConcurrencyThreshold(): number;
|
|
3
|
+
/**
|
|
4
|
+
* Given a certain directory, search its contents for files that end with '.testSuite-meta.xml'
|
|
5
|
+
* and extract the class names mentioned in the test suites.
|
|
6
|
+
*
|
|
7
|
+
* @param directory directory within the project to search for files
|
|
8
|
+
* @returns a Promise<string> with a list of test names
|
|
9
|
+
*/
|
|
10
|
+
export declare function searchDirectoryForTestNamesInTestSuites(directory: string): Promise<string[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Given a certain directory, search its contents for files that end with '.cls' or '.trigger'.
|
|
13
|
+
* Extracts the test names from the annotations on those files, and returns a list with those.
|
|
14
|
+
*
|
|
15
|
+
* @param directory directory within the project to search for files
|
|
16
|
+
* @param names names of test files
|
|
17
|
+
* @returns list of test classes
|
|
18
|
+
*/
|
|
19
|
+
export declare function searchDirectoryForTestClasses(directory: string, names: string[] | null): Promise<SearchResult>;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
'use strict';
|
|
3
|
+
import { availableParallelism } from 'node:os';
|
|
4
|
+
import { readdirSync, readFileSync } from 'node:fs';
|
|
5
|
+
import { queue } from 'async';
|
|
6
|
+
import { parseTestsNames, parseTestSuiteFile, parseTestSuitesNames } from './parsers.js';
|
|
7
|
+
const TEST_NAME_REGEX = /(@Tests).+/g;
|
|
8
|
+
const TEST_SUITE_NAME_REGEX = /(@TestSuites).+/g;
|
|
9
|
+
export function getConcurrencyThreshold() {
|
|
10
|
+
const AVAILABLE_PARALLELISM = availableParallelism ? availableParallelism() : Infinity;
|
|
11
|
+
return Math.min(AVAILABLE_PARALLELISM, 6);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Given a certain directory, search its contents for files that end with '.testSuite-meta.xml'
|
|
15
|
+
* and extract the class names mentioned in the test suites.
|
|
16
|
+
*
|
|
17
|
+
* @param directory directory within the project to search for files
|
|
18
|
+
* @returns a Promise<string> with a list of test names
|
|
19
|
+
*/
|
|
20
|
+
export async function searchDirectoryForTestNamesInTestSuites(directory) {
|
|
21
|
+
const testClassesNames = new Set();
|
|
22
|
+
let readDir;
|
|
23
|
+
try {
|
|
24
|
+
readDir = readdirSync(directory, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw new Error(`Invalid or inaccessible directory: ${directory}`);
|
|
28
|
+
}
|
|
29
|
+
// Gets the list of test suites
|
|
30
|
+
const suiteFiles = readDir.filter((file) => file.endsWith('.testSuite-meta.xml'));
|
|
31
|
+
// Function that handles the parsing of test suites and helps to build the
|
|
32
|
+
// list of test classes for the next steps
|
|
33
|
+
const testSuiteNameHandler = (fileName) => {
|
|
34
|
+
const path = `${directory}/${fileName}`;
|
|
35
|
+
const data = readFileSync(path, 'utf-8');
|
|
36
|
+
const classes = parseTestSuiteFile(data);
|
|
37
|
+
// TODO: Support for wildcards
|
|
38
|
+
for (const test of classes.filter((name) => !name.includes('*'))) {
|
|
39
|
+
testClassesNames.add(test);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
// define the processors
|
|
43
|
+
const testSuiteNameProcessor = queue((f, cb) => {
|
|
44
|
+
testSuiteNameHandler(f);
|
|
45
|
+
cb();
|
|
46
|
+
}, getConcurrencyThreshold());
|
|
47
|
+
// initialize the processor with the names of files we want to process
|
|
48
|
+
await testSuiteNameProcessor.push(suiteFiles);
|
|
49
|
+
// make sure no dangling process is left before continuing
|
|
50
|
+
if (testSuiteNameProcessor.length() > 0) {
|
|
51
|
+
await testSuiteNameProcessor.drain();
|
|
52
|
+
}
|
|
53
|
+
return Array.from(testClassesNames).sort();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Given a certain directory, search its contents for files that end with '.cls' or '.trigger'.
|
|
57
|
+
* Extracts the test names from the annotations on those files, and returns a list with those.
|
|
58
|
+
*
|
|
59
|
+
* @param directory directory within the project to search for files
|
|
60
|
+
* @param names names of test files
|
|
61
|
+
* @returns list of test classes
|
|
62
|
+
*/
|
|
63
|
+
export async function searchDirectoryForTestClasses(directory, names) {
|
|
64
|
+
const testClassesNames = new Set();
|
|
65
|
+
const testSuitesNames = new Set();
|
|
66
|
+
let readDir;
|
|
67
|
+
try {
|
|
68
|
+
readDir = readdirSync(directory, { recursive: true });
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
throw new Error(`Invalid or inaccessible directory: ${directory}`);
|
|
72
|
+
}
|
|
73
|
+
// Gets the list of Apex files (classes and triggers)
|
|
74
|
+
const apexFiles = readDir.filter((file) => {
|
|
75
|
+
if (!file.endsWith('.cls') && !file.endsWith('.trigger')) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
const fileFullName = file.split('/').pop()?.split('.');
|
|
79
|
+
if (!names) {
|
|
80
|
+
return fileFullName;
|
|
81
|
+
}
|
|
82
|
+
if (fileFullName && fileFullName.length > 0) {
|
|
83
|
+
const formattedName = `${fileFullName[1] === 'cls' ? 'ApexClass' : 'ApexTrigger'}:${fileFullName[0]}`;
|
|
84
|
+
return names.includes(formattedName);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
// Function that handles the parsing of test classes and helps to build the
|
|
88
|
+
// list of test classes
|
|
89
|
+
const testClassNameHandler = (fileName) => {
|
|
90
|
+
const path = `${directory}/${fileName}`;
|
|
91
|
+
const data = readFileSync(path, 'utf-8');
|
|
92
|
+
const matches = data.match(TEST_NAME_REGEX);
|
|
93
|
+
parseTestsNames(matches).forEach((testMethod) => {
|
|
94
|
+
testClassesNames.add(testMethod);
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
const testSuiteNameHandler = (fileName) => {
|
|
98
|
+
const path = `${directory}/${fileName}`;
|
|
99
|
+
const data = readFileSync(path, 'utf-8');
|
|
100
|
+
const matches = data.match(TEST_SUITE_NAME_REGEX);
|
|
101
|
+
parseTestSuitesNames(matches).forEach((testMethod) => {
|
|
102
|
+
testSuitesNames.add(testMethod);
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
// initialize the processor with the names of files we want to process
|
|
106
|
+
const testClassNameProcessor = queue((f, cb) => {
|
|
107
|
+
testClassNameHandler(f);
|
|
108
|
+
testSuiteNameHandler(f);
|
|
109
|
+
cb();
|
|
110
|
+
}, getConcurrencyThreshold());
|
|
111
|
+
// initialize the processor with the names of files we want to process
|
|
112
|
+
await testClassNameProcessor.push(apexFiles);
|
|
113
|
+
// make sure no dangling process is left before continuing
|
|
114
|
+
if (testClassNameProcessor.length() > 0) {
|
|
115
|
+
await testClassNameProcessor.drain();
|
|
116
|
+
}
|
|
117
|
+
// return the list of apex tests, sorted
|
|
118
|
+
return { classes: Array.from(testClassesNames), testSuites: Array.from(testSuitesNames) };
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=readers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readers.js","sourceRoot":"","sources":["../../src/helpers/readers.ts"],"names":[],"mappings":"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"}
|
package/lib/helpers/types.d.ts
CHANGED
package/oclif.lock
CHANGED
|
@@ -1331,11 +1331,11 @@
|
|
|
1331
1331
|
version "1.1.0"
|
|
1332
1332
|
resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8"
|
|
1333
1333
|
|
|
1334
|
-
"@salesforce/cli-plugins-testkit@^5.3.
|
|
1335
|
-
version "5.3.
|
|
1336
|
-
resolved "https://registry.yarnpkg.com/@salesforce/cli-plugins-testkit/-/cli-plugins-testkit-5.3.
|
|
1334
|
+
"@salesforce/cli-plugins-testkit@^5.3.34":
|
|
1335
|
+
version "5.3.34"
|
|
1336
|
+
resolved "https://registry.yarnpkg.com/@salesforce/cli-plugins-testkit/-/cli-plugins-testkit-5.3.34.tgz#456503a30dade3459e1736a77a362fce2b41947b"
|
|
1337
1337
|
dependencies:
|
|
1338
|
-
"@salesforce/core" "^8.6.
|
|
1338
|
+
"@salesforce/core" "^8.6.2"
|
|
1339
1339
|
"@salesforce/kit" "^3.2.3"
|
|
1340
1340
|
"@salesforce/ts-types" "^2.0.11"
|
|
1341
1341
|
"@types/shelljs" "^0.8.15"
|
|
@@ -1346,9 +1346,9 @@
|
|
|
1346
1346
|
strip-ansi "6.0.1"
|
|
1347
1347
|
ts-retry-promise "^0.8.1"
|
|
1348
1348
|
|
|
1349
|
-
"@salesforce/core@^8.5.1", "@salesforce/core@^8.
|
|
1350
|
-
version "8.6.
|
|
1351
|
-
resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-8.6.
|
|
1349
|
+
"@salesforce/core@^8.5.1", "@salesforce/core@^8.6.1", "@salesforce/core@^8.6.2":
|
|
1350
|
+
version "8.6.2"
|
|
1351
|
+
resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-8.6.2.tgz#50120d923504ceb04604b7f03e359386845a9f9d"
|
|
1352
1352
|
dependencies:
|
|
1353
1353
|
"@jsforce/jsforce-node" "^3.4.1"
|
|
1354
1354
|
"@salesforce/kit" "^3.2.2"
|
|
@@ -2045,8 +2045,8 @@
|
|
|
2045
2045
|
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e"
|
|
2046
2046
|
|
|
2047
2047
|
"@types/mocha@^10", "@types/mocha@^10.0.7":
|
|
2048
|
-
version "10.0.
|
|
2049
|
-
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.
|
|
2048
|
+
version "10.0.9"
|
|
2049
|
+
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.9.tgz#101e9da88d2c02e5ac8952982c23b224524d662a"
|
|
2050
2050
|
|
|
2051
2051
|
"@types/mute-stream@^0.0.4":
|
|
2052
2052
|
version "0.0.4"
|
|
@@ -2054,9 +2054,9 @@
|
|
|
2054
2054
|
dependencies:
|
|
2055
2055
|
"@types/node" "*"
|
|
2056
2056
|
|
|
2057
|
-
"@types/node@*", "@types/node@^22.5.5", "@types/node@^22.7.
|
|
2058
|
-
version "22.7.
|
|
2059
|
-
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.
|
|
2057
|
+
"@types/node@*", "@types/node@^22.5.5", "@types/node@^22.7.5":
|
|
2058
|
+
version "22.7.5"
|
|
2059
|
+
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b"
|
|
2060
2060
|
dependencies:
|
|
2061
2061
|
undici-types "~6.19.2"
|
|
2062
2062
|
|
|
@@ -3412,11 +3412,11 @@ eslint-plugin-jsdoc@^46.10.1:
|
|
|
3412
3412
|
semver "^7.5.4"
|
|
3413
3413
|
spdx-expression-parse "^4.0.0"
|
|
3414
3414
|
|
|
3415
|
-
eslint-plugin-sf-plugin@^1.20.
|
|
3416
|
-
version "1.20.
|
|
3417
|
-
resolved "https://registry.yarnpkg.com/eslint-plugin-sf-plugin/-/eslint-plugin-sf-plugin-1.20.
|
|
3415
|
+
eslint-plugin-sf-plugin@^1.20.9:
|
|
3416
|
+
version "1.20.9"
|
|
3417
|
+
resolved "https://registry.yarnpkg.com/eslint-plugin-sf-plugin/-/eslint-plugin-sf-plugin-1.20.9.tgz#87d17902f696ac242a1b7c6ccbb43f271d883e7e"
|
|
3418
3418
|
dependencies:
|
|
3419
|
-
"@salesforce/core" "^8.
|
|
3419
|
+
"@salesforce/core" "^8.6.2"
|
|
3420
3420
|
"@typescript-eslint/utils" "^7.18.0"
|
|
3421
3421
|
|
|
3422
3422
|
eslint-plugin-unicorn@^50.0.1:
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apextestlist",
|
|
3
3
|
"description": "A plugin that generates a list of apex test and test suite names for use in CI/CD pipelines.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@oclif/core": "4.0.27",
|
|
7
7
|
"@salesforce/core": "^8.6.1",
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
"@commitlint/cli": "^19.5.0",
|
|
15
15
|
"@commitlint/config-conventional": "^19.5.0",
|
|
16
16
|
"@oclif/plugin-command-snapshot": "^5.2.18",
|
|
17
|
-
"@salesforce/cli-plugins-testkit": "^5.3.
|
|
17
|
+
"@salesforce/cli-plugins-testkit": "^5.3.34",
|
|
18
18
|
"@salesforce/dev-scripts": "^10.2.10",
|
|
19
19
|
"@types/async": "^3.2.24",
|
|
20
20
|
"@types/mocha": "^10",
|
|
21
|
-
"@types/node": "^22.7.
|
|
21
|
+
"@types/node": "^22.7.5",
|
|
22
22
|
"@types/xml2js": "^0.4.14",
|
|
23
|
-
"eslint-plugin-sf-plugin": "^1.20.
|
|
23
|
+
"eslint-plugin-sf-plugin": "^1.20.9",
|
|
24
24
|
"husky": "^9.1.6",
|
|
25
25
|
"mocha": "^10.7.3",
|
|
26
26
|
"nyc": "^17.1.0",
|