QUnit.test('the {{link-to}} helper does not call preventDefault if `preventDefault=boundFalseyThing` is passed as an option', function() { setTemplate('index', compile("{{#link-to 'about' id='about-link' preventDefault=boundFalseyThing}}About{{/link-to}}")); App.IndexController = Controller.extend({ boundFalseyThing: false }); Router.map(function() { this.route('about'); }); bootApplication(); run(router, 'handleURL', '/'); let event = jQuery.Event('click'); jQuery('#about-link', '#qunit-fixture').trigger(event); equal(event.isDefaultPrevented(), false, 'should not preventDefault'); });
QUnit.test('Assigning defaultLayout to a component should set it up as a layout if layout was found [DEPRECATED]', function() { expect(2); setTemplate('application', compile('<div id=\'wrapper\'>{{#my-component}}{{text}}{{/my-component}}</div>')); setTemplate('components/my-component', compile('{{text}}-{{yield}}')); expectDeprecation(() => { boot(() => { appInstance.register('controller:application', Controller.extend({ 'text': 'outer' })); appInstance.register('component:my-component', Component.extend({ text: 'inner', defaultLayout: compile('should not see this!') })); }); }, /Specifying `defaultLayout` to .+ is deprecated\./); equal(jQuery('#wrapper').text(), 'inner-outer', 'The component is composed correctly'); });
QUnit.test('The {{link-to}} helper interaction event includes the route name', function(assert) { assert.expect(2); Router.map(function(match) { this.route('about'); }); bootApplication(); run(() => router.handleURL('/')); subscribe('interaction.link-to', { before(name, timestamp, { routeName }) { assert.equal(routeName, 'about', 'instrumentation subscriber was passed route name'); }, after(name, timestamp, { routeName }) { assert.equal(routeName, 'about', 'instrumentation subscriber was passed route name'); } }); jQuery('#about-link', '#qunit-fixture').click(); });
QUnit.test('The {{link-to}} helper fires an interaction event', function(assert) { assert.expect(2); Router.map(function(match) { this.route('about'); }); bootApplication(); run(() => router.handleURL('/')); subscribe('interaction.link-to', { before() { assert.ok(true, 'instrumentation subscriber was called'); }, after() { assert.ok(true, 'instrumentation subscriber was called'); } }); jQuery('#about-link', '#qunit-fixture').click(); });
QUnit.test('Don\'t enter loading route unless either route or template defined', function() { delete templates.loading; expect(2); let indexDeferred = RSVP.defer(); App.ApplicationController = Controller.extend(); App.IndexRoute = Route.extend({ model() { return indexDeferred.promise; } }); bootApplication(); let appController = container.lookup('controller:application'); ok(appController.get('currentPath') !== 'loading', 'loading state not entered'); run(indexDeferred, 'resolve', {}); equal(jQuery('#app', '#qunit-fixture').text(), 'INDEX'); });
QUnit.test("Issue 4201 - Shorthand for route.index shouldn't throw errors about context arguments", function() { expect(2); Router.map(function() { this.route('lobby', function() { this.route('index', { path: ':lobby_id' }); this.route('list'); }); }); App.LobbyIndexRoute = Route.extend({ model(params) { equal(params.lobby_id, 'foobar'); return params.lobby_id; } }); setTemplate('lobby/index', compile("{{#link-to 'lobby' 'foobar' id='lobby-link'}}Lobby{{/link-to}}")); setTemplate('index', compile('')); setTemplate('lobby/list', compile("{{#link-to 'lobby' 'foobar' id='lobby-link'}}Lobby{{/link-to}}")); bootApplication(); run(router, 'handleURL', '/lobby/list'); run(jQuery('#lobby-link'), 'click'); shouldBeActive('#lobby-link'); });
QUnit.test('Components trigger actions in the components context when called from within its template', function() { setTemplate('application', compile('<div id=\'wrapper\'>{{#my-component}}{{text}}{{/my-component}}</div>')); setTemplate('components/my-component', compile('<a href=\'#\' id=\'fizzbuzz\' {{action \'fizzbuzz\'}}>Fizzbuzz</a>')); boot(() => { appInstance.register('controller:application', Controller.extend({ actions: { fizzbuzz() { ok(false, 'action triggered on the wrong context'); } } })); appInstance.register('component:my-component', Component.extend({ actions: { fizzbuzz() { ok(true, 'action triggered on component'); } } })); }); jQuery('#fizzbuzz', '#wrapper').click(); });
QUnit.test('The {{link-to}} helper does not disregard current-when when it is set via a bound param', function() { Router.map(function(match) { this.route('index', { path: '/' }, function() { this.route('about'); }); this.route('items', function() { this.route('item'); }); }); App.IndexAboutController = Controller.extend({ currentWhen: 'index' }); setTemplate('index', compile('<h3>Home</h3>{{outlet}}')); setTemplate('index/about', compile("{{#link-to 'items' id='other-link' current-when=currentWhen}}ITEM{{/link-to}}")); bootApplication(); run(() => router.handleURL('/about')); equal(jQuery('#other-link.active', '#qunit-fixture').length, 1, 'The link is active when current-when is given for explicitly for a route'); });
QUnit.test('The {{link-to}} helper moves into the named route', function() { Router.map(function(match) { this.route('about'); }); bootApplication(); run(() => router.handleURL('/')); equal(jQuery('h3:contains(Home)', '#qunit-fixture').length, 1, 'The home template was rendered'); equal(jQuery('#self-link.active', '#qunit-fixture').length, 1, 'The self-link was rendered with active class'); equal(jQuery('#about-link:not(.active)', '#qunit-fixture').length, 1, 'The other link was rendered without active class'); run(() => jQuery('#about-link', '#qunit-fixture').click()); equal(jQuery('h3:contains(About)', '#qunit-fixture').length, 1, 'The about template was rendered'); equal(jQuery('#self-link.active', '#qunit-fixture').length, 1, 'The self-link was rendered with active class'); equal(jQuery('#home-link:not(.active)', '#qunit-fixture').length, 1, 'The other link was rendered without active class'); });
append(component) { let element = jQuery('#qunit-fixture')[0]; this.runTask(() => component.appendTo(element)); this.didAppend(component); return element; }
append(component) { this.runTask(() => component.appendTo('#qunit-fixture')); this.didAppend(component); return jQuery('#qunit-fixture')[0]; }
$(sel) { return sel ? jQuery(sel, this.element) : jQuery(this.element); }
this.ids.forEach(id => { let $element = jQuery(id).remove(); this.assert.strictEqual($element.length, 0, `Should not leak element: #${id}`); });
import Engine from '../../system/engine'; import Application from '../../system/application'; import ApplicationInstance from '../../system/application-instance'; import { run } from 'ember-metal'; import { jQuery } from 'ember-views'; import { privatize as P } from 'container'; import { factory } from 'internal-test-helpers'; import { Object as EmberObject } from 'ember-runtime'; let application, appInstance; QUnit.module('Ember.ApplicationInstance', { setup() { jQuery('#qunit-fixture').html('<div id=\'one\'><div id=\'one-child\'>HI</div></div><div id=\'two\'>HI</div>'); application = run(() => Application.create({ rootElement: '#one', router: null })); }, teardown() { jQuery('#qunit-fixture').empty(); if (appInstance) { run(appInstance, 'destroy'); } if (application) { run(application, 'destroy'); } } }); QUnit.test('an application instance can be created based upon an application', function() {
registry.register('template:index', compile('<h1>Node 1</h1>{{special-button}}', { moduleName: 'index' })); registry.register('template:components/special-button', compile('<button class=\'do-stuff\' {{action \'doStuff\'}}>Button</button>', { moduleName: 'components/special-button' })); }); return application; } function handleURL(application, path) { let router = application.__container__.lookup('router:main'); return run(router, 'handleURL', path); } QUnit.module('View Integration', { setup() { actions = []; jQuery('#qunit-fixture').html('<div id="app-1"></div><div id="app-2"></div>'); App1 = startApp('#app-1'); App2 = startApp('#app-2'); }, teardown() { run(App1, 'destroy'); run(App2, 'destroy'); App1 = App2 = null; } }); QUnit.test('booting multiple applications can properly handle events', function(assert) { run(App1, 'advanceReadiness'); run(App2, 'advanceReadiness');
function assertEquality(href) { equal(normalizeUrl(jQuery('#string-link', '#qunit-fixture').attr('href')), '/'); equal(normalizeUrl(jQuery('#path-link', '#qunit-fixture').attr('href')), href); }
trigger(type, xhr) { jQuery(document).trigger(type, xhr); }
QUnit.test('Ember Islands-style setup', function(assert) { let xFooInitCalled = false; let xFooDidInsertElementCalled = false; let xBarInitCalled = false; let xBarDidInsertElementCalled = false; run(() => { createApplication(true); App.Router.map(function() { this.route('show', { path: '/:component_name' }); }); App.register('route:show', Route.extend({ queryParams: { data: { refreshModel: true } }, model(params) { return { componentName: params.component_name, componentData: params.data ? JSON.parse(params.data) : undefined }; } })); let Counter = EmberObject.extend({ value: 0, increment() { this.incrementProperty('value'); } }); App.register('service:isolated-counter', Counter); App.register('service:shared-counter', Counter.create(), { instantiate: false }); App.register('template:show', compile('{{component model.componentName model=model.componentData}}')); App.register('template:components/x-foo', compile(` <h1>X-Foo</h1> <p>Hello {{model.name}}, I have been clicked {{isolatedCounter.value}} times ({{sharedCounter.value}} times combined)!</p> `)); App.register('component:x-foo', Component.extend({ tagName: 'x-foo', isolatedCounter: inject.service(), sharedCounter: inject.service(), init() { this._super(); xFooInitCalled = true; }, didInsertElement() { xFooDidInsertElementCalled = true; }, click() { this.get('isolatedCounter').increment(); this.get('sharedCounter').increment(); } })); App.register('template:components/x-bar', compile(` <h1>X-Bar</h1> <button {{action "incrementCounter"}}>Join {{counter.value}} others in clicking me!</button> `)); App.register('component:x-bar', Component.extend({ counter: inject.service('shared-counter'), actions: { incrementCounter() { this.get('counter').increment(); } }, init() { this._super(); xBarInitCalled = true; }, didInsertElement() { xBarDidInsertElementCalled = true; } })); }); let $foo = jQuery('<div />').appendTo('#qunit-fixture'); let $bar = jQuery('<div />').appendTo('#qunit-fixture'); let data = encodeURIComponent(JSON.stringify({ name: 'Godfrey' })); return RSVP.all([ run(App, 'visit', `/x-foo?data=${data}`, { rootElement: $foo[0] }), run(App, 'visit', '/x-bar', { rootElement: $bar[0] }) ]).then(() => { assert.ok(xFooInitCalled); assert.ok(xFooDidInsertElementCalled); assert.ok(xBarInitCalled); assert.ok(xBarDidInsertElementCalled); assert.equal($foo.find('h1').text(), 'X-Foo'); assert.equal($foo.find('p').text(), 'Hello Godfrey, I have been clicked 0 times (0 times combined)!'); assert.ok($foo.text().indexOf('X-Bar') === -1); assert.equal($bar.find('h1').text(), 'X-Bar'); assert.equal($bar.find('button').text(), 'Join 0 others in clicking me!'); assert.ok($bar.text().indexOf('X-Foo') === -1); run(() => $foo.find('x-foo').click()); assert.equal($foo.find('p').text(), 'Hello Godfrey, I have been clicked 1 times (1 times combined)!'); assert.equal($bar.find('button').text(), 'Join 1 others in clicking me!'); run(() => { $bar.find('button').click(); $bar.find('button').click(); }); assert.equal($foo.find('p').text(), 'Hello Godfrey, I have been clicked 1 times (3 times combined)!'); assert.equal($bar.find('button').text(), 'Join 3 others in clicking me!'); }); });
run(() => { equal(router.currentRouteName, 'cars.index'); equal(router.get('url'), '/cars'); equal(carsController.get('page'), 1, 'The page query-param is 1'); jQuery('#page2-link').click(); });
return run(App, 'visit', '/blog', { shouldRender: true }).then(instance => { assert.strictEqual(jQuery('#qunit-fixture').text(), 'turnt up', 'Engine component is resolved'); });
return run(App, 'visit', '/blog', { shouldRender: false }).then(instance => { assert.ok(instance instanceof ApplicationInstance, 'promise is resolved with an ApplicationInstance'); assert.strictEqual(jQuery('#qunit-fixture').children().length, 0, 'there are still no elements in the fixture element after visit'); });
return run(App, 'visit', '/').then(instance => { assert.ok(instance instanceof ApplicationInstance, 'promise is resolved with an ApplicationInstance'); assert.equal(jQuery('#qunit-fixture > .ember-view h1').text(), 'Hello world', 'the application was rendered once the promise resolves'); });
return this.visit('/parent/child?foo=lol').then(() => { assert.equal(parentModelCount, 1); run(jQuery('#parent-link'), 'click'); assert.equal(parentModelCount, 2); });
run(() => jQuery('#about-link', '#qunit-fixture').click());
import { run } from 'ember-metal'; import { jQuery } from 'ember-views'; var App; QUnit.module('Simple Testing Setup', { teardown() { if (App) { App.removeTestHelpers(); jQuery('#ember-testing-container, #ember-testing').remove(); run(App, 'destroy'); App = null; } } });
QUnit.test('The helper becomes the body of the component', function() { boot(); equal(jQuery('div.ember-view > div.ember-view', '#qunit-fixture').text(), 'hello world', 'The component is composed correctly'); });
run(() => { equal(router.currentRouteName, 'cars.create'); jQuery('#close-link').click(); });
QUnit.test('link-to with null/undefined dynamic parameters are put in a loading state', function() { expect(19); let oldWarn = Logger.warn; let warnCalled = false; Logger.warn = function() { warnCalled = true; }; setTemplate('index', compile("{{#link-to destinationRoute routeContext loadingClass='i-am-loading' id='context-link'}}string{{/link-to}}{{#link-to secondRoute loadingClass=loadingClass id='static-link'}}string{{/link-to}}")); let thing = EmberObject.create({ id: 123 }); App.IndexController = Controller.extend({ destinationRoute: null, routeContext: null, loadingClass: 'i-am-loading' }); App.AboutRoute = Route.extend({ activate() { ok(true, 'About was entered'); } }); App.Router.map(function() { this.route('thing', { path: '/thing/:thing_id' }); this.route('about'); }); bootApplication(); run(router, 'handleURL', '/'); function assertLinkStatus($link, url) { if (url) { equal(normalizeUrl($link.attr('href')), url, 'loaded link-to has expected href'); ok(!$link.hasClass('i-am-loading'), 'loaded linkComponent has no loadingClass'); } else { equal(normalizeUrl($link.attr('href')), '#', "unloaded link-to has href='#'"); ok($link.hasClass('i-am-loading'), 'loading linkComponent has loadingClass'); } } let $contextLink = jQuery('#context-link', '#qunit-fixture'); let $staticLink = jQuery('#static-link', '#qunit-fixture'); let controller = appInstance.lookup('controller:index'); assertLinkStatus($contextLink); assertLinkStatus($staticLink); run(() => { warnCalled = false; $contextLink.click(); ok(warnCalled, 'Logger.warn was called from clicking loading link'); }); // Set the destinationRoute (context is still null). run(controller, 'set', 'destinationRoute', 'thing'); assertLinkStatus($contextLink); // Set the routeContext to an id run(controller, 'set', 'routeContext', '456'); assertLinkStatus($contextLink, '/thing/456'); // Test that 0 isn't interpreted as falsy. run(controller, 'set', 'routeContext', 0); assertLinkStatus($contextLink, '/thing/0'); // Set the routeContext to an object run(controller, 'set', 'routeContext', thing); assertLinkStatus($contextLink, '/thing/123'); // Set the destinationRoute back to null. run(controller, 'set', 'destinationRoute', null); assertLinkStatus($contextLink); run(() => { warnCalled = false; $staticLink.click(); ok(warnCalled, 'Logger.warn was called from clicking loading link'); }); run(controller, 'set', 'secondRoute', 'about'); assertLinkStatus($staticLink, '/about'); // Click the now-active link run($staticLink, 'click'); Logger.warn = oldWarn; });
function checkActive(selector, active) { let classList = jQuery(selector, '#qunit-fixture')[0].className; equal(classList.indexOf('active') > -1, active, selector + ' active should be ' + active.toString()); }
run(() => { jQuery('#fizzbuzz', '#wrapper').click(); });