sf-delta-tests 0.1.0 → 0.2.1
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 +59 -90
- package/lib/commands/delta/test-classes.d.ts +10 -10
- package/lib/commands/delta/test-classes.js +61 -46
- package/lib/commands/delta/test-classes.js.map +1 -1
- package/lib/elements/object-types.js +23 -26
- package/lib/elements/object-types.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -2
- package/lib/index.js.map +1 -1
- package/lib/services/apex-class-service.js +8 -12
- package/lib/services/apex-class-service.js.map +1 -1
- package/lib/services/cli-service.js +1 -5
- package/lib/services/cli-service.js.map +1 -1
- package/lib/services/dependency-service.js +19 -22
- package/lib/services/dependency-service.js.map +1 -1
- package/lib/services/dependency-services.test.js +6 -8
- package/lib/services/dependency-services.test.js.map +1 -1
- package/lib/services/flow-service.d.ts +22 -5
- package/lib/services/flow-service.js +72 -50
- package/lib/services/flow-service.js.map +1 -1
- package/lib/services/manifest-service.d.ts +1 -1
- package/lib/services/manifest-service.js +5 -9
- package/lib/services/manifest-service.js.map +1 -1
- package/lib/services/output-service.d.ts +1 -1
- package/lib/services/output-service.js +10 -13
- package/lib/services/output-service.js.map +1 -1
- package/messages/delta.test-classes.md +1 -1
- package/oclif.manifest.json +46 -25
- package/package.json +215 -158
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/* eslint-disable class-methods-use-this */
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class DependencyService {
|
|
2
|
+
import { sortBy } from '@salesforce/kit';
|
|
3
|
+
import lodash from 'lodash';
|
|
4
|
+
import { APEX_CLASS, defaultTypesToFetchFromDependencyServer } from '../elements/object-types.js';
|
|
5
|
+
export class DependencyService {
|
|
6
|
+
connection;
|
|
9
7
|
connect(connection) {
|
|
10
8
|
this.connection = connection;
|
|
11
9
|
}
|
|
12
10
|
async getDependenciesByObjects(additionalObjects = []) {
|
|
13
|
-
const objects = new Set([...
|
|
11
|
+
const objects = new Set([...defaultTypesToFetchFromDependencyServer, ...additionalObjects]);
|
|
14
12
|
const promises = [];
|
|
15
13
|
objects.forEach((object) => promises.push(this.getDependencyByObject(object)));
|
|
16
14
|
const results = await Promise.all(promises);
|
|
17
15
|
// return oua;
|
|
18
|
-
return
|
|
16
|
+
return lodash.uniqBy(results.flat(), (result) => result.MetadataComponentName +
|
|
19
17
|
result.MetadataComponentType +
|
|
20
18
|
result.RefMetadataComponentName +
|
|
21
19
|
result.RefMetadataComponentType);
|
|
@@ -28,9 +26,9 @@ class DependencyService {
|
|
|
28
26
|
directDependencies.add(depData);
|
|
29
27
|
}
|
|
30
28
|
}
|
|
31
|
-
const dependencies = Array.from(this.getRelations(dependencyList.filter((depData) => depData.RefMetadataComponentType ===
|
|
32
|
-
return
|
|
33
|
-
.filter((dependency) => dependency.MetadataComponentType ===
|
|
29
|
+
const dependencies = Array.from(this.getRelations(dependencyList.filter((depData) => depData.RefMetadataComponentType === APEX_CLASS), directDependencies));
|
|
30
|
+
return lodash.uniq(dependencies
|
|
31
|
+
.filter((dependency) => dependency.MetadataComponentType === APEX_CLASS)
|
|
34
32
|
.map((dependency) => dependency.MetadataComponentName));
|
|
35
33
|
}
|
|
36
34
|
getRelations(dependenciesRelatingToApex, relatedDependencies, relationCounter = 0) {
|
|
@@ -60,22 +58,21 @@ class DependencyService {
|
|
|
60
58
|
}
|
|
61
59
|
const dependencies = await this.connection.tooling.query(this.getDependencySoql(objectType));
|
|
62
60
|
const refDependencies = await this.connection.tooling.query(this.getRefDependencySoql(objectType));
|
|
63
|
-
return
|
|
61
|
+
return sortBy([...dependencies.records, ...refDependencies.records], ['MetadataComponentType', 'RefMetadataComponentType']);
|
|
64
62
|
}
|
|
65
63
|
getDependencySoql(objectType) {
|
|
66
|
-
return `SELECT MetadataComponentName, MetadataComponentType, RefMetadataComponentName, RefMetadataComponentType
|
|
67
|
-
FROM MetadataComponentDependency
|
|
68
|
-
WHERE MetadataComponentType = '${objectType}'
|
|
69
|
-
AND MetadataComponentNamespace = NULL
|
|
64
|
+
return `SELECT MetadataComponentName, MetadataComponentType, RefMetadataComponentName, RefMetadataComponentType
|
|
65
|
+
FROM MetadataComponentDependency
|
|
66
|
+
WHERE MetadataComponentType = '${objectType}'
|
|
67
|
+
AND MetadataComponentNamespace = NULL
|
|
70
68
|
AND RefMetadataComponentNamespace = NULL`;
|
|
71
69
|
}
|
|
72
70
|
getRefDependencySoql(objectType) {
|
|
73
|
-
return `SELECT MetadataComponentName, MetadataComponentType, RefMetadataComponentName, RefMetadataComponentType
|
|
74
|
-
FROM MetadataComponentDependency
|
|
75
|
-
WHERE RefMetadataComponentType = '${objectType}'
|
|
76
|
-
AND MetadataComponentNamespace = NULL
|
|
71
|
+
return `SELECT MetadataComponentName, MetadataComponentType, RefMetadataComponentName, RefMetadataComponentType
|
|
72
|
+
FROM MetadataComponentDependency
|
|
73
|
+
WHERE RefMetadataComponentType = '${objectType}'
|
|
74
|
+
AND MetadataComponentNamespace = NULL
|
|
77
75
|
AND RefMetadataComponentNamespace = NULL`;
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
|
-
exports.DependencyService = DependencyService;
|
|
81
78
|
//# sourceMappingURL=dependency-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-service.js","sourceRoot":"","sources":["../../src/services/dependency-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dependency-service.js","sourceRoot":"","sources":["../../src/services/dependency-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
1
|
// import { TestContext } from '@salesforce/core/lib/testSetup';
|
|
4
2
|
// import { stubSfCommandUx } from '@salesforce/sf-plugins-core';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
import { expect } from 'chai';
|
|
5
|
+
import { DependencyService } from './dependency-service.js';
|
|
8
6
|
describe('dependency-services', () => {
|
|
9
7
|
let dependencyService;
|
|
10
8
|
let dependencyList;
|
|
11
9
|
before(() => {
|
|
12
|
-
dependencyList = JSON.parse(
|
|
10
|
+
dependencyList = JSON.parse(readFileSync('test/fixtures/dependency-exploration-sf.json').toString());
|
|
13
11
|
});
|
|
14
12
|
beforeEach(() => {
|
|
15
|
-
dependencyService = new
|
|
13
|
+
dependencyService = new DependencyService();
|
|
16
14
|
});
|
|
17
15
|
describe('getRelatedApexClasses', () => {
|
|
18
16
|
it('test', () => {
|
|
19
17
|
const results = dependencyService.getRelatedApexClasses(dependencyList, ['APIUsers']);
|
|
20
|
-
|
|
18
|
+
expect(results).to.deep.eq(['APIUsers', 'APIUsersTest']);
|
|
21
19
|
});
|
|
22
20
|
});
|
|
23
21
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-services.test.js","sourceRoot":"","sources":["../../src/services/dependency-services.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dependency-services.test.js","sourceRoot":"","sources":["../../src/services/dependency-services.test.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,iEAAiE;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAA+B,MAAM,yBAAyB,CAAC;AAEzF,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,iBAAoC,CAAC;IACzC,IAAI,cAA6C,CAAC;IAElD,MAAM,CAAC,GAAG,EAAE;QACV,cAAc,GAAG,IAAI,CAAC,KAAK,CACzB,YAAY,CAAC,8CAA8C,CAAC,CAAC,QAAQ,EAAE,CACvC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,GAAG,EAAE;QACd,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YACd,MAAM,OAAO,GAAG,iBAAiB,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;YACtF,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,20 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Connection } from '@salesforce/core';
|
|
2
|
+
import { MetadataComponent } from './manifest-service.js';
|
|
2
3
|
export type FlowMetadata = {
|
|
3
4
|
apiName: string;
|
|
4
5
|
triggerType?: string;
|
|
5
6
|
processType?: string;
|
|
6
7
|
triggerObjectOrEvent?: string;
|
|
7
8
|
};
|
|
9
|
+
export type FlowTestCoverage = {
|
|
10
|
+
ApexTestClassId: string;
|
|
11
|
+
FlowDefinitionViewId: string;
|
|
12
|
+
TestMethodName: string;
|
|
13
|
+
NumElementsCovered: number;
|
|
14
|
+
NumElementsNotCovered: number;
|
|
15
|
+
};
|
|
8
16
|
export declare class FlowService {
|
|
9
17
|
private alwaysArray;
|
|
10
18
|
private xmlParser;
|
|
11
19
|
private logger;
|
|
20
|
+
private connection;
|
|
21
|
+
connect(connection: Connection): void;
|
|
22
|
+
/**
|
|
23
|
+
* Gets changed Flow names from the manifest.
|
|
24
|
+
*/
|
|
25
|
+
getChangedFlowNames(changedMetadataWithType: MetadataComponent[]): string[];
|
|
12
26
|
/**
|
|
13
|
-
*
|
|
14
|
-
* If includeAllFlows is true, and any changed flow requires tests, return changed flows plus all flows that require tests.
|
|
15
|
-
* Otherwise, returns only the changed flows.
|
|
27
|
+
* Checks if any of the changed flows require test coverage.
|
|
16
28
|
*/
|
|
17
|
-
|
|
29
|
+
hasTestableFlowChanged(changedFlowNames: string[], rootPath?: string): Promise<boolean>;
|
|
18
30
|
/**
|
|
19
31
|
* Extracts Flow metadata from local Flow definition files.
|
|
20
32
|
* Parses .flow-meta.xml files to get trigger information.
|
|
@@ -28,6 +40,11 @@ export declare class FlowService {
|
|
|
28
40
|
* Gets all Flow API names from local Flow definition files.
|
|
29
41
|
*/
|
|
30
42
|
getAllFlowNames(rootPath?: string): Promise<string[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Gets test class names that cover the specified Flows from Salesforce's FlowTestCoverage records.
|
|
45
|
+
* This queries the Tooling API to find which Apex test classes have previously executed and covered these Flows.
|
|
46
|
+
*/
|
|
47
|
+
getFlowTestCoverage(changedFlows: string[] | undefined, includeAllFlows: boolean): Promise<string[]>;
|
|
31
48
|
/**
|
|
32
49
|
* Determines if a Flow requires test coverage.
|
|
33
50
|
* All processes and autolaunched flows require coverage, except Screen Flows.
|
|
@@ -1,53 +1,42 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/* eslint-disable class-methods-use-this */
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
this.
|
|
22
|
-
this.isNotNullOrUndefined = (value) => value !== undefined && value !== null;
|
|
2
|
+
import { parse as parsePath } from 'path';
|
|
3
|
+
import { readFile } from 'fs/promises';
|
|
4
|
+
import { glob } from 'glob';
|
|
5
|
+
import { XMLParser } from 'fast-xml-parser';
|
|
6
|
+
import { Logger } from '@salesforce/core';
|
|
7
|
+
import loash from 'lodash';
|
|
8
|
+
import { FLOW } from '../elements/object-types.js';
|
|
9
|
+
export class FlowService {
|
|
10
|
+
alwaysArray = ['Flow.processMetadataValues'];
|
|
11
|
+
xmlParser = new XMLParser({
|
|
12
|
+
ignoreAttributes: false,
|
|
13
|
+
parseAttributeValue: false,
|
|
14
|
+
trimValues: true,
|
|
15
|
+
isArray: (_, jpath) => this.alwaysArray.includes(jpath),
|
|
16
|
+
});
|
|
17
|
+
logger = new Logger('FlowService');
|
|
18
|
+
connection;
|
|
19
|
+
connect(connection) {
|
|
20
|
+
this.connection = connection;
|
|
23
21
|
}
|
|
24
22
|
/**
|
|
25
|
-
* Gets Flow names
|
|
26
|
-
* If includeAllFlows is true, and any changed flow requires tests, return changed flows plus all flows that require tests.
|
|
27
|
-
* Otherwise, returns only the changed flows.
|
|
23
|
+
* Gets changed Flow names from the manifest.
|
|
28
24
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
getChangedFlowNames(changedMetadataWithType) {
|
|
26
|
+
return changedMetadataWithType.filter((m) => m.type === FLOW).map((m) => m.name);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Checks if any of the changed flows require test coverage.
|
|
30
|
+
*/
|
|
31
|
+
async hasTestableFlowChanged(changedFlowNames, rootPath = 'force-app/main/default/flows') {
|
|
32
|
+
if (changedFlowNames.length === 0) {
|
|
33
|
+
return false;
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
-
const changedFlowMetadata = await this.getFlowMetadata(changedFlows);
|
|
35
|
+
const changedFlowMetadata = await this.getFlowMetadata(changedFlowNames, rootPath);
|
|
36
36
|
const changedFlowsRequiringTests = changedFlowMetadata.filter((flow) => this.flowRequiresTestCoverage(flow));
|
|
37
|
-
this.logger.
|
|
38
|
-
this.logger.
|
|
39
|
-
|
|
40
|
-
// Get all flows and filter to only those requiring test coverage
|
|
41
|
-
const allFlowNames = await this.getAllFlowNames();
|
|
42
|
-
const allFlowsRequiringTests = (await this.getFlowMetadata(allFlowNames))
|
|
43
|
-
.filter((flow) => this.flowRequiresTestCoverage(flow))
|
|
44
|
-
.map((flow) => flow.apiName);
|
|
45
|
-
this.logger.info('changedFlows', changedFlows);
|
|
46
|
-
this.logger.info('allFlowNames', allFlowNames);
|
|
47
|
-
this.logger.info('allFlowsRequiringTests', allFlowsRequiringTests);
|
|
48
|
-
return (0, lodash_1.uniq)([...changedFlows, ...allFlowsRequiringTests]);
|
|
49
|
-
}
|
|
50
|
-
return changedFlows;
|
|
37
|
+
this.logger.debug('changedFlowMetadata', changedFlowMetadata);
|
|
38
|
+
this.logger.debug('changedFlowsRequiringTests', changedFlowsRequiringTests);
|
|
39
|
+
return changedFlowsRequiringTests.length > 0;
|
|
51
40
|
}
|
|
52
41
|
/**
|
|
53
42
|
* Extracts Flow metadata from local Flow definition files.
|
|
@@ -59,14 +48,14 @@ class FlowService {
|
|
|
59
48
|
}
|
|
60
49
|
const flowPaths = await Promise.all(flowNames.map(async (flowName) => {
|
|
61
50
|
const globPattern = `**/${flowName}.flow-meta.xml`;
|
|
62
|
-
return
|
|
51
|
+
return glob(globPattern, { cwd: rootPath });
|
|
63
52
|
}));
|
|
64
53
|
const flowMetadataPromises = flowPaths.flat().map(async (flowPath) => {
|
|
65
54
|
const fullPath = `${rootPath}/${flowPath}`;
|
|
66
|
-
const parsedPath = (
|
|
55
|
+
const parsedPath = parsePath(fullPath);
|
|
67
56
|
const apiName = parsedPath.name.replace('.flow-meta', '');
|
|
68
57
|
try {
|
|
69
|
-
const fileContent = await
|
|
58
|
+
const fileContent = await readFile(fullPath, 'utf8');
|
|
70
59
|
const flowDef = this.parseFlowXml(fileContent);
|
|
71
60
|
return {
|
|
72
61
|
apiName,
|
|
@@ -96,12 +85,45 @@ class FlowService {
|
|
|
96
85
|
* Gets all Flow API names from local Flow definition files.
|
|
97
86
|
*/
|
|
98
87
|
async getAllFlowNames(rootPath = 'force-app/main/default/flows') {
|
|
99
|
-
const flowPaths = await
|
|
88
|
+
const flowPaths = await glob('**/*.flow-meta.xml', { cwd: rootPath });
|
|
100
89
|
return flowPaths.map((flowPath) => {
|
|
101
|
-
const parsedPath = (
|
|
90
|
+
const parsedPath = parsePath(flowPath);
|
|
102
91
|
return parsedPath.name.replace('.flow-meta', '');
|
|
103
92
|
});
|
|
104
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Gets test class names that cover the specified Flows from Salesforce's FlowTestCoverage records.
|
|
96
|
+
* This queries the Tooling API to find which Apex test classes have previously executed and covered these Flows.
|
|
97
|
+
*/
|
|
98
|
+
async getFlowTestCoverage(changedFlows = [], includeAllFlows) {
|
|
99
|
+
if (!this.connection) {
|
|
100
|
+
throw new Error('Connection not set. Call connect() first.');
|
|
101
|
+
}
|
|
102
|
+
if (changedFlows.length === 0) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const result = await this.connection.tooling
|
|
107
|
+
.sobject('FlowTestCoverage')
|
|
108
|
+
.find({
|
|
109
|
+
'FlowVersion.Definition.DeveloperName': includeAllFlows
|
|
110
|
+
? { $ne: null }
|
|
111
|
+
: { $in: changedFlows },
|
|
112
|
+
}, {
|
|
113
|
+
'ApexTestClass.Name': 1,
|
|
114
|
+
'FlowVersion.Definition.DeveloperName': 1,
|
|
115
|
+
});
|
|
116
|
+
const testClassNames = result
|
|
117
|
+
.map((record) => record.ApexTestClass?.Name)
|
|
118
|
+
.filter(this.isNotNullOrUndefined);
|
|
119
|
+
this.logger.debug('FlowTestCoverage query returned test classes:', testClassNames);
|
|
120
|
+
return loash.uniq(testClassNames);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
this.logger.warn('Failed to query FlowTestCoverage:', error);
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
}
|
|
105
127
|
/**
|
|
106
128
|
* Determines if a Flow requires test coverage.
|
|
107
129
|
* All processes and autolaunched flows require coverage, except Screen Flows.
|
|
@@ -137,6 +159,6 @@ class FlowService {
|
|
|
137
159
|
triggerObjectOrEvent,
|
|
138
160
|
};
|
|
139
161
|
}
|
|
162
|
+
isNotNullOrUndefined = (value) => value !== undefined && value !== null;
|
|
140
163
|
}
|
|
141
|
-
exports.FlowService = FlowService;
|
|
142
164
|
//# sourceMappingURL=flow-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-service.js","sourceRoot":"","sources":["../../src/services/flow-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"flow-service.js","sourceRoot":"","sources":["../../src/services/flow-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ResolveManifestResult } from '@salesforce/source-deploy-retrieve/lib/src/resolve/manifestResolver';
|
|
1
|
+
import { ResolveManifestResult } from '@salesforce/source-deploy-retrieve/lib/src/resolve/manifestResolver.js';
|
|
2
2
|
export type MetadataComponent = {
|
|
3
3
|
name: string;
|
|
4
4
|
type: string;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/* eslint-disable class-methods-use-this */
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const object_types_1 = require("../elements/object-types");
|
|
7
|
-
class ManifestService {
|
|
2
|
+
import { ManifestResolver } from '@salesforce/source-deploy-retrieve';
|
|
3
|
+
import { meaningfulMetadataChanges } from '../elements/object-types.js';
|
|
4
|
+
export class ManifestService {
|
|
8
5
|
async parseManifest(path = 'manifest/package.xml') {
|
|
9
|
-
const manifestResolver = new
|
|
6
|
+
const manifestResolver = new ManifestResolver();
|
|
10
7
|
return manifestResolver.resolve(path);
|
|
11
8
|
}
|
|
12
9
|
extractMetadataComponentsWithType(manifestData) {
|
|
@@ -17,7 +14,7 @@ class ManifestService {
|
|
|
17
14
|
continue;
|
|
18
15
|
}
|
|
19
16
|
// Only include metadata that we care about. Aka: meaningful
|
|
20
|
-
if (!
|
|
17
|
+
if (!meaningfulMetadataChanges.includes(component.type.name)) {
|
|
21
18
|
continue;
|
|
22
19
|
}
|
|
23
20
|
// Children components, we want to get the parent. Example: `Account.Name` -> `Account`
|
|
@@ -34,5 +31,4 @@ class ManifestService {
|
|
|
34
31
|
return Array.from(componentMap.values());
|
|
35
32
|
}
|
|
36
33
|
}
|
|
37
|
-
exports.ManifestService = ManifestService;
|
|
38
34
|
//# sourceMappingURL=manifest-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest-service.js","sourceRoot":"","sources":["../../src/services/manifest-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manifest-service.js","sourceRoot":"","sources":["../../src/services/manifest-service.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAE3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAOxE,MAAM,OAAO,eAAe;IACnB,KAAK,CAAC,aAAa,CAAC,IAAI,GAAG,sBAAsB;QACtD,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC;QAChD,OAAO,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAEM,iCAAiC,CAAC,YAAmC;QAC1E,MAAM,YAAY,GAAG,IAAI,GAAG,EAA6B,CAAC;QAC1D,KAAK,MAAM,SAAS,IAAI,YAAY,CAAC,UAAU,EAAE,CAAC;YAChD,4DAA4D;YAC5D,IAAI,SAAS,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;gBAC/B,SAAS;YACX,CAAC;YAED,4DAA4D;YAC5D,IAAI,CAAC,yBAAyB,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7D,SAAS;YACX,CAAC;YAED,uFAAuF;YACvF,IAAI,IAAY,CAAC;YACjB,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrC,MAAM,kBAAkB,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACzD,IAAI,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC;YAC5B,CAAC;YAED,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;CACF"}
|
|
@@ -1,26 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const fs_1 = require("fs");
|
|
7
|
-
class OutputService {
|
|
1
|
+
import { resolve, join } from 'path';
|
|
2
|
+
import { writeFile, access, mkdir } from 'fs/promises';
|
|
3
|
+
import { constants } from 'fs';
|
|
4
|
+
export class OutputService {
|
|
5
|
+
outputFolder;
|
|
8
6
|
constructor(outputFolder = '.sf-delta-tests') {
|
|
9
|
-
this.outputFolder =
|
|
7
|
+
this.outputFolder = resolve(outputFolder);
|
|
10
8
|
}
|
|
11
9
|
async dependencyData(dependencyData) {
|
|
12
10
|
return this.write('dependency-graph.json', JSON.stringify(dependencyData));
|
|
13
11
|
}
|
|
14
12
|
async write(fileName, data) {
|
|
15
|
-
const path =
|
|
13
|
+
const path = join(this.outputFolder, fileName);
|
|
16
14
|
try {
|
|
17
|
-
await
|
|
15
|
+
await access(this.outputFolder, constants.W_OK);
|
|
18
16
|
}
|
|
19
17
|
catch {
|
|
20
|
-
await
|
|
18
|
+
await mkdir(this.outputFolder);
|
|
21
19
|
}
|
|
22
|
-
return
|
|
20
|
+
return writeFile(path, data);
|
|
23
21
|
}
|
|
24
22
|
}
|
|
25
|
-
exports.OutputService = OutputService;
|
|
26
23
|
//# sourceMappingURL=output-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output-service.js","sourceRoot":"","sources":["../../src/services/output-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"output-service.js","sourceRoot":"","sources":["../../src/services/output-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAG/B,MAAM,OAAO,aAAa;IACP,YAAY,CAAS;IACtC,YAAmB,YAAY,GAAG,iBAAiB;QACjD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC;IACM,KAAK,CAAC,cAAc,CAAC,cAA6C;QACvE,OAAO,IAAI,CAAC,KAAK,CAAC,uBAAuB,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC;IAC7E,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,IAAY;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAE/C,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACjC,CAAC;QAED,OAAO,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -4,7 +4,7 @@ Run only related tests
|
|
|
4
4
|
|
|
5
5
|
# description
|
|
6
6
|
|
|
7
|
-
Calculates the tests needed to be ran based on the changed metadata given using the Salesforce Dependency API
|
|
7
|
+
Calculates the tests needed to be ran based on the changed metadata given using the Salesforce Dependency API. For Flows, also queries FlowTestCoverage to include test classes that have previously covered the Flows.
|
|
8
8
|
|
|
9
9
|
# examples
|
|
10
10
|
|
package/oclif.manifest.json
CHANGED
|
@@ -1,57 +1,78 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.0.26",
|
|
3
2
|
"commands": {
|
|
4
3
|
"delta:test-classes": {
|
|
5
|
-
"id": "delta:test-classes",
|
|
6
|
-
"summary": "Run only related tests",
|
|
7
|
-
"description": "Calculates the tests needed to be ran based on the changed metadata given using the Salesforce Dependency API",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"pluginName": "sf-delta-tests",
|
|
10
|
-
"pluginAlias": "sf-delta-tests",
|
|
11
|
-
"pluginType": "core",
|
|
12
4
|
"aliases": [],
|
|
5
|
+
"args": {},
|
|
6
|
+
"description": "Calculates the tests needed to be ran based on the changed metadata given using the Salesforce Dependency API. For Flows, also queries FlowTestCoverage to include test classes that have previously covered the Flows.",
|
|
13
7
|
"examples": [
|
|
14
8
|
"testCmd=$(sf delta test-classes --target-org matt@never.io.dev)\r\nsf project deploy validate ${testCmd}"
|
|
15
9
|
],
|
|
16
10
|
"flags": {
|
|
17
11
|
"json": {
|
|
18
|
-
"name": "json",
|
|
19
|
-
"type": "boolean",
|
|
20
12
|
"description": "Format output as json.",
|
|
21
13
|
"helpGroup": "GLOBAL",
|
|
22
|
-
"
|
|
14
|
+
"name": "json",
|
|
15
|
+
"allowNo": false,
|
|
16
|
+
"type": "boolean"
|
|
17
|
+
},
|
|
18
|
+
"flags-dir": {
|
|
19
|
+
"helpGroup": "GLOBAL",
|
|
20
|
+
"name": "flags-dir",
|
|
21
|
+
"summary": "Import flag values from a directory.",
|
|
22
|
+
"hasDynamicHelp": false,
|
|
23
|
+
"multiple": false,
|
|
24
|
+
"type": "option"
|
|
23
25
|
},
|
|
24
26
|
"target-org": {
|
|
25
|
-
"name": "target-org",
|
|
26
|
-
"type": "option",
|
|
27
27
|
"char": "o",
|
|
28
|
-
"
|
|
28
|
+
"name": "target-org",
|
|
29
|
+
"noCacheDefault": true,
|
|
29
30
|
"required": true,
|
|
30
|
-
"
|
|
31
|
+
"summary": "The org you want to check the dependencies against.",
|
|
32
|
+
"hasDynamicHelp": true,
|
|
33
|
+
"multiple": false,
|
|
34
|
+
"type": "option"
|
|
31
35
|
},
|
|
32
36
|
"package-path": {
|
|
33
|
-
"name": "package-path",
|
|
34
|
-
"type": "option",
|
|
35
37
|
"char": "p",
|
|
38
|
+
"name": "package-path",
|
|
36
39
|
"summary": "Path to the package.xml that will be deployed.",
|
|
40
|
+
"default": "manifest/package.xml",
|
|
41
|
+
"hasDynamicHelp": false,
|
|
37
42
|
"multiple": false,
|
|
38
|
-
"
|
|
43
|
+
"type": "option"
|
|
39
44
|
},
|
|
40
45
|
"always-run-test": {
|
|
41
46
|
"name": "always-run-test",
|
|
42
|
-
"type": "option",
|
|
43
47
|
"summary": "A test class to run when no tests need to be ran.",
|
|
44
|
-
"
|
|
48
|
+
"hasDynamicHelp": false,
|
|
49
|
+
"multiple": true,
|
|
50
|
+
"type": "option"
|
|
45
51
|
},
|
|
46
52
|
"include-all-flows": {
|
|
47
53
|
"name": "include-all-flows",
|
|
48
|
-
"type": "boolean",
|
|
49
54
|
"summary": "When enabled, if any Flow is changed, include all Flows that require test coverage based on their trigger type or process type. This ensures proper test coverage validation since Salesforce checks coverage for all such Flows during deployment, not just the changed ones. Use --no-include-all-flows to disable.",
|
|
50
|
-
"allowNo": true
|
|
55
|
+
"allowNo": true,
|
|
56
|
+
"type": "boolean"
|
|
51
57
|
}
|
|
52
58
|
},
|
|
53
|
-
"
|
|
54
|
-
"
|
|
59
|
+
"hasDynamicHelp": true,
|
|
60
|
+
"hiddenAliases": [],
|
|
61
|
+
"id": "delta:test-classes",
|
|
62
|
+
"pluginAlias": "sf-delta-tests",
|
|
63
|
+
"pluginName": "sf-delta-tests",
|
|
64
|
+
"pluginType": "core",
|
|
65
|
+
"strict": true,
|
|
66
|
+
"summary": "Run only related tests",
|
|
67
|
+
"enableJsonFlag": true,
|
|
68
|
+
"isESM": true,
|
|
69
|
+
"relativePath": [
|
|
70
|
+
"lib",
|
|
71
|
+
"commands",
|
|
72
|
+
"delta",
|
|
73
|
+
"test-classes.js"
|
|
74
|
+
]
|
|
55
75
|
}
|
|
56
|
-
}
|
|
76
|
+
},
|
|
77
|
+
"version": "0.2.1"
|
|
57
78
|
}
|