From 0eb7a930ffcd4fc77b5b6c75e490299f92ca8a8e Mon Sep 17 00:00:00 2001 From: Brandon Smith Date: Sun, 10 Dec 2017 22:06:08 -0500 Subject: [PATCH] Add AppVeyor CI & fix tests on Windows (#183) * Enable AppVeyor windows builds * Fix css, glob, javascript, watcher, html and hmr tests on windows --- appveyor.yml | 24 ++++++++++++++++++++++++ src/assets/GlobAsset.js | 11 +++++++++-- test/css.js | 8 ++++++-- test/hmr.js | 12 ++++++------ test/html.js | 8 ++++++-- test/javascript.js | 15 +++++++++------ test/utils.js | 21 +++++++++++++++++++-- test/watcher.js | 11 ++++------- 8 files changed, 83 insertions(+), 27 deletions(-) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000000..32194b0b517 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,24 @@ +# Test against the latest version of this Node.js version +environment: + nodejs_version: "8" + +# Install scripts. (runs after repo cloning) +install: + # Get the latest stable version of Node.js or io.js + - ps: Install-Product node $env:nodejs_version + # install modules + - yarn install + +# Post-install test scripts. +test_script: + # Output useful info for debugging. + - node --version + - yarn --version + # run tests + - yarn test + +cache: + - "%LOCALAPPDATA%\\Yarn" + +# Don't actually build. +build: off diff --git a/src/assets/GlobAsset.js b/src/assets/GlobAsset.js index a3ece17f97b..445a19fcba6 100644 --- a/src/assets/GlobAsset.js +++ b/src/assets/GlobAsset.js @@ -12,8 +12,15 @@ class GlobAsset extends Asset { } async load() { - let files = await globPromise(this.name, {strict: true, nodir: true}); - let re = micromatch.makeRe(this.name, {capture: true}); + let regularExpressionSafeName = this.name; + if (process.platform === 'win32') + regularExpressionSafeName = regularExpressionSafeName.replace(/\\/g, '/'); + + let files = glob.sync(regularExpressionSafeName, { + strict: true, + nodir: true + }); + let re = micromatch.makeRe(regularExpressionSafeName, {capture: true}); let matches = {}; for (let file of files) { diff --git a/test/css.js b/test/css.js index 1af4bfac0b9..7cf37149c96 100644 --- a/test/css.js +++ b/test/css.js @@ -137,10 +137,14 @@ describe('css', function() { let output = run(b); assert.equal(typeof output, 'function'); - assert.equal(output(), '_index_1ezyc_1'); + + let value = output(); + assert(/_index_[0-9a-z]+_1/.test(value)); + + let cssClass = value.match(/(_index_[0-9a-z]+_1)/)[1]; let css = fs.readFileSync(__dirname + '/dist/index.css', 'utf8'); - assert(css.includes('._index_1ezyc_1')); + assert(css.includes(`.${cssClass}`)); }); it('should minify CSS in production mode', async function() { diff --git a/test/hmr.js b/test/hmr.js index fdaf3baba5f..251f9cb344c 100644 --- a/test/hmr.js +++ b/test/hmr.js @@ -1,6 +1,7 @@ const assert = require('assert'); const fs = require('fs'); -const {bundler, run, assertBundleTree} = require('./utils'); +const path = require('path'); +const {bundler, run, assertBundleTree, sleep} = require('./utils'); const rimraf = require('rimraf'); const promisify = require('../src/utils/promisify'); const ncp = promisify(require('ncp')); @@ -31,10 +32,6 @@ describe('hmr', function() { }); } - function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); - } - it('should emit an HMR update for the file that changed', async function() { await ncp(__dirname + '/integration/commonjs', __dirname + '/input'); @@ -90,7 +87,10 @@ describe('hmr', function() { assert.equal(msg.type, 'error'); assert.equal( msg.error.message, - __dirname + '/input/local.js:1:12: Unexpected token, expected , (1:12)' + `${path.join( + __dirname, + '/input/local.js' + )}:1:12: Unexpected token, expected , (1:12)` ); assert.equal( msg.error.stack, diff --git a/test/html.js b/test/html.js index c82fb842994..e7e7430000a 100644 --- a/test/html.js +++ b/test/html.js @@ -73,7 +73,11 @@ describe('html', function() { }); let html = fs.readFileSync(__dirname + '/dist/index.html'); - assert(//.test(html)); + assert( + //.test( + html + ) + ); }); it('should insert a HEAD element if needed when adding CSS bundles', async function() { @@ -99,7 +103,7 @@ describe('html', function() { let html = fs.readFileSync(__dirname + '/dist/index.html'); assert( - /<\/head>/.test( + /<\/head>/.test( html ) ); diff --git a/test/javascript.js b/test/javascript.js index c17f3962dd5..ac5bc86b5ed 100644 --- a/test/javascript.js +++ b/test/javascript.js @@ -1,5 +1,6 @@ const assert = require('assert'); const fs = require('fs'); +const path = require('path'); const {bundle, run, assertBundleTree} = require('./utils'); describe('javascript', function() { @@ -63,10 +64,12 @@ describe('javascript', function() { assertBundleTree(b, { name: 'index.js', assets: ['index.js', 'bundle-loader.js', 'bundle-url.js'], - childBundles: [{ - assets: ['local.js'], - childBundles: [] - }] + childBundles: [ + { + assets: ['local.js'], + childBundles: [] + } + ] }); let output = run(b).default; @@ -156,8 +159,8 @@ describe('javascript', function() { let output = run(b); assert.deepEqual(output(), { - dir: __dirname + '/integration/globals', - file: __dirname + '/integration/globals/index.js', + dir: path.join(__dirname, '/integration/globals'), + file: path.join(__dirname, '/integration/globals/index.js'), buf: new Buffer('browser').toString('base64'), global: true }); diff --git a/test/utils.js b/test/utils.js index 87bab9b7779..de6212580af 100644 --- a/test/utils.js +++ b/test/utils.js @@ -6,10 +6,26 @@ const fs = require('fs'); const path = require('path'); const WebSocket = require('ws'); -beforeEach(function() { - rimraf.sync(path.join(__dirname, 'dist')); +beforeEach(function(done) { + const finalize = () => { + rimraf.sync(path.join(__dirname, 'dist')); + done(); + }; + + // Test run in a single process, creating and deleting the same file(s) + // Windows needs a delay for the file handles to be released before deleting + // is possible. Without a delay, rimraf fails on `beforeEach` for `/dist` + if (process.platform === 'win32') { + sleep(50).then(finalize); + } else { + finalize(); + } }); +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + function bundler(file, opts) { return new Bundler( file, @@ -107,6 +123,7 @@ function assertBundleTree(bundle, tree) { } } +exports.sleep = sleep; exports.bundler = bundler; exports.bundle = bundle; exports.run = run; diff --git a/test/watcher.js b/test/watcher.js index 944feac8627..1ea0c5272ff 100644 --- a/test/watcher.js +++ b/test/watcher.js @@ -1,6 +1,7 @@ const assert = require('assert'); const fs = require('fs'); -const {bundler, run, assertBundleTree} = require('./utils'); +const path = require('path'); +const {bundler, run, assertBundleTree, sleep} = require('./utils'); const rimraf = require('rimraf'); const promisify = require('../src/utils/promisify'); const ncp = promisify(require('ncp')); @@ -23,10 +24,6 @@ describe('watcher', function() { }); } - function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); - } - it('should rebuild on file change', async function() { await ncp(__dirname + '/integration/commonjs', __dirname + '/input'); @@ -155,7 +152,7 @@ describe('watcher', function() { let output = run(bundle); assert.equal(await output(), 7); - assert(b.loadedAssets.has(__dirname + '/input/common-dep.js')); + assert(b.loadedAssets.has(path.join(__dirname, '/input/common-dep.js'))); // Get rid of common-dep.js fs.writeFileSync(__dirname + '/input/common.js', 'module.exports = 5;'); @@ -179,6 +176,6 @@ describe('watcher', function() { output = run(bundle); assert.equal(await output(), 13); - assert(!b.loadedAssets.has(__dirname + '/input/common-dep.js')); + assert(!b.loadedAssets.has(path.join(__dirname, '/input/common-dep.js'))); }); });