diff --git a/config/environment.js b/config/environment.js index 012a412..826bb01 100644 --- a/config/environment.js +++ b/config/environment.js @@ -3,4 +3,4 @@ module.exports = function(/* environment, appConfig */) { return { }; -}; +} diff --git a/ember-cli-build.js b/ember-cli-build.js index 156e23f..1aed934 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -5,7 +5,10 @@ const EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); module.exports = function(defaults) { let app = new EmberAddon(defaults, { - // Add options here + 'ember-cli-babel': { + // Needed because ember-maybe-import-regenerator uses Promise + includePolyfill: (EmberAddon.env() === 'test'), + }, }); /* diff --git a/package.json b/package.json index 495e2f9..2e88d57 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "ember-disable-prototype-extensions": "^1.1.0", "ember-export-application-global": "^2.0.0", "ember-load-initializers": "^2.0.0", + "ember-maybe-import-regenerator": "^0.1.6", "ember-resolver": "^5.1.3", "ember-source": "~2.14.1", "loader.js": "^4.7.0", diff --git a/tests/acceptance/asset-load-test.js b/tests/acceptance/asset-load-test.js index 1f6322f..af18c8a 100644 --- a/tests/acceptance/asset-load-test.js +++ b/tests/acceptance/asset-load-test.js @@ -1,9 +1,8 @@ -import Ember from 'ember'; -import { test } from 'qunit'; -import moduleForAcceptance from '../../tests/helpers/module-for-acceptance'; - -const { run } = Ember; -const { Promise } = Ember.RSVP; +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import { visit, currentRouteName } from '@ember/test-helpers'; +import { run } from '@ember/runloop'; +import { Promise } from 'rsvp'; function waitFor(checkerFn, timeout = 1000) { let start = Date.now(); @@ -25,22 +24,22 @@ function waitFor(checkerFn, timeout = 1000) { }); } -moduleForAcceptance('Acceptance | asset-load'); +module('Acceptance | asset-load', function(hooks) { + setupApplicationTest(hooks); -test('visiting a route which loads a bundle', function(assert) { - assert.expect(7); + test('visiting a route which loads a bundle', async function(assert) { + assert.expect(7); - const container = document.getElementById('ember-testing'); - const originalContainerStyle = window.getComputedStyle(container); - const originalBackgroundColor = originalContainerStyle.backgroundColor; - const originalColor = originalContainerStyle.color; + const container = document.getElementById('ember-testing'); + const originalContainerStyle = window.getComputedStyle(container); + const originalBackgroundColor = originalContainerStyle.backgroundColor; + const originalColor = originalContainerStyle.color; - const containerText = container.innerText; - assert.equal(containerText, '', 'test container is empty before load'); + let containerText = container.innerText; + assert.equal(containerText, '', 'test container is empty before load'); - visit('/'); + await visit('/'); - andThen(function() { assert.equal(currentRouteName(), 'index', 'transitioned '); const testScriptText = container.querySelector('h2').innerText; @@ -49,7 +48,7 @@ test('visiting a route which loads a bundle', function(assert) { const routeText = container.querySelector('h1').innerText; assert.equal(routeText, 'Welcome!', 'route was loaded correctly'); - const containerText = container.innerText; + containerText = container.innerText; assert.ok(containerText.indexOf(testScriptText) < containerText.indexOf(routeText), 'test script was executed before route load'); return waitFor(() => { @@ -66,16 +65,14 @@ test('visiting a route which loads a bundle', function(assert) { assert.notEqual(containerStyle.color, originalColor, 'color is different after css load'); }); }); -}); -test('visiting a route which fails to load a script removes the node from DOM', function(assert) { - assert.expect(2); + test('visiting a route which fails to load a script removes the node from DOM', async function(assert) { + assert.expect(2); - const getScript = () => document.querySelector('script[src="foo.js"]'); + const getScript = () => document.querySelector('script[src="foo.js"]'); - visit('asset-error'); + await visit('asset-error'); - andThen(function() { assert.equal(currentRouteName(), 'asset-error', 'transitioned '); return waitFor(() => !getScript()) diff --git a/tests/dummy/config/environment.js b/tests/dummy/config/environment.js index 251bdcb..fc456bb 100644 --- a/tests/dummy/config/environment.js +++ b/tests/dummy/config/environment.js @@ -41,6 +41,7 @@ module.exports = function(environment) { ENV.APP.LOG_VIEW_LOOKUPS = false; ENV.APP.rootElement = '#ember-testing'; + ENV.APP.autoboot = false; } if (environment === 'production') { diff --git a/tests/test-helper.js b/tests/test-helper.js index f219659..7827a6a 100644 --- a/tests/test-helper.js +++ b/tests/test-helper.js @@ -1,8 +1,7 @@ -import resolver from './helpers/resolver'; -import { - setResolver -} from 'ember-qunit'; -import { start } from 'ember-cli-qunit'; +import Application from '../app'; +import config from '../config/environment'; +import { setApplication } from '@ember/test-helpers'; +import { start } from 'ember-qunit'; -setResolver(resolver); +setApplication(Application.create(config.APP)); start(); diff --git a/tests/unit/asset-manifest-test.js b/tests/unit/asset-manifest-test.js index 4776aaf..c974714 100644 --- a/tests/unit/asset-manifest-test.js +++ b/tests/unit/asset-manifest-test.js @@ -3,56 +3,56 @@ import { module, test } from 'qunit'; import require from 'require'; -module('Unit | asset-manifest', { - beforeEach() { +module('Unit | asset-manifest', function(hooks) { + hooks.beforeEach(function() { resetModules(); this.originalNodeModule = requirejs.entries['dummy/config/node-asset-manifest']; - }, + }); - afterEach() { + hooks.afterEach(function() { requirejs.entries['dummy/config/node-asset-manifest'] = this.originalNodeModule; resetModules(); - } -}); + }); -function resetModules() { - requirejs.unsee('dummy/config/node-asset-manifest'); - requirejs.unsee('dummy/config/asset-manifest'); -} + function resetModules() { + requirejs.unsee('dummy/config/node-asset-manifest'); + requirejs.unsee('dummy/config/asset-manifest'); + } -test('node-asset-manifest is generated properly', function(assert) { - const nodeManifest = require('dummy/config/node-asset-manifest').default; - delete requirejs.entries['dummy/config/node-asset-manifest']; + test('node-asset-manifest is generated properly', function(assert) { + const nodeManifest = require('dummy/config/node-asset-manifest').default; + delete requirejs.entries['dummy/config/node-asset-manifest']; - const manifest = require('dummy/config/asset-manifest').default; + const manifest = require('dummy/config/asset-manifest').default; - assert.notStrictEqual(nodeManifest, manifest); - assert.deepEqual(nodeManifest, manifest); -}); + assert.notStrictEqual(nodeManifest, manifest); + assert.deepEqual(nodeManifest, manifest); + }); -test('loads the node-asset-manifest if present', function(assert) { - const replacementModule = {}; - define('dummy/config/node-asset-manifest', () => ({ default: replacementModule})); + test('loads the node-asset-manifest if present', function(assert) { + const replacementModule = {}; + define('dummy/config/node-asset-manifest', () => ({ default: replacementModule})); - assert.strictEqual(require('dummy/config/asset-manifest').default, replacementModule); -}); + assert.strictEqual(require('dummy/config/asset-manifest').default, replacementModule); + }); -test('loads the manifest from the meta tag if available', function(assert) { - delete requirejs.entries['dummy/config/node-asset-manifest']; + test('loads the manifest from the meta tag if available', function(assert) { + delete requirejs.entries['dummy/config/node-asset-manifest']; - const meta = document.querySelector('meta[name="dummy/config/asset-manifest"]'); - const metaContent = meta.getAttribute('content'); - meta.setAttribute('content', '{"derp":"herp"}'); - assert.deepEqual(require('dummy/config/asset-manifest').default, { derp: 'herp' }); - meta.setAttribute('content', metaContent); -}); + const meta = document.querySelector('meta[name="dummy/config/asset-manifest"]'); + const metaContent = meta.getAttribute('content'); + meta.setAttribute('content', '{"derp":"herp"}'); + assert.deepEqual(require('dummy/config/asset-manifest').default, { derp: 'herp' }); + meta.setAttribute('content', metaContent); + }); -test('throws an error if unable to load the manifest', function(assert) { - delete requirejs.entries['dummy/config/node-asset-manifest']; + test('throws an error if unable to load the manifest', function(assert) { + delete requirejs.entries['dummy/config/node-asset-manifest']; - const meta = document.querySelector('meta[name="dummy/config/asset-manifest"]'); - const metaContent = meta.getAttribute('content'); - meta.setAttribute('content', 'herp'); - assert.throws(() => assert.deepEqual(require('dummy/config/asset-manifest').default, {})); - meta.setAttribute('content', metaContent); + const meta = document.querySelector('meta[name="dummy/config/asset-manifest"]'); + const metaContent = meta.getAttribute('content'); + meta.setAttribute('content', 'herp'); + assert.throws(() => assert.deepEqual(require('dummy/config/asset-manifest').default, {})); + meta.setAttribute('content', metaContent); + }); }); diff --git a/tests/unit/errors/asset-load-test.js b/tests/unit/errors/asset-load-test.js index 41aeb67..39e4c57 100644 --- a/tests/unit/errors/asset-load-test.js +++ b/tests/unit/errors/asset-load-test.js @@ -1,32 +1,36 @@ import AssetLoadError from 'ember-asset-loader/errors/asset-load'; import { module, test } from 'qunit'; -module('Unit | Error | asset-load', { - asset: { - type: 'js', - uri: 'some-js-file.js' - }, - loader: { - loadAsset(asset) { - return `Loaded ${asset.type} asset with uri "${asset.uri}".`; - } - }, - originalError: new Error('some error') -}); +module('Unit | Error | asset-load', function(hooks) { + hooks.beforeEach(function() { + this.asset = { + type: 'js', + uri: 'some-js-file.js' + }; -test('constructor() - accepts an asset and the original error', function(assert) { - const error = new AssetLoadError(this.loader, this.asset, this.originalError); - assert.ok(error instanceof Error, 'AssetLoadError inherits Error'); - assert.ok(error.stack, 'stack is preserved'); - assert.strictEqual(error.asset, this.asset, 'asset is set'); -}); + this.loader = { + loadAsset(asset) { + return `Loaded ${asset.type} asset with uri "${asset.uri}".`; + } + }; -test('toString() - has correct name and message', function(assert) { - const error = new AssetLoadError(this.loader, this.asset, this.originalError); - assert.equal(error.toString(), 'AssetLoadError: The js asset with uri "some-js-file.js" failed to load with the error: Error: some error.'); -}); + this.originalError = new Error('some error'); + }); + + test('constructor() - accepts an asset and the original error', function(assert) { + const error = new AssetLoadError(this.loader, this.asset, this.originalError); + assert.ok(error instanceof Error, 'AssetLoadError inherits Error'); + assert.ok(error.stack, 'stack is preserved'); + assert.strictEqual(error.asset, this.asset, 'asset is set'); + }); + + test('toString() - has correct name and message', function(assert) { + const error = new AssetLoadError(this.loader, this.asset, this.originalError); + assert.equal(error.toString(), 'AssetLoadError: The js asset with uri "some-js-file.js" failed to load with the error: Error: some error.'); + }); -test('retryLoad() - calls loadAsset on the loader', function(assert) { - const error = new AssetLoadError(this.loader, this.asset, this.originalError); - assert.equal(error.retryLoad(), 'Loaded js asset with uri "some-js-file.js".'); + test('retryLoad() - calls loadAsset on the loader', function(assert) { + const error = new AssetLoadError(this.loader, this.asset, this.originalError); + assert.equal(error.retryLoad(), 'Loaded js asset with uri "some-js-file.js".'); + }); }); diff --git a/tests/unit/errors/bundle-load-test.js b/tests/unit/errors/bundle-load-test.js index 4542c88..2a42b56 100644 --- a/tests/unit/errors/bundle-load-test.js +++ b/tests/unit/errors/bundle-load-test.js @@ -1,32 +1,36 @@ import BundleLoadError from 'ember-asset-loader/errors/bundle-load'; import { module, test } from 'qunit'; -module('Unit | Error | bundle-load', { - bundleName: 'herp-de-derp', - errors: [ - new Error('derp error') - ], - loader: { - loadBundle(bundleName) { - return `Loaded the bundle "${bundleName}".`; - } - } -}); +module('Unit | Error | bundle-load', function(hooks) { + hooks.beforeEach(function() { + this.bundleName = 'herp-de-derp'; -test('constructor() - accepts a bundleName and errors array', function(assert) { - const error = new BundleLoadError(this.loader, this.bundleName, this.errors); - assert.ok(error instanceof Error, 'BundleLoadError inherits Error'); - assert.ok(error.stack, 'stack is preserved'); - assert.equal(error.bundleName, this.bundleName, 'bundleName is set'); - assert.strictEqual(error.errors, this.errors, 'errors is set'); -}); + this.errors = [ + new Error('derp error') + ]; -test('toString() - has correct name and message', function(assert) { - const error = new BundleLoadError(this.loader, this.bundleName, this.errors); - assert.equal(error.toString(), 'BundleLoadError: The bundle "herp-de-derp" failed to load.'); -}); + this.loader = { + loadBundle(bundleName) { + return `Loaded the bundle "${bundleName}".`; + } + }; + }); + + test('constructor() - accepts a bundleName and errors array', function(assert) { + const error = new BundleLoadError(this.loader, this.bundleName, this.errors); + assert.ok(error instanceof Error, 'BundleLoadError inherits Error'); + assert.ok(error.stack, 'stack is preserved'); + assert.equal(error.bundleName, this.bundleName, 'bundleName is set'); + assert.strictEqual(error.errors, this.errors, 'errors is set'); + }); + + test('toString() - has correct name and message', function(assert) { + const error = new BundleLoadError(this.loader, this.bundleName, this.errors); + assert.equal(error.toString(), 'BundleLoadError: The bundle "herp-de-derp" failed to load.'); + }); -test('retryLoad() - calls loadBundle on the loader', function(assert) { - const error = new BundleLoadError(this.loader, this.bundleName, this.errors); - assert.equal(error.retryLoad(), 'Loaded the bundle "herp-de-derp".'); + test('retryLoad() - calls loadBundle on the loader', function(assert) { + const error = new BundleLoadError(this.loader, this.bundleName, this.errors); + assert.equal(error.retryLoad(), 'Loaded the bundle "herp-de-derp".'); + }); }); diff --git a/tests/unit/errors/load-test.js b/tests/unit/errors/load-test.js index 48b18f0..07bcc6b 100644 --- a/tests/unit/errors/load-test.js +++ b/tests/unit/errors/load-test.js @@ -1,25 +1,25 @@ import LoadError from 'ember-asset-loader/errors/load'; import { module, test } from 'qunit'; -module('Unit | Error | load'); +module('Unit | Error | load', function() { + test('constructor() - accepts a message and a loader', function(assert) { + const message = 'herp-de-derp'; + const loader = {}; + const error = new LoadError(message, loader); -test('constructor() - accepts a message and a loader', function(assert) { - const message = 'herp-de-derp'; - const loader = {}; - const error = new LoadError(message, loader); + assert.ok(error instanceof Error, 'LoadError inherits Error'); + assert.ok(error.stack, 'stack is preserved'); + assert.equal(error.message, message, 'message is set'); + assert.strictEqual(error.loader, loader, 'loader is set'); + }); - assert.ok(error instanceof Error, 'LoadError inherits Error'); - assert.ok(error.stack, 'stack is preserved'); - assert.equal(error.message, message, 'message is set'); - assert.strictEqual(error.loader, loader, 'loader is set'); -}); - -test('toString() - has correct name and message', function(assert) { - const error = new LoadError('herp-de-derp'); - assert.equal(error.toString(), 'LoadError: herp-de-derp'); -}); + test('toString() - has correct name and message', function(assert) { + const error = new LoadError('herp-de-derp'); + assert.equal(error.toString(), 'LoadError: herp-de-derp'); + }); -test('retryLoad() - throws an error', function(assert) { - const error = new LoadError(); - assert.throws(() => error.retryLoad(), /You must define a behavior for 'retryLoad' in a subclass./); + test('retryLoad() - throws an error', function(assert) { + const error = new LoadError(); + assert.throws(() => error.retryLoad(), /You must define a behavior for 'retryLoad' in a subclass./); + }); }); diff --git a/tests/unit/services/asset-loader-test.js b/tests/unit/services/asset-loader-test.js index 0ae711f..9b78ad4 100644 --- a/tests/unit/services/asset-loader-test.js +++ b/tests/unit/services/asset-loader-test.js @@ -1,5 +1,6 @@ import RSVP from 'rsvp'; -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; function noop() {} function shouldNotHappen(assert) { @@ -9,425 +10,427 @@ function shouldHappen(assert) { return () => assert.ok(true, 'callback should happen'); } -moduleFor('service:asset-loader', 'Unit | Service | asset-loader'); +module('Unit | Service | asset-loader', function(hooks) { + setupTest(hooks); -test('loadBundle() - throws an error if no asset manifest has been provided', function(assert) { - const service = this.subject(); + test('loadBundle() - throws an error if no asset manifest has been provided', function(assert) { + const service = this.owner.lookup('service:asset-loader'); - assert.throws(() => service.loadBundle('blog'), /No asset manifest found. Ensure you call pushManifest before attempting to use the AssetLoader./); -}); - -test('loadBundle() - throws an error if asset manifest does not list any bundles', function(assert) { - const service = this.subject(); - - service.pushManifest({}); + assert.throws(() => service.loadBundle('blog'), /No bundle with name "blog" exists./); + }); - assert.throws(() => service.loadBundle('blog'), /Asset manifest does not list any available bundles./); -}); + test('loadBundle() - throws an error if asset manifest does not list any bundles', function(assert) { + const service = this.owner.lookup('service:asset-loader'); -test('loadBundle() - throws an error if asset manifest does not contain the bundle', function(assert) { - const service = this.subject(); + service.pushManifest({}); - service.pushManifest({ - bundles: { - chat: {} - } + assert.throws(() => service.loadBundle('blog'), /No bundle with name "blog" exists./); }); - assert.throws(() => service.loadBundle('blog'), /No bundle with name "blog" exists in the asset manifest./); -}); - -test('loadBundle() - returns a promise that resolves with the name of the loaded bundle', function(assert) { - assert.expect(1); + test('loadBundle() - throws an error if asset manifest does not contain the bundle', function(assert) { + const service = this.owner.lookup('service:asset-loader'); - const service = this.subject(); + service.pushManifest({ + bundles: { + chat: {} + } + }); - service.pushManifest({ - bundles: { - blog: {} - } + assert.throws(() => service.loadBundle('blog'), /No bundle with name "blog" exists in the asset manifest./); }); - return service.loadBundle('blog').then((bundle) => { - assert.equal(bundle, 'blog'); - }); -}); + test('loadBundle() - returns a promise that resolves with the name of the loaded bundle', function(assert) { + assert.expect(1); -test('loadBundle() - subsequent calls return the same promise', function(assert) { - assert.expect(1); + const service = this.owner.lookup('service:asset-loader'); - const service = this.subject(); + service.pushManifest({ + bundles: { + blog: {} + } + }); - service.pushManifest({ - bundles: { - blog: {} - } + return service.loadBundle('blog').then((bundle) => { + assert.equal(bundle, 'blog'); + }); }); - const firstCall = service.loadBundle('blog'); - const secondCall = service.loadBundle('blog'); + test('loadBundle() - subsequent calls return the same promise', function(assert) { + assert.expect(1); - assert.strictEqual(firstCall, secondCall); -}); + const service = this.owner.lookup('service:asset-loader'); -test('loadBundle() - rejects with a BundleLoadError', function(assert) { - assert.expect(2); + service.pushManifest({ + bundles: { + blog: {} + } + }); - const service = this.subject(); + const firstCall = service.loadBundle('blog'); + const secondCall = service.loadBundle('blog'); - service.pushManifest({ - bundles: { - blog: { - assets: [ - { type: 'fail', uri: 'someuri' } - ] - } - } + assert.strictEqual(firstCall, secondCall); }); - service.defineLoader('fail', () => RSVP.reject('rejected')); + test('loadBundle() - rejects with a BundleLoadError', function(assert) { + assert.expect(2); - return service.loadBundle('blog').then( - shouldNotHappen(assert), - (error) => { - assert.equal(error.errors.length, 1, 'has an array of the errors causing the load to fail.'); - assert.equal(error.toString(), 'BundleLoadError: The bundle "blog" failed to load.', 'error message contains correct info.'); - } - ); -}); + const service = this.owner.lookup('service:asset-loader'); -test('loadBundle() - a rejection allows retrying the load', function(assert) { - assert.expect(2); + service.pushManifest({ + bundles: { + blog: { + assets: [ + { type: 'fail', uri: 'someuri' } + ] + } + } + }); - const service = this.subject(); + service.defineLoader('fail', () => RSVP.reject('rejected')); - service.pushManifest({ - bundles: { - blog: { - assets: [ - { type: 'fail', uri: 'someuri' } - ] + return service.loadBundle('blog').then( + shouldNotHappen(assert), + (error) => { + assert.equal(error.errors.length, 1, 'has an array of the errors causing the load to fail.'); + assert.equal(error.toString(), 'BundleLoadError: The bundle "blog" failed to load.', 'error message contains correct info.'); } - } + ); }); - service.defineLoader('fail', () => RSVP.reject('rejected')); + test('loadBundle() - a rejection allows retrying the load', function(assert) { + assert.expect(2); - return service.loadBundle('blog').then( - shouldNotHappen(assert), - (error) => { - assert.ok(true, 'first error occured'); - return error.retryLoad(); - } - ).then( - shouldNotHappen(assert), - () => { - assert.ok(true, 'retry error occured'); - } - ); -}); + const service = this.owner.lookup('service:asset-loader'); -test('loadBundle() - subsequent call after rejection returns a new promise', function(assert) { - assert.expect(2); + service.pushManifest({ + bundles: { + blog: { + assets: [ + { type: 'fail', uri: 'someuri' } + ] + } + } + }); - const service = this.subject(); - let firstRetry; + service.defineLoader('fail', () => RSVP.reject('rejected')); - service.pushManifest({ - bundles: { - blog: { - assets: [ - { type: 'fail', uri: 'someuri' } - ] + return service.loadBundle('blog').then( + shouldNotHappen(assert), + (error) => { + assert.ok(true, 'first error occured'); + return error.retryLoad(); } - } + ).then( + shouldNotHappen(assert), + () => { + assert.ok(true, 'retry error occured'); + } + ); }); - service.defineLoader('fail', () => RSVP.reject('rejected')); + test('loadBundle() - subsequent call after rejection returns a new promise', function(assert) { + assert.expect(2); - return service.loadBundle('blog').then( - shouldNotHappen(assert), - (error) => firstRetry = error.retryLoad() - ).then( - shouldNotHappen(assert), - () => { - service.defineLoader('fail', () => RSVP.resolve()); + const service = this.owner.lookup('service:asset-loader'); + let firstRetry; - const serviceRetry = service.loadBundle('blog'); + service.pushManifest({ + bundles: { + blog: { + assets: [ + { type: 'fail', uri: 'someuri' } + ] + } + } + }); - assert.notStrictEqual(firstRetry, serviceRetry, 'calling loadAsset again returns other result'); + service.defineLoader('fail', () => RSVP.reject('rejected')); - return serviceRetry; - } - ).then(shouldHappen(assert), shouldNotHappen(assert)); -}); + return service.loadBundle('blog').then( + shouldNotHappen(assert), + (error) => firstRetry = error.retryLoad() + ).then( + shouldNotHappen(assert), + () => { + service.defineLoader('fail', () => RSVP.resolve()); -test('loadBundle() - retrying a load twice returns the same promise', function(assert) { - assert.expect(2); + const serviceRetry = service.loadBundle('blog'); - const service = this.subject(); + assert.notStrictEqual(firstRetry, serviceRetry, 'calling loadAsset again returns other result'); - service.pushManifest({ - bundles: { - blog: { - assets: [ - { type: 'fail', uri: 'someuri' } - ] + return serviceRetry; } - } + ).then(shouldHappen(assert), shouldNotHappen(assert)); }); - service.defineLoader('fail', () => RSVP.reject('rejected')); + test('loadBundle() - retrying a load twice returns the same promise', function(assert) { + assert.expect(2); - return service.loadBundle('blog').then( - shouldNotHappen(assert), - (error) => { - const firstRetry = error.retryLoad(); - const secondRetry = error.retryLoad(); - const serviceRetry = service.loadBundle('blog'); + const service = this.owner.lookup('service:asset-loader'); - assert.strictEqual(firstRetry, secondRetry, 'multiple retries produce same results'); - assert.strictEqual(firstRetry, serviceRetry, 'calling loadBundle again returns the retry result'); + service.pushManifest({ + bundles: { + blog: { + assets: [ + { type: 'fail', uri: 'someuri' } + ] + } + } + }); - return firstRetry; - } - ).catch(noop); -}); + service.defineLoader('fail', () => RSVP.reject('rejected')); -test('loadAsset() - throws an error if there is no loader defined for the asset type', function(assert) { - const service = this.subject(); - const asset = { type: 'crazy-type', uri: 'someuri' }; + return service.loadBundle('blog').then( + shouldNotHappen(assert), + (error) => { + const firstRetry = error.retryLoad(); + const secondRetry = error.retryLoad(); + const serviceRetry = service.loadBundle('blog'); - assert.throws(() => service.loadAsset(asset), /No loader for assets of type "crazy-type" defined./); -}); + assert.strictEqual(firstRetry, secondRetry, 'multiple retries produce same results'); + assert.strictEqual(firstRetry, serviceRetry, 'calling loadBundle again returns the retry result'); -test('loadAsset() - returns a promise that resolves with the loaded asset information', function(assert) { - assert.expect(1); + return firstRetry; + } + ).catch(noop); + }); + + test('loadAsset() - throws an error if there is no loader defined for the asset type', function(assert) { + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'crazy-type', uri: 'someuri' }; + + assert.throws(() => service.loadAsset(asset), /No loader for assets of type "crazy-type" defined./); + }); - const service = this.subject(); - const asset = { type: 'test', uri: 'someuri' }; + test('loadAsset() - returns a promise that resolves with the loaded asset information', function(assert) { + assert.expect(1); - service.defineLoader('test', (uri) => RSVP.resolve(uri)); + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'test', uri: 'someuri' }; - return service.loadAsset(asset).then((result) => { - assert.deepEqual(result, asset); + service.defineLoader('test', (uri) => RSVP.resolve(uri)); + + return service.loadAsset(asset).then((result) => { + assert.deepEqual(result, asset); + }); }); -}); -test('loadAsset() - subsequent calls return the same promise', function(assert) { - assert.expect(1); + test('loadAsset() - subsequent calls return the same promise', function(assert) { + assert.expect(1); - const service = this.subject(); - const asset = { type: 'test', uri: 'someuri' }; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'test', uri: 'someuri' }; - service.defineLoader('test', (uri) => RSVP.resolve(uri)); + service.defineLoader('test', (uri) => RSVP.resolve(uri)); - const firstCall = service.loadAsset(asset); - const secondCall = service.loadAsset(asset); + const firstCall = service.loadAsset(asset); + const secondCall = service.loadAsset(asset); - assert.strictEqual(firstCall, secondCall); -}); + assert.strictEqual(firstCall, secondCall); + }); -test('loadAsset() - rejects with an AssetLoadPromise', function(assert) { - assert.expect(1); + test('loadAsset() - rejects with an AssetLoadPromise', function(assert) { + assert.expect(1); - const service = this.subject(); - const asset = { type: 'test', uri: 'someuri' }; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'test', uri: 'someuri' }; - service.defineLoader('test', () => RSVP.reject('some error')); + service.defineLoader('test', () => RSVP.reject('some error')); - return service.loadAsset(asset).then(shouldNotHappen(assert), (error) => { - assert.equal(error.toString(), 'AssetLoadError: The test asset with uri "someuri" failed to load with the error: some error.'); + return service.loadAsset(asset).then(shouldNotHappen(assert), (error) => { + assert.equal(error.toString(), 'AssetLoadError: The test asset with uri "someuri" failed to load with the error: some error.'); + }); }); -}); -test('loadAsset() - a rejection allows retrying the load', function(assert) { - assert.expect(2); + test('loadAsset() - a rejection allows retrying the load', function(assert) { + assert.expect(2); - const service = this.subject(); - const asset = { type: 'test', uri: 'someuri' }; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'test', uri: 'someuri' }; - service.defineLoader('test', () => RSVP.reject('some error')); + service.defineLoader('test', () => RSVP.reject('some error')); - return service.loadAsset(asset).then( - shouldNotHappen(assert), - (error) => { - assert.ok(true, 'first error occured'); - return error.retryLoad(); - } - ).then( - shouldNotHappen(assert), - () => { - assert.ok(true, 'retry error occured'); - } - ); -}); + return service.loadAsset(asset).then( + shouldNotHappen(assert), + (error) => { + assert.ok(true, 'first error occured'); + return error.retryLoad(); + } + ).then( + shouldNotHappen(assert), + () => { + assert.ok(true, 'retry error occured'); + } + ); + }); -test('loadAsset() - subsequent call after rejection returns a new promise', function(assert) { - assert.expect(2); + test('loadAsset() - subsequent call after rejection returns a new promise', function(assert) { + assert.expect(2); - const service = this.subject(); - const asset = { type: 'test', uri: 'someuri' }; - let firstRetry; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'test', uri: 'someuri' }; + let firstRetry; - service.defineLoader('test', () => RSVP.reject('some error')); + service.defineLoader('test', () => RSVP.reject('some error')); - return service.loadAsset(asset).then( - shouldNotHappen(assert), - (error) => firstRetry = error.retryLoad() - ).then( - shouldNotHappen(assert), - () => { - service.defineLoader('test', () => RSVP.resolve()); + return service.loadAsset(asset).then( + shouldNotHappen(assert), + (error) => firstRetry = error.retryLoad() + ).then( + shouldNotHappen(assert), + () => { + service.defineLoader('test', () => RSVP.resolve()); - const serviceRetry = service.loadAsset(asset); + const serviceRetry = service.loadAsset(asset); - assert.notStrictEqual(firstRetry, serviceRetry, 'calling loadAsset again returns other result'); + assert.notStrictEqual(firstRetry, serviceRetry, 'calling loadAsset again returns other result'); - return serviceRetry; - } - ).then(shouldHappen(assert), shouldNotHappen(assert)); -}); + return serviceRetry; + } + ).then(shouldHappen(assert), shouldNotHappen(assert)); + }); -test('loadAsset() - retrying a load twice returns the same promise', function(assert) { - assert.expect(2); + test('loadAsset() - retrying a load twice returns the same promise', function(assert) { + assert.expect(2); - const service = this.subject(); - const asset = { type: 'test', uri: 'someuri' }; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'test', uri: 'someuri' }; - service.defineLoader('test', () => RSVP.reject('some error')); + service.defineLoader('test', () => RSVP.reject('some error')); - return service.loadAsset(asset).then( - shouldNotHappen(assert), - (error) => { - const firstRetry = error.retryLoad(); - const secondRetry = error.retryLoad(); - const serviceRetry = service.loadAsset(asset); + return service.loadAsset(asset).then( + shouldNotHappen(assert), + (error) => { + const firstRetry = error.retryLoad(); + const secondRetry = error.retryLoad(); + const serviceRetry = service.loadAsset(asset); - assert.strictEqual(firstRetry, secondRetry, 'multiple retries produce same results'); - assert.strictEqual(firstRetry, serviceRetry, 'calling loadBundle again returns the retry result'); + assert.strictEqual(firstRetry, secondRetry, 'multiple retries produce same results'); + assert.strictEqual(firstRetry, serviceRetry, 'calling loadBundle again returns the retry result'); - return firstRetry; - } - ).catch(noop); -}); + return firstRetry; + } + ).catch(noop); + }); -test('loadAsset() - js - handles successful load', function(assert) { - assert.expect(1); + test('loadAsset() - js - handles successful load', function(assert) { + assert.expect(1); - const service = this.subject(); - const asset = { type: 'js', uri: '/unit-test.js' }; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'js', uri: '/unit-test.js' }; - return service.loadAsset(asset).then(shouldHappen(assert), shouldNotHappen(assert)); -}); + return service.loadAsset(asset).then(shouldHappen(assert), shouldNotHappen(assert)); + }); -test('loadAsset() - js - handles failed load', function(assert) { - assert.expect(1); + test('loadAsset() - js - handles failed load', function(assert) { + assert.expect(1); - const service = this.subject(); - const asset = { type: 'js', uri: '/unit-test.jsss' }; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'js', uri: '/unit-test.jsss' }; - return service.loadAsset(asset).then(shouldNotHappen(assert), shouldHappen(assert)); -}); + return service.loadAsset(asset).then(shouldNotHappen(assert), shouldHappen(assert)); + }); -test('loadAsset() - js - does not insert additional script tag if asset is in DOM already', function(assert) { - assert.expect(1); + test('loadAsset() - js - does not insert additional script tag if asset is in DOM already', function(assert) { + assert.expect(1); - if (!document.querySelector('script[src="/unit-test.js"]')) { - const script = document.createElement('script'); - script.src = '/unit-test.js'; - document.body.appendChild(script); - } + if (!document.querySelector('script[src="/unit-test.js"]')) { + const script = document.createElement('script'); + script.src = '/unit-test.js'; + document.body.appendChild(script); + } - const service = this.subject(); - const asset = { type: 'js', uri: '/unit-test.js' }; - const numScripts = document.querySelectorAll('script').length; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'js', uri: '/unit-test.js' }; + const numScripts = document.querySelectorAll('script').length; - return service.loadAsset(asset).then(() => { - const newNumScripts = document.querySelectorAll('script').length; - assert.equal(newNumScripts, numScripts); + return service.loadAsset(asset).then(() => { + const newNumScripts = document.querySelectorAll('script').length; + assert.equal(newNumScripts, numScripts); + }); }); -}); -test('loadAsset() - js - sets async false to try to guarantee execution order', function(assert) { - assert.expect(1); + test('loadAsset() - js - sets async false to try to guarantee execution order', function(assert) { + assert.expect(1); - const service = this.subject(); - const asset = { type: 'js', uri: '/unit-test.js' }; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'js', uri: '/unit-test.js' }; - return service.loadAsset(asset).then(() => { - const script = document.querySelector('script[src="/unit-test.js"]'); - assert.equal(script.async, false); + return service.loadAsset(asset).then(() => { + const script = document.querySelector('script[src="/unit-test.js"]'); + assert.equal(script.async, false); + }); }); -}); -test('loadAsset() - css - handles successful load', function(assert) { - assert.expect(1); + test('loadAsset() - css - handles successful load', function(assert) { + assert.expect(1); - const service = this.subject(); - const asset = { type: 'css', uri: '/unit-test.css' }; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'css', uri: '/unit-test.css' }; - return service.loadAsset(asset).then(shouldHappen(assert), shouldNotHappen(assert)); -}); + return service.loadAsset(asset).then(shouldHappen(assert), shouldNotHappen(assert)); + }); -test('loadAsset() - css - handles failed load', function(assert) { - assert.expect(1); + test('loadAsset() - css - handles failed load', function(assert) { + assert.expect(1); - const service = this.subject(); - const asset = { type: 'css', uri: '/unit-test.csss' }; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'css', uri: '/unit-test.csss' }; - // Since onload/onerror support is spotty for link elements, we allow - // non-Chrome browsers to either resolve or reject (they should do something). - var isChrome = !!window.chrome && window.navigator.vendor === 'Google Inc.'; - if (isChrome) { - return service.loadAsset(asset).then(shouldNotHappen(assert), shouldHappen(assert)); - } else { - return service.loadAsset(asset).then(shouldHappen(assert), shouldHappen(assert)); - } -}); + // Since onload/onerror support is spotty for link elements, we allow + // non-Chrome browsers to either resolve or reject (they should do something). + var isChrome = !!window.chrome && window.navigator.vendor === 'Google Inc.'; + if (isChrome) { + return service.loadAsset(asset).then(shouldNotHappen(assert), shouldHappen(assert)); + } else { + return service.loadAsset(asset).then(shouldHappen(assert), shouldHappen(assert)); + } + }); -test('loadAsset() - css - does not insert additional link tag if asset is in DOM already', function(assert) { - assert.expect(1); + test('loadAsset() - css - does not insert additional link tag if asset is in DOM already', function(assert) { + assert.expect(1); - if (!document.querySelector('link[href="/unit-test.css"]')) { - const link = document.createElement('link'); - link.href = '/unit-test.css'; - document.head.appendChild(link); - } + if (!document.querySelector('link[href="/unit-test.css"]')) { + const link = document.createElement('link'); + link.href = '/unit-test.css'; + document.head.appendChild(link); + } - const service = this.subject(); - const asset = { type: 'css', uri: '/unit-test.css' }; - const numLinks = document.querySelectorAll('link').length; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'css', uri: '/unit-test.css' }; + const numLinks = document.querySelectorAll('link').length; - return service.loadAsset(asset).then(() => { - const newNumLinks = document.querySelectorAll('link').length; - assert.equal(newNumLinks, numLinks); + return service.loadAsset(asset).then(() => { + const newNumLinks = document.querySelectorAll('link').length; + assert.equal(newNumLinks, numLinks); + }); }); -}); -test('defineLoader() - overwrites existing asset loader types', function(assert) { - assert.expect(1); + test('defineLoader() - overwrites existing asset loader types', function(assert) { + assert.expect(1); - const service = this.subject(); - const asset = { type: 'test', uri: 'someuri' }; + const service = this.owner.lookup('service:asset-loader'); + const asset = { type: 'test', uri: 'someuri' }; - service.defineLoader('test', () => RSVP.reject()); - service.defineLoader('test', () => RSVP.resolve()); + service.defineLoader('test', () => RSVP.reject()); + service.defineLoader('test', () => RSVP.resolve()); - return service.loadAsset(asset).then( - () => assert.ok(true), - shouldNotHappen(assert) - ); -}); + return service.loadAsset(asset).then( + () => assert.ok(true), + shouldNotHappen(assert) + ); + }); -test('pushManifest() - throws an error when merging two manifests with the same bundle', function(assert) { - const service = this.subject(); - const manifest = { - bundles: { - blog: {} - } - }; + test('pushManifest() - throws an error when merging two manifests with the same bundle', function(assert) { + const service = this.owner.lookup('service:asset-loader'); + const manifest = { + bundles: { + blog: {} + } + }; - service.pushManifest(manifest); - assert.throws(() => service.pushManifest(manifest), /The bundle "blog" already exists./); + service.pushManifest(manifest); + assert.throws(() => service.pushManifest(manifest), /The bundle "blog" already exists./); + }); }); diff --git a/tests/unit/test-helpers/loaded-asset-state-test.js b/tests/unit/test-helpers/loaded-asset-state-test.js index 5491e58..6920393 100644 --- a/tests/unit/test-helpers/loaded-asset-state-test.js +++ b/tests/unit/test-helpers/loaded-asset-state-test.js @@ -1,43 +1,30 @@ -import { moduleFor, test } from 'ember-qunit'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; import { cacheLoadedAssetState, getLoadedAssetState, resetLoadedAssetState } from 'ember-asset-loader/test-support/loaded-asset-state'; -moduleFor('service:asset-loader', 'Unit | Test Helper | loaded-asset-state', { - beforeEach() { - this.service = this.subject(); - this.service.pushManifest({ - bundles: { - 'loaded-asset-state': { - assets: [ - { - uri: '/test-dist/loaded-asset-state/loaded-asset-state.css', - type: 'css' - }, - { - uri: '/test-dist/loaded-asset-state/loaded-asset-state.js', - type: 'js' - } - ] - } - } - }); - } -}); +module('Unit | Test Helper | loaded-asset-state', function(hooks) { + setupTest(hooks); -test('resetLoadedAssetState removes new script tags, new link tags, and new modules', function(assert) { - assert.expect(4); + hooks.beforeEach(function() { + this.service = this.owner.lookup('service:asset-loader'); + }); - const startingState = getLoadedAssetState(); + test('resetLoadedAssetState removes new script tags, new link tags, and new modules', function(assert) { + assert.expect(4); - cacheLoadedAssetState(); + const startingState = getLoadedAssetState(); - return this.service.loadBundle('loaded-asset-state').then(() => { - const middleState = getLoadedAssetState(); - assert.notDeepEqual(startingState.requireEntries, middleState.requireEntries, 'starting and middle state for require entries are not the same'); - assert.notDeepEqual(startingState.scripts, middleState.scripts, 'starting and middle state for scripts are not the same'); - assert.notDeepEqual(startingState.links, middleState.links, 'starting and middle state for links are not the same'); + cacheLoadedAssetState(); - resetLoadedAssetState(); + return this.service.loadBundle('loaded-asset-state').then(() => { + const middleState = getLoadedAssetState(); + assert.notDeepEqual(startingState.requireEntries, middleState.requireEntries, 'starting and middle state for require entries are not the same'); + assert.notDeepEqual(startingState.scripts, middleState.scripts, 'starting and middle state for scripts are not the same'); + assert.notDeepEqual(startingState.links, middleState.links, 'starting and middle state for links are not the same'); - assert.deepEqual(startingState, getLoadedAssetState(), 'starting and ending state are the same'); + resetLoadedAssetState(); + + assert.deepEqual(startingState, getLoadedAssetState(), 'starting and ending state are the same'); + }); }); }); diff --git a/yarn.lock b/yarn.lock index 00beb0e..1419669 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1993,7 +1993,7 @@ broccoli-funnel-reducer@^1.0.0: resolved "https://registry.yarnpkg.com/broccoli-funnel-reducer/-/broccoli-funnel-reducer-1.0.0.tgz#11365b2a785aec9b17972a36df87eef24c5cc0ea" integrity sha1-ETZbKnha7JsXlyo234fu8kxcwOo= -broccoli-funnel@^1.0.0, broccoli-funnel@^1.2.0: +broccoli-funnel@^1.0.0, broccoli-funnel@^1.0.1, broccoli-funnel@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-1.2.0.tgz#cddc3afc5ff1685a8023488fff74ce6fb5a51296" integrity sha1-zdw6/F/xaFqAI0iP/3TOb7WlEpY= @@ -3085,25 +3085,7 @@ ember-assign-polyfill@~2.4.0: ember-cli-babel "^6.6.0" ember-cli-version-checker "^2.0.0" -ember-cli-babel@^6.0.0-beta.7, ember-cli-babel@^6.11.0, ember-cli-babel@^6.6.0, ember-cli-babel@^6.8.1: - version "6.12.0" - resolved "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.12.0.tgz#3adcdbe1278da1fcd0b9038f1360cb4ac5d4414c" - dependencies: - amd-name-resolver "0.0.7" - babel-plugin-debug-macros "^0.1.11" - babel-plugin-ember-modules-api-polyfill "^2.3.0" - babel-plugin-transform-es2015-modules-amd "^6.24.0" - babel-polyfill "^6.16.0" - babel-preset-env "^1.5.1" - broccoli-babel-transpiler "^6.1.2" - broccoli-debug "^0.6.2" - broccoli-funnel "^1.0.0" - broccoli-source "^1.1.0" - clone "^2.0.0" - ember-cli-version-checker "^2.1.0" - semver "^5.4.1" - -ember-cli-babel@^6.12.0, ember-cli-babel@^6.16.0, ember-cli-babel@^6.8.2: +ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.12.0, ember-cli-babel@^6.16.0, ember-cli-babel@^6.8.2: version "6.18.0" resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.18.0.tgz#3f6435fd275172edeff2b634ee7b29ce74318957" integrity sha512-7ceC8joNYxY2wES16iIBlbPSxwKDBhYwC8drU3ZEvuPDMwVv1KzxCNu1fvxyFEBWhwaRNTUxSCsEVoTd9nosGA== @@ -3122,6 +3104,24 @@ ember-cli-babel@^6.12.0, ember-cli-babel@^6.16.0, ember-cli-babel@^6.8.2: ember-cli-version-checker "^2.1.2" semver "^5.5.0" +ember-cli-babel@^6.0.0-beta.7, ember-cli-babel@^6.11.0, ember-cli-babel@^6.6.0, ember-cli-babel@^6.8.1: + version "6.12.0" + resolved "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.12.0.tgz#3adcdbe1278da1fcd0b9038f1360cb4ac5d4414c" + dependencies: + amd-name-resolver "0.0.7" + babel-plugin-debug-macros "^0.1.11" + babel-plugin-ember-modules-api-polyfill "^2.3.0" + babel-plugin-transform-es2015-modules-amd "^6.24.0" + babel-polyfill "^6.16.0" + babel-preset-env "^1.5.1" + broccoli-babel-transpiler "^6.1.2" + broccoli-debug "^0.6.2" + broccoli-funnel "^1.0.0" + broccoli-source "^1.1.0" + clone "^2.0.0" + ember-cli-version-checker "^2.1.0" + semver "^5.4.1" + ember-cli-babel@^7.0.0, ember-cli-babel@^7.5.0: version "7.5.0" resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.5.0.tgz#af654dcef23630391d2efe85aaa3bdf8b6ca17b7" @@ -3447,6 +3447,16 @@ ember-load-initializers@^2.0.0: dependencies: ember-cli-babel "^7.0.0" +ember-maybe-import-regenerator@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ember-maybe-import-regenerator/-/ember-maybe-import-regenerator-0.1.6.tgz#35d41828afa6d6a59bc0da3ce47f34c573d776ca" + integrity sha1-NdQYKK+m1qWbwNo85H80xXPXdso= + dependencies: + broccoli-funnel "^1.0.1" + broccoli-merge-trees "^1.0.0" + ember-cli-babel "^6.0.0-beta.4" + regenerator-runtime "^0.9.5" + ember-qunit@^3.5.0: version "3.5.3" resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-3.5.3.tgz#bfd0bff8298c78c77e870cca43fe0826e78a0d09" @@ -6829,6 +6839,11 @@ regenerator-runtime@^0.12.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== +regenerator-runtime@^0.9.5: + version "0.9.6" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" + integrity sha1-0z65XQ0gAaS+OWWXB8UbDLcc4Ck= + regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd"