diff --git a/ts/addon.ts b/ts/addon.ts index de2f645a7..291268538 100644 --- a/ts/addon.ts +++ b/ts/addon.ts @@ -46,12 +46,16 @@ export default addon({ return `${__dirname}/blueprints`; }, - serverMiddleware({ app }) { - this._addTypecheckMiddleware(app); + serverMiddleware({ app, options }) { + if (!options || !options.path) { + this._addTypecheckMiddleware(app); + } }, - testemMiddleware(app) { - this._addTypecheckMiddleware(app); + testemMiddleware(app, options) { + if (!options || !options.path) { + this._addTypecheckMiddleware(app); + } }, async postBuild() { diff --git a/ts/tests/acceptance/build-test.ts b/ts/tests/acceptance/build-test.ts index 10ff9a233..8f0822b2d 100644 --- a/ts/tests/acceptance/build-test.ts +++ b/ts/tests/acceptance/build-test.ts @@ -69,6 +69,52 @@ describe('Acceptance: build', function() { ); }); + it("doesn't launch type checking when --path used", async () => { + await app.build(); + let server = app.serve({ + args: ['--path', 'dist'], + env: { DEBUG: 'ember-cli-typescript|express:*' }, + }); + let result = await server.raceForOutputs([ + 'ember-cli-typescript:typecheck-worker', + 'Serving on', + ]); + expect(result).to.include('Serving on'); + }); + + it('does launch type checking when --path not used', async () => { + await app.build(); + let server = app.serve({ env: { DEBUG: 'ember-cli-typescript|express:*' } }); + let result = await server.raceForOutputs([ + 'ember-cli-typescript:typecheck-worker', + 'Serving on', + ]); + expect(result).to.include('ember-cli-typescript:typecheck-worker'); + }); + + it("doesn't launch type checking when --path used for tests", async () => { + await app.build(); + let test = app.test({ + args: ['--path', 'dist'], + env: { DEBUG: 'ember-cli-typescript|express:*' }, + }); + let result = await test.raceForOutputs([ + 'ember-cli-typescript:typecheck-worker', + 'express:application', + ]); + expect(result).to.include('express:application'); + }); + + it('does launch type checking when --path not used for tests', async () => { + await app.build(); + let test = app.test({ env: { DEBUG: 'ember-cli-typescript|express:*' } }); + let result = await test.raceForOutputs([ + 'ember-cli-typescript:typecheck-worker', + 'express:application', + ]); + expect(result).to.include('ember-cli-typescript:typecheck-worker'); + }); + it('fails the build when noEmitOnError is set and an error is emitted', async () => { app.writeFile('app/app.ts', `import { foo } from 'nonexistent';`); diff --git a/ts/tests/helpers/skeleton-app.ts b/ts/tests/helpers/skeleton-app.ts index e5435c549..9e7ab5662 100644 --- a/ts/tests/helpers/skeleton-app.ts +++ b/ts/tests/helpers/skeleton-app.ts @@ -15,9 +15,15 @@ const getEmberPort = (() => { return () => lastPort++; })(); +interface EmberCliOptions { + args?: string[]; + env?: any; +} + export default class SkeletonApp { port = getEmberPort(); - watched: WatchedBuild | null = null; + watched: WatchedEmberProcess | null = null; + watchedTest: WatchedEmberProcess | null = null; tmpDir = tmp.dirSync({ tries: 10, unsafeCleanup: true, @@ -31,17 +37,25 @@ export default class SkeletonApp { } build() { - return this._ember(['build']); + return this._ember({ args: ['build'] }); } - serve() { + serve(options: EmberCliOptions = { args: [], env: {} }) { if (this.watched) { throw new Error('Already serving'); } - return (this.watched = new WatchedBuild( - this._ember(['serve', '--port', `${this.port}`]), - this.port - )); + options.args = options.args || []; + options.args = ['serve', '--port', `${this.port}`, ...options.args]; + return (this.watched = new WatchedEmberProcess(this._ember(options), this.port)); + } + + test(options: EmberCliOptions = { args: [], env: {} }) { + if (this.watchedTest) { + throw new Error('Already testing'); + } + options.args = options.args || []; + options.args = ['test', ...options.args]; + return (this.watchedTest = new WatchedEmberProcess(this._ember(options))); } updatePackageJSON(callback: (arg: any) => any) { @@ -68,17 +82,20 @@ export default class SkeletonApp { if (this.watched) { this.watched.kill(); } + if (this.watchedTest) { + this.watchedTest.kill(); + } this.tmpDir.removeCallback(); } - _ember(args: string[]) { + _ember(options: EmberCliOptions) { let ember = require.resolve('ember-cli/bin/ember'); - return execa.node(ember, args, { cwd: this.root, all: true }); + return execa.node(ember, options.args, { cwd: this.root, all: true, env: options.env }); } } -class WatchedBuild extends EventEmitter { - constructor(protected ember: execa.ExecaChildProcess, protected port: number) { +class WatchedEmberProcess extends EventEmitter { + constructor(protected ember: execa.ExecaChildProcess, protected port?: number) { super(); this.ember.stdout.on('data', data => { let output = data.toString(); @@ -102,6 +119,10 @@ class WatchedBuild extends EventEmitter { return got(`http://localhost:${this.port}${path}`); } + raceForOutputs(targets: string[]) { + return Promise.race(targets.map(target => this.waitForOutput(target))); + } + waitForOutput(target: string) { return new Promise(resolve => { let output = ''; diff --git a/ts/types/ember-cli/index.d.ts b/ts/types/ember-cli/index.d.ts index 1c78069ef..bb75f7694 100644 --- a/ts/types/ember-cli/index.d.ts +++ b/ts/types/ember-cli/index.d.ts @@ -11,6 +11,7 @@ declare module 'ember-cli/lib/models/addon' { import UI from 'console-ui'; import { Application } from 'express'; import Project from 'ember-cli/lib/models/project'; + import { TaskOptions } from 'ember-cli/lib/models/task'; import Command from 'ember-cli/lib/models/command'; import EmberApp from 'ember-cli/lib/broccoli/ember-app'; import PreprocessRegistry from 'ember-cli-preprocess-registry'; @@ -36,8 +37,8 @@ declare module 'ember-cli/lib/models/addon' { includedCommands(): Record> | void; shouldIncludeChildAddon(addon: Addon): boolean; isDevelopingAddon(): boolean; - serverMiddleware(options: { app: Application }): void | Promise; - testemMiddleware(app: Application): void; + serverMiddleware(options: { app: Application; options?: TaskOptions }): void | Promise; + testemMiddleware(app: Application, options?: TaskOptions): void; setupPreprocessorRegistry(type: 'self' | 'parent', registry: PreprocessRegistry): void; } } @@ -49,6 +50,12 @@ declare module 'ember-cli/lib/models/blueprint' { export = Blueprint; } +declare module 'ember-cli/lib/models/task' { + export interface TaskOptions { + path?: string; + } +} + declare module 'ember-cli/lib/models/command' { import CoreObject from 'core-object'; import UI from 'console-ui';