Initial attempt for e2e tests
- Add node code for e2e tests. This is a first take to try running these tests via actions. - Relates to #401
This commit is contained in:
51
.github/workflows/e2e.yml
vendored
Normal file
51
.github/workflows/e2e.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
name: e2e
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
e2e:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- nickname: win
|
||||
os: windows-2019
|
||||
graal: 22.0.0.2
|
||||
- nickname: macos
|
||||
os: macos-latest
|
||||
graal: 22.0.0.2
|
||||
- nickname: linux
|
||||
os: ubuntu-latest
|
||||
graal: 22.0.0.2
|
||||
name: CI Native ${{ matrix.nickname }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: adopt
|
||||
java-version: 11
|
||||
cache: maven
|
||||
- uses: graalvm/setup-graalvm@v1
|
||||
with:
|
||||
version: ${{ matrix.graal }}
|
||||
java-version: 11
|
||||
components: native-image
|
||||
set-java-home: false
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
- run: |
|
||||
./mvnw clean package -Pnative
|
||||
- name: compile e2e module
|
||||
working-directory: e2e/spring-shell-e2e
|
||||
run: |
|
||||
npm install
|
||||
npm run build
|
||||
- name: run e2e tests
|
||||
working-directory: e2e/spring-shell-e2e-tests
|
||||
run: |
|
||||
npm install
|
||||
npm test
|
||||
1
e2e/spring-shell-e2e-tests/.gitignore
vendored
Normal file
1
e2e/spring-shell-e2e-tests/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
5
e2e/spring-shell-e2e-tests/.prettierignore
Normal file
5
e2e/spring-shell-e2e-tests/.prettierignore
Normal file
@@ -0,0 +1,5 @@
|
||||
# dont care about typings
|
||||
types/
|
||||
|
||||
# for test data
|
||||
test/data/
|
||||
11
e2e/spring-shell-e2e-tests/.prettierrc.json
Normal file
11
e2e/spring-shell-e2e-tests/.prettierrc.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "avoid",
|
||||
"parser": "typescript"
|
||||
}
|
||||
12
e2e/spring-shell-e2e-tests/jest.config.js
Normal file
12
e2e/spring-shell-e2e-tests/jest.config.js
Normal file
@@ -0,0 +1,12 @@
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
moduleFileExtensions: ['js', 'ts'],
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/*.test.ts'],
|
||||
testRunner: 'jest-circus/runner',
|
||||
transform: {
|
||||
'^.+\\.ts$': 'ts-jest'
|
||||
},
|
||||
verbose: true,
|
||||
setupFilesAfterEnv: ['jest-extended', '@alex_neo/jest-expect-message']
|
||||
}
|
||||
6295
e2e/spring-shell-e2e-tests/package-lock.json
generated
Normal file
6295
e2e/spring-shell-e2e-tests/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
39
e2e/spring-shell-e2e-tests/package.json
Normal file
39
e2e/spring-shell-e2e-tests/package.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "spring-shell-e2e-tests",
|
||||
"version": "2.1.0",
|
||||
"description": "e2e tests for spring-shell",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"format": "prettier --write **/*.ts",
|
||||
"format-check": "prettier --check **/*.ts",
|
||||
"test": "jest"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/spring-projects/spring-shell.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/spring-projects/spring-shell/issues"
|
||||
},
|
||||
"homepage": "https://github.com/spring-projects/spring-shell",
|
||||
"devDependencies": {
|
||||
"@actions/io": "^1.1.2",
|
||||
"@alex_neo/jest-expect-message": "^1.0.5",
|
||||
"@types/jest": "^27.4.1",
|
||||
"@types/jest-expect-message": "^1.0.3",
|
||||
"@types/lodash": "^4.14.172",
|
||||
"@types/node": "^15.6.0",
|
||||
"jest": "^27.5.1",
|
||||
"jest-circus": "^27.5.1",
|
||||
"jest-extended": "^2.0.0",
|
||||
"prettier": "^2.3.0",
|
||||
"ts-jest": "^27.1.3",
|
||||
"typescript": "^4.6.2",
|
||||
"wait-for-expect": "^3.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"spring-shell-e2e": "file:../spring-shell-e2e"
|
||||
}
|
||||
}
|
||||
18
e2e/spring-shell-e2e-tests/src/utils.ts
Normal file
18
e2e/spring-shell-e2e-tests/src/utils.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
|
||||
export const tempDir = path.join(__dirname, 'spring-shell', 'temp');
|
||||
export const isWindows = os.platform() === 'win32';
|
||||
export const cliPathRelative = isWindows
|
||||
? '..\\..\\spring-shell-samples\\target\\spring-shell-samples.exe'
|
||||
: '../../spring-shell-samples/target/spring-shell-samples';
|
||||
export const jarPathRelative = isWindows
|
||||
? '..\\..\\spring-shell-samples\\target\\spring-shell-samples-2.1.0-SNAPSHOT-exec.jar'
|
||||
: '../../spring-shell-samples/target/spring-shell-samples-2.1.0-SNAPSHOT-exec.jar';
|
||||
export const cliPath = path.resolve(cliPathRelative);
|
||||
export const jarPath = path.resolve(jarPathRelative);
|
||||
export const nativeDesc = 'native';
|
||||
export const jarDesc = 'jar';
|
||||
export const jarCommand = 'java';
|
||||
export const nativeCommand = cliPath;
|
||||
export const jarOptions = ['-jar', jarPath];
|
||||
69
e2e/spring-shell-e2e-tests/test/builtin.test.ts
Normal file
69
e2e/spring-shell-e2e-tests/test/builtin.test.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import 'jest-extended';
|
||||
import waitForExpect from 'wait-for-expect';
|
||||
import { Cli } from 'spring-shell-e2e';
|
||||
import { nativeDesc, jarDesc, jarCommand, nativeCommand, jarOptions } from '../src/utils';
|
||||
|
||||
// all buildin commands
|
||||
describe('builtin commands', () => {
|
||||
let cli: Cli;
|
||||
let command: string;
|
||||
let options: string[] = [];
|
||||
|
||||
/**
|
||||
* test for version command returns expected info
|
||||
*/
|
||||
const versionReturnsInfoDesc = 'version returns info';
|
||||
const versionCommand = ['version'];
|
||||
const versionReturnsInfo = async (cli: Cli) => {
|
||||
cli.run();
|
||||
await waitForExpect(async () => {
|
||||
const screen = cli.screen();
|
||||
expect(screen).toEqual(expect.arrayContaining([expect.stringContaining('Build Version')]));
|
||||
});
|
||||
await expect(cli.exitCode()).resolves.toBe(0);
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
waitForExpect.defaults.timeout = 3000;
|
||||
waitForExpect.defaults.interval = 100;
|
||||
}, 300000);
|
||||
|
||||
afterEach(async () => {
|
||||
cli?.dispose();
|
||||
}, 100000);
|
||||
|
||||
/**
|
||||
* native commands
|
||||
*/
|
||||
describe(nativeDesc, () => {
|
||||
beforeAll(() => {
|
||||
command = nativeCommand;
|
||||
});
|
||||
|
||||
it(versionReturnsInfoDesc, async () => {
|
||||
cli = new Cli({
|
||||
command: command,
|
||||
options: [...options, ...versionCommand]
|
||||
});
|
||||
await versionReturnsInfo(cli);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* fatjar commands
|
||||
*/
|
||||
describe(jarDesc, () => {
|
||||
beforeAll(() => {
|
||||
command = jarCommand;
|
||||
options = jarOptions;
|
||||
});
|
||||
|
||||
it(versionReturnsInfoDesc, async () => {
|
||||
cli = new Cli({
|
||||
command: command,
|
||||
options: [...options, ...versionCommand]
|
||||
});
|
||||
await versionReturnsInfo(cli);
|
||||
});
|
||||
});
|
||||
});
|
||||
91
e2e/spring-shell-e2e-tests/test/flow.test.ts
Normal file
91
e2e/spring-shell-e2e-tests/test/flow.test.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import 'jest-extended';
|
||||
import waitForExpect from 'wait-for-expect';
|
||||
import { Cli } from 'spring-shell-e2e';
|
||||
import { nativeDesc, jarDesc, jarCommand, nativeCommand, jarOptions } from '../src/utils';
|
||||
|
||||
// all flow commands
|
||||
describe('flow commands', () => {
|
||||
let cli: Cli;
|
||||
let command: string;
|
||||
let options: string[] = [];
|
||||
|
||||
/**
|
||||
* test for flow conditional field2 skips field1
|
||||
*/
|
||||
const flowConditionalField2SkipsFields1Desc = 'flow conditional field2 skips field1';
|
||||
const flowConditionalCommand = ['flow', 'conditional'];
|
||||
const flowConditionalField2SkipsFields1 = async (cli: Cli) => {
|
||||
cli.run();
|
||||
|
||||
await waitForExpect(async () => {
|
||||
const screen = cli.screen();
|
||||
expect(screen).toEqual(expect.arrayContaining([expect.stringContaining('Single1')]));
|
||||
});
|
||||
|
||||
await cli.keyDown();
|
||||
await waitForExpect(async () => {
|
||||
const screen = cli.screen();
|
||||
expect(screen).toEqual(expect.arrayContaining([expect.stringContaining('> Field2')]));
|
||||
});
|
||||
|
||||
await cli.keyEnter();
|
||||
await waitForExpect(async () => {
|
||||
const screen = cli.screen();
|
||||
expect(screen).toEqual(
|
||||
expect.arrayContaining([expect.stringContaining('? Field2 [Default defaultField2Value]')])
|
||||
);
|
||||
});
|
||||
|
||||
await cli.keyEnter();
|
||||
await waitForExpect(async () => {
|
||||
const screen = cli.screen();
|
||||
expect(screen).toEqual(expect.arrayContaining([expect.stringContaining('Field2 defaultField2Value')]));
|
||||
});
|
||||
|
||||
await expect(cli.exitCode()).resolves.toBe(0);
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
waitForExpect.defaults.timeout = 3000;
|
||||
waitForExpect.defaults.interval = 100;
|
||||
}, 300000);
|
||||
|
||||
afterEach(async () => {
|
||||
cli?.dispose();
|
||||
}, 100000);
|
||||
|
||||
/**
|
||||
* native commands
|
||||
*/
|
||||
describe(nativeDesc, () => {
|
||||
beforeAll(() => {
|
||||
command = nativeCommand;
|
||||
});
|
||||
|
||||
it(flowConditionalField2SkipsFields1Desc, async () => {
|
||||
cli = new Cli({
|
||||
command: command,
|
||||
options: [...options, ...flowConditionalCommand]
|
||||
});
|
||||
await flowConditionalField2SkipsFields1(cli);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* fatjar commands
|
||||
*/
|
||||
describe(jarDesc, () => {
|
||||
beforeAll(() => {
|
||||
command = jarCommand;
|
||||
options = jarOptions;
|
||||
});
|
||||
|
||||
it(flowConditionalField2SkipsFields1Desc, async () => {
|
||||
cli = new Cli({
|
||||
command: command,
|
||||
options: [...options, ...flowConditionalCommand]
|
||||
});
|
||||
await flowConditionalField2SkipsFields1(cli);
|
||||
});
|
||||
});
|
||||
});
|
||||
19
e2e/spring-shell-e2e-tests/tsconfig.json
Normal file
19
e2e/spring-shell-e2e-tests/tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2019",
|
||||
"module": "commonjs",
|
||||
"outDir": "./lib",
|
||||
"rootDirs": ["./src", "./test"],
|
||||
"strict": true,
|
||||
"baseUrl": ".",
|
||||
"noImplicitAny": false,
|
||||
"paths": {
|
||||
"*": ["./types/*"]
|
||||
},
|
||||
"esModuleInterop": true,
|
||||
"lib": [
|
||||
"es2019"
|
||||
]
|
||||
},
|
||||
"exclude": ["node_modules", "**/*.test.ts"]
|
||||
}
|
||||
2
e2e/spring-shell-e2e/.gitignore
vendored
Normal file
2
e2e/spring-shell-e2e/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
lib
|
||||
11
e2e/spring-shell-e2e/.prettierrc.json
Normal file
11
e2e/spring-shell-e2e/.prettierrc.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "avoid",
|
||||
"parser": "typescript"
|
||||
}
|
||||
38
e2e/spring-shell-e2e/package-lock.json
generated
Normal file
38
e2e/spring-shell-e2e/package-lock.json
generated
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "spring-shell-e2e",
|
||||
"version": "2.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"nan": {
|
||||
"version": "2.15.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
|
||||
"integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ=="
|
||||
},
|
||||
"node-pty": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/node-pty/-/node-pty-0.10.1.tgz",
|
||||
"integrity": "sha512-JTdtUS0Im/yRsWJSx7yiW9rtpfmxqxolrtnyKwPLI+6XqTAPW/O2MjS8FYL4I5TsMbH2lVgDb2VMjp+9LoQGNg==",
|
||||
"requires": {
|
||||
"nan": "^2.14.0"
|
||||
}
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
|
||||
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.6.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
|
||||
"integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
|
||||
"dev": true
|
||||
},
|
||||
"xterm-headless": {
|
||||
"version": "4.18.0",
|
||||
"resolved": "https://registry.npmjs.org/xterm-headless/-/xterm-headless-4.18.0.tgz",
|
||||
"integrity": "sha512-VwSPG2cyVOwesVVLBVrybYNY6cUMiVkD2fLnIXcBs/1iJ3M7bhD3lP9HdQOHGtOkbxV2Duf7MZNmEfngBXL/iQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
41
e2e/spring-shell-e2e/package.json
Normal file
41
e2e/spring-shell-e2e/package.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "spring-shell-e2e",
|
||||
"version": "2.1.0",
|
||||
"description": "spring-shell e2e test framework",
|
||||
"main": "./lib/cli.js",
|
||||
"exports": {
|
||||
".": "./lib/cli.js"
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"cli.d.ts": [
|
||||
"lib/cli.d.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "jest",
|
||||
"format": "prettier --write **/*.ts",
|
||||
"format-check": "prettier --check **/*.ts"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/spring-projects/spring-shell.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/spring-projects/spring-shell/issues"
|
||||
},
|
||||
"homepage": "https://github.com/spring-projects/spring-shell#readme",
|
||||
"devDependencies": {
|
||||
"prettier": "^2.6.2",
|
||||
"typescript": "^4.6.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-pty": "^0.10.1",
|
||||
"xterm-headless": "^4.18.0"
|
||||
}
|
||||
}
|
||||
128
e2e/spring-shell-e2e/src/cli.ts
Normal file
128
e2e/spring-shell-e2e/src/cli.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import * as pty from 'node-pty';
|
||||
import { Terminal } from 'xterm-headless';
|
||||
|
||||
export interface CliOptions {
|
||||
command: string;
|
||||
options?: string[];
|
||||
keyWait?: number;
|
||||
cols?: number;
|
||||
rows?: number;
|
||||
}
|
||||
|
||||
export class Cli {
|
||||
private isDisposed: boolean = false;
|
||||
private pty: pty.IPty | undefined;
|
||||
private term: Terminal | undefined;
|
||||
private keyWait: number = 500;
|
||||
private cols: number = 80;
|
||||
private rows: number = 20;
|
||||
private exit: Promise<number> | undefined;
|
||||
|
||||
constructor(private options: CliOptions) {
|
||||
if (options.keyWait) {
|
||||
this.keyWait = options.keyWait;
|
||||
}
|
||||
if (options.cols) {
|
||||
this.cols = options.cols;
|
||||
}
|
||||
if (options.rows) {
|
||||
this.rows = options.rows;
|
||||
}
|
||||
}
|
||||
|
||||
public run(): void {
|
||||
this.pty = pty.spawn(this.options.command, this.options.options || [], {
|
||||
name: 'xterm-256color',
|
||||
cols: this.cols,
|
||||
rows: this.rows
|
||||
});
|
||||
this.term = new Terminal({
|
||||
cols: this.cols,
|
||||
rows: this.rows
|
||||
});
|
||||
this.pty.onData(data => {
|
||||
this.term?.write(data);
|
||||
});
|
||||
this.exit = new Promise(resolve => {
|
||||
this.pty?.onExit(data => {
|
||||
resolve(data.exitCode);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public exitCode(): Promise<number> {
|
||||
if (!this.exit) {
|
||||
return Promise.reject('cli has not been started');
|
||||
}
|
||||
return this.exit;
|
||||
}
|
||||
|
||||
public screen(): string[] {
|
||||
const l = this.term?.buffer.active.length || 0;
|
||||
const ret: string[] = [];
|
||||
for (let index = 0; index < l; index++) {
|
||||
const line = this.term?.buffer.active.getLine(index)?.translateToString();
|
||||
if (line) {
|
||||
ret.push(line);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public async keyText(data: string, wait: number): Promise<Cli> {
|
||||
if (!this.pty) {
|
||||
return Promise.reject('cli has not been started');
|
||||
}
|
||||
this.pty.write(data);
|
||||
await this.doWait(wait);
|
||||
return this;
|
||||
}
|
||||
|
||||
public async keyUp(wait?: number): Promise<Cli> {
|
||||
if (!this.pty) {
|
||||
return Promise.reject('cli has not been started');
|
||||
}
|
||||
this.pty.write('\x1BOA');
|
||||
await this.doWait(wait);
|
||||
return this;
|
||||
}
|
||||
|
||||
public async keyDown(wait?: number): Promise<Cli> {
|
||||
if (!this.pty) {
|
||||
return Promise.reject('cli has not been started');
|
||||
}
|
||||
this.pty.write('\x1BOB');
|
||||
await this.doWait(wait);
|
||||
return this;
|
||||
}
|
||||
|
||||
public async keyEnter(wait?: number): Promise<Cli> {
|
||||
if (!this.pty) {
|
||||
return Promise.reject('cli has not been started');
|
||||
}
|
||||
this.pty.write('\x0D');
|
||||
await this.doWait(wait);
|
||||
return this;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this.isDisposed) {
|
||||
return;
|
||||
}
|
||||
if (this.pty) {
|
||||
this.pty.kill();
|
||||
}
|
||||
if (this.term) {
|
||||
this.term.dispose();
|
||||
}
|
||||
this.isDisposed = true;
|
||||
}
|
||||
|
||||
private async doWait(wait?: number): Promise<void> {
|
||||
await this.sleep(wait || this.keyWait);
|
||||
}
|
||||
|
||||
private async sleep(ms: number): Promise<void> {
|
||||
return new Promise(r => setTimeout(r, ms));
|
||||
}
|
||||
}
|
||||
13
e2e/spring-shell-e2e/tsconfig.json
Normal file
13
e2e/spring-shell-e2e/tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
"module": "commonjs", /* Specify what module code is generated. */
|
||||
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
"outDir": "./lib", /* Specify an output folder for all emitted files. */
|
||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
|
||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user