66 */
77import { CancellationTokenSource , TestLevel , TestResult , TestRunIdResult , TestService } from '@salesforce/apex-node' ;
88import {
9+ arrayWithDeprecation ,
910 Flags ,
1011 loglevel ,
1112 orgApiVersionFlagWithDeprecations ,
@@ -24,6 +25,7 @@ const messages = Messages.loadMessages('@salesforce/plugin-apex', 'runtest');
2425
2526export const TestLevelValues = [ 'RunLocalTests' , 'RunAllTestsInOrg' , 'RunSpecifiedTests' ] ;
2627export type RunCommandResult = RunResult | TestRunIdResult ;
28+ const exclusiveTestSpecifiers = [ 'class-names' , 'suite-names' , 'tests' ] ;
2729export default class Test extends SfCommand < RunCommandResult > {
2830 public static readonly summary = messages . getMessage ( 'summary' ) ;
2931 public static readonly description = messages . getMessage ( 'description' ) ;
@@ -55,12 +57,13 @@ export default class Test extends SfCommand<RunCommandResult> {
5557 description : messages . getMessage ( 'flags.test-level.description' ) ,
5658 options : TestLevelValues ,
5759 } ) ,
58- 'class-names' : Flags . string ( {
60+ 'class-names' : arrayWithDeprecation ( {
5961 deprecateAliases : true ,
6062 aliases : [ 'classnames' ] ,
6163 char : 'n' ,
6264 summary : messages . getMessage ( 'flags.class-names.summary' ) ,
6365 description : messages . getMessage ( 'flags.class-names.description' ) ,
66+ exclusive : exclusiveTestSpecifiers . filter ( ( specifier ) => specifier !== 'class-names' ) ,
6467 } ) ,
6568 'result-format' : Flags . string ( {
6669 deprecateAliases : true ,
@@ -70,17 +73,19 @@ export default class Test extends SfCommand<RunCommandResult> {
7073 options : resultFormat ,
7174 default : 'human' ,
7275 } ) ,
73- 'suite-names' : Flags . string ( {
76+ 'suite-names' : arrayWithDeprecation ( {
7477 deprecateAliases : true ,
7578 aliases : [ 'suitenames' ] ,
7679 char : 's' ,
7780 summary : messages . getMessage ( 'flags.suite-names.summary' ) ,
7881 description : messages . getMessage ( 'flags.suite-names.description' ) ,
82+ exclusive : exclusiveTestSpecifiers . filter ( ( specifier ) => specifier !== 'suite-names' ) ,
7983 } ) ,
80- tests : Flags . string ( {
84+ tests : arrayWithDeprecation ( {
8185 char : 't' ,
8286 summary : messages . getMessage ( 'flags.tests.summary' ) ,
8387 description : messages . getMessage ( 'flags.tests.description' ) ,
88+ exclusive : exclusiveTestSpecifiers . filter ( ( specifier ) => specifier !== 'tests' ) ,
8489 } ) ,
8590 // we want to pass `undefined` to the API
8691 // eslint-disable-next-line sf-plugin/flag-min-max-default
@@ -108,9 +113,7 @@ export default class Test extends SfCommand<RunCommandResult> {
108113 public async run ( ) : Promise < RunCommandResult > {
109114 const { flags } = await this . parse ( Test ) ;
110115
111- const testLevel = await this . validateFlags (
112- flags [ 'code-coverage' ] ,
113- flags [ 'result-format' ] ,
116+ const testLevel = await validateFlags (
114117 flags [ 'class-names' ] ,
115118 flags [ 'suite-names' ] ,
116119 flags . tests ,
@@ -159,48 +162,17 @@ export default class Test extends SfCommand<RunCommandResult> {
159162 }
160163 }
161164
162- // eslint-disable-next-line class-methods-use-this
163- public async validateFlags (
164- codeCoverage ?: boolean ,
165- resultFormatFlag ?: string ,
166- classNames ?: string ,
167- suiteNames ?: string ,
168- tests ?: string ,
169- synchronous ?: boolean ,
170- testLevel ?: TestLevel
171- ) : Promise < TestLevel > {
172- if ( ( classNames && ( suiteNames || tests ) ) || ( suiteNames && tests ) ) {
173- return Promise . reject ( new Error ( messages . getMessage ( 'classSuiteTestErr' ) ) ) ;
174- }
175-
176- if ( synchronous && ( suiteNames || ( classNames && classNames . split ( ',' ) . length > 1 ) ) ) {
177- return Promise . reject ( new Error ( messages . getMessage ( 'syncClassErr' ) ) ) ;
178- }
179-
180- if ( ( tests || classNames || suiteNames ) && testLevel && testLevel !== 'RunSpecifiedTests' ) {
181- return Promise . reject ( new Error ( messages . getMessage ( 'testLevelErr' ) ) ) ;
182- }
183-
184- if ( testLevel ) {
185- return testLevel ;
186- }
187- if ( classNames || suiteNames || tests ) {
188- return TestLevel . RunSpecifiedTests ;
189- }
190- return TestLevel . RunLocalTests ;
191- }
192-
193165 private async runTest (
194166 testService : TestService ,
195167 flags : {
196- tests ?: string ;
197- 'class-names' ?: string ;
168+ tests ?: string [ ] ;
169+ 'class-names' ?: string [ ] ;
198170 'code-coverage' ?: boolean ;
199171 } ,
200172 testLevel : TestLevel
201173 ) : Promise < TestResult > {
202174 const payload = {
203- ...( await testService . buildSyncPayload ( testLevel , flags . tests , flags [ 'class-names' ] ) ) ,
175+ ...( await testService . buildSyncPayload ( testLevel , flags . tests ?. join ( ',' ) , flags [ 'class-names' ] ?. join ( ',' ) ) ) ,
204176 skipCodeCoverage : ! flags [ 'code-coverage' ] ,
205177 } ;
206178 return testService . runTestSynchronous (
@@ -213,9 +185,9 @@ export default class Test extends SfCommand<RunCommandResult> {
213185 private async runTestAsynchronous (
214186 testService : TestService ,
215187 flags : {
216- tests ?: string ;
217- 'class-names' ?: string ;
218- 'suite-names' ?: string ;
188+ tests ?: string [ ] ;
189+ 'class-names' ?: string [ ] ;
190+ 'suite-names' ?: string [ ] ;
219191 'code-coverage' ?: boolean ;
220192 synchronous ?: boolean ;
221193 'result-format' ?: string ;
@@ -225,7 +197,12 @@ export default class Test extends SfCommand<RunCommandResult> {
225197 testLevel : TestLevel
226198 ) : Promise < TestRunIdResult > {
227199 const payload = {
228- ...( await testService . buildAsyncPayload ( testLevel , flags . tests , flags [ 'class-names' ] , flags [ 'suite-names' ] ) ) ,
200+ ...( await testService . buildAsyncPayload (
201+ testLevel ,
202+ flags . tests ?. join ( ',' ) ,
203+ flags [ 'class-names' ] ?. join ( ',' ) ,
204+ flags [ 'suite-names' ] ?. join ( ',' )
205+ ) ) ,
229206 skipCodeCoverage : ! flags [ 'code-coverage' ] ,
230207 } ;
231208
@@ -239,3 +216,28 @@ export default class Test extends SfCommand<RunCommandResult> {
239216 ) as Promise < TestRunIdResult > ;
240217 }
241218}
219+
220+ // eslint-disable-next-line class-methods-use-this
221+ const validateFlags = async (
222+ classNames ?: string [ ] ,
223+ suiteNames ?: string [ ] ,
224+ tests ?: string [ ] ,
225+ synchronous ?: boolean ,
226+ testLevel ?: TestLevel
227+ ) : Promise < TestLevel > => {
228+ if ( synchronous && ( suiteNames || ( classNames ?. length && classNames . length > 1 ) ) ) {
229+ return Promise . reject ( new Error ( messages . getMessage ( 'syncClassErr' ) ) ) ;
230+ }
231+
232+ if ( ( tests || classNames || suiteNames ) && testLevel && testLevel !== 'RunSpecifiedTests' ) {
233+ return Promise . reject ( new Error ( messages . getMessage ( 'testLevelErr' ) ) ) ;
234+ }
235+
236+ if ( testLevel ) {
237+ return testLevel ;
238+ }
239+ if ( classNames || suiteNames || tests ) {
240+ return TestLevel . RunSpecifiedTests ;
241+ }
242+ return TestLevel . RunLocalTests ;
243+ } ;
0 commit comments