mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-16 10:33:43 +08:00
test: update tests to work with Jasmine version 4
These changes include fixes to tests, timeout and stop of architect to make tests work with Jasmine 4. One noticeable change that when we didn't stop architect through `run.stop()` this causes Bazel to timeout now. Example ``` -- Test timed out at 2022-03-24 12:07:07 UTC -- /private/var/tmp/_bazel_alanagius/5168427e57f204ca069c602aa7ed1931/sandbox/darwin-sandbox/398/execroot/angular_cli/bazel-out/darwin-fastbuild/bin/packages/angular_devkit/build_angular/build_angular_browser_test.sh.runfiles/angular_cli/packages/angular_devkit/build_angular/build_angular_browser_test.sh: line 424: 41835 Terminated: 15 "${node}" ${LAUNCHER_NODE_OPTIONS[@]+"${LAUNCHER_NODE_OPTIONS[@]}"} ${USER_NODE_OPTIONS[@]+"${USER_NODE_OPTIONS[@]}"} "${MAIN}" ${ARGS[@]+"${ARGS[@]}"} 0<&0 ```
This commit is contained in:
parent
b50efbbd46
commit
4b4cecf88f
4
lib/bootstrap-local.js
vendored
4
lib/bootstrap-local.js
vendored
@ -16,11 +16,11 @@ const debugBuildTs = debug('ng:local:build:ts');
|
||||
|
||||
const child_process = require('child_process');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const temp = require('temp');
|
||||
const ts = require('typescript');
|
||||
|
||||
const tmpRoot = temp.mkdirSync('angular-devkit-');
|
||||
const tmpRoot = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), 'angular-devkit-'));
|
||||
|
||||
debugLocal('starting bootstrap local');
|
||||
|
||||
|
@ -202,7 +202,6 @@
|
||||
"stylus-loader": "6.2.0",
|
||||
"symbol-observable": "4.0.0",
|
||||
"tar": "^6.1.6",
|
||||
"temp": "^0.9.0",
|
||||
"terser": "5.12.1",
|
||||
"text-table": "0.2.0",
|
||||
"tree-kill": "1.2.2",
|
||||
|
@ -63,7 +63,6 @@ jasmine_node_test(
|
||||
"@npm//pidtree",
|
||||
"@npm//pidusage",
|
||||
"@npm//source-map",
|
||||
"@npm//temp",
|
||||
"@npm//tree-kill",
|
||||
"@npm//yargs-parser",
|
||||
],
|
||||
|
@ -6,13 +6,11 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
|
||||
import { existsSync, mkdtempSync, readFileSync, realpathSync, unlinkSync, writeFileSync } from 'fs';
|
||||
import { tmpdir } from 'os';
|
||||
import { basename, dirname, join } from 'path';
|
||||
import { main } from './main';
|
||||
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
const temp = require('temp');
|
||||
|
||||
// We only care about the write method in these mocks of NodeJS.WriteStream.
|
||||
class MockWriteStream {
|
||||
lines: string[] = [];
|
||||
@ -29,7 +27,7 @@ describe('benchmark binary', () => {
|
||||
const exitCodeOneScript = require.resolve(join(__dirname, './test/exit-code-one.js'));
|
||||
const benchmarkWatchScript = require.resolve(join(__dirname, './test/watch-test-cmd.js'));
|
||||
const watchTriggerScript = require.resolve(join(__dirname, './test/watch-test-script.js'));
|
||||
const outputFileRoot = temp.mkdirSync('benchmark-binary-spec-');
|
||||
const outputFileRoot = mkdtempSync(join(realpathSync(tmpdir()), 'benchmark-binary-spec-'));
|
||||
const outputFile = join(outputFileRoot, 'output.log');
|
||||
let stdout: MockWriteStream, stderr: MockWriteStream;
|
||||
|
||||
|
@ -30,11 +30,8 @@ describe('Browser Builder build optimizer', () => {
|
||||
it('fails if AOT is disabled', async () => {
|
||||
const overrides = { aot: false, buildOptimizer: true };
|
||||
const run = await architect.scheduleTarget(targetSpec, overrides);
|
||||
|
||||
try {
|
||||
await run.result;
|
||||
expect('THE ABOVE LINE SHOULD THROW').toBe('');
|
||||
} catch {}
|
||||
await expectAsync(run.result).toBeRejectedWithError();
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
it('reduces bundle size', async () => {
|
||||
|
@ -99,5 +99,6 @@ describe('Browser Builder crossOrigin', () => {
|
||||
const fileName = join(normalize(output.outputPath), 'runtime.js');
|
||||
const content = virtualFs.fileBufferToString(await host.read(normalize(fileName)).toPromise());
|
||||
expect(content).toContain('script.crossOrigin = "use-credentials"');
|
||||
await run.stop();
|
||||
});
|
||||
});
|
||||
|
@ -156,6 +156,7 @@ describe('Browser Builder index HTML processing', () => {
|
||||
`<script src="polyfills.js" type="module"></script>` +
|
||||
`<script src="vendor.js" type="module"></script><script src="main.js" type="module"></script></body></html>`,
|
||||
);
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
it('uses the output value from the index option longform', async () => {
|
||||
@ -202,6 +203,7 @@ describe('Browser Builder index HTML processing', () => {
|
||||
`<script src="polyfills.js" type="module"></script>` +
|
||||
`<script src="vendor.js" type="module"></script><script src="main.js" type="module"></script></body></html>`,
|
||||
);
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
it('creates subdirectories for output value from the index option longform', async () => {
|
||||
@ -248,5 +250,6 @@ describe('Browser Builder index HTML processing', () => {
|
||||
`<script src="polyfills.js" type="module"></script>` +
|
||||
`<script src="vendor.js" type="module"></script><script src="main.js" type="module"></script></body></html>`,
|
||||
);
|
||||
await run.stop();
|
||||
});
|
||||
});
|
||||
|
@ -65,7 +65,7 @@ describe('Browser Builder lazy modules', () => {
|
||||
|
||||
const { files } = await browserBuild(architect, host, target, { aot: true });
|
||||
const data = await files['src_app_lazy_lazy_module_ts.js'];
|
||||
expect(data).not.toBeUndefined('Lazy module output bundle does not exist');
|
||||
expect(data).not.toBeUndefined();
|
||||
expect(data).toContain('LazyModule.ɵmod');
|
||||
});
|
||||
});
|
||||
@ -85,7 +85,8 @@ describe('Browser Builder lazy modules', () => {
|
||||
const run = await architect.scheduleTarget(target, {}, { logger });
|
||||
const output = await run.result;
|
||||
expect(output.success).toBe(false);
|
||||
expect(hasMissingModuleError(logs.join())).toBe(true, 'Should show missing module error');
|
||||
expect(hasMissingModuleError(logs.join())).toBeTrue();
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
it('should show error when lazy route is invalid on watch mode AOT', async () => {
|
||||
@ -98,7 +99,7 @@ describe('Browser Builder lazy modules', () => {
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
await run.output
|
||||
.pipe(
|
||||
debounceTime(3000),
|
||||
debounceTime(1500),
|
||||
tap((buildEvent) => {
|
||||
buildNumber++;
|
||||
switch (buildNumber) {
|
||||
|
@ -65,6 +65,7 @@ describe('Browser Builder output path', () => {
|
||||
|
||||
expect(await host.exists(join(host.root(), 'dist')).toPromise()).toBe(false);
|
||||
expect(await host.exists(join(host.root(), 'src-link')).toPromise()).toBe(true);
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
it('does not allow output path to be project root', async () => {
|
||||
|
@ -7,8 +7,9 @@
|
||||
*/
|
||||
|
||||
import { Architect } from '@angular-devkit/architect';
|
||||
import { debounceTime, take, tap } from 'rxjs/operators';
|
||||
import { debounceTime, take, tap, timeout } from 'rxjs/operators';
|
||||
import { createArchitect, host } from '../../../testing/test-utils';
|
||||
import { BUILD_TIMEOUT } from '../index';
|
||||
|
||||
describe('Browser Builder poll', () => {
|
||||
const target = { project: 'app', target: 'build' };
|
||||
@ -21,13 +22,14 @@ describe('Browser Builder poll', () => {
|
||||
afterEach(async () => host.restore().toPromise());
|
||||
|
||||
it('works', async () => {
|
||||
const overrides = { watch: true, poll: 10000 };
|
||||
const overrides = { watch: true, poll: 4000 };
|
||||
const intervals: number[] = [];
|
||||
let startTime: number | undefined;
|
||||
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
// Debounce 1s, otherwise changes are too close together and polling doesn't work.
|
||||
debounceTime(1000),
|
||||
tap((buildEvent) => {
|
||||
@ -46,5 +48,7 @@ describe('Browser Builder poll', () => {
|
||||
const median = intervals[Math.trunc(intervals.length / 2)];
|
||||
expect(median).toBeGreaterThan(3000);
|
||||
expect(median).toBeLessThan(12000);
|
||||
|
||||
await run.stop();
|
||||
});
|
||||
});
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import { Architect } from '@angular-devkit/architect';
|
||||
import { join, logging, normalize, virtualFs } from '@angular-devkit/core';
|
||||
import { debounceTime, take, takeWhile, tap } from 'rxjs/operators';
|
||||
import { debounceTime, take, takeWhile, tap, timeout } from 'rxjs/operators';
|
||||
import {
|
||||
createArchitect,
|
||||
host,
|
||||
@ -16,6 +16,7 @@ import {
|
||||
lazyModuleFnImport,
|
||||
outputPath,
|
||||
} from '../../../testing/test-utils';
|
||||
import { BUILD_TIMEOUT } from '../index';
|
||||
|
||||
describe('Browser Builder rebuilds', () => {
|
||||
const target = { project: 'app', target: 'build' };
|
||||
@ -78,9 +79,10 @@ describe('Browser Builder rebuilds', () => {
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap((result) => {
|
||||
expect(result.success).toBe(true, 'build should succeed');
|
||||
expect(result.success).toBeTrue();
|
||||
const hasLazyChunk = host
|
||||
.scopedSync()
|
||||
.exists(normalize('dist/src_app_lazy_lazy_module_ts.js'));
|
||||
@ -131,6 +133,7 @@ describe('Browser Builder rebuilds', () => {
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => host.appendToFile('src/app/app.component.css', ':host { color: blue; }')),
|
||||
@ -164,6 +167,7 @@ describe('Browser Builder rebuilds', () => {
|
||||
const run = await architect.scheduleTarget(target, overrides, { logger });
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap((buildEvent) => {
|
||||
buildNumber += 1;
|
||||
@ -217,12 +221,14 @@ describe('Browser Builder rebuilds', () => {
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => host.writeMultipleFiles({ 'src/type.ts': `export type MyType = string;` })),
|
||||
take(2),
|
||||
)
|
||||
.toPromise();
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
it('rebuilds on transitive type-only file changes', async () => {
|
||||
@ -250,6 +256,7 @@ describe('Browser Builder rebuilds', () => {
|
||||
let buildNumber = 0;
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => {
|
||||
@ -266,6 +273,8 @@ describe('Browser Builder rebuilds', () => {
|
||||
take(5),
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
it('rebuilds on transitive non node package DTS file changes', async () => {
|
||||
@ -293,6 +302,7 @@ describe('Browser Builder rebuilds', () => {
|
||||
let buildNumber = 0;
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
|
||||
tap(() => {
|
||||
@ -304,6 +314,7 @@ describe('Browser Builder rebuilds', () => {
|
||||
take(2),
|
||||
)
|
||||
.toPromise();
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
it('rebuilds after errors in JIT', async () => {
|
||||
@ -318,6 +329,7 @@ describe('Browser Builder rebuilds', () => {
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap((buildEvent) => {
|
||||
buildNumber++;
|
||||
@ -363,6 +375,7 @@ describe('Browser Builder rebuilds', () => {
|
||||
const run = await architect.scheduleTarget(target, overrides, { logger });
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap((buildEvent) => {
|
||||
buildNumber += 1;
|
||||
@ -461,6 +474,7 @@ describe('Browser Builder rebuilds', () => {
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap((buildEvent) => {
|
||||
buildNumber += 1;
|
||||
@ -551,6 +565,7 @@ describe('Browser Builder rebuilds', () => {
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap((buildEvent) => {
|
||||
buildNumber += 1;
|
||||
@ -615,6 +630,7 @@ describe('Browser Builder rebuilds', () => {
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
await run.output
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT),
|
||||
debounceTime(rebuildDebounceTime),
|
||||
tap(() => {
|
||||
const content = virtualFs.fileBufferToString(
|
||||
|
@ -76,10 +76,7 @@ describe('Browser Builder file replacements', () => {
|
||||
};
|
||||
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
try {
|
||||
await run.result;
|
||||
expect('THE ABOVE LINE SHOULD THROW').toBe('');
|
||||
} catch {}
|
||||
await expectAsync(run.result).toBeRejectedWithError();
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
@ -94,10 +91,7 @@ describe('Browser Builder file replacements', () => {
|
||||
};
|
||||
|
||||
const run = await architect.scheduleTarget(target, overrides);
|
||||
try {
|
||||
await run.result;
|
||||
expect('THE ABOVE LINE SHOULD THROW').toBe('');
|
||||
} catch {}
|
||||
await expectAsync(run.result).toBeRejectedWithError();
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
@ -214,7 +208,7 @@ describe('Browser Builder file replacements', () => {
|
||||
.subscribe();
|
||||
|
||||
const res = await stop$.toPromise();
|
||||
expect(res).not.toBe(null, 'Test timed out.');
|
||||
expect(res).toBeDefined();
|
||||
expect(res).not.toContain(unexpectedError);
|
||||
await run.stop();
|
||||
});
|
||||
|
@ -62,5 +62,7 @@ describe('Browser Builder resolve json module', () => {
|
||||
take(2),
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
await run.stop();
|
||||
});
|
||||
});
|
||||
|
@ -513,6 +513,8 @@ describe('Browser Builder styles', () => {
|
||||
|
||||
const run2 = await architect.scheduleTarget(target, overrides);
|
||||
await expectAsync(run2.result).toBeResolvedTo(jasmine.objectContaining({ success: false }));
|
||||
await run2.stop();
|
||||
await run.stop();
|
||||
});
|
||||
|
||||
it('supports Protocol-relative Url', async () => {
|
||||
|
@ -11,7 +11,7 @@ import { Architect, BuilderRun } from '@angular-devkit/architect';
|
||||
import { tags } from '@angular-devkit/core';
|
||||
import { createProxyServer } from 'http-proxy';
|
||||
import puppeteer, { Browser, Page } from 'puppeteer';
|
||||
import { debounceTime, switchMap, take } from 'rxjs/operators';
|
||||
import { debounceTime, finalize, switchMap, take } from 'rxjs/operators';
|
||||
import { createArchitect, host } from '../../../testing/test-utils';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@ -131,7 +131,6 @@ describe('Dev Server Builder live-reload', () => {
|
||||
let browser: Browser;
|
||||
let page: Page;
|
||||
let runs: BuilderRun[];
|
||||
let proxy: ProxyInstance | undefined;
|
||||
|
||||
beforeAll(async () => {
|
||||
browser = await puppeteer.launch({
|
||||
@ -164,8 +163,6 @@ describe('Dev Server Builder live-reload', () => {
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
proxy?.server.close();
|
||||
proxy = undefined;
|
||||
await host.restore().toPromise();
|
||||
await page.close();
|
||||
await Promise.all(runs.map((r) => r.stop()));
|
||||
@ -227,6 +224,9 @@ describe('Dev Server Builder live-reload', () => {
|
||||
buildCount++;
|
||||
}),
|
||||
take(2),
|
||||
finalize(() => {
|
||||
proxy?.server.close();
|
||||
}),
|
||||
)
|
||||
.toPromise();
|
||||
});
|
||||
@ -258,6 +258,9 @@ describe('Dev Server Builder live-reload', () => {
|
||||
buildCount++;
|
||||
}),
|
||||
take(2),
|
||||
finalize(() => {
|
||||
proxy?.server.close();
|
||||
}),
|
||||
)
|
||||
.toPromise();
|
||||
});
|
||||
|
@ -57,7 +57,7 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
|
||||
const buildCount = await harness
|
||||
.execute()
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT * 2),
|
||||
timeout(BUILD_TIMEOUT),
|
||||
concatMap(async ({ result }, index) => {
|
||||
expect(result?.success).toBe(true);
|
||||
|
||||
|
@ -32,7 +32,7 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
|
||||
await harness
|
||||
.execute()
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT * 2),
|
||||
timeout(BUILD_TIMEOUT),
|
||||
concatMap(async ({ result }, index) => {
|
||||
expect(result?.success).toBe(true);
|
||||
|
||||
@ -68,7 +68,7 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
|
||||
const buildCount = await harness
|
||||
.execute()
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT * 2),
|
||||
timeout(BUILD_TIMEOUT),
|
||||
concatMap(async ({ result }, index) => {
|
||||
expect(result?.success).toBe(true);
|
||||
|
||||
@ -100,7 +100,7 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
|
||||
const buildCount = await harness
|
||||
.execute()
|
||||
.pipe(
|
||||
timeout(BUILD_TIMEOUT * 2),
|
||||
timeout(BUILD_TIMEOUT),
|
||||
concatMap(async ({ result }, index) => {
|
||||
expect(result?.success).toBe(true);
|
||||
|
||||
|
@ -38,7 +38,7 @@ export const BASE_OPTIONS = Object.freeze<Schema>({
|
||||
* Maximum time for single build/rebuild
|
||||
* This accounts for CI variability.
|
||||
*/
|
||||
export const BUILD_TIMEOUT = 15_000;
|
||||
export const BUILD_TIMEOUT = 25_000;
|
||||
|
||||
/**
|
||||
* Cached browser builder option schema
|
||||
|
@ -57,7 +57,6 @@ jasmine_node_test(
|
||||
srcs = [":node_test_lib"],
|
||||
deps = [
|
||||
"@npm//chokidar",
|
||||
"@npm//temp",
|
||||
# @node_module: ajv
|
||||
# @node_module: fast_json_stable_stringify
|
||||
# @node_module: magic_string
|
||||
|
@ -6,15 +6,13 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { normalize, virtualFs } from '@angular-devkit/core';
|
||||
import { NodeJsAsyncHost, NodeJsSyncHost } from '@angular-devkit/core/node';
|
||||
import * as fs from 'fs';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
const temp = require('temp');
|
||||
import { tmpdir } from 'os';
|
||||
import { join } from 'path';
|
||||
|
||||
// TODO: replace this with an "it()" macro that's reusable globally.
|
||||
let linuxOnlyIt: typeof it = it;
|
||||
@ -27,11 +25,11 @@ describe('NodeJsAsyncHost', () => {
|
||||
let host: virtualFs.Host<fs.Stats>;
|
||||
|
||||
beforeEach(() => {
|
||||
root = temp.mkdirSync('core-node-spec-');
|
||||
root = fs.mkdtempSync(join(fs.realpathSync(tmpdir()), 'core-node-spec-'));
|
||||
host = new virtualFs.ScopedHost(new NodeJsAsyncHost(), normalize(root));
|
||||
});
|
||||
|
||||
afterEach((done) => host.delete(normalize('/')).toPromise().then(done, done.fail));
|
||||
afterEach(async () => host.delete(normalize('/')).toPromise());
|
||||
|
||||
it('should get correct result for exists', async () => {
|
||||
const filePath = normalize('not-found');
|
||||
@ -42,35 +40,30 @@ describe('NodeJsAsyncHost', () => {
|
||||
|
||||
linuxOnlyIt(
|
||||
'can watch',
|
||||
(done) => {
|
||||
let obs: Observable<virtualFs.HostWatchEvent>;
|
||||
let subscription: Subscription;
|
||||
async () => {
|
||||
const content = virtualFs.stringToFileBuffer('hello world');
|
||||
const content2 = virtualFs.stringToFileBuffer('hello world 2');
|
||||
const allEvents: virtualFs.HostWatchEvent[] = [];
|
||||
|
||||
Promise.resolve()
|
||||
.then(() => fs.mkdirSync(root + '/sub1'))
|
||||
.then(() => fs.writeFileSync(root + '/sub1/file1', 'hello world'))
|
||||
.then(() => {
|
||||
obs = host.watch(normalize('/sub1'), { recursive: true })!;
|
||||
expect(obs).not.toBeNull();
|
||||
subscription = obs.subscribe((event) => {
|
||||
allEvents.push(event);
|
||||
});
|
||||
})
|
||||
.then(() => new Promise((resolve) => setTimeout(resolve, 100)))
|
||||
// Discard the events registered so far.
|
||||
.then(() => allEvents.splice(0))
|
||||
.then(() => host.write(normalize('/sub1/sub2/file3'), content).toPromise())
|
||||
.then(() => host.write(normalize('/sub1/file2'), content2).toPromise())
|
||||
.then(() => host.delete(normalize('/sub1/file1')).toPromise())
|
||||
.then(() => new Promise((resolve) => setTimeout(resolve, 2000)))
|
||||
.then(() => {
|
||||
expect(allEvents.length).toBe(3);
|
||||
subscription.unsubscribe();
|
||||
})
|
||||
.then(done, done.fail);
|
||||
fs.mkdirSync(root + '/sub1');
|
||||
fs.writeFileSync(root + '/sub1/file1', 'hello world');
|
||||
|
||||
const obs = host.watch(normalize('/sub1'), { recursive: true });
|
||||
expect(obs).toBeDefined();
|
||||
const subscription = obs!.subscribe((event) => {
|
||||
allEvents.push(event);
|
||||
});
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
// Discard the events registered so far.
|
||||
allEvents.splice(0);
|
||||
await host.write(normalize('/sub1/sub2/file3'), content).toPromise();
|
||||
await host.write(normalize('/sub1/file2'), content2).toPromise();
|
||||
await host.delete(normalize('/sub1/file1')).toPromise();
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
expect(allEvents.length).toBe(3);
|
||||
subscription.unsubscribe();
|
||||
},
|
||||
30000,
|
||||
);
|
||||
@ -81,7 +74,7 @@ describe('NodeJsSyncHost', () => {
|
||||
let host: virtualFs.SyncDelegateHost<fs.Stats>;
|
||||
|
||||
beforeEach(() => {
|
||||
root = temp.mkdirSync('core-node-spec-');
|
||||
root = fs.mkdtempSync(join(fs.realpathSync(tmpdir()), 'core-node-spec-'));
|
||||
host = new virtualFs.SyncDelegateHost(
|
||||
new virtualFs.ScopedHost(new NodeJsSyncHost(), normalize(root)),
|
||||
);
|
||||
@ -92,56 +85,47 @@ describe('NodeJsSyncHost', () => {
|
||||
|
||||
linuxOnlyIt(
|
||||
'can watch',
|
||||
(done) => {
|
||||
let obs: Observable<virtualFs.HostWatchEvent>;
|
||||
let subscription: Subscription;
|
||||
async () => {
|
||||
const content = virtualFs.stringToFileBuffer('hello world');
|
||||
const content2 = virtualFs.stringToFileBuffer('hello world 2');
|
||||
const allEvents: virtualFs.HostWatchEvent[] = [];
|
||||
|
||||
Promise.resolve()
|
||||
.then(() => fs.mkdirSync(root + '/sub1'))
|
||||
.then(() => fs.writeFileSync(root + '/sub1/file1', 'hello world'))
|
||||
.then(() => {
|
||||
obs = host.watch(normalize('/sub1'), { recursive: true })!;
|
||||
expect(obs).not.toBeNull();
|
||||
subscription = obs.subscribe((event) => {
|
||||
allEvents.push(event);
|
||||
});
|
||||
})
|
||||
.then(() => new Promise((resolve) => setTimeout(resolve, 100)))
|
||||
// Discard the events registered so far.
|
||||
.then(() => allEvents.splice(0))
|
||||
.then(() => {
|
||||
host.write(normalize('/sub1/sub2/file3'), content);
|
||||
host.write(normalize('/sub1/file2'), content2);
|
||||
host.delete(normalize('/sub1/file1'));
|
||||
})
|
||||
.then(() => new Promise((resolve) => setTimeout(resolve, 2000)))
|
||||
.then(() => {
|
||||
expect(allEvents.length).toBe(3);
|
||||
subscription.unsubscribe();
|
||||
})
|
||||
.then(done, done.fail);
|
||||
fs.mkdirSync(root + '/sub1');
|
||||
fs.writeFileSync(root + '/sub1/file1', 'hello world');
|
||||
|
||||
const obs = host.watch(normalize('/sub1'), { recursive: true });
|
||||
expect(obs).toBeDefined();
|
||||
const subscription = obs!.subscribe((event) => {
|
||||
allEvents.push(event);
|
||||
});
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
// Discard the events registered so far.
|
||||
allEvents.splice(0);
|
||||
|
||||
host.write(normalize('/sub1/sub2/file3'), content);
|
||||
host.write(normalize('/sub1/file2'), content2);
|
||||
host.delete(normalize('/sub1/file1'));
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
|
||||
expect(allEvents.length).toBe(3);
|
||||
subscription.unsubscribe();
|
||||
},
|
||||
30000,
|
||||
);
|
||||
|
||||
linuxOnlyIt(
|
||||
'rename to a non-existing dir',
|
||||
(done) => {
|
||||
Promise.resolve()
|
||||
.then(() => fs.mkdirSync(root + '/rename'))
|
||||
.then(() => fs.writeFileSync(root + '/rename/a.txt', 'hello world'))
|
||||
.then(() => {
|
||||
host.rename(normalize('/rename/a.txt'), normalize('/rename/b/c/d/a.txt'));
|
||||
if (fs.existsSync(root + '/rename/b/c/d/a.txt')) {
|
||||
const resContent = host.read(normalize('/rename/b/c/d/a.txt'));
|
||||
const content = virtualFs.fileBufferToString(resContent);
|
||||
expect(content).toEqual('hello world');
|
||||
}
|
||||
})
|
||||
.then(done, done.fail);
|
||||
() => {
|
||||
fs.mkdirSync(root + '/rename');
|
||||
fs.writeFileSync(root + '/rename/a.txt', 'hello world');
|
||||
|
||||
host.rename(normalize('/rename/a.txt'), normalize('/rename/b/c/d/a.txt'));
|
||||
if (fs.existsSync(root + '/rename/b/c/d/a.txt')) {
|
||||
const resContent = host.read(normalize('/rename/b/c/d/a.txt'));
|
||||
const content = virtualFs.fileBufferToString(resContent);
|
||||
expect(content).toEqual('hello world');
|
||||
}
|
||||
},
|
||||
30000,
|
||||
);
|
||||
|
@ -11,7 +11,7 @@ import { map, mergeMap } from 'rxjs/operators';
|
||||
import { CoreSchemaRegistry } from './registry';
|
||||
|
||||
describe('Prompt Provider', () => {
|
||||
it('sets properties with answer', (done) => {
|
||||
it('sets properties with answer', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -19,7 +19,7 @@ describe('Prompt Provider', () => {
|
||||
return { [definitions[0].id]: true };
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -34,11 +34,10 @@ describe('Prompt Provider', () => {
|
||||
expect(data.test).toBe(true);
|
||||
}),
|
||||
)
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('supports mixed schema references', (done) => {
|
||||
it('supports mixed schema references', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -50,7 +49,7 @@ describe('Prompt Provider', () => {
|
||||
};
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
bool: {
|
||||
@ -96,12 +95,11 @@ describe('Prompt Provider', () => {
|
||||
expect(data.obj.deep.three).toEqual('test3-answer');
|
||||
}),
|
||||
)
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
describe('with shorthand', () => {
|
||||
it('supports message value', (done) => {
|
||||
it('supports message value', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -112,7 +110,7 @@ describe('Prompt Provider', () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -122,11 +120,10 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('analyzes enums', (done) => {
|
||||
it('analyzes enums', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -138,7 +135,7 @@ describe('Prompt Provider', () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -149,11 +146,10 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('analyzes boolean properties', (done) => {
|
||||
it('analyzes boolean properties', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -165,7 +161,7 @@ describe('Prompt Provider', () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -175,13 +171,12 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with longhand', () => {
|
||||
it('supports message option', (done) => {
|
||||
it('supports message option', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -192,7 +187,7 @@ describe('Prompt Provider', () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -204,11 +199,10 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('analyzes enums WITH explicit list type', (done) => {
|
||||
it('analyzes enums WITH explicit list type', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -220,7 +214,7 @@ describe('Prompt Provider', () => {
|
||||
return { [definitions[0].id]: 'one' };
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -234,11 +228,10 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('analyzes list with true multiselect option and object items', (done) => {
|
||||
it('analyzes list with true multiselect option and object items', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -254,7 +247,7 @@ describe('Prompt Provider', () => {
|
||||
return { [definitions[0].id]: { 'value': 'one', 'label': 'one' } };
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -272,11 +265,10 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('analyzes list with false multiselect option and object items', (done) => {
|
||||
it('analyzes list with false multiselect option and object items', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -292,7 +284,7 @@ describe('Prompt Provider', () => {
|
||||
return { [definitions[0].id]: { 'value': 'one', 'label': 'one' } };
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -310,11 +302,10 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('analyzes list without multiselect option and object items', (done) => {
|
||||
it('analyzes list without multiselect option and object items', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -330,7 +321,7 @@ describe('Prompt Provider', () => {
|
||||
return { [definitions[0].id]: { 'value': 'two', 'label': 'two' } };
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -347,11 +338,10 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('analyzes enums WITHOUT explicit list type', (done) => {
|
||||
it('analyzes enums WITHOUT explicit list type', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -364,7 +354,7 @@ describe('Prompt Provider', () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -377,11 +367,10 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('analyzes enums WITHOUT explicit list type and multiselect', (done) => {
|
||||
it('analyzes enums WITHOUT explicit list type and multiselect', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -394,7 +383,7 @@ describe('Prompt Provider', () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -407,11 +396,10 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('analyzes boolean properties', (done) => {
|
||||
it('analyzes boolean properties', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -423,7 +411,7 @@ describe('Prompt Provider', () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -435,11 +423,10 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('allows prompt type override', (done) => {
|
||||
it('allows prompt type override', async () => {
|
||||
const registry = new CoreSchemaRegistry();
|
||||
const data: any = {};
|
||||
|
||||
@ -451,7 +438,7 @@ describe('Prompt Provider', () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
registry
|
||||
await registry
|
||||
.compile({
|
||||
properties: {
|
||||
test: {
|
||||
@ -464,8 +451,7 @@ describe('Prompt Provider', () => {
|
||||
},
|
||||
})
|
||||
.pipe(mergeMap((validator) => validator(data)))
|
||||
.toPromise()
|
||||
.then(done, done.fail);
|
||||
.toPromise();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -18,7 +18,7 @@ const host = new virtualFs.test.TestHost({
|
||||
});
|
||||
|
||||
describe('DryRunSink', () => {
|
||||
it('works when creating everything', (done) => {
|
||||
it('works when creating everything', async () => {
|
||||
const tree = new HostCreateTree(host);
|
||||
|
||||
tree.create('/test', 'testing 1 2');
|
||||
@ -34,21 +34,20 @@ describe('DryRunSink', () => {
|
||||
expect(treeFiles).toEqual(files.map(normalize));
|
||||
|
||||
const sink = new DryRunSink(new virtualFs.SimpleMemoryHost());
|
||||
sink.reporter
|
||||
.pipe(toArray())
|
||||
.toPromise()
|
||||
.then((infos) => {
|
||||
expect(infos.length).toBe(4);
|
||||
for (const info of infos) {
|
||||
expect(info.kind).toBe('create');
|
||||
}
|
||||
})
|
||||
.then(done, done.fail);
|
||||
|
||||
sink.commit(tree).toPromise().then(done, done.fail);
|
||||
const [infos] = await Promise.all([
|
||||
sink.reporter.pipe(toArray()).toPromise(),
|
||||
sink.commit(tree).toPromise(),
|
||||
]);
|
||||
|
||||
expect(infos.length).toBe(4);
|
||||
|
||||
for (const info of infos) {
|
||||
expect(info.kind).toBe('create');
|
||||
}
|
||||
});
|
||||
|
||||
it('works with root', (done) => {
|
||||
it('works with root', async () => {
|
||||
const tree = new HostTree(host);
|
||||
|
||||
tree.create('/test', 'testing 1 2');
|
||||
@ -68,14 +67,11 @@ describe('DryRunSink', () => {
|
||||
outputHost.write(normalize('/hello'), virtualFs.stringToFileBuffer('')).subscribe();
|
||||
|
||||
const sink = new DryRunSink(outputHost);
|
||||
sink.reporter
|
||||
.pipe(toArray())
|
||||
.toPromise()
|
||||
.then((infos) => {
|
||||
expect(infos.map((x) => x.kind)).toEqual(['create', 'update']);
|
||||
})
|
||||
.then(done, done.fail);
|
||||
const [infos] = await Promise.all([
|
||||
sink.reporter.pipe(toArray()).toPromise(),
|
||||
sink.commit(tree).toPromise(),
|
||||
]);
|
||||
|
||||
sink.commit(tree).toPromise().then(done, done.fail);
|
||||
expect(infos.map((x) => x.kind)).toEqual(['create', 'update']);
|
||||
});
|
||||
});
|
||||
|
15
yarn.lock
15
yarn.lock
@ -9195,13 +9195,6 @@ rimraf@~2.4.0:
|
||||
dependencies:
|
||||
glob "^6.0.1"
|
||||
|
||||
rimraf@~2.6.2:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
||||
integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
rollup-plugin-sourcemaps@^0.6.3:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.6.3.tgz#bf93913ffe056e414419607f1d02780d7ece84ed"
|
||||
@ -10108,14 +10101,6 @@ tar@^6.0.2, tar@^6.1.11, tar@^6.1.2, tar@^6.1.6:
|
||||
mkdirp "^1.0.3"
|
||||
yallist "^4.0.0"
|
||||
|
||||
temp@^0.9.0:
|
||||
version "0.9.4"
|
||||
resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.4.tgz#cd20a8580cb63635d0e4e9d4bd989d44286e7620"
|
||||
integrity sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==
|
||||
dependencies:
|
||||
mkdirp "^0.5.1"
|
||||
rimraf "~2.6.2"
|
||||
|
||||
terser-webpack-plugin@^5.1.3:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz#0320dcc270ad5372c1e8993fabbd927929773e54"
|
||||
|
Loading…
x
Reference in New Issue
Block a user