/*! * @overview Ember - JavaScript Application Framework * @copyright Copyright 2011-2015 Tilde Inc. and contributors * Portions Copyright 2006-2011 Strobe Inc. * Portions Copyright 2008-2011 Apple Inc. All rights reserved. * @license Licensed under MIT license * See https://raw.github.com/emberjs/ember.js/master/LICENSE * @version 1.11.3 */ (function() { var enifed, requireModule, eriuqer, requirejs, Ember; var mainContext = this; (function() { Ember = this.Ember = this.Ember || {}; if (typeof Ember === 'undefined') { Ember = {}; }; function UNDEFINED() { } if (typeof Ember.__loader === 'undefined') { var registry = {}; var seen = {}; enifed = function(name, deps, callback) { var value = { }; if (!callback) { value.deps = []; value.callback = deps; } else { value.deps = deps; value.callback = callback; } registry[name] = value; }; requirejs = eriuqer = requireModule = function(name) { var s = seen[name]; if (s !== undefined) { return seen[name]; } if (s === UNDEFINED) { return undefined; } seen[name] = {}; if (!registry[name]) { throw new Error('Could not find module ' + name); } var mod = registry[name]; var deps = mod.deps; var callback = mod.callback; var reified = []; var exports; var length = deps.length; for (var i=0; i"; }; Klass.create = create; Klass.extend = extend; Klass.reopen = extend; Klass.reopenClass = reopenClass; return Klass; function create(options) { return new this.prototype.constructor(options); } function reopenClass(options) { setProperties(this, options); } function extend(options) { var Child = function (options) { Klass.call(this, options); }; var Parent = this; Child.prototype = new Parent(); Child.prototype.constructor = Child; setProperties(Child, Klass); setProperties(Child.prototype, options); Child.create = create; Child.extend = extend; Child.reopen = extend; Child.reopenClass = reopenClass; return Child; } }; exports.factory = factory; exports.setProperties = setProperties; }); enifed('container/tests/container_helper.jscs-test', function () { 'use strict'; module("JSCS - container/tests"); test("container/tests/container_helper.js should pass jscs", function () { ok(true, "container/tests/container_helper.js should pass jscs."); }); }); enifed('container/tests/container_helper.jshint', function () { 'use strict'; module("JSHint - container/tests"); test("container/tests/container_helper.js should pass jshint", function () { ok(true, "container/tests/container_helper.js should pass jshint."); }); }); enifed('container/tests/container_test', ['container/tests/container_helper', 'container/registry'], function (container_helper, Registry) { 'use strict'; var originalModelInjections; QUnit.module("Container", { setup: function () { originalModelInjections = Ember.MODEL_FACTORY_INJECTIONS; }, teardown: function () { Ember.MODEL_FACTORY_INJECTIONS = originalModelInjections; } }); QUnit.test("A registered factory returns the same instance each time", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); var postController = container.lookup("controller:post"); ok(postController instanceof PostController, "The lookup is an instance of the factory"); equal(postController, container.lookup("controller:post")); }); QUnit.test("A registered factory is returned from lookupFactory", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); var PostControllerFactory = container.lookupFactory("controller:post"); ok(PostControllerFactory, "factory is returned"); ok(PostControllerFactory.create() instanceof PostController, "The return of factory.create is an instance of PostController"); }); QUnit.test("A registered factory is returned from lookupFactory is the same factory each time", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); deepEqual(container.lookupFactory("controller:post"), container.lookupFactory("controller:post"), "The return of lookupFactory is always the same"); }); QUnit.test("A factory returned from lookupFactory has a debugkey", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); var PostFactory = container.lookupFactory("controller:post"); ok(!PostFactory.container, "factory instance receives a container"); equal(PostFactory._debugContainerKey, "controller:post", "factory instance receives _debugContainerKey"); }); QUnit.test("fallback for to create time injections if factory has no extend", function () { var registry = new Registry['default'](); var container = registry.container(); var AppleController = container_helper.factory(); var PostController = container_helper.factory(); PostController.extend = undefined; // remove extend registry.register("controller:apple", AppleController); registry.register("controller:post", PostController); registry.injection("controller:post", "apple", "controller:apple"); var postController = container.lookup("controller:post"); ok(postController.container, "instance receives a container"); equal(postController.container, container, "instance receives the correct container"); equal(postController._debugContainerKey, "controller:post", "instance receives _debugContainerKey"); ok(postController.apple instanceof AppleController, "instance receives an apple of instance AppleController"); }); QUnit.test("The descendants of a factory returned from lookupFactory have a container and debugkey", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); var instance; registry.register("controller:post", PostController); instance = container.lookupFactory("controller:post").create(); ok(instance.container, "factory instance receives a container"); equal(instance._debugContainerKey, "controller:post", "factory instance receives _debugContainerKey"); ok(instance instanceof PostController, "factory instance is instance of factory"); }); QUnit.test("A registered factory returns a fresh instance if singleton: false is passed as an option", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); var postController1 = container.lookup("controller:post"); var postController2 = container.lookup("controller:post", { singleton: false }); var postController3 = container.lookup("controller:post", { singleton: false }); var postController4 = container.lookup("controller:post"); equal(postController1.toString(), postController4.toString(), "Singleton factories looked up normally return the same value"); notEqual(postController1.toString(), postController2.toString(), "Singleton factories are not equal to factories looked up with singleton: false"); notEqual(postController2.toString(), postController3.toString(), "Two factories looked up with singleton: false are not equal"); notEqual(postController3.toString(), postController4.toString(), "A singleton factory looked up after a factory called with singleton: false is not equal"); ok(postController1 instanceof PostController, "All instances are instances of the registered factory"); ok(postController2 instanceof PostController, "All instances are instances of the registered factory"); ok(postController3 instanceof PostController, "All instances are instances of the registered factory"); ok(postController4 instanceof PostController, "All instances are instances of the registered factory"); }); QUnit.test("A container lookup has access to the container", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); var postController = container.lookup("controller:post"); equal(postController.container, container); }); QUnit.test("A factory type with a registered injection's instances receive that injection", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); var Store = container_helper.factory(); registry.register("controller:post", PostController); registry.register("store:main", Store); registry.typeInjection("controller", "store", "store:main"); var postController = container.lookup("controller:post"); var store = container.lookup("store:main"); equal(postController.store, store); }); QUnit.test("An individual factory with a registered injection receives the injection", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); var Store = container_helper.factory(); registry.register("controller:post", PostController); registry.register("store:main", Store); registry.injection("controller:post", "store", "store:main"); var postController = container.lookup("controller:post"); var store = container.lookup("store:main"); equal(store.container, container); equal(store._debugContainerKey, "store:main"); equal(postController.container, container); equal(postController._debugContainerKey, "controller:post"); equal(postController.store, store, "has the correct store injected"); }); QUnit.test("A factory with both type and individual injections", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); var Store = container_helper.factory(); var Router = container_helper.factory(); registry.register("controller:post", PostController); registry.register("store:main", Store); registry.register("router:main", Router); registry.injection("controller:post", "store", "store:main"); registry.typeInjection("controller", "router", "router:main"); var postController = container.lookup("controller:post"); var store = container.lookup("store:main"); var router = container.lookup("router:main"); equal(postController.store, store); equal(postController.router, router); }); QUnit.test("A factory with both type and individual factoryInjections", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); var Store = container_helper.factory(); var Router = container_helper.factory(); registry.register("controller:post", PostController); registry.register("store:main", Store); registry.register("router:main", Router); registry.factoryInjection("controller:post", "store", "store:main"); registry.factoryTypeInjection("controller", "router", "router:main"); var PostControllerFactory = container.lookupFactory("controller:post"); var store = container.lookup("store:main"); var router = container.lookup("router:main"); equal(PostControllerFactory.store, store, "PostControllerFactory has the instance of store"); equal(PostControllerFactory.router, router, "PostControllerFactory has the route instance"); }); QUnit.test("A non-singleton instance is never cached", function () { var registry = new Registry['default'](); var container = registry.container(); var PostView = container_helper.factory(); registry.register("view:post", PostView, { singleton: false }); var postView1 = container.lookup("view:post"); var postView2 = container.lookup("view:post"); ok(postView1 !== postView2, "Non-singletons are not cached"); }); QUnit.test("A non-instantiated property is not instantiated", function () { var registry = new Registry['default'](); var container = registry.container(); var template = function () {}; registry.register("template:foo", template, { instantiate: false }); equal(container.lookup("template:foo"), template); }); QUnit.test("A failed lookup returns undefined", function () { var registry = new Registry['default'](); var container = registry.container(); equal(container.lookup("doesnot:exist"), undefined); }); QUnit.test("An invalid factory throws an error", function () { var registry = new Registry['default'](); var container = registry.container(); registry.register("controller:foo", {}); throws(function () { container.lookup("controller:foo"); }, /Failed to create an instance of \'controller:foo\'/); }); QUnit.test("Injecting a failed lookup raises an error", function () { Ember.MODEL_FACTORY_INJECTIONS = true; var registry = new Registry['default'](); var container = registry.container(); var fooInstance = {}; var fooFactory = {}; var Foo = { create: function (args) { return fooInstance; }, extend: function (args) { return fooFactory; } }; registry.register("model:foo", Foo); registry.injection("model:foo", "store", "store:main"); throws(function () { container.lookup("model:foo"); }); }); QUnit.test("Injecting a falsy value does not raise an error", function () { var registry = new Registry['default'](); var container = registry.container(); var ApplicationController = container_helper.factory(); registry.register("controller:application", ApplicationController); registry.register("user:current", null, { instantiate: false }); registry.injection("controller:application", "currentUser", "user:current"); equal(container.lookup("controller:application").currentUser, null); }); QUnit.test("Destroying the container destroys any cached singletons", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); var PostView = container_helper.factory(); var template = function () {}; registry.register("controller:post", PostController); registry.register("view:post", PostView, { singleton: false }); registry.register("template:post", template, { instantiate: false }); registry.injection("controller:post", "postView", "view:post"); var postController = container.lookup("controller:post"); var postView = postController.postView; ok(postView instanceof PostView, "The non-singleton was injected"); container.destroy(); ok(postController.isDestroyed, "Singletons are destroyed"); ok(!postView.isDestroyed, "Non-singletons are not destroyed"); }); QUnit.test("The container can use a registry hook to resolve factories lazily", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); registry.resolver = function (fullName) { if (fullName === "controller:post") { return PostController; } }; var postController = container.lookup("controller:post"); ok(postController instanceof PostController, "The correct factory was provided"); }); QUnit.test("The container normalizes names before resolving", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); registry.normalizeFullName = function (fullName) { return "controller:post"; }; registry.register("controller:post", PostController); var postController = container.lookup("controller:normalized"); ok(postController instanceof PostController, "Normalizes the name before resolving"); }); QUnit.test("The container normalizes names when looking factory up", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); registry.normalizeFullName = function (fullName) { return "controller:post"; }; registry.register("controller:post", PostController); var fact = container.lookupFactory("controller:normalized"); equal(fact.toString() === PostController.extend().toString(), true, "Normalizes the name when looking factory up"); }); QUnit.test("The container can get options that should be applied to a given factory", function () { var registry = new Registry['default'](); var container = registry.container(); var PostView = container_helper.factory(); registry.resolver = function (fullName) { if (fullName === "view:post") { return PostView; } }; registry.options("view:post", { instantiate: true, singleton: false }); var postView1 = container.lookup("view:post"); var postView2 = container.lookup("view:post"); ok(postView1 instanceof PostView, "The correct factory was provided"); ok(postView2 instanceof PostView, "The correct factory was provided"); ok(postView1 !== postView2, "The two lookups are different"); }); QUnit.test("The container can get options that should be applied to all factories for a given type", function () { var registry = new Registry['default'](); var container = registry.container(); var PostView = container_helper.factory(); registry.resolver = function (fullName) { if (fullName === "view:post") { return PostView; } }; registry.optionsForType("view", { singleton: false }); var postView1 = container.lookup("view:post"); var postView2 = container.lookup("view:post"); ok(postView1 instanceof PostView, "The correct factory was provided"); ok(postView2 instanceof PostView, "The correct factory was provided"); ok(postView1 !== postView2, "The two lookups are different"); }); QUnit.test("factory resolves are cached", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); var resolveWasCalled = []; registry.resolve = function (fullName) { resolveWasCalled.push(fullName); return PostController; }; deepEqual(resolveWasCalled, []); container.lookupFactory("controller:post"); deepEqual(resolveWasCalled, ["controller:post"]); container.lookupFactory("controller:post"); deepEqual(resolveWasCalled, ["controller:post"]); }); QUnit.test("factory for non extendables (MODEL) resolves are cached", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = container_helper.factory(); var resolveWasCalled = []; registry.resolve = function (fullName) { resolveWasCalled.push(fullName); return PostController; }; deepEqual(resolveWasCalled, []); container.lookupFactory("model:post"); deepEqual(resolveWasCalled, ["model:post"]); container.lookupFactory("model:post"); deepEqual(resolveWasCalled, ["model:post"]); }); QUnit.test("factory for non extendables resolves are cached", function () { var registry = new Registry['default'](); var container = registry.container(); var PostController = {}; var resolveWasCalled = []; registry.resolve = function (fullName) { resolveWasCalled.push(fullName); return PostController; }; deepEqual(resolveWasCalled, []); container.lookupFactory("foo:post"); deepEqual(resolveWasCalled, ["foo:post"]); container.lookupFactory("foo:post"); deepEqual(resolveWasCalled, ["foo:post"]); }); QUnit.test("The `_onLookup` hook is called on factories when looked up the first time", function () { expect(2); var registry = new Registry['default'](); var container = registry.container(); var Apple = container_helper.factory(); Apple.reopenClass({ _onLookup: function (fullName) { equal(fullName, "apple:main", "calls lazy injection method with the lookup full name"); equal(this, Apple, "calls lazy injection method in the factory context"); } }); registry.register("apple:main", Apple); container.lookupFactory("apple:main"); container.lookupFactory("apple:main"); }); QUnit.test("A factory's lazy injections are validated when first instantiated", function () { var registry = new Registry['default'](); var container = registry.container(); var Apple = container_helper.factory(); var Orange = container_helper.factory(); Apple.reopenClass({ _lazyInjections: function () { return ["orange:main", "banana:main"]; } }); registry.register("apple:main", Apple); registry.register("orange:main", Orange); throws(function () { container.lookup("apple:main"); }, /Attempting to inject an unknown injection: `banana:main`/); }); QUnit.test("Lazy injection validations are cached", function () { expect(1); var registry = new Registry['default'](); var container = registry.container(); var Apple = container_helper.factory(); var Orange = container_helper.factory(); Apple.reopenClass({ _lazyInjections: function () { ok(true, "should call lazy injection method"); return ["orange:main"]; } }); registry.register("apple:main", Apple); registry.register("orange:main", Orange); container.lookup("apple:main"); container.lookup("apple:main"); }); }); enifed('container/tests/container_test.jscs-test', function () { 'use strict'; module("JSCS - container/tests"); test("container/tests/container_test.js should pass jscs", function () { ok(true, "container/tests/container_test.js should pass jscs."); }); }); enifed('container/tests/container_test.jshint', function () { 'use strict'; module("JSHint - container/tests"); test("container/tests/container_test.js should pass jshint", function () { ok(true, "container/tests/container_test.js should pass jshint."); }); }); enifed('container/tests/registry_test', ['container/tests/container_helper', 'container'], function (container_helper, _container) { 'use strict'; var originalModelInjections; QUnit.module("Registry", { setup: function () { originalModelInjections = Ember.MODEL_FACTORY_INJECTIONS; }, teardown: function () { Ember.MODEL_FACTORY_INJECTIONS = originalModelInjections; } }); QUnit.test("A registered factory is returned from resolve", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); var PostControllerFactory = registry.resolve("controller:post"); ok(PostControllerFactory, "factory is returned"); ok(PostControllerFactory.create() instanceof PostController, "The return of factory.create is an instance of PostController"); }); QUnit.test("The registered factory returned from resolve is the same factory each time", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); deepEqual(registry.resolve("controller:post"), registry.resolve("controller:post"), "The return of resolve is always the same"); }); QUnit.test("A registered factory returns true for `has` if an item is registered", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); equal(registry.has("controller:post"), true, "The `has` method returned true for registered factories"); equal(registry.has("controller:posts"), false, "The `has` method returned false for unregistered factories"); }); QUnit.test("Throw exception when trying to inject `type:thing` on all type(s)", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); throws(function () { registry.typeInjection("controller", "injected", "controller:post"); }, "Cannot inject a `controller:post` on other controller(s)."); }); QUnit.test("The registry can take a hook to resolve factories lazily", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); registry.resolver = function (fullName) { if (fullName === "controller:post") { return PostController; } }; strictEqual(registry.resolve("controller:post"), PostController, "The correct factory was provided"); }); QUnit.test("The registry respects the resolver hook for `has`", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); registry.resolver = function (fullName) { if (fullName === "controller:post") { return PostController; } }; ok(registry.has("controller:post"), "the `has` method uses the resolver hook"); }); QUnit.test("The registry normalizes names when resolving", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); registry.normalizeFullName = function (fullName) { return "controller:post"; }; registry.register("controller:post", PostController); var type = registry.resolve("controller:normalized"); strictEqual(type, PostController, "Normalizes the name when resolving"); }); QUnit.test("The registry normalizes names when checking if the factory is registered", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); registry.normalizeFullName = function (fullName) { return "controller:post"; }; registry.register("controller:post", PostController); var isPresent = registry.has("controller:normalized"); equal(isPresent, true, "Normalizes the name when checking if the factory or instance is present"); }); QUnit.test("validateFullName throws an error if name is incorrect", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); registry.normalize = function (fullName) { return "controller:post"; }; registry.register("controller:post", PostController); throws(function () { registry.resolve("post"); }, "TypeError: Invalid Fullname, expected: `type:name` got: post"); }); QUnit.test("The registry normalizes names when injecting", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); var user = { name: "Stef" }; registry.normalize = function (fullName) { return "controller:post"; }; registry.register("controller:post", PostController); registry.register("user:post", user, { instantiate: false }); registry.injection("controller:post", "user", "controller:normalized"); deepEqual(registry.resolve("controller:post"), user, "Normalizes the name when injecting"); }); QUnit.test("cannot register an `undefined` factory", function () { var registry = new _container.Registry(); throws(function () { registry.register("controller:apple", undefined); }, ""); }); QUnit.test("can re-register a factory", function () { var registry = new _container.Registry(); var FirstApple = container_helper.factory("first"); var SecondApple = container_helper.factory("second"); registry.register("controller:apple", FirstApple); registry.register("controller:apple", SecondApple); ok(registry.resolve("controller:apple").create() instanceof SecondApple); }); QUnit.test("cannot re-register a factory if it has been resolved", function () { var registry = new _container.Registry(); var FirstApple = container_helper.factory("first"); var SecondApple = container_helper.factory("second"); registry.register("controller:apple", FirstApple); strictEqual(registry.resolve("controller:apple"), FirstApple); throws(function () { registry.register("controller:apple", SecondApple); }, "Cannot re-register: `controller:apple`, as it has already been resolved."); strictEqual(registry.resolve("controller:apple"), FirstApple); }); QUnit.test("registry.has should not accidentally cause injections on that factory to be run. (Mitigate merely on observing)", function () { expect(1); var registry = new _container.Registry(); var FirstApple = container_helper.factory("first"); var SecondApple = container_helper.factory("second"); SecondApple.extend = function (a, b, c) { ok(false, "should not extend or touch the injected model, merely to inspect existence of another"); }; registry.register("controller:apple", FirstApple); registry.register("controller:second-apple", SecondApple); registry.injection("controller:apple", "badApple", "controller:second-apple"); ok(registry.has("controller:apple")); }); QUnit.test("once resolved, always return the same result", function () { expect(1); var registry = new _container.Registry(); registry.resolver = function () { return "bar"; }; var Bar = registry.resolve("models:bar"); registry.resolver = function () { return "not bar"; }; equal(registry.resolve("models:bar"), Bar); }); QUnit.test("factory resolves are cached", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); var resolveWasCalled = []; registry.resolver = function (fullName) { resolveWasCalled.push(fullName); return PostController; }; deepEqual(resolveWasCalled, []); registry.resolve("controller:post"); deepEqual(resolveWasCalled, ["controller:post"]); registry.resolve("controller:post"); deepEqual(resolveWasCalled, ["controller:post"]); }); QUnit.test("factory for non extendables (MODEL) resolves are cached", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); var resolveWasCalled = []; registry.resolver = function (fullName) { resolveWasCalled.push(fullName); return PostController; }; deepEqual(resolveWasCalled, []); registry.resolve("model:post"); deepEqual(resolveWasCalled, ["model:post"]); registry.resolve("model:post"); deepEqual(resolveWasCalled, ["model:post"]); }); QUnit.test("factory for non extendables resolves are cached", function () { var registry = new _container.Registry(); var PostController = {}; var resolveWasCalled = []; registry.resolver = function (fullName) { resolveWasCalled.push(fullName); return PostController; }; deepEqual(resolveWasCalled, []); registry.resolve("foo:post"); deepEqual(resolveWasCalled, ["foo:post"]); registry.resolve("foo:post"); deepEqual(resolveWasCalled, ["foo:post"]); }); QUnit.test("registry.container creates an associated container", function () { var registry = new _container.Registry(); var PostController = container_helper.factory(); registry.register("controller:post", PostController); var container = registry.container(); var postController = container.lookup("controller:post"); ok(postController instanceof PostController, "The lookup is an instance of the registered factory"); strictEqual(registry._defaultContainer, container, "_defaultContainer is set to the first created container and used for Ember 1.x Container compatibility"); }); QUnit.test("`resolve` can be handled by a fallback registry", function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); var PostController = container_helper.factory(); fallback.register("controller:post", PostController); var PostControllerFactory = registry.resolve("controller:post"); ok(PostControllerFactory, "factory is returned"); ok(PostControllerFactory.create() instanceof PostController, "The return of factory.create is an instance of PostController"); }); QUnit.test("`has` can be handled by a fallback registry", function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); var PostController = container_helper.factory(); fallback.register("controller:post", PostController); equal(registry.has("controller:post"), true, "Fallback registry is checked for registration"); }); QUnit.test("`getInjections` includes injections from a fallback registry", function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); equal(registry.getInjections("model:user").length, 0, "No injections in the primary registry"); fallback.injection("model:user", "post", "model:post"); equal(registry.getInjections("model:user").length, 1, "Injections from the fallback registry are merged"); }); QUnit.test("`getTypeInjections` includes type injections from a fallback registry", function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); equal(registry.getTypeInjections("model").length, 0, "No injections in the primary registry"); fallback.injection("model", "source", "source:main"); equal(registry.getTypeInjections("model").length, 1, "Injections from the fallback registry are merged"); }); QUnit.test("`getFactoryInjections` includes factory injections from a fallback registry", function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); equal(registry.getFactoryInjections("model:user").length, 0, "No factory injections in the primary registry"); fallback.factoryInjection("model:user", "store", "store:main"); equal(registry.getFactoryInjections("model:user").length, 1, "Factory injections from the fallback registry are merged"); }); QUnit.test("`getFactoryTypeInjections` includes factory type injections from a fallback registry", function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); equal(registry.getFactoryTypeInjections("model").length, 0, "No factory type injections in the primary registry"); fallback.factoryInjection("model", "store", "store:main"); equal(registry.getFactoryTypeInjections("model").length, 1, "Factory type injections from the fallback registry are merged"); }); }); enifed('container/tests/registry_test.jscs-test', function () { 'use strict'; module("JSCS - container/tests"); test("container/tests/registry_test.js should pass jscs", function () { ok(true, "container/tests/registry_test.js should pass jscs."); }); }); enifed('container/tests/registry_test.jshint', function () { 'use strict'; module("JSHint - container/tests"); test("container/tests/registry_test.js should pass jshint", function () { ok(true, "container/tests/registry_test.js should pass jshint."); }); }); enifed('ember-application.jscs-test', function () { 'use strict'; module("JSCS - ."); test("ember-application.js should pass jscs", function () { ok(true, "ember-application.js should pass jscs."); }); }); enifed('ember-application.jshint', function () { 'use strict'; module("JSHint - ."); test("ember-application.js should pass jshint", function () { ok(true, "ember-application.js should pass jshint."); }); }); enifed('ember-application/ext/controller.jscs-test', function () { 'use strict'; module("JSCS - ember-application/ext"); test("ember-application/ext/controller.js should pass jscs", function () { ok(true, "ember-application/ext/controller.js should pass jscs."); }); }); enifed('ember-application/ext/controller.jshint', function () { 'use strict'; module("JSHint - ember-application/ext"); test("ember-application/ext/controller.js should pass jshint", function () { ok(true, "ember-application/ext/controller.js should pass jshint."); }); }); enifed('ember-application/system/application-instance.jscs-test', function () { 'use strict'; module("JSCS - ember-application/system"); test("ember-application/system/application-instance.js should pass jscs", function () { ok(true, "ember-application/system/application-instance.js should pass jscs."); }); }); enifed('ember-application/system/application-instance.jshint', function () { 'use strict'; module("JSHint - ember-application/system"); test("ember-application/system/application-instance.js should pass jshint", function () { ok(true, "ember-application/system/application-instance.js should pass jshint."); }); }); enifed('ember-application/system/application.jscs-test', function () { 'use strict'; module("JSCS - ember-application/system"); test("ember-application/system/application.js should pass jscs", function () { ok(true, "ember-application/system/application.js should pass jscs."); }); }); enifed('ember-application/system/application.jshint', function () { 'use strict'; module("JSHint - ember-application/system"); test("ember-application/system/application.js should pass jshint", function () { ok(true, "ember-application/system/application.js should pass jshint."); }); }); enifed('ember-application/system/resolver.jscs-test', function () { 'use strict'; module("JSCS - ember-application/system"); test("ember-application/system/resolver.js should pass jscs", function () { ok(true, "ember-application/system/resolver.js should pass jscs."); }); }); enifed('ember-application/system/resolver.jshint', function () { 'use strict'; module("JSHint - ember-application/system"); test("ember-application/system/resolver.js should pass jshint", function () { ok(true, "ember-application/system/resolver.js should pass jshint."); }); }); enifed('ember-application/tests/system/application_test', ['ember-metal/core', 'ember-metal/run_loop', 'ember-application/system/application', 'ember-application/system/resolver', 'ember-routing/system/router', 'ember-views/views/view', 'ember-runtime/controllers/controller', 'ember-routing/location/none_location', 'ember-runtime/system/object', 'ember-views/system/jquery', 'ember-template-compiler/system/compile'], function (Ember, run, Application, DefaultResolver, Router, View, Controller, NoneLocation, EmberObject, jQuery, compile) { 'use strict'; /*globals EmberDev */ var trim = jQuery['default'].trim; var app, application, originalLookup, originalDebug; QUnit.module("Ember.Application", { setup: function () { originalLookup = Ember['default'].lookup; originalDebug = Ember['default'].debug; jQuery['default']("#qunit-fixture").html("
HI
HI
"); run['default'](function () { application = Application['default'].create({ rootElement: "#one", router: null }); }); }, teardown: function () { jQuery['default']("#qunit-fixture").empty(); Ember['default'].debug = originalDebug; Ember['default'].lookup = originalLookup; if (application) { run['default'](application, "destroy"); } if (app) { run['default'](app, "destroy"); } } }); QUnit.test("you can make a new application in a non-overlapping element", function () { run['default'](function () { app = Application['default'].create({ rootElement: "#two", router: null }); }); run['default'](app, "destroy"); ok(true, "should not raise"); }); QUnit.test("you cannot make a new application that is a parent of an existing application", function () { expectAssertion(function () { run['default'](function () { Application['default'].create({ rootElement: "#qunit-fixture" }); }); }); }); QUnit.test("you cannot make a new application that is a descendent of an existing application", function () { expectAssertion(function () { run['default'](function () { Application['default'].create({ rootElement: "#one-child" }); }); }); }); QUnit.test("you cannot make a new application that is a duplicate of an existing application", function () { expectAssertion(function () { run['default'](function () { Application['default'].create({ rootElement: "#one" }); }); }); }); QUnit.test("you cannot make two default applications without a rootElement error", function () { expectAssertion(function () { run['default'](function () { Application['default'].create({ router: false }); }); }); }); QUnit.test("acts like a namespace", function () { var lookup = Ember['default'].lookup = {}; var app; run['default'](function () { app = lookup.TestApp = Application['default'].create({ rootElement: "#two", router: false }); }); Ember['default'].BOOTED = false; app.Foo = EmberObject['default'].extend(); equal(app.Foo.toString(), "TestApp.Foo", "Classes pick up their parent namespace"); }); QUnit.module("Ember.Application initialization", { teardown: function () { if (app) { run['default'](app, "destroy"); } Ember['default'].TEMPLATES = {}; } }); QUnit.test("initialized application go to initial route", function () { run['default'](function () { app = Application['default'].create({ rootElement: "#qunit-fixture" }); app.Router.reopen({ location: "none" }); app.register("template:application", compile['default']("{{outlet}}")); Ember['default'].TEMPLATES.index = compile['default']("

Hi from index

"); }); equal(jQuery['default']("#qunit-fixture h1").text(), "Hi from index"); }); QUnit.test("initialize application via initialize call", function () { run['default'](function () { app = Application['default'].create({ rootElement: "#qunit-fixture" }); app.Router.reopen({ location: "none" }); app.ApplicationView = View['default'].extend({ template: function () { return "

Hello!

"; } }); }); // This is not a public way to access the container; we just // need to make some assertions about the created router var router = app.__container__.lookup("router:main"); equal(router instanceof Router['default'], true, "Router was set from initialize call"); equal(router.location instanceof NoneLocation['default'], true, "Location was set from location implementation name"); }); QUnit.test("initialize application with stateManager via initialize call from Router class", function () { run['default'](function () { app = Application['default'].create({ rootElement: "#qunit-fixture" }); app.Router.reopen({ location: "none" }); app.register("template:application", function () { return "

Hello!

"; }); }); var router = app.__container__.lookup("router:main"); equal(router instanceof Router['default'], true, "Router was set from initialize call"); equal(jQuery['default']("#qunit-fixture h1").text(), "Hello!"); }); QUnit.test("ApplicationView is inserted into the page", function () { run['default'](function () { app = Application['default'].create({ rootElement: "#qunit-fixture" }); app.ApplicationView = View['default'].extend({ render: function (buffer) { buffer.push("

Hello!

"); } }); app.ApplicationController = Controller['default'].extend(); app.Router.reopen({ location: "none" }); }); equal(jQuery['default']("#qunit-fixture h1").text(), "Hello!"); }); QUnit.test("Minimal Application initialized with just an application template", function () { jQuery['default']("#qunit-fixture").html(""); run['default'](function () { app = Application['default'].create({ rootElement: "#qunit-fixture" }); }); equal(trim(jQuery['default']("#qunit-fixture").text()), "Hello World"); }); QUnit.test("enable log of libraries with an ENV var", function () { if (EmberDev && EmberDev.runningProdBuild) { ok(true, "Logging does not occur in production builds"); return; } var debug = Ember['default'].debug; var messages = []; Ember['default'].LOG_VERSION = true; Ember['default'].debug = function (message) { messages.push(message); }; Ember['default'].libraries.register("my-lib", "2.0.0a"); run['default'](function () { app = Application['default'].create({ rootElement: "#qunit-fixture" }); }); equal(messages[1], "Ember : " + Ember['default'].VERSION); equal(messages[2], "jQuery : " + jQuery['default']().jquery); equal(messages[3], "my-lib : " + "2.0.0a"); Ember['default'].libraries.deRegister("my-lib"); Ember['default'].LOG_VERSION = false; Ember['default'].debug = debug; }); QUnit.test("disable log version of libraries with an ENV var", function () { var logged = false; Ember['default'].LOG_VERSION = false; Ember['default'].debug = function (message) { logged = true; }; jQuery['default']("#qunit-fixture").empty(); run['default'](function () { app = Application['default'].create({ rootElement: "#qunit-fixture" }); app.Router.reopen({ location: "none" }); }); ok(!logged, "library version logging skipped"); }); QUnit.test("can resolve custom router", function () { var CustomRouter = Router['default'].extend(); var CustomResolver = DefaultResolver['default'].extend({ resolveMain: function (parsedName) { if (parsedName.type === "router") { return CustomRouter; } else { return this._super(parsedName); } } }); app = run['default'](function () { return Application['default'].create({ Resolver: CustomResolver }); }); ok(app.__container__.lookup("router:main") instanceof CustomRouter, "application resolved the correct router"); }); QUnit.test("can specify custom router", function () { var CustomRouter = Router['default'].extend(); app = run['default'](function () { return Application['default'].create({ Router: CustomRouter }); }); ok(app.__container__.lookup("router:main") instanceof CustomRouter, "application resolved the correct router"); }); QUnit.test("throws helpful error if `app.then` is used", function () { run['default'](function () { app = Application['default'].create({ rootElement: "#qunit-fixture" }); }); expectDeprecation(function () { run['default'](app, "then", function () { return this; }); }, /Do not use `.then` on an instance of Ember.Application. Please use the `.ready` hook instead./); }); QUnit.test("registers controls onto to container", function () { run['default'](function () { app = Application['default'].create({ rootElement: "#qunit-fixture" }); }); ok(app.__container__.lookup("view:select"), "Select control is registered into views"); }); }); enifed('ember-application/tests/system/application_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system"); test("ember-application/tests/system/application_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/application_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/application_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system"); test("ember-application/tests/system/application_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/application_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/controller_test', ['ember-runtime/controllers/controller', 'ember-application/ext/controller', 'ember-runtime/system/container', 'ember-runtime/system/native_array', 'ember-runtime/controllers/array_controller', 'ember-metal/computed'], function (Controller, __dep1__, system__container, native_array, ArrayController, computed) { 'use strict'; /*jshint newcap:false */ QUnit.module("Controller dependencies"); QUnit.test("If a controller specifies a dependency, but does not have a container it should error", function () { var AController = Controller['default'].extend({ needs: "posts" }); expectAssertion(function () { AController.create(); }, /specifies `needs`, but does not have a container. Please ensure this controller was instantiated with a container./); }); QUnit.test("If a controller specifies a dependency, it is accessible", function () { var registry = new system__container.Registry(); var container = registry.container(); registry.register("controller:post", Controller['default'].extend({ needs: "posts" })); registry.register("controller:posts", Controller['default'].extend()); var postController = container.lookup("controller:post"); var postsController = container.lookup("controller:posts"); equal(postsController, postController.get("controllers.posts"), "controller.posts must be auto synthesized"); }); QUnit.test("If a controller specifies an unavailable dependency, it raises", function () { var registry = new system__container.Registry(); var container = registry.container(); registry.register("controller:post", Controller['default'].extend({ needs: ["comments"] })); throws(function () { container.lookup("controller:post"); }, /controller:comments/); registry.register("controller:blog", Controller['default'].extend({ needs: ["posts", "comments"] })); throws(function () { container.lookup("controller:blog"); }, /controller:posts, controller:comments/); }); QUnit.test("Mixin sets up controllers if there is needs before calling super", function () { var registry = new system__container.Registry(); var container = registry.container(); registry.register("controller:other", ArrayController['default'].extend({ needs: "posts", model: computed.computed.alias("controllers.posts") })); registry.register("controller:another", ArrayController['default'].extend({ needs: "posts", modelBinding: "controllers.posts" })); registry.register("controller:posts", ArrayController['default'].extend()); container.lookup("controller:posts").set("model", native_array.A(["a", "b", "c"])); deepEqual(["a", "b", "c"], container.lookup("controller:other").toArray()); deepEqual(["a", "b", "c"], container.lookup("controller:another").toArray()); }); QUnit.test("raises if trying to get a controller that was not pre-defined in `needs`", function () { var registry = new system__container.Registry(); var container = registry.container(); registry.register("controller:foo", Controller['default'].extend()); registry.register("controller:bar", Controller['default'].extend({ needs: "foo" })); var fooController = container.lookup("controller:foo"); var barController = container.lookup("controller:bar"); throws(function () { fooController.get("controllers.bar"); }, /#needs does not include `bar`/, "throws if controllers is accesed but needs not defined"); equal(barController.get("controllers.foo"), fooController, "correctly needed controllers should continue to work"); throws(function () { barController.get("controllers.baz"); }, /#needs does not include `baz`/, "should throw if no such controller was needed"); }); QUnit.test("setting the value of a controller dependency should not be possible", function () { var registry = new system__container.Registry(); var container = registry.container(); registry.register("controller:post", Controller['default'].extend({ needs: "posts" })); registry.register("controller:posts", Controller['default'].extend()); var postController = container.lookup("controller:post"); container.lookup("controller:posts"); throws(function () { postController.set("controllers.posts", "epic-self-troll"); }, /You cannot overwrite the value of `controllers.posts` of .+/, "should raise when attempting to set the value of a controller dependency property"); postController.set("controllers.posts.title", "A Troll's Life"); equal(postController.get("controllers.posts.title"), "A Troll's Life", "can set the value of controllers.posts.title"); }); QUnit.test("raises if a dependency with a period is requested", function () { var registry = new system__container.Registry(); var container = registry.container(); registry.register("controller:big.bird", Controller['default'].extend()); registry.register("controller:foo", Controller['default'].extend({ needs: "big.bird" })); expectAssertion(function () { container.lookup("controller:foo"); }, /needs must not specify dependencies with periods in their names \(big\.bird\)/, "throws if periods used"); }); QUnit.test("can unit test controllers with `needs` dependencies by stubbing their `controllers` properties", function () { expect(1); var BrotherController = Controller['default'].extend({ needs: "sister", foo: computed.computed.alias("controllers.sister.foo") }); var broController = BrotherController.create({ controllers: { sister: { foo: 5 } } }); equal(broController.get("foo"), 5, "`needs` dependencies can be stubbed"); }); }); enifed('ember-application/tests/system/controller_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system"); test("ember-application/tests/system/controller_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/controller_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/controller_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system"); test("ember-application/tests/system/controller_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/controller_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/dependency_injection/custom_resolver_test', ['ember-views/system/jquery', 'ember-metal/run_loop', 'ember-application/system/application', 'ember-application/system/resolver'], function (jQuery, run, Application, DefaultResolver) { 'use strict'; var application; QUnit.module("Ember.Application Dependency Injection – customResolver", { setup: function () { function fallbackTemplate() { return "

Fallback

"; } var Resolver = DefaultResolver['default'].extend({ resolveTemplate: function (resolvable) { var resolvedTemplate = this._super(resolvable); if (resolvedTemplate) { return resolvedTemplate; } return fallbackTemplate; } }); application = run['default'](function () { return Application['default'].create({ Resolver: Resolver, rootElement: "#qunit-fixture" }); }); }, teardown: function () { run['default'](application, "destroy"); } }); QUnit.test("a resolver can be supplied to application", function () { equal(jQuery['default']("h1", application.rootElement).text(), "Fallback"); }); }); enifed('ember-application/tests/system/dependency_injection/custom_resolver_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system/dependency_injection"); test("ember-application/tests/system/dependency_injection/custom_resolver_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/dependency_injection/custom_resolver_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/dependency_injection/custom_resolver_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system/dependency_injection"); test("ember-application/tests/system/dependency_injection/custom_resolver_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/dependency_injection/custom_resolver_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/dependency_injection/default_resolver_test', ['ember-metal/core', 'ember-metal/run_loop', 'ember-metal/logger', 'ember-runtime/controllers/controller', 'ember-runtime/system/object', 'ember-runtime/system/namespace', 'ember-application/system/application', 'ember-htmlbars/helpers'], function (Ember, run, Logger, Controller, EmberObject, Namespace, Application, helpers) { 'use strict'; var registry, locator, application, originalLookup, originalLoggerInfo; QUnit.module("Ember.Application Dependency Injection - default resolver", { setup: function () { originalLookup = Ember['default'].lookup; application = run['default'](Application['default'], "create"); registry = application.registry; locator = application.__container__; originalLoggerInfo = Logger['default'].info; }, teardown: function () { Ember['default'].TEMPLATES = {}; Ember['default'].lookup = originalLookup; run['default'](application, "destroy"); var UserInterfaceNamespace = Namespace['default'].NAMESPACES_BY_ID["UserInterface"]; if (UserInterfaceNamespace) { run['default'](UserInterfaceNamespace, "destroy"); } Logger['default'].info = originalLoggerInfo; } }); QUnit.test("the default resolver can look things up in other namespaces", function () { var UserInterface = Ember['default'].lookup.UserInterface = Namespace['default'].create(); UserInterface.NavigationController = Controller['default'].extend(); var nav = locator.lookup("controller:userInterface/navigation"); ok(nav instanceof UserInterface.NavigationController, "the result should be an instance of the specified class"); }); QUnit.test("the default resolver looks up templates in Ember.TEMPLATES", function () { function fooTemplate() {} function fooBarTemplate() {} function fooBarBazTemplate() {} Ember['default'].TEMPLATES["foo"] = fooTemplate; Ember['default'].TEMPLATES["fooBar"] = fooBarTemplate; Ember['default'].TEMPLATES["fooBar/baz"] = fooBarBazTemplate; equal(locator.lookup("template:foo"), fooTemplate, "resolves template:foo"); equal(locator.lookup("template:fooBar"), fooBarTemplate, "resolves template:foo_bar"); equal(locator.lookup("template:fooBar.baz"), fooBarBazTemplate, "resolves template:foo_bar.baz"); }); QUnit.test("the default resolver looks up basic name as no prefix", function () { ok(Controller['default'].detect(locator.lookup("controller:basic")), "locator looksup correct controller"); }); function detectEqual(first, second, message) { ok(first.detect(second), message); } QUnit.test("the default resolver looks up arbitrary types on the namespace", function () { application.FooManager = EmberObject['default'].extend({}); detectEqual(application.FooManager, registry.resolver("manager:foo"), "looks up FooManager on application"); }); QUnit.test("the default resolver resolves models on the namespace", function () { application.Post = EmberObject['default'].extend({}); detectEqual(application.Post, locator.lookupFactory("model:post"), "looks up Post model on application"); }); QUnit.test("the default resolver resolves *:main on the namespace", function () { application.FooBar = EmberObject['default'].extend({}); detectEqual(application.FooBar, locator.lookupFactory("foo-bar:main"), "looks up FooBar type without name on application"); }); QUnit.test("the default resolver resolves helpers", function () { expect(2); function fooresolvertestHelper() { ok(true, "found fooresolvertestHelper"); } function barBazResolverTestHelper() { ok(true, "found barBazResolverTestHelper"); } helpers.registerHelper("fooresolvertest", fooresolvertestHelper); helpers.registerHelper("bar-baz-resolver-test", barBazResolverTestHelper); fooresolvertestHelper(); barBazResolverTestHelper(); }); QUnit.test("the default resolver resolves container-registered helpers", function () { function gooresolvertestHelper() { return "GOO"; } function gooGazResolverTestHelper() { return "GAZ"; } application.register("helper:gooresolvertest", gooresolvertestHelper); application.register("helper:goo-baz-resolver-test", gooGazResolverTestHelper); equal(gooresolvertestHelper, locator.lookup("helper:gooresolvertest"), "looks up gooresolvertest helper"); equal(gooGazResolverTestHelper, locator.lookup("helper:goo-baz-resolver-test"), "looks up gooGazResolverTestHelper helper"); }); QUnit.test("the default resolver throws an error if the fullName to resolve is invalid", function () { throws(function () { registry.resolve(undefined); }, TypeError, /Invalid fullName/); throws(function () { registry.resolve(null); }, TypeError, /Invalid fullName/); throws(function () { registry.resolve(""); }, TypeError, /Invalid fullName/); throws(function () { registry.resolve(""); }, TypeError, /Invalid fullName/); throws(function () { registry.resolve(":"); }, TypeError, /Invalid fullName/); throws(function () { registry.resolve("model"); }, TypeError, /Invalid fullName/); throws(function () { registry.resolve("model:"); }, TypeError, /Invalid fullName/); throws(function () { registry.resolve(":type"); }, TypeError, /Invalid fullName/); }); QUnit.test("the default resolver logs hits if `LOG_RESOLVER` is set", function () { expect(3); application.LOG_RESOLVER = true; application.ScoobyDoo = EmberObject['default'].extend(); application.toString = function () { return "App"; }; Logger['default'].info = function (symbol, name, padding, lookupDescription) { equal(symbol, "[✓]", "proper symbol is printed when a module is found"); equal(name, "doo:scooby", "proper lookup value is logged"); equal(lookupDescription, "App.ScoobyDoo"); }; registry.resolve("doo:scooby"); }); QUnit.test("the default resolver logs misses if `LOG_RESOLVER` is set", function () { expect(3); application.LOG_RESOLVER = true; application.toString = function () { return "App"; }; Logger['default'].info = function (symbol, name, padding, lookupDescription) { equal(symbol, "[ ]", "proper symbol is printed when a module is not found"); equal(name, "doo:scooby", "proper lookup value is logged"); equal(lookupDescription, "App.ScoobyDoo"); }; registry.resolve("doo:scooby"); }); QUnit.test("doesn't log without LOG_RESOLVER", function () { var infoCount = 0; application.ScoobyDoo = EmberObject['default'].extend(); Logger['default'].info = function (symbol, name) { infoCount = infoCount + 1; }; registry.resolve("doo:scooby"); registry.resolve("doo:scrappy"); equal(infoCount, 0, "Logger.info should not be called if LOG_RESOLVER is not set"); }); QUnit.test("lookup description", function () { application.toString = function () { return "App"; }; equal(registry.describe("controller:foo"), "App.FooController", "Type gets appended at the end"); equal(registry.describe("controller:foo.bar"), "App.FooBarController", "dots are removed"); equal(registry.describe("model:foo"), "App.Foo", "models don't get appended at the end"); }); }); enifed('ember-application/tests/system/dependency_injection/default_resolver_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system/dependency_injection"); test("ember-application/tests/system/dependency_injection/default_resolver_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/dependency_injection/default_resolver_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/dependency_injection/default_resolver_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system/dependency_injection"); test("ember-application/tests/system/dependency_injection/default_resolver_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/dependency_injection/default_resolver_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/dependency_injection/normalization_test', ['ember-metal/run_loop', 'ember-metal/array', 'ember-application/system/application'], function (run, array, Application) { 'use strict'; var application, registry; QUnit.module("Ember.Application Dependency Injection – normalization", { setup: function () { application = run['default'](Application['default'], "create"); registry = application.registry; }, teardown: function () { run['default'](application, "destroy"); } }); QUnit.test("normalization", function () { ok(registry.normalize, "registry#normalize is present"); equal(registry.normalize("foo:bar"), "foo:bar"); equal(registry.normalize("controller:posts"), "controller:posts"); equal(registry.normalize("controller:posts_index"), "controller:postsIndex"); equal(registry.normalize("controller:posts.index"), "controller:postsIndex"); equal(registry.normalize("controller:posts.post.index"), "controller:postsPostIndex"); equal(registry.normalize("controller:posts_post.index"), "controller:postsPostIndex"); equal(registry.normalize("controller:posts.post_index"), "controller:postsPostIndex"); equal(registry.normalize("controller:postsIndex"), "controller:postsIndex"); equal(registry.normalize("controller:blogPosts.index"), "controller:blogPostsIndex"); equal(registry.normalize("controller:blog/posts.index"), "controller:blog/postsIndex"); equal(registry.normalize("controller:blog/posts.post.index"), "controller:blog/postsPostIndex"); equal(registry.normalize("controller:blog/posts_post.index"), "controller:blog/postsPostIndex"); equal(registry.normalize("template:blog/posts_index"), "template:blog/posts_index"); }); QUnit.test("normalization is indempotent", function () { var examples = ["controller:posts", "controller:posts.post.index", "controller:blog/posts.post_index", "template:foo_bar"]; array.forEach.call(examples, function (example) { equal(registry.normalize(registry.normalize(example)), registry.normalize(example)); }); }); }); enifed('ember-application/tests/system/dependency_injection/normalization_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system/dependency_injection"); test("ember-application/tests/system/dependency_injection/normalization_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/dependency_injection/normalization_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/dependency_injection/normalization_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system/dependency_injection"); test("ember-application/tests/system/dependency_injection/normalization_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/dependency_injection/normalization_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/dependency_injection/to_string_test', ['ember-metal/core', 'ember-metal/run_loop', 'ember-application/system/application', 'ember-runtime/system/object', 'ember-application/system/resolver', 'ember-metal/utils'], function (Ember, run, Application, EmberObject, DefaultResolver, utils) { 'use strict'; var originalLookup, App, originalModelInjections; QUnit.module("Ember.Application Dependency Injection – toString", { setup: function () { originalModelInjections = Ember['default'].MODEL_FACTORY_INJECTIONS; Ember['default'].MODEL_FACTORY_INJECTIONS = true; originalLookup = Ember['default'].lookup; run['default'](function () { App = Application['default'].create(); Ember['default'].lookup = { App: App }; }); App.Post = EmberObject['default'].extend(); }, teardown: function () { Ember['default'].lookup = originalLookup; run['default'](App, "destroy"); Ember['default'].MODEL_FACTORY_INJECTIONS = originalModelInjections; } }); QUnit.test("factories", function () { var PostFactory = App.__container__.lookupFactory("model:post"); equal(PostFactory.toString(), "App.Post", "expecting the model to be post"); }); QUnit.test("instances", function () { var post = App.__container__.lookup("model:post"); var guid = utils.guidFor(post); equal(post.toString(), "", "expecting the model to be post"); }); QUnit.test("with a custom resolver", function () { run['default'](App, "destroy"); run['default'](function () { App = Application['default'].create({ Resolver: DefaultResolver['default'].extend({ makeToString: function (factory, fullName) { return fullName; } }) }); }); App.registry.register("model:peter", EmberObject['default'].extend()); var peter = App.__container__.lookup("model:peter"); var guid = utils.guidFor(peter); equal(peter.toString(), "", "expecting the supermodel to be peter"); }); }); enifed('ember-application/tests/system/dependency_injection/to_string_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system/dependency_injection"); test("ember-application/tests/system/dependency_injection/to_string_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/dependency_injection/to_string_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/dependency_injection/to_string_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system/dependency_injection"); test("ember-application/tests/system/dependency_injection/to_string_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/dependency_injection/to_string_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/dependency_injection_test', ['ember-metal/run_loop', 'ember-runtime/system/object', 'ember-application/system/application'], function (run, EmberObject, Application) { 'use strict'; var EmberApplication = Application['default']; var originalLookup = Ember.lookup; var registry, locator, lookup, application, originalModelInjections; QUnit.module("Ember.Application Dependency Injection", { setup: function () { originalModelInjections = Ember.MODEL_FACTORY_INJECTIONS; Ember.MODEL_FACTORY_INJECTIONS = true; application = run['default'](EmberApplication, "create"); application.Person = EmberObject['default'].extend({}); application.Orange = EmberObject['default'].extend({}); application.Email = EmberObject['default'].extend({}); application.User = EmberObject['default'].extend({}); application.PostIndexController = EmberObject['default'].extend({}); application.register("model:person", application.Person, { singleton: false }); application.register("model:user", application.User, { singleton: false }); application.register("fruit:favorite", application.Orange); application.register("communication:main", application.Email, { singleton: false }); application.register("controller:postIndex", application.PostIndexController, { singleton: true }); registry = application.registry; locator = application.__container__; lookup = Ember.lookup = {}; }, teardown: function () { run['default'](application, "destroy"); application = locator = null; Ember.lookup = originalLookup; Ember.MODEL_FACTORY_INJECTIONS = originalModelInjections; } }); QUnit.test("container lookup is normalized", function () { var dotNotationController = locator.lookup("controller:post.index"); var camelCaseController = locator.lookup("controller:postIndex"); ok(dotNotationController instanceof application.PostIndexController); ok(camelCaseController instanceof application.PostIndexController); equal(dotNotationController, camelCaseController); }); QUnit.test("registered entities can be looked up later", function () { equal(registry.resolve("model:person"), application.Person); equal(registry.resolve("model:user"), application.User); equal(registry.resolve("fruit:favorite"), application.Orange); equal(registry.resolve("communication:main"), application.Email); equal(registry.resolve("controller:postIndex"), application.PostIndexController); equal(locator.lookup("fruit:favorite"), locator.lookup("fruit:favorite"), "singleton lookup worked"); ok(locator.lookup("model:user") !== locator.lookup("model:user"), "non-singleton lookup worked"); }); QUnit.test("injections", function () { application.inject("model", "fruit", "fruit:favorite"); application.inject("model:user", "communication", "communication:main"); var user = locator.lookup("model:user"); var person = locator.lookup("model:person"); var fruit = locator.lookup("fruit:favorite"); equal(user.get("fruit"), fruit); equal(person.get("fruit"), fruit); ok(application.Email.detectInstance(user.get("communication"))); }); }); enifed('ember-application/tests/system/dependency_injection_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system"); test("ember-application/tests/system/dependency_injection_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/dependency_injection_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/dependency_injection_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system"); test("ember-application/tests/system/dependency_injection_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/dependency_injection_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/initializers_test', ['ember-metal/run_loop', 'ember-application/system/application', 'ember-metal/array', 'ember-views/system/jquery', 'container/registry'], function (run, Application, array, jQuery, Registry) { 'use strict'; var app; QUnit.module("Ember.Application initializers", { setup: function () {}, teardown: function () { if (app) { run['default'](function () { app.destroy(); }); } } }); QUnit.test("initializers require proper 'name' and 'initialize' properties", function () { var MyApplication = Application['default'].extend(); expectAssertion(function () { run['default'](function () { MyApplication.initializer({ name: "initializer" }); }); }); expectAssertion(function () { run['default'](function () { MyApplication.initializer({ initialize: Ember.K }); }); }); }); QUnit.test("initializers are passed a registry and App", function () { var MyApplication = Application['default'].extend(); MyApplication.initializer({ name: "initializer", initialize: function (registry, App) { ok(registry instanceof Registry['default'], "initialize is passed a registry"); ok(App instanceof Application['default'], "initialize is passed an Application"); } }); run['default'](function () { app = MyApplication.create({ router: false, rootElement: "#qunit-fixture" }); }); }); QUnit.test("initializers can be registered in a specified order", function () { var order = []; var MyApplication = Application['default'].extend(); MyApplication.initializer({ name: "fourth", after: "third", initialize: function (registry) { order.push("fourth"); } }); MyApplication.initializer({ name: "second", after: "first", before: "third", initialize: function (registry) { order.push("second"); } }); MyApplication.initializer({ name: "fifth", after: "fourth", before: "sixth", initialize: function (registry) { order.push("fifth"); } }); MyApplication.initializer({ name: "first", before: "second", initialize: function (registry) { order.push("first"); } }); MyApplication.initializer({ name: "third", initialize: function (registry) { order.push("third"); } }); MyApplication.initializer({ name: "sixth", initialize: function (registry) { order.push("sixth"); } }); run['default'](function () { app = MyApplication.create({ router: false, rootElement: "#qunit-fixture" }); }); deepEqual(order, ["first", "second", "third", "fourth", "fifth", "sixth"]); }); QUnit.test("initializers can be registered in a specified order as an array", function () { var order = []; var MyApplication = Application['default'].extend(); MyApplication.initializer({ name: "third", initialize: function (registry) { order.push("third"); } }); MyApplication.initializer({ name: "second", after: "first", before: ["third", "fourth"], initialize: function (registry) { order.push("second"); } }); MyApplication.initializer({ name: "fourth", after: ["second", "third"], initialize: function (registry) { order.push("fourth"); } }); MyApplication.initializer({ name: "fifth", after: "fourth", before: "sixth", initialize: function (registry) { order.push("fifth"); } }); MyApplication.initializer({ name: "first", before: ["second"], initialize: function (registry) { order.push("first"); } }); MyApplication.initializer({ name: "sixth", initialize: function (registry) { order.push("sixth"); } }); run['default'](function () { app = MyApplication.create({ router: false, rootElement: "#qunit-fixture" }); }); deepEqual(order, ["first", "second", "third", "fourth", "fifth", "sixth"]); }); QUnit.test("initializers can have multiple dependencies", function () { var order = []; var a = { name: "a", before: "b", initialize: function (registry) { order.push("a"); } }; var b = { name: "b", initialize: function (registry) { order.push("b"); } }; var c = { name: "c", after: "b", initialize: function (registry) { order.push("c"); } }; var afterB = { name: "after b", after: "b", initialize: function (registry) { order.push("after b"); } }; var afterC = { name: "after c", after: "c", initialize: function (registry) { order.push("after c"); } }; Application['default'].initializer(b); Application['default'].initializer(a); Application['default'].initializer(afterC); Application['default'].initializer(afterB); Application['default'].initializer(c); run['default'](function () { app = Application['default'].create({ router: false, rootElement: "#qunit-fixture" }); }); ok(array.indexOf.call(order, a.name) < array.indexOf.call(order, b.name), "a < b"); ok(array.indexOf.call(order, b.name) < array.indexOf.call(order, c.name), "b < c"); ok(array.indexOf.call(order, b.name) < array.indexOf.call(order, afterB.name), "b < afterB"); ok(array.indexOf.call(order, c.name) < array.indexOf.call(order, afterC.name), "c < afterC"); }); QUnit.test("initializers set on Application subclasses should not be shared between apps", function () { var firstInitializerRunCount = 0; var secondInitializerRunCount = 0; var FirstApp = Application['default'].extend(); FirstApp.initializer({ name: "first", initialize: function (registry) { firstInitializerRunCount++; } }); var SecondApp = Application['default'].extend(); SecondApp.initializer({ name: "second", initialize: function (registry) { secondInitializerRunCount++; } }); jQuery['default']("#qunit-fixture").html("
"); run['default'](function () { FirstApp.create({ router: false, rootElement: "#qunit-fixture #first" }); }); equal(firstInitializerRunCount, 1, "first initializer only was run"); equal(secondInitializerRunCount, 0, "first initializer only was run"); run['default'](function () { SecondApp.create({ router: false, rootElement: "#qunit-fixture #second" }); }); equal(firstInitializerRunCount, 1, "second initializer only was run"); equal(secondInitializerRunCount, 1, "second initializer only was run"); }); QUnit.test("initializers are concatenated", function () { var firstInitializerRunCount = 0; var secondInitializerRunCount = 0; var FirstApp = Application['default'].extend(); FirstApp.initializer({ name: "first", initialize: function (registry) { firstInitializerRunCount++; } }); var SecondApp = FirstApp.extend(); SecondApp.initializer({ name: "second", initialize: function (registry) { secondInitializerRunCount++; } }); jQuery['default']("#qunit-fixture").html("
"); run['default'](function () { FirstApp.create({ router: false, rootElement: "#qunit-fixture #first" }); }); equal(firstInitializerRunCount, 1, "first initializer only was run when base class created"); equal(secondInitializerRunCount, 0, "first initializer only was run when base class created"); firstInitializerRunCount = 0; run['default'](function () { SecondApp.create({ router: false, rootElement: "#qunit-fixture #second" }); }); equal(firstInitializerRunCount, 1, "first initializer was run when subclass created"); equal(secondInitializerRunCount, 1, "second initializers was run when subclass created"); }); QUnit.test("initializers are per-app", function () { expect(0); var FirstApp = Application['default'].extend(); FirstApp.initializer({ name: "shouldNotCollide", initialize: function (registry) {} }); var SecondApp = Application['default'].extend(); SecondApp.initializer({ name: "shouldNotCollide", initialize: function (registry) {} }); }); }); enifed('ember-application/tests/system/initializers_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system"); test("ember-application/tests/system/initializers_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/initializers_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/initializers_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system"); test("ember-application/tests/system/initializers_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/initializers_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/instance_initializers_test', ['ember-metal/run_loop', 'ember-application/system/application', 'ember-application/system/application-instance', 'ember-metal/array', 'ember-views/system/jquery'], function (run, Application, ApplicationInstance, array, jQuery) { 'use strict'; var app, initializeContextFeatureEnabled; }); enifed('ember-application/tests/system/instance_initializers_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system"); test("ember-application/tests/system/instance_initializers_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/instance_initializers_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/instance_initializers_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system"); test("ember-application/tests/system/instance_initializers_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/instance_initializers_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/logging_test', ['ember-metal/run_loop', 'ember-application/system/application', 'ember-views/views/view', 'ember-runtime/controllers/controller', 'ember-routing/system/route', 'ember-runtime/ext/rsvp', 'ember-metal/keys', 'ember-template-compiler/system/compile', 'ember-routing'], function (run, Application, View, Controller, Route, RSVP, keys, compile) { 'use strict'; /*globals EmberDev */ var App, logs, originalLogger; QUnit.module("Ember.Application – logging of generated classes", { setup: function () { logs = {}; originalLogger = Ember.Logger.info; Ember.Logger.info = function () { var fullName = arguments[1].fullName; logs[fullName] = logs[fullName] || 0; logs[fullName]++; }; run['default'](function () { App = Application['default'].create({ LOG_ACTIVE_GENERATION: true }); App.Router.reopen({ location: "none" }); App.Router.map(function () { this.resource("posts"); }); App.deferReadiness(); }); }, teardown: function () { Ember.Logger.info = originalLogger; run['default'](App, "destroy"); logs = App = null; } }); function visit(path) { QUnit.stop(); var promise = run['default'](function () { return new RSVP['default'].Promise(function (resolve, reject) { var router = App.__container__.lookup("router:main"); resolve(router.handleURL(path).then(function (value) { QUnit.start(); ok(true, "visited: `" + path + "`"); return value; }, function (reason) { QUnit.start(); ok(false, "failed to visit:`" + path + "` reason: `" + QUnit.jsDump.parse(reason)); throw reason; })); }); }); return { then: function (resolve, reject) { run['default'](promise, "then", resolve, reject); } }; } QUnit.test("log class generation if logging enabled", function () { if (EmberDev && EmberDev.runningProdBuild) { ok(true, "Logging does not occur in production builds"); return; } run['default'](App, "advanceReadiness"); visit("/posts").then(function () { equal(Ember.keys(logs).length, 6, "expected logs"); }); }); QUnit.test("do NOT log class generation if logging disabled", function () { App.reopen({ LOG_ACTIVE_GENERATION: false }); run['default'](App, "advanceReadiness"); visit("/posts").then(function () { equal(keys['default'](logs).length, 0, "expected no logs"); }); }); QUnit.test("actively generated classes get logged", function () { if (EmberDev && EmberDev.runningProdBuild) { ok(true, "Logging does not occur in production builds"); return; } run['default'](App, "advanceReadiness"); visit("/posts").then(function () { equal(logs["controller:application"], 1, "expected: ApplicationController was generated"); equal(logs["controller:posts"], 1, "expected: PostsController was generated"); equal(logs["route:application"], 1, "expected: ApplicationRoute was generated"); equal(logs["route:posts"], 1, "expected: PostsRoute was generated"); }); }); QUnit.test("predefined classes do not get logged", function () { App.ApplicationController = Controller['default'].extend(); App.PostsController = Controller['default'].extend(); App.ApplicationRoute = Route['default'].extend(); App.PostsRoute = Route['default'].extend(); run['default'](App, "advanceReadiness"); visit("/posts").then(function () { ok(!logs["controller:application"], "did not expect: ApplicationController was generated"); ok(!logs["controller:posts"], "did not expect: PostsController was generated"); ok(!logs["route:application"], "did not expect: ApplicationRoute was generated"); ok(!logs["route:posts"], "did not expect: PostsRoute was generated"); }); }); QUnit.module("Ember.Application – logging of view lookups", { setup: function () { logs = {}; originalLogger = Ember.Logger.info; Ember.Logger.info = function () { var fullName = arguments[1].fullName; logs[fullName] = logs[fullName] || 0; logs[fullName]++; }; run['default'](function () { App = Application['default'].create({ LOG_VIEW_LOOKUPS: true }); App.Router.reopen({ location: "none" }); App.Router.map(function () { this.resource("posts"); }); App.deferReadiness(); }); }, teardown: function () { Ember.Logger.info = originalLogger; run['default'](App, "destroy"); logs = App = null; } }); QUnit.test("log when template and view are missing when flag is active", function () { if (EmberDev && EmberDev.runningProdBuild) { ok(true, "Logging does not occur in production builds"); return; } App.register("template:application", compile['default']("{{outlet}}")); run['default'](App, "advanceReadiness"); visit("/posts").then(function () { equal(logs["template:application"], undefined, "expected: Should not log template:application since it exists."); equal(logs["template:index"], 1, "expected: Could not find \"index\" template or view."); equal(logs["template:posts"], 1, "expected: Could not find \"posts\" template or view."); }); }); QUnit.test("do not log when template and view are missing when flag is not true", function () { App.reopen({ LOG_VIEW_LOOKUPS: false }); run['default'](App, "advanceReadiness"); visit("/posts").then(function () { equal(keys['default'](logs).length, 0, "expected no logs"); }); }); QUnit.test("log which view is used with a template", function () { if (EmberDev && EmberDev.runningProdBuild) { ok(true, "Logging does not occur in production builds"); return; } App.register("template:application", compile['default']("{{outlet}}")); App.register("template:foo", function () { return "Template with custom view"; }); App.register("view:posts", View['default'].extend({ templateName: "foo" })); run['default'](App, "advanceReadiness"); visit("/posts").then(function () { equal(logs["view:application"], 1, "expected: Should log use of default view"); equal(logs["view:index"], undefined, "expected: Should not log when index is not present."); equal(logs["view:posts"], 1, "expected: Rendering posts with PostsView."); }); }); QUnit.test("do not log which views are used with templates when flag is not true", function () { App.reopen({ LOG_VIEW_LOOKUPS: false }); run['default'](App, "advanceReadiness"); visit("/posts").then(function () { equal(keys['default'](logs).length, 0, "expected no logs"); }); }); }); enifed('ember-application/tests/system/logging_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system"); test("ember-application/tests/system/logging_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/logging_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/logging_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system"); test("ember-application/tests/system/logging_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/logging_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/readiness_test', ['ember-metal/run_loop', 'ember-application/system/application'], function (run, EmberApplication) { 'use strict'; var jQuery, application, Application; var readyWasCalled, domReady, readyCallbacks; // We are using a small mock of jQuery because jQuery is third-party code with // very well-defined semantics, and we want to confirm that a jQuery stub run // in a more minimal server environment that implements this behavior will be // sufficient for Ember's requirements. QUnit.module("Application readiness", { setup: function () { readyWasCalled = 0; readyCallbacks = []; var jQueryInstance = { ready: function (callback) { readyCallbacks.push(callback); if (jQuery.isReady) { domReady(); } } }; jQuery = function () { return jQueryInstance; }; jQuery.isReady = false; var domReadyCalled = 0; domReady = function () { if (domReadyCalled !== 0) { return; } domReadyCalled++; var i; for (i = 0; i < readyCallbacks.length; i++) { readyCallbacks[i](); } }; Application = EmberApplication['default'].extend({ $: jQuery, ready: function () { readyWasCalled++; } }); }, teardown: function () { if (application) { run['default'](function () { application.destroy(); }); } } }); // These tests are confirming that if the callbacks passed into jQuery's ready hook is called // synchronously during the application's initialization, we get the same behavior as if // it was triggered after initialization. QUnit.test("Ember.Application's ready event is called right away if jQuery is already ready", function () { jQuery.isReady = true; run['default'](function () { application = Application.create({ router: false }); equal(readyWasCalled, 0, "ready is not called until later"); }); equal(readyWasCalled, 1, "ready was called"); domReady(); equal(readyWasCalled, 1, "application's ready was not called again"); }); QUnit.test("Ember.Application's ready event is called after the document becomes ready", function () { run['default'](function () { application = Application.create({ router: false }); }); equal(readyWasCalled, 0, "ready wasn't called yet"); domReady(); equal(readyWasCalled, 1, "ready was called now that DOM is ready"); }); QUnit.test("Ember.Application's ready event can be deferred by other components", function () { run['default'](function () { application = Application.create({ router: false }); application.deferReadiness(); }); equal(readyWasCalled, 0, "ready wasn't called yet"); domReady(); equal(readyWasCalled, 0, "ready wasn't called yet"); run['default'](function () { application.advanceReadiness(); equal(readyWasCalled, 0); }); equal(readyWasCalled, 1, "ready was called now all readiness deferrals are advanced"); }); QUnit.test("Ember.Application's ready event can be deferred by other components", function () { jQuery.isReady = false; run['default'](function () { application = Application.create({ router: false }); application.deferReadiness(); equal(readyWasCalled, 0, "ready wasn't called yet"); }); domReady(); equal(readyWasCalled, 0, "ready wasn't called yet"); run['default'](function () { application.advanceReadiness(); }); equal(readyWasCalled, 1, "ready was called now all readiness deferrals are advanced"); expectAssertion(function () { application.deferReadiness(); }); }); }); enifed('ember-application/tests/system/readiness_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system"); test("ember-application/tests/system/readiness_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/readiness_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/readiness_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system"); test("ember-application/tests/system/readiness_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/readiness_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/reset_test', ['ember-metal/run_loop', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-application/system/application', 'ember-runtime/system/object', 'ember-routing/system/router', 'ember-views/views/view', 'ember-runtime/controllers/controller', 'ember-views/system/jquery', 'container/registry'], function (run, property_get, property_set, EmberApplication, EmberObject, Router, View, Controller, jQuery, Registry) { 'use strict'; var application, Application; QUnit.module("Ember.Application - resetting", { setup: function () { Application = EmberApplication['default'].extend({ name: "App", rootElement: "#qunit-fixture" }); }, teardown: function () { Application = null; if (application) { run['default'](application, "destroy"); } } }); QUnit.test("Brings its own run-loop if not provided", function () { application = run['default'](Application, "create"); application.ready = function () { QUnit.start(); ok(true, "app booted"); }; QUnit.stop(); application.reset(); }); QUnit.test("does not bring its own run loop if one is already provided", function () { expect(3); var didBecomeReady = false; application = run['default'](Application, "create"); run['default'](function () { application.ready = function () { didBecomeReady = true; }; application.reset(); application.deferReadiness(); ok(!didBecomeReady, "app is not ready"); }); ok(!didBecomeReady, "app is not ready"); run['default'](application, "advanceReadiness"); ok(didBecomeReady, "app is ready"); }); QUnit.test("When an application is reset, new instances of controllers are generated", function () { run['default'](function () { application = Application.create(); application.AcademicController = Controller['default'].extend(); }); var firstController = application.__container__.lookup("controller:academic"); var secondController = application.__container__.lookup("controller:academic"); application.reset(); var thirdController = application.__container__.lookup("controller:academic"); strictEqual(firstController, secondController, "controllers looked up in succession should be the same instance"); ok(firstController.isDestroying, "controllers are destroyed when their application is reset"); notStrictEqual(firstController, thirdController, "controllers looked up after the application is reset should not be the same instance"); }); QUnit.test("When an application is reset, the eventDispatcher is destroyed and recreated", function () { var eventDispatcherWasSetup, eventDispatcherWasDestroyed; eventDispatcherWasSetup = 0; eventDispatcherWasDestroyed = 0; var mock_event_dispatcher = { create: function () { return { setup: function () { eventDispatcherWasSetup++; }, destroy: function () { eventDispatcherWasDestroyed++; } }; } }; // this is pretty awful. We should make this less Global-ly. var originalRegister = Registry['default'].prototype.register; Registry['default'].prototype.register = function (name, type, options) { if (name === "event_dispatcher:main") { return mock_event_dispatcher; } else { return originalRegister.call(this, name, type, options); } }; try { run['default'](function () { application = Application.create(); equal(eventDispatcherWasSetup, 0); equal(eventDispatcherWasDestroyed, 0); }); equal(eventDispatcherWasSetup, 1); equal(eventDispatcherWasDestroyed, 0); application.reset(); equal(eventDispatcherWasDestroyed, 1); equal(eventDispatcherWasSetup, 2, "setup called after reset"); } catch (error) { Registry['default'].prototype.register = originalRegister; } Registry['default'].prototype.register = originalRegister; }); QUnit.test("When an application is reset, the ApplicationView is torn down", function () { run['default'](function () { application = Application.create(); application.ApplicationView = View['default'].extend({ elementId: "application-view" }); }); equal(jQuery['default']("#qunit-fixture #application-view").length, 1, "precond - the application view is rendered"); var originalView = View['default'].views["application-view"]; application.reset(); var resettedView = View['default'].views["application-view"]; equal(jQuery['default']("#qunit-fixture #application-view").length, 1, "the application view is rendered"); notStrictEqual(originalView, resettedView, "The view object has changed"); }); QUnit.test("When an application is reset, the router URL is reset to `/`", function () { var location, router; run['default'](function () { application = Application.create(); application.Router = Router['default'].extend({ location: "none" }); application.Router.map(function () { this.route("one"); this.route("two"); }); }); router = application.__container__.lookup("router:main"); location = router.get("location"); run['default'](function () { location.handleURL("/one"); }); application.reset(); var applicationController = application.__container__.lookup("controller:application"); router = application.__container__.lookup("router:main"); location = router.get("location"); equal(location.getURL(), ""); equal(property_get.get(applicationController, "currentPath"), "index"); location = application.__container__.lookup("router:main").get("location"); run['default'](function () { location.handleURL("/one"); }); equal(property_get.get(applicationController, "currentPath"), "one"); }); QUnit.test("When an application with advance/deferReadiness is reset, the app does correctly become ready after reset", function () { var readyCallCount; readyCallCount = 0; run['default'](function () { application = Application.create({ ready: function () { readyCallCount++; } }); application.deferReadiness(); equal(readyCallCount, 0, "ready has not yet been called"); }); run['default'](function () { application.advanceReadiness(); }); equal(readyCallCount, 1, "ready was called once"); application.reset(); equal(readyCallCount, 2, "ready was called twice"); }); QUnit.test("With ember-data like initializer and constant", function () { var readyCallCount; readyCallCount = 0; var DS = { Store: EmberObject['default'].extend({ init: function () { if (!property_get.get(DS, "defaultStore")) { property_set.set(DS, "defaultStore", this); } this._super.apply(this, arguments); }, willDestroy: function () { if (property_get.get(DS, "defaultStore") === this) { property_set.set(DS, "defaultStore", null); } } }) }; Application.initializer({ name: "store", initialize: function (registry, application) { registry.unregister("store:main"); registry.register("store:main", application.Store); application.__container__.lookup("store:main"); } }); run['default'](function () { application = Application.create(); application.Store = DS.Store; }); ok(DS.defaultStore, "has defaultStore"); application.reset(); ok(DS.defaultStore, "still has defaultStore"); ok(application.__container__.lookup("store:main"), "store is still present"); }); QUnit.test("Ensure that the hashchange event listener is removed", function () { var listeners; jQuery['default'](window).off("hashchange"); // ensure that any previous listeners are cleared run['default'](function () { application = Application.create(); }); listeners = jQuery['default']._data(jQuery['default'](window)[0], "events"); equal(listeners["hashchange"].length, 1, "hashchange event listener was setup"); application.reset(); listeners = jQuery['default']._data(jQuery['default'](window)[0], "events"); equal(listeners["hashchange"].length, 1, "hashchange event only exists once"); }); }); enifed('ember-application/tests/system/reset_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system"); test("ember-application/tests/system/reset_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/reset_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/reset_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system"); test("ember-application/tests/system/reset_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/reset_test.js should pass jshint."); }); }); enifed('ember-application/tests/system/visit_test', ['ember-metal/run_loop', 'ember-application/system/application', 'ember-application/system/application-instance', 'ember-routing/system/router', 'ember-template-compiler/system/compile'], function (run, Application, ApplicationInstance, Router, compile) { 'use strict'; function createApplication() { var App = Application['default'].extend().create({ autoboot: false, LOG_TRANSITIONS: true, LOG_TRANSITIONS_INTERNAL: true, LOG_ACTIVE_GENERATION: true }); App.Router = Router['default'].extend(); return App; } }); enifed('ember-application/tests/system/visit_test.jscs-test', function () { 'use strict'; module("JSCS - ember-application/tests/system"); test("ember-application/tests/system/visit_test.js should pass jscs", function () { ok(true, "ember-application/tests/system/visit_test.js should pass jscs."); }); }); enifed('ember-application/tests/system/visit_test.jshint', function () { 'use strict'; module("JSHint - ember-application/tests/system"); test("ember-application/tests/system/visit_test.js should pass jshint", function () { ok(true, "ember-application/tests/system/visit_test.js should pass jshint."); }); }); enifed('ember-debug.jscs-test', function () { 'use strict'; module("JSCS - ."); test("ember-debug.js should pass jscs", function () { ok(true, "ember-debug.js should pass jscs."); }); }); enifed('ember-debug.jshint', function () { 'use strict'; module("JSHint - ."); test("ember-debug.js should pass jshint", function () { ok(true, "ember-debug.js should pass jshint."); }); }); enifed('ember-debug/tests/main_test', ['ember-metal/core'], function (Ember) { 'use strict'; QUnit.module("ember-debug"); QUnit.test("Ember.deprecate throws deprecation with one argument", function () { expect(1); throws(function () { Ember['default'].deprecate("Deprecation is thrown"); }); }); QUnit.test("Ember.deprecate throws deprecation if second argument is falsy", function () { expect(3); throws(function () { Ember['default'].deprecate("Deprecation is thrown", false); }); throws(function () { Ember['default'].deprecate("Deprecation is thrown", ""); }); throws(function () { Ember['default'].deprecate("Deprecation is thrown", 0); }); }); QUnit.test("Ember.deprecate does not throw deprecation if second argument is a function and it returns true", function () { expect(1); Ember['default'].deprecate("Deprecation is thrown", function () { return true; }); ok(true, "deprecation was not thrown"); }); QUnit.test("Ember.deprecate throws if second argument is a function and it returns false", function () { expect(1); throws(function () { Ember['default'].deprecate("Deprecation is thrown", function () { return false; }); }); }); QUnit.test("Ember.deprecate does not throw deprecations if second argument is truthy", function () { expect(1); Ember['default'].deprecate("Deprecation is thrown", true); Ember['default'].deprecate("Deprecation is thrown", "1"); Ember['default'].deprecate("Deprecation is thrown", 1); ok(true, "deprecations were not thrown"); }); QUnit.test("Ember.assert throws if second argument is falsy", function () { expect(3); throws(function () { Ember['default'].assert("Assertion is thrown", false); }); throws(function () { Ember['default'].assert("Assertion is thrown", ""); }); throws(function () { Ember['default'].assert("Assertion is thrown", 0); }); }); QUnit.test("Ember.assert does not throw if second argument is a function and it returns true", function () { expect(1); Ember['default'].assert("Assertion is thrown", function () { return true; }); ok(true, "assertion was not thrown"); }); QUnit.test("Ember.assert throws if second argument is a function and it returns false", function () { expect(1); throws(function () { Ember['default'].assert("Assertion is thrown", function () { return false; }); }); }); QUnit.test("Ember.assert does not throw if second argument is truthy", function () { expect(1); Ember['default'].assert("Assertion is thrown", true); Ember['default'].assert("Assertion is thrown", "1"); Ember['default'].assert("Assertion is thrown", 1); ok(true, "assertions were not thrown"); }); QUnit.test("Ember.assert does not throw if second argument is an object", function () { expect(1); var Igor = Ember['default'].Object.extend(); Ember['default'].assert("is truthy", Igor); Ember['default'].assert("is truthy", Igor.create()); ok(true, "assertions were not thrown"); }); }); enifed('ember-debug/tests/main_test.jscs-test', function () { 'use strict'; module("JSCS - ember-debug/tests"); test("ember-debug/tests/main_test.js should pass jscs", function () { ok(true, "ember-debug/tests/main_test.js should pass jscs."); }); }); enifed('ember-debug/tests/main_test.jshint', function () { 'use strict'; module("JSHint - ember-debug/tests"); test("ember-debug/tests/main_test.js should pass jshint", function () { ok(true, "ember-debug/tests/main_test.js should pass jshint."); }); }); enifed('ember-debug/tests/warn_if_using_stripped_feature_flags_test', ['ember-metal/core', 'ember-debug'], function (Ember, ember_debug) { 'use strict'; var oldWarn, oldRunInDebug, origEnvFeatures, origEnableAll, origEnableOptional; function confirmWarns(expectedMsg) { var featuresWereStripped = true; var FEATURES = Ember['default'].ENV.FEATURES; Ember['default'].warn = function (msg, test) { if (!test) { equal(msg, expectedMsg); } }; Ember['default'].runInDebug = function (func) { func(); }; // Should trigger our 1 warning ember_debug._warnIfUsingStrippedFeatureFlags(FEATURES, featuresWereStripped); // Shouldn't trigger any warnings now that we're "in canary" featuresWereStripped = false; ember_debug._warnIfUsingStrippedFeatureFlags(FEATURES, featuresWereStripped); } QUnit.module("ember-debug - _warnIfUsingStrippedFeatureFlags", { setup: function () { oldWarn = Ember['default'].warn; oldRunInDebug = Ember['default'].runInDebug; origEnvFeatures = Ember['default'].ENV.FEATURES; origEnableAll = Ember['default'].ENV.ENABLE_ALL_FEATURES; origEnableOptional = Ember['default'].ENV.ENABLE_OPTIONAL_FEATURES; }, teardown: function () { Ember['default'].warn = oldWarn; Ember['default'].runInDebug = oldRunInDebug; Ember['default'].ENV.FEATURES = origEnvFeatures; Ember['default'].ENV.ENABLE_ALL_FEATURES = origEnableAll; Ember['default'].ENV.ENABLE_OPTIONAL_FEATURES = origEnableOptional; } }); QUnit.test("Setting Ember.ENV.ENABLE_ALL_FEATURES truthy in non-canary, debug build causes a warning", function () { expect(1); Ember['default'].ENV.ENABLE_ALL_FEATURES = true; Ember['default'].ENV.ENABLE_OPTIONAL_FEATURES = false; Ember['default'].ENV.FEATURES = {}; confirmWarns("Ember.ENV.ENABLE_ALL_FEATURES is only available in canary builds."); }); QUnit.test("Setting Ember.ENV.ENABLE_OPTIONAL_FEATURES truthy in non-canary, debug build causes a warning", function () { expect(1); Ember['default'].ENV.ENABLE_ALL_FEATURES = false; Ember['default'].ENV.ENABLE_OPTIONAL_FEATURES = true; Ember['default'].ENV.FEATURES = {}; confirmWarns("Ember.ENV.ENABLE_OPTIONAL_FEATURES is only available in canary builds."); }); QUnit.test("Enabling a FEATURES flag in non-canary, debug build causes a warning", function () { expect(1); Ember['default'].ENV.ENABLE_ALL_FEATURES = false; Ember['default'].ENV.ENABLE_OPTIONAL_FEATURES = false; Ember['default'].ENV.FEATURES = { "fred": true, "barney": false, "wilma": null }; confirmWarns("FEATURE[\"fred\"] is set as enabled, but FEATURE flags are only available in canary builds."); }); }); enifed('ember-debug/tests/warn_if_using_stripped_feature_flags_test.jscs-test', function () { 'use strict'; module("JSCS - ember-debug/tests"); test("ember-debug/tests/warn_if_using_stripped_feature_flags_test.js should pass jscs", function () { ok(true, "ember-debug/tests/warn_if_using_stripped_feature_flags_test.js should pass jscs."); }); }); enifed('ember-debug/tests/warn_if_using_stripped_feature_flags_test.jshint', function () { 'use strict'; module("JSHint - ember-debug/tests"); test("ember-debug/tests/warn_if_using_stripped_feature_flags_test.js should pass jshint", function () { ok(true, "ember-debug/tests/warn_if_using_stripped_feature_flags_test.js should pass jshint."); }); }); enifed('ember-dev/test-helper/assertion', ['exports', './method-call-expectation', './utils'], function (exports, MethodCallExpectation, utils) { 'use strict'; /* globals QUnit */ function AssertExpectation(Ember, message) { MethodCallExpectation['default'].call(this, Ember, "assert"); this.expectedMessage = message; } AssertExpectation.Error = function () {}; AssertExpectation.prototype = utils.o_create(MethodCallExpectation['default'].prototype); AssertExpectation.prototype.handleCall = function (message, test) { var noAssertion = typeof test === "function" ? test() : test; this.sawCall = true; if (noAssertion) { return; } this.actualMessage = message; // Halt execution throw new AssertExpectation.Error(); }; AssertExpectation.prototype.assert = function (fn) { try { this.runWithStub(fn); } catch (e) { if (!(e instanceof AssertExpectation.Error)) { throw e; } } // Run assertions in an order that is useful when debugging a test failure. // if (!this.sawCall) { QUnit.ok(false, "Expected Ember.assert to be called (Not called with any value)."); } else if (!this.actualMessage) { QUnit.ok(false, "Expected a failing Ember.assert (Ember.assert called, but without a failing test)."); } else { if (this.expectedMessage) { if (this.expectedMessage instanceof RegExp) { QUnit.ok(this.expectedMessage.test(this.actualMessage), "Expected failing Ember.assert: '" + this.expectedMessage + "', but got '" + this.actualMessage + "'."); } else { QUnit.equal(this.actualMessage, this.expectedMessage, "Expected failing Ember.assert: '" + this.expectedMessage + "', but got '" + this.actualMessage + "'."); } } else { // Positive assertion that assert was called QUnit.ok(true, "Expected a failing Ember.assert."); } } }; var AssertionAssert = function (env) { this.env = env; }; AssertionAssert.prototype = { reset: function () {}, inject: function () { var assertion = this; // Looks for an exception raised within the fn. // // expectAssertion(function(){ // Ember.assert("Homie don't roll like that"); // } /* , optionalMessageStringOrRegex */); // window.expectAssertion = function expectAssertion(fn, message) { if (assertion.env.runningProdBuild) { QUnit.ok(true, "Assertions disabled in production builds."); return; } // do not assert as the production builds do not contain Ember.assert new AssertExpectation(assertion.env.Ember, message).assert(fn); }; window.ignoreAssertion = function ignoreAssertion(fn) { var stubber = new MethodCallExpectation['default'](assertion.env.Ember, "assert"), noop = function () {}; stubber.runWithStub(fn, noop); }; }, assert: function () {}, restore: function () { window.expectAssertion = null; window.ignoreAssertion = null; } }; exports['default'] = AssertionAssert; }); enifed('ember-dev/test-helper/deprecation', ['exports', './method-call-expectation'], function (exports, MethodCallExpectation) { 'use strict'; /* globals QUnit */ var NONE = function () {}; var DeprecationAssert = function (env) { this.env = env; this.reset(); }; DeprecationAssert.prototype = { reset: function () { this.expecteds = null; this.actuals = null; }, stubEmber: function () { if (!this._previousEmberDeprecate && this._previousEmberDeprecate !== this.env.Ember.deprecate) { this._previousEmberDeprecate = this.env.Ember.deprecate; } var assertion = this; this.env.Ember.deprecate = function (msg, test) { var pushDeprecation = typeof test === "function" ? !test() : !test; assertion.actuals = assertion.actuals || []; if (pushDeprecation) { assertion.actuals.push([msg, test]); } }; }, inject: function () { var assertion = this; // Expects no deprecation to happen from the time of calling until // the end of the test. // // expectNoDeprecation(/* optionalStringOrRegex */); // Ember.deprecate("Old And Busted"); // window.expectNoDeprecation = function () { if (assertion.expecteds != null && typeof assertion.expecteds === "object") { throw new Error("expectNoDeprecation was called after expectDeprecation was called!"); } assertion.stubEmber(); assertion.expecteds = NONE; }; // Expect a deprecation to happen within a function, or if no function // is pass, from the time of calling until the end of the test. Can be called // multiple times to assert deprecations with different specific messages // were fired. // // expectDeprecation(function(){ // Ember.deprecate("Old And Busted"); // }, /* optionalStringOrRegex */); // // expectDeprecation(/* optionalStringOrRegex */); // Ember.deprecate("Old And Busted"); // window.expectDeprecation = function (fn, message) { var originalExpecteds, originalActuals; if (assertion.expecteds === NONE) { throw new Error("expectDeprecation was called after expectNoDeprecation was called!"); } assertion.stubEmber(); assertion.expecteds = assertion.expecteds || []; if (fn && typeof fn !== "function") { // fn is a message assertion.expecteds.push(fn); } else { originalExpecteds = assertion.expecteds.slice(); originalActuals = assertion.actuals ? assertion.actuals.slice() : assertion.actuals; assertion.expecteds.push(message || /.*/); if (fn) { fn(); assertion.assert(); assertion.expecteds = originalExpecteds; assertion.actuals = originalActuals; } } }; window.ignoreDeprecation = function ignoreDeprecation(fn) { var stubber = new MethodCallExpectation['default'](assertion.env.Ember, "deprecate"), noop = function () {}; stubber.runWithStub(fn, noop); }; }, // Forces an assert the deprecations occurred, and resets the globals // storing asserts for the next run. // // expectNoDeprecation(/Old/); // setTimeout(function(){ // Ember.deprecate("Old And Busted"); // assertDeprecation(); // }); // // assertDeprecation is called after each test run to catch any expectations // without explicit asserts. // assert: function () { var expecteds = this.expecteds || [], actuals = this.actuals || []; var o, i; if (expecteds !== NONE && expecteds.length === 0 && actuals.length === 0) { return; } if (this.env.runningProdBuild) { QUnit.ok(true, "deprecations disabled in production builds."); return; } if (expecteds === NONE) { var actualMessages = []; for (i = 0; i < actuals.length; i++) { actualMessages.push(actuals[i][0]); } QUnit.ok(actuals.length === 0, "Expected no deprecation calls, got " + actuals.length + ": " + actualMessages.join(", ")); return; } var expected, actual, match; for (o = 0; o < expecteds.length; o++) { expected = expecteds[o]; for (i = 0; i < actuals.length; i++) { actual = actuals[i]; if (!actual[1]) { if (expected instanceof RegExp) { if (expected.test(actual[0])) { match = actual; break; } } else { if (expected === actual[0]) { match = actual; break; } } } } if (!actual) { QUnit.ok(false, "Recieved no deprecate calls at all, expecting: " + expected); } else if (match && !match[1]) { QUnit.ok(true, "Recieved failing deprecation with message: " + match[0]); } else if (match && match[1]) { QUnit.ok(false, "Expected failing deprecation, got succeeding with message: " + match[0]); } else if (actual[1]) { QUnit.ok(false, "Did not receive failing deprecation matching '" + expected + "', last was success with '" + actual[0] + "'"); } else if (!actual[1]) { QUnit.ok(false, "Did not receive failing deprecation matching '" + expected + "', last was failure with '" + actual[0] + "'"); } } }, restore: function () { if (this._previousEmberDeprecate) { this.env.Ember.deprecate = this._previousEmberDeprecate; this._previousEmberDeprecate = null; } window.expectNoDeprecation = null; } }; exports['default'] = DeprecationAssert; }); enifed('ember-dev/test-helper/index', ['exports', './deprecation', './remaining-view', './remaining-template', './assertion', './run-loop', './utils'], function (exports, DeprecationAssert, RemainingViewAssert, RemainingTemplateAssert, AssertionAssert, RunLoopAssert, utils) { 'use strict'; var EmberDevTestHelperAssert = utils.buildCompositeAssert([DeprecationAssert['default'], RemainingViewAssert['default'], RemainingTemplateAssert['default'], AssertionAssert['default'], RunLoopAssert['default']]); exports['default'] = EmberDevTestHelperAssert; }); enifed('ember-dev/test-helper/method-call-expectation', ['exports'], function (exports) { 'use strict'; /* globals QUnit */ // A light class for stubbing // function MethodCallExpectation(target, property) { this.target = target; this.property = property; } MethodCallExpectation.prototype = { handleCall: function () { this.sawCall = true; return this.originalMethod.apply(this.target, arguments); }, stubMethod: function (replacementFunc) { var context = this, property = this.property; this.originalMethod = this.target[property]; if (typeof replacementFunc === "function") { this.target[property] = replacementFunc; } else { this.target[property] = function () { return context.handleCall.apply(context, arguments); }; } }, restoreMethod: function () { this.target[this.property] = this.originalMethod; }, runWithStub: function (fn, replacementFunc) { try { this.stubMethod(replacementFunc); fn(); } finally { this.restoreMethod(); } }, assert: function () { this.runWithStub.apply(this, arguments); QUnit.ok(this.sawCall, "Expected " + this.property + " to be called."); } }; exports['default'] = MethodCallExpectation; }); enifed('ember-dev/test-helper/remaining-template', ['exports'], function (exports) { 'use strict'; /* globals QUnit */ var RemainingTemplateAssert = function (env) { this.env = env; }; RemainingTemplateAssert.prototype = { reset: function () {}, inject: function () {}, assert: function () { if (this.env.Ember && this.env.Ember.TEMPLATES) { var templateNames = [], name; for (name in this.env.Ember.TEMPLATES) { if (this.env.Ember.TEMPLATES[name] != null) { templateNames.push(name); } } if (templateNames.length > 0) { QUnit.deepEqual(templateNames, [], "Ember.TEMPLATES should be empty"); this.env.Ember.TEMPLATES = {}; } } }, restore: function () {} }; exports['default'] = RemainingTemplateAssert; }); enifed('ember-dev/test-helper/remaining-view', ['exports'], function (exports) { 'use strict'; /* globals QUnit */ var RemainingViewAssert = function (env) { this.env = env; }; RemainingViewAssert.prototype = { reset: function () {}, inject: function () {}, assert: function () { if (this.env.Ember && this.env.Ember.View) { var viewIds = [], id; for (id in this.env.Ember.View.views) { if (this.env.Ember.View.views[id] != null) { viewIds.push(id); } } if (viewIds.length > 0) { QUnit.deepEqual(viewIds, [], "Ember.View.views should be empty"); this.env.Ember.View.views = []; } } }, restore: function () {} }; exports['default'] = RemainingViewAssert; }); enifed('ember-dev/test-helper/run-loop', ['exports'], function (exports) { 'use strict'; /* globals QUnit */ function RunLoopAssertion(env) { this.env = env; } RunLoopAssertion.prototype = { reset: function () {}, inject: function () {}, assert: function () { var run = this.env.Ember.run; if (run.currentRunLoop) { QUnit.ok(false, "Should not be in a run loop at end of test"); while (run.currentRunLoop) { run.end(); } } if (run.hasScheduledTimers()) { QUnit.ok(false, "Ember run should not have scheduled timers at end of test"); run.cancelTimers(); } }, restore: function () {} }; exports['default'] = RunLoopAssertion; }); enifed('ember-dev/test-helper/setup-qunit', ['exports'], function (exports) { 'use strict'; /* globals QUnit */ exports['default'] = setupQUnit; function setupQUnit(assertion, _qunitGlobal) { var qunitGlobal = QUnit; if (_qunitGlobal) { qunitGlobal = _qunitGlobal; } var originalModule = qunitGlobal.module; qunitGlobal.module = function (name, _options) { var options = _options || {}; var originalSetup = options.setup || function () {}; var originalTeardown = options.teardown || function () {}; options.setup = function () { assertion.reset(); assertion.inject(); originalSetup.call(this); }; options.teardown = function () { originalTeardown.call(this); assertion.assert(); assertion.restore(); }; return originalModule(name, options); }; } }); enifed('ember-dev/test-helper/utils', ['exports'], function (exports) { 'use strict'; exports.buildCompositeAssert = buildCompositeAssert; function callForEach(prop, func) { return function () { for (var i = 0, l = this[prop].length; i < l; i++) { this[prop][i][func](); } }; } function buildCompositeAssert(klasses) { var Composite = function (emberKlass, runningProdBuild) { this.asserts = []; for (var i = 0, l = klasses.length; i < l; i++) { this.asserts.push(new klasses[i]({ Ember: emberKlass, runningProdBuild: runningProdBuild })); } }; Composite.prototype = { reset: callForEach("asserts", "reset"), inject: callForEach("asserts", "inject"), assert: callForEach("asserts", "assert"), restore: callForEach("asserts", "restore") }; return Composite; } var o_create = Object.create || (function () { function F() {} return function (o) { if (arguments.length !== 1) { throw new Error("Object.create implementation only accepts one parameter."); } F.prototype = o; return new F(); }; })(); var o_create; exports.o_create = o_create; }); enifed('ember-extension-support.jscs-test', function () { 'use strict'; module("JSCS - ."); test("ember-extension-support.js should pass jscs", function () { ok(true, "ember-extension-support.js should pass jscs."); }); }); enifed('ember-extension-support.jshint', function () { 'use strict'; module("JSHint - ."); test("ember-extension-support.js should pass jshint", function () { ok(true, "ember-extension-support.js should pass jshint."); }); }); enifed('ember-extension-support/container_debug_adapter.jscs-test', function () { 'use strict'; module("JSCS - ember-extension-support"); test("ember-extension-support/container_debug_adapter.js should pass jscs", function () { ok(true, "ember-extension-support/container_debug_adapter.js should pass jscs."); }); }); enifed('ember-extension-support/container_debug_adapter.jshint', function () { 'use strict'; module("JSHint - ember-extension-support"); test("ember-extension-support/container_debug_adapter.js should pass jshint", function () { ok(true, "ember-extension-support/container_debug_adapter.js should pass jshint."); }); }); enifed('ember-extension-support/data_adapter.jscs-test', function () { 'use strict'; module("JSCS - ember-extension-support"); test("ember-extension-support/data_adapter.js should pass jscs", function () { ok(true, "ember-extension-support/data_adapter.js should pass jscs."); }); }); enifed('ember-extension-support/data_adapter.jshint', function () { 'use strict'; module("JSHint - ember-extension-support"); test("ember-extension-support/data_adapter.js should pass jshint", function () { ok(true, "ember-extension-support/data_adapter.js should pass jshint."); }); }); enifed('ember-extension-support/tests/container_debug_adapter_test', ['ember-metal/run_loop', 'ember-runtime/controllers/controller', 'ember-extension-support', 'ember-application/system/application'], function (run, EmberController, __dep2__, Application) { 'use strict'; var adapter, App; function boot() { run['default'](App, "advanceReadiness"); } QUnit.module("Container Debug Adapter", { setup: function () { run['default'](function () { App = Application['default'].create(); // ES6TODO: this comes from the ember-application package NOT ember-runtime App.toString = function () { return "App"; }; App.deferReadiness(); }); boot(); run['default'](function () { adapter = App.__container__.lookup("container-debug-adapter:main"); }); }, teardown: function () { run['default'](function () { adapter.destroy(); App.destroy(); App = null; }); } }); QUnit.test("the default ContainerDebugAdapter cannot catalog certain entries by type", function () { equal(adapter.canCatalogEntriesByType("model"), false, "canCatalogEntriesByType should return false for model"); equal(adapter.canCatalogEntriesByType("template"), false, "canCatalogEntriesByType should return false for template"); }); QUnit.test("the default ContainerDebugAdapter can catalog typical entries by type", function () { equal(adapter.canCatalogEntriesByType("controller"), true, "canCatalogEntriesByType should return true for controller"); equal(adapter.canCatalogEntriesByType("route"), true, "canCatalogEntriesByType should return true for route"); equal(adapter.canCatalogEntriesByType("view"), true, "canCatalogEntriesByType should return true for view"); }); QUnit.test("the default ContainerDebugAdapter catalogs controller entries", function () { App.PostController = EmberController['default'].extend(); var controllerClasses = adapter.catalogEntriesByType("controller"); equal(controllerClasses.length, 1, "found 1 class"); equal(controllerClasses[0], "post", "found the right class"); }); }); enifed('ember-extension-support/tests/container_debug_adapter_test.jscs-test', function () { 'use strict'; module("JSCS - ember-extension-support/tests"); test("ember-extension-support/tests/container_debug_adapter_test.js should pass jscs", function () { ok(true, "ember-extension-support/tests/container_debug_adapter_test.js should pass jscs."); }); }); enifed('ember-extension-support/tests/container_debug_adapter_test.jshint', function () { 'use strict'; module("JSHint - ember-extension-support/tests"); test("ember-extension-support/tests/container_debug_adapter_test.js should pass jshint", function () { ok(true, "ember-extension-support/tests/container_debug_adapter_test.js should pass jshint."); }); }); enifed('ember-extension-support/tests/data_adapter_test', ['ember-metal/core', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/run_loop', 'ember-metal/observer', 'ember-runtime/system/object', 'ember-extension-support/data_adapter', 'ember-application/system/application', 'ember-application/system/resolver'], function (Ember, property_get, property_set, run, observer, EmberObject, EmberDataAdapter, EmberApplication, DefaultResolver) { 'use strict'; var adapter, App; var Model = EmberObject['default'].extend(); var DataAdapter = EmberDataAdapter['default'].extend({ detect: function (klass) { return klass !== Model && Model.detect(klass); } }); QUnit.module("Data Adapter", { setup: function () { run['default'](function () { App = EmberApplication['default'].create(); App.toString = function () { return "App"; }; App.deferReadiness(); App.registry.register("data-adapter:main", DataAdapter); }); }, teardown: function () { run['default'](function () { adapter.destroy(); App.destroy(); }); } }); QUnit.test("Model types added with DefaultResolver", function () { App.Post = Model.extend(); adapter = App.__container__.lookup("data-adapter:main"); adapter.reopen({ getRecords: function () { return Ember['default'].A([1, 2, 3]); }, columnsForType: function () { return [{ name: "title", desc: "Title" }]; } }); run['default'](App, "advanceReadiness"); var modelTypesAdded = function (types) { equal(types.length, 1); var postType = types[0]; equal(postType.name, "post", "Correctly sets the name"); equal(postType.count, 3, "Correctly sets the record count"); strictEqual(postType.object, App.Post, "Correctly sets the object"); deepEqual(postType.columns, [{ name: "title", desc: "Title" }], "Correctly sets the columns"); }; adapter.watchModelTypes(modelTypesAdded); }); QUnit.test("Model types added with custom container-debug-adapter", function () { var PostClass = Model.extend(); var StubContainerDebugAdapter = DefaultResolver['default'].extend({ canCatalogEntriesByType: function (type) { return true; }, catalogEntriesByType: function (type) { return [PostClass]; } }); App.registry.register("container-debug-adapter:main", StubContainerDebugAdapter); adapter = App.__container__.lookup("data-adapter:main"); adapter.reopen({ getRecords: function () { return Ember['default'].A([1, 2, 3]); }, columnsForType: function () { return [{ name: "title", desc: "Title" }]; } }); run['default'](App, "advanceReadiness"); var modelTypesAdded = function (types) { equal(types.length, 1); var postType = types[0]; equal(postType.name, PostClass.toString(), "Correctly sets the name"); equal(postType.count, 3, "Correctly sets the record count"); strictEqual(postType.object, PostClass, "Correctly sets the object"); deepEqual(postType.columns, [{ name: "title", desc: "Title" }], "Correctly sets the columns"); }; adapter.watchModelTypes(modelTypesAdded); }); QUnit.test("Model Types Updated", function () { App.Post = Model.extend(); adapter = App.__container__.lookup("data-adapter:main"); var records = Ember['default'].A([1, 2, 3]); adapter.reopen({ getRecords: function () { return records; } }); run['default'](App, "advanceReadiness"); var modelTypesAdded = function () { run['default'](function () { records.pushObject(4); }); }; var modelTypesUpdated = function (types) { var postType = types[0]; equal(postType.count, 4, "Correctly updates the count"); }; adapter.watchModelTypes(modelTypesAdded, modelTypesUpdated); }); QUnit.test("Records Added", function () { expect(8); var countAdded = 1; App.Post = Model.extend(); var post = App.Post.create(); var recordList = Ember['default'].A([post]); adapter = App.__container__.lookup("data-adapter:main"); adapter.reopen({ getRecords: function () { return recordList; }, getRecordColor: function () { return "blue"; }, getRecordColumnValues: function () { return { title: "Post " + countAdded }; }, getRecordKeywords: function () { return ["Post " + countAdded]; } }); var recordsAdded = function (records) { var record = records[0]; equal(record.color, "blue", "Sets the color correctly"); deepEqual(record.columnValues, { title: "Post " + countAdded }, "Sets the column values correctly"); deepEqual(record.searchKeywords, ["Post " + countAdded], "Sets search keywords correctly"); strictEqual(record.object, post, "Sets the object to the record instance"); }; adapter.watchRecords(App.Post, recordsAdded); countAdded++; post = App.Post.create(); recordList.pushObject(post); }); QUnit.test("Observes and releases a record correctly", function () { var updatesCalled = 0; App.Post = Model.extend(); var post = App.Post.create({ title: "Post" }); var recordList = Ember['default'].A([post]); adapter = App.__container__.lookup("data-adapter:main"); adapter.reopen({ getRecords: function () { return recordList; }, observeRecord: function (record, recordUpdated) { var self = this; var callback = function () { recordUpdated(self.wrapRecord(record)); }; observer.addObserver(record, "title", callback); return function () { observer.removeObserver(record, "title", callback); }; }, getRecordColumnValues: function (record) { return { title: property_get.get(record, "title") }; } }); var recordsAdded = function () { property_set.set(post, "title", "Post Modified"); }; var recordsUpdated = function (records) { updatesCalled++; equal(records[0].columnValues.title, "Post Modified"); }; var release = adapter.watchRecords(App.Post, recordsAdded, recordsUpdated); release(); property_set.set(post, "title", "New Title"); equal(updatesCalled, 1, "Release function removes observers"); }); }); enifed('ember-extension-support/tests/data_adapter_test.jscs-test', function () { 'use strict'; module("JSCS - ember-extension-support/tests"); test("ember-extension-support/tests/data_adapter_test.js should pass jscs", function () { ok(true, "ember-extension-support/tests/data_adapter_test.js should pass jscs."); }); }); enifed('ember-extension-support/tests/data_adapter_test.jshint', function () { 'use strict'; module("JSHint - ember-extension-support/tests"); test("ember-extension-support/tests/data_adapter_test.js should pass jshint", function () { ok(true, "ember-extension-support/tests/data_adapter_test.js should pass jshint."); }); }); enifed('ember-htmlbars.jscs-test', function () { 'use strict'; module("JSCS - ."); test("ember-htmlbars.js should pass jscs", function () { ok(true, "ember-htmlbars.js should pass jscs."); }); }); enifed('ember-htmlbars.jshint', function () { 'use strict'; module("JSHint - ."); test("ember-htmlbars.js should pass jshint", function () { ok(false, "ember-htmlbars.js should pass jshint.\nember-htmlbars.js: line 15, col 14, 'helpers' is defined but never used.\n\n1 error"); }); }); enifed('ember-htmlbars/compat.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars"); test("ember-htmlbars/compat.js should pass jscs", function () { ok(true, "ember-htmlbars/compat.js should pass jscs."); }); }); enifed('ember-htmlbars/compat.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars"); test("ember-htmlbars/compat.js should pass jshint", function () { ok(true, "ember-htmlbars/compat.js should pass jshint."); }); }); enifed('ember-htmlbars/compat/handlebars-get.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/compat"); test("ember-htmlbars/compat/handlebars-get.js should pass jscs", function () { ok(true, "ember-htmlbars/compat/handlebars-get.js should pass jscs."); }); }); enifed('ember-htmlbars/compat/handlebars-get.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/compat"); test("ember-htmlbars/compat/handlebars-get.js should pass jshint", function () { ok(true, "ember-htmlbars/compat/handlebars-get.js should pass jshint."); }); }); enifed('ember-htmlbars/compat/helper.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/compat"); test("ember-htmlbars/compat/helper.js should pass jscs", function () { ok(true, "ember-htmlbars/compat/helper.js should pass jscs."); }); }); enifed('ember-htmlbars/compat/helper.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/compat"); test("ember-htmlbars/compat/helper.js should pass jshint", function () { ok(true, "ember-htmlbars/compat/helper.js should pass jshint."); }); }); enifed('ember-htmlbars/compat/make-bound-helper.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/compat"); test("ember-htmlbars/compat/make-bound-helper.js should pass jscs", function () { ok(true, "ember-htmlbars/compat/make-bound-helper.js should pass jscs."); }); }); enifed('ember-htmlbars/compat/make-bound-helper.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/compat"); test("ember-htmlbars/compat/make-bound-helper.js should pass jshint", function () { ok(true, "ember-htmlbars/compat/make-bound-helper.js should pass jshint."); }); }); enifed('ember-htmlbars/compat/register-bound-helper.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/compat"); test("ember-htmlbars/compat/register-bound-helper.js should pass jscs", function () { ok(true, "ember-htmlbars/compat/register-bound-helper.js should pass jscs."); }); }); enifed('ember-htmlbars/compat/register-bound-helper.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/compat"); test("ember-htmlbars/compat/register-bound-helper.js should pass jshint", function () { ok(true, "ember-htmlbars/compat/register-bound-helper.js should pass jshint."); }); }); enifed('ember-htmlbars/env.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars"); test("ember-htmlbars/env.js should pass jscs", function () { ok(true, "ember-htmlbars/env.js should pass jscs."); }); }); enifed('ember-htmlbars/env.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars"); test("ember-htmlbars/env.js should pass jshint", function () { ok(true, "ember-htmlbars/env.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars"); test("ember-htmlbars/helpers.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars"); test("ember-htmlbars/helpers.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/bind-attr.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/bind-attr.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/bind-attr.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/bind-attr.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/bind-attr.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/bind-attr.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/collection.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/collection.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/collection.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/collection.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/collection.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/collection.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/component.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/component.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/component.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/component.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/component.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/component.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/debugger.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/debugger.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/debugger.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/debugger.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/debugger.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/debugger.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/each.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/each.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/each.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/each.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/each.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/each.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/if_unless.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/if_unless.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/if_unless.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/if_unless.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/if_unless.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/if_unless.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/input.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/input.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/input.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/input.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/input.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/input.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/loc.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/loc.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/loc.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/loc.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/loc.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/loc.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/log.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/log.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/log.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/log.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/log.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/log.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/partial.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/partial.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/partial.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/partial.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/partial.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/partial.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/template.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/template.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/template.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/template.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/template.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/template.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/text_area.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/text_area.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/text_area.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/text_area.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/text_area.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/text_area.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/unbound.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/unbound.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/unbound.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/unbound.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/unbound.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/unbound.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/view.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/view.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/view.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/view.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/view.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/view.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/with.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/with.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/with.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/with.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/with.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/with.js should pass jshint."); }); }); enifed('ember-htmlbars/helpers/yield.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/yield.js should pass jscs", function () { ok(true, "ember-htmlbars/helpers/yield.js should pass jscs."); }); }); enifed('ember-htmlbars/helpers/yield.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/helpers"); test("ember-htmlbars/helpers/yield.js should pass jshint", function () { ok(true, "ember-htmlbars/helpers/yield.js should pass jshint."); }); }); enifed('ember-htmlbars/hooks/attribute.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/attribute.js should pass jscs", function () { ok(true, "ember-htmlbars/hooks/attribute.js should pass jscs."); }); }); enifed('ember-htmlbars/hooks/attribute.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/attribute.js should pass jshint", function () { ok(true, "ember-htmlbars/hooks/attribute.js should pass jshint."); }); }); enifed('ember-htmlbars/hooks/block.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/block.js should pass jscs", function () { ok(true, "ember-htmlbars/hooks/block.js should pass jscs."); }); }); enifed('ember-htmlbars/hooks/block.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/block.js should pass jshint", function () { ok(true, "ember-htmlbars/hooks/block.js should pass jshint."); }); }); enifed('ember-htmlbars/hooks/component.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/component.js should pass jscs", function () { ok(true, "ember-htmlbars/hooks/component.js should pass jscs."); }); }); enifed('ember-htmlbars/hooks/component.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/component.js should pass jshint", function () { ok(true, "ember-htmlbars/hooks/component.js should pass jshint."); }); }); enifed('ember-htmlbars/hooks/concat.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/concat.js should pass jscs", function () { ok(true, "ember-htmlbars/hooks/concat.js should pass jscs."); }); }); enifed('ember-htmlbars/hooks/concat.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/concat.js should pass jshint", function () { ok(true, "ember-htmlbars/hooks/concat.js should pass jshint."); }); }); enifed('ember-htmlbars/hooks/content.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/content.js should pass jscs", function () { ok(true, "ember-htmlbars/hooks/content.js should pass jscs."); }); }); enifed('ember-htmlbars/hooks/content.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/content.js should pass jshint", function () { ok(true, "ember-htmlbars/hooks/content.js should pass jshint."); }); }); enifed('ember-htmlbars/hooks/element.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/element.js should pass jscs", function () { ok(true, "ember-htmlbars/hooks/element.js should pass jscs."); }); }); enifed('ember-htmlbars/hooks/element.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/element.js should pass jshint", function () { ok(true, "ember-htmlbars/hooks/element.js should pass jshint."); }); }); enifed('ember-htmlbars/hooks/get.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/get.js should pass jscs", function () { ok(true, "ember-htmlbars/hooks/get.js should pass jscs."); }); }); enifed('ember-htmlbars/hooks/get.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/get.js should pass jshint", function () { ok(true, "ember-htmlbars/hooks/get.js should pass jshint."); }); }); enifed('ember-htmlbars/hooks/inline.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/inline.js should pass jscs", function () { ok(true, "ember-htmlbars/hooks/inline.js should pass jscs."); }); }); enifed('ember-htmlbars/hooks/inline.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/inline.js should pass jshint", function () { ok(true, "ember-htmlbars/hooks/inline.js should pass jshint."); }); }); enifed('ember-htmlbars/hooks/set.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/set.js should pass jscs", function () { ok(true, "ember-htmlbars/hooks/set.js should pass jscs."); }); }); enifed('ember-htmlbars/hooks/set.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/set.js should pass jshint", function () { ok(true, "ember-htmlbars/hooks/set.js should pass jshint."); }); }); enifed('ember-htmlbars/hooks/subexpr.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/subexpr.js should pass jscs", function () { ok(true, "ember-htmlbars/hooks/subexpr.js should pass jscs."); }); }); enifed('ember-htmlbars/hooks/subexpr.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/hooks"); test("ember-htmlbars/hooks/subexpr.js should pass jshint", function () { ok(true, "ember-htmlbars/hooks/subexpr.js should pass jshint."); }); }); enifed('ember-htmlbars/system/append-templated-view.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/system"); test("ember-htmlbars/system/append-templated-view.js should pass jscs", function () { ok(true, "ember-htmlbars/system/append-templated-view.js should pass jscs."); }); }); enifed('ember-htmlbars/system/append-templated-view.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/system"); test("ember-htmlbars/system/append-templated-view.js should pass jshint", function () { ok(true, "ember-htmlbars/system/append-templated-view.js should pass jshint."); }); }); enifed('ember-htmlbars/system/bootstrap.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/system"); test("ember-htmlbars/system/bootstrap.js should pass jscs", function () { ok(true, "ember-htmlbars/system/bootstrap.js should pass jscs."); }); }); enifed('ember-htmlbars/system/bootstrap.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/system"); test("ember-htmlbars/system/bootstrap.js should pass jshint", function () { ok(true, "ember-htmlbars/system/bootstrap.js should pass jshint."); }); }); enifed('ember-htmlbars/system/helper.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/system"); test("ember-htmlbars/system/helper.js should pass jscs", function () { ok(true, "ember-htmlbars/system/helper.js should pass jscs."); }); }); enifed('ember-htmlbars/system/helper.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/system"); test("ember-htmlbars/system/helper.js should pass jshint", function () { ok(true, "ember-htmlbars/system/helper.js should pass jshint."); }); }); enifed('ember-htmlbars/system/lookup-helper.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/system"); test("ember-htmlbars/system/lookup-helper.js should pass jscs", function () { ok(true, "ember-htmlbars/system/lookup-helper.js should pass jscs."); }); }); enifed('ember-htmlbars/system/lookup-helper.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/system"); test("ember-htmlbars/system/lookup-helper.js should pass jshint", function () { ok(true, "ember-htmlbars/system/lookup-helper.js should pass jshint."); }); }); enifed('ember-htmlbars/system/make-view-helper.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/system"); test("ember-htmlbars/system/make-view-helper.js should pass jscs", function () { ok(true, "ember-htmlbars/system/make-view-helper.js should pass jscs."); }); }); enifed('ember-htmlbars/system/make-view-helper.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/system"); test("ember-htmlbars/system/make-view-helper.js should pass jshint", function () { ok(true, "ember-htmlbars/system/make-view-helper.js should pass jshint."); }); }); enifed('ember-htmlbars/system/make_bound_helper.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/system"); test("ember-htmlbars/system/make_bound_helper.js should pass jscs", function () { ok(true, "ember-htmlbars/system/make_bound_helper.js should pass jscs."); }); }); enifed('ember-htmlbars/system/make_bound_helper.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/system"); test("ember-htmlbars/system/make_bound_helper.js should pass jshint", function () { ok(true, "ember-htmlbars/system/make_bound_helper.js should pass jshint."); }); }); enifed('ember-htmlbars/system/merge-view-bindings.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/system"); test("ember-htmlbars/system/merge-view-bindings.js should pass jscs", function () { ok(true, "ember-htmlbars/system/merge-view-bindings.js should pass jscs."); }); }); enifed('ember-htmlbars/system/merge-view-bindings.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/system"); test("ember-htmlbars/system/merge-view-bindings.js should pass jshint", function () { ok(true, "ember-htmlbars/system/merge-view-bindings.js should pass jshint."); }); }); enifed('ember-htmlbars/system/render-view.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/system"); test("ember-htmlbars/system/render-view.js should pass jscs", function () { ok(true, "ember-htmlbars/system/render-view.js should pass jscs."); }); }); enifed('ember-htmlbars/system/render-view.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/system"); test("ember-htmlbars/system/render-view.js should pass jshint", function () { ok(true, "ember-htmlbars/system/render-view.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/attr_nodes/boolean_test', ['ember-views/views/view', 'ember-metal/run_loop', 'ember-template-compiler/system/compile', 'htmlbars-test-helpers'], function (EmberView, run, compile, htmlbars_test_helpers) { 'use strict'; var view; function appendView(view) { run['default'](function () { view.appendTo("#qunit-fixture"); }); } // jscs:disable validateIndentation QUnit.module("ember-htmlbars: boolean attribute", { teardown: function () { if (view) { run['default'](view, view.destroy); } } }); QUnit.test("disabled property can be set true", function () { view = EmberView['default'].create({ context: { isDisabled: true }, template: compile['default']("") }); appendView(view); equal(view.element.firstChild.hasAttribute("disabled"), true, "attribute is output"); equal(view.element.firstChild.disabled, true, "boolean property is set true"); }); QUnit.test("disabled property can be set false with a blank string", function () { view = EmberView['default'].create({ context: { isDisabled: "" }, template: compile['default']("") }); appendView(view); equal(view.element.firstChild.hasAttribute("disabled"), false, "attribute is not output"); equal(view.element.firstChild.disabled, false, "boolean property is set false"); }); QUnit.test("disabled property can be set false", function () { view = EmberView['default'].create({ context: { isDisabled: false }, template: compile['default']("") }); appendView(view); htmlbars_test_helpers.equalInnerHTML(view.element, "", "attribute is not output"); equal(view.element.firstChild.disabled, false, "boolean property is set false"); }); QUnit.test("disabled property can be set true with a string", function () { view = EmberView['default'].create({ context: { isDisabled: "oh, no a string" }, template: compile['default']("") }); appendView(view); equal(view.element.firstChild.hasAttribute("disabled"), true, "attribute is output"); equal(view.element.firstChild.disabled, true, "boolean property is set true"); }); QUnit.test("disabled attribute turns a value to a string", function () { view = EmberView['default'].create({ context: { isDisabled: false }, template: compile['default']("") }); appendView(view); equal(view.element.firstChild.hasAttribute("disabled"), true, "attribute is output"); equal(view.element.firstChild.disabled, true, "boolean property is set true"); }); QUnit.test("disabled attribute preserves a blank string value", function () { view = EmberView['default'].create({ context: { isDisabled: "" }, template: compile['default']("") }); appendView(view); htmlbars_test_helpers.equalInnerHTML(view.element, "", "attribute is not output"); equal(view.element.firstChild.disabled, false, "boolean property is set false"); }); // jscs:enable validateIndentation }); enifed('ember-htmlbars/tests/attr_nodes/boolean_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/boolean_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/attr_nodes/boolean_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/attr_nodes/boolean_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/boolean_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/attr_nodes/boolean_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/attr_nodes/class_test', ['ember-views/views/view', 'ember-metal/run_loop', 'ember-template-compiler/system/compile', 'htmlbars-test-helpers'], function (EmberView, run, compile, htmlbars_test_helpers) { 'use strict'; var view; function appendView(view) { run['default'](function () { view.appendTo("#qunit-fixture"); }); } var isInlineIfEnabled = false; isInlineIfEnabled = true; // jscs:disable validateIndentation QUnit.module("ember-htmlbars: class attribute", { teardown: function () { if (view) { run['default'](view, view.destroy); } } }); QUnit.test("class renders before didInsertElement", function () { var matchingElement; view = EmberView['default'].create({ didInsertElement: function () { matchingElement = this.$("div.blue"); }, context: { color: "blue" }, template: compile['default']("
Hi!
") }); appendView(view); equal(view.element.firstChild.className, "blue", "attribute is output"); equal(matchingElement.length, 1, "element is in the DOM when didInsertElement"); }); QUnit.test("class property can contain multiple classes", function () { view = EmberView['default'].create({ context: { classes: "large blue" }, template: compile['default']("
") }); appendView(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
", "attribute is output"); ok(view.$(".large")[0], "first class found"); ok(view.$(".blue")[0], "second class found"); }); QUnit.test("class property is removed when updated with a null value", function () { view = EmberView['default'].create({ context: { "class": "large" }, template: compile['default']("
") }); appendView(view); equal(view.element.firstChild.className, "large", "attribute is output"); run['default'](view, view.set, "context.class", null); equal(view.element.firstChild.className, "", "attribute is removed"); }); QUnit.test("class attribute concats bound values", function () { view = EmberView['default'].create({ context: { size: "large", color: "blue" }, template: compile['default']("
") }); appendView(view); ok(view.element.firstChild.className, "large blue round", "classes are set"); }); if (isInlineIfEnabled) { QUnit.test("class attribute accepts nested helpers, and updates", function () { view = EmberView['default'].create({ context: { size: "large", hasColor: true, hasShape: false, shape: "round" }, template: compile['default']("
") }); appendView(view); ok(view.element.firstChild.className, "large blue no-shape", "classes are set"); run['default'](view, view.set, "context.hasColor", false); run['default'](view, view.set, "context.hasShape", true); ok(view.element.firstChild.className, "large round", "classes are updated"); }); } QUnit.test("class attribute can accept multiple classes from a single value, and update", function () { view = EmberView['default'].create({ context: { size: "large small" }, template: compile['default']("
") }); appendView(view); ok(view.element.firstChild.className, "large small", "classes are set"); run['default'](view, view.set, "context.size", "medium"); ok(view.element.firstChild.className, "medium", "classes are updated"); }); QUnit.test("class attribute can grok concatted classes, and update", function () { view = EmberView['default'].create({ context: { size: "large", prefix: "pre-pre pre", postfix: "post" }, template: compile['default']("
") }); appendView(view); ok(view.element.firstChild.className, "btn-large pre-pre pre-post whoop", "classes are set"); run['default'](view, view.set, "context.prefix", ""); ok(view.element.firstChild.className, "btn-large -post whoop", "classes are updated"); }); QUnit.test("class attribute stays in order", function () { view = EmberView['default'].create({ context: { showA: "a", showB: "b" }, template: compile['default']("
") }); appendView(view); run['default'](view, view.set, "context.showB", false); run['default'](view, view.set, "context.showB", true); ok(view.element.firstChild.className, "r b a c", "classes are in the right order"); }); // jscs:enable validateIndentation }); enifed('ember-htmlbars/tests/attr_nodes/class_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/class_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/attr_nodes/class_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/attr_nodes/class_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/class_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/attr_nodes/class_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/attr_nodes/data_test', ['ember-views/views/view', 'ember-metal/run_loop', 'ember-runtime/system/object', 'ember-template-compiler/system/compile', 'ember-views/system/renderer', 'htmlbars-test-helpers', 'ember-htmlbars/env', 'ember-runtime/tests/utils'], function (EmberView, run, EmberObject, compile, Renderer, htmlbars_test_helpers, env, utils) { 'use strict'; var view, originalSetAttribute, setAttributeCalls, renderer; QUnit.module("ember-htmlbars: data attribute", { teardown: function () { utils.runDestroy(view); } }); QUnit.test("property is output", function () { view = EmberView['default'].create({ context: { name: "erik" }, template: compile['default']("
Hi!
") }); utils.runAppend(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "attribute is output"); }); QUnit.test("property set before didInsertElement", function () { var matchingElement; view = EmberView['default'].create({ didInsertElement: function () { matchingElement = this.$("div[data-name=erik]"); }, context: { name: "erik" }, template: compile['default']("
Hi!
") }); utils.runAppend(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "attribute is output"); equal(matchingElement.length, 1, "element is in the DOM when didInsertElement"); }); QUnit.test("quoted attributes are concatenated", function () { view = EmberView['default'].create({ context: { firstName: "max", lastName: "jackson" }, template: compile['default']("
Hi!
") }); utils.runAppend(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "attribute is output"); }); QUnit.test("quoted attributes are updated when changed", function () { view = EmberView['default'].create({ context: { firstName: "max", lastName: "jackson" }, template: compile['default']("
Hi!
") }); utils.runAppend(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "precond - attribute is output"); run['default'](view, view.set, "context.firstName", "james"); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "attribute is output"); }); QUnit.test("quoted attributes are not removed when value is null", function () { view = EmberView['default'].create({ context: { firstName: "max", lastName: "jackson" }, template: compile['default']("
Hi!
") }); utils.runAppend(view); equal(view.element.firstChild.getAttribute("data-name"), "max", "precond - attribute is output"); run['default'](view, view.set, "context.firstName", null); equal(view.element.firstChild.getAttribute("data-name"), "", "attribute is output"); }); QUnit.test("unquoted attributes are removed when value is null", function () { view = EmberView['default'].create({ context: { firstName: "max" }, template: compile['default']("
Hi!
") }); utils.runAppend(view); equal(view.element.firstChild.getAttribute("data-name"), "max", "precond - attribute is output"); run['default'](view, view.set, "context.firstName", null); ok(!view.element.firstChild.hasAttribute("data-name"), "attribute is removed output"); }); QUnit.test("unquoted attributes that are null are not added", function () { view = EmberView['default'].create({ context: { firstName: null }, template: compile['default']("
Hi!
") }); utils.runAppend(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "attribute is not present"); }); QUnit.test("unquoted attributes are added when changing from null", function () { view = EmberView['default'].create({ context: { firstName: null }, template: compile['default']("
Hi!
") }); utils.runAppend(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "precond - attribute is not present"); run['default'](view, view.set, "context.firstName", "max"); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "attribute is added output"); }); QUnit.test("property value is directly added to attribute", function () { view = EmberView['default'].create({ context: { name: "\"\" data-foo=\"blah\"" }, template: compile['default']("
Hi!
") }); utils.runAppend(view); equal(view.element.firstChild.getAttribute("data-name"), "\"\" data-foo=\"blah\"", "attribute is output"); }); QUnit.test("path is output", function () { view = EmberView['default'].create({ context: { name: { firstName: "erik" } }, template: compile['default']("
Hi!
") }); utils.runAppend(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "attribute is output"); }); QUnit.test("changed property updates", function () { var context = EmberObject['default'].create({ name: "erik" }); view = EmberView['default'].create({ context: context, template: compile['default']("
Hi!
") }); utils.runAppend(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "precond - attribute is output"); run['default'](context, context.set, "name", "mmun"); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "attribute is updated output"); }); QUnit.test("updates are scheduled in the render queue", function () { expect(4); var context = EmberObject['default'].create({ name: "erik" }); view = EmberView['default'].create({ context: context, template: compile['default']("
Hi!
") }); utils.runAppend(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "precond - attribute is output"); run['default'](function () { run['default'].schedule("render", function () { htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "precond - attribute is not updated sync"); }); context.set("name", "mmun"); run['default'].schedule("render", function () { htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "attribute is updated output"); }); }); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "attribute is updated output"); }); QUnit.test("updates fail silently after an element is destroyed", function () { var context = EmberObject['default'].create({ name: "erik" }); view = EmberView['default'].create({ context: context, template: compile['default']("
Hi!
") }); utils.runAppend(view); htmlbars_test_helpers.equalInnerHTML(view.element, "
Hi!
", "precond - attribute is output"); run['default'](function () { context.set("name", "mmun"); utils.runDestroy(view); }); }); QUnit.module("ember-htmlbars: {{attribute}} helper -- setAttribute", { setup: function () { renderer = new Renderer['default'](env.domHelper); originalSetAttribute = env.domHelper.setAttribute; env.domHelper.setAttribute = function (element, name, value) { if (name.substr(0, 5) === "data-") { setAttributeCalls.push([name, value]); } originalSetAttribute.call(env.domHelper, element, name, value); }; setAttributeCalls = []; }, teardown: function () { env.domHelper.setAttribute = originalSetAttribute; utils.runDestroy(view); } }); QUnit.test("calls setAttribute for new values", function () { var context = EmberObject['default'].create({ name: "erik" }); view = EmberView['default'].create({ renderer: renderer, context: context, template: compile['default']("
Hi!
") }); utils.runAppend(view); run['default'](context, context.set, "name", "mmun"); var expected = [["data-name", "erik"], ["data-name", "mmun"]]; deepEqual(setAttributeCalls, expected); }); QUnit.test("does not call setAttribute if the same value is set", function () { var context = EmberObject['default'].create({ name: "erik" }); view = EmberView['default'].create({ renderer: renderer, context: context, template: compile['default']("
Hi!
") }); utils.runAppend(view); run['default'](function () { context.set("name", "mmun"); context.set("name", "erik"); }); var expected = [["data-name", "erik"]]; deepEqual(setAttributeCalls, expected); }); }); enifed('ember-htmlbars/tests/attr_nodes/data_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/data_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/attr_nodes/data_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/attr_nodes/data_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/data_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/attr_nodes/data_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/attr_nodes/href_test', ['ember-views/views/view', 'ember-metal/run_loop', 'ember-template-compiler/system/compile', 'htmlbars-test-helpers'], function (EmberView, run, compile, htmlbars_test_helpers) { 'use strict'; var view; function appendView(view) { run['default'](function () { view.appendTo("#qunit-fixture"); }); } // jscs:disable validateIndentation QUnit.module("ember-htmlbars: href attribute", { teardown: function () { if (view) { run['default'](view, view.destroy); } } }); QUnit.test("href is set", function () { view = EmberView['default'].create({ context: { url: "http://example.com" }, template: compile['default']("") }); appendView(view); htmlbars_test_helpers.equalInnerHTML(view.element, "", "attribute is output"); }); // jscs:enable validateIndentation }); enifed('ember-htmlbars/tests/attr_nodes/href_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/href_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/attr_nodes/href_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/attr_nodes/href_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/href_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/attr_nodes/href_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/attr_nodes/property_test', ['ember-views/views/view', 'ember-metal/run_loop', 'ember-template-compiler/system/compile'], function (EmberView, run, compile) { 'use strict'; var view; function appendView(view) { run['default'](function () { view.appendTo("#qunit-fixture"); }); } function canSetFalsyMaxLength() { var input = document.createElement("input"); input.maxLength = 0; return input.maxLength === 0; } // jscs:disable validateIndentation QUnit.module("ember-htmlbars: property", { teardown: function () { if (view) { run['default'](view, view.destroy); } } }); QUnit.test("maxlength sets the property and attribute", function () { view = EmberView['default'].create({ context: { length: 5 }, template: compile['default']("") }); appendView(view); equal(view.element.firstChild.maxLength, 5); Ember.run(view, view.set, "context.length", 1); equal(view.element.firstChild.maxLength, 1); }); QUnit.test("quoted maxlength sets the property and attribute", function () { view = EmberView['default'].create({ context: { length: 5 }, template: compile['default']("") }); appendView(view); equal(view.element.firstChild.maxLength, "5"); if (canSetFalsyMaxLength()) { Ember.run(view, view.set, "context.length", null); equal(view.element.firstChild.maxLength, 0); } else { Ember.run(view, view.set, "context.length", 1); equal(view.element.firstChild.maxLength, 1); } }); QUnit.test("array value can be set as property", function () { view = EmberView['default'].create({ context: {}, template: compile['default']("") }); appendView(view); Ember.run(view, view.set, "context.items", [4, 5]); ok(true, "no legacy assertion prohibited setting an array"); }); // jscs:enable validateIndentation }); enifed('ember-htmlbars/tests/attr_nodes/property_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/property_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/attr_nodes/property_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/attr_nodes/property_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/property_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/attr_nodes/property_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/attr_nodes/sanitized_test', ['ember-views/views/view', 'ember-template-compiler/system/compile', 'ember-htmlbars/utils/string', 'ember-runtime/tests/utils', 'ember-metal/environment'], function (EmberView, compile, string, utils, environment) { 'use strict'; /* jshint scripturl:true */ var view; QUnit.module("ember-htmlbars: sanitized attribute", { teardown: function () { utils.runDestroy(view); } }); // jscs:disable validateIndentation // jscs:disable disallowTrailingWhitespace var badTags = [{ tag: "a", attr: "href", unquotedTemplate: compile['default'](""), quotedTemplate: compile['default'](""), multipartTemplate: compile['default']("") }, { tag: "base", attr: "href", unquotedTemplate: compile['default'](""), quotedTemplate: compile['default'](""), multipartTemplate: compile['default']("") }, { tag: "embed", attr: "src", unquotedTemplate: compile['default'](""), quotedTemplate: compile['default'](""), multipartTemplate: compile['default']("") }, { tag: "body", attr: "background", unquotedTemplate: compile['default'](""), quotedTemplate: compile['default'](""), multipartTemplate: compile['default']("") }, { tag: "link", attr: "href", unquotedTemplate: compile['default'](""), quotedTemplate: compile['default'](""), multipartTemplate: compile['default']("") }, { tag: "img", attr: "src", unquotedTemplate: compile['default'](""), quotedTemplate: compile['default'](""), multipartTemplate: compile['default']("") }, { tag: "iframe", attr: "src", // Setting an iframe with a bad protocol results in the browser // being redirected. in IE8. Skip the iframe tests on that platform. skip: environment['default'].hasDOM && document.documentMode && document.documentMode <= 8, unquotedTemplate: compile['default'](""), quotedTemplate: compile['default'](""), multipartTemplate: compile['default']("") }]; for (var i = 0, l = badTags.length; i < l; i++) { (function () { var subject = badTags[i]; if (subject.skip) { return; } QUnit.test(subject.tag + " " + subject.attr + " is sanitized when using blacklisted protocol", function () { view = EmberView['default'].create({ context: { url: "javascript://example.com" }, template: subject.unquotedTemplate }); utils.runAppend(view); equal(view.element.firstChild.getAttribute(subject.attr), "unsafe:javascript://example.com", "attribute is output"); }); QUnit.test(subject.tag + " " + subject.attr + " is sanitized when using quoted non-whitelisted protocol", function () { view = EmberView['default'].create({ context: { url: "javascript://example.com" }, template: subject.quotedTemplate }); utils.runAppend(view); equal(view.element.firstChild.getAttribute(subject.attr), "unsafe:javascript://example.com", "attribute is output"); }); QUnit.test(subject.tag + " " + subject.attr + " is not sanitized when using non-whitelisted protocol with a SafeString", function () { view = EmberView['default'].create({ context: { url: new string.SafeString("javascript://example.com") }, template: subject.unquotedTemplate }); try { utils.runAppend(view); equal(view.element.firstChild.getAttribute(subject.attr), "javascript://example.com", "attribute is output"); } catch (e) { // IE does not allow javascript: to be set on img src ok(true, "caught exception " + e); } }); QUnit.test(subject.tag + " " + subject.attr + " is sanitized when using quoted+concat non-whitelisted protocol", function () { view = EmberView['default'].create({ context: { protocol: "javascript:", path: "//example.com" }, template: subject.multipartTemplate }); utils.runAppend(view); equal(view.element.firstChild.getAttribute(subject.attr), "unsafe:javascript://example.com", "attribute is output"); }); })(); //jshint ignore:line } // jscs:enable disallowTrailingWhitespace // jscs:enable validateIndentation }); enifed('ember-htmlbars/tests/attr_nodes/sanitized_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/sanitized_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/attr_nodes/sanitized_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/attr_nodes/sanitized_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/sanitized_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/attr_nodes/sanitized_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/attr_nodes/style_test', ['ember-metal/core', 'ember-views/views/view', 'ember-template-compiler/system/compile', 'ember-htmlbars/utils/string', 'ember-runtime/tests/utils', 'ember-views/attr_nodes/attr_node'], function (Ember, EmberView, compile, string, utils, attr_node) { 'use strict'; /* globals EmberDev */ var view, originalWarn, warnings; QUnit.module("ember-htmlbars: style attribute", { setup: function () { warnings = []; originalWarn = Ember['default'].warn; Ember['default'].warn = function (message, test) { if (!test) { warnings.push(message); } }; }, teardown: function () { utils.runDestroy(view); Ember['default'].warn = originalWarn; } }); // jscs:disable validateIndentation if (!EmberDev.runningProdBuild) { QUnit.test("specifying `
` generates a warning", function () { view = EmberView['default'].create({ userValue: "width: 42px", template: compile['default']("
") }); utils.runAppend(view); deepEqual(warnings, [attr_node.styleWarning]); }); QUnit.test("specifying `attributeBindings: [\"style\"]` generates a warning", function () { view = EmberView['default'].create({ userValue: "width: 42px", template: compile['default']("
") }); utils.runAppend(view); deepEqual(warnings, [attr_node.styleWarning]); }); } QUnit.test("specifying `
` works properly without a warning", function () { view = EmberView['default'].create({ userValue: "width: 42px", template: compile['default']("
") }); utils.runAppend(view); deepEqual(warnings, []); }); QUnit.test("specifying `
` works properly with a SafeString", function () { view = EmberView['default'].create({ userValue: new string.SafeString("width: 42px"), template: compile['default']("
") }); utils.runAppend(view); deepEqual(warnings, []); }); // jscs:enable validateIndentation }); enifed('ember-htmlbars/tests/attr_nodes/style_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/style_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/attr_nodes/style_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/attr_nodes/style_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/style_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/attr_nodes/style_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/attr_nodes/svg_test', ['ember-views/views/view', 'ember-metal/run_loop', 'ember-template-compiler/system/compile', 'htmlbars-test-helpers'], function (EmberView, run, compile, htmlbars_test_helpers) { 'use strict'; var view; function appendView(view) { run['default'](function () { view.appendTo("#qunit-fixture"); }); } // jscs:disable validateIndentation QUnit.module("ember-htmlbars: svg attribute", { teardown: function () { if (view) { run['default'](view, view.destroy); } } }); QUnit.test("unquoted viewBox property is output", function () { var viewBoxString = "0 0 100 100"; view = EmberView['default'].create({ context: { viewBoxString: viewBoxString }, template: compile['default']("") }); appendView(view); htmlbars_test_helpers.equalInnerHTML(view.element, "", "attribute is output"); Ember.run(view, view.set, "context.viewBoxString", null); equal(view.element.getAttribute("svg"), null, "attribute is removed"); }); QUnit.test("quoted viewBox property is output", function () { var viewBoxString = "0 0 100 100"; view = EmberView['default'].create({ context: { viewBoxString: viewBoxString }, template: compile['default']("") }); appendView(view); htmlbars_test_helpers.equalInnerHTML(view.element, "", "attribute is output"); }); QUnit.test("quoted viewBox property is concat", function () { var viewBoxString = "100 100"; view = EmberView['default'].create({ context: { viewBoxString: viewBoxString }, template: compile['default']("") }); appendView(view); htmlbars_test_helpers.equalInnerHTML(view.element, "", "attribute is output"); var newViewBoxString = "200 200"; Ember.run(view, view.set, "context.viewBoxString", newViewBoxString); htmlbars_test_helpers.equalInnerHTML(view.element, "", "attribute is output"); }); QUnit.test("class is output", function () { view = EmberView['default'].create({ context: { color: "blue" }, template: compile['default']("") }); appendView(view); htmlbars_test_helpers.equalInnerHTML(view.element, "", "attribute is output"); Ember.run(view, view.set, "context.color", "red"); htmlbars_test_helpers.equalInnerHTML(view.element, "", "attribute is output"); }); // jscs:enable validateIndentation }); enifed('ember-htmlbars/tests/attr_nodes/svg_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/svg_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/attr_nodes/svg_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/attr_nodes/svg_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/svg_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/attr_nodes/svg_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/attr_nodes/value_test', ['ember-views/views/view', 'ember-metal/run_loop', 'ember-template-compiler/system/compile'], function (EmberView, run, compile) { 'use strict'; var view; function appendView(view) { run['default'](function () { view.appendTo("#qunit-fixture"); }); } // jscs:disable validateIndentation QUnit.module("ember-htmlbars: value attribute", { teardown: function () { if (view) { run['default'](view, view.destroy); } } }); QUnit.test("property is output", function () { view = EmberView['default'].create({ context: { name: "rick" }, template: compile['default']("") }); appendView(view); equal(view.element.firstChild.tagName, "INPUT", "input element is created"); equal(view.element.firstChild.value, "rick", "property is set true"); }); QUnit.test("string property is output", function () { view = EmberView['default'].create({ context: { name: "rick" }, template: compile['default']("") }); appendView(view); equal(view.element.firstChild.tagName, "INPUT", "input element is created"); equal(view.element.firstChild.value, "rick", "property is set true"); }); QUnit.test("blank property is output", function () { view = EmberView['default'].create({ context: { name: "" }, template: compile['default']("") }); appendView(view); equal(view.element.firstChild.tagName, "INPUT", "input element is created"); equal(view.element.firstChild.value, "", "property is set true"); }); // jscs:enable validateIndentation }); enifed('ember-htmlbars/tests/attr_nodes/value_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/value_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/attr_nodes/value_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/attr_nodes/value_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/attr_nodes"); test("ember-htmlbars/tests/attr_nodes/value_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/attr_nodes/value_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/compat/handlebars_get_test', ['ember-metal/core', 'ember-views/views/metamorph_view', 'ember-views/views/view', 'ember-htmlbars/compat/handlebars-get', 'ember-runtime/system/container', 'ember-runtime/tests/utils', 'ember-htmlbars/compat'], function (Ember, _MetamorphView, EmberView, handlebarsGet, system__container, utils, EmberHandlebars) { 'use strict'; var compile = EmberHandlebars['default'].compile; var originalLookup = Ember['default'].lookup; var TemplateTests, registry, container, lookup, view; QUnit.module("ember-htmlbars: Ember.Handlebars.get", { setup: function () { Ember['default'].lookup = lookup = {}; registry = new system__container.Registry(); container = registry.container(); registry.optionsForType("template", { instantiate: false }); registry.optionsForType("helper", { instantiate: false }); registry.register("view:default", _MetamorphView['default']); registry.register("view:toplevel", EmberView['default'].extend()); }, teardown: function () { utils.runDestroy(container); utils.runDestroy(view); registry = container = view = null; Ember['default'].lookup = lookup = originalLookup; TemplateTests = null; } }); QUnit.test("it can lookup a path from the current context", function () { expect(1); registry.register("helper:handlebars-get", function (path, options) { var context = options.contexts && options.contexts[0] || this; ignoreDeprecation(function () { equal(handlebarsGet['default'](context, path, options), "bar"); }); }); view = EmberView['default'].create({ container: container, controller: { foo: "bar" }, template: compile("{{handlebars-get \"foo\"}}") }); utils.runAppend(view); }); QUnit.test("it can lookup a path from the current keywords", function () { expect(1); registry.register("helper:handlebars-get", function (path, options) { var context = options.contexts && options.contexts[0] || this; ignoreDeprecation(function () { equal(handlebarsGet['default'](context, path, options), "bar"); }); }); view = EmberView['default'].create({ container: container, controller: { foo: "bar" }, template: compile("{{#with foo as bar}}{{handlebars-get \"bar\"}}{{/with}}") }); utils.runAppend(view); }); QUnit.test("it can lookup a path from globals", function () { expect(1); lookup.Blammo = { foo: "blah" }; registry.register("helper:handlebars-get", function (path, options) { var context = options.contexts && options.contexts[0] || this; ignoreDeprecation(function () { equal(handlebarsGet['default'](context, path, options), lookup.Blammo.foo); }); }); view = EmberView['default'].create({ container: container, controller: {}, template: compile("{{handlebars-get \"Blammo.foo\"}}") }); utils.runAppend(view); }); QUnit.test("it raises a deprecation warning on use", function () { expect(1); registry.register("helper:handlebars-get", function (path, options) { var context = options.contexts && options.contexts[0] || this; expectDeprecation(function () { handlebarsGet['default'](context, path, options); }, "Usage of Ember.Handlebars.get is deprecated, use a Component or Ember.Handlebars.makeBoundHelper instead."); }); view = EmberView['default'].create({ container: container, controller: { foo: "bar" }, template: compile("{{handlebars-get \"foo\"}}") }); utils.runAppend(view); }); }); enifed('ember-htmlbars/tests/compat/handlebars_get_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/compat"); test("ember-htmlbars/tests/compat/handlebars_get_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/compat/handlebars_get_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/compat/handlebars_get_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/compat"); test("ember-htmlbars/tests/compat/handlebars_get_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/compat/handlebars_get_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/compat/helper_test', ['ember-htmlbars/compat/helper', 'ember-views/views/view', 'ember-views/views/component', 'ember-htmlbars/system/make-view-helper', 'ember-htmlbars/helpers', 'ember-template-compiler/system/compile', 'ember-runtime/tests/utils'], function (compat__helper, EmberView, Component, makeViewHelper, helpers, compile, utils) { 'use strict'; var view; QUnit.module("ember-htmlbars: Handlebars compatible helpers", { teardown: function () { utils.runDestroy(view); delete helpers['default'].test; delete helpers['default']["view-helper"]; } }); QUnit.test("wraps provided function so that original path params are provided to the helper", function () { expect(2); function someHelper(param1, param2, options) { equal(param1, "blammo"); equal(param2, "blazzico"); } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { value: "foo" }, template: compile['default']("{{test \"blammo\" \"blazzico\"}}") }); utils.runAppend(view); }); QUnit.test("combines `env` and `options` for the wrapped helper", function () { expect(1); function someHelper(options) { equal(options.data.view, view); } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { value: "foo" }, template: compile['default']("{{test}}") }); utils.runAppend(view); }); QUnit.test("adds `hash` into options `options` for the wrapped helper", function () { expect(1); function someHelper(options) { equal(options.hash.bestFriend, "Jacquie"); } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { value: "foo" }, template: compile['default']("{{test bestFriend=\"Jacquie\"}}") }); utils.runAppend(view); }); QUnit.test("bound `hash` params are provided with their original paths", function () { expect(1); function someHelper(options) { equal(options.hash.bestFriend, "value"); } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { value: "Jacquie" }, template: compile['default']("{{test bestFriend=value}}") }); utils.runAppend(view); }); QUnit.test("bound ordered params are provided with their original paths", function () { expect(2); function someHelper(param1, param2, options) { equal(param1, "first"); equal(param2, "second"); } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { first: "blammo", second: "blazzico" }, template: compile['default']("{{test first second}}") }); utils.runAppend(view); }); QUnit.test("allows unbound usage within an element", function () { expect(4); function someHelper(param1, param2, options) { equal(param1, "blammo"); equal(param2, "blazzico"); return "class='foo'"; } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { value: "foo" }, template: compile['default']("
Bar
") }); expectDeprecation(function () { utils.runAppend(view); }, "Returning a string of attributes from a helper inside an element is deprecated."); equal(view.$(".foo").length, 1, "class attribute was added by helper"); }); QUnit.test("registering a helper created from `Ember.Handlebars.makeViewHelper` does not double wrap the helper", function () { expect(1); var ViewHelperComponent = Component['default'].extend({ layout: compile['default']("woot!") }); var helper = makeViewHelper['default'](ViewHelperComponent); compat__helper.registerHandlebarsCompatibleHelper("view-helper", helper); view = EmberView['default'].extend({ template: compile['default']("{{view-helper}}") }).create(); utils.runAppend(view); equal(view.$().text(), "woot!"); }); QUnit.test("does not add `options.fn` if no block was specified", function () { expect(1); function someHelper(options) { ok(!options.fn, "`options.fn` is not present when block is not specified"); } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { value: "foo" }, template: compile['default']("{{test}}") }); utils.runAppend(view); }); QUnit.test("does not return helper result if block was specified", function () { expect(1); function someHelper(options) { return "asdf"; } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { value: "foo" }, template: compile['default']("{{#test}}lkj;{{/test}}") }); utils.runAppend(view); equal(view.$().text(), ""); }); QUnit.test("allows usage of the template fn", function () { expect(1); function someHelper(options) { options.fn(); } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { value: "foo" }, template: compile['default']("{{#test}}{{value}}{{/test}}") }); utils.runAppend(view); equal(view.$().text(), "foo"); }); QUnit.test("allows usage of the template inverse", function () { expect(1); function someHelper(options) { options.inverse(); } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { value: "foo" }, template: compile['default']("{{#test}}Nothing to see here.{{else}}{{value}}{{/test}}") }); utils.runAppend(view); equal(view.$().text(), "foo"); }); QUnit.test("ordered param types are added to options.types", function () { expect(3); function someHelper(param1, param2, param3, options) { equal(options.types[0], "NUMBER"); equal(options.types[1], "ID"); equal(options.types[2], "STRING"); } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { first: "blammo", second: "blazzico" }, template: compile['default']("{{test 1 two \"3\"}}") }); utils.runAppend(view); }); QUnit.test("`hash` params are to options.hashTypes", function () { expect(3); function someHelper(options) { equal(options.hashTypes.string, "STRING"); equal(options.hashTypes.number, "NUMBER"); equal(options.hashTypes.id, "ID"); } compat__helper.registerHandlebarsCompatibleHelper("test", someHelper); view = EmberView['default'].create({ controller: { value: "Jacquie" }, template: compile['default']("{{test string=\"foo\" number=42 id=someBoundThing}}") }); utils.runAppend(view); }); }); enifed('ember-htmlbars/tests/compat/helper_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/compat"); test("ember-htmlbars/tests/compat/helper_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/compat/helper_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/compat/helper_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/compat"); test("ember-htmlbars/tests/compat/helper_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/compat/helper_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/compat/make-view-helper_test', ['ember-views/views/view', 'container/registry', 'ember-template-compiler/system/compile', 'ember-htmlbars/system/make-view-helper', 'ember-views/views/component', 'ember-runtime/tests/utils'], function (EmberView, Registry, compile, makeViewHelper, Component, utils) { 'use strict'; var registry, container, view; QUnit.module("ember-htmlbars: makeViewHelper compat", { setup: function () { registry = new Registry['default'](); container = registry.container(); registry.optionsForType("helper", { instantiate: false }); }, teardown: function () { utils.runDestroy(container); utils.runDestroy(view); registry = container = view = null; } }); QUnit.test("makeViewHelper", function () { expect(1); var ViewHelperComponent = Component['default'].extend({ layout: compile['default']("woot!") }); var helper = makeViewHelper['default'](ViewHelperComponent); registry.register("helper:view-helper", helper); view = EmberView['default'].extend({ template: compile['default']("{{view-helper}}"), container: container }).create(); utils.runAppend(view); equal(view.$().text(), "woot!"); }); }); enifed('ember-htmlbars/tests/compat/make-view-helper_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/compat"); test("ember-htmlbars/tests/compat/make-view-helper_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/compat/make-view-helper_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/compat/make-view-helper_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/compat"); test("ember-htmlbars/tests/compat/make-view-helper_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/compat/make-view-helper_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/compat/make_bound_helper_test', ['ember-views/views/view', 'ember-metal/run_loop', 'ember-runtime/system/object', 'ember-runtime/system/native_array', 'ember-views/views/simple_bound_view', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-runtime/tests/utils', 'ember-runtime/system/string', 'ember-htmlbars/compat'], function (EmberView, run, EmberObject, native_array, SimpleBoundView, property_get, property_set, utils, string, EmberHandlebars) { 'use strict'; /*jshint newcap:false*/ var compile, helpers, helper; compile = EmberHandlebars['default'].compile; helpers = EmberHandlebars['default'].helpers; helper = EmberHandlebars['default'].helper; var view; var originalLookup = Ember.lookup; function registerRepeatHelper() { expectDeprecationInHTMLBars(); helper("repeat", function (value, options) { var count = options.hash.count || 1; var a = []; while (a.length < count) { a.push(value); } return a.join(""); }); } function expectDeprecationInHTMLBars() {} QUnit.module("ember-htmlbars: makeBoundHelper", { setup: function () {}, teardown: function () { utils.runDestroy(view); Ember.lookup = originalLookup; } }); QUnit.test("primitives should work correctly [DEPRECATED]", function () { expectDeprecation("Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each foo in bar}}`) instead."); expectDeprecation("Using the context switching form of `{{with}}` is deprecated. Please use the keyword form (`{{with foo as bar}}`) instead."); view = EmberView['default'].create({ prims: Ember.A(["string", 12]), template: compile("{{#each view.prims}}{{#if this}}inside-if{{/if}}{{#with this}}inside-with{{/with}}{{/each}}") }); utils.runAppend(view); equal(view.$().text(), "inside-ifinside-withinside-ifinside-with"); }); QUnit.test("should update bound helpers when properties change", function () { expectDeprecationInHTMLBars(); helper("capitalize", function (value) { return value.toUpperCase(); }); view = EmberView['default'].create({ controller: EmberObject['default'].create({ name: "Brogrammer" }), template: compile("{{capitalize name}}") }); utils.runAppend(view); equal(view.$().text(), "BROGRAMMER", "helper output is correct"); run['default'](function () { property_set.set(view, "controller.name", "wes"); }); equal(view.$().text(), "WES", "helper output updated"); }); QUnit.test("should update bound helpers in a subexpression when properties change", function () { expectDeprecationInHTMLBars(); helper("dasherize", function (value) { return string.dasherize(value); }); view = EmberView['default'].create({ controller: { prop: "isThing" }, template: compile("
{{prop}}
") }); utils.runAppend(view); equal(view.$("div[data-foo=\"is-thing\"]").text(), "isThing", "helper output is correct"); run['default'](view, "set", "controller.prop", "notThing"); equal(view.$("div[data-foo=\"not-thing\"]").text(), "notThing", "helper output is correct"); }); QUnit.test("should allow for computed properties with dependencies", function () { expectDeprecationInHTMLBars(); helper("capitalizeName", function (value) { return property_get.get(value, "name").toUpperCase(); }, "name"); view = EmberView['default'].create({ controller: EmberObject['default'].create({ person: EmberObject['default'].create({ name: "Brogrammer" }) }), template: compile("{{capitalizeName person}}") }); utils.runAppend(view); equal(view.$().text(), "BROGRAMMER", "helper output is correct"); run['default'](function () { property_set.set(view, "controller.person.name", "wes"); }); equal(view.$().text(), "WES", "helper output updated"); }); QUnit.test("bound helpers should support options", function () { registerRepeatHelper(); view = EmberView['default'].create({ controller: EmberObject['default'].create({ text: "ab" }), template: compile("{{repeat text count=3}}") }); utils.runAppend(view); equal(view.$().text(), "ababab", "helper output is correct"); }); QUnit.test("bound helpers should support keywords", function () { expectDeprecationInHTMLBars(); helper("capitalize", function (value) { return value.toUpperCase(); }); view = EmberView['default'].create({ text: "ab", template: compile("{{capitalize view.text}}") }); utils.runAppend(view); equal(view.$().text(), "AB", "helper output is correct"); }); QUnit.test("bound helpers should support global paths [DEPRECATED]", function () { expectDeprecationInHTMLBars(); helper("capitalize", function (value) { return value.toUpperCase(); }); Ember.lookup = { Text: "ab" }; view = EmberView['default'].create({ template: compile("{{capitalize Text}}") }); expectDeprecation(function () { utils.runAppend(view); }, /Global lookup of Text from a Handlebars template is deprecated/); equal(view.$().text(), "AB", "helper output is correct"); }); QUnit.test("bound helper should support this keyword", function () { expectDeprecationInHTMLBars(); helper("capitalize", function (value) { return property_get.get(value, "text").toUpperCase(); }); view = EmberView['default'].create({ controller: EmberObject['default'].create({ text: "ab" }), template: compile("{{capitalize this}}") }); utils.runAppend(view); equal(view.$().text(), "AB", "helper output is correct"); }); QUnit.test("bound helpers should support bound options", function () { registerRepeatHelper(); view = EmberView['default'].create({ controller: EmberObject['default'].create({ text: "ab", numRepeats: 3 }), template: compile("{{repeat text countBinding=\"numRepeats\"}}") }); utils.runAppend(view); equal(view.$().text(), "ababab", "helper output is correct"); run['default'](function () { view.set("controller.numRepeats", 4); }); equal(view.$().text(), "abababab", "helper correctly re-rendered after bound option was changed"); run['default'](function () { view.set("controller.numRepeats", 2); view.set("controller.text", "YES"); }); equal(view.$().text(), "YESYES", "helper correctly re-rendered after both bound option and property changed"); }); QUnit.test("bound helpers should support unquoted values as bound options", function () { registerRepeatHelper(); view = EmberView['default'].create({ controller: EmberObject['default'].create({ text: "ab", numRepeats: 3 }), template: compile("{{repeat text count=numRepeats}}") }); utils.runAppend(view); equal(view.$().text(), "ababab", "helper output is correct"); run['default'](function () { view.set("controller.numRepeats", 4); }); equal(view.$().text(), "abababab", "helper correctly re-rendered after bound option was changed"); run['default'](function () { view.set("controller.numRepeats", 2); view.set("controller.text", "YES"); }); equal(view.$().text(), "YESYES", "helper correctly re-rendered after both bound option and property changed"); }); QUnit.test("bound helpers should support multiple bound properties", function () { expectDeprecationInHTMLBars(); helper("combine", function () { return [].slice.call(arguments, 0, -1).join(""); }); view = EmberView['default'].create({ controller: EmberObject['default'].create({ thing1: "ZOID", thing2: "BERG" }), template: compile("{{combine thing1 thing2}}") }); utils.runAppend(view); equal(view.$().text(), "ZOIDBERG", "helper output is correct"); run['default'](function () { view.set("controller.thing2", "NERD"); }); equal(view.$().text(), "ZOIDNERD", "helper correctly re-rendered after second bound helper property changed"); run['default'](function () { view.get("controller").setProperties({ thing1: "WOOT", thing2: "YEAH" }); }); equal(view.$().text(), "WOOTYEAH", "helper correctly re-rendered after both bound helper properties changed"); }); QUnit.test("bound helpers should expose property names in options.data.properties", function () { expectDeprecationInHTMLBars(); helper("echo", function () { var options = arguments[arguments.length - 1]; var values = [].slice.call(arguments, 0, -1); var a = []; for (var i = 0; i < values.length; ++i) { var propertyName = options.data.properties[i]; a.push(propertyName); } return a.join(" "); }); view = EmberView['default'].create({ controller: EmberObject['default'].create({ thing1: "ZOID", thing2: "BERG", thing3: EmberObject['default'].create({ foo: 123 }) }), template: compile("{{echo thing1 thing2 thing3.foo}}") }); utils.runAppend(view); equal(view.$().text(), "thing1 thing2 thing3.foo", "helper output is correct"); }); QUnit.test("bound helpers can be invoked with zero args", function () { expectDeprecationInHTMLBars(); helper("troll", function (options) { return options.hash.text || "TROLOLOL"; }); view = EmberView['default'].create({ controller: EmberObject['default'].create({ trollText: "yumad" }), template: compile("{{troll}} and {{troll text=\"bork\"}}") }); utils.runAppend(view); equal(view.$().text(), "TROLOLOL and bork", "helper output is correct"); }); QUnit.test("bound helpers should not be invoked with blocks", function () { registerRepeatHelper(); view = EmberView['default'].create({ controller: EmberObject['default'].create({}), template: compile("{{#repeat}}Sorry, Charlie{{/repeat}}") }); expectAssertion(function () { utils.runAppend(view); }, /registerBoundHelper-generated helpers do not support use with Handlebars blocks/i); }); QUnit.test("should observe dependent keys passed to registerBoundHelper", function () { try { expectDeprecationInHTMLBars(); var simplyObject = EmberObject['default'].create({ firstName: "Jim", lastName: "Owen", birthday: EmberObject['default'].create({ year: "2009" }) }); helper("fullName", function (value) { return [value.get("firstName"), value.get("lastName"), value.get("birthday.year")].join(" "); }, "firstName", "lastName", "birthday.year"); view = EmberView['default'].create({ template: compile("{{fullName this}}"), context: simplyObject }); utils.runAppend(view); equal(view.$().text(), "Jim Owen 2009", "simply render the helper"); run['default'](simplyObject, simplyObject.set, "firstName", "Tom"); equal(view.$().text(), "Tom Owen 2009", "render the helper after prop change"); run['default'](simplyObject, simplyObject.set, "birthday.year", "1692"); equal(view.$().text(), "Tom Owen 1692", "render the helper after path change"); } finally { delete helpers["fullName"]; } }); QUnit.test("shouldn't treat raw numbers as bound paths", function () { expectDeprecationInHTMLBars(); helper("sum", function (a, b) { return a + b; }); view = EmberView['default'].create({ controller: EmberObject['default'].create({ aNumber: 1 }), template: compile("{{sum aNumber 1}} {{sum 0 aNumber}} {{sum 5 6}}") }); utils.runAppend(view); equal(view.$().text(), "2 1 11", "helper output is correct"); run['default'](view, "set", "controller.aNumber", 5); equal(view.$().text(), "6 5 11", "helper still updates as expected"); }); QUnit.test("shouldn't treat quoted strings as bound paths", function () { expectDeprecationInHTMLBars(); var helperCount = 0; helper("combine", function (a, b, opt) { helperCount++; return a + b; }); view = EmberView['default'].create({ controller: EmberObject['default'].create({ word: "jerkwater", loo: "unused" }), template: compile("{{combine word 'loo'}} {{combine '' word}} {{combine 'will' \"didi\"}}") }); utils.runAppend(view); equal(view.$().text(), "jerkwaterloo jerkwater willdidi", "helper output is correct"); run['default'](view, "set", "controller.word", "bird"); equal(view.$().text(), "birdloo bird willdidi", "helper still updates as expected"); run['default'](view, "set", "controller.loo", "soup-de-doo"); equal(view.$().text(), "birdloo bird willdidi", "helper still updates as expected"); equal(helperCount, 5, "changing controller property with same name as quoted string doesn't re-render helper"); }); QUnit.test("bound helpers can handle nulls in array (with primitives) [DEPRECATED]", function () { expectDeprecationInHTMLBars(); helper("reverse", function (val) { return val ? val.split("").reverse().join("") : "NOPE"; }); view = EmberView['default'].create({ controller: EmberObject['default'].create({ things: native_array.A([null, 0, undefined, false, "OMG"]) }), template: compile("{{#each things}}{{this}}|{{reverse this}} {{/each}}{{#each thing in things}}{{thing}}|{{reverse thing}} {{/each}}") }); expectDeprecation(function () { utils.runAppend(view); }, "Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each foo in bar}}`) instead."); equal(view.$().text(), "|NOPE 0|NOPE |NOPE false|NOPE OMG|GMO |NOPE 0|NOPE |NOPE false|NOPE OMG|GMO ", "helper output is correct"); run['default'](function () { view.get("controller.things").pushObject("blorg"); view.get("controller.things").shiftObject(); }); equal(view.$().text(), "0|NOPE |NOPE false|NOPE OMG|GMO blorg|grolb 0|NOPE |NOPE false|NOPE OMG|GMO blorg|grolb ", "helper output is still correct"); }); QUnit.test("bound helpers can handle nulls in array (with objects)", function () { expectDeprecationInHTMLBars(); helper("print-foo", function (val) { return val ? property_get.get(val, "foo") : "NOPE"; }); view = EmberView['default'].create({ controller: EmberObject['default'].create({ things: native_array.A([null, { foo: 5 }]) }), template: compile("{{#each things}}{{foo}}|{{print-foo this}} {{/each}}{{#each thing in things}}{{thing.foo}}|{{print-foo thing}} {{/each}}") }); expectDeprecation(function () { utils.runAppend(view); }, "Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each foo in bar}}`) instead."); equal(view.$().text(), "|NOPE 5|5 |NOPE 5|5 ", "helper output is correct"); run['default'](view.get("controller.things"), "pushObject", { foo: 6 }); equal(view.$().text(), "|NOPE 5|5 6|6 |NOPE 5|5 6|6 ", "helper output is correct"); }); QUnit.test("bound helpers can handle `this` keyword when it's a non-object", function () { expectDeprecationInHTMLBars(); helper("shout", function (value) { return value + "!"; }); view = EmberView['default'].create({ context: "alex", template: compile("{{shout this}}") }); utils.runAppend(view); equal(view.$().text(), "alex!", "helper output is correct"); run['default'](function () { property_set.set(view, "context", ""); }); equal(view.$().text(), "!", "helper output is correct"); run['default'](function () { property_set.set(view, "context", "wallace"); }); equal(view.$().text(), "wallace!", "helper output is correct"); }); QUnit.test("should have correct argument types", function () { expectDeprecationInHTMLBars(); helper("getType", function (value) { return typeof value; }); view = EmberView['default'].create({ controller: EmberObject['default'].create(), template: compile("{{getType null}}, {{getType undefProp}}, {{getType \"string\"}}, {{getType 1}}, {{getType}}") }); utils.runAppend(view); equal(view.$().text(), "undefined, undefined, string, number, object", "helper output is correct"); }); QUnit.test("when no parameters are bound, no new views are created", function () { registerRepeatHelper(); var originalRender = SimpleBoundView['default'].prototype.render; var renderWasCalled = false; SimpleBoundView['default'].prototype.render = function () { renderWasCalled = true; return originalRender.apply(this, arguments); }; try { view = EmberView['default'].create({ template: compile("{{repeat \"a\"}}"), controller: EmberObject['default'].create() }); utils.runAppend(view); } finally { SimpleBoundView['default'].prototype.render = originalRender; } ok(!renderWasCalled, "simple bound view should not have been created and rendered"); equal(view.$().text(), "a"); }); QUnit.test("when no hash parameters are bound, no new views are created", function () { registerRepeatHelper(); var originalRender = SimpleBoundView['default'].prototype.render; var renderWasCalled = false; SimpleBoundView['default'].prototype.render = function () { renderWasCalled = true; return originalRender.apply(this, arguments); }; try { view = EmberView['default'].create({ template: compile("{{repeat \"a\" count=3}}"), controller: EmberObject['default'].create() }); utils.runAppend(view); } finally { SimpleBoundView['default'].prototype.render = originalRender; } ok(!renderWasCalled, "simple bound view should not have been created and rendered"); equal(view.$().text(), "aaa"); }); // leave this empty function as a place holder to // enable a deprecation notice }); enifed('ember-htmlbars/tests/compat/make_bound_helper_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/compat"); test("ember-htmlbars/tests/compat/make_bound_helper_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/compat/make_bound_helper_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/compat/make_bound_helper_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/compat"); test("ember-htmlbars/tests/compat/make_bound_helper_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/compat/make_bound_helper_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/compat/precompile_test', ['ember-htmlbars/compat'], function (EmberHandlebars) { 'use strict'; var precompile = EmberHandlebars['default'].precompile; var template = "Hello World"; var result; QUnit.module("ember-htmlbars: Ember.Handlebars.precompile"); QUnit.test("precompile creates an object when asObject isn't defined", function () { result = precompile(template); equal(typeof result, "object"); }); QUnit.test("precompile creates an object when asObject is true", function () { result = precompile(template, true); equal(typeof result, "object"); }); QUnit.test("precompile creates a string when asObject is false", function () { result = precompile(template, false); equal(typeof result, "string"); }); }); enifed('ember-htmlbars/tests/compat/precompile_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/compat"); test("ember-htmlbars/tests/compat/precompile_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/compat/precompile_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/compat/precompile_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/compat"); test("ember-htmlbars/tests/compat/precompile_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/compat/precompile_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/helpers/bind_attr_test', ['ember-metal/core', 'ember-metal/run_loop', 'ember-runtime/system/namespace', 'ember-views/views/view', 'ember-views/views/metamorph_view', 'ember-runtime/system/object', 'ember-runtime/system/native_array', 'ember-metal/computed', 'ember-metal/observer', 'ember-runtime/system/container', 'ember-metal/property_set', 'ember-runtime/tests/utils', 'ember-views/attr_nodes/attr_node', 'ember-htmlbars/utils/string', 'ember-htmlbars/helpers', 'ember-template-compiler/system/compile'], function (Ember, run, Namespace, EmberView, _MetamorphView, EmberObject, native_array, computed, observer, system__container, property_set, utils, attr_node, string, helpers, compile) { 'use strict'; /*globals EmberDev */ /*jshint newcap:false*/ var view; var originalLookup = Ember['default'].lookup; var TemplateTests, registry, container, lookup, warnings, originalWarn; /** This module specifically tests integration with Handlebars and Ember-specific Handlebars extensions. If you add additional template support to View, you should create a new file in which to test. */ QUnit.module("ember-htmlbars: {{bind-attr}}", { setup: function () { Ember['default'].lookup = lookup = {}; lookup.TemplateTests = TemplateTests = Namespace['default'].create(); registry = new system__container.Registry(); container = registry.container(); registry.optionsForType("template", { instantiate: false }); registry.register("view:default", _MetamorphView['default']); registry.register("view:toplevel", EmberView['default'].extend()); warnings = []; originalWarn = Ember['default'].warn; Ember['default'].warn = function (message, test) { if (!test) { warnings.push(message); } }; }, teardown: function () { utils.runDestroy(container); utils.runDestroy(view); registry = container = view = null; Ember['default'].lookup = lookup = originalLookup; Ember['default'].warn = originalWarn; TemplateTests = null; } }); QUnit.test("should be able to bind element attributes using {{bind-attr}}", function () { var template = compile['default']("view.content.title}}"); view = EmberView['default'].create({ template: template, content: EmberObject['default'].create({ url: "http://www.emberjs.com/assets/images/logo.png", title: "The SproutCore Logo" }) }); utils.runAppend(view); equal(view.$("img").attr("src"), "http://www.emberjs.com/assets/images/logo.png", "sets src attribute"); equal(view.$("img").attr("alt"), "The SproutCore Logo", "sets alt attribute"); run['default'](function () { property_set.set(view, "content.title", "El logo de Eember"); }); equal(view.$("img").attr("alt"), "El logo de Eember", "updates alt attribute when content's title attribute changes"); run['default'](function () { property_set.set(view, "content", EmberObject['default'].create({ url: "http://www.thegooglez.com/theydonnothing", title: "I CAN HAZ SEARCH" })); }); equal(view.$("img").attr("alt"), "I CAN HAZ SEARCH", "updates alt attribute when content object changes"); run['default'](function () { property_set.set(view, "content", { url: "http://www.emberjs.com/assets/images/logo.png", title: "The SproutCore Logo" }); }); equal(view.$("img").attr("alt"), "The SproutCore Logo", "updates alt attribute when content object is a hash"); run['default'](function () { property_set.set(view, "content", EmberObject['default'].createWithMixins({ url: "http://www.emberjs.com/assets/images/logo.png", title: computed.computed(function () { return "Nanananana Ember!"; }) })); }); equal(view.$("img").attr("alt"), "Nanananana Ember!", "updates alt attribute when title property is computed"); }); QUnit.test("should be able to bind to view attributes with {{bind-attr}}", function () { view = EmberView['default'].create({ value: "Test", template: compile['default']("view.value}}") }); utils.runAppend(view); equal(view.$("img").attr("alt"), "Test", "renders initial value"); run['default'](function () { view.set("value", "Updated"); }); equal(view.$("img").attr("alt"), "Updated", "updates value"); }); QUnit.test("should be able to bind to globals with {{bind-attr}} (DEPRECATED)", function () { TemplateTests.set("value", "Test"); view = EmberView['default'].create({ template: compile['default']("TemplateTests.value}}") }); expectDeprecation(function () { utils.runAppend(view); }, /Global lookup of TemplateTests.value from a Handlebars template is deprecated/); equal(view.$("img").attr("alt"), "Test", "renders initial value"); }); QUnit.test("should not allow XSS injection via {{bind-attr}}", function () { view = EmberView['default'].create({ template: compile['default']("view.content.value}}"), content: { value: "Trololol\" onmouseover=\"alert('HAX!');" } }); utils.runAppend(view); equal(view.$("img").attr("onmouseover"), undefined); // If the whole string is here, then it means we got properly escaped equal(view.$("img").attr("alt"), "Trololol\" onmouseover=\"alert('HAX!');"); }); QUnit.test("should be able to bind use {{bind-attr}} more than once on an element", function () { var template = compile['default']("view.content.title}}"); view = EmberView['default'].create({ template: template, content: EmberObject['default'].create({ url: "http://www.emberjs.com/assets/images/logo.png", title: "The SproutCore Logo" }) }); utils.runAppend(view); equal(view.$("img").attr("src"), "http://www.emberjs.com/assets/images/logo.png", "sets src attribute"); equal(view.$("img").attr("alt"), "The SproutCore Logo", "sets alt attribute"); run['default'](function () { property_set.set(view, "content.title", "El logo de Eember"); }); equal(view.$("img").attr("alt"), "El logo de Eember", "updates alt attribute when content's title attribute changes"); run['default'](function () { property_set.set(view, "content", EmberObject['default'].create({ url: "http://www.thegooglez.com/theydonnothing", title: "I CAN HAZ SEARCH" })); }); equal(view.$("img").attr("alt"), "I CAN HAZ SEARCH", "updates alt attribute when content object changes"); run['default'](function () { property_set.set(view, "content", { url: "http://www.emberjs.com/assets/images/logo.png", title: "The SproutCore Logo" }); }); equal(view.$("img").attr("alt"), "The SproutCore Logo", "updates alt attribute when content object is a hash"); run['default'](function () { property_set.set(view, "content", EmberObject['default'].createWithMixins({ url: "http://www.emberjs.com/assets/images/logo.png", title: computed.computed(function () { return "Nanananana Ember!"; }) })); }); equal(view.$("img").attr("alt"), "Nanananana Ember!", "updates alt attribute when title property is computed"); }); QUnit.test("{{bindAttr}} is aliased to {{bind-attr}}", function () { expect(4); var originalBindAttr = helpers['default']["bind-attr"]; try { helpers['default']["bind-attr"] = { helperFunction: function () { equal(arguments[0], "foo", "First arg match"); equal(arguments[1], "bar", "Second arg match"); return "result"; } }; expectDeprecation(function () { var result; result = helpers['default'].bindAttr.helperFunction("foo", "bar"); equal(result, "result", "Result match"); }, "The 'bindAttr' view helper is deprecated in favor of 'bind-attr'"); } finally { helpers['default']["bind-attr"] = originalBindAttr; } }); QUnit.test("{{bindAttr}} can be used to bind attributes [DEPRECATED]", function () { expect(3); view = EmberView['default'].create({ value: "Test", template: compile['default']("view.value}}") }); expectDeprecation(function () { utils.runAppend(view); }, /The 'bindAttr' view helper is deprecated in favor of 'bind-attr'/); equal(view.$("img").attr("alt"), "Test", "renders initial value"); run['default'](function () { view.set("value", "Updated"); }); equal(view.$("img").attr("alt"), "Updated", "updates value"); }); QUnit.test("should be able to bind element attributes using {{bind-attr}} inside a block", function () { var template = compile['default']("{{#with view.content as image}}image.title}}{{/with}}"); view = EmberView['default'].create({ template: template, content: EmberObject['default'].create({ url: "http://www.emberjs.com/assets/images/logo.png", title: "The SproutCore Logo" }) }); utils.runAppend(view); equal(view.$("img").attr("src"), "http://www.emberjs.com/assets/images/logo.png", "sets src attribute"); equal(view.$("img").attr("alt"), "The SproutCore Logo", "sets alt attribute"); run['default'](function () { property_set.set(view, "content.title", "El logo de Eember"); }); equal(view.$("img").attr("alt"), "El logo de Eember", "updates alt attribute when content's title attribute changes"); }); QUnit.test("should be able to bind class attribute with {{bind-attr}}", function () { var template = compile['default'](""); view = EmberView['default'].create({ template: template, foo: "bar" }); utils.runAppend(view); equal(view.element.firstChild.className, "bar", "renders class"); run['default'](function () { property_set.set(view, "foo", "baz"); }); equal(view.element.firstChild.className, "baz", "updates rendered class"); }); QUnit.test("should be able to bind unquoted class attribute with {{bind-attr}}", function () { var template = compile['default'](""); view = EmberView['default'].create({ template: template, foo: "bar" }); utils.runAppend(view); equal(view.$("img").attr("class"), "bar", "renders class"); run['default'](function () { property_set.set(view, "foo", "baz"); }); equal(view.$("img").attr("class"), "baz", "updates class"); }); QUnit.test("should be able to bind class attribute via a truthy property with {{bind-attr}}", function () { var template = compile['default'](""); view = EmberView['default'].create({ template: template, isNumber: 5 }); utils.runAppend(view); equal(view.element.firstChild.className, "is-truthy", "renders class"); run['default'](function () { property_set.set(view, "isNumber", 0); }); ok(view.element.firstChild.className !== "is-truthy", "removes class"); }); QUnit.test("should be able to bind class to view attribute with {{bind-attr}}", function () { var template = compile['default'](""); view = EmberView['default'].create({ template: template, foo: "bar" }); utils.runAppend(view); equal(view.$("img").attr("class"), "bar", "renders class"); run['default'](function () { property_set.set(view, "foo", "baz"); }); equal(view.$("img").attr("class"), "baz", "updates class"); }); QUnit.test("should not allow XSS injection via {{bind-attr}} with class", function () { view = EmberView['default'].create({ template: compile['default'](""), foo: "\" onmouseover=\"alert('I am in your classes hacking your app');" }); try { utils.runAppend(view); } catch (e) {} equal(view.$("img").attr("onmouseover"), undefined); }); QUnit.test("should be able to bind class attribute using ternary operator in {{bind-attr}}", function () { var template = compile['default'](""); var content = EmberObject['default'].create({ isDisabled: true }); view = EmberView['default'].create({ template: template, content: content }); utils.runAppend(view); ok(view.$("img").hasClass("disabled"), "disabled class is rendered"); ok(!view.$("img").hasClass("enabled"), "enabled class is not rendered"); run['default'](function () { property_set.set(content, "isDisabled", false); }); ok(!view.$("img").hasClass("disabled"), "disabled class is not rendered"); ok(view.$("img").hasClass("enabled"), "enabled class is rendered"); }); QUnit.test("should be able to add multiple classes using {{bind-attr class}}", function () { var template = compile['default']("
"); var content = EmberObject['default'].create({ isAwesomeSauce: true, isAlsoCool: true, isAmazing: true, isEnabled: true }); view = EmberView['default'].create({ template: template, content: content }); utils.runAppend(view); ok(view.$("div").hasClass("is-awesome-sauce"), "dasherizes first property and sets classname"); ok(view.$("div").hasClass("is-also-cool"), "dasherizes second property and sets classname"); ok(view.$("div").hasClass("amazing"), "uses alias for third property and sets classname"); ok(view.$("div").hasClass("is-super-duper"), "static class is present"); ok(view.$("div").hasClass("enabled"), "truthy class in ternary classname definition is rendered"); ok(!view.$("div").hasClass("disabled"), "falsy class in ternary classname definition is not rendered"); run['default'](function () { property_set.set(content, "isAwesomeSauce", false); property_set.set(content, "isAmazing", false); property_set.set(content, "isEnabled", false); }); ok(!view.$("div").hasClass("is-awesome-sauce"), "removes dasherized class when property is set to false"); ok(!view.$("div").hasClass("amazing"), "removes aliased class when property is set to false"); ok(view.$("div").hasClass("is-super-duper"), "static class is still present"); ok(!view.$("div").hasClass("enabled"), "truthy class in ternary classname definition is not rendered"); ok(view.$("div").hasClass("disabled"), "falsy class in ternary classname definition is rendered"); }); QUnit.test("should be able to bind classes to globals with {{bind-attr class}} (DEPRECATED)", function () { TemplateTests.set("isOpen", true); view = EmberView['default'].create({ template: compile['default']("") }); expectDeprecation(function () { utils.runAppend(view); }, /Global lookup of TemplateTests.isOpen from a Handlebars template is deprecated/); ok(view.$("img").hasClass("is-open"), "sets classname to the dasherized value of the global property"); }); QUnit.test("should be able to bind-attr to 'this' in an {{#each}} block [DEPRECATED]", function () { expectDeprecation("Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each foo in bar}}`) instead."); view = EmberView['default'].create({ template: compile['default']("{{#each view.images}}{{/each}}"), images: native_array.A(["one.png", "two.jpg", "three.gif"]) }); utils.runAppend(view); var images = view.$("img"); ok(/one\.png$/.test(images[0].src)); ok(/two\.jpg$/.test(images[1].src)); ok(/three\.gif$/.test(images[2].src)); }); QUnit.test("should be able to bind classes to 'this' in an {{#each}} block with {{bind-attr class}} [DEPRECATED]", function () { expectDeprecation("Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each foo in bar}}`) instead."); view = EmberView['default'].create({ template: compile['default']("{{#each view.items}}
  • Item
  • {{/each}}"), items: native_array.A(["a", "b", "c"]) }); utils.runAppend(view); ok(view.$("li").eq(0).hasClass("a"), "sets classname to the value of the first item"); ok(view.$("li").eq(1).hasClass("b"), "sets classname to the value of the second item"); ok(view.$("li").eq(2).hasClass("c"), "sets classname to the value of the third item"); }); QUnit.test("should be able to bind-attr to var in {{#each var in list}} block", function () { view = EmberView['default'].create({ template: compile['default']("{{#each image in view.images}}{{/each}}"), images: native_array.A(["one.png", "two.jpg", "three.gif"]) }); utils.runAppend(view); var images = view.$("img"); ok(/one\.png$/.test(images[0].src)); ok(/two\.jpg$/.test(images[1].src)); ok(/three\.gif$/.test(images[2].src)); run['default'](function () { var imagesArray = view.get("images"); imagesArray.removeAt(0); }); images = view.$("img"); ok(images.length === 2, ""); ok(/two\.jpg$/.test(images[0].src)); ok(/three\.gif$/.test(images[1].src)); }); QUnit.test("should teardown observers from bind-attr on rerender", function () { view = EmberView['default'].create({ template: compile['default']("wat"), foo: "bar" }); utils.runAppend(view); equal(observer.observersFor(view, "foo").length, 1); run['default'](function () { view.rerender(); }); equal(observer.observersFor(view, "foo").length, 1); }); QUnit.test("should keep class in the order it appears in", function () { view = EmberView['default'].create({ template: compile['default']("") }); utils.runAppend(view); equal(view.element.firstChild.className, "foo baz", "classes are in expected order"); }); QUnit.test("should allow either quoted or unquoted values", function () { view = EmberView['default'].create({ value: "Test", source: "test.jpg", template: compile['default']("\"view.value\"") }); utils.runAppend(view); equal(view.$("img").attr("alt"), "Test", "renders initial value"); equal(view.$("img").attr("src"), "test.jpg", "renders initial value"); run['default'](function () { view.set("value", "Updated"); view.set("source", "test2.jpg"); }); equal(view.$("img").attr("alt"), "Updated", "updates value"); equal(view.$("img").attr("src"), "test2.jpg", "updates value"); }); QUnit.test("property before didInsertElement", function () { var matchingElement; view = EmberView['default'].create({ name: "bob", template: compile['default']("
    "), didInsertElement: function () { matchingElement = this.$("div[alt=bob]"); } }); utils.runAppend(view); equal(matchingElement.length, 1, "element is in the DOM when didInsertElement"); }); QUnit.test("asserts for
    ", function () { var template = compile['default']("
    "); view = EmberView['default'].create({ template: template, foo: "bar" }); expectAssertion(function () { utils.runAppend(view); }, /You cannot set `class` manually and via `{{bind-attr}}` helper on the same element/); }); QUnit.test("asserts for
    ", function () { var template = compile['default']("
    "); view = EmberView['default'].create({ template: template, blah: "bar" }); expectAssertion(function () { utils.runAppend(view); }, /You cannot set `data-bar` manually and via `{{bind-attr}}` helper on the same element/); }); QUnit.test("src attribute bound to undefined is empty", function () { var template = compile['default'](""); view = EmberView['default'].create({ template: template, undefinedValue: undefined }); utils.runAppend(view); equal(view.element.firstChild.getAttribute("src"), "", "src attribute is empty"); }); QUnit.test("src attribute bound to null is empty", function () { var template = compile['default'](""); view = EmberView['default'].create({ template: template, nullValue: null }); utils.runAppend(view); equal(view.element.firstChild.getAttribute("src"), "", "src attribute is empty"); }); QUnit.test("src attribute will be cleared when the value is set to null or undefined", function () { var template = compile['default'](""); view = EmberView['default'].create({ template: template, value: "one" }); utils.runAppend(view); equal(view.element.firstChild.getAttribute("src"), "one", "src attribute is present"); run['default'](function () { property_set.set(view, "value", "two"); }); equal(view.element.firstChild.getAttribute("src"), "two", "src attribute is present"); run['default'](function () { property_set.set(view, "value", null); }); equal(view.element.firstChild.getAttribute("src"), "", "src attribute is empty"); run['default'](function () { property_set.set(view, "value", "three"); }); equal(view.element.firstChild.getAttribute("src"), "three", "src attribute is present"); run['default'](function () { property_set.set(view, "value", undefined); }); equal(view.element.firstChild.getAttribute("src"), "", "src attribute is empty"); }); if (!EmberDev.runningProdBuild) { QUnit.test("specifying `
    ` triggers a warning", function () { view = EmberView['default'].create({ userValue: "42", template: compile['default']("
    ") }); utils.runAppend(view); deepEqual(warnings, [attr_node.styleWarning]); }); } QUnit.test("specifying `
    ` works properly with a SafeString", function () { view = EmberView['default'].create({ userValue: new string.SafeString("42"), template: compile['default']("
    ") }); utils.runAppend(view); deepEqual(warnings, []); }); }); enifed('ember-htmlbars/tests/helpers/bind_attr_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/helpers"); test("ember-htmlbars/tests/helpers/bind_attr_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/helpers/bind_attr_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/helpers/bind_attr_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/helpers"); test("ember-htmlbars/tests/helpers/bind_attr_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/helpers/bind_attr_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/helpers/collection_test', ['ember-views/views/collection_view', 'ember-runtime/system/object', 'ember-views/views/view', 'ember-runtime/system/array_proxy', 'ember-runtime/system/namespace', 'ember-runtime/system/container', 'ember-runtime/system/native_array', 'ember-metal/run_loop', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-views/system/jquery', 'ember-metal/computed', 'ember-runtime/tests/utils', 'ember-template-compiler/system/compile'], function (CollectionView, EmberObject, EmberView, ArrayProxy, Namespace, system__container, native_array, run, property_get, property_set, jQuery, computed, utils, compile) { 'use strict'; /*jshint newcap:false*/ var trim = jQuery['default'].trim; var view; var originalLookup = Ember.lookup; var TemplateTests, registry, container, lookup; function nthChild(view, nth) { return property_get.get(view, "childViews").objectAt(nth || 0); } var firstChild = nthChild; function firstGrandchild(view) { return property_get.get(property_get.get(view, "childViews").objectAt(0), "childViews").objectAt(0); } QUnit.module("collection helper", { setup: function () { Ember.lookup = lookup = {}; lookup.TemplateTests = TemplateTests = Namespace['default'].create(); registry = new system__container.Registry(); container = registry.container(); registry.optionsForType("template", { instantiate: false }); // registry.register('view:default', _MetamorphView); registry.register("view:toplevel", EmberView['default'].extend()); }, teardown: function () { utils.runDestroy(container); utils.runDestroy(view); registry = container = view = null; Ember.lookup = lookup = originalLookup; TemplateTests = null; } }); QUnit.test("Collection views that specify an example view class have their children be of that class", function () { var ExampleViewCollection = CollectionView['default'].extend({ itemViewClass: EmberView['default'].extend({ isCustom: true }), content: native_array.A(["foo"]) }); view = EmberView['default'].create({ exampleViewCollection: ExampleViewCollection, template: compile['default']("{{#collection view.exampleViewCollection}}OHAI{{/collection}}") }); utils.runAppend(view); ok(firstGrandchild(view).isCustom, "uses the example view class"); }); QUnit.test("itemViewClass works in the #collection helper with a global (DEPRECATED)", function () { TemplateTests.ExampleItemView = EmberView['default'].extend({ isAlsoCustom: true }); view = EmberView['default'].create({ exampleController: ArrayProxy['default'].create({ content: native_array.A(["alpha"]) }), template: compile['default']("{{#collection content=view.exampleController itemViewClass=TemplateTests.ExampleItemView}}beta{{/collection}}") }); var deprecation = /Global lookup of TemplateTests.ExampleItemView from a Handlebars template is deprecated/; expectDeprecation(function () { utils.runAppend(view); }, deprecation); ok(firstGrandchild(view).isAlsoCustom, "uses the example view class specified in the #collection helper"); }); QUnit.test("itemViewClass works in the #collection helper with a property", function () { var ExampleItemView = EmberView['default'].extend({ isAlsoCustom: true }); var ExampleCollectionView = CollectionView['default']; view = EmberView['default'].create({ possibleItemView: ExampleItemView, exampleCollectionView: ExampleCollectionView, exampleController: ArrayProxy['default'].create({ content: native_array.A(["alpha"]) }), template: compile['default']("{{#collection view.exampleCollectionView content=view.exampleController itemViewClass=view.possibleItemView}}beta{{/collection}}") }); utils.runAppend(view); ok(firstGrandchild(view).isAlsoCustom, "uses the example view class specified in the #collection helper"); }); QUnit.test("itemViewClass works in the #collection via container", function () { registry.register("view:example-item", EmberView['default'].extend({ isAlsoCustom: true })); view = EmberView['default'].create({ container: container, exampleCollectionView: CollectionView['default'].extend(), exampleController: ArrayProxy['default'].create({ content: native_array.A(["alpha"]) }), template: compile['default']("{{#collection view.exampleCollectionView content=view.exampleController itemViewClass=\"example-item\"}}beta{{/collection}}") }); utils.runAppend(view); ok(firstGrandchild(view).isAlsoCustom, "uses the example view class specified in the #collection helper"); }); QUnit.test("passing a block to the collection helper sets it as the template for example views", function () { var CollectionTestView = CollectionView['default'].extend({ tagName: "ul", content: native_array.A(["foo", "bar", "baz"]) }); view = EmberView['default'].create({ collectionTestView: CollectionTestView, template: compile['default']("{{#collection view.collectionTestView}} {{/collection}}") }); utils.runAppend(view); equal(view.$("label").length, 3, "one label element is created for each content item"); }); QUnit.test("collection helper should try to use container to resolve view", function () { var registry = new system__container.Registry(); var container = registry.container(); var ACollectionView = CollectionView['default'].extend({ tagName: "ul", content: native_array.A(["foo", "bar", "baz"]) }); registry.register("view:collectionTest", ACollectionView); var controller = { container: container }; view = EmberView['default'].create({ controller: controller, template: compile['default']("{{#collection \"collectionTest\"}} {{/collection}}") }); utils.runAppend(view); equal(view.$("label").length, 3, "one label element is created for each content item"); }); QUnit.test("collection helper should accept relative paths", function () { view = EmberView['default'].create({ template: compile['default']("{{#collection view.collection}} {{/collection}}"), collection: CollectionView['default'].extend({ tagName: "ul", content: native_array.A(["foo", "bar", "baz"]) }) }); utils.runAppend(view); equal(view.$("label").length, 3, "one label element is created for each content item"); }); QUnit.test("empty views should be removed when content is added to the collection (regression, ht: msofaer)", function () { var EmptyView = EmberView['default'].extend({ template: compile['default']("No Rows Yet") }); var ListView = CollectionView['default'].extend({ emptyView: EmptyView }); var listController = ArrayProxy['default'].create({ content: native_array.A() }); view = EmberView['default'].create({ listView: ListView, listController: listController, template: compile['default']("{{#collection view.listView content=view.listController tagName=\"table\"}} {{view.content.title}} {{/collection}}") }); utils.runAppend(view); equal(view.$("tr").length, 1, "Make sure the empty view is there (regression)"); run['default'](function () { listController.pushObject({ title: "Go Away, Placeholder Row!" }); }); equal(view.$("tr").length, 1, "has one row"); equal(view.$("tr:nth-child(1) td").text(), "Go Away, Placeholder Row!", "The content is the updated data."); }); QUnit.test("should be able to specify which class should be used for the empty view", function () { var App; run['default'](function () { lookup.App = App = Namespace['default'].create(); }); var EmptyView = EmberView['default'].extend({ template: compile['default']("This is an empty view") }); view = EmberView['default'].create({ container: { lookupFactory: function () { return EmptyView; } }, template: compile['default']("{{collection emptyViewClass=\"empty-view\"}}") }); utils.runAppend(view); equal(view.$().text(), "This is an empty view", "Empty view should be rendered."); utils.runDestroy(App); }); QUnit.test("if no content is passed, and no 'else' is specified, nothing is rendered", function () { var CollectionTestView = CollectionView['default'].extend({ tagName: "ul", content: native_array.A() }); view = EmberView['default'].create({ collectionTestView: CollectionTestView, template: compile['default']("{{#collection view.collectionTestView}} {{/collection}}") }); utils.runAppend(view); equal(view.$("li").length, 0, "if no \"else\" is specified, nothing is rendered"); }); QUnit.test("if no content is passed, and 'else' is specified, the else block is rendered", function () { var CollectionTestView = CollectionView['default'].extend({ tagName: "ul", content: native_array.A() }); view = EmberView['default'].create({ collectionTestView: CollectionTestView, template: compile['default']("{{#collection view.collectionTestView}} {{ else }} {{/collection}}") }); utils.runAppend(view); equal(view.$("li:has(del)").length, 1, "the else block is rendered"); }); QUnit.test("a block passed to a collection helper defaults to the content property of the context", function () { var CollectionTestView = CollectionView['default'].extend({ tagName: "ul", content: native_array.A(["foo", "bar", "baz"]) }); view = EmberView['default'].create({ collectionTestView: CollectionTestView, template: compile['default']("{{#collection view.collectionTestView}} {{/collection}}") }); utils.runAppend(view); equal(view.$("li:nth-child(1) label").length, 1); equal(view.$("li:nth-child(1) label").text(), "foo"); equal(view.$("li:nth-child(2) label").length, 1); equal(view.$("li:nth-child(2) label").text(), "bar"); equal(view.$("li:nth-child(3) label").length, 1); equal(view.$("li:nth-child(3) label").text(), "baz"); }); QUnit.test("a block passed to a collection helper defaults to the view", function () { var CollectionTestView = CollectionView['default'].extend({ tagName: "ul", content: native_array.A(["foo", "bar", "baz"]) }); view = EmberView['default'].create({ collectionTestView: CollectionTestView, template: compile['default']("{{#collection view.collectionTestView}} {{/collection}}") }); utils.runAppend(view); // Preconds equal(view.$("li:nth-child(1) label").length, 1); equal(view.$("li:nth-child(1) label").text(), "foo"); equal(view.$("li:nth-child(2) label").length, 1); equal(view.$("li:nth-child(2) label").text(), "bar"); equal(view.$("li:nth-child(3) label").length, 1); equal(view.$("li:nth-child(3) label").text(), "baz"); run['default'](function () { property_set.set(firstChild(view), "content", native_array.A()); }); equal(view.$("label").length, 0, "all list item views should be removed from DOM"); }); QUnit.test("should include an id attribute if id is set in the options hash", function () { var CollectionTestView = CollectionView['default'].extend({ tagName: "ul", content: native_array.A(["foo", "bar", "baz"]) }); view = EmberView['default'].create({ collectionTestView: CollectionTestView, template: compile['default']("{{#collection view.collectionTestView id=\"baz\"}}foo{{/collection}}") }); utils.runAppend(view); equal(view.$("ul#baz").length, 1, "adds an id attribute"); }); QUnit.test("should give its item views the class specified by itemClass", function () { var ItemClassTestCollectionView = CollectionView['default'].extend({ tagName: "ul", content: native_array.A(["foo", "bar", "baz"]) }); view = EmberView['default'].create({ itemClassTestCollectionView: ItemClassTestCollectionView, template: compile['default']("{{#collection view.itemClassTestCollectionView itemClass=\"baz\"}}foo{{/collection}}") }); utils.runAppend(view); equal(view.$("ul li.baz").length, 3, "adds class attribute"); }); QUnit.test("should give its item views the class specified by itemClass", function () { var ItemClassBindingTestCollectionView = CollectionView['default'].extend({ tagName: "ul", content: native_array.A([EmberObject['default'].create({ isBaz: false }), EmberObject['default'].create({ isBaz: true }), EmberObject['default'].create({ isBaz: true })]) }); view = EmberView['default'].create({ itemClassBindingTestCollectionView: ItemClassBindingTestCollectionView, isBar: true, template: compile['default']("{{#collection view.itemClassBindingTestCollectionView itemClass=view.isBar}}foo{{/collection}}") }); utils.runAppend(view); equal(view.$("ul li.is-bar").length, 3, "adds class on initial rendering"); // NOTE: in order to bind an item's class to a property of the item itself (e.g. `isBaz` above), it will be necessary // to introduce a new keyword that could be used from within `itemClassBinding`. For instance, `itemClassBinding="item.isBaz"`. }); QUnit.test("should give its item views the property specified by itemProperty", function () { var ItemPropertyBindingTestItemView = EmberView['default'].extend({ tagName: "li" }); // Use preserveContext=false so the itemView handlebars context is the view context // Set itemView bindings using item* view = EmberView['default'].create({ baz: "baz", content: native_array.A([EmberObject['default'].create(), EmberObject['default'].create(), EmberObject['default'].create()]), container: { lookupFactory: function () { return ItemPropertyBindingTestItemView; } }, template: compile['default']("{{#collection content=view.content tagName=\"ul\" itemViewClass=\"item-property-binding-test-item-view\" itemProperty=view.baz preserveContext=false}}{{view.property}}{{/collection}}") }); utils.runAppend(view); equal(view.$("ul li").length, 3, "adds 3 itemView"); view.$("ul li").each(function (i, li) { equal(jQuery['default'](li).text(), "baz", "creates the li with the property = baz"); }); run['default'](function () { property_set.set(view, "baz", "yobaz"); }); equal(view.$("ul li:first").text(), "yobaz", "change property of sub view"); }); QUnit.test("should unsubscribe stream bindings", function () { view = EmberView['default'].create({ baz: "baz", content: native_array.A([EmberObject['default'].create(), EmberObject['default'].create(), EmberObject['default'].create()]), template: compile['default']("{{#collection content=view.content itemProperty=view.baz}}{{view.property}}{{/collection}}") }); utils.runAppend(view); var barStreamBinding = view._streamBindings["view.baz"]; equal(barStreamBinding.subscribers.length, 3 * 2, "adds 3 subscribers"); run['default'](function () { view.get("content").popObject(); }); equal(barStreamBinding.subscribers.length, 2 * 2, "removes 1 subscriber"); }); QUnit.test("should work inside a bound {{#if}}", function () { var testData = native_array.A([EmberObject['default'].create({ isBaz: false }), EmberObject['default'].create({ isBaz: true }), EmberObject['default'].create({ isBaz: true })]); var IfTestCollectionView = CollectionView['default'].extend({ tagName: "ul", content: testData }); view = EmberView['default'].create({ ifTestCollectionView: IfTestCollectionView, template: compile['default']("{{#if view.shouldDisplay}}{{#collection view.ifTestCollectionView}}{{content.isBaz}}{{/collection}}{{/if}}"), shouldDisplay: true }); utils.runAppend(view); equal(view.$("ul li").length, 3, "renders collection when conditional is true"); run['default'](function () { property_set.set(view, "shouldDisplay", false); }); equal(view.$("ul li").length, 0, "removes collection when conditional changes to false"); run['default'](function () { property_set.set(view, "shouldDisplay", true); }); equal(view.$("ul li").length, 3, "collection renders when conditional changes to true"); }); QUnit.test("should pass content as context when using {{#each}} helper [DEPRECATED]", function () { view = EmberView['default'].create({ template: compile['default']("{{#each view.releases}}Mac OS X {{version}}: {{name}} {{/each}}"), releases: native_array.A([{ version: "10.7", name: "Lion" }, { version: "10.6", name: "Snow Leopard" }, { version: "10.5", name: "Leopard" }]) }); expectDeprecation(function () { utils.runAppend(view); }, "Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each foo in bar}}`) instead."); equal(view.$().text(), "Mac OS X 10.7: Lion Mac OS X 10.6: Snow Leopard Mac OS X 10.5: Leopard ", "prints each item in sequence"); }); QUnit.test("should re-render when the content object changes", function () { var RerenderTest = CollectionView['default'].extend({ tagName: "ul", content: native_array.A() }); view = EmberView['default'].create({ rerenderTestView: RerenderTest, template: compile['default']("{{#collection view.rerenderTestView}}{{view.content}}{{/collection}}") }); utils.runAppend(view); run['default'](function () { property_set.set(firstChild(view), "content", native_array.A(["bing", "bat", "bang"])); }); run['default'](function () { property_set.set(firstChild(view), "content", native_array.A(["ramalamadingdong"])); }); equal(view.$("li").length, 1, "rerenders with correct number of items"); equal(trim(view.$("li:eq(0)").text()), "ramalamadingdong"); }); QUnit.test("select tagName on collection helper automatically sets child tagName to option", function () { var RerenderTest = CollectionView['default'].extend({ content: native_array.A(["foo"]) }); view = EmberView['default'].create({ rerenderTestView: RerenderTest, template: compile['default']("{{#collection view.rerenderTestView tagName=\"select\"}}{{view.content}}{{/collection}}") }); utils.runAppend(view); equal(view.$("option").length, 1, "renders the correct child tag name"); }); QUnit.test("tagName works in the #collection helper", function () { var RerenderTest = CollectionView['default'].extend({ content: native_array.A(["foo", "bar"]) }); view = EmberView['default'].create({ rerenderTestView: RerenderTest, template: compile['default']("{{#collection view.rerenderTestView tagName=\"ol\"}}{{view.content}}{{/collection}}") }); utils.runAppend(view); equal(view.$("ol").length, 1, "renders the correct tag name"); equal(view.$("li").length, 2, "rerenders with correct number of items"); run['default'](function () { property_set.set(firstChild(view), "content", native_array.A(["bing", "bat", "bang"])); }); equal(view.$("li").length, 3, "rerenders with correct number of items"); equal(trim(view.$("li:eq(0)").text()), "bing"); }); QUnit.test("should render nested collections", function () { var registry = new system__container.Registry(); var container = registry.container(); registry.register("view:inner-list", CollectionView['default'].extend({ tagName: "ul", content: native_array.A(["one", "two", "three"]) })); registry.register("view:outer-list", CollectionView['default'].extend({ tagName: "ul", content: native_array.A(["foo"]) })); view = EmberView['default'].create({ container: container, template: compile['default']("{{#collection \"outer-list\" class=\"outer\"}}{{content}}{{#collection \"inner-list\" class=\"inner\"}}{{content}}{{/collection}}{{/collection}}") }); utils.runAppend(view); equal(view.$("ul.outer > li").length, 1, "renders the outer list with correct number of items"); equal(view.$("ul.inner").length, 1, "the inner list exsits"); equal(view.$("ul.inner > li").length, 3, "renders the inner list with correct number of items"); }); QUnit.test("should render multiple, bound nested collections (#68)", function () { var view; run['default'](function () { TemplateTests.contentController = ArrayProxy['default'].create({ content: native_array.A(["foo", "bar"]) }); var InnerList = CollectionView['default'].extend({ tagName: "ul", contentBinding: "parentView.innerListContent" }); var OuterListItem = EmberView['default'].extend({ innerListView: InnerList, template: compile['default']("{{#collection view.innerListView class=\"inner\"}}{{content}}{{/collection}}{{content}}"), innerListContent: computed.computed(function () { return native_array.A([1, 2, 3]); }) }); var OuterList = CollectionView['default'].extend({ tagName: "ul", contentBinding: "TemplateTests.contentController", itemViewClass: OuterListItem }); view = EmberView['default'].create({ outerListView: OuterList, template: compile['default']("{{collection view.outerListView class=\"outer\"}}") }); }); utils.runAppend(view); equal(view.$("ul.outer > li").length, 2, "renders the outer list with correct number of items"); equal(view.$("ul.inner").length, 2, "renders the correct number of inner lists"); equal(view.$("ul.inner:first > li").length, 3, "renders the first inner list with correct number of items"); equal(view.$("ul.inner:last > li").length, 3, "renders the second list with correct number of items"); utils.runDestroy(view); }); QUnit.test("should allow view objects to be swapped out without throwing an error (#78)", function () { var view, dataset, secondDataset; run['default'](function () { TemplateTests.datasetController = EmberObject['default'].create(); var ExampleCollectionView = CollectionView['default'].extend({ contentBinding: "parentView.items", tagName: "ul", template: compile['default']("{{view.content}}") }); var ReportingView = EmberView['default'].extend({ exampleCollectionView: ExampleCollectionView, datasetBinding: "TemplateTests.datasetController.dataset", readyBinding: "dataset.ready", itemsBinding: "dataset.items", template: compile['default']("{{#if view.ready}}{{collection view.exampleCollectionView}}{{else}}Loading{{/if}}") }); view = ReportingView.create(); }); utils.runAppend(view); equal(view.$().text(), "Loading", "renders the loading text when the dataset is not ready"); run['default'](function () { dataset = EmberObject['default'].create({ ready: true, items: native_array.A([1, 2, 3]) }); TemplateTests.datasetController.set("dataset", dataset); }); equal(view.$("ul > li").length, 3, "renders the collection with the correct number of items when the dataset is ready"); run['default'](function () { secondDataset = EmberObject['default'].create({ ready: false }); TemplateTests.datasetController.set("dataset", secondDataset); }); equal(view.$().text(), "Loading", "renders the loading text when the second dataset is not ready"); utils.runDestroy(view); }); QUnit.test("context should be content", function () { var view; registry = new system__container.Registry(); container = registry.container(); var items = native_array.A([EmberObject['default'].create({ name: "Dave" }), EmberObject['default'].create({ name: "Mary" }), EmberObject['default'].create({ name: "Sara" })]); registry.register("view:an-item", EmberView['default'].extend({ template: compile['default']("Greetings {{name}}") })); view = EmberView['default'].create({ container: container, controller: { items: items }, template: compile['default']("{{collection content=items itemViewClass=\"an-item\"}}") }); utils.runAppend(view); equal(view.$().text(), "Greetings DaveGreetings MaryGreetings Sara"); utils.runDestroy(view); }); }); enifed('ember-htmlbars/tests/helpers/collection_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/helpers"); test("ember-htmlbars/tests/helpers/collection_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/helpers/collection_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/helpers/collection_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/helpers"); test("ember-htmlbars/tests/helpers/collection_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/helpers/collection_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/helpers/component_test', ['ember-views/component_lookup', 'container/registry', 'ember-views/views/view', 'ember-template-compiler/system/compile', 'ember-runtime/tests/utils'], function (ComponentLookup, Registry, EmberView, compile, utils) { 'use strict'; var set = Ember.set; var get = Ember.get; var view, registry, container; QUnit.module("ember-htmlbars: {{#component}} helper", { setup: function () { registry = new Registry['default'](); container = registry.container(); registry.optionsForType("template", { instantiate: false }); registry.register("component-lookup:main", ComponentLookup['default']); }, teardown: function () { utils.runDestroy(view); utils.runDestroy(container); registry = container = view = null; } }); QUnit.test("component helper with unquoted string is bound", function () { registry.register("template:components/foo-bar", compile['default']("yippie! {{location}} {{yield}}")); registry.register("template:components/baz-qux", compile['default']("yummy {{location}} {{yield}}")); view = EmberView['default'].create({ container: container, dynamicComponent: "foo-bar", location: "Caracas", template: compile['default']("{{#component view.dynamicComponent location=view.location}}arepas!{{/component}}") }); utils.runAppend(view); equal(view.$().text(), "yippie! Caracas arepas!", "component was looked up and rendered"); Ember.run(function () { set(view, "dynamicComponent", "baz-qux"); set(view, "location", "Loisaida"); }); equal(view.$().text(), "yummy Loisaida arepas!", "component was updated and re-rendered"); }); QUnit.test("component helper with actions", function () { registry.register("template:components/foo-bar", compile['default']("yippie! {{yield}}")); registry.register("component:foo-bar", Ember.Component.extend({ classNames: "foo-bar", didInsertElement: function () { // trigger action on click in absence of app's EventDispatcher var self = this; this.$().on("click", function () { self.sendAction("fooBarred"); }); }, willDestroyElement: function () { this.$().off("click"); } })); var actionTriggered = 0; var controller = Ember.Controller.extend({ dynamicComponent: "foo-bar", actions: { mappedAction: function () { actionTriggered++; } } }).create(); view = EmberView['default'].create({ container: container, controller: controller, template: compile['default']("{{#component dynamicComponent fooBarred=\"mappedAction\"}}arepas!{{/component}}") }); utils.runAppend(view); Ember.run(function () { view.$(".foo-bar").trigger("click"); }); equal(actionTriggered, 1, "action was triggered"); }); QUnit.test("component helper maintains expected logical parentView", function () { registry.register("template:components/foo-bar", compile['default']("yippie! {{yield}}")); var componentInstance; registry.register("component:foo-bar", Ember.Component.extend({ didInsertElement: function () { componentInstance = this; } })); view = EmberView['default'].create({ container: container, dynamicComponent: "foo-bar", template: compile['default']("{{#component view.dynamicComponent}}arepas!{{/component}}") }); utils.runAppend(view); equal(get(componentInstance, "parentView"), view, "component's parentView is the view invoking the helper"); }); QUnit.test("nested component helpers", function () { registry.register("template:components/foo-bar", compile['default']("yippie! {{location}} {{yield}}")); registry.register("template:components/baz-qux", compile['default']("yummy {{location}} {{yield}}")); registry.register("template:components/corge-grault", compile['default']("delicious {{location}} {{yield}}")); view = EmberView['default'].create({ container: container, dynamicComponent1: "foo-bar", dynamicComponent2: "baz-qux", location: "Caracas", template: compile['default']("{{#component view.dynamicComponent1 location=view.location}}{{#component view.dynamicComponent2 location=view.location}}arepas!{{/component}}{{/component}}") }); utils.runAppend(view); equal(view.$().text(), "yippie! Caracas yummy Caracas arepas!", "components were looked up and rendered"); Ember.run(function () { set(view, "dynamicComponent1", "corge-grault"); set(view, "location", "Loisaida"); }); equal(view.$().text(), "delicious Loisaida yummy Loisaida arepas!", "components were updated and re-rendered"); }); QUnit.test("component helper can be used with a quoted string (though you probably would not do this)", function () { registry.register("template:components/foo-bar", compile['default']("yippie! {{location}} {{yield}}")); view = EmberView['default'].create({ container: container, location: "Caracas", template: compile['default']("{{#component \"foo-bar\" location=view.location}}arepas!{{/component}}") }); utils.runAppend(view); equal(view.$().text(), "yippie! Caracas arepas!", "component was looked up and rendered"); }); QUnit.test("component with unquoted param resolving to non-existent component", function () { view = EmberView['default'].create({ container: container, dynamicComponent: "does-not-exist", location: "Caracas", template: compile['default']("{{#component view.dynamicComponent location=view.location}}arepas!{{/component}}") }); throws(function () { utils.runAppend(view); }, /HTMLBars error: Could not find component named "does-not-exist"./); }); QUnit.test("component with quoted param for non-existent component", function () { view = EmberView['default'].create({ container: container, location: "Caracas", template: compile['default']("{{#component \"does-not-exist\" location=view.location}}arepas!{{/component}}") }); throws(function () { utils.runAppend(view); }, /HTMLBars error: Could not find component named "does-not-exist"./); }); }); enifed('ember-htmlbars/tests/helpers/component_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/helpers"); test("ember-htmlbars/tests/helpers/component_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/helpers/component_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/helpers/component_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/helpers"); test("ember-htmlbars/tests/helpers/component_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/helpers/component_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/helpers/debug_test', ['ember-metal/core', 'ember-metal/logger', 'ember-views/views/view', 'ember-template-compiler/system/compile', 'ember-runtime/tests/utils'], function (Ember, EmberLogger, EmberView, compile, utils) { 'use strict'; var originalLookup = Ember['default'].lookup; var lookup; var originalLog, logCalls; var view; QUnit.module("Handlebars {{log}} helper", { setup: function () { Ember['default'].lookup = lookup = { Ember: Ember['default'] }; originalLog = EmberLogger['default'].log; logCalls = []; EmberLogger['default'].log = function () { logCalls.push.apply(logCalls, arguments); }; }, teardown: function () { utils.runDestroy(view); view = null; EmberLogger['default'].log = originalLog; Ember['default'].lookup = originalLookup; } }); QUnit.test("should be able to log multiple properties", function () { var context = { value: "one", valueTwo: "two" }; view = EmberView['default'].create({ context: context, template: compile['default']("{{log value valueTwo}}") }); utils.runAppend(view); equal(view.$().text(), "", "shouldn't render any text"); equal(logCalls[0], "one"); equal(logCalls[1], "two"); }); QUnit.test("should be able to log primitives", function () { var context = { value: "one", valueTwo: "two" }; view = EmberView['default'].create({ context: context, template: compile['default']("{{log value \"foo\" 0 valueTwo true}}") }); utils.runAppend(view); equal(view.$().text(), "", "shouldn't render any text"); strictEqual(logCalls[0], "one"); strictEqual(logCalls[1], "foo"); strictEqual(logCalls[2], 0); strictEqual(logCalls[3], "two"); strictEqual(logCalls[4], true); }); }); enifed('ember-htmlbars/tests/helpers/debug_test.jscs-test', function () { 'use strict'; module("JSCS - ember-htmlbars/tests/helpers"); test("ember-htmlbars/tests/helpers/debug_test.js should pass jscs", function () { ok(true, "ember-htmlbars/tests/helpers/debug_test.js should pass jscs."); }); }); enifed('ember-htmlbars/tests/helpers/debug_test.jshint', function () { 'use strict'; module("JSHint - ember-htmlbars/tests/helpers"); test("ember-htmlbars/tests/helpers/debug_test.js should pass jshint", function () { ok(true, "ember-htmlbars/tests/helpers/debug_test.js should pass jshint."); }); }); enifed('ember-htmlbars/tests/helpers/each_test', ['ember-metal/core', 'ember-runtime/system/object', 'ember-metal/run_loop', 'ember-views/views/view', 'ember-views/views/metamorph_view', 'ember-metal/computed', 'ember-runtime/controllers/array_controller', 'ember-runtime/system/native_array', 'ember-runtime/controllers/controller', 'ember-runtime/controllers/object_controller', 'ember-runtime/system/container', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-runtime/tests/utils', 'ember-template-compiler/system/compile'], function (Ember, EmberObject, run, EmberView, _MetamorphView, computed, ArrayController, native_array, EmberController, ObjectController, system__container, property_get, property_set, utils, compile) { 'use strict'; /*jshint newcap:false*/ var people, view, registry, container; var template, templateMyView, MyView, MyEmptyView, templateMyEmptyView; // This function lets us write {{#EACH|people|p}} {{p}} {{/each}} // and generate: // // - {{#each p in people}} (legacy) // - {{#each people as |p|}} (legacy) function makeReplacer(useBlockParams) { return function (_, matchString) { var values = matchString.split("|"); if (values.length === 1) { return "each"; } var arr = useBlockParams ? ["each", values[1], "as", "|" + values[2] + "|"] : ["each", values[2], "in", values[1]]; var options = values[3]; if (options) { if (useBlockParams) { arr.splice(2, 0, options); } else { arr.push(options); } } return arr.join(" "); }; } var parseEachReplacerBlockParam = makeReplacer(true); var parseEachReplacerNonBlockParam = makeReplacer(false); var EACH_REGEX = /(EACH[^\}]*)/g; function parseEach(str, useBlockParams) { return str.replace(EACH_REGEX, useBlockParams ? parseEachReplacerBlockParam : parseEachReplacerNonBlockParam); } QUnit.module("parseEach test helper"); QUnit.test("block param syntax substitution", function () { equal(parseEach("{{#EACH|people|p}}p people{{/EACH}}", true), "{{#each people as |p|}}p people{{/each}}"); equal(parseEach("{{#EACH|people|p|a='b' c='d'}}p people{{/EACH}}", true), "{{#each people a='b' c='d' as |p|}}p people{{/each}}"); }); QUnit.test("non-block param syntax substitution", function () { equal(parseEach("{{#EACH|people|p}}p people{{/EACH}}", false), "{{#each p in people}}p people{{/each}}"); equal(parseEach("{{#EACH|people|p|a='b' c='d'}}p people{{/EACH}}", false), "{{#each p in people a='b' c='d'}}p people{{/each}}"); }); function templateFor(templateString, useBlockParams) { return compile['default'](parseEach(templateString, useBlockParams)); } var originalLookup = Ember['default'].lookup; var lookup; QUnit.module("the scope changing #each helper [DEPRECATED]", { setup: function () { Ember['default'].lookup = lookup = { Ember: Ember['default'] }; template = templateFor("{{#each view.people}}{{name}}{{/each}}"); people = native_array.A([{ name: "Steve Holt" }, { name: "Annabelle" }]); registry = new system__container.Registry(); container = registry.container(); registry.register("view:default", _MetamorphView['default']); registry.register("view:toplevel", EmberView['default'].extend()); view = EmberView['default'].create({ container: container, template: template, people: people }); templateMyView = templateFor("{{name}}"); lookup.MyView = MyView = EmberView['default'].extend({ template: templateMyView }); templateMyEmptyView = templateFor("I'm empty"); lookup.MyEmptyView = MyEmptyView = EmberView['default'].extend({ template: templateMyEmptyView }); expectDeprecation(function () { utils.runAppend(view); }, "Using the context switching form of {{each}} is deprecated. Please use the keyword form (`{{#each foo in bar}}`) instead."); }, teardown: function () { utils.runDestroy(container); utils.runDestroy(view); registry = container = view = null; Ember['default'].lookup = originalLookup; } }); var assertHTML = function (view, expectedHTML) { var html = view.$().html(); // IE 8 (and prior?) adds the \r\n html = html.replace(/]*><\/script>/ig, "").replace(/[\r\n]/g, ""); equal(html, expectedHTML); }; var assertText = function (view, expectedText) { equal(view.$().text(), expectedText); }; QUnit.test("it renders the template for each item in an array", function () { assertHTML(view, "Steve HoltAnnabelle"); }); QUnit.test("it updates the view if an item is added", function () { run['default'](function () { people.pushObject({ name: "Tom Dale" }); }); assertHTML(view, "Steve HoltAnnabelleTom Dale"); }); if (typeof Handlebars === "object") { QUnit.test("should be able to use standard Handlebars #each helper", function () { utils.runDestroy(view); view = EmberView['default'].create({ context: { items: ["a", "b", "c"] }, template: Handlebars.compile("{{#each items}}{{this}}{{/each}}") }); utils.runAppend(view); equal(view.$().html(), "abc"); }); } QUnit.test("it allows you to access the current context using {{this}}", function () { utils.runDestroy(view); view = EmberView['default'].create({ template: templateFor("{{#each view.people}}{{this}}{{/each}}"), people: native_array.A(["Black Francis", "Joey Santiago", "Kim Deal", "David Lovering"]) }); utils.runAppend(view); assertHTML(view, "Black FrancisJoey SantiagoKim DealDavid Lovering"); }); QUnit.test("it updates the view if an item is removed", function () { run['default'](function () { people.removeAt(0); }); assertHTML(view, "Annabelle"); }); QUnit.test("it updates the view if an item is replaced", function () { run['default'](function () { people.removeAt(0); people.insertAt(0, { name: "Kazuki" }); }); assertHTML(view, "KazukiAnnabelle"); }); QUnit.test("can add and replace in the same runloop", function () { run['default'](function () { people.pushObject({ name: "Tom Dale" }); people.removeAt(0); people.insertAt(0, { name: "Kazuki" }); }); assertHTML(view, "KazukiAnnabelleTom Dale"); }); QUnit.test("can add and replace the object before the add in the same runloop", function () { run['default'](function () { people.pushObject({ name: "Tom Dale" }); people.removeAt(1); people.insertAt(1, { name: "Kazuki" }); }); assertHTML(view, "Steve HoltKazukiTom Dale"); }); QUnit.test("can add and replace complicatedly", function () { run['default'](function () { people.pushObject({ name: "Tom Dale" }); people.removeAt(1); people.insertAt(1, { name: "Kazuki" }); people.pushObject({ name: "Firestone" }); people.pushObject({ name: "McMunch" }); people.removeAt(3); }); assertHTML(view, "Steve HoltKazukiTom DaleMcMunch"); }); QUnit.test("can add and replace complicatedly harder", function () { run['default'](function () { people.pushObject({ name: "Tom Dale" }); people.removeAt(1); people.insertAt(1, { name: "Kazuki" }); people.pushObject({ name: "Firestone" }); people.pushObject({ name: "McMunch" }); people.removeAt(2); }); assertHTML(view, "Steve HoltKazukiFirestoneMcMunch"); }); QUnit.test("it does not mark each option tag as selected", function () { var selectView = EmberView['default'].create({ template: templateFor(""), people: people }); utils.runAppend(selectView); equal(selectView.$("option").length, 3, "renders 3