• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import * as path from 'node:path';
17import type { CommandLineOptions } from '../lib/CommandLineOptions';
18import type { LinterOptions } from '../lib/LinterOptions';
19import { LintTest } from './LintTest';
20import type { RunTestFileOptions } from './RunTestFileOptions';
21import { parseCommandLine } from '../cli/CommandLineParser';
22import { getCommandLineArguments } from './CommandLineUtil';
23import type { TestModeProperties } from './TestMode';
24import { DEFAULT_MODE_PROPERTIES, TestMode, testModePropsMap } from './TestMode';
25import type { TestArguments } from './TestArgs';
26import { readTestArgsFile } from './TestArgs';
27import { MigrateTest } from './MigrateTest';
28
29interface CreateTestOptions {
30  runTestFileOpts: RunTestFileOptions;
31  testModeProps: TestModeProperties;
32  testModeArgs?: string;
33  testCommonOpts?: LinterOptions;
34}
35
36export interface CreateLintTestOptions {
37  testDir: string;
38  testFile: string;
39  testModeProps: TestModeProperties;
40  cmdOptions: CommandLineOptions;
41}
42
43export function createTests(runTestFileOpts: RunTestFileOptions): LintTest[] {
44  const testArgs = readTestArgsFile(runTestFileOpts.testDir, runTestFileOpts.testFile);
45  return testArgs ?
46    createTestsFromTestArgs(runTestFileOpts, testArgs) :
47    [createTest({ runTestFileOpts, testModeProps: DEFAULT_MODE_PROPERTIES })];
48}
49
50function createTestsFromTestArgs(runTestFileOpts: RunTestFileOptions, testArgs: TestArguments): LintTest[] {
51  const tests: LintTest[] = [];
52  const testCommonOpts = testArgs.commonArgs ? getLinterOptionsFromCommandLine(testArgs.commonArgs) : undefined;
53
54  addDefaultModeIfNeeded(testArgs);
55
56  if (testArgs.mode) {
57    for (const mode of Object.keys(testArgs.mode)) {
58      const testModeProps = testModePropsMap.get(mode);
59      if (!testModeProps) {
60        throw new Error(`Failed to create test. Unknown mode: '${mode}'`);
61      }
62      const testModeArgs: string | undefined = testArgs.mode[mode];
63      tests.push(createTest({ runTestFileOpts, testModeProps, testCommonOpts, testModeArgs }));
64    }
65  }
66
67  return tests;
68}
69
70function addDefaultModeIfNeeded(testArgs: TestArguments): void {
71  if (testArgs.mode?.default === undefined) {
72    // For convenience, always add 'default' mode as first
73    testArgs.mode = Object.assign({ default: '' }, testArgs.mode);
74  }
75}
76
77function createTest(createTestOpts: CreateTestOptions): LintTest {
78  const opts = createCreateLintTestOpts(createTestOpts);
79  if (createTestOpts.testModeProps.mode === TestMode.MIGRATE) {
80    return new MigrateTest(opts);
81  }
82  return new LintTest(opts);
83}
84
85function createCreateLintTestOpts(createTestConfigOpts: CreateTestOptions): CreateLintTestOptions {
86  const { runTestFileOpts, testCommonOpts, testModeArgs, testModeProps } = createTestConfigOpts;
87  const { testDir, testFile, testRunnerOpts } = runTestFileOpts;
88
89  /*
90   * Test options are formed in the following order (from lowest to highest priority):
91   *   - default test options;
92   *   - [test_args_file] --> 'commonArgs';
93   *   - [test_args_file] --> the arguments specified for a mode;
94   *   - options specified by TestRunner command-line arguments;
95   *   - options that enable specific mode.
96   */
97  const linterOpts = getDefaultTestOptions();
98  if (testCommonOpts) {
99    Object.assign(linterOpts, testCommonOpts);
100  }
101  if (testModeArgs) {
102    Object.assign(linterOpts, getLinterOptionsFromCommandLine(testModeArgs));
103  }
104  Object.assign(linterOpts, testRunnerOpts.linterOptions);
105  Object.assign(linterOpts, testModeProps.modeOpts);
106
107  const cmdOptions: CommandLineOptions = {
108    inputFiles: [path.join(testDir, testFile)],
109    linterOptions: linterOpts
110  };
111
112  return {
113    testDir,
114    testFile,
115    testModeProps,
116    cmdOptions
117  };
118}
119
120function getLinterOptionsFromCommandLine(cmdLine: string): LinterOptions {
121  return parseCommandLine(getCommandLineArguments(cmdLine), { exitOnFail: false, disableErrorOutput: true }).
122    linterOptions;
123}
124
125function getDefaultTestOptions(): LinterOptions {
126  return {
127    useRtLogic: true,
128    checkTsAsSource:
129      true /* By default, treat any test file with '.ts' extension as a source file (as opposed to library) */,
130    compatibleSdkVersion: 12,
131    compatibleSdkVersionStage: 'beta3',
132    checkTsAndJs: true
133  };
134}
135