diff --git a/package-lock.json b/package-lock.json index 7074cfc6..5108090c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -886,9 +886,8 @@ } }, "@dojo/webpack-contrib": { - "version": "8.0.0-alpha.1", - "resolved": "https://registry.npmjs.org/@dojo/webpack-contrib/-/webpack-contrib-8.0.0-alpha.1.tgz", - "integrity": "sha512-7pjbALd//LmpBCdIgaEQ/0rBJlIZqFuI0aU++QaG9HSKG8f2GoOqofN5LTIxhDeYH2y79xIDnHRPmDz9mAr0UQ==", + "version": "file:../webpack-contrib/dist/release/dojo-webpack-contrib-8.0.0-pre.tgz", + "integrity": "sha512-pFFXiUIx6g+diaNaLvohMrUSQIVS4H06q+rPN8IO0NLHsLAwYRwQI4F+eXuUKcWq/PwPSeJNoLl9DtqI+7gP3g==", "requires": { "@dojo/framework": "~7.0.2", "acorn": "6.1.1", @@ -921,6 +920,7 @@ "mkdirp": "0.5.1", "node-html-parser": "1.2.20", "opener": "1.4.3", + "ora": "5.0.0", "postcss": "7.0.7", "puppeteer": "1.11.0", "recast": "0.12.7", @@ -934,9 +934,14 @@ }, "dependencies": { "@types/node": { - "version": "12.12.56", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.56.tgz", - "integrity": "sha512-8OdIupOIZtmObR13fvGyTvpcuzKmMugkATeVcfNwCjGtHxhjEKmOvLqXwR8U9VOtNnZ4EXaSfNiLVsPinaCXkQ==" + "version": "12.12.58", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.58.tgz", + "integrity": "sha512-Be46CNIHWAagEfINOjmriSxuv7IVcqbGe+sDSg2SYCEz/0CRBy7LRASGfRbD8KZkqoePU73Wsx3UvOSFcq/9hA==" + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "camelcase": { "version": "4.1.0", @@ -953,6 +958,32 @@ "supports-color": "^4.0.0" } }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.4.0.tgz", + "integrity": "sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA==" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "connect-history-api-fallback": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", @@ -973,11 +1004,130 @@ "extract-zip": "^1.0.3" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "requires": { + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "ora": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.0.0.tgz", + "integrity": "sha512-s26qdWqke2kjN/wC4dy+IQPBIMWBJlSU/0JZhk30ZDBLelW25rv66yutUWARMigpGPzcXHb+Nac5pNhN/WsARw==", + "requires": { + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.4.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, "ts-loader": { "version": "5.4.5", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz", @@ -1618,15 +1768,6 @@ "integrity": "sha512-Cq4pUCsBL6H7X0HFAOap75lmQqcnSmUDSP0R03lz9UsxRvBu5QsnKLLgIoitlFBX+j6LmciWYQAbOSmGMi7vwA==", "dev": true }, - "@types/ora": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/ora/-/ora-1.3.1.tgz", - "integrity": "sha512-K9nqHo2rzMfM1KJW5F8uGYx1dmWzF2bJyn1sQ5v+NXQO14p/+8FWQk3//sbBYlmftf83pV9HGIG9X2GtknIrGg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", @@ -2044,9 +2185,9 @@ } }, "abab": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", - "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" }, "accepts": { "version": "1.3.7", @@ -3954,11 +4095,6 @@ "restore-cursor": "^2.0.0" } }, - "cli-spinners": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", - "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==" - }, "cli-truncate": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", @@ -4003,6 +4139,11 @@ "wrap-ansi": "^2.0.0" } }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + }, "clone-regexp": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.1.tgz", @@ -5866,6 +6007,14 @@ "strip-bom": "^2.0.0" } }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "requires": { + "clone": "^1.0.2" + } + }, "defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", @@ -10397,6 +10546,11 @@ "is-path-inside": "^1.0.0" } }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" + }, "is-jpg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-2.0.0.tgz", @@ -13153,49 +13307,6 @@ "logalot": "^2.0.0" } }, - "ora": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-1.3.0.tgz", - "integrity": "sha1-gAeN0rkqk0r2ajrXKluRBpTt5Ro=", - "requires": { - "chalk": "^1.1.1", - "cli-cursor": "^2.1.0", - "cli-spinners": "^1.0.0", - "log-symbols": "^1.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "requires": { - "chalk": "^1.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - } - } - }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", @@ -19338,6 +19449,14 @@ "chokidar": "^2.1.8" } }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "requires": { + "defaults": "^1.0.3" + } + }, "web-animations-js": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/web-animations-js/-/web-animations-js-2.3.1.tgz", diff --git a/package.json b/package.json index 8cd00bc2..b19bb0b2 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,6 @@ "@types/minimatch": "3.0.3", "@types/mockery": "1.4.29", "@types/node": "~9.6.5", - "@types/ora": "1.3.1", "@types/rimraf": "2.0.2", "@types/sinon": "~4.3.3", "@types/strip-ansi": "3.0.0", @@ -105,7 +104,7 @@ "tslint": "5.18.0" }, "dependencies": { - "@dojo/webpack-contrib": "8.0.0-alpha.1", + "@dojo/webpack-contrib": "file:~/Projects/opensource/webpack-contrib/dist/release/dojo-webpack-contrib-8.0.0-pre.tgz", "@typescript-eslint/eslint-plugin": "2.34.0", "@typescript-eslint/parser": "2.34.0", "caniuse-lite": "1.0.30000973", @@ -144,7 +143,7 @@ "mini-css-extract-plugin": "0.4.2", "minimatch": "3.0.4", "optimize-css-assets-webpack-plugin": "5.0.1", - "ora": "1.3.0", + "ora": "4.0.4", "pkg-dir": "2.0.0", "postcss-import": "12.0.0", "postcss-loader": "3.0.0", diff --git a/src/dist.config.ts b/src/dist.config.ts index 2d428463..30f3b0fb 100644 --- a/src/dist.config.ts +++ b/src/dist.config.ts @@ -18,6 +18,7 @@ import baseConfigFactory, { packageName, libraryName } from './base.config'; +import { LiveLogger } from '@dojo/webpack-contrib/logger/logger'; import { WebAppManifest } from './interfaces'; const CompressionPlugin = require('compression-webpack-plugin'); @@ -31,7 +32,7 @@ Copyright [JS Foundation](https://js.foundation/) & contributors All rights reserved `; -function webpackConfig(args: any): webpack.Configuration { +function webpackConfig(args: any, logger: LiveLogger): webpack.Configuration { const basePath = process.cwd(); const base = args.target === 'electron' ? './' : args.base || '/'; const config = baseConfigFactory(args); @@ -153,7 +154,8 @@ function webpackConfig(args: any): webpack.Configuration { basePath, baseUrl: base, scope: libraryName, - onDemand: Boolean(args.serve && args.watch) + onDemand: Boolean(args.serve && args.watch), + logger: logger('BTR') }) ); } diff --git a/src/ejected.config.ts b/src/ejected.config.ts index 2541641e..c2c4e127 100644 --- a/src/ejected.config.ts +++ b/src/ejected.config.ts @@ -1,4 +1,5 @@ import * as webpack from 'webpack'; +import createLiveLogger from '@dojo/webpack-contrib/logger/logger'; import devConfigFactory from './dev.config'; import distConfigFactory from './dist.config'; @@ -20,7 +21,7 @@ function webpackConfig(env: EnvOptions = {}): webpack.Configuration { } else if (mode === 'functional') { config = functionalConfigFactory(rc); } else { - config = distConfigFactory(rc); + config = distConfigFactory(rc, createLiveLogger('building')); } return config; } diff --git a/src/main.ts b/src/main.ts index ca3d961d..83400d3f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,6 @@ import { Command, EjectOutput, Helper, OptionsHelper } from '@dojo/cli/interfaces'; import * as express from 'express'; import * as logUpdate from 'log-update'; -import * as ora from 'ora'; import * as path from 'path'; import * as url from 'url'; import * as webpack from 'webpack'; @@ -12,6 +11,7 @@ import * as expressCompression from 'compression'; import * as proxy from 'http-proxy-middleware'; import * as history from 'connect-history-api-fallback'; import OnDemandBtr from '@dojo/webpack-contrib/build-time-render/BuildTimeRenderMiddleware'; +import createLiveLogger from '@dojo/webpack-contrib/logger/logger'; const pkgDir = require('pkg-dir'); const expressStaticGzip = require('express-static-gzip'); @@ -20,8 +20,8 @@ import unitConfigFactory from './unit.config'; import functionalConfigFactory from './functional.config'; import distConfigFactory from './dist.config'; import electronConfigFactory from './electron.config'; -import logger from './logger'; import { moveBuildOptions } from './util/eject'; +import logger from './logger'; import { readFileSync } from 'fs'; const packageJsonPath = path.join(process.cwd(), 'package.json'); @@ -50,13 +50,13 @@ interface MultiCompilerWithHooks extends webpack.MultiCompiler { function createWatchCompiler(configs: webpack.Configuration[]) { const compiler = webpack(configs) as MultiCompilerWithHooks; - const spinner = ora('building').start(); + const liveLogger = createLiveLogger('building').start(); compiler.hooks.invalid.tap('@dojo/cli-build-app', () => { logUpdate(''); - spinner.start(); + liveLogger.start(); }); compiler.hooks.done.tap('@dojo/cli-build-app', () => { - spinner.stop(); + liveLogger.stop(); }); return compiler; } @@ -84,10 +84,10 @@ function serveStatic( function build(configs: webpack.Configuration[], args: any) { const compiler = webpack(configs); - const spinner = ora('building').start(); + const liveLogger = createLiveLogger('building').start(); return new Promise((resolve, reject) => { compiler.run((err, stats) => { - spinner.stop(); + liveLogger.stop(); if (err) { reject(err); } @@ -376,6 +376,7 @@ const command: Command = { args.base = `${args.base}/`; } + const baseLogger = createLiveLogger('building'); if (args.mode === 'dev') { configs.push(devConfigFactory(args)); } else if (args.mode === 'unit' || args.mode === 'test') { @@ -383,7 +384,7 @@ const command: Command = { } else if (args.mode === 'functional') { configs.push(functionalConfigFactory(args)); } else { - configs.push(distConfigFactory(args)); + configs.push(distConfigFactory(args, baseLogger)); } if (args.target === 'electron') { diff --git a/tests/unit/main.ts b/tests/unit/main.ts index c9ced38e..0a8507c8 100644 --- a/tests/unit/main.ts +++ b/tests/unit/main.ts @@ -228,8 +228,8 @@ describe('command', () => { it('shows a building spinner on start', () => { const main = mockModule.getModuleUnderTest().default; return main.run(getMockHelper(), {}).then(() => { - assert.isTrue(mockModule.getMock('ora').ctor.calledWith('building')); - assert.isTrue(mockSpinner.start.called); + assert.isTrue(mockModule.getMock('ora').ctor.called); + assert.isTrue(mockSpinner.start.calledWith('building')); assert.isTrue(mockSpinner.stop.called); }); }); @@ -273,8 +273,8 @@ describe('command', () => { ); setTimeout( dfd.callback(() => { - assert.isTrue(mockModule.getMock('ora').ctor.calledWith('building')); - assert.isTrue(mockSpinner.start.called); + assert.isTrue(mockModule.getMock('ora').ctor.called); + assert.isTrue(mockSpinner.start.calledWith('building')); assert.isTrue(mockSpinner.stop.called); }), 1000