// ========================================================================== // Project: Ember - JavaScript Application Framework // Copyright: Copyright 2011-2013 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.2.2 var JSHINTRC = { "predef": [ "QUnit", "define", "console", "Ember", "DS", "Handlebars", "Metamorph", "RSVP", "require", "requireModule", "equal", "notEqual", "notStrictEqual", "test", "asyncTest", "testBoth", "testWithDefault", "raises", "throws", "deepEqual", "start", "stop", "ok", "strictEqual", "module", "expect", "minispade", "expectAssertion", // A safe subset of "browser:true": "window", "location", "document", "XMLSerializer", "setTimeout", "clearTimeout", "setInterval", "clearInterval" ], "node" : false, "browser" : false, "boss" : true, "curly": false, "debug": false, "devel": false, "eqeqeq": true, "evil": true, "forin": false, "immed": false, "laxbreak": false, "newcap": true, "noarg": true, "noempty": false, "nonew": false, "nomen": false, "onevar": false, "plusplus": false, "regexp": false, "undef": true, "sub": true, "strict": false, "white": false, "eqnull": true } ; minispade.register('container/~tests/container_test', "(function() {var passedOptions;\nvar Container = requireModule('container');\n\nfunction setProperties(object, properties) {\n for (var key in properties) {\n if (properties.hasOwnProperty(key)) {\n object[key] = properties[key];\n }\n }\n}\n\nvar o_create = Object.create || (function(){\n function F(){}\n\n return function(o) {\n if (arguments.length !== 1) {\n throw new Ember.Error('Object.create implementation only accepts one parameter.');\n }\n F.prototype = o;\n return new F();\n };\n}());\n\nvar originalModelInjections;\n\nmodule(\"Container\", {\n setup: function() {\n originalModelInjections = Ember.MODEL_FACTORY_INJECTIONS;\n },\n teardown: function() {\n Ember.MODEL_FACTORY_INJECTIONS = originalModelInjections;\n }\n});\n\nvar guids = 0;\n\nfunction factory() {\n var Klass = function(options) {\n setProperties(this, options);\n this._guid = guids++;\n };\n\n Klass.prototype.constructor = Klass;\n Klass.prototype.destroy = function() {\n this.isDestroyed = true;\n };\n\n Klass.prototype.toString = function() {\n return \"\";\n };\n\n Klass.create = create;\n Klass.extend = extend;\n Klass.reopen = extend;\n Klass.reopenClass = reopenClass;\n\n return Klass;\n\n function create(options) {\n passedOptions = options;\n return new this.prototype.constructor(options);\n }\n\n function reopenClass(options) {\n setProperties(this, options);\n }\n\n function extend(options) {\n var Child = function(options) {\n Klass.call(this, options);\n };\n\n var Parent = this;\n\n Child.prototype = new Parent();\n Child.prototype.constructor = Child;\n\n setProperties(Child.prototype, options);\n\n Child.create = create;\n Child.extend = extend;\n Child.reopen = extend;\n\n Child.reopenClass = reopenClass;\n\n return Child;\n }\n}\n\ntest(\"A registered factory returns the same instance each time\", function() {\n var container = new Container();\n var PostController = factory();\n\n container.register('controller:post', PostController);\n\n var postController = container.lookup('controller:post');\n\n ok(postController instanceof PostController, \"The lookup is an instance of the factory\");\n\n equal(postController, container.lookup('controller:post'));\n});\n\ntest(\"A registered factory is returned from lookupFactory\", function() {\n var container = new Container();\n var PostController = factory();\n\n container.register('controller:post', PostController);\n\n var PostControllerFactory = container.lookupFactory('controller:post');\n\n ok(PostControllerFactory, 'factory is returned');\n ok(PostControllerFactory.create() instanceof PostController, \"The return of factory.create is an instance of PostController\");\n});\n\ntest(\"A registered factory is returned from lookupFactory is the same factory each time\", function() {\n var container = new Container();\n var PostController = factory();\n\n container.register('controller:post', PostController);\n\n deepEqual(container.lookupFactory('controller:post'), container.lookupFactory('controller:post'), 'The return of lookupFactory is always the same');\n});\n\ntest(\"A factory returned from lookupFactory has a debugkey\", function(){\n var container = new Container();\n var PostController = factory();\n var instance;\n\n container.register('controller:post', PostController);\n var PostFactory = container.lookupFactory('controller:post');\n\n ok(!PostFactory.container, 'factory instance receives a container');\n equal(PostFactory._debugContainerKey, 'controller:post', 'factory instance receives _debugContainerKey');\n});\n\ntest(\"fallback for to create time injections if factory has no extend\", function(){\n var container = new Container();\n var AppleController = factory();\n var PostController = factory();\n\n PostController.extend = undefined; // remove extend\n\n var instance;\n\n container.register('controller:apple', AppleController);\n container.register('controller:post', PostController);\n container.injection('controller:post', 'apple', 'controller:apple');\n\n var postController = container.lookup('controller:post');\n\n ok(postController.container, 'instance receives a container');\n equal(postController.container, container, 'instance receives the correct container');\n equal(postController._debugContainerKey, 'controller:post', 'instance receives _debugContainerKey');\n ok(postController.apple instanceof AppleController, 'instance receives an apple of instance AppleController');\n});\n\ntest(\"The descendants of a factory returned from lookupFactory have a container and debugkey\", function(){\n var container = new Container();\n var PostController = factory();\n var instance;\n\n container.register('controller:post', PostController);\n instance = container.lookupFactory('controller:post').create();\n\n ok(instance.container, 'factory instance receives a container');\n equal(instance._debugContainerKey, 'controller:post', 'factory instance receives _debugContainerKey');\n\n ok(instance instanceof PostController, 'factory instance is instance of factory');\n});\n\ntest(\"A registered factory returns a fresh instance if singleton: false is passed as an option\", function() {\n var container = new Container();\n var PostController = factory();\n\n container.register('controller:post', PostController);\n\n var postController1 = container.lookup('controller:post');\n var postController2 = container.lookup('controller:post', { singleton: false });\n var postController3 = container.lookup('controller:post', { singleton: false });\n var postController4 = container.lookup('controller:post');\n\n equal(postController1.toString(), postController4.toString(), \"Singleton factories looked up normally return the same value\");\n notEqual(postController1.toString(), postController2.toString(), \"Singleton factories are not equal to factories looked up with singleton: false\");\n notEqual(postController2.toString(), postController3.toString(), \"Two factories looked up with singleton: false are not equal\");\n notEqual(postController3.toString(), postController4.toString(), \"A singleton factory looked up after a factory called with singleton: false is not equal\");\n\n ok(postController1 instanceof PostController, \"All instances are instances of the registered factory\");\n ok(postController2 instanceof PostController, \"All instances are instances of the registered factory\");\n ok(postController3 instanceof PostController, \"All instances are instances of the registered factory\");\n ok(postController4 instanceof PostController, \"All instances are instances of the registered factory\");\n});\n\ntest(\"A registered factory returns true for `has` if an item is registered\", function() {\n var container = new Container();\n var PostController = factory();\n\n container.register('controller:post', PostController);\n\n equal(container.has('controller:post'), true, \"The `has` method returned true for registered factories\");\n equal(container.has('controller:posts'), false, \"The `has` method returned false for unregistered factories\");\n});\n\ntest(\"A Registered factory can be unregistered, and all cached instances are removed\", function() {\n var container = new Container();\n var PostController = factory();\n\n container.register('controller:post', PostController);\n\n equal(container.has('controller:post'), true, \"container is aware of the PostController\");\n\n ok(container.lookup('controller:post') instanceof PostController, \"lookup is correct instance\");\n\n container.unregister(\"controller:post\");\n\n equal(container.has('controller:post'), false, \"container is no-longer aware of the PostController\");\n equal(container.lookup('controller:post'), undefined, \"lookup no longer returns a controller\");\n\n // re-registration continues to work\n container.register('controller:post', PostController);\n\n equal(container.has('controller:post'), true, \"container is aware of the PostController\");\n\n ok(container.lookup('controller:post') instanceof PostController, \"lookup is correct instance\");\n});\n\ntest(\"A container lookup has access to the container\", function() {\n var container = new Container();\n var PostController = factory();\n\n container.register('controller:post', PostController);\n\n var postController = container.lookup('controller:post');\n\n equal(postController.container, container);\n});\n\ntest(\"A factory type with a registered injection's instances receive that injection\", function() {\n var container = new Container();\n var PostController = factory();\n var Store = factory();\n\n container.register('controller:post', PostController);\n container.register('store:main', Store);\n\n container.typeInjection('controller', 'store', 'store:main');\n\n var postController = container.lookup('controller:post');\n var store = container.lookup('store:main');\n\n equal(postController.store, store);\n});\n\ntest(\"An individual factory with a registered injection receives the injection\", function() {\n var container = new Container();\n var PostController = factory();\n var Store = factory();\n\n container.register('controller:post', PostController);\n container.register('store:main', Store);\n\n container.injection('controller:post', 'store', 'store:main');\n\n var postController = container.lookup('controller:post');\n var store = container.lookup('store:main');\n\n equal(store.container, container);\n equal(store._debugContainerKey, 'store:main');\n\n equal(postController.container, container);\n equal(postController._debugContainerKey, 'controller:post');\n equal(postController.store, store, 'has the correct store injected');\n});\n\ntest(\"A factory with both type and individual injections\", function() {\n var container = new Container();\n var PostController = factory();\n var Store = factory();\n var Router = factory();\n\n container.register('controller:post', PostController);\n container.register('store:main', Store);\n container.register('router:main', Router);\n\n container.injection('controller:post', 'store', 'store:main');\n container.typeInjection('controller', 'router', 'router:main');\n\n var postController = container.lookup('controller:post');\n var store = container.lookup('store:main');\n var router = container.lookup('router:main');\n\n equal(postController.store, store);\n equal(postController.router, router);\n});\n\ntest(\"A factory with both type and individual factoryInjections\", function() {\n var container = new Container();\n var PostController = factory();\n var Store = factory();\n var Router = factory();\n\n container.register('controller:post', PostController);\n container.register('store:main', Store);\n container.register('router:main', Router);\n\n container.factoryInjection('controller:post', 'store', 'store:main');\n container.factoryTypeInjection('controller', 'router', 'router:main');\n\n var PostControllerFactory = container.lookupFactory('controller:post');\n var store = container.lookup('store:main');\n var router = container.lookup('router:main');\n\n equal(PostControllerFactory.store, store, 'PostControllerFactory has the instance of store');\n equal(PostControllerFactory.router, router, 'PostControllerFactory has the route instance');\n});\n\ntest(\"A non-singleton instance is never cached\", function() {\n var container = new Container();\n var PostView = factory();\n\n container.register('view:post', PostView, { singleton: false });\n\n var postView1 = container.lookup('view:post');\n var postView2 = container.lookup('view:post');\n\n ok(postView1 !== postView2, \"Non-singletons are not cached\");\n});\n\ntest(\"A non-instantiated property is not instantiated\", function() {\n var container = new Container();\n\n var template = function() {};\n container.register('template:foo', template, { instantiate: false });\n equal(container.lookup('template:foo'), template);\n});\n\ntest(\"A failed lookup returns undefined\", function() {\n var container = new Container();\n\n equal(container.lookup('doesnot:exist'), undefined);\n});\n\ntest(\"Injecting a failed lookup raises an error\", function() {\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n var container = new Container();\n\n var fooInstance = {};\n var fooFactory = {};\n\n var Foo = {\n create: function(args) { return fooInstance; },\n extend: function(args) { return fooFactory; }\n };\n\n container.register('model:foo', Foo);\n container.injection('model:foo', 'store', 'store:main');\n\n throws(function() {\n container.lookup('model:foo');\n });\n});\n\ntest(\"Injecting a falsy value does not raise an error\", function() {\n var container = new Container();\n var ApplicationController = factory();\n\n container.register('controller:application', ApplicationController);\n container.register('user:current', null, { instantiate: false });\n container.injection('controller:application', 'currentUser', 'user:current');\n\n equal(container.lookup('controller:application').currentUser, null);\n});\n\ntest(\"Destroying the container destroys any cached singletons\", function() {\n var container = new Container();\n var PostController = factory();\n var PostView = factory();\n var template = function() {};\n\n container.register('controller:post', PostController);\n container.register('view:post', PostView, { singleton: false });\n container.register('template:post', template, { instantiate: false });\n\n container.injection('controller:post', 'postView', 'view:post');\n\n var postController = container.lookup('controller:post');\n var postView = postController.postView;\n\n ok(postView instanceof PostView, \"The non-singleton was injected\");\n\n container.destroy();\n\n ok(postController.isDestroyed, \"Singletons are destroyed\");\n ok(!postView.isDestroyed, \"Non-singletons are not destroyed\");\n});\n\ntest(\"The container can take a hook to resolve factories lazily\", function() {\n var container = new Container();\n var PostController = factory();\n\n container.resolver = function(fullName) {\n if (fullName === 'controller:post') {\n return PostController;\n }\n };\n\n var postController = container.lookup('controller:post');\n\n ok(postController instanceof PostController, \"The correct factory was provided\");\n});\n\ntest(\"The container respect the resolver hook for `has`\", function() {\n var container = new Container();\n var PostController = factory();\n\n container.resolver = function(fullName) {\n if (fullName === 'controller:post') {\n return PostController;\n }\n };\n\n ok(container.has('controller:post'), \"the `has` method uses the resolver hook\");\n});\n\ntest(\"The container normalizes names before resolving\", function() {\n var container = new Container();\n var PostController = factory();\n\n container.normalize = function(fullName) {\n return 'controller:post';\n };\n\n container.register('controller:post', PostController);\n var postController = container.lookup('wycats');\n\n ok(postController instanceof PostController, \"Normalizes the name before resolving\");\n});\n\ntest(\"The container can get options that should be applied to all factories for a given type\", function() {\n var container = new Container();\n var PostView = factory();\n\n container.resolver = function(fullName) {\n if (fullName === 'view:post') {\n return PostView;\n }\n };\n\n container.optionsForType('view', { singleton: false });\n\n var postView1 = container.lookup('view:post');\n var postView2 = container.lookup('view:post');\n\n ok(postView1 instanceof PostView, \"The correct factory was provided\");\n ok(postView2 instanceof PostView, \"The correct factory was provided\");\n\n ok(postView1 !== postView2, \"The two lookups are different\");\n});\n\ntest(\"cannot register an `undefined` factory\", function(){\n var container = new Container();\n\n throws(function(){\n container.register('controller:apple', undefined);\n }, '');\n});\n\ntest(\"can re-register a factory\", function(){\n var container = new Container(),\n FirstApple = factory('first'),\n SecondApple = factory('second');\n\n container.register('controller:apple', FirstApple);\n container.register('controller:apple', SecondApple);\n\n ok(container.lookup('controller:apple') instanceof SecondApple);\n});\n\ntest(\"cannot re-register a factory if has been looked up\", function(){\n var container = new Container(),\n FirstApple = factory('first'),\n SecondApple = factory('second');\n\n container.register('controller:apple', FirstApple);\n ok(container.lookup('controller:apple') instanceof FirstApple);\n\n throws(function(){\n container.register('controller:apple', SecondApple);\n }, 'Cannot re-register: `controller:apple`, as it has already been looked up.');\n\n ok(container.lookup('controller:apple') instanceof FirstApple);\n});\n\n\n\n})();\n//@ sourceURL=container/~tests/container_test");minispade.register('container/~tests/sub_container_test', "(function() {var passedOptions;\nvar Container = requireModule('container');\n\nvar o_create = Object.create || (function(){\n function F(){}\n\n return function(o) {\n if (arguments.length !== 1) {\n throw new Ember.Error('Object.create implementation only accepts one parameter.');\n }\n F.prototype = o;\n return new F();\n };\n}());\n\nvar guids = 0;\n\nfunction factory() {\n var Klass = function(options) {\n setProperties(this, options);\n this._guid = guids++;\n };\n\n Klass.prototype.constructor = Klass;\n Klass.prototype.destroy = function() {\n this.isDestroyed = true;\n };\n\n Klass.prototype.toString = function() {\n return \"\";\n };\n\n Klass.create = create;\n Klass.extend = extend;\n Klass.reopen = extend;\n\n return Klass;\n\n function create(options) {\n passedOptions = options;\n return new this.prototype.constructor(options);\n }\n\n function reopenClass(options) {\n setProperties(this, options);\n }\n\n function extend (options) {\n var Child = function(options) {\n Klass.call(this, options);\n };\n\n var Parent = this;\n\n Child.prototype = new Parent();\n Child.prototype.constructor = Child;\n\n setProperties(Child.prototype, options);\n\n Child.create = create;\n Child.extend = extend;\n Child.reopen = extend;\n Child.reopenClass = reopenClass;\n\n return Child;\n }\n}\n\nfunction setProperties(object, properties) {\n for (var key in properties) {\n if (properties.hasOwnProperty(key)) {\n object[key] = properties[key];\n }\n }\n}\n\nvar container;\n\nmodule(\"Container (sub-containers)\", {\n setup: function() {\n container = new Container();\n var PostController = factory();\n\n container.register('controller:post', PostController);\n },\n\n teardown: function() {\n if (!container.isDestroyed) {\n container.destroy();\n }\n }\n});\n\ntest(\"Singletons already found on the parent container will be found again on the sub-container\", function() {\n var postController = container.lookup('controller:post');\n var subContainer = container.child();\n\n equal(postController, subContainer.lookup('controller:post'));\n});\n\ntest(\"Destroying a sub-container doesn't destroy any singletons on the parent\", function() {\n var postController = container.lookup('controller:post');\n var subContainer = container.child();\n subContainer.destroy();\n\n equal(postController.isDestroyed, undefined, \"The parent's singletons are not destroyed\");\n});\n\ntest(\"Looking up a singleton that wasn't yet looked up on a child container will cache it on the child\", function() {\n var subContainer1 = container.child();\n var subContainer2 = container.child();\n\n var postController1 = subContainer1.lookup('controller:post');\n var postController2 = subContainer2.lookup('controller:post');\n\n notEqual(postController1, postController2);\n});\n\ntest(\"Destroying a parent container destroys the sub-containers\", function() {\n var subContainer1 = container.child();\n var subContainer2 = container.child();\n\n var postController1 = subContainer1.lookup('controller:post');\n var postController2 = subContainer2.lookup('controller:post');\n\n container.destroy();\n\n equal(postController1.isDestroyed, true, \"The child's singleton is destroyed\");\n equal(postController2.isDestroyed, true, \"The child's singleton is destroyed\");\n});\n\ntest(\"Resolver is inherited from parent container\", function() {\n var otherController = factory();\n container.resolver = function(fullName) {\n return otherController;\n };\n var subContainer = container.child();\n\n equal(subContainer.resolve('controller:post'), otherController, 'should use parent resolver');\n equal(container.resolve('controller:post'), otherController, 'should use resolver');\n});\n\ntest(\"Type injections should be inherited\", function() {\n var container = new Container();\n var PostController = factory();\n var Store = factory();\n\n container.register('controller:post', PostController);\n container.register('store:main', Store);\n\n container.typeInjection('controller', 'store', 'store:main');\n\n var store = container.lookup('store:main');\n\n var childContainer = container.child();\n var postController = childContainer.lookup('controller:post');\n\n equal(postController.store, store);\n});\n\n})();\n//@ sourceURL=container/~tests/sub_container_test");minispade.register('ember-application/~tests/system/application_test', "(function() {var view;\nvar app;\nvar application;\nvar set = Ember.set, get = Ember.get;\nvar forEach = Ember.ArrayPolyfills.forEach;\nvar trim = Ember.$.trim;\nvar originalLookup;\nvar originalDebug;\n\nmodule(\"Ember.Application\", {\n setup: function() {\n originalLookup = Ember.lookup;\n originalDebug = Ember.debug;\n\n Ember.$(\"#qunit-fixture\").html(\"
HI
HI
\");\n Ember.run(function() {\n application = Ember.Application.create({ rootElement: '#one', router: null });\n });\n },\n\n teardown: function() {\n Ember.$(\"#qunit-fixture\").empty();\n Ember.debug = originalDebug;\n\n Ember.lookup = originalLookup;\n\n if (application) {\n Ember.run(application, 'destroy');\n }\n\n if (app) {\n Ember.run(app, 'destroy');\n }\n }\n});\n\ntest(\"you can make a new application in a non-overlapping element\", function() {\n Ember.run(function() {\n app = Ember.Application.create({ rootElement: '#two', router: null });\n });\n\n Ember.run(app, 'destroy');\n ok(true, \"should not raise\");\n});\n\ntest(\"you cannot make a new application that is a parent of an existing application\", function() {\n expectAssertion(function() {\n Ember.run(function() {\n Ember.Application.create({ rootElement: '#qunit-fixture' });\n });\n });\n});\n\ntest(\"you cannot make a new application that is a descendent of an existing application\", function() {\n expectAssertion(function() {\n Ember.run(function() {\n Ember.Application.create({ rootElement: '#one-child' });\n });\n });\n});\n\ntest(\"you cannot make a new application that is a duplicate of an existing application\", function() {\n expectAssertion(function() {\n Ember.run(function() {\n Ember.Application.create({ rootElement: '#one' });\n });\n });\n});\n\ntest(\"you cannot make two default applications without a rootElement error\", function() {\n expectAssertion(function() {\n Ember.run(function() {\n Ember.Application.create({ router: false });\n });\n });\n});\n\ntest(\"acts like a namespace\", function() {\n var lookup = Ember.lookup = {}, app;\n\n Ember.run(function() {\n app = lookup.TestApp = Ember.Application.create({ rootElement: '#two', router: false });\n });\n\n Ember.BOOTED = false;\n app.Foo = Ember.Object.extend();\n equal(app.Foo.toString(), \"TestApp.Foo\", \"Classes pick up their parent namespace\");\n});\n\nmodule(\"Ember.Application initialization\", {\n teardown: function() {\n Ember.run(app, 'destroy');\n Ember.TEMPLATES = {};\n }\n});\n\ntest('initialized application go to initial route', function() {\n Ember.run(function() {\n app = Ember.Application.create({\n rootElement: '#qunit-fixture'\n });\n\n app.Router.reopen({\n location: 'none'\n });\n\n app.register('template:application',\n Ember.Handlebars.compile(\"{{outlet}}\")\n );\n\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\n \"

Hi from index

\"\n );\n });\n\n equal(Ember.$('#qunit-fixture h1').text(), \"Hi from index\");\n});\n\ntest(\"initialize application via initialize call\", function() {\n Ember.run(function() {\n app = Ember.Application.create({\n rootElement: '#qunit-fixture'\n });\n\n app.Router.reopen({\n location: 'none'\n });\n\n app.ApplicationView = Ember.View.extend({\n template: function() { return \"

Hello!

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

Hello!

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

Hello!

\");\n }\n });\n\n app.ApplicationController = Ember.Controller.extend();\n\n app.Router.reopen({\n location: 'none'\n });\n });\n\n equal(Ember.$(\"#qunit-fixture h1\").text(), \"Hello!\");\n});\n\ntest(\"Minimal Application initialized with just an application template\", function() {\n Ember.$('#qunit-fixture').html('');\n Ember.run(function () {\n app = Ember.Application.create({\n rootElement: '#qunit-fixture'\n });\n });\n\n equal(trim(Ember.$('#qunit-fixture').text()), 'Hello World');\n});\n\ntest('enable log of libraries with an ENV var', function() {\n var debug = Ember.debug;\n var messages = [];\n\n Ember.LOG_VERSION = true;\n\n Ember.debug = function(message) {\n messages.push(message);\n };\n\n Ember.libraries.register(\"my-lib\", \"2.0.0a\");\n\n Ember.run(function() {\n app = Ember.Application.create({\n rootElement: '#qunit-fixture'\n });\n });\n\n equal(messages[1], \"Ember : \" + Ember.VERSION);\n equal(messages[2], \"Handlebars : \" + Handlebars.VERSION);\n equal(messages[3], \"jQuery : \" + Ember.$().jquery);\n equal(messages[4], \"my-lib : \" + \"2.0.0a\");\n\n Ember.libraries.deRegister(\"my-lib\");\n Ember.LOG_VERSION = false;\n Ember.debug = debug;\n});\n\ntest('disable log version of libraries with an ENV var', function() {\n var logged = false;\n\n Ember.LOG_VERSION = false;\n\n Ember.debug = function(message) {\n logged = true;\n };\n\n Ember.$(\"#qunit-fixture\").empty();\n\n Ember.run(function() {\n app = Ember.Application.create({\n rootElement: '#qunit-fixture'\n });\n\n app.Router.reopen({\n location: 'none'\n });\n });\n\n ok(!logged, 'library version logging skipped');\n});\n\ntest(\"can resolve custom router\", function(){\n var CustomRouter = Ember.Router.extend();\n\n var CustomResolver = Ember.DefaultResolver.extend({\n resolveOther: function(parsedName){\n if (parsedName.type === \"router\") {\n return CustomRouter;\n } else {\n return this._super(parsedName);\n }\n }\n });\n\n app = Ember.run(function(){\n return Ember.Application.create({\n Resolver: CustomResolver\n });\n });\n\n ok(app.__container__.lookup('router:main') instanceof CustomRouter, 'application resolved the correct router');\n});\n\n})();\n//@ sourceURL=ember-application/~tests/system/application_test");minispade.register('ember-application/~tests/system/controller_test', "(function() {module(\"Controller dependencies\");\n\ntest(\"If a controller specifies a dependency, but does not have a container it should error\", function(){\n var Controller = Ember.Controller.extend({\n needs: 'posts'\n });\n\n expectAssertion(function(){\n Controller.create();\n }, /specifies `needs`, but does not have a container. Please ensure this controller was instantiated with a container./);\n});\n\ntest(\"If a controller specifies a dependency, it is accessible\", function() {\n var container = new Ember.Container();\n\n container.register('controller:post', Ember.Controller.extend({\n needs: 'posts'\n }));\n\n container.register('controller:posts', Ember.Controller.extend());\n\n var postController = container.lookup('controller:post'),\n postsController = container.lookup('controller:posts');\n\n equal(postsController, postController.get('controllers.posts'), \"controller.posts must be auto synthesized\");\n});\n\ntest(\"If a controller specifies an unavailable dependency, it raises\", function() {\n var container = new Ember.Container();\n\n container.register('controller:post', Ember.Controller.extend({\n needs: 'posts'\n }));\n\n expectAssertion(function() {\n container.lookup('controller:post');\n }, /controller:posts/);\n});\n\ntest(\"Mixin sets up controllers if there is needs before calling super\", function() {\n var container = new Ember.Container();\n\n container.register('controller:other', Ember.ArrayController.extend({\n needs: 'posts',\n content: Ember.computed.alias('controllers.posts')\n }));\n\n container.register('controller:another', Ember.ArrayController.extend({\n needs: 'posts',\n contentBinding: 'controllers.posts'\n }));\n\n container.register('controller:posts', Ember.ArrayController.extend());\n\n container.lookup('controller:posts').set('content', Ember.A(['a','b','c']));\n\n deepEqual(['a','b','c'], container.lookup('controller:other').toArray());\n deepEqual(['a','b','c'], container.lookup('controller:another').toArray());\n});\n\ntest(\"raises if trying to get a controller that was not pre-defined in `needs`\", function() {\n var container = new Ember.Container();\n\n container.register('controller:foo', Ember.Controller.extend());\n container.register('controller:bar', Ember.Controller.extend({\n needs: 'foo'\n }));\n\n var fooController = container.lookup('controller:foo');\n var barController = container.lookup('controller:bar');\n\n throws(function(){\n fooController.get('controllers.bar');\n }, /#needs does not include `bar`/,\n 'throws if controllers is accesed but needs not defined');\n\n equal(barController.get('controllers.foo'), fooController, 'correctly needed controllers should continue to work');\n\n throws(function(){\n barController.get('controllers.baz');\n }, /#needs does not include `baz`/,\n 'should throw if no such controller was needed');\n});\n\ntest(\"setting the controllers property directly, should not be possible\", function(){\n var controller = Ember.Controller.create();\n var controllers = controller.get('controllers');\n\n throws(function(){\n controller.set('controllers', 'epic-self-troll');\n }, /Cannot Set: controllers on:/,\n 'should raise when attempting to set to the controllers property');\n\n equal(controller.get('controllers'), controllers, 'original controllers CP should have been unchanged');\n});\n\n})();\n//@ sourceURL=ember-application/~tests/system/controller_test");minispade.register('ember-application/~tests/system/dependency_injection/custom_resolver_test', "(function() {var application;\n\nmodule(\"Ember.Application Depedency Injection – customResolver\",{\n setup: function() {\n function fallbackTemplate() { return \"

Fallback

\"; }\n\n var Resolver = Ember.DefaultResolver.extend({\n resolveTemplate: function(parsedName) {\n var resolvedTemplate = this._super(parsedName);\n if (resolvedTemplate) { return resolvedTemplate; }\n return fallbackTemplate;\n }\n });\n\n application = Ember.run(function() {\n return Ember.Application.create({\n Resolver: Resolver,\n rootElement: '#qunit-fixture'\n\n });\n });\n },\n teardown: function() {\n Ember.run(application, 'destroy');\n }\n});\n\ntest(\"a resolver can be supplied to application\", function() {\n equal(Ember.$(\"h1\", application.rootElement).text(), \"Fallback\");\n});\n\n\n})();\n//@ sourceURL=ember-application/~tests/system/dependency_injection/custom_resolver_test");minispade.register('ember-application/~tests/system/dependency_injection/default_resolver_test', "(function() {var locator, application, lookup, originalLookup;\n\nmodule(\"Ember.Application Depedency Injection\", {\n setup: function() {\n originalLookup = Ember.lookup;\n application = Ember.run(Ember.Application, 'create');\n\n locator = application.__container__;\n },\n\n teardown: function() {\n Ember.TEMPLATES = {};\n Ember.lookup = originalLookup;\n Ember.run(application, 'destroy');\n }\n});\n\ntest('the default resolver can look things up in other namespaces', function() {\n var UserInterface = Ember.lookup.UserInterface = Ember.Namespace.create();\n UserInterface.NavigationController = Ember.Controller.extend();\n\n var nav = locator.lookup('controller:userInterface/navigation');\n\n ok(nav instanceof UserInterface.NavigationController, \"the result should be an instance of the specified class\");\n});\n\ntest('the default resolver looks up templates in Ember.TEMPLATES', function() {\n function fooTemplate() {}\n function fooBarTemplate() {}\n function fooBarBazTemplate() {}\n\n Ember.TEMPLATES['foo'] = fooTemplate;\n Ember.TEMPLATES['fooBar'] = fooBarTemplate;\n Ember.TEMPLATES['fooBar/baz'] = fooBarBazTemplate;\n\n equal(locator.lookup('template:foo'), fooTemplate, \"resolves template:foo\");\n equal(locator.lookup('template:fooBar'), fooBarTemplate, \"resolves template:foo_bar\");\n equal(locator.lookup('template:fooBar.baz'), fooBarBazTemplate, \"resolves template:foo_bar.baz\");\n});\n\ntest('the default resolver looks up basic name as no prefix', function() {\n ok(Ember.Controller.detect(locator.lookup('controller:basic')), 'locator looksup correct controller');\n});\n\nfunction detectEqual(first, second, message) {\n ok(first.detect(second), message);\n}\n\ntest('the default resolver looks up arbitrary types on the namespace', function() {\n application.FooManager = Ember.Object.extend({});\n\n detectEqual(application.FooManager, locator.resolver('manager:foo'),\"looks up FooManager on application\");\n});\n\ntest(\"the default resolver resolves models on the namespace\", function() {\n application.Post = Ember.Object.extend({});\n\n detectEqual(application.Post, locator.lookupFactory('model:post'), \"looks up Post model on application\");\n});\n\nif (Ember.FEATURES.isEnabled('container-renderables')) {\n test(\"the default resolver resolves helpers from Ember.Handlebars.helpers\", function(){\n function fooresolvertestHelper(){ return 'FOO'; }\n function barBazResolverTestHelper(){ return 'BAZ'; }\n Ember.Handlebars.registerHelper('fooresolvertest', fooresolvertestHelper);\n Ember.Handlebars.registerHelper('bar-baz-resolver-test', barBazResolverTestHelper);\n equal(fooresolvertestHelper, locator.lookup('helper:fooresolvertest'), \"looks up fooresolvertestHelper helper\");\n equal(barBazResolverTestHelper, locator.lookup('helper:bar-baz-resolver-test'), \"looks up barBazResolverTestHelper helper\");\n });\n\n test(\"the default resolver resolves container-registered helpers\", function(){\n function gooresolvertestHelper(){ return 'GOO'; }\n function gooGazResolverTestHelper(){ return 'GAZ'; }\n application.register('helper:gooresolvertest', gooresolvertestHelper);\n application.register('helper:goo-baz-resolver-test', gooGazResolverTestHelper);\n equal(gooresolvertestHelper, locator.lookup('helper:gooresolvertest'), \"looks up gooresolvertest helper\");\n equal(gooGazResolverTestHelper, locator.lookup('helper:goo-baz-resolver-test'), \"looks up gooGazResolverTestHelper helper\");\n });\n}\n\ntest(\"the default resolver throws an error if the fullName to resolve is invalid\", function(){\n raises(function(){ locator.resolve(undefined);}, TypeError, /Invalid fullName/ );\n raises(function(){ locator.resolve(null); }, TypeError, /Invalid fullName/ );\n raises(function(){ locator.resolve(''); }, TypeError, /Invalid fullName/ );\n raises(function(){ locator.resolve(''); }, TypeError, /Invalid fullName/ );\n raises(function(){ locator.resolve(':'); }, TypeError, /Invalid fullName/ );\n raises(function(){ locator.resolve('model'); }, TypeError, /Invalid fullName/ );\n raises(function(){ locator.resolve('model:'); }, TypeError, /Invalid fullName/ );\n raises(function(){ locator.resolve(':type'); }, TypeError, /Invalid fullName/ );\n});\n\n})();\n//@ sourceURL=ember-application/~tests/system/dependency_injection/default_resolver_test");minispade.register('ember-application/~tests/system/dependency_injection/normalization_test', "(function() {var application, locator, forEach = Ember.ArrayPolyfills.forEach;\n\nmodule(\"Ember.Application Depedency Injection – normalization\", {\n setup: function() {\n application = Ember.run(Ember.Application, 'create');\n locator = application.__container__;\n },\n\n teardown: function() {\n Ember.run(application, 'destroy');\n }\n});\n\ntest('normalization', function() {\n ok(locator.normalize, 'locator#normalize is present');\n\n equal(locator.normalize('foo:bar'), 'foo:bar');\n\n equal(locator.normalize('controller:posts'), 'controller:posts');\n equal(locator.normalize('controller:posts_index'), 'controller:postsIndex');\n equal(locator.normalize('controller:posts.index'), 'controller:postsIndex');\n equal(locator.normalize('controller:posts.post.index'), 'controller:postsPostIndex');\n equal(locator.normalize('controller:posts_post.index'), 'controller:postsPostIndex');\n equal(locator.normalize('controller:posts.post_index'), 'controller:postsPostIndex');\n equal(locator.normalize('controller:postsIndex'), 'controller:postsIndex');\n equal(locator.normalize('controller:blogPosts.index'), 'controller:blogPostsIndex');\n equal(locator.normalize('controller:blog/posts.index'), 'controller:blog/postsIndex');\n equal(locator.normalize('controller:blog/posts.post.index'), 'controller:blog/postsPostIndex');\n equal(locator.normalize('controller:blog/posts_post.index'), 'controller:blog/postsPostIndex');\n\n equal(locator.normalize('template:blog/posts_index'), 'template:blog/posts_index');\n});\n\ntest('normalization is indempotent', function() {\n var examples = ['controller:posts', 'controller:posts.post.index', 'controller:blog/posts.post_index', 'template:foo_bar'];\n\n forEach.call(examples, function (example) {\n equal(locator.normalize(locator.normalize(example)), locator.normalize(example));\n });\n});\n\n})();\n//@ sourceURL=ember-application/~tests/system/dependency_injection/normalization_test");minispade.register('ember-application/~tests/system/dependency_injection/to_string_test', "(function() {var originalLookup, App, originalModelInjections;\n\nmodule(\"Ember.Application Dependency Injection – toString\",{\n setup: function() {\n originalModelInjections = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n originalLookup = Ember.lookup;\n\n Ember.run(function(){\n App = Ember.Application.create();\n Ember.lookup = {\n App: App\n };\n });\n\n App.Post = Ember.Object.extend();\n\n },\n\n teardown: function() {\n Ember.lookup = originalLookup;\n Ember.run(App, 'destroy');\n Ember.MODEL_FACTORY_INJECTIONS = originalModelInjections;\n }\n});\n\ntest(\"factories\", function() {\n var PostFactory = App.__container__.lookupFactory('model:post');\n equal(PostFactory.toString(), 'App.Post', 'expecting the model to be post');\n});\n\ntest(\"instances\", function() {\n var post = App.__container__.lookup('model:post');\n var guid = Ember.guidFor(post);\n\n equal(post.toString(), '', 'expecting the model to be post');\n});\n\ntest(\"with a custom resolver\", function() {\n Ember.run(App,'destroy');\n\n Ember.run(function(){\n App = Ember.Application.create({\n Resolver: Ember.DefaultResolver.extend({\n makeToString: function(factory, fullName) {\n return fullName;\n }\n })\n });\n });\n\n App.__container__.register('model:peter', Ember.Object.extend());\n\n var peter = App.__container__.lookup('model:peter');\n var guid = Ember.guidFor(peter);\n\n equal(peter.toString(), '', 'expecting the supermodel to be peter');\n});\n\n})();\n//@ sourceURL=ember-application/~tests/system/dependency_injection/to_string_test");minispade.register('ember-application/~tests/system/dependency_injection_test', "(function() {var locator, originalLookup = Ember.lookup, lookup,\n application, set = Ember.set, get = Ember.get,\n forEach = Ember.ArrayPolyfills.forEach, originalModelInjections;\n\nmodule(\"Ember.Application Dependency Injection\", {\n setup: function() {\n originalModelInjections = Ember.MODEL_FACTORY_INJECTIONS;\n Ember.MODEL_FACTORY_INJECTIONS = true;\n\n application = Ember.run(Ember.Application, 'create');\n\n application.Person = Ember.Object.extend({});\n application.Orange = Ember.Object.extend({});\n application.Email = Ember.Object.extend({});\n application.User = Ember.Object.extend({});\n application.PostIndexController = Ember.Object.extend({});\n\n application.register('model:person', application.Person, {singleton: false });\n application.register('model:user', application.User, {singleton: false });\n application.register('fruit:favorite', application.Orange);\n application.register('communication:main', application.Email, {singleton: false});\n application.register('controller:postIndex', application.PostIndexController, {singleton: true});\n\n locator = application.__container__;\n\n lookup = Ember.lookup = {};\n },\n teardown: function() {\n Ember.run(application, 'destroy');\n application = locator = null;\n Ember.lookup = originalLookup;\n Ember.MODEL_FACTORY_INJECTIONS = originalModelInjections;\n Ember.TESTING_DEPRECATION = false;\n }\n});\n\ntest('container lookup is normalized', function() {\n var dotNotationController = locator.lookup('controller:post.index');\n var camelCaseController = locator.lookup('controller:postIndex');\n\n ok(dotNotationController instanceof application.PostIndexController);\n ok(camelCaseController instanceof application.PostIndexController);\n\n equal(dotNotationController, camelCaseController);\n});\n\ntest('Ember.Container.defaultContainer is the same as the Apps container, but emits deprecation warnings', function() {\n Ember.TESTING_DEPRECATION = true;\n var routerFromContainer = locator.lookup('router:main'),\n routerFromDefaultCOntainer = Ember.Container.defaultContainer.lookup('router:main');\n\n equal(routerFromContainer, routerFromDefaultCOntainer, 'routers from both containers are equal');\n});\n\ntest('registered entities can be looked up later', function() {\n equal(locator.resolve('model:person'), application.Person);\n equal(locator.resolve('model:user'), application.User);\n equal(locator.resolve('fruit:favorite'), application.Orange);\n equal(locator.resolve('communication:main'), application.Email);\n equal(locator.resolve('controller:postIndex'), application.PostIndexController);\n\n equal(locator.lookup('fruit:favorite'), locator.lookup('fruit:favorite'), 'singleton lookup worked');\n ok(locator.lookup('model:user') !== locator.lookup('model:user'), 'non-singleton lookup worked');\n});\n\n\ntest('injections', function() {\n application.inject('model', 'fruit', 'fruit:favorite');\n application.inject('model:user', 'communication', 'communication:main');\n\n var user = locator.lookup('model:user'),\n person = locator.lookup('model:person'),\n fruit = locator.lookup('fruit:favorite');\n\n equal(user.get('fruit'), fruit);\n equal(person.get('fruit'), fruit);\n\n ok(application.Email.detectInstance(user.get('communication')));\n});\n\n})();\n//@ sourceURL=ember-application/~tests/system/dependency_injection_test");minispade.register('ember-application/~tests/system/initializers_test', "(function() {var oldInitializers, app;\nvar indexOf = Ember.ArrayPolyfills.indexOf;\n\nmodule(\"Ember.Application initializers\", {\n setup: function() {\n },\n\n teardown: function() {\n if (app) {\n Ember.run(function() { app.destroy(); });\n }\n }\n});\n\ntest(\"initializers can be registered in a specified order\", function() {\n var order = [];\n var Application = Ember.Application.extend();\n Application.initializer({\n name: 'fourth',\n after: 'third',\n initialize: function(container) {\n order.push('fourth');\n }\n });\n\n Application.initializer({\n name: 'second',\n before: 'third',\n initialize: function(container) {\n order.push('second');\n }\n });\n\n Application.initializer({\n name: 'fifth',\n after: 'fourth',\n initialize: function(container) {\n order.push('fifth');\n }\n });\n\n Application.initializer({\n name: 'first',\n before: 'second',\n initialize: function(container) {\n order.push('first');\n }\n });\n\n Application.initializer({\n name: 'third',\n initialize: function(container) {\n order.push('third');\n }\n });\n\n Ember.run(function() {\n app = Application.create({\n router: false,\n rootElement: '#qunit-fixture'\n });\n });\n\n deepEqual(order, ['first', 'second', 'third', 'fourth', 'fifth']);\n});\n\ntest(\"initializers can have multiple dependencies\", function () {\n var order = [],\n a = {\n name: \"a\",\n before: \"b\",\n initialize: function(container) {\n order.push('a');\n }\n },\n b = {\n name: \"b\",\n initialize: function(container) {\n order.push('b');\n }\n },\n c = {\n name: \"c\",\n after: \"b\",\n initialize: function(container) {\n order.push('c');\n }\n },\n afterB = {\n name: \"after b\",\n after: \"b\",\n initialize: function(container) {\n order.push(\"after b\");\n }\n },\n afterC = {\n name: \"after c\",\n after: \"c\",\n initialize: function(container) {\n order.push(\"after c\");\n }\n };\n Ember.Application.initializer(b);\n Ember.Application.initializer(a);\n Ember.Application.initializer(afterC);\n Ember.Application.initializer(afterB);\n Ember.Application.initializer(c);\n\n Ember.run(function() {\n app = Ember.Application.create({\n router: false,\n rootElement: '#qunit-fixture'\n });\n });\n\n ok(indexOf.call(order, a.name) < indexOf.call(order, b.name), 'a < b');\n ok(indexOf.call(order, b.name) < indexOf.call(order, c.name), 'b < c');\n ok(indexOf.call(order, b.name) < indexOf.call(order, afterB.name), 'b < afterB');\n ok(indexOf.call(order, c.name) < indexOf.call(order, afterC.name), 'c < afterC');\n});\n\ntest(\"initializers set on Application subclasses should not be shared between apps\", function(){\n var firstInitializerRunCount = 0, secondInitializerRunCount = 0;\n var FirstApp = Ember.Application.extend();\n FirstApp.initializer({\n name: 'first',\n initialize: function(container) {\n firstInitializerRunCount++;\n }\n });\n var SecondApp = Ember.Application.extend();\n SecondApp.initializer({\n name: 'second',\n initialize: function(container) {\n secondInitializerRunCount++;\n }\n });\n Ember.$('#qunit-fixture').html('
');\n Ember.run(function() {\n var firstApp = FirstApp.create({\n router: false,\n rootElement: '#qunit-fixture #first'\n });\n });\n equal(firstInitializerRunCount, 1, 'first initializer only was run');\n equal(secondInitializerRunCount, 0, 'first initializer only was run');\n Ember.run(function() {\n var secondApp = SecondApp.create({\n router: false,\n rootElement: '#qunit-fixture #second'\n });\n });\n equal(firstInitializerRunCount, 1, 'second initializer only was run');\n equal(secondInitializerRunCount, 1, 'second initializer only was run');\n});\n\ntest(\"initializers are concatenated\", function(){\n var firstInitializerRunCount = 0, secondInitializerRunCount = 0;\n var FirstApp = Ember.Application.extend();\n FirstApp.initializer({\n name: 'first',\n initialize: function(container) {\n firstInitializerRunCount++;\n }\n });\n\n var SecondApp = FirstApp.extend();\n SecondApp.initializer({\n name: 'second',\n initialize: function(container) {\n secondInitializerRunCount++;\n }\n });\n\n Ember.$('#qunit-fixture').html('
');\n Ember.run(function() {\n var firstApp = FirstApp.create({\n router: false,\n rootElement: '#qunit-fixture #first'\n });\n });\n equal(firstInitializerRunCount, 1, 'first initializer only was run when base class created');\n equal(secondInitializerRunCount, 0, 'first initializer only was run when base class created');\n firstInitializerRunCount = 0;\n Ember.run(function() {\n var secondApp = SecondApp.create({\n router: false,\n rootElement: '#qunit-fixture #second'\n });\n });\n equal(firstInitializerRunCount, 1, 'first initializer was run when subclass created');\n equal(secondInitializerRunCount, 1, 'second initializers was run when subclass created');\n});\n\ntest(\"initializers are per-app\", function(){\n expect(0);\n var FirstApp = Ember.Application.extend();\n FirstApp.initializer({\n name: 'shouldNotCollide',\n initialize: function(container) {}\n });\n\n var SecondApp = Ember.Application.extend();\n SecondApp.initializer({\n name: 'shouldNotCollide',\n initialize: function(container) {}\n });\n});\n\n})();\n//@ sourceURL=ember-application/~tests/system/initializers_test");minispade.register('ember-application/~tests/system/logging_test', "(function() {var App, logs, originalLogger;\n\nmodule(\"Ember.Application – logging of generated classes\", {\n setup: function() {\n logs = {};\n\n originalLogger = Ember.Logger.info;\n\n Ember.Logger.info = function() {\n var fullName = arguments[1].fullName;\n\n logs[fullName] = logs[fullName] || 0;\n logs[fullName]++;\n };\n\n Ember.run(function() {\n App = Ember.Application.create({\n LOG_ACTIVE_GENERATION: true\n });\n\n App.Router.reopen({\n location: 'none'\n });\n\n App.Router.map(function() {\n this.resource(\"posts\");\n });\n\n App.deferReadiness();\n });\n },\n\n teardown: function() {\n Ember.Logger.info = originalLogger;\n\n Ember.run(App, 'destroy');\n\n logs = App = null;\n }\n});\n\nfunction visit(path) {\n stop();\n\n var promise = Ember.run(function(){\n return new Ember.RSVP.Promise(function(resolve, reject){\n var router = App.__container__.lookup('router:main');\n\n resolve(router.handleURL(path).then(function(value){\n start();\n ok(true, 'visited: `' + path + '`');\n return value;\n }, function(reason) {\n start();\n ok(false, 'failed to visit:`' + path + '` reason: `' + QUnit.jsDump.parse(reason));\n throw reason;\n }));\n });\n });\n\n return {\n then: function(resolve, reject) {\n Ember.run(promise, 'then', resolve, reject);\n }\n };\n}\n\ntest(\"log class generation if logging enabled\", function() {\n Ember.run(App, 'advanceReadiness');\n\n visit('/posts').then(function() {\n equal(Ember.keys(logs).length, 6, 'expected logs');\n });\n});\n\ntest(\"do NOT log class generation if logging disabled\", function() {\n App.reopen({\n LOG_ACTIVE_GENERATION: false\n });\n\n Ember.run(App, 'advanceReadiness');\n\n visit('/posts').then(function() {\n equal(Ember.keys(logs).length, 0, 'expected no logs');\n });\n});\n\ntest(\"actively generated classes get logged\", function() {\n Ember.run(App, 'advanceReadiness');\n\n visit('/posts').then(function() {\n equal(logs['controller:application'], 1, 'expected: ApplicationController was generated');\n equal(logs['controller:posts'], 1, 'expected: PostsController was generated');\n\n equal(logs['route:application'], 1, 'expected: ApplicationRoute was generated');\n equal(logs['route:posts'], 1, 'expected: PostsRoute was generated');\n });\n});\n\ntest(\"predefined classes do not get logged\", function() {\n App.ApplicationController = Ember.Controller.extend();\n App.PostsController = Ember.Controller.extend();\n\n App.ApplicationRoute = Ember.Route.extend();\n App.PostsRoute = Ember.Route.extend();\n\n Ember.run(App, 'advanceReadiness');\n\n visit('/posts').then(function() {\n ok(!logs['controller:application'], 'did not expect: ApplicationController was generated');\n ok(!logs['controller:posts'], 'did not expect: PostsController was generated');\n\n ok(!logs['route:application'], 'did not expect: ApplicationRoute was generated');\n ok(!logs['route:posts'], 'did not expect: PostsRoute was generated');\n });\n});\n\nmodule(\"Ember.Application – logging of view lookups\", {\n setup: function() {\n logs = {};\n\n originalLogger = Ember.Logger.info;\n\n Ember.Logger.info = function() {\n var fullName = arguments[1].fullName;\n\n logs[fullName] = logs[fullName] || 0;\n logs[fullName]++;\n };\n\n Ember.run(function() {\n App = Ember.Application.create({\n LOG_VIEW_LOOKUPS: true\n });\n\n App.Router.reopen({\n location: 'none'\n });\n\n App.Router.map(function() {\n this.resource(\"posts\");\n });\n\n App.deferReadiness();\n });\n },\n\n teardown: function() {\n Ember.Logger.info = originalLogger;\n\n Ember.run(App, 'destroy');\n\n logs = App = null;\n }\n});\n\ntest(\"log when template and view are missing when flag is active\", function() {\n App.register('template:application', function() { return ''; });\n Ember.run(App, 'advanceReadiness');\n\n visit('/posts').then(function() {\n equal(logs['template:application'], undefined, 'expected: Should not log template:application since it exists.');\n equal(logs['template:index'], 1, 'expected: Could not find \"index\" template or view.');\n equal(logs['template:posts'], 1, 'expected: Could not find \"posts\" template or view.');\n });\n});\n\ntest(\"do not log when template and view are missing when flag is not true\", function() {\n App.reopen({\n LOG_VIEW_LOOKUPS: false\n });\n\n Ember.run(App, 'advanceReadiness');\n\n visit('/posts').then(function() {\n equal(Ember.keys(logs).length, 0, 'expected no logs');\n });\n});\n\ntest(\"log which view is used with a template\", function() {\n App.register('template:application', function() { return 'Template with default view'; });\n App.register('template:foo', function() { return 'Template with custom view'; });\n App.register('view:posts', Ember.View.extend({templateName: 'foo'}));\n Ember.run(App, 'advanceReadiness');\n\n visit('/posts').then(function() {\n equal(logs['view:application'], 1, 'expected: Should log use of default view');\n equal(logs['view:index'], undefined, 'expected: Should not log when index is not present.');\n equal(logs['view:posts'], 1, 'expected: Rendering posts with PostsView.');\n });\n});\n\ntest(\"do not log which views are used with templates when flag is not true\", function() {\n App.reopen({\n LOG_VIEW_LOOKUPS: false\n });\n\n Ember.run(App, 'advanceReadiness');\n\n visit('/posts').then(function() {\n equal(Ember.keys(logs).length, 0, 'expected no logs');\n });\n});\n\n})();\n//@ sourceURL=ember-application/~tests/system/logging_test");minispade.register('ember-application/~tests/system/readiness_test', "(function() {var jQuery, Application, application;\nvar readyWasCalled, domReady, readyCallbacks;\n\n// We are using a small mock of jQuery because jQuery is third-party code with\n// very well-defined semantics, and we want to confirm that a jQuery stub run\n// in a more minimal server environment that implements this behavior will be\n// sufficient for Ember's requirements.\n\nmodule(\"Application readiness\", {\n setup: function() {\n readyWasCalled = 0;\n readyCallbacks = [];\n\n var jQueryInstance = {\n ready: function(callback) {\n readyCallbacks.push(callback);\n if (jQuery.isReady) {\n domReady();\n }\n }\n };\n\n jQuery = function() {\n return jQueryInstance;\n };\n jQuery.isReady = false;\n\n var domReadyCalled = 0;\n domReady = function() {\n if (domReadyCalled !== 0) { return; }\n domReadyCalled++;\n var i;\n for (i=0; itemplate was called\"));\n\n view = Ember.View.create({\n container: container,\n templateName: 'testTemplate'\n });\n\n appendView();\n\n ok(view.$('#twas-called').length, \"the named template was called\");\n});\n\ntest(\"template view should call the function of the associated template with itself as the context\", function() {\n container.register('template:testTemplate', Ember.Handlebars.compile(\"

template was called for {{view.personName}}. Yea {{view.personName}}

\"));\n\n view = Ember.View.createWithMixins({\n container: container,\n templateName: 'testTemplate',\n\n _personName: \"Tom DAAAALE\",\n _i: 0,\n\n personName: Ember.computed(function() {\n this._i++;\n return this._personName + this._i;\n })\n });\n\n appendView();\n\n equal(\"template was called for Tom DAAAALE1. Yea Tom DAAAALE1\", view.$('#twas-called').text(), \"the named template was called with the view as the data source\");\n});\n\ntest(\"should allow values from normal JavaScript hash objects to be used\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#with view.person}}{{firstName}} {{lastName}} (and {{pet.name}}){{/with}}'),\n\n person: {\n firstName: 'Señor',\n lastName: 'CFC',\n pet: {\n name: 'Fido'\n }\n }\n });\n\n appendView();\n\n equal(view.$().text(), \"Señor CFC (and Fido)\", \"prints out values from a hash\");\n});\n\ntest(\"htmlSafe should return an instance of Handlebars.SafeString\", function() {\n var safeString = Ember.String.htmlSafe(\"you need to be more bold\");\n\n ok(safeString instanceof Handlebars.SafeString, \"should return SafeString\");\n});\n\ntest(\"should escape HTML in normal mustaches\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{view.output}}'),\n output: \"you need to be more bold\"\n });\n\n appendView();\n equal(view.$('b').length, 0, \"does not create an element\");\n equal(view.$().text(), 'you need to be more bold', \"inserts entities, not elements\");\n\n Ember.run(function() { set(view, 'output', \"you are so super\"); });\n equal(view.$().text(), 'you are so super', \"updates with entities, not elements\");\n equal(view.$('i').length, 0, \"does not create an element when value is updated\");\n});\n\ntest(\"should not escape HTML in triple mustaches\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{{view.output}}}'),\n output: \"you need to be more bold\"\n });\n\n appendView();\n\n equal(view.$('b').length, 1, \"creates an element\");\n\n Ember.run(function() {\n set(view, 'output', \"you are so super\");\n });\n\n equal(view.$('i').length, 1, \"creates an element when value is updated\");\n});\n\ntest(\"should not escape HTML if string is a Handlebars.SafeString\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{view.output}}'),\n output: new Handlebars.SafeString(\"you need to be more bold\")\n });\n\n appendView();\n\n equal(view.$('b').length, 1, \"creates an element\");\n\n Ember.run(function() {\n set(view, 'output', new Handlebars.SafeString(\"you are so super\"));\n });\n\n equal(view.$('i').length, 1, \"creates an element when value is updated\");\n});\n\ntest(\"child views can be inserted using the {{view}} Handlebars helper\", function() {\n container.register('template:nester', Ember.Handlebars.compile(\"

Hello {{world}}

{{view \\\"TemplateTests.LabelView\\\"}}\"));\n container.register('template:nested', Ember.Handlebars.compile(\"
Goodbye {{cruel}} {{world}}
\"));\n\n var context = {\n world: \"world!\"\n };\n\n TemplateTests.LabelView = Ember.View.extend({\n container: container,\n tagName: \"aside\",\n templateName: 'nested'\n });\n\n view = Ember.View.create({\n container: container,\n templateName: 'nester',\n context: context\n });\n\n Ember.set(context, 'cruel', \"cruel\");\n\n appendView();\n\n ok(view.$(\"#hello-world:contains('Hello world!')\").length, \"The parent view renders its contents\");\n ok(view.$(\"#child-view:contains('Goodbye cruel world!')\").length === 1, \"The child view renders its content once\");\n ok(view.$().text().match(/Hello world!.*Goodbye cruel world\\!/), \"parent view should appear before the child view\");\n});\n\ntest(\"should accept relative paths to views\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('Hey look, at {{view \"view.myCool.view\"}}'),\n\n myCool: Ember.Object.create({\n view: Ember.View.extend({\n template: Ember.Handlebars.compile(\"my cool view\")\n })\n })\n });\n\n appendView();\n\n equal(view.$().text(), \"Hey look, at my cool view\");\n});\n\ntest(\"child views can be inserted inside a bind block\", function() {\n container.register('template:nester', Ember.Handlebars.compile(\"

Hello {{world}}

{{view \\\"TemplateTests.BQView\\\"}}\"));\n container.register('template:nested', Ember.Handlebars.compile(\"
Goodbye {{#with content}}{{blah}} {{view \\\"TemplateTests.OtherView\\\"}}{{/with}} {{world}}
\"));\n container.register('template:other', Ember.Handlebars.compile(\"cruel\"));\n\n var context = {\n world: \"world!\"\n };\n\n TemplateTests.BQView = Ember.View.extend({\n container: container,\n tagName: \"blockquote\",\n templateName: 'nested'\n });\n\n TemplateTests.OtherView = Ember.View.extend({\n container: container,\n templateName: 'other'\n });\n\n view = Ember.View.create({\n container: container,\n context: context,\n templateName: 'nester'\n });\n\n Ember.set(context, 'content', Ember.Object.create({ blah: \"wot\" }));\n\n appendView();\n\n ok(view.$(\"#hello-world:contains('Hello world!')\").length, \"The parent view renders its contents\");\n\n ok(view.$(\"blockquote\").text().match(/Goodbye.*wot.*cruel.*world\\!/), \"The child view renders its content once\");\n ok(view.$().text().match(/Hello world!.*Goodbye.*wot.*cruel.*world\\!/), \"parent view should appear before the child view\");\n});\n\ntest(\"Ember.View should bind properties in the parent context\", function() {\n var context = {\n content: Ember.Object.create({\n wham: 'bam'\n }),\n\n blam: \"shazam\"\n };\n\n view = Ember.View.create({\n context: context,\n template: Ember.Handlebars.compile('

{{#with content}}{{wham}}-{{../blam}}{{/with}}

')\n });\n\n appendView();\n\n equal(view.$('#first').text(), \"bam-shazam\", \"renders parent properties\");\n});\n\n\ntest(\"Ember.View should bind properties in the grandparent context\", function() {\n var context = {\n content: Ember.Object.create({\n wham: 'bam',\n thankYou: Ember.Object.create({\n value: \"ma'am\"\n })\n }),\n\n blam: \"shazam\"\n };\n\n view = Ember.View.create({\n context: context,\n template: Ember.Handlebars.compile('

{{#with content}}{{#with thankYou}}{{value}}-{{../wham}}-{{../../blam}}{{/with}}{{/with}}

')\n });\n\n appendView();\n\n equal(view.$('#first').text(), \"ma'am-bam-shazam\", \"renders grandparent properties\");\n});\n\ntest(\"Ember.View should update when a property changes and the bind helper is used\", function() {\n container.register('template:foo', Ember.Handlebars.compile('

{{#with view.content}}{{bind \"wham\"}}{{/with}}

'));\n\n view = Ember.View.create({\n container: container,\n templateName: 'foo',\n\n content: Ember.Object.create({\n wham: 'bam',\n thankYou: \"ma'am\"\n })\n });\n\n appendView();\n\n equal(view.$('#first').text(), \"bam\", \"precond - view renders Handlebars template\");\n\n Ember.run(function() { set(get(view, 'content'), 'wham', 'bazam'); });\n equal(view.$('#first').text(), \"bazam\", \"view updates when a bound property changes\");\n});\n\ntest(\"Ember.View should not use keyword incorrectly - Issue #1315\", function() {\n container.register('template:foo', Ember.Handlebars.compile('{{#each value in view.content}}{{value}}-{{#each option in view.options}}{{option.value}}:{{option.label}} {{/each}}{{/each}}'));\n\n view = Ember.View.create({\n container: container,\n templateName: 'foo',\n\n content: Ember.A(['X', 'Y']),\n options: Ember.A([\n { label: 'One', value: 1 },\n { label: 'Two', value: 2 }\n ])\n });\n\n appendView();\n\n equal(view.$().text(), 'X-1:One 2:Two Y-1:One 2:Two ');\n});\n\ntest(\"Ember.View should update when a property changes and no bind helper is used\", function() {\n container.register('template:foo', Ember.Handlebars.compile('

{{#with view.content}}{{wham}}{{/with}}

'));\n\n var templates = Ember.Object.create({\n foo: Ember.Handlebars.compile('

{{#with view.content}}{{wham}}{{/with}}

')\n });\n\n view = Ember.View.create({\n container: container,\n templateName: 'foo',\n\n content: Ember.Object.create({\n wham: 'bam',\n thankYou: \"ma'am\"\n })\n });\n\n appendView();\n\n equal(view.$('#first').text(), \"bam\", \"precond - view renders Handlebars template\");\n\n Ember.run(function() { set(get(view, 'content'), 'wham', 'bazam'); });\n\n equal(view.$('#first').text(), \"bazam\", \"view updates when a bound property changes\");\n});\n\ntest(\"Ember.View should update when the property used with the #with helper changes\", function() {\n container.register('template:foo', Ember.Handlebars.compile('

{{#with view.content}}{{wham}}{{/with}}

'));\n\n view = Ember.View.create({\n container: container,\n templateName: 'foo',\n\n content: Ember.Object.create({\n wham: 'bam',\n thankYou: \"ma'am\"\n })\n });\n\n appendView();\n\n equal(view.$('#first').text(), \"bam\", \"precond - view renders Handlebars template\");\n\n Ember.run(function() {\n set(view, 'content', Ember.Object.create({\n wham: 'bazam'\n }));\n });\n\n equal(view.$('#first').text(), \"bazam\", \"view updates when a bound property changes\");\n});\n\ntest(\"should not update when a property is removed from the view\", function() {\n container.register('template:foo', Ember.Handlebars.compile('

{{#bind \"view.content\"}}{{#bind \"foo\"}}{{bind \"baz\"}}{{/bind}}{{/bind}}

'));\n\n view = Ember.View.create({\n container: container,\n templateName: 'foo',\n\n content: Ember.Object.create({\n foo: Ember.Object.create({\n baz: \"unicorns\"\n })\n })\n });\n\n appendView();\n\n equal(view.$('#first').text(), \"unicorns\", \"precond - renders the bound value\");\n\n var oldContent = get(view, 'content');\n\n Ember.run(function() {\n set(view, 'content', Ember.Object.create({\n foo: Ember.Object.create({\n baz: \"ninjas\"\n })\n }));\n });\n\n equal(view.$('#first').text(), 'ninjas', \"updates to new content value\");\n\n Ember.run(function() {\n set(oldContent, 'foo.baz', 'rockstars');\n });\n\n Ember.run(function() {\n set(oldContent, 'foo.baz', 'ewoks');\n });\n\n equal(view.$('#first').text(), \"ninjas\", \"does not update removed object\");\n});\n\ntest(\"Handlebars templates update properties if a content object changes\", function() {\n container.register('template:menu', Ember.Handlebars.compile('

Today\\'s Menu

{{#bind \"view.coffee\"}}

{{color}} coffee

{{bind \"price\"}}{{/bind}}'));\n\n Ember.run(function() {\n view = Ember.View.create({\n container: container,\n templateName: 'menu',\n\n coffee: Ember.Object.create({\n color: 'brown',\n price: '$4'\n })\n });\n });\n\n appendView();\n\n equal(view.$('h2').text(), \"brown coffee\", \"precond - renders color correctly\");\n equal(view.$('#price').text(), '$4', \"precond - renders price correctly\");\n\n Ember.run(function() {\n set(view, 'coffee', Ember.Object.create({\n color: \"mauve\",\n price: \"$4.50\"\n }));\n });\n\n equal(view.$('h2').text(), \"mauve coffee\", \"should update name field when content changes\");\n equal(view.$('#price').text(), \"$4.50\", \"should update price field when content changes\");\n\n Ember.run(function() {\n set(view, 'coffee', Ember.Object.create({\n color: \"mauve\",\n price: \"$5.50\"\n }));\n });\n\n equal(view.$('h2').text(), \"mauve coffee\", \"should update name field when content changes\");\n equal(view.$('#price').text(), \"$5.50\", \"should update price field when content changes\");\n\n Ember.run(function() {\n set(view, 'coffee.price', \"$5\");\n });\n\n equal(view.$('#price').text(), \"$5\", \"should update price field when price property is changed\");\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\ntest(\"Template updates correctly if a path is passed to the bind helper\", function() {\n container.register('template:menu', Ember.Handlebars.compile('

{{bind \"view.coffee.price\"}}

'));\n\n view = Ember.View.create({\n container: container,\n templateName: 'menu',\n\n coffee: Ember.Object.create({\n price: '$4'\n })\n });\n\n appendView();\n\n equal(view.$('h1').text(), \"$4\", \"precond - renders price\");\n\n Ember.run(function() {\n set(view, 'coffee.price', \"$5\");\n });\n\n equal(view.$('h1').text(), \"$5\", \"updates when property changes\");\n\n Ember.run(function() {\n set(view, 'coffee', { price: \"$6\" });\n });\n\n equal(view.$('h1').text(), \"$6\", \"updates when parent property changes\");\n});\n\ntest(\"Template updates correctly if a path is passed to the bind helper and the context object is an Ember.ObjectController\", function() {\n container.register('template:menu', Ember.Handlebars.compile('

{{bind \"view.coffee.price\"}}

'));\n\n var controller = Ember.ObjectController.create();\n\n var realObject = Ember.Object.create({\n price: \"$4\"\n });\n\n set(controller, 'content', realObject);\n\n view = Ember.View.create({\n container: container,\n templateName: 'menu',\n\n coffee: controller\n });\n\n appendView();\n\n equal(view.$('h1').text(), \"$4\", \"precond - renders price\");\n\n Ember.run(function() {\n set(realObject, 'price', \"$5\");\n });\n\n equal(view.$('h1').text(), \"$5\", \"updates when property is set on real object\");\n\n Ember.run(function() {\n set(controller, 'price', \"$6\" );\n });\n\n equal(view.$('h1').text(), \"$6\", \"updates when property is set on object controller\");\n});\n\ntest(\"should update the block when object passed to #if helper changes\", function() {\n container.register('template:menu', Ember.Handlebars.compile('

{{#if view.inception}}{{view.INCEPTION}}{{/if}}

'));\n\n view = Ember.View.create({\n container: container,\n templateName: 'menu',\n\n INCEPTION: \"BOOOOOOOONG doodoodoodoodooodoodoodoo\",\n inception: 'OOOOoooooOOOOOOooooooo'\n });\n\n appendView();\n\n equal(view.$('h1').text(), \"BOOOOOOOONG doodoodoodoodooodoodoodoo\", \"renders block if a string\");\n\n var tests = [false, null, undefined, [], '', 0];\n\n forEach(tests, function(val) {\n Ember.run(function() {\n set(view, 'inception', val);\n });\n\n equal(view.$('h1').text(), '', Ember.String.fmt(\"hides block when conditional is '%@'\", [String(val)]));\n\n Ember.run(function() {\n set(view, 'inception', true);\n });\n\n equal(view.$('h1').text(), \"BOOOOOOOONG doodoodoodoodooodoodoodoo\", \"precond - renders block when conditional is true\");\n });\n});\n\ntest(\"should update the block when object passed to #unless helper changes\", function() {\n container.register('template:advice', Ember.Handlebars.compile('

{{#unless view.onDrugs}}{{view.doWellInSchool}}{{/unless}}

'));\n\n view = Ember.View.create({\n container: container,\n templateName: 'advice',\n\n onDrugs: true,\n doWellInSchool: \"Eat your vegetables\"\n });\n\n appendView();\n\n equal(view.$('h1').text(), \"\", \"hides block if true\");\n\n var tests = [false, null, undefined, [], '', 0];\n\n forEach(tests, function(val) {\n Ember.run(function() {\n set(view, 'onDrugs', val);\n });\n\n equal(view.$('h1').text(), 'Eat your vegetables', Ember.String.fmt(\"renders block when conditional is '%@'; %@\", [String(val), Ember.typeOf(val)]));\n\n Ember.run(function() {\n set(view, 'onDrugs', true);\n });\n\n equal(view.$('h1').text(), \"\", \"precond - hides block when conditional is true\");\n });\n});\n\ntest(\"should update the block when object passed to #if helper changes and an inverse is supplied\", function() {\n container.register('template:menu', Ember.Handlebars.compile('

{{#if view.inception}}{{view.INCEPTION}}{{else}}{{view.SAD}}{{/if}}

'));\n\n view = Ember.View.create({\n container: container,\n templateName: 'menu',\n\n INCEPTION: \"BOOOOOOOONG doodoodoodoodooodoodoodoo\",\n inception: false,\n SAD: 'BOONG?'\n });\n\n appendView();\n\n equal(view.$('h1').text(), \"BOONG?\", \"renders alternate if false\");\n\n Ember.run(function() { set(view, 'inception', true); });\n\n var tests = [false, null, undefined, [], '', 0];\n\n forEach(tests, function(val) {\n Ember.run(function() {\n set(view, 'inception', val);\n });\n\n equal(view.$('h1').text(), 'BOONG?', Ember.String.fmt(\"renders alternate if %@\", [String(val)]));\n\n Ember.run(function() {\n set(view, 'inception', true);\n });\n\n equal(view.$('h1').text(), \"BOOOOOOOONG doodoodoodoodooodoodoodoo\", \"precond - renders block when conditional is true\");\n });\n});\n\ntest(\"edge case: child conditional should not render children if parent conditional becomes false\", function() {\n var childCreated = false;\n\n view = Ember.View.create({\n cond1: true,\n cond2: false,\n viewClass: Ember.View.extend({\n init: function() {\n this._super();\n childCreated = true;\n }\n }),\n template: Ember.Handlebars.compile('{{#if view.cond1}}{{#if view.cond2}}{{#view view.viewClass}}test{{/view}}{{/if}}{{/if}}')\n });\n\n appendView();\n\n Ember.run(function() {\n // The order of these sets is important for the test\n view.set('cond2', true);\n view.set('cond1', false);\n });\n\n ok(!childCreated, 'child should not be created');\n});\n\ntest(\"Template views return throw if their template cannot be found\", function() {\n view = Ember.View.create({\n templateName: 'cantBeFound',\n container: { lookup: function() { }}\n });\n\n expectAssertion(function() {\n get(view, 'template');\n }, /cantBeFound/);\n});\n\ntest(\"Layout views return throw if their layout cannot be found\", function() {\n view = Ember.View.create({\n layoutName: 'cantBeFound'\n });\n\n expectAssertion(function() {\n get(view, 'layout');\n }, /cantBeFound/);\n});\n\ntest(\"Template views add an elementId to child views created using the view helper\", function() {\n container.register('template:parent', Ember.Handlebars.compile('
{{view \"TemplateTests.ChildView\"}}
'));\n container.register('template:child', Ember.Handlebars.compile(\"I can't believe it's not butter.\"));\n\n TemplateTests.ChildView = Ember.View.extend({\n container: container,\n templateName: 'child'\n });\n\n view = Ember.View.create({\n container: container,\n templateName: 'parent'\n });\n\n appendView();\n var childView = get(view, 'childViews.firstObject');\n equal(view.$().children().first().children().first().attr('id'), get(childView, 'elementId'));\n});\n\ntest(\"views set the template of their children to a passed block\", function() {\n container.register('template:parent', Ember.Handlebars.compile('

{{#view \"TemplateTests.NoTemplateView\"}}It worked!{{/view}}

'));\n\n TemplateTests.NoTemplateView = Ember.View.extend();\n\n view = Ember.View.create({\n container: container,\n templateName: 'parent'\n });\n\n appendView();\n ok(view.$('h1:has(span)').length === 1, \"renders the passed template inside the parent template\");\n});\n\ntest(\"views render their template in the context of the parent view's context\", function() {\n container.register('template:parent', Ember.Handlebars.compile('

{{#with content}}{{#view}}{{firstName}} {{lastName}}{{/view}}{{/with}}

'));\n\n var context = {\n content: {\n firstName: \"Lana\",\n lastName: \"del Heeeyyyyyy\"\n }\n };\n\n view = Ember.View.create({\n container: container,\n templateName: 'parent',\n context: context\n });\n\n appendView();\n equal(view.$('h1').text(), \"Lana del Heeeyyyyyy\", \"renders properties from parent context\");\n});\n\ntest(\"views make a view keyword available that allows template to reference view context\", function() {\n container.register('template:parent', Ember.Handlebars.compile('

{{#with view.content}}{{#view subview}}{{view.firstName}} {{lastName}}{{/view}}{{/with}}

'));\n\n view = Ember.View.create({\n container: container,\n templateName: 'parent',\n\n content: {\n subview: Ember.View.extend({\n firstName: \"Brodele\"\n }),\n firstName: \"Lana\",\n lastName: \"del Heeeyyyyyy\"\n }\n });\n\n appendView();\n equal(view.$('h1').text(), \"Brodele del Heeeyyyyyy\", \"renders properties from parent context\");\n});\n\ntest(\"a view helper's bindings are to the parent context\", function() {\n var Subview = Ember.View.extend({\n classNameBindings: ['color'],\n controller: Ember.Object.create({\n color: 'green',\n name: \"bar\"\n }),\n template: Ember.Handlebars.compile('{{view.someController.name}} {{name}}')\n });\n var View = Ember.View.extend({\n controller: Ember.Object.create({\n color: \"mauve\",\n name: 'foo'\n }),\n Subview: Subview,\n template: Ember.Handlebars.compile('

{{view view.Subview colorBinding=\"color\" someControllerBinding=\"this\"}}

')\n });\n view = View.create();\n appendView();\n equal(view.$('h1 .mauve').length, 1, \"renders property on helper declaration from parent context\");\n equal(view.$('h1 .mauve').text(), \"foo bar\", \"renders property bound in template from subview context\");\n});\n\ntest(\"should warn if setting a template on a view with a templateName already specified\", function() {\n view = Ember.View.create({\n childView: Ember.View.extend({\n templateName: 'foo'\n }),\n\n template: Ember.Handlebars.compile('{{#view childView}}test{{/view}}')\n });\n\n expectAssertion(function() {\n appendView();\n }, \"Unable to find view at path 'childView'\");\n\n Ember.run(function() {\n view.destroy();\n });\n\n view = Ember.View.create({\n childView: Ember.View.extend(),\n template: Ember.Handlebars.compile('{{#view childView templateName=\"foo\"}}test{{/view}}')\n });\n\n expectAssertion(function() {\n appendView();\n }, \"Unable to find view at path 'childView'\");\n});\n\ntest(\"Child views created using the view helper should have their parent view set properly\", function() {\n TemplateTests = {};\n\n var template = '{{#view \"Ember.View\"}}{{#view \"Ember.View\"}}{{view \"Ember.View\"}}{{/view}}{{/view}}';\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(template)\n });\n\n appendView();\n\n var childView = firstGrandchild(view);\n equal(childView, get(firstChild(childView), 'parentView'), 'parent view is correct');\n});\n\ntest(\"Child views created using the view helper should have their IDs registered for events\", function() {\n TemplateTests = {};\n\n var template = '{{view \"Ember.View\"}}{{view \"Ember.View\" id=\"templateViewTest\"}}';\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(template)\n });\n\n appendView();\n\n var childView = firstChild(view);\n var id = childView.$()[0].id;\n equal(Ember.View.views[id], childView, 'childView without passed ID is registered with Ember.View.views so that it can properly receive events from RootResponder');\n\n childView = nthChild(view, 1);\n id = childView.$()[0].id;\n equal(id, 'templateViewTest', 'precond -- id of childView should be set correctly');\n equal(Ember.View.views[id], childView, 'childView with passed ID is registered with Ember.View.views so that it can properly receive events from RootResponder');\n});\n\ntest(\"Child views created using the view helper and that have a viewName should be registered as properties on their parentView\", function() {\n TemplateTests = {};\n\n var template = '{{#view Ember.View}}{{view Ember.View viewName=\"ohai\"}}{{/view}}';\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(template)\n });\n\n appendView();\n\n var parentView = firstChild(view),\n childView = firstGrandchild(view);\n equal(get(parentView, 'ohai'), childView);\n});\n\ntest(\"Collection views that specify an example view class have their children be of that class\", function() {\n TemplateTests.ExampleViewCollection = Ember.CollectionView.extend({\n itemViewClass: Ember.View.extend({\n isCustom: true\n }),\n\n content: Ember.A(['foo'])\n });\n\n var parentView = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection \"TemplateTests.ExampleViewCollection\"}}OHAI{{/collection}}')\n });\n\n Ember.run(function() {\n parentView.append();\n });\n\n ok(firstGrandchild(parentView).isCustom, \"uses the example view class\");\n\n Ember.run(function() {\n parentView.destroy();\n });\n});\n\ntest(\"itemViewClass works in the #collection helper\", function() {\n TemplateTests.ExampleController = Ember.ArrayProxy.create({\n content: Ember.A(['alpha'])\n });\n\n TemplateTests.ExampleItemView = Ember.View.extend({\n isAlsoCustom: true\n });\n\n var parentView = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection contentBinding=\"TemplateTests.ExampleController\" itemViewClass=\"TemplateTests.ExampleItemView\"}}beta{{/collection}}')\n });\n\n Ember.run(function() {\n parentView.append();\n });\n\n ok(firstGrandchild(parentView).isAlsoCustom, \"uses the example view class specified in the #collection helper\");\n\n Ember.run(function() {\n parentView.destroy();\n });\n});\n\ntest(\"itemViewClass works in the #collection helper relatively\", function() {\n TemplateTests.ExampleController = Ember.ArrayProxy.create({\n content: Ember.A(['alpha'])\n });\n\n TemplateTests.ExampleItemView = Ember.View.extend({\n isAlsoCustom: true\n });\n\n TemplateTests.CollectionView = Ember.CollectionView.extend({\n possibleItemView: TemplateTests.ExampleItemView\n });\n\n var parentView = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection TemplateTests.CollectionView contentBinding=\"TemplateTests.ExampleController\" itemViewClass=\"possibleItemView\"}}beta{{/collection}}')\n });\n\n Ember.run(function() {\n parentView.append();\n });\n\n ok(firstGrandchild(parentView).isAlsoCustom, \"uses the example view class specified in the #collection helper\");\n\n Ember.run(function() {\n parentView.destroy();\n });\n});\n\ntest(\"should update boundIf blocks if the conditional changes\", function() {\n container.register('template:foo', Ember.Handlebars.compile('

{{#boundIf \"view.content.myApp.isEnabled\"}}{{view.content.wham}}{{/boundIf}}

'));\n\n view = Ember.View.create({\n container: container,\n templateName: 'foo',\n\n content: Ember.Object.create({\n wham: 'bam',\n thankYou: \"ma'am\",\n myApp: Ember.Object.create({\n isEnabled: true\n })\n })\n });\n\n appendView();\n\n equal(view.$('#first').text(), \"bam\", \"renders block when condition is true\");\n\n Ember.run(function() {\n set(get(view, 'content'), 'myApp.isEnabled', false);\n });\n\n equal(view.$('#first').text(), \"\", \"re-renders without block when condition is false\");\n\n Ember.run(function() {\n set(get(view, 'content'), 'myApp.isEnabled', true);\n });\n\n equal(view.$('#first').text(), \"bam\", \"re-renders block when condition changes to true\");\n});\n\ntest(\"should not update boundIf if truthiness does not change\", function() {\n var renderCount = 0;\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('

{{#boundIf \"view.shouldDisplay\"}}{{view view.InnerViewClass}}{{/boundIf}}

'),\n\n shouldDisplay: true,\n\n InnerViewClass: Ember.View.extend({\n template: Ember.Handlebars.compile(\"bam\"),\n\n render: function() {\n renderCount++;\n return this._super.apply(this, arguments);\n }\n })\n });\n\n appendView();\n\n equal(renderCount, 1, \"precond - should have rendered once\");\n equal(view.$('#first').text(), \"bam\", \"renders block when condition is true\");\n\n Ember.run(function() {\n set(view, 'shouldDisplay', 1);\n });\n\n equal(renderCount, 1, \"should not have rerendered\");\n equal(view.$('#first').text(), \"bam\", \"renders block when condition is true\");\n});\n\ntest(\"boundIf should support parent access\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\n '

{{#with view.content}}{{#with thankYou}}'+\n '{{#boundIf ../view.show}}parent{{/boundIf}}-{{#boundIf ../../view.show}}grandparent{{/boundIf}}'+\n '{{/with}}{{/with}}

'\n ),\n\n content: Ember.Object.create({\n show: true,\n thankYou: Ember.Object.create()\n }),\n\n show: true\n });\n\n appendView();\n\n equal(view.$('#first').text(), \"parent-grandparent\", \"renders boundIfs using ..\");\n});\n\ntest(\"{{view}} id attribute should set id on layer\", function() {\n container.register('template:foo', Ember.Handlebars.compile('{{#view \"TemplateTests.IdView\" id=\"bar\"}}baz{{/view}}'));\n\n TemplateTests.IdView = Ember.View;\n\n view = Ember.View.create({\n container: container,\n templateName: 'foo'\n });\n\n appendView();\n\n equal(view.$('#bar').length, 1, \"adds id attribute to layer\");\n equal(view.$('#bar').text(), 'baz', \"emits content\");\n});\n\ntest(\"{{view}} tag attribute should set tagName of the view\", function() {\n container.register('template:foo', Ember.Handlebars.compile('{{#view \"TemplateTests.TagView\" tag=\"span\"}}baz{{/view}}'));\n\n TemplateTests.TagView = Ember.View;\n\n view = Ember.View.create({\n container: container,\n templateName: 'foo'\n });\n\n appendView();\n\n equal(view.$('span').length, 1, \"renders with tag name\");\n equal(view.$('span').text(), 'baz', \"emits content\");\n});\n\ntest(\"{{view}} class attribute should set class on layer\", function() {\n container.register('template:foo', Ember.Handlebars.compile('{{#view \"TemplateTests.IdView\" class=\"bar\"}}baz{{/view}}'));\n\n TemplateTests.IdView = Ember.View;\n\n view = Ember.View.create({\n container: container,\n templateName: 'foo'\n });\n\n appendView();\n\n equal(view.$('.bar').length, 1, \"adds class attribute to layer\");\n equal(view.$('.bar').text(), 'baz', \"emits content\");\n});\n\ntest(\"{{view}} should not allow attributeBindings to be set\", function() {\n expectAssertion(function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{view \"Ember.View\" attributeBindings=\"one two\"}}')\n });\n appendView();\n }, /Setting 'attributeBindings' via Handlebars is not allowed/);\n});\n\ntest(\"{{view}} should be able to point to a local view\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{view view.common}}\"),\n\n common: Ember.View.extend({\n template: Ember.Handlebars.compile(\"common\")\n })\n });\n\n appendView();\n\n equal(view.$().text(), \"common\", \"tries to look up view name locally\");\n});\n\ntest(\"{{view}} should evaluate class bindings set to global paths\", function() {\n var App;\n\n Ember.run(function() {\n lookup.App = App = Ember.Application.create({\n isApp: true,\n isGreat: true,\n directClass: \"app-direct\",\n isEnabled: true\n });\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{view Ember.TextField class=\"unbound\" classBinding=\"App.isGreat:great App.directClass App.isApp App.isEnabled:enabled:disabled\"}}')\n });\n\n appendView();\n\n ok(view.$('input').hasClass('unbound'), \"sets unbound classes directly\");\n ok(view.$('input').hasClass('great'), \"evaluates classes bound to global paths\");\n ok(view.$('input').hasClass('app-direct'), \"evaluates classes bound directly to global paths\");\n ok(view.$('input').hasClass('is-app'), \"evaluates classes bound directly to booleans in global paths - dasherizes and sets class when true\");\n ok(view.$('input').hasClass('enabled'), \"evaluates ternary operator in classBindings\");\n ok(!view.$('input').hasClass('disabled'), \"evaluates ternary operator in classBindings\");\n\n Ember.run(function() {\n App.set('isApp', false);\n App.set('isEnabled', false);\n });\n\n ok(!view.$('input').hasClass('is-app'), \"evaluates classes bound directly to booleans in global paths - removes class when false\");\n ok(!view.$('input').hasClass('enabled'), \"evaluates ternary operator in classBindings\");\n ok(view.$('input').hasClass('disabled'), \"evaluates ternary operator in classBindings\");\n\n Ember.run(function() {\n lookup.App.destroy();\n });\n});\n\ntest(\"{{view}} should evaluate class bindings set in the current context\", function() {\n view = Ember.View.create({\n isView: true,\n isEditable: true,\n directClass: \"view-direct\",\n isEnabled: true,\n template: Ember.Handlebars.compile('{{view Ember.TextField class=\"unbound\" classBinding=\"view.isEditable:editable view.directClass view.isView view.isEnabled:enabled:disabled\"}}')\n });\n\n appendView();\n\n ok(view.$('input').hasClass('unbound'), \"sets unbound classes directly\");\n ok(view.$('input').hasClass('editable'), \"evaluates classes bound in the current context\");\n ok(view.$('input').hasClass('view-direct'), \"evaluates classes bound directly in the current context\");\n ok(view.$('input').hasClass('is-view'), \"evaluates classes bound directly to booleans in the current context - dasherizes and sets class when true\");\n ok(view.$('input').hasClass('enabled'), \"evaluates ternary operator in classBindings\");\n ok(!view.$('input').hasClass('disabled'), \"evaluates ternary operator in classBindings\");\n\n Ember.run(function() {\n view.set('isView', false);\n view.set('isEnabled', false);\n });\n\n ok(!view.$('input').hasClass('is-view'), \"evaluates classes bound directly to booleans in the current context - removes class when false\");\n ok(!view.$('input').hasClass('enabled'), \"evaluates ternary operator in classBindings\");\n ok(view.$('input').hasClass('disabled'), \"evaluates ternary operator in classBindings\");\n});\n\ntest(\"{{view}} should evaluate class bindings set with either classBinding or classNameBindings\", function() {\n var App;\n\n Ember.run(function() {\n lookup.App = App = Ember.Application.create({\n isGreat: true,\n isEnabled: true\n });\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{view Ember.TextField class=\"unbound\" classBinding=\"App.isGreat:great App.isEnabled:enabled:disabled\" classNameBindings=\"App.isGreat:really-great App.isEnabled:really-enabled:really-disabled\"}}')\n });\n\n appendView();\n\n ok(view.$('input').hasClass('unbound'), \"sets unbound classes directly\");\n ok(view.$('input').hasClass('great'), \"evaluates classBinding\");\n ok(view.$('input').hasClass('really-great'), \"evaluates classNameBinding\");\n ok(view.$('input').hasClass('enabled'), \"evaluates ternary operator in classBindings\");\n ok(view.$('input').hasClass('really-enabled'), \"evaluates ternary operator in classBindings\");\n ok(!view.$('input').hasClass('disabled'), \"evaluates ternary operator in classBindings\");\n ok(!view.$('input').hasClass('really-disabled'), \"evaluates ternary operator in classBindings\");\n\n Ember.run(function() {\n App.set('isEnabled', false);\n });\n\n ok(!view.$('input').hasClass('enabled'), \"evaluates ternary operator in classBindings\");\n ok(!view.$('input').hasClass('really-enabled'), \"evaluates ternary operator in classBindings\");\n ok(view.$('input').hasClass('disabled'), \"evaluates ternary operator in classBindings\");\n ok(view.$('input').hasClass('really-disabled'), \"evaluates ternary operator in classBindings\");\n\n Ember.run(function() {\n lookup.App.destroy();\n });\n});\n\ntest(\"{{view}} should evaluate other attribute bindings set to global paths\", function() {\n Ember.run(function() {\n lookup.App = Ember.Application.create({\n name: \"myApp\"\n });\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{view Ember.TextField valueBinding=\"App.name\"}}')\n });\n\n appendView();\n\n equal(view.$('input').attr('value'), \"myApp\", \"evaluates attributes bound to global paths\");\n\n Ember.run(function() {\n lookup.App.destroy();\n });\n});\n\ntest(\"{{view}} should evaluate other attributes bindings set in the current context\", function() {\n view = Ember.View.create({\n name: \"myView\",\n template: Ember.Handlebars.compile('{{view Ember.TextField valueBinding=\"view.name\"}}')\n });\n\n appendView();\n\n equal(view.$('input').attr('value'), \"myView\", \"evaluates attributes bound in the current context\");\n});\n\ntest(\"{{view}} should be able to bind class names to truthy properties\", function() {\n container.register('template:template', Ember.Handlebars.compile('{{#view \"TemplateTests.classBindingView\" classBinding=\"view.number:is-truthy\"}}foo{{/view}}'));\n\n TemplateTests.classBindingView = Ember.View.extend();\n\n view = Ember.View.create({\n container: container,\n number: 5,\n templateName: 'template'\n });\n\n appendView();\n\n equal(view.$('.is-truthy').length, 1, \"sets class name\");\n\n Ember.run(function() {\n set(view, 'number', 0);\n });\n\n equal(view.$('.is-truthy').length, 0, \"removes class name if bound property is set to falsey\");\n});\n\ntest(\"{{view}} should be able to bind class names to truthy or falsy properties\", function() {\n container.register('template:template', Ember.Handlebars.compile('{{#view \"TemplateTests.classBindingView\" classBinding=\"view.number:is-truthy:is-falsy\"}}foo{{/view}}'));\n\n TemplateTests.classBindingView = Ember.View.extend();\n\n view = Ember.View.create({\n container: container,\n number: 5,\n templateName: 'template'\n });\n\n appendView();\n\n equal(view.$('.is-truthy').length, 1, \"sets class name to truthy value\");\n equal(view.$('.is-falsy').length, 0, \"doesn't set class name to falsy value\");\n\n Ember.run(function() {\n set(view, 'number', 0);\n });\n\n equal(view.$('.is-truthy').length, 0, \"doesn't set class name to truthy value\");\n equal(view.$('.is-falsy').length, 1, \"sets class name to falsy value\");\n});\n\ntest(\"should be able to bind element attributes using {{bind-attr}}\", function() {\n var template = Ember.Handlebars.compile('\"view.content.title\"}}');\n\n view = Ember.View.create({\n template: template,\n content: Ember.Object.create({\n url: \"http://www.emberjs.com/assets/images/logo.png\",\n title: \"The SproutCore Logo\"\n })\n });\n\n appendView();\n\n equal(view.$('img').attr('src'), \"http://www.emberjs.com/assets/images/logo.png\", \"sets src attribute\");\n equal(view.$('img').attr('alt'), \"The SproutCore Logo\", \"sets alt attribute\");\n\n Ember.run(function() {\n set(view, 'content.title', \"El logo de Eember\");\n });\n\n equal(view.$('img').attr('alt'), \"El logo de Eember\", \"updates alt attribute when content's title attribute changes\");\n\n Ember.run(function() {\n set(view, 'content', Ember.Object.create({\n url: \"http://www.thegooglez.com/theydonnothing\",\n title: \"I CAN HAZ SEARCH\"\n }));\n });\n\n equal(view.$('img').attr('alt'), \"I CAN HAZ SEARCH\", \"updates alt attribute when content object changes\");\n\n Ember.run(function() {\n set(view, 'content', {\n url: \"http://www.emberjs.com/assets/images/logo.png\",\n title: \"The SproutCore Logo\"\n });\n });\n\n equal(view.$('img').attr('alt'), \"The SproutCore Logo\", \"updates alt attribute when content object is a hash\");\n\n Ember.run(function() {\n set(view, 'content', Ember.Object.createWithMixins({\n url: \"http://www.emberjs.com/assets/images/logo.png\",\n title: Ember.computed(function() {\n return \"Nanananana Ember!\";\n })\n }));\n });\n\n equal(view.$('img').attr('alt'), \"Nanananana Ember!\", \"updates alt attribute when title property is computed\");\n});\n\ntest(\"should be able to bind to view attributes with {{bind-attr}}\", function() {\n view = Ember.View.create({\n value: 'Test',\n template: Ember.Handlebars.compile('\"view.value\"}}')\n });\n\n appendView();\n\n equal(view.$('img').attr('alt'), \"Test\", \"renders initial value\");\n\n Ember.run(function() {\n view.set('value', 'Updated');\n });\n\n equal(view.$('img').attr('alt'), \"Updated\", \"updates value\");\n});\n\ntest(\"should be able to bind to globals with {{bind-attr}}\", function() {\n TemplateTests.set('value', 'Test');\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('\"TemplateTests.value\"}}')\n });\n\n appendView();\n\n equal(view.$('img').attr('alt'), \"Test\", \"renders initial value\");\n\n Ember.run(function() {\n TemplateTests.set('value', 'Updated');\n });\n\n equal(view.$('img').attr('alt'), \"Updated\", \"updates value\");\n});\n\ntest(\"should not allow XSS injection via {{bind-attr}}\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('\"view.content.value\"}}'),\n content: {\n value: 'Trololol\" onmouseover=\"alert(\\'HAX!\\');'\n }\n });\n\n appendView();\n\n equal(view.$('img').attr('onmouseover'), undefined);\n // If the whole string is here, then it means we got properly escaped\n equal(view.$('img').attr('alt'), 'Trololol\" onmouseover=\"alert(\\'HAX!\\');');\n});\n\ntest(\"should be able to bind use {{bind-attr}} more than once on an element\", function() {\n var template = Ember.Handlebars.compile('\"view.content.title\"}}');\n\n view = Ember.View.create({\n template: template,\n content: Ember.Object.create({\n url: \"http://www.emberjs.com/assets/images/logo.png\",\n title: \"The SproutCore Logo\"\n })\n });\n\n appendView();\n\n equal(view.$('img').attr('src'), \"http://www.emberjs.com/assets/images/logo.png\", \"sets src attribute\");\n equal(view.$('img').attr('alt'), \"The SproutCore Logo\", \"sets alt attribute\");\n\n Ember.run(function() {\n set(view, 'content.title', \"El logo de Eember\");\n });\n\n equal(view.$('img').attr('alt'), \"El logo de Eember\", \"updates alt attribute when content's title attribute changes\");\n\n Ember.run(function() {\n set(view, 'content', Ember.Object.create({\n url: \"http://www.thegooglez.com/theydonnothing\",\n title: \"I CAN HAZ SEARCH\"\n }));\n });\n\n equal(view.$('img').attr('alt'), \"I CAN HAZ SEARCH\", \"updates alt attribute when content object changes\");\n\n Ember.run(function() {\n set(view, 'content', {\n url: \"http://www.emberjs.com/assets/images/logo.png\",\n title: \"The SproutCore Logo\"\n });\n });\n\n equal(view.$('img').attr('alt'), \"The SproutCore Logo\", \"updates alt attribute when content object is a hash\");\n\n Ember.run(function() {\n set(view, 'content', Ember.Object.createWithMixins({\n url: \"http://www.emberjs.com/assets/images/logo.png\",\n title: Ember.computed(function() {\n return \"Nanananana Ember!\";\n })\n }));\n });\n\n equal(view.$('img').attr('alt'), \"Nanananana Ember!\", \"updates alt attribute when title property is computed\");\n\n});\n\ntest(\"{{bindAttr}} is aliased to {{bind-attr}}\", function() {\n equal(Ember.Handlebars.helpers.bindAttr, Ember.Handlebars.helpers['bind-attr']);\n});\n\ntest(\"should not reset cursor position when text field receives keyUp event\", function() {\n view = Ember.TextField.create({\n value: \"Broseidon, King of the Brocean\"\n });\n\n Ember.run(function() {\n view.append();\n });\n\n view.$().val('Brosiedoon, King of the Brocean');\n setCaretPosition(view.$(), 5);\n\n Ember.run(function() {\n view.trigger('keyUp', {});\n });\n\n equal(caretPosition(view.$()), 5, \"The keyUp event should not result in the cursor being reset due to the bind-attr observers\");\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\ntest(\"should be able to bind element attributes using {{bind-attr}} inside a block\", function() {\n var template = Ember.Handlebars.compile('{{#with view.content}}\"title\"}}{{/with}}');\n\n view = Ember.View.create({\n template: template,\n content: Ember.Object.create({\n url: \"http://www.emberjs.com/assets/images/logo.png\",\n title: \"The SproutCore Logo\"\n })\n });\n\n appendView();\n\n equal(view.$('img').attr('src'), \"http://www.emberjs.com/assets/images/logo.png\", \"sets src attribute\");\n equal(view.$('img').attr('alt'), \"The SproutCore Logo\", \"sets alt attribute\");\n\n Ember.run(function() {\n set(view, 'content.title', \"El logo de Eember\");\n });\n\n equal(view.$('img').attr('alt'), \"El logo de Eember\", \"updates alt attribute when content's title attribute changes\");\n});\n\ntest(\"should be able to bind class attribute with {{bind-attr}}\", function() {\n var template = Ember.Handlebars.compile('');\n\n view = Ember.View.create({\n template: template,\n foo: 'bar'\n });\n\n appendView();\n\n equal(view.$('img').attr('class'), 'bar', \"renders class\");\n\n Ember.run(function() {\n set(view, 'foo', 'baz');\n });\n\n equal(view.$('img').attr('class'), 'baz', \"updates class\");\n});\n\ntest(\"should be able to bind class attribute via a truthy property with {{bind-attr}}\", function() {\n var template = Ember.Handlebars.compile('');\n\n view = Ember.View.create({\n template: template,\n isNumber: 5\n });\n\n appendView();\n\n equal(view.$('.is-truthy').length, 1, \"sets class name\");\n\n Ember.run(function() {\n set(view, 'isNumber', 0);\n });\n\n equal(view.$('.is-truthy').length, 0, \"removes class name if bound property is set to something non-truthy\");\n});\n\ntest(\"should be able to bind class to view attribute with {{bind-attr}}\", function() {\n var template = Ember.Handlebars.compile('');\n\n view = Ember.View.create({\n template: template,\n foo: 'bar'\n });\n\n appendView();\n\n equal(view.$('img').attr('class'), 'bar', \"renders class\");\n\n Ember.run(function() {\n set(view, 'foo', 'baz');\n });\n\n equal(view.$('img').attr('class'), 'baz', \"updates class\");\n});\n\ntest(\"should not allow XSS injection via {{bind-attr}} with class\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile(''),\n foo: '\" onmouseover=\"alert(\\'I am in your classes hacking your app\\');'\n });\n\n appendView();\n\n equal(view.$('img').attr('onmouseover'), undefined);\n // If the whole string is here, then it means we got properly escaped\n equal(view.$('img').attr('class'), '\" onmouseover=\"alert(\\'I am in your classes hacking your app\\');');\n});\n\ntest(\"should be able to bind class attribute using ternary operator in {{bind-attr}}\", function() {\n var template = Ember.Handlebars.compile('');\n var content = Ember.Object.create({\n isDisabled: true\n });\n\n view = Ember.View.create({\n template: template,\n content: content\n });\n\n appendView();\n\n ok(view.$('img').hasClass('disabled'), 'disabled class is rendered');\n ok(!view.$('img').hasClass('enabled'), 'enabled class is not rendered');\n\n Ember.run(function() {\n set(content, 'isDisabled', false);\n });\n\n ok(!view.$('img').hasClass('disabled'), 'disabled class is not rendered');\n ok(view.$('img').hasClass('enabled'), 'enabled class is rendered');\n});\n\ntest(\"should be able to add multiple classes using {{bind-attr class}}\", function() {\n var template = Ember.Handlebars.compile('
');\n var content = Ember.Object.create({\n isAwesomeSauce: true,\n isAlsoCool: true,\n isAmazing: true,\n isEnabled: true\n });\n\n view = Ember.View.create({\n template: template,\n content: content\n });\n\n appendView();\n\n ok(view.$('div').hasClass('is-awesome-sauce'), \"dasherizes first property and sets classname\");\n ok(view.$('div').hasClass('is-also-cool'), \"dasherizes second property and sets classname\");\n ok(view.$('div').hasClass('amazing'), \"uses alias for third property and sets classname\");\n ok(view.$('div').hasClass('is-super-duper'), \"static class is present\");\n ok(view.$('div').hasClass('enabled'), \"truthy class in ternary classname definition is rendered\");\n ok(!view.$('div').hasClass('disabled'), \"falsy class in ternary classname definition is not rendered\");\n\n Ember.run(function() {\n set(content, 'isAwesomeSauce', false);\n set(content, 'isAmazing', false);\n set(content, 'isEnabled', false);\n });\n\n ok(!view.$('div').hasClass('is-awesome-sauce'), \"removes dasherized class when property is set to false\");\n ok(!view.$('div').hasClass('amazing'), \"removes aliased class when property is set to false\");\n ok(view.$('div').hasClass('is-super-duper'), \"static class is still present\");\n ok(!view.$('div').hasClass('enabled'), \"truthy class in ternary classname definition is not rendered\");\n ok(view.$('div').hasClass('disabled'), \"falsy class in ternary classname definition is rendered\");\n});\n\ntest(\"should be able to bind classes to globals with {{bind-attr class}}\", function() {\n TemplateTests.set('isOpen', true);\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('')\n });\n\n appendView();\n\n ok(view.$('img').hasClass('is-open'), \"sets classname to the dasherized value of the global property\");\n\n Ember.run(function() {\n TemplateTests.set('isOpen', false);\n });\n\n ok(!view.$('img').hasClass('is-open'), \"removes the classname when the global property has changed\");\n});\n\ntest(\"should be able to bind-attr to 'this' in an {{#each}} block\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#each view.images}}{{/each}}'),\n images: Ember.A(['one.png', 'two.jpg', 'three.gif'])\n });\n\n appendView();\n\n var images = view.$('img');\n ok(/one\\.png$/.test(images[0].src));\n ok(/two\\.jpg$/.test(images[1].src));\n ok(/three\\.gif$/.test(images[2].src));\n});\n\ntest(\"should be able to bind classes to 'this' in an {{#each}} block with {{bind-attr class}}\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#each view.items}}
  • Item
  • {{/each}}'),\n items: Ember.A(['a', 'b', 'c'])\n });\n\n appendView();\n\n ok(view.$('li').eq(0).hasClass('a'), \"sets classname to the value of the first item\");\n ok(view.$('li').eq(1).hasClass('b'), \"sets classname to the value of the second item\");\n ok(view.$('li').eq(2).hasClass('c'), \"sets classname to the value of the third item\");\n});\n\ntest(\"should be able to bind-attr to var in {{#each var in list}} block\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#each image in view.images}}{{/each}}'),\n images: Ember.A(['one.png', 'two.jpg', 'three.gif'])\n });\n\n appendView();\n\n var images = view.$('img');\n ok(/one\\.png$/.test(images[0].src));\n ok(/two\\.jpg$/.test(images[1].src));\n ok(/three\\.gif$/.test(images[2].src));\n\n Ember.run(function() {\n var imagesArray = view.get('images');\n imagesArray.removeAt(0);\n });\n\n images = view.$('img');\n ok(images.length === 2, \"\");\n ok(/two\\.jpg$/.test(images[0].src));\n ok(/three\\.gif$/.test(images[1].src));\n});\n\ntest(\"should be able to output a property without binding\", function() {\n var context = {\n content: Ember.Object.create({\n anUnboundString: \"No spans here, son.\"\n }),\n\n anotherUnboundString: \"Not here, either.\"\n };\n\n view = Ember.View.create({\n context: context,\n template: Ember.Handlebars.compile(\n '
    {{unbound content.anUnboundString}}
    '+\n '{{#with content}}
    {{unbound ../anotherUnboundString}}
    {{/with}}'\n )\n });\n\n appendView();\n\n equal(view.$('#first').html(), \"No spans here, son.\");\n equal(view.$('#second').html(), \"Not here, either.\");\n});\n\ntest(\"should allow standard Handlebars template usage\", function() {\n view = Ember.View.create({\n context: { name: \"Erik\" },\n template: Handlebars.compile(\"Hello, {{name}}\")\n });\n\n appendView();\n\n equal(view.$().text(), \"Hello, Erik\");\n});\n\ntest(\"should be able to use standard Handlebars #each helper\", function() {\n view = Ember.View.create({\n context: { items: ['a', 'b', 'c'] },\n template: Handlebars.compile(\"{{#each items}}{{this}}{{/each}}\")\n });\n\n appendView();\n\n equal(view.$().html(), \"abc\");\n});\n\ntest(\"should be able to use unbound helper in #each helper\", function() {\n view = Ember.View.create({\n items: Ember.A(['a', 'b', 'c', 1, 2, 3]),\n template: Ember.Handlebars.compile(\n \"
      {{#each view.items}}
    • {{unbound this}}
    • {{/each}}
    \")\n });\n\n appendView();\n\n equal(view.$().text(), \"abc123\");\n equal(view.$('li').children().length, 0, \"No markers\");\n});\n\ntest(\"should be able to use unbound helper in #each helper (with objects)\", function() {\n view = Ember.View.create({\n items: Ember.A([{wham: 'bam'}, {wham: 1}]),\n template: Ember.Handlebars.compile(\n \"
      {{#each view.items}}
    • {{unbound wham}}
    • {{/each}}
    \")\n });\n\n appendView();\n\n equal(view.$().text(), \"bam1\");\n equal(view.$('li').children().length, 0, \"No markers\");\n});\n\ntest(\"should work with precompiled templates\", function() {\n var templateString = Ember.Handlebars.precompile(\"{{view.value}}\"),\n compiledTemplate = Ember.Handlebars.template(eval(templateString));\n view = Ember.View.create({\n value: \"rendered\",\n template: compiledTemplate\n });\n\n appendView();\n\n equal(view.$().text(), \"rendered\", \"the precompiled template was rendered\");\n\n Ember.run(function() { view.set('value', 'updated'); });\n\n equal(view.$().text(), \"updated\", \"the precompiled template was updated\");\n});\n\ntest(\"should expose a controller keyword when present on the view\", function() {\n var templateString = \"{{controller.foo}}{{#view}}{{controller.baz}}{{/view}}\";\n view = Ember.View.create({\n controller: Ember.Object.create({\n foo: \"bar\",\n baz: \"bang\"\n }),\n\n template: Ember.Handlebars.compile(templateString)\n });\n\n appendView();\n\n equal(view.$().text(), \"barbang\", \"renders values from controller and parent controller\");\n\n var controller = get(view, 'controller');\n\n Ember.run(function() {\n controller.set('foo', \"BAR\");\n controller.set('baz', \"BLARGH\");\n });\n\n equal(view.$().text(), \"BARBLARGH\", \"updates the DOM when a bound value is updated\");\n\n Ember.run(function() {\n view.destroy();\n });\n\n view = Ember.View.create({\n controller: \"aString\",\n template: Ember.Handlebars.compile(\"{{controller}}\")\n });\n\n appendView();\n\n equal(view.$().text(), \"aString\", \"renders the controller itself if no additional path is specified\");\n});\n\ntest(\"should expose a controller keyword that can be used in conditionals\", function() {\n var templateString = \"{{#view}}{{#if controller}}{{controller.foo}}{{/if}}{{/view}}\";\n view = Ember.View.create({\n controller: Ember.Object.create({\n foo: \"bar\"\n }),\n\n template: Ember.Handlebars.compile(templateString)\n });\n\n appendView();\n\n equal(view.$().text(), \"bar\", \"renders values from controller and parent controller\");\n\n Ember.run(function() {\n view.set('controller', null);\n });\n\n equal(view.$().text(), \"\", \"updates the DOM when the controller is changed\");\n});\n\ntest(\"should expose a controller keyword that persists through Ember.ContainerView\", function() {\n var templateString = \"{{view Ember.ContainerView}}\";\n view = Ember.View.create({\n controller: Ember.Object.create({\n foo: \"bar\"\n }),\n\n template: Ember.Handlebars.compile(templateString)\n });\n\n appendView();\n\n var containerView = get(view, 'childViews.firstObject');\n var viewInstanceToBeInserted = Ember.View.create({\n template: Ember.Handlebars.compile('{{controller.foo}}')\n });\n\n Ember.run(function() {\n containerView.pushObject(viewInstanceToBeInserted);\n });\n\n equal(trim(viewInstanceToBeInserted.$().text()), \"bar\", \"renders value from parent's controller\");\n});\n\ntest(\"should expose a view keyword\", function() {\n var templateString = '{{#with view.differentContent}}{{view.foo}}{{#view baz=\"bang\"}}{{view.baz}}{{/view}}{{/with}}';\n view = Ember.View.create({\n differentContent: {\n view: {\n foo: \"WRONG\",\n baz: \"WRONG\"\n }\n },\n\n foo: \"bar\",\n\n template: Ember.Handlebars.compile(templateString)\n });\n\n appendView();\n\n equal(view.$().text(), \"barbang\", \"renders values from view and child view\");\n});\n\ntest(\"Ember.Button targets should respect keywords\", function() {\n Ember.TESTING_DEPRECATION = true;\n\n var templateString = '{{#with view.anObject}}{{view Ember.Button target=\"controller.foo\"}}{{/with}}';\n view = Ember.View.create({\n template: Ember.Handlebars.compile(templateString),\n anObject: {},\n controller: {\n foo: \"bar\"\n }\n });\n\n appendView();\n\n var button = view.get('childViews').objectAt(0);\n equal(button.get('targetObject'), \"bar\", \"resolves the target\");\n});\n\ntest(\"should be able to explicitly set a view's context\", function() {\n var context = Ember.Object.create({\n test: 'test'\n });\n\n TemplateTests.CustomContextView = Ember.View.extend({\n context: context,\n template: Ember.Handlebars.compile(\"{{test}}\")\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{view TemplateTests.CustomContextView}}\")\n });\n\n appendView();\n\n equal(view.$().text(), \"test\");\n});\n\ntest(\"should escape HTML in primitive value contexts when using normal mustaches\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#each view.kiddos}}{{this}}{{/each}}'),\n kiddos: Ember.A(['Max', 'James'])\n });\n\n appendView();\n equal(view.$('b').length, 0, \"does not create an element\");\n equal(view.$().text(), 'MaxJames', \"inserts entities, not elements\");\n\n Ember.run(function() { set(view, 'kiddos', Ember.A(['Max','James'])); });\n equal(view.$().text(), 'MaxJames', \"updates with entities, not elements\");\n equal(view.$('i').length, 0, \"does not create an element when value is updated\");\n});\n\ntest(\"should not escape HTML in primitive value contexts when using triple mustaches\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#each view.kiddos}}{{{this}}}{{/each}}'),\n kiddos: Ember.A(['Max', 'James'])\n });\n\n appendView();\n\n equal(view.$('b').length, 2, \"creates an element\");\n\n Ember.run(function() { set(view, 'kiddos', Ember.A(['Max','James'])); });\n equal(view.$('i').length, 2, \"creates an element when value is updated\");\n});\n\nmodule(\"Ember.View - handlebars integration\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n\n originalLog = Ember.Logger.log;\n logCalls = [];\n Ember.Logger.log = function(arg) { logCalls.push(arg); };\n },\n\n teardown: function() {\n if (view) {\n Ember.run(function() {\n view.destroy();\n });\n view = null;\n }\n\n Ember.Logger.log = originalLog;\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"should be able to log a property\", function() {\n var context = {\n value: 'one',\n valueTwo: 'two',\n\n content: Ember.Object.create({})\n };\n\n view = Ember.View.create({\n context: context,\n template: Ember.Handlebars.compile('{{log value}}{{#with content}}{{log ../valueTwo}}{{/with}}')\n });\n\n appendView();\n\n equal(view.$().text(), \"\", \"shouldn't render any text\");\n equal(logCalls[0], 'one', \"should call log with value\");\n equal(logCalls[1], 'two', \"should call log with valueTwo\");\n});\n\ntest(\"should be able to log a view property\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{log view.value}}'),\n value: 'one'\n });\n\n appendView();\n\n equal(view.$().text(), \"\", \"shouldn't render any text\");\n equal(logCalls[0], 'one', \"should call log with value\");\n});\n\ntest(\"should be able to log `this`\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#each view.items}}{{log this}}{{/each}}'),\n items: Ember.A(['one', 'two'])\n });\n\n appendView();\n\n equal(view.$().text(), \"\", \"shouldn't render any text\");\n equal(logCalls[0], 'one', \"should call log with item one\");\n equal(logCalls[1], 'two', \"should call log with item two\");\n});\n\nvar MyApp;\n\nmodule(\"Templates redrawing and bindings\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n MyApp = lookup.MyApp = Ember.Object.create({});\n },\n teardown: function() {\n Ember.run(function() {\n if (view) view.destroy();\n });\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"should be able to update when bound property updates\", function() {\n MyApp.set('controller', Ember.Object.create({name: 'first'}));\n\n var View = Ember.View.extend({\n template: Ember.Handlebars.compile('{{view.value.name}}, {{view.computed}}'),\n valueBinding: 'MyApp.controller',\n computed: Ember.computed(function() {\n return this.get('value.name') + ' - computed';\n }).property('value')\n });\n\n Ember.run(function() {\n view = View.create();\n });\n\n appendView();\n\n Ember.run(function() {\n MyApp.set('controller', Ember.Object.create({\n name: 'second'\n }));\n });\n\n equal(view.get('computed'), \"second - computed\", \"view computed properties correctly update\");\n equal(view.$('i').text(), 'second, second - computed', \"view rerenders when bound properties change\");\n});\n\ntest(\"properties within an if statement should not fail on re-render\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#if view.value}}{{view.value}}{{/if}}'),\n value: null\n });\n\n appendView();\n\n equal(view.$().text(), '');\n\n Ember.run(function() {\n view.set('value', 'test');\n });\n\n equal(view.$().text(), 'test');\n\n Ember.run(function() {\n view.set('value', null);\n });\n\n equal(view.$().text(), '');\n});\n\ntest('should cleanup bound properties on rerender', function() {\n view = Ember.View.create({\n controller: Ember.Object.create({name: 'wycats'}),\n template: Ember.Handlebars.compile('{{name}}')\n });\n\n appendView();\n\n equal(view.$().text(), 'wycats', 'rendered binding');\n\n Ember.run(view, 'rerender');\n\n equal(view._childViews.length, 1);\n});\n\ntest(\"views within an if statement should be sane on re-render\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#if view.display}}{{view Ember.TextField}}{{/if}}'),\n display: false\n });\n\n appendView();\n\n equal(view.$('input').length, 0);\n\n Ember.run(function() {\n // Setting twice will trigger the observer twice, this is intentional\n view.set('display', true);\n view.set('display', 'yes');\n });\n\n var textfield = view.$('input');\n equal(textfield.length, 1);\n\n // Make sure the view is still registered in Ember.View.views\n ok(Ember.View.views[textfield.attr('id')]);\n});\n\ntest(\"the {{this}} helper should not fail on removal\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#if view.show}}{{#each view.list}}{{this}}{{/each}}{{/if}}'),\n show: true,\n list: Ember.A(['a', 'b', 'c'])\n });\n\n appendView();\n\n equal(view.$().text(), 'abc', \"should start property - precond\");\n\n Ember.run(function() {\n view.set('show', false);\n });\n\n equal(view.$().text(), '');\n});\n\ntest(\"bindings should be relative to the current context\", function() {\n view = Ember.View.create({\n museumOpen: true,\n\n museumDetails: Ember.Object.create({\n name: \"SFMoMA\",\n price: 20\n }),\n\n museumView: Ember.View.extend({\n template: Ember.Handlebars.compile('Name: {{view.name}} Price: ${{view.dollars}}')\n }),\n\n template: Ember.Handlebars.compile('{{#if view.museumOpen}} {{view view.museumView nameBinding=\"view.museumDetails.name\" dollarsBinding=\"view.museumDetails.price\"}} {{/if}}')\n });\n\n appendView();\n\n equal(Ember.$.trim(view.$().text()), \"Name: SFMoMA Price: $20\", \"should print baz twice\");\n});\n\ntest(\"bindings should respect keywords\", function() {\n view = Ember.View.create({\n museumOpen: true,\n\n controller: {\n museumOpen: true,\n museumDetails: Ember.Object.create({\n name: \"SFMoMA\",\n price: 20\n })\n },\n\n museumView: Ember.View.extend({\n template: Ember.Handlebars.compile('Name: {{view.name}} Price: ${{view.dollars}}')\n }),\n\n template: Ember.Handlebars.compile('{{#if view.museumOpen}}{{view view.museumView nameBinding=\"controller.museumDetails.name\" dollarsBinding=\"controller.museumDetails.price\"}}{{/if}}')\n });\n\n appendView();\n\n equal(Ember.$.trim(view.$().text()), \"Name: SFMoMA Price: $20\", \"should print baz twice\");\n});\n\ntest(\"bindings can be 'this', in which case they *are* the current context\", function() {\n view = Ember.View.create({\n museumOpen: true,\n\n museumDetails: Ember.Object.create({\n name: \"SFMoMA\",\n price: 20,\n museumView: Ember.View.extend({\n template: Ember.Handlebars.compile('Name: {{view.museum.name}} Price: ${{view.museum.price}}')\n })\n }),\n\n\n template: Ember.Handlebars.compile('{{#if view.museumOpen}} {{#with view.museumDetails}}{{view museumView museumBinding=\"this\"}} {{/with}}{{/if}}')\n });\n\n appendView();\n\n equal(Ember.$.trim(view.$().text()), \"Name: SFMoMA Price: $20\", \"should print baz twice\");\n});\n\n// https://github.com/emberjs/ember.js/issues/120\n\ntest(\"should not enter an infinite loop when binding an attribute in Handlebars\", function() {\n var App;\n\n Ember.run(function() {\n lookup.App = App = Ember.Application.create();\n });\n\n App.test = Ember.Object.create({ href: 'test' });\n App.Link = Ember.View.extend({\n classNames: ['app-link'],\n tagName: 'a',\n attributeBindings: ['href'],\n href: '#none',\n\n click: function() {\n return false;\n }\n });\n\n var parentView = Ember.View.create({\n template: Ember.Handlebars.compile('{{#view App.Link hrefBinding=\"App.test.href\"}} Test {{/view}}')\n });\n\n\n Ember.run(function() {\n parentView.appendTo('#qunit-fixture');\n });\n\n // Use match, since old IE appends the whole URL\n var href = parentView.$('a').attr('href');\n ok(href.match(/(^|\\/)test$/), \"Expected href to be 'test' but got '\"+href+\"'\");\n\n Ember.run(function() {\n parentView.destroy();\n });\n\n Ember.run(function() {\n lookup.App.destroy();\n });\n});\n\ntest(\"should update bound values after the view is removed and then re-appended\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{#if view.showStuff}}{{view.boundValue}}{{else}}Not true.{{/if}}\"),\n showStuff: true,\n boundValue: \"foo\"\n });\n\n appendView();\n\n equal(Ember.$.trim(view.$().text()), \"foo\");\n Ember.run(function() {\n set(view, 'showStuff', false);\n });\n equal(Ember.$.trim(view.$().text()), \"Not true.\");\n\n Ember.run(function() {\n set(view, 'showStuff', true);\n });\n equal(Ember.$.trim(view.$().text()), \"foo\");\n\n Ember.run(function() {\n view.remove();\n set(view, 'showStuff', false);\n });\n Ember.run(function() {\n set(view, 'showStuff', true);\n });\n appendView();\n\n Ember.run(function() {\n set(view, 'boundValue', \"bar\");\n });\n equal(Ember.$.trim(view.$().text()), \"bar\");\n});\n\ntest(\"should update bound values after view's parent is removed and then re-appended\", function() {\n var controller = Ember.Object.create();\n\n var parentView = Ember.ContainerView.create({\n childViews: ['testView'],\n\n controller: controller,\n\n testView: Ember.View.create({\n template: Ember.Handlebars.compile(\"{{#if showStuff}}{{boundValue}}{{else}}Not true.{{/if}}\")\n })\n });\n\n controller.setProperties({\n showStuff: true,\n boundValue: \"foo\"\n });\n\n Ember.run(function() {\n parentView.appendTo('#qunit-fixture');\n });\n view = parentView.get('testView');\n\n equal(Ember.$.trim(view.$().text()), \"foo\");\n Ember.run(function() {\n set(controller, 'showStuff', false);\n });\n equal(Ember.$.trim(view.$().text()), \"Not true.\");\n\n Ember.run(function() {\n set(controller, 'showStuff', true);\n });\n equal(Ember.$.trim(view.$().text()), \"foo\");\n\n\n Ember.run(function() {\n parentView.remove();\n set(controller, 'showStuff', false);\n });\n Ember.run(function() {\n set(controller, 'showStuff', true);\n });\n Ember.run(function() {\n parentView.appendTo('#qunit-fixture');\n });\n\n Ember.run(function() {\n set(controller, 'boundValue', \"bar\");\n });\n equal(Ember.$.trim(view.$().text()), \"bar\");\n\n Ember.run(function() {\n parentView.destroy();\n });\n});\n\ntest(\"should call a registered helper for mustache without parameters\", function() {\n Ember.Handlebars.registerHelper('foobar', function() {\n return 'foobar';\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{foobar}}\")\n });\n\n appendView();\n\n ok(view.$().text() === 'foobar', \"Regular helper was invoked correctly\");\n});\n\ntest(\"should bind to the property if no registered helper found for a mustache without parameters\", function() {\n view = Ember.View.createWithMixins({\n template: Ember.Handlebars.compile(\"{{view.foobarProperty}}\"),\n foobarProperty: Ember.computed(function() {\n return 'foobarProperty';\n })\n });\n\n appendView();\n\n ok(view.$().text() === 'foobarProperty', \"Property was bound to correctly\");\n});\n\ntest(\"should accept bindings as a string or an Ember.Binding\", function() {\n var viewClass = Ember.View.extend({\n template: Ember.Handlebars.compile(\"binding: {{view.bindingTest}}, string: {{view.stringTest}}\")\n });\n\n Ember.Handlebars.registerHelper('boogie', function(id, options) {\n options.hash = options.hash || {};\n options.hash.bindingTestBinding = Ember.Binding.oneWay('context.' + id);\n options.hash.stringTestBinding = id;\n return Ember.Handlebars.ViewHelper.helper(this, viewClass, options);\n });\n\n view = Ember.View.create({\n context: Ember.Object.create({\n direction: 'down'\n }),\n template: Ember.Handlebars.compile(\"{{boogie direction}}\")\n });\n\n appendView();\n\n equal(Ember.$.trim(view.$().text()), \"binding: down, string: down\");\n});\n\ntest(\"should teardown observers from bound properties on rerender\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{view.foo}}\"),\n foo: 'bar'\n });\n\n appendView();\n\n equal(Ember.observersFor(view, 'foo').length, 1);\n\n Ember.run(function() {\n view.rerender();\n });\n\n equal(Ember.observersFor(view, 'foo').length, 1);\n});\n\ntest(\"should teardown observers from bind-attr on rerender\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('wat'),\n foo: 'bar'\n });\n\n appendView();\n\n equal(Ember.observersFor(view, 'foo').length, 2);\n\n Ember.run(function() {\n view.rerender();\n });\n\n equal(Ember.observersFor(view, 'foo').length, 2);\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/handlebars_test");minispade.register('ember-handlebars/~tests/helpers/bound_helper_test', "(function() {/*globals TemplateTests*/\n\nvar get = Ember.get, set = Ember.set;\n\nvar view;\n\nvar appendView = function() {\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n};\n\nvar registerRepeatHelper = function() {\n Ember.Handlebars.helper('repeat', function(value, options) {\n var count = options.hash.count;\n var a = [];\n while(a.length < count) {\n a.push(value);\n }\n return a.join('');\n });\n};\n\nmodule(\"Handlebars bound helpers\", {\n setup: function() {\n window.TemplateTests = Ember.Namespace.create();\n },\n teardown: function() {\n Ember.run(function() {\n if (view) {\n view.destroy();\n }\n });\n window.TemplateTests = undefined;\n }\n});\n\ntest(\"should update bound helpers when properties change\", function() {\n Ember.Handlebars.helper('capitalize', function(value) {\n return value.toUpperCase();\n });\n\n view = Ember.View.create({\n controller: Ember.Object.create({name: \"Brogrammer\"}),\n template: Ember.Handlebars.compile(\"{{capitalize name}}\")\n });\n\n appendView();\n\n equal(view.$().text(), 'BROGRAMMER', \"helper output is correct\");\n\n Ember.run(function() {\n set(view.controller, 'name', 'wes');\n });\n\n equal(view.$().text(), 'WES', \"helper output updated\");\n});\n\ntest(\"should allow for computed properties with dependencies\", function() {\n Ember.Handlebars.helper('capitalizeName', function(value) {\n return get(value, 'name').toUpperCase();\n }, 'name');\n\n view = Ember.View.create({\n controller: Ember.Object.create({\n person: Ember.Object.create({\n name: 'Brogrammer'\n })\n }),\n template: Ember.Handlebars.compile(\"{{capitalizeName person}}\")\n });\n\n appendView();\n\n equal(view.$().text(), 'BROGRAMMER', \"helper output is correct\");\n\n Ember.run(function() {\n set(view.controller.person, 'name', 'wes');\n });\n\n equal(view.$().text(), 'WES', \"helper output updated\");\n});\n\ntest(\"bound helpers should support options\", function() {\n\n registerRepeatHelper();\n\n view = Ember.View.create({\n controller: Ember.Object.create({text: 'ab'}),\n template: Ember.Handlebars.compile(\"{{repeat text count=3}}\")\n });\n\n appendView();\n\n ok(view.$().text() === 'ababab', \"helper output is correct\");\n});\n\ntest(\"bound helpers should support keywords\", function() {\n Ember.Handlebars.helper('capitalize', function(value) {\n return value.toUpperCase();\n });\n\n view = Ember.View.create({\n text: 'ab',\n template: Ember.Handlebars.compile(\"{{capitalize view.text}}\")\n });\n\n appendView();\n\n ok(view.$().text() === 'AB', \"helper output is correct\");\n});\n\ntest(\"bound helpers should support global paths\", function() {\n Ember.Handlebars.helper('capitalize', function(value) {\n return value.toUpperCase();\n });\n\n TemplateTests.text = 'ab';\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{capitalize TemplateTests.text}}\")\n });\n\n appendView();\n\n ok(view.$().text() === 'AB', \"helper output is correct\");\n});\n\ntest(\"bound helper should support this keyword\", function() {\n Ember.Handlebars.helper('capitalize', function(value) {\n return get(value, 'text').toUpperCase();\n });\n\n view = Ember.View.create({\n controller: Ember.Object.create({text: 'ab'}),\n template: Ember.Handlebars.compile(\"{{capitalize this}}\")\n });\n\n appendView();\n\n ok(view.$().text() === 'AB', \"helper output is correct\");\n});\n\ntest(\"bound helpers should support bound options\", function() {\n\n registerRepeatHelper();\n\n view = Ember.View.create({\n controller: Ember.Object.create({text: 'ab', numRepeats: 3}),\n template: Ember.Handlebars.compile('{{repeat text countBinding=\"numRepeats\"}}')\n });\n\n appendView();\n\n equal(view.$().text(), 'ababab', \"helper output is correct\");\n\n Ember.run(function() {\n view.set('controller.numRepeats', 4);\n });\n\n equal(view.$().text(), 'abababab', \"helper correctly re-rendered after bound option was changed\");\n\n Ember.run(function() {\n view.set('controller.numRepeats', 2);\n view.set('controller.text', \"YES\");\n });\n\n equal(view.$().text(), 'YESYES', \"helper correctly re-rendered after both bound option and property changed\");\n});\n\n\ntest(\"bound helpers should support multiple bound properties\", function() {\n\n Ember.Handlebars.helper('concat', function() {\n return [].slice.call(arguments, 0, -1).join('');\n });\n\n view = Ember.View.create({\n controller: Ember.Object.create({thing1: 'ZOID', thing2: 'BERG'}),\n template: Ember.Handlebars.compile('{{concat thing1 thing2}}')\n });\n\n appendView();\n\n equal(view.$().text(), 'ZOIDBERG', \"helper output is correct\");\n\n Ember.run(function() {\n view.set('controller.thing2', \"NERD\");\n });\n\n equal(view.$().text(), 'ZOIDNERD', \"helper correctly re-rendered after second bound helper property changed\");\n\n Ember.run(function() {\n view.controller.setProperties({\n thing1: \"WOOT\",\n thing2: \"YEAH\"\n });\n });\n\n equal(view.$().text(), 'WOOTYEAH', \"helper correctly re-rendered after both bound helper properties changed\");\n});\n\ntest(\"bound helpers should expose property names in options.data.properties\", function() {\n Ember.Handlebars.helper('echo', function() {\n var options = arguments[arguments.length - 1];\n var values = [].slice.call(arguments, 0, -1);\n var a = [];\n for(var i = 0; i < values.length; ++i) {\n var propertyName = options.data.properties[i];\n a.push(propertyName);\n }\n return a.join(' ');\n });\n\n view = Ember.View.create({\n controller: Ember.Object.create({\n thing1: 'ZOID',\n thing2: 'BERG',\n thing3: Ember.Object.create({\n foo: 123\n })\n }),\n template: Ember.Handlebars.compile('{{echo thing1 thing2 thing3.foo}}')\n });\n\n appendView();\n\n equal(view.$().text(), 'thing1 thing2 thing3.foo', \"helper output is correct\");\n});\n\ntest(\"bound helpers can be invoked with zero args\", function() {\n Ember.Handlebars.helper('troll', function(options) {\n return options.hash.text || \"TROLOLOL\";\n });\n\n view = Ember.View.create({\n controller: Ember.Object.create({trollText: \"yumad\"}),\n template: Ember.Handlebars.compile('{{troll}} and {{troll text=\"bork\"}}')\n });\n\n appendView();\n\n equal(view.$().text(), 'TROLOLOL and bork', \"helper output is correct\");\n});\n\ntest(\"bound helpers should not be invoked with blocks\", function() {\n registerRepeatHelper();\n view = Ember.View.create({\n controller: Ember.Object.create({}),\n template: Ember.Handlebars.compile(\"{{#repeat}}Sorry, Charlie{{/repeat}}\")\n });\n\n expectAssertion(function() {\n appendView();\n }, /registerBoundHelper-generated helpers do not support use with Handlebars blocks/i);\n});\n\ntest(\"should observe dependent keys passed to registerBoundHelper\", function() {\n try {\n expect(2);\n\n var SimplyObject = Ember.Object.create({\n firstName: 'Jim',\n lastName: 'Owen'\n });\n\n Ember.Handlebars.registerBoundHelper('fullName', function(value){\n return value.get('firstName') + ' ' + value.get('lastName');\n }, 'firstName', 'lastName');\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{fullName this}}'),\n context: SimplyObject\n });\n appendView(view);\n\n equal(view.$().text(), 'Jim Owen', 'simply render the helper');\n\n Ember.run(SimplyObject, SimplyObject.set, 'firstName', 'Tom');\n\n equal(view.$().text(), 'Tom Owen', 'simply render the helper');\n } finally {\n delete Ember.Handlebars.helpers['fullName'];\n }\n});\n\ntest(\"shouldn't treat raw numbers as bound paths\", function() {\n Ember.Handlebars.helper('sum', function(a, b) {\n return a + b;\n });\n\n view = Ember.View.create({\n controller: Ember.Object.create({aNumber: 1}),\n template: Ember.Handlebars.compile(\"{{sum aNumber 1}} {{sum 0 aNumber}} {{sum 5 6}}\")\n });\n\n appendView();\n\n equal(view.$().text(), '2 1 11', \"helper output is correct\");\n\n Ember.run(view.controller, 'set', 'aNumber', 5);\n\n equal(view.$().text(), '6 5 11', \"helper still updates as expected\");\n});\n\ntest(\"shouldn't treat quoted strings as bound paths\", function() {\n var helperCount = 0;\n Ember.Handlebars.helper('concat', function(a, b, opt) {\n helperCount++;\n return a + b;\n });\n\n view = Ember.View.create({\n controller: Ember.Object.create({word: \"jerkwater\", loo: \"unused\"}),\n template: Ember.Handlebars.compile(\"{{concat word 'loo'}} {{concat '' word}} {{concat 'will' \\\"didi\\\"}}\")\n });\n\n appendView();\n\n equal(view.$().text(), 'jerkwaterloo jerkwater willdidi', \"helper output is correct\");\n\n Ember.run(view.controller, 'set', 'word', 'bird');\n equal(view.$().text(), 'birdloo bird willdidi', \"helper still updates as expected\");\n\n Ember.run(view.controller, 'set', 'loo', 'soup-de-doo');\n equal(view.$().text(), 'birdloo bird willdidi', \"helper still updates as expected\");\n equal(helperCount, 5, \"changing controller property with same name as quoted string doesn't re-render helper\");\n});\n\ntest(\"bound helpers can handle nulls in array (with primitives)\", function() {\n Ember.Handlebars.helper('reverse', function(val) {\n return val ? val.split('').reverse().join('') : \"NOPE\";\n });\n\n view = Ember.View.create({\n controller: Ember.Object.create({\n things: Ember.A([ null, 0, undefined, false, \"OMG\" ])\n }),\n template: Ember.Handlebars.compile(\"{{#each things}}{{this}}|{{reverse this}} {{/each}}{{#each thing in things}}{{thing}}|{{reverse thing}} {{/each}}\")\n });\n\n appendView();\n\n equal(view.$().text(), '|NOPE 0|NOPE |NOPE false|NOPE OMG|GMO |NOPE 0|NOPE |NOPE false|NOPE OMG|GMO ', \"helper output is correct\");\n\n Ember.run(function() {\n view.controller.things.pushObject('blorg');\n view.controller.things.shiftObject();\n });\n\n 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\");\n});\n\ntest(\"bound helpers can handle nulls in array (with objects)\", function() {\n Ember.Handlebars.helper('print-foo', function(val) {\n return val ? Ember.get(val, 'foo') : \"NOPE\";\n });\n\n view = Ember.View.create({\n controller: Ember.Object.create({\n things: Ember.A([ null, { foo: 5 } ])\n }),\n template: Ember.Handlebars.compile(\"{{#each things}}{{foo}}|{{print-foo this}} {{/each}}{{#each thing in things}}{{thing.foo}}|{{print-foo thing}} {{/each}}\")\n });\n\n appendView();\n\n equal(view.$().text(), '|NOPE 5|5 |NOPE 5|5 ', \"helper output is correct\");\n\n Ember.run(view.controller.things, 'pushObject', { foo: 6 });\n\n equal(view.$().text(), '|NOPE 5|5 6|6 |NOPE 5|5 6|6 ', \"helper output is correct\");\n});\n\ntest(\"bound helpers can handle `this` keyword when it's a non-object\", function() {\n\n Ember.Handlebars.helper(\"shout\", function(value) {\n return value + '!';\n });\n\n view = Ember.View.create({\n controller: Ember.Object.create({\n things: Ember.A(['alex'])\n }),\n template: Ember.Handlebars.compile(\"{{#each things}}{{shout this}}{{/each}}\")\n });\n\n appendView();\n\n equal(view.$().text(), 'alex!', \"helper output is correct\");\n\n Ember.run(view.controller.things, 'shiftObject');\n equal(view.$().text(), '', \"helper output is correct\");\n\n Ember.run(view.controller.things, 'pushObject', 'wallace');\n equal(view.$().text(), 'wallace!', \"helper output is correct\");\n});\n\n\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/bound_helper_test");minispade.register('ember-handlebars/~tests/helpers/custom_view_helper_test', "(function() {/*globals TemplateTests*/\n\nvar view;\n\nvar appendView = function() {\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n};\n\nmodule(\"Handlebars custom view helpers\", {\n setup: function() {\n window.TemplateTests = Ember.Namespace.create();\n },\n teardown: function() {\n Ember.run(function() {\n if (view) {\n view.destroy();\n }\n });\n window.TemplateTests = undefined;\n }\n});\n\ntest(\"should render an instance of the specified view\", function() {\n TemplateTests.OceanView = Ember.View.extend({\n template: Ember.Handlebars.compile('zomg, nice view')\n });\n\n Ember.Handlebars.helper('oceanView', TemplateTests.OceanView);\n\n view = Ember.View.create({\n controller: Ember.Object.create(),\n template: Ember.Handlebars.compile('{{oceanView tagName=\"strong\"}}')\n });\n\n appendView();\n\n var oceanViews = view.$().find(\"strong:contains('zomg, nice view')\");\n\n equal(oceanViews.length, 1, \"helper rendered an instance of the view\");\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/custom_view_helper_test");minispade.register('ember-handlebars/~tests/helpers/each_test', "(function() {var get = Ember.get, set = Ember.set;\nvar people, view;\nvar template, templateMyView;\nvar templateFor = function(template) {\n return Ember.Handlebars.compile(template);\n};\n\nvar originalLookup = Ember.lookup, lookup;\n\nmodule(\"the #each helper\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n\n template = templateFor(\"{{#each view.people}}{{name}}{{/each}}\");\n people = Ember.A([{ name: \"Steve Holt\" }, { name: \"Annabelle\" }]);\n\n view = Ember.View.create({\n template: template,\n people: people\n });\n\n\n templateMyView = templateFor(\"{{name}}\");\n lookup.MyView = Ember.View.extend({\n template: templateMyView\n });\n\n append(view);\n },\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n view = null;\n });\n Ember.lookup = originalLookup;\n Ember.TESTING_DEPRECATION = false;\n }\n});\n\n\nvar append = function(view) {\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n};\n\nvar assertHTML = function(view, expectedHTML) {\n var html = view.$().html();\n\n // IE 8 (and prior?) adds the \\r\\n\n html = html.replace(/]*><\\/script>/ig, '').replace(/[\\r\\n]/g, '');\n\n equal(html, expectedHTML);\n};\n\nvar assertText = function(view, expectedText) {\n equal(view.$().text(), expectedText);\n};\n\ntest(\"it renders the template for each item in an array\", function() {\n assertHTML(view, \"Steve HoltAnnabelle\");\n});\n\ntest(\"it updates the view if an item is added\", function() {\n Ember.run(function() {\n people.pushObject({ name: \"Tom Dale\" });\n });\n\n assertHTML(view, \"Steve HoltAnnabelleTom Dale\");\n});\n\ntest(\"it allows you to access the current context using {{this}}\", function() {\n Ember.run(function() { view.destroy(); }); // destroy existing view\n view = Ember.View.create({\n template: templateFor(\"{{#each view.people}}{{this}}{{/each}}\"),\n people: Ember.A(['Black Francis', 'Joey Santiago', 'Kim Deal', 'David Lovering'])\n });\n\n append(view);\n\n assertHTML(view, \"Black FrancisJoey SantiagoKim DealDavid Lovering\");\n});\n\ntest(\"it updates the view if an item is removed\", function() {\n Ember.run(function() {\n people.removeAt(0);\n });\n\n assertHTML(view, \"Annabelle\");\n});\n\ntest(\"it updates the view if an item is replaced\", function() {\n Ember.run(function() {\n people.removeAt(0);\n people.insertAt(0, { name: \"Kazuki\" });\n });\n\n assertHTML(view, \"KazukiAnnabelle\");\n});\n\ntest(\"can add and replace in the same runloop\", function() {\n Ember.run(function() {\n people.pushObject({ name: \"Tom Dale\" });\n people.removeAt(0);\n people.insertAt(0, { name: \"Kazuki\" });\n });\n\n assertHTML(view, \"KazukiAnnabelleTom Dale\");\n});\n\ntest(\"can add and replace the object before the add in the same runloop\", function() {\n Ember.run(function() {\n people.pushObject({ name: \"Tom Dale\" });\n people.removeAt(1);\n people.insertAt(1, { name: \"Kazuki\" });\n });\n\n assertHTML(view, \"Steve HoltKazukiTom Dale\");\n});\n\ntest(\"can add and replace complicatedly\", function() {\n Ember.run(function() {\n people.pushObject({ name: \"Tom Dale\" });\n people.removeAt(1);\n people.insertAt(1, { name: \"Kazuki\" });\n people.pushObject({ name: \"Firestone\" });\n people.pushObject({ name: \"McMunch\" });\n people.removeAt(3);\n });\n\n assertHTML(view, \"Steve HoltKazukiTom DaleMcMunch\");\n});\n\ntest(\"can add and replace complicatedly harder\", function() {\n Ember.run(function() {\n people.pushObject({ name: \"Tom Dale\" });\n people.removeAt(1);\n people.insertAt(1, { name: \"Kazuki\" });\n people.pushObject({ name: \"Firestone\" });\n people.pushObject({ name: \"McMunch\" });\n people.removeAt(2);\n });\n\n assertHTML(view, \"Steve HoltKazukiFirestoneMcMunch\");\n});\n\ntest(\"it works inside a ul element\", function() {\n var ulView = Ember.View.create({\n template: templateFor('
      {{#each view.people}}
    • {{name}}
    • {{/each}}
    '),\n people: people\n });\n\n append(ulView);\n\n equal(ulView.$('li').length, 2, \"renders two
  • elements\");\n\n Ember.run(function() {\n people.pushObject({name: \"Black Francis\"});\n });\n\n equal(ulView.$('li').length, 3, \"renders an additional
  • element when an object is added\");\n\n Ember.run(function() {\n ulView.destroy();\n });\n});\n\ntest(\"it works inside a table element\", function() {\n var tableView = Ember.View.create({\n template: templateFor('{{#each view.people}}{{/each}}
    {{name}}
    '),\n people: people\n });\n\n append(tableView);\n\n equal(tableView.$('td').length, 2, \"renders two elements\");\n\n Ember.run(function() {\n people.pushObject({name: \"Black Francis\"});\n });\n\n equal(tableView.$('td').length, 3, \"renders an additional element when an object is added\");\n\n Ember.run(function() {\n people.insertAt(0, {name: \"Kim Deal\"});\n });\n\n equal(tableView.$('td').length, 4, \"renders an additional when an object is inserted at the beginning of the array\");\n\n Ember.run(function() {\n tableView.destroy();\n });\n});\n\ntest(\"it supports itemController\", function() {\n var Controller = Ember.Controller.extend({\n controllerName: Ember.computed(function() {\n return \"controller:\"+this.get('content.name');\n })\n });\n\n var container = new Ember.Container();\n\n Ember.run(function() { view.destroy(); }); // destroy existing view\n\n var parentController = {\n container: container\n };\n\n container.register('controller:array', Ember.ArrayController.extend());\n\n view = Ember.View.create({\n container: container,\n template: templateFor('{{#each view.people itemController=\"person\"}}{{controllerName}}{{/each}}'),\n people: people,\n controller: parentController\n });\n\n container.register('controller:person', Controller);\n\n append(view);\n\n equal(view.$().text(), \"controller:Steve Holtcontroller:Annabelle\");\n\n Ember.run(function() {\n view.rerender();\n });\n\n assertText(view, \"controller:Steve Holtcontroller:Annabelle\");\n\n Ember.run(function() {\n people.pushObject({ name: \"Yehuda Katz\" });\n });\n\n assertText(view, \"controller:Steve Holtcontroller:Annabellecontroller:Yehuda Katz\");\n\n Ember.run(function() {\n set(view, 'people', Ember.A([{ name: \"Trek Glowacki\" }, { name: \"Geoffrey Grosenbach\" }]));\n });\n\n assertText(view, \"controller:Trek Glowackicontroller:Geoffrey Grosenbach\");\n\n var controller = view.get('_childViews')[0].get('controller');\n strictEqual(view.get('_childViews')[0].get('_arrayController.target'), parentController, \"the target property of the child controllers are set correctly\");\n});\n\ntest(\"itemController gets a parentController property\", function() {\n // using an ObjectController for this test to verify that parentController does accidentally get set\n // on the proxied model.\n var Controller = Ember.ObjectController.extend({\n controllerName: Ember.computed(function() {\n return \"controller:\"+this.get('content.name') + ' of ' + this.get('parentController.company');\n })\n }),\n container = new Ember.Container(),\n parentController = {\n container: container,\n company: 'Yapp'\n };\n\n container.register('controller:array', Ember.ArrayController.extend());\n Ember.run(function() { view.destroy(); }); // destroy existing view\n\n view = Ember.View.create({\n container: container,\n template: templateFor('{{#each view.people itemController=\"person\"}}{{controllerName}}{{/each}}'),\n people: people,\n controller: parentController\n });\n\n container.register('controller:person', Controller);\n\n append(view);\n\n equal(view.$().text(), \"controller:Steve Holt of Yappcontroller:Annabelle of Yapp\");\n});\n\ntest(\"it supports itemController when using a custom keyword\", function() {\n var Controller = Ember.Controller.extend({\n controllerName: Ember.computed(function() {\n return \"controller:\"+this.get('content.name');\n })\n });\n\n var container = new Ember.Container();\n container.register('controller:array', Ember.ArrayController.extend());\n\n Ember.run(function() { view.destroy(); }); // destroy existing view\n view = Ember.View.create({\n container: container,\n template: templateFor('{{#each person in view.people itemController=\"person\"}}{{person.controllerName}}{{/each}}'),\n people: people,\n controller: {\n container: container\n }\n });\n\n container.register('controller:person', Controller);\n\n append(view);\n\n equal(view.$().text(), \"controller:Steve Holtcontroller:Annabelle\");\n\n Ember.run(function() {\n view.rerender();\n });\n\n equal(view.$().text(), \"controller:Steve Holtcontroller:Annabelle\");\n});\n\ntest(\"it supports {{itemView=}}\", function() {\n var container = new Ember.Container();\n\n var itemView = Ember.View.extend({\n template: templateFor('itemView:{{name}}')\n });\n\n Ember.run(function() { view.destroy(); }); // destroy existing view\n view = Ember.View.create({\n template: templateFor('{{each view.people itemView=\"anItemView\"}}'),\n people: people,\n controller: {\n container: container\n }\n });\n\n container.register('view:anItemView', itemView);\n\n append(view);\n\n assertText(view, \"itemView:Steve HoltitemView:Annabelle\");\n});\n\n\ntest(\"it defers all normalization of itemView names to the resolver\", function() {\n var container = new Ember.Container();\n\n var itemView = Ember.View.extend({\n template: templateFor('itemView:{{name}}')\n });\n\n Ember.run(function() { view.destroy(); }); // destroy existing view\n view = Ember.View.create({\n template: templateFor('{{each view.people itemView=\"an-item-view\"}}'),\n people: people,\n controller: {\n container: container\n }\n });\n\n container.register('view:an-item-view', itemView);\n container.resolve = function(fullname) {\n equal(fullname, \"view:an-item-view\", \"leaves fullname untouched\");\n return Ember.Container.prototype.resolve.call(this, fullname);\n };\n append(view);\n\n});\n\ntest(\"it supports {{itemViewClass=}}\", function() {\n Ember.run(function() { view.destroy(); }); // destroy existing view\n view = Ember.View.create({\n template: templateFor('{{each view.people itemViewClass=\"MyView\"}}'),\n people: people\n });\n\n append(view);\n\n assertText(view, \"Steve HoltAnnabelle\");\n});\n\ntest(\"it supports {{itemViewClass=}} with tagName\", function() {\n Ember.TESTING_DEPRECATION = true;\n\n Ember.run(function() { view.destroy(); }); // destroy existing view\n view = Ember.View.create({\n template: templateFor('{{each view.people itemViewClass=\"MyView\" tagName=\"ul\"}}'),\n people: people\n });\n\n append(view);\n\n var html = view.$().html();\n\n // IE 8 (and prior?) adds the \\r\\n\n html = html.replace(/]*><\\/script>/ig, '').replace(/[\\r\\n]/g, '');\n html = html.replace(/]*><\\/div>/ig, '').replace(/[\\r\\n]/g, '');\n html = html.replace(/]*/ig, '
  • steve holt
  • annabelle
  • \");\n});\n\ntest(\"it supports {{itemViewClass=}} with in format\", function() {\n\n lookup.MyView = Ember.View.extend({\n template: templateFor(\"{{person.name}}\")\n });\n\n Ember.run(function() { view.destroy(); }); // destroy existing view\n view = Ember.View.create({\n template: templateFor('{{each person in view.people itemViewClass=\"MyView\"}}'),\n people: people\n });\n\n append(view);\n\n assertText(view, \"Steve HoltAnnabelle\");\n\n});\n\ntest(\"it supports {{else}}\", function() {\n Ember.run(function() { view.destroy(); }); // destroy existing view\n view = Ember.View.create({\n template: templateFor(\"{{#each view.items}}{{this}}{{else}}Nothing{{/each}}\"),\n items: Ember.A(['one', 'two'])\n });\n\n append(view);\n\n assertHTML(view, \"onetwo\");\n\n Ember.run(function() {\n view.set('items', Ember.A());\n });\n\n assertHTML(view, \"Nothing\");\n});\n\ntest(\"it works with the controller keyword\", function() {\n var controller = Ember.ArrayController.create({\n content: Ember.A([\"foo\", \"bar\", \"baz\"])\n });\n\n Ember.run(function() { view.destroy(); }); // destroy existing view\n view = Ember.View.create({\n controller: controller,\n template: templateFor(\"{{#view}}{{#each controller}}{{this}}{{/each}}{{/view}}\")\n });\n\n append(view);\n\n equal(view.$().text(), \"foobarbaz\");\n});\n\nmodule(\"{{#each foo in bar}}\", {\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n }\n});\n\ntest(\"#each accepts a name binding\", function() {\n view = Ember.View.create({\n template: templateFor(\"{{#each item in view.items}}{{view.title}} {{item}}{{/each}}\"),\n title: \"My Cool Each Test\",\n items: Ember.A([1, 2])\n });\n\n append(view);\n\n equal(view.$().text(), \"My Cool Each Test 1My Cool Each Test 2\");\n});\n\ntest(\"#each accepts a name binding and does not change the context\", function() {\n var controller = Ember.Controller.create({\n name: 'bob the controller'\n }),\n obj = Ember.Object.create({\n name: 'henry the item'\n });\n\n view = Ember.View.create({\n template: templateFor(\"{{#each item in view.items}}{{name}}{{/each}}\"),\n title: \"My Cool Each Test\",\n items: Ember.A([obj]),\n controller: controller\n });\n\n append(view);\n\n equal(view.$().text(), \"bob the controller\");\n});\n\n\ntest(\"#each accepts a name binding and can display child properties\", function() {\n view = Ember.View.create({\n template: templateFor(\"{{#each item in view.items}}{{view.title}} {{item.name}}{{/each}}\"),\n title: \"My Cool Each Test\",\n items: Ember.A([{ name: 1 }, { name: 2 }])\n });\n\n append(view);\n\n equal(view.$().text(), \"My Cool Each Test 1My Cool Each Test 2\");\n});\n\ntest(\"#each accepts 'this' as the right hand side\", function() {\n view = Ember.View.create({\n template: templateFor(\"{{#each item in this}}{{view.title}} {{item.name}}{{/each}}\"),\n title: \"My Cool Each Test\",\n controller: Ember.A([{ name: 1 }, { name: 2 }])\n });\n\n append(view);\n\n equal(view.$().text(), \"My Cool Each Test 1My Cool Each Test 2\");\n});\n\ntest(\"views inside #each preserve the new context\", function() {\n var controller = Ember.A([ { name: \"Adam\" }, { name: \"Steve\" } ]);\n\n view = Ember.View.create({\n controller: controller,\n template: templateFor('{{#each controller}}{{#view}}{{name}}{{/view}}{{/each}}')\n });\n\n append(view);\n\n equal(view.$().text(), \"AdamSteve\");\n});\n\ntest(\"controller is assignable inside an #each\", function() {\n var controller = Ember.ArrayController.create({\n content: Ember.A([ { name: \"Adam\" }, { name: \"Steve\" } ])\n });\n\n view = Ember.View.create({\n controller: controller,\n template: templateFor('{{#each personController in this}}{{#view controllerBinding=\"personController\"}}{{name}}{{/view}}{{/each}}')\n });\n\n append(view);\n\n equal(view.$().text(), \"AdamSteve\");\n});\n\ntest(\"single-arg each defaults to current context\", function() {\n view = Ember.View.create({\n context: Ember.A([ { name: \"Adam\" }, { name: \"Steve\" } ]),\n template: templateFor('{{#each}}{{name}}{{/each}}')\n });\n\n append(view);\n\n equal(view.$().text(), \"AdamSteve\");\n});\n\ntest(\"single-arg each will iterate over controller if present\", function() {\n view = Ember.View.create({\n controller: Ember.A([ { name: \"Adam\" }, { name: \"Steve\" } ]),\n template: templateFor('{{#each}}{{name}}{{/each}}')\n });\n\n append(view);\n\n equal(view.$().text(), \"AdamSteve\");\n});\n\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/each_test");minispade.register('ember-handlebars/~tests/helpers/group_test', "(function() {var trim = Ember.$.trim;\n\nvar view;\n\nmodule(\"Ember.Handlebars - group flag\", {\n setup: function() {},\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n Ember.run.cancelTimers();\n }\n});\n\nfunction createGroupedView(template, context) {\n var options = {\n context: context,\n template: Ember.Handlebars.compile(template),\n templateData: {insideGroup: true, keywords: {}}\n };\n Ember.run(function() {\n view = Ember.View.create(options);\n });\n}\n\nfunction appendView() {\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n}\n\ntest(\"should properly modify behavior inside the block\", function() {\n createGroupedView(\"{{msg}}\", {msg: 'ohai'});\n appendView();\n\n equal(view.$('script').length, 0, \"No Metamorph markers are output\");\n equal(view.$().text(), 'ohai', 'Original value was rendered');\n\n Ember.run(function() {\n view.set('context.msg', 'ohbai');\n });\n equal(view.$().text(), 'ohbai', 'Updated value was rendered');\n\n Ember.run(function() {\n view.set('context.msg', null);\n });\n equal(view.$().text(), '', 'null value properly rendered as a blank');\n\n Ember.run(function() {\n view.set('context.msg', undefined);\n });\n equal(view.$().text(), '', 'undefined value properly rendered as a blank');\n});\n\ntest(\"property changes inside views should only rerender their view\", function() {\n createGroupedView(\n '{{#view}}{{msg}}{{/view}}',\n {msg: 'ohai'}\n );\n var rerenderWasCalled = false;\n view.reopen({\n rerender: function() { rerenderWasCalled = true; this._super(); }\n });\n appendView();\n equal(view.$('script').length, 0, \"No Metamorph markers are output\");\n equal(trim(view.$().text()), 'ohai', 'Original value was rendered');\n\n Ember.run(function() {\n view.set('context.msg', 'ohbai');\n });\n ok(!rerenderWasCalled, \"The GroupView rerender method was not called\");\n equal(trim(view.$().text()), 'ohbai', \"The updated value was rendered\");\n});\n\ntest(\"should work with bindAttr\", function() {\n createGroupedView(\n '',\n {innerClass: 'magic'}\n );\n appendView();\n equal(view.$('.magic').length, 1);\n\n Ember.run(function() {\n view.set('context.innerClass', 'bindings');\n });\n equal(view.$('.bindings').length, 1);\n\n Ember.run(function() {\n view.rerender();\n });\n equal(view.$('.bindings').length, 1);\n});\n\ntest(\"should work with the #if helper\", function() {\n createGroupedView(\n '{{#if something}}hooray{{else}}boo{{/if}}',\n {something: true}\n );\n appendView();\n\n equal(view.$('script').length, 0, \"No Metamorph markers are output\");\n equal(trim(view.$().text()), 'hooray', 'Truthy text was rendered');\n\n Ember.run(function() {\n view.set('context.something', false);\n });\n equal(trim(view.$().text()), 'boo', \"The falsy value was rendered\");\n});\n\ntest(\"#each with no content\", function() {\n expect(0);\n createGroupedView(\n \"{{#each missing}}{{this}}{{/each}}\"\n );\n appendView();\n});\n\ntest(\"#each's content can be changed right before a destroy\", function() {\n expect(0);\n\n createGroupedView(\n \"{{#each numbers}}{{this}}{{/each}}\",\n {numbers: Ember.A([1,2,3])}\n );\n appendView();\n\n Ember.run(function() {\n view.set('context.numbers', Ember.A([3,2,1]));\n view.destroy();\n });\n});\n\ntest(\"#each can be nested\", function() {\n createGroupedView(\n \"{{#each numbers}}{{this}}{{/each}}\",\n {numbers: Ember.A([1, 2, 3])}\n );\n appendView();\n equal(view.$('script').length, 0, \"No Metamorph markers are output\");\n equal(view.$().text(), '123', \"The content was rendered\");\n\n Ember.run(function() {\n view.get('context.numbers').pushObject(4);\n });\n\n equal(view.$().text(), '1234', \"The array observer properly updated the rendered output\");\n\n Ember.run(function() {\n view.set('context.numbers', Ember.A(['a', 'b', 'c']));\n });\n\n equal(view.$().text(), 'abc', \"Replacing the array properly updated the rendered output\");\n});\n\ntest(\"#each can be used with an ArrayProxy\", function() {\n createGroupedView(\n \"{{#each numbers}}{{this}}{{/each}}\",\n {numbers: Ember.ArrayProxy.create({content: Ember.A([1, 2, 3])})}\n );\n appendView();\n equal(view.$('script').length, 0, \"No Metamorph markers are output\");\n equal(view.$().text(), '123', \"The content was rendered\");\n});\n\ntest(\"an #each can be nested with a view inside\", function() {\n var yehuda = {name: 'Yehuda'};\n createGroupedView(\n '{{#each people}}{{#view}}{{name}}{{/view}}{{/each}}',\n {people: Ember.A([yehuda, {name: 'Tom'}])}\n );\n appendView();\n equal(view.$('script').length, 0, \"No Metamorph markers are output\");\n equal(view.$().text(), 'YehudaTom', \"The content was rendered\");\n\n Ember.run(function() {\n Ember.set(yehuda, 'name', 'Erik');\n });\n\n equal(view.$().text(), 'ErikTom', \"The updated object's view was rerendered\");\n});\n\ntest(\"#each with groupedRows=true behaves like a normal bound #each\", function() {\n createGroupedView(\n '{{#each numbers groupedRows=true}}{{this}}{{/each}}',\n {numbers: Ember.A([1, 2, 3])}\n );\n appendView();\n equal(view.$('script').length, 8, \"Correct number of Metamorph markers are output\");\n equal(view.$().text(), '123');\n\n Ember.run(function() {\n view.get('context.numbers').pushObject(4);\n });\n\n equal(view.$('script').length, 10, \"Correct number of Metamorph markers are output\");\n equal(view.$().text(), '1234');\n});\n\ntest(\"#each with itemViewClass behaves like a normal bound #each\", function() {\n createGroupedView(\n '{{#each people itemViewClass=\"Ember.View\"}}{{name}}{{/each}}',\n {people: Ember.A([{name: 'Erik'}, {name: 'Peter'}])}\n );\n appendView();\n equal(view.$('script').length, 2, \"Correct number of Metamorph markers are output\");\n equal(view.$('.ember-view').length, 2, \"Correct number of views are output\");\n equal(view.$().text(), 'ErikPeter');\n\n Ember.run(function() {\n view.get('context.people').pushObject({name: 'Tom'});\n });\n\n equal(view.$('script').length, 2, \"Correct number of Metamorph markers are output\");\n equal(view.$('.ember-view').length, 3, \"Correct number of views are output\");\n // IE likes to add newlines\n equal(view.$().text().replace(/\\s+/g, ''), 'ErikPeterTom');\n});\n\ntest(\"should escape HTML in normal mustaches\", function() {\n createGroupedView(\n '{{msg}}', {msg: 'you need to be more bold'}\n );\n appendView();\n equal(view.$('b').length, 0, \"does not create an element\");\n equal(view.$().text(), 'you need to be more bold', \"inserts entities, not elements\");\n});\n\ntest(\"should not escape HTML in triple mustaches\", function() {\n createGroupedView(\n '{{{msg}}}', {msg: 'you need to be more bold'}\n );\n appendView();\n equal(view.$('b').length, 1, \"creates an element\");\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/group_test");minispade.register('ember-handlebars/~tests/helpers/if_unless_test', "(function() {var appendView = function(view) {\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n};\n\nvar compile = Ember.Handlebars.compile;\n\nvar view;\n\nmodule(\"Handlebars {{#if}} and {{#unless}} helpers\", {\n teardown: function() {\n Ember.run(function() {\n if (view) {\n view.destroy();\n }\n });\n }\n});\n\ntest(\"unless should keep the current context (#784)\", function() {\n view = Ember.View.create({\n o: Ember.Object.create({foo: '42'}),\n\n template: compile('{{#with view.o}}{{#view Ember.View}}{{#unless view.doesNotExist}}foo: {{foo}}{{/unless}}{{/view}}{{/with}}')\n });\n\n appendView(view);\n\n equal(view.$().text(), 'foo: 42');\n});\n\ntest(\"The `if` helper tests for `isTruthy` if available\", function() {\n view = Ember.View.create({\n truthy: Ember.Object.create({ isTruthy: true }),\n falsy: Ember.Object.create({ isTruthy: false }),\n\n template: compile('{{#if view.truthy}}Yep{{/if}}{{#if view.falsy}}Nope{{/if}}')\n });\n\n appendView(view);\n\n equal(view.$().text(), 'Yep');\n});\n\ntest(\"The `if` helper does not print the contents for an object proxy without content\", function() {\n view = Ember.View.create({\n truthy: Ember.ObjectProxy.create({ content: {} }),\n falsy: Ember.ObjectProxy.create({ content: null }),\n\n template: compile('{{#if view.truthy}}Yep{{/if}}{{#if view.falsy}}Nope{{/if}}')\n });\n\n appendView(view);\n\n equal(view.$().text(), 'Yep');\n});\n\ntest(\"The `if` helper updates if an object proxy gains or loses context\", function() {\n view = Ember.View.create({\n proxy: Ember.ObjectProxy.create({ content: null }),\n\n template: compile('{{#if view.proxy}}Yep{{/if}}')\n });\n\n appendView(view);\n\n equal(view.$().text(), '');\n\n Ember.run(function() {\n view.set('proxy.content', {});\n });\n\n equal(view.$().text(), 'Yep');\n\n Ember.run(function() {\n view.set('proxy.content', null);\n });\n\n equal(view.$().text(), '');\n});\n\ntest(\"The `if` helper updates if an array is empty or not\", function() {\n view = Ember.View.create({\n array: Ember.A(),\n\n template: compile('{{#if view.array}}Yep{{/if}}')\n });\n\n appendView(view);\n\n equal(view.$().text(), '');\n\n Ember.run(function() {\n view.get('array').pushObject(1);\n });\n\n equal(view.$().text(), 'Yep');\n\n Ember.run(function() {\n view.get('array').removeObject(1);\n });\n\n equal(view.$().text(), '');\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/if_unless_test");minispade.register('ember-handlebars/~tests/helpers/loc_test', "(function() {var buildView = function(template, context) {\n return Ember.View.create({\n template: Ember.Handlebars.compile(template),\n context: (context || {})\n });\n};\n\nvar appendView = function(view) {\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n};\n\nvar destroyView = function(view) {\n Ember.run(function() {\n view.destroy();\n });\n};\n\nvar oldString;\n\nmodule('Handlebars {{loc valueToLocalize}} helper', {\n setup: function() {\n oldString = Ember.STRINGS;\n Ember.STRINGS = {\n '_Howdy Friend': 'Hallo Freund'\n };\n },\n\n teardown: function() {\n Ember.STRINGS = oldString;\n }\n});\n\ntest(\"let the original value through by default\", function() {\n var view = buildView('{{loc \"Hiya buddy!\"}}');\n appendView(view);\n\n equal(view.$().text(), \"Hiya buddy!\");\n\n destroyView(view);\n});\n\ntest(\"localize a simple string\", function() {\n var view = buildView('{{loc \"_Howdy Friend\"}}');\n appendView(view);\n\n equal(view.$().text(), \"Hallo Freund\");\n\n destroyView(view);\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/loc_test");minispade.register('ember-handlebars/~tests/helpers/partial_test', "(function() {var MyApp;\nvar originalLookup = Ember.lookup, lookup, TemplateTests, view, container;\n\nmodule(\"Support for {{partial}} helper\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n MyApp = lookup.MyApp = Ember.Object.create({});\n container = new Ember.Container();\n container.optionsForType('template', { instantiate: false });\n },\n teardown: function() {\n Ember.run(function() {\n if (view) {\n view.destroy();\n }\n });\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"should render other templates registered with the container\", function() {\n container.register('template:_subTemplateFromContainer', Ember.Handlebars.compile('sub-template'));\n\n view = Ember.View.create({\n container: container,\n template: Ember.Handlebars.compile('This {{partial \"subTemplateFromContainer\"}} is pretty great.')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(Ember.$.trim(view.$().text()), \"This sub-template is pretty great.\");\n});\n\ntest(\"should render other slash-separated templates registered with the container\", function() {\n container.register('template:child/_subTemplateFromContainer', Ember.Handlebars.compile(\"sub-template\"));\n\n view = Ember.View.create({\n container: container,\n template: Ember.Handlebars.compile('This {{partial \"child/subTemplateFromContainer\"}} is pretty great.')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(Ember.$.trim(view.$().text()), \"This sub-template is pretty great.\");\n});\n\ntest(\"should use the current view's context\", function() {\n container.register('template:_person_name', Ember.Handlebars.compile(\"{{firstName}} {{lastName}}\"));\n\n view = Ember.View.create({\n container: container,\n template: Ember.Handlebars.compile('Who is {{partial \"person_name\"}}?')\n });\n view.set('controller', Ember.Object.create({\n firstName: 'Kris',\n lastName: 'Selden'\n }));\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(Ember.$.trim(view.$().text()), \"Who is Kris Selden?\");\n});\n\ntest(\"Quoteless parameters passed to {{template}} perform a bound property lookup of the partial name\", function() {\n container.register('template:_subTemplate', Ember.Handlebars.compile(\"sub-template\"));\n container.register('template:_otherTemplate', Ember.Handlebars.compile(\"other-template\"));\n\n view = Ember.View.create({\n container: container,\n template: Ember.Handlebars.compile('This {{partial view.partialName}} is pretty {{partial nonexistent}}great.'),\n partialName: 'subTemplate'\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(Ember.$.trim(view.$().text()), \"This sub-template is pretty great.\");\n\n Ember.run(function() {\n view.set('partialName', 'otherTemplate');\n });\n\n equal(Ember.$.trim(view.$().text()), \"This other-template is pretty great.\");\n\n Ember.run(function() {\n view.set('partialName', null);\n });\n\n equal(Ember.$.trim(view.$().text()), \"This is pretty great.\");\n});\n\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/partial_test");minispade.register('ember-handlebars/~tests/helpers/template_test', "(function() {var MyApp;\nvar originalLookup = Ember.lookup, lookup, TemplateTests, view, container;\n\nmodule(\"Support for {{template}} helper\", {\n setup: function() {\n Ember.TESTING_DEPRECATION = true;\n\n Ember.lookup = lookup = { Ember: Ember };\n MyApp = lookup.MyApp = Ember.Object.create({});\n container = new Ember.Container();\n container.optionsForType('template', { instantiate: false });\n },\n teardown: function() {\n Ember.run(function() {\n if (view) {\n view.destroy();\n }\n });\n Ember.lookup = originalLookup;\n\n Ember.TESTING_DEPRECATION = false;\n }\n});\n\ntest(\"should render other templates via the container\", function() {\n container.register('template:sub_template_from_container', Ember.Handlebars.compile('sub-template'));\n\n view = Ember.View.create({\n container: container,\n template: Ember.Handlebars.compile('This {{template \"sub_template_from_container\"}} is pretty great.')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(Ember.$.trim(view.$().text()), \"This sub-template is pretty great.\");\n});\n\ntest(\"should use the current view's context\", function() {\n container.register('template:person_name', Ember.Handlebars.compile(\"{{firstName}} {{lastName}}\"));\n\n view = Ember.View.create({\n container: container,\n template: Ember.Handlebars.compile('Who is {{template \"person_name\"}}?')\n });\n view.set('controller', Ember.Object.create({\n firstName: 'Kris',\n lastName: 'Selden'\n }));\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(Ember.$.trim(view.$().text()), \"Who is Kris Selden?\");\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/template_test");minispade.register('ember-handlebars/~tests/helpers/unbound_test', "(function() {/*globals Foo */\n\nvar get = Ember.get, set = Ember.set;\n\nvar appendView = function(view) {\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n};\n\nvar view;\nvar originalLookup = Ember.lookup, lookup;\n\nmodule(\"Handlebars {{#unbound}} helper -- classic single-property usage\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{unbound foo}} {{unbound bar}}\"),\n context: Ember.Object.create({\n foo: \"BORK\",\n barBinding: 'foo'\n })\n });\n\n appendView(view);\n },\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"it should render the current value of a property on the context\", function() {\n equal(view.$().text(), \"BORK BORK\", \"should render the current value of a property\");\n});\n\ntest(\"it should not re-render if the property changes\", function() {\n Ember.run(function() {\n view.set('context.foo', 'OOF');\n });\n equal(view.$().text(), \"BORK BORK\", \"should not re-render if the property changes\");\n});\n\n\nmodule(\"Handlebars {{#unbound boundHelper arg1 arg2... argN}} form: render unbound helper invocations\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n\n Ember.Handlebars.registerBoundHelper('capitalize', function(value) {\n return value.toUpperCase();\n });\n\n Ember.Handlebars.registerBoundHelper('capitalizeName', function(value) {\n return get(value, 'firstName').toUpperCase();\n }, 'firstName');\n\n Ember.Handlebars.registerBoundHelper('concat', function(value) {\n return [].slice.call(arguments, 0, -1).join('');\n });\n\n Ember.Handlebars.registerBoundHelper('concatNames', function(value) {\n return get(value, 'firstName') + get(value, 'lastName');\n }, 'firstName', 'lastName');\n },\n\n teardown: function() {\n delete Ember.Handlebars.helpers['capitalize'];\n delete Ember.Handlebars.helpers['capitalizeName'];\n delete Ember.Handlebars.helpers['concat'];\n delete Ember.Handlebars.helpers['concatNames'];\n\n Ember.run(function() {\n view.destroy();\n });\n Ember.lookup = originalLookup;\n }\n});\n\n\ntest(\"should be able to render an unbound helper invocation\", function() {\n try {\n Ember.Handlebars.registerBoundHelper('repeat', function(value, options) {\n var count = options.hash.count;\n var a = [];\n while(a.length < count) {\n a.push(value);\n }\n return a.join('');\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{unbound repeat foo countBinding=\"bar\"}} {{repeat foo countBinding=\"bar\"}} {{unbound repeat foo count=2}} {{repeat foo count=4}}'),\n context: Ember.Object.create({\n foo: \"X\",\n numRepeatsBinding: \"bar\",\n bar: 5\n })\n });\n appendView(view);\n\n equal(view.$().text(), \"XXXXX XXXXX XX XXXX\", \"first render is correct\");\n\n Ember.run(function() {\n set(view, 'context.bar', 1);\n });\n\n equal(view.$().text(), \"XXXXX X XX XXXX\", \"only unbound bound options changed\");\n } finally {\n delete Ember.Handlebars.helpers['repeat'];\n }\n});\n\n\ntest(\"should be able to render unbound forms of multi-arg helpers\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{concat foo bar bing}} {{unbound concat foo bar bing}}\"),\n context: Ember.Object.create({\n foo: \"a\",\n bar: \"b\",\n bing: \"c\"\n })\n });\n appendView(view);\n\n equal(view.$().text(), \"abc abc\", \"first render is correct\");\n\n Ember.run(function() {\n set(view, 'context.bar', 'X');\n });\n\n equal(view.$().text(), \"aXc abc\", \"unbound helpers/properties stayed the same\");\n});\n\n\ntest(\"should be able to render an unbound helper invocation for helpers with dependent keys\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{capitalizeName person}} {{unbound capitalizeName person}} {{concatNames person}} {{unbound concatNames person}}\"),\n context: Ember.Object.create({\n person: Ember.Object.create({\n firstName: 'shooby',\n lastName: 'taylor'\n })\n })\n });\n appendView(view);\n\n equal(view.$().text(), \"SHOOBY SHOOBY shoobytaylor shoobytaylor\", \"first render is correct\");\n\n Ember.run(function() {\n set(view, 'context.person.firstName', 'sally');\n });\n\n equal(view.$().text(), \"SALLY SHOOBY sallytaylor shoobytaylor\", \"only bound values change\");\n});\n\n\ntest(\"should be able to render an unbound helper invocation in #each helper\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\n [ \"{{#each person in people}}\",\n \"{{capitalize person.firstName}} {{unbound capitalize person.firstName}}\",\n \"{{/each}}\"].join(\"\")),\n context: {\n people: Ember.A([\n {\n firstName: 'shooby',\n lastName: 'taylor'\n },\n {\n firstName: 'cindy',\n lastName: 'taylor'\n }\n ])}\n });\n appendView(view);\n\n equal(view.$().text(), \"SHOOBY SHOOBYCINDY CINDY\", \"unbound rendered correctly\");\n});\n\n\ntest(\"should be able to render an unbound helper invocation with bound hash options\", function() {\n try {\n Ember.Handlebars.registerBoundHelper('repeat', function(value) {\n return [].slice.call(arguments, 0, -1).join('');\n });\n\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{capitalizeName person}} {{unbound capitalizeName person}} {{concatNames person}} {{unbound concatNames person}}\"),\n context: Ember.Object.create({\n person: Ember.Object.create({\n firstName: 'shooby',\n lastName: 'taylor'\n })\n })\n });\n appendView(view);\n\n equal(view.$().text(), \"SHOOBY SHOOBY shoobytaylor shoobytaylor\", \"first render is correct\");\n\n Ember.run(function() {\n set(view, 'context.person.firstName', 'sally');\n });\n\n equal(view.$().text(), \"SALLY SHOOBY sallytaylor shoobytaylor\", \"only bound values change\");\n } finally {\n delete Ember.Handlebars.registerBoundHelper['repeat'];\n }\n});\n\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/unbound_test");minispade.register('ember-handlebars/~tests/helpers/view_test', "(function() {var view, originalLookup;\n\nvar container = {\n lookupFactory: function() { }\n};\n\nfunction viewClass(options) {\n options.container = options.container || container;\n return Ember.View.extend(options);\n}\n\nmodule(\"Handlebars {{#view}} helper\", {\n setup: function() {\n originalLookup = Ember.lookup;\n\n },\n\n teardown: function() {\n Ember.lookup = originalLookup;\n Ember.run(view, 'destroy');\n }\n});\n\n\ntest(\"View lookup - App.FuView\", function() {\n Ember.lookup = {\n App: {\n FuView: viewClass({\n elementId: \"fu\",\n template: Ember.Handlebars.compile(\"bro\")\n })\n }\n };\n\n view = viewClass({\n template: Ember.Handlebars.compile(\"{{view App.FuView}}\")\n }).create();\n\n Ember.run(view, 'appendTo', '#qunit-fixture');\n\n equal(Ember.$('#fu').text(), 'bro');\n});\n\ntest(\"View lookup - 'App.FuView'\", function() {\n Ember.lookup = {\n App: {\n FuView: viewClass({\n elementId: \"fu\",\n template: Ember.Handlebars.compile(\"bro\")\n })\n }\n };\n\n view = viewClass({\n template: Ember.Handlebars.compile(\"{{view 'App.FuView'}}\")\n }).create();\n\n Ember.run(view, 'appendTo', '#qunit-fixture');\n\n equal(Ember.$('#fu').text(), 'bro');\n});\n\ntest(\"View lookup - 'fu'\", function() {\n var FuView = viewClass({\n elementId: \"fu\",\n template: Ember.Handlebars.compile(\"bro\")\n });\n\n var container = {\n lookupFactory: lookupFactory\n };\n\n view = Ember.View.extend({\n template: Ember.Handlebars.compile(\"{{view 'fu'}}\"),\n container: container\n }).create();\n\n Ember.run(view, 'appendTo', '#qunit-fixture');\n\n equal(Ember.$('#fu').text(), 'bro');\n\n function lookupFactory(fullName) {\n equal(fullName, 'view:fu');\n\n return FuView;\n }\n});\n\ntest(\"id bindings downgrade to one-time property lookup\", function() {\n view = Ember.View.extend({\n template: Ember.Handlebars.compile(\"{{#view Ember.View id=view.meshuggah}}{{view.parentView.meshuggah}}{{/view}}\"),\n meshuggah: 'stengah'\n }).create();\n\n Ember.run(view, 'appendTo', '#qunit-fixture');\n\n equal(Ember.$('#stengah').text(), 'stengah', \"id binding performed property lookup\");\n Ember.run(view, 'set', 'meshuggah', 'omg');\n equal(Ember.$('#stengah').text(), 'omg', \"id didn't change\");\n});\n\ntest(\"mixing old and new styles of property binding fires a warning, treats value as if it were quoted\", function() {\n\n expect(2);\n\n var oldWarn = Ember.warn;\n\n Ember.warn = function(msg) {\n equal(msg, \"You're attempting to render a view by passing borfBinding=view.snork to a view helper, but this syntax is ambiguous. You should either surround view.snork in quotes or remove `Binding` from borfBinding.\");\n };\n\n view = Ember.View.extend({\n template: Ember.Handlebars.compile(\"{{#view Ember.View borfBinding=view.snork}}

    {{view.borf}}

    {{/view}}\"),\n snork: \"nerd\"\n }).create();\n\n Ember.run(view, 'appendTo', '#qunit-fixture');\n\n equal(Ember.$('#lol').text(), \"nerd\", \"awkward mixed syntax treated like binding\");\n\n Ember.warn = oldWarn;\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/view_test");minispade.register('ember-handlebars/~tests/helpers/with_test', "(function() {/*globals Foo */\n\nvar appendView = function(view) {\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n};\n\nvar view;\nvar originalLookup = Ember.lookup, lookup;\n\nmodule(\"Handlebars {{#with}} helper\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{#with person as tom}}{{title}}: {{tom.name}}{{/with}}\"),\n context: {\n title: \"Señor Engineer\",\n person: { name: \"Tom Dale\" }\n }\n });\n\n appendView(view);\n },\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"it should support #with foo as bar\", function() {\n equal(view.$().text(), \"Señor Engineer: Tom Dale\", \"should be properly scoped\");\n});\n\ntest(\"updating the context should update the alias\", function() {\n Ember.run(function() {\n view.set('context.person', {\n name: \"Yehuda Katz\"\n });\n });\n\n equal(view.$().text(), \"Señor Engineer: Yehuda Katz\", \"should be properly scoped after updating\");\n});\n\ntest(\"updating a property on the context should update the HTML\", function() {\n Ember.run(function() {\n Ember.set(view, 'context.person.name', \"Yehuda Katz\");\n });\n\n equal(view.$().text(), \"Señor Engineer: Yehuda Katz\", \"should be properly scoped after updating\");\n});\n\ntest(\"updating a property on the view should update the HTML\", function() {\n Ember.run(function() {\n view.set('context.title', \"Señorette Engineer\");\n });\n\n equal(view.$().text(), \"Señorette Engineer: Tom Dale\", \"should be properly scoped after updating\");\n});\n\nmodule(\"Handlebars {{#with}} globals helper\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n\n lookup.Foo = { bar: 'baz' };\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{#with Foo.bar as qux}}{{qux}}{{/with}}\")\n });\n\n appendView(view);\n },\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"it should support #with Foo.bar as qux\", function() {\n equal(view.$().text(), \"baz\", \"should be properly scoped\");\n\n Ember.run(function() {\n Ember.set(lookup.Foo, 'bar', 'updated');\n });\n\n equal(view.$().text(), \"updated\", \"should update\");\n});\n\nmodule(\"Handlebars {{#with keyword as foo}}\");\n\ntest(\"it should support #with view as foo\", function() {\n var view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{#with view as myView}}{{myView.name}}{{/with}}\"),\n name: \"Sonics\"\n });\n\n appendView(view);\n equal(view.$().text(), \"Sonics\", \"should be properly scoped\");\n\n Ember.run(function() {\n Ember.set(view, 'name', \"Thunder\");\n });\n\n equal(view.$().text(), \"Thunder\", \"should update\");\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\ntest(\"it should support #with name as food, then #with foo as bar\", function() {\n var view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{#with name as foo}}{{#with foo as bar}}{{bar}}{{/with}}{{/with}}\"),\n context: { name: \"caterpillar\" }\n });\n\n appendView(view);\n equal(view.$().text(), \"caterpillar\", \"should be properly scoped\");\n\n Ember.run(function() {\n Ember.set(view, 'context.name', \"butterfly\");\n });\n\n equal(view.$().text(), \"butterfly\", \"should update\");\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\nmodule(\"Handlebars {{#with this as foo}}\");\n\ntest(\"it should support #with this as qux\", function() {\n var view = Ember.View.create({\n template: Ember.Handlebars.compile(\"{{#with this as person}}{{person.name}}{{/with}}\"),\n controller: Ember.Object.create({ name: \"Los Pivots\" })\n });\n\n appendView(view);\n equal(view.$().text(), \"Los Pivots\", \"should be properly scoped\");\n\n Ember.run(function() {\n Ember.set(view, 'controller.name', \"l'Pivots\");\n });\n\n equal(view.$().text(), \"l'Pivots\", \"should update\");\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\nmodule(\"Handlebars {{#with foo}} insideGroup\");\n\ntest(\"it should render without fail\", function() {\n var View = Ember.View.extend({\n template: Ember.Handlebars.compile(\"{{#view view.childView}}{{#with person}}{{name}}{{/with}}{{/view}}\"),\n controller: Ember.Object.create({ person: { name: \"Ivan IV Vasilyevich\" } }),\n childView: Ember.View.extend({\n render: function(){\n this.set('templateData.insideGroup', true);\n return this._super.apply(this, arguments);\n }\n })\n });\n\n var view = View.create();\n appendView(view);\n equal(view.$().text(), \"Ivan IV Vasilyevich\", \"should be properly scoped\");\n\n Ember.run(function() {\n Ember.set(view, 'controller.person.name', \"Ivan the Terrible\");\n });\n\n equal(view.$().text(), \"Ivan the Terrible\", \"should update\");\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/with_test");minispade.register('ember-handlebars/~tests/helpers/yield_test', "(function() {\nvar set = Ember.set, get = Ember.get;\n\nvar originalLookup = Ember.lookup, lookup, TemplateTests, view, container;\n\nmodule(\"Support for {{yield}} helper (#307)\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n\n lookup.TemplateTests = TemplateTests = Ember.Namespace.create();\n\n container = new Ember.Container();\n container.optionsForType('template', { instantiate: false });\n },\n teardown: function() {\n Ember.run(function() {\n Ember.TEMPLATES = {};\n if (view) {\n view.destroy();\n }\n });\n\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"a view with a layout set renders its template where the {{yield}} helper appears\", function() {\n TemplateTests.ViewWithLayout = Ember.View.extend({\n layout: Ember.Handlebars.compile('

    {{title}}

    {{yield}}
    ')\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#view TemplateTests.ViewWithLayout title=\"My Fancy Page\"}}
    Show something interesting here
    {{/view}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div.wrapper div.page-body').length, 1, 'page-body is embedded within wrapping my-page');\n});\n\ntest(\"block should work properly even when templates are not hard-coded\", function() {\n container.register('template:nester', Ember.Handlebars.compile('

    {{title}}

    {{yield}}
    '));\n container.register('template:nested', Ember.Handlebars.compile('{{#view TemplateTests.ViewWithLayout title=\"My Fancy Page\"}}
    Show something interesting here
    {{/view}}'));\n\n TemplateTests.ViewWithLayout = Ember.View.extend({\n container: container,\n layoutName: 'nester'\n });\n\n view = Ember.View.create({\n container: container,\n templateName: 'nested'\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div.wrapper div.page-body').length, 1, 'page-body is embedded within wrapping my-page');\n\n});\n\ntest(\"templates should yield to block, when the yield is embedded in a hierarchy of virtual views\", function() {\n TemplateTests.TimesView = Ember.View.extend({\n layout: Ember.Handlebars.compile('
    {{#each view.index}}{{yield}}{{/each}}
    '),\n n: null,\n index: Ember.computed(function() {\n var n = Ember.get(this, 'n'), indexArray = Ember.A();\n for (var i=0; i < n; i++) {\n indexArray[i] = i;\n }\n return indexArray;\n })\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('
    Counting to 5
    {{#view TemplateTests.TimesView n=5}}
    Hello
    {{/view}}
    ')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div#container div.times-item').length, 5, 'times-item is embedded within wrapping container 5 times, as expected');\n});\n\ntest(\"templates should yield to block, when the yield is embedded in a hierarchy of non-virtual views\", function() {\n TemplateTests.NestingView = Ember.View.extend({\n layout: Ember.Handlebars.compile('{{#view Ember.View tagName=\"div\" classNames=\"nesting\"}}{{yield}}{{/view}}')\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('
    {{#view TemplateTests.NestingView}}
    Hello
    {{/view}}
    ')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div#container div.nesting div#block').length, 1, 'nesting view yields correctly even within a view hierarchy in the nesting view');\n});\n\ntest(\"block should not be required\", function() {\n TemplateTests.YieldingView = Ember.View.extend({\n layout: Ember.Handlebars.compile('{{#view Ember.View tagName=\"div\" classNames=\"yielding\"}}{{yield}}{{/view}}')\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('
    {{view TemplateTests.YieldingView}}
    ')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div#container div.yielding').length, 1, 'yielding view is rendered as expected');\n});\n\ntest(\"yield uses the outer context\", function() {\n var component = Ember.Component.extend({\n boundText: \"inner\",\n layout: Ember.Handlebars.compile(\"

    {{boundText}}

    {{yield}}

    \")\n });\n\n view = Ember.View.create({\n controller: { boundText: \"outer\", component: component },\n template: Ember.Handlebars.compile('{{#view component}}{{boundText}}{{/view}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div p:contains(inner) + p:contains(outer)').length, 1, \"Yield points at the right context\");\n});\n\ntest(\"yield inside a conditional uses the outer context\", function() {\n var component = Ember.Component.extend({\n boundText: \"inner\",\n truthy: true,\n obj: {},\n layout: Ember.Handlebars.compile(\"

    {{boundText}}

    {{#if truthy}}{{#with obj}}{{yield}}{{/with}}{{/if}}

    \")\n });\n\n view = Ember.View.create({\n controller: { boundText: \"outer\", truthy: true, obj: { component: component, truthy: true, boundText: 'insideWith' } },\n template: Ember.Handlebars.compile('{{#with obj}}{{#if truthy}}{{#view component}}{{#if truthy}}{{boundText}}{{/if}}{{/view}}{{/if}}{{/with}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div p:contains(inner) + p:contains(insideWith)').length, 1, \"Yield points at the right context\");\n});\n\ntest(\"outer keyword doesn't mask inner component property\", function () {\n var component = Ember.Component.extend({\n item: \"inner\",\n layout: Ember.Handlebars.compile(\"

    {{item}}

    {{yield}}

    \")\n });\n\n view = Ember.View.create({\n controller: { boundText: \"outer\", component: component },\n template: Ember.Handlebars.compile('{{#with boundText as item}}{{#view component}}{{item}}{{/view}}{{/with}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div p:contains(inner) + p:contains(outer)').length, 1, \"inner component property isn't masked by outer keyword\");\n});\n\ntest(\"inner keyword doesn't mask yield property\", function() {\n var component = Ember.Component.extend({\n boundText: \"inner\",\n layout: Ember.Handlebars.compile(\"{{#with boundText as item}}

    {{item}}

    {{yield}}

    {{/with}}\")\n });\n\n view = Ember.View.create({\n controller: { item: \"outer\", component: component },\n template: Ember.Handlebars.compile('{{#view component}}{{item}}{{/view}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div p:contains(inner) + p:contains(outer)').length, 1, \"outer property isn't masked by inner keyword\");\n});\n\ntest(\"can bind a keyword to a component and use it in yield\", function() {\n var component = Ember.Component.extend({\n content: null,\n layout: Ember.Handlebars.compile(\"

    {{content}}

    {{yield}}

    \")\n });\n\n view = Ember.View.create({\n controller: { boundText: \"outer\", component: component },\n template: Ember.Handlebars.compile('{{#with boundText as item}}{{#view component contentBinding=\"item\"}}{{item}}{{/view}}{{/with}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div p:contains(outer) + p:contains(outer)').length, 1, \"component and yield have keyword\");\n\n Ember.run(function() {\n view.set('controller.boundText', 'update');\n });\n\n equal(view.$('div p:contains(update) + p:contains(update)').length, 1, \"keyword has correctly propagated update\");\n});\n\ntest(\"yield uses the layout context for non component\", function() {\n view = Ember.View.create({\n controller: {\n boundText: \"outer\",\n inner: {\n boundText: \"inner\"\n }\n },\n layout: Ember.Handlebars.compile(\"

    {{boundText}}

    {{#with inner}}

    {{yield}}

    {{/with}}\"),\n template: Ember.Handlebars.compile('{{boundText}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal('outerinner', view.$('p').text(), \"Yield points at the right context\");\n});\n\ntest(\"yield view should be a virtual view\", function() {\n var component = Ember.Component.extend({\n isParentComponent: true,\n\n template: Ember.Handlebars.compile('{{view includedComponent}}'),\n layout: Ember.Handlebars.compile('{{yield}}')\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{view component}}'),\n controller: {\n component: component,\n includedComponent: Ember.Component.extend({\n didInsertElement: function() {\n var parentView = this.get('parentView');\n\n ok(parentView.get('isParentComponent'), \"parent view is the parent component\");\n }\n })\n }\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n});\n\n\ntest(\"adding a layout should not affect the context of normal views\", function() {\n var parentView = Ember.View.create({\n context: \"ParentContext\"\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\"View context: {{this}}\"),\n context: \"ViewContext\",\n _parentView: parentView\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.$().text(), \"View context: ViewContext\");\n\n\n set(view, 'layout', Ember.Handlebars.compile(\"Layout: {{yield}}\"));\n\n Ember.run(function() {\n view.destroyElement();\n view.createElement();\n });\n\n equal(view.$().text(), \"Layout: View context: ViewContext\");\n\n Ember.run(function() {\n parentView.destroy();\n });\n});\n\ntest(\"yield should work for views even if _parentView is null\", function() {\n view = Ember.View.create({\n layout: Ember.Handlebars.compile('Layout: {{yield}}'),\n template: Ember.Handlebars.compile(\"View Content\")\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.$().text(), \"Layout: View Content\");\n\n});\n\nmodule(\"Component {{yield}}\", {\n setup: function() {},\n teardown: function() {\n Ember.run(function() {\n if (view) {\n view.destroy();\n }\n delete Ember.Handlebars.helpers['inner-component'];\n delete Ember.Handlebars.helpers['outer-component'];\n });\n }\n});\n\ntest(\"yield with nested components (#3220)\", function(){\n var count = 0;\n var InnerComponent = Ember.Component.extend({\n layout: Ember.Handlebars.compile(\"{{yield}}\"),\n _yield: function (context, options) {\n count++;\n if (count > 1) throw new Ember.Error('is looping');\n return this._super(context, options);\n }\n });\n\n Ember.Handlebars.helper('inner-component', InnerComponent);\n\n var OuterComponent = Ember.Component.extend({\n layout: Ember.Handlebars.compile(\"{{#inner-component}}{{yield}}{{/inner-component}}\")\n });\n\n Ember.Handlebars.helper('outer-component', OuterComponent);\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile(\n \"{{#outer-component}}Hello world{{/outer-component}}\"\n )\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('div > span').text(), \"Hello world\");\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/helpers/yield_test");minispade.register('ember-handlebars/~tests/loader_test', "(function() {var originalLookup = Ember.lookup, lookup, Tobias, App, view;\n\nmodule(\"test Ember.Handlebars.bootstrap\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n },\n teardown: function() {\n Ember.TEMPLATES = {};\n Ember.lookup = originalLookup;\n if(App) { Ember.run(App, 'destroy'); }\n if (view) { Ember.run(view, 'destroy'); }\n }\n});\n\nfunction checkTemplate(templateName) {\n Ember.run(function() {\n Ember.Handlebars.bootstrap(Ember.$('#qunit-fixture'));\n });\n var template = Ember.TEMPLATES[templateName];\n ok(template, 'template is available on Ember.TEMPLATES');\n equal(Ember.$('#qunit-fixture script').length, 0, 'script removed');\n var view = Ember.View.create({\n template: template,\n context: {\n firstName: 'Tobias',\n drug: 'teamocil'\n }\n });\n Ember.run(function() {\n view.createElement();\n });\n equal(Ember.$.trim(view.$().text()), 'Tobias takes teamocil', 'template works');\n Ember.run(function() {\n view.destroy();\n });\n}\n\ntest('template with data-template-name should add a new template to Ember.TEMPLATES', function() {\n Ember.$('#qunit-fixture').html('');\n\n checkTemplate('funkyTemplate');\n});\n\ntest('template with id instead of data-template-name should add a new template to Ember.TEMPLATES', function() {\n Ember.$('#qunit-fixture').html('');\n\n checkTemplate('funkyTemplate');\n});\n\ntest('template without data-template-name or id should default to application', function() {\n Ember.$('#qunit-fixture').html('');\n\n checkTemplate('application');\n});\n\ntest('template with type text/x-raw-handlebars should be parsed', function() {\n Ember.$('#qunit-fixture').html('');\n\n Ember.run(function() {\n Ember.Handlebars.bootstrap(Ember.$('#qunit-fixture'));\n });\n\n ok(Ember.TEMPLATES['funkyTemplate'], 'template with name funkyTemplate available');\n\n // This won't even work with Ember templates\n equal(Ember.$.trim(Ember.TEMPLATES['funkyTemplate']({ name: 'Tobias' })), \"Tobias\");\n});\n\ntest('duplicated default application templates should throw exception', function() {\n Ember.$('#qunit-fixture').html('');\n\n throws(function () {\n Ember.Handlebars.bootstrap(Ember.$('#qunit-fixture'));\n },\n /Template named \"[^\"]+\" already exists\\./,\n \"duplicate templates should not be allowed\");\n});\n\ntest('default application template and id application template present should throw exception', function() {\n Ember.$('#qunit-fixture').html('');\n\n throws(function () {\n Ember.Handlebars.bootstrap(Ember.$('#qunit-fixture'));\n },\n /Template named \"[^\"]+\" already exists\\./,\n \"duplicate templates should not be allowed\");\n});\n\ntest('default application template and data-template-name application template present should throw exception', function() {\n Ember.$('#qunit-fixture').html('');\n\n throws(function () {\n Ember.Handlebars.bootstrap(Ember.$('#qunit-fixture'));\n },\n /Template named \"[^\"]+\" already exists\\./,\n \"duplicate templates should not be allowed\");\n});\n\ntest('duplicated template id should throw exception', function() {\n Ember.$('#qunit-fixture').html('');\n\n throws(function () {\n Ember.Handlebars.bootstrap(Ember.$('#qunit-fixture'));\n },\n /Template named \"[^\"]+\" already exists\\./,\n \"duplicate templates should not be allowed\");\n});\n\ntest('duplicated template data-template-name should throw exception', function() {\n Ember.$('#qunit-fixture').html('');\n\n throws(function () {\n Ember.Handlebars.bootstrap(Ember.$('#qunit-fixture'));\n },\n /Template named \"[^\"]+\" already exists\\./,\n \"duplicate templates should not be allowed\");\n});\n\nif (Ember.component) {\n test('registerComponents initializer', function(){\n Ember.TEMPLATES['components/x-apple'] = 'asdf';\n\n App = Ember.run(Ember.Application, 'create');\n\n ok(Ember.Handlebars.helpers['x-apple'], 'x-apple helper is present');\n ok(App.__container__.has('component:x-apple'), 'the container is aware of x-apple');\n });\n\n test('registerComponents and generated components', function(){\n Ember.TEMPLATES['components/x-apple'] = 'asdf';\n\n App = Ember.run(Ember.Application, 'create');\n view = App.__container__.lookup('component:x-apple');\n equal(view.get('layoutName'), 'components/x-apple', 'has correct layout name');\n });\n\n test('registerComponents and non-geneated components', function(){\n Ember.TEMPLATES['components/x-apple'] = 'asdf';\n\n Ember.run(function(){\n App = Ember.Application.create();\n\n // currently Component code must be loaded before initializers\n // this is mostly due to how they are bootstrapped. We will hopefully\n // sort this out soon.\n App.XAppleComponent = Ember.Component.extend({\n isCorrect: true\n });\n });\n\n view = App.__container__.lookup('component:x-apple');\n equal(view.get('layoutName'), 'components/x-apple', 'has correct layout name');\n ok(view.get('isCorrect'), 'ensure a non-generated component');\n });\n}\n\n})();\n//@ sourceURL=ember-handlebars/~tests/loader_test");minispade.register('ember-handlebars/~tests/lookup_test', "(function() {module(\"Ember.Handlebars.resolveParams\");\n\ntest(\"Raw string parameters should be returned as Strings\", function() {\n var params = Ember.Handlebars.resolveParams({}, [\"foo\", \"bar\", \"baz\"], { types: [\"STRING\", \"STRING\", \"STRING\"] });\n deepEqual(params, [\"foo\", \"bar\", \"baz\"]);\n});\n\ntest(\"Raw boolean parameters should be returned as Booleans\", function() {\n var params = Ember.Handlebars.resolveParams({}, [true, false], { types: [\"BOOLEAN\", \"BOOLEAN\"] });\n deepEqual(params, [true, false]);\n});\n\ntest(\"Raw numeric parameters should be returned as Numbers\", function() {\n var params = Ember.Handlebars.resolveParams({}, [1, 1.0, 1.5, 0.5], { types: [\"NUMBER\", \"NUMBER\", \"NUMBER\", \"NUMBER\"] });\n deepEqual(params, [1, 1, 1.5, 0.5]);\n});\n\ntest(\"ID parameters should be looked up on the context\", function() {\n var context = {\n salutation: \"Mr\",\n name: {\n first: \"Tom\",\n last: \"Dale\"\n }\n };\n\n var params = Ember.Handlebars.resolveParams(context, [\"salutation\", \"name.first\", \"name.last\"], { types: [\"ID\", \"ID\", \"ID\"] });\n deepEqual(params, [\"Mr\", \"Tom\", \"Dale\"]);\n});\n\ntest(\"ID parameters can look up keywords\", function() {\n var controller = {\n salutation: \"Mr\"\n };\n\n var view = {\n name: { first: \"Tom\", last: \"Dale\" }\n };\n\n var context = {\n yuno: \"State Charts\"\n };\n\n var options = {\n types: [\"ID\", \"ID\", \"ID\", \"ID\"],\n data: {\n keywords: {\n controller: controller,\n view: view\n }\n }\n };\n\n var params = Ember.Handlebars.resolveParams(context, [\"controller.salutation\", \"view.name.first\", \"view.name.last\", \"yuno\"], options);\n deepEqual(params, [\"Mr\", \"Tom\", \"Dale\", \"State Charts\"]);\n});\n\nmodule(\"Ember.Handlebars.resolveHash\");\n\ntest(\"Raw string parameters should be returned as Strings\", function() {\n var hash = Ember.Handlebars.resolveHash({}, { string: \"foo\" }, { hashTypes: { string: \"STRING\" } });\n deepEqual(hash, { string: \"foo\" });\n});\n\ntest(\"Raw boolean parameters should be returned as Booleans\", function() {\n var hash = Ember.Handlebars.resolveHash({}, { yes: true, no: false }, { hashTypes: { yes: \"BOOLEAN\", no: \"BOOLEAN\" } });\n deepEqual(hash, { yes: true, no: false });\n});\n\ntest(\"Raw numeric parameters should be returned as Numbers\", function() {\n var hash = Ember.Handlebars.resolveHash({}, { one: 1, oneFive: 1.5, ohFive: 0.5 }, { hashTypes: { one: \"NUMBER\", oneFive: \"NUMBER\", ohFive: \"NUMBER\" } });\n deepEqual(hash, { one: 1, oneFive: 1.5, ohFive: 0.5 });\n});\n\ntest(\"ID parameters should be looked up on the context\", function() {\n var context = {\n salutation: \"Mr\",\n name: {\n first: \"Tom\",\n last: \"Dale\"\n }\n };\n\n var hash = Ember.Handlebars.resolveHash(context, { mr: \"salutation\", firstName: \"name.first\", lastName: \"name.last\" }, { hashTypes: { mr: \"ID\", firstName: \"ID\", lastName: \"ID\" } });\n deepEqual(hash, { mr: \"Mr\", firstName: \"Tom\", lastName: \"Dale\" });\n});\n\ntest(\"ID parameters can look up keywords\", function() {\n var controller = {\n salutation: \"Mr\"\n };\n\n var view = {\n name: { first: \"Tom\", last: \"Dale\" }\n };\n\n var context = {\n yuno: \"State Charts\"\n };\n\n var options = {\n hashTypes: { mr: \"ID\", firstName: \"ID\", lastName: \"ID\", yuno: \"ID\" },\n data: {\n keywords: {\n controller: controller,\n view: view\n }\n }\n };\n\n var hash = Ember.Handlebars.resolveHash(context, { mr: \"controller.salutation\", firstName: \"view.name.first\", lastName: \"view.name.last\", yuno: \"yuno\" }, options);\n deepEqual(hash, { mr: \"Mr\", firstName: \"Tom\", lastName: \"Dale\", yuno: \"State Charts\" });\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/lookup_test");minispade.register('ember-handlebars/~tests/views/collection_view_test', "(function() {/*globals TemplateTests:true App:true */\n\nvar set = Ember.set, get = Ember.get, trim = Ember.$.trim;\nvar firstGrandchild = function(view) {\n return get(get(view, 'childViews').objectAt(0), 'childViews').objectAt(0);\n};\nvar nthChild = function(view, nth) {\n return get(view, 'childViews').objectAt(nth || 0);\n};\nvar firstChild = nthChild;\n\nvar originalLookup = Ember.lookup, lookup, TemplateTests, view;\n\nmodule(\"ember-handlebars/tests/views/collection_view_test\", {\n setup: function() {\n Ember.lookup = lookup = { Ember: Ember };\n lookup.TemplateTests = TemplateTests = Ember.Namespace.create();\n },\n teardown: function() {\n Ember.run(function() {\n if (view) {\n view.destroy();\n }\n });\n\n Ember.lookup = originalLookup;\n Ember.TESTING_DEPRECATION = false;\n }\n});\n\ntest(\"passing a block to the collection helper sets it as the template for example views\", function() {\n TemplateTests.CollectionTestView = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A(['foo', 'bar', 'baz'])\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection TemplateTests.CollectionTestView}} {{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('label').length, 3, 'one label element is created for each content item');\n});\n\ntest(\"collection helper should accept relative paths\", function() {\n Ember.TESTING_DEPRECATION = true;\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection view.collection}} {{/collection}}'),\n collection: Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A(['foo', 'bar', 'baz'])\n })\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('label').length, 3, 'one label element is created for each content item');\n});\n\ntest(\"empty views should be removed when content is added to the collection (regression, ht: msofaer)\", function() {\n var App;\n\n Ember.run(function() {\n lookup.App = App = Ember.Application.create();\n });\n\n App.EmptyView = Ember.View.extend({\n template : Ember.Handlebars.compile(\"No Rows Yet\")\n });\n\n App.ListView = Ember.CollectionView.extend({\n emptyView: App.EmptyView\n });\n\n App.listController = Ember.ArrayProxy.create({\n content : Ember.A()\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection App.ListView contentBinding=\"App.listController\" tagName=\"table\"}} {{view.content.title}} {{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('tr').length, 1, 'Make sure the empty view is there (regression)');\n\n Ember.run(function() {\n App.listController.pushObject({title : \"Go Away, Placeholder Row!\"});\n });\n\n equal(view.$('tr').length, 1, 'has one row');\n equal(view.$('tr:nth-child(1) td').text(), 'Go Away, Placeholder Row!', 'The content is the updated data.');\n\n Ember.run(function() { App.destroy(); });\n});\n\ntest(\"should be able to specify which class should be used for the empty view\", function() {\n Ember.TESTING_DEPRECATION = true;\n\n var App;\n\n Ember.run(function() {\n lookup.App = App = Ember.Application.create();\n });\n\n App.EmptyView = Ember.View.extend({\n template: Ember.Handlebars.compile('This is an empty view')\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{collection emptyViewClass=\"App.EmptyView\"}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$().text(), 'This is an empty view', \"Empty view should be rendered.\");\n\n Ember.run(function() {\n App.destroy();\n });\n});\n\ntest(\"if no content is passed, and no 'else' is specified, nothing is rendered\", function() {\n TemplateTests.CollectionTestView = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A()\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection \"TemplateTests.CollectionTestView\"}} {{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('li').length, 0, 'if no \"else\" is specified, nothing is rendered');\n});\n\ntest(\"if no content is passed, and 'else' is specified, the else block is rendered\", function() {\n TemplateTests.CollectionTestView = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A()\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection \"TemplateTests.CollectionTestView\"}} {{ else }} {{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('li:has(del)').length, 1, 'the else block is rendered');\n});\n\ntest(\"a block passed to a collection helper defaults to the content property of the context\", function() {\n TemplateTests.CollectionTestView = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A(['foo', 'bar', 'baz'])\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection \"TemplateTests.CollectionTestView\"}} {{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('li:nth-child(1) label').length, 1);\n equal(view.$('li:nth-child(1) label').text(), 'foo');\n equal(view.$('li:nth-child(2) label').length, 1);\n equal(view.$('li:nth-child(2) label').text(), 'bar');\n equal(view.$('li:nth-child(3) label').length, 1);\n equal(view.$('li:nth-child(3) label').text(), 'baz');\n});\n\ntest(\"a block passed to a collection helper defaults to the view\", function() {\n TemplateTests.CollectionTestView = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A(['foo', 'bar', 'baz'])\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection \"TemplateTests.CollectionTestView\"}} {{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n // Preconds\n equal(view.$('li:nth-child(1) label').length, 1);\n equal(view.$('li:nth-child(1) label').text(), 'foo');\n equal(view.$('li:nth-child(2) label').length, 1);\n equal(view.$('li:nth-child(2) label').text(), 'bar');\n equal(view.$('li:nth-child(3) label').length, 1);\n equal(view.$('li:nth-child(3) label').text(), 'baz');\n\n Ember.run(function() {\n set(firstChild(view), 'content', Ember.A());\n });\n equal(view.$('label').length, 0, \"all list item views should be removed from DOM\");\n});\n\ntest(\"should include an id attribute if id is set in the options hash\", function() {\n TemplateTests.CollectionTestView = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A(['foo', 'bar', 'baz'])\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection \"TemplateTests.CollectionTestView\" id=\"baz\"}}foo{{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('ul#baz').length, 1, \"adds an id attribute\");\n});\n\ntest(\"should give its item views the class specified by itemClass\", function() {\n TemplateTests.itemClassTestCollectionView = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A(['foo', 'bar', 'baz'])\n });\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection \"TemplateTests.itemClassTestCollectionView\" itemClass=\"baz\"}}foo{{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('ul li.baz').length, 3, \"adds class attribute\");\n});\n\ntest(\"should give its item views the classBinding specified by itemClassBinding\", function() {\n TemplateTests.itemClassBindingTestCollectionView = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A([Ember.Object.create({ isBaz: false }), Ember.Object.create({ isBaz: true }), Ember.Object.create({ isBaz: true })])\n });\n\n view = Ember.View.create({\n isBar: true,\n template: Ember.Handlebars.compile('{{#collection \"TemplateTests.itemClassBindingTestCollectionView\" itemClassBinding=\"view.isBar\"}}foo{{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('ul li.is-bar').length, 3, \"adds class on initial rendering\");\n\n // NOTE: in order to bind an item's class to a property of the item itself (e.g. `isBaz` above), it will be necessary\n // to introduce a new keyword that could be used from within `itemClassBinding`. For instance, `itemClassBinding=\"item.isBaz\"`.\n});\n\ntest(\"should give its item views the property specified by itemPropertyBinding\", function() {\n Ember.TESTING_DEPRECATION = true;\n\n TemplateTests.itemPropertyBindingTestItemView = Ember.View.extend({\n tagName: 'li'\n });\n\n // Use preserveContext=false so the itemView handlebars context is the view context\n // Set itemView bindings using item*\n view = Ember.View.create({\n baz: \"baz\",\n content: Ember.A([Ember.Object.create(), Ember.Object.create(), Ember.Object.create()]),\n template: Ember.Handlebars.compile('{{#collection contentBinding=\"view.content\" tagName=\"ul\" itemViewClass=\"TemplateTests.itemPropertyBindingTestItemView\" itemPropertyBinding=\"view.baz\" preserveContext=false}}{{view.property}}{{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('ul li').length, 3, \"adds 3 itemView\");\n\n view.$('ul li').each(function(i, li) {\n equal(Ember.$(li).text(), \"baz\", \"creates the li with the property = baz\");\n });\n\n Ember.run(function() {\n set(view, 'baz', \"yobaz\");\n });\n\n equal(view.$('ul li:first').text(), \"yobaz\", \"change property of sub view\");\n});\n\ntest(\"should work inside a bound {{#if}}\", function() {\n var testData = Ember.A([Ember.Object.create({ isBaz: false }), Ember.Object.create({ isBaz: true }), Ember.Object.create({ isBaz: true })]);\n TemplateTests.ifTestCollectionView = Ember.CollectionView.extend({\n tagName: 'ul',\n content: testData\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#if view.shouldDisplay}}{{#collection \"TemplateTests.ifTestCollectionView\"}}{{content.isBaz}}{{/collection}}{{/if}}'),\n shouldDisplay: true\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('ul li').length, 3, \"renders collection when conditional is true\");\n\n Ember.run(function() { set(view, 'shouldDisplay', false); });\n equal(view.$('ul li').length, 0, \"removes collection when conditional changes to false\");\n\n Ember.run(function() { set(view, 'shouldDisplay', true); });\n equal(view.$('ul li').length, 3, \"collection renders when conditional changes to true\");\n});\n\ntest(\"should pass content as context when using {{#each}} helper\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#each view.releases}}Mac OS X {{version}}: {{name}} {{/each}}'),\n\n releases: Ember.A([\n { version: '10.7',\n name: 'Lion' },\n { version: '10.6',\n name: 'Snow Leopard' },\n { version: '10.5',\n name: 'Leopard' }\n ])\n });\n\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n\n 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\");\n});\n\ntest(\"should re-render when the content object changes\", function() {\n TemplateTests.RerenderTest = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A()\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection TemplateTests.RerenderTest}}{{view.content}}{{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n Ember.run(function() {\n set(firstChild(view), 'content', Ember.A(['bing', 'bat', 'bang']));\n });\n\n Ember.run(function() {\n set(firstChild(view), 'content', Ember.A(['ramalamadingdong']));\n });\n\n equal(view.$('li').length, 1, \"rerenders with correct number of items\");\n equal(trim(view.$('li:eq(0)').text()), \"ramalamadingdong\");\n\n});\n\ntest(\"select tagName on collection helper automatically sets child tagName to option\", function() {\n TemplateTests.RerenderTest = Ember.CollectionView.extend({\n content: Ember.A(['foo'])\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection TemplateTests.RerenderTest tagName=\"select\"}}{{view.content}}{{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('option').length, 1, \"renders the correct child tag name\");\n\n});\n\ntest(\"tagName works in the #collection helper\", function() {\n TemplateTests.RerenderTest = Ember.CollectionView.extend({\n content: Ember.A(['foo', 'bar'])\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection TemplateTests.RerenderTest tagName=\"ol\"}}{{view.content}}{{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('ol').length, 1, \"renders the correct tag name\");\n equal(view.$('li').length, 2, \"rerenders with correct number of items\");\n\n Ember.run(function() {\n set(firstChild(view), 'content', Ember.A(['bing', 'bat', 'bang']));\n });\n\n equal(view.$('li').length, 3, \"rerenders with correct number of items\");\n equal(trim(view.$('li:eq(0)').text()), \"bing\");\n});\n\ntest(\"should render nested collections\", function() {\n\n TemplateTests.InnerList = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A(['one','two','three'])\n });\n\n TemplateTests.OuterList = Ember.CollectionView.extend({\n tagName: 'ul',\n content: Ember.A(['foo'])\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#collection TemplateTests.OuterList class=\"outer\"}}{{content}}{{#collection TemplateTests.InnerList class=\"inner\"}}{{content}}{{/collection}}{{/collection}}')\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('ul.outer > li').length, 1, \"renders the outer list with correct number of items\");\n equal(view.$('ul.inner').length, 1, \"the inner list exsits\");\n equal(view.$('ul.inner > li').length, 3, \"renders the inner list with correct number of items\");\n\n});\n\ntest(\"should render multiple, bound nested collections (#68)\", function() {\n var view;\n\n Ember.run(function() {\n TemplateTests.contentController = Ember.ArrayProxy.create({\n content: Ember.A(['foo','bar'])\n });\n\n TemplateTests.InnerList = Ember.CollectionView.extend({\n tagName: 'ul',\n contentBinding: 'parentView.innerListContent'\n });\n\n TemplateTests.OuterListItem = Ember.View.extend({\n template: Ember.Handlebars.compile('{{#collection TemplateTests.InnerList class=\"inner\"}}{{content}}{{/collection}}{{content}}'),\n innerListContent: Ember.computed(function() {\n return Ember.A([1,2,3]);\n })\n });\n\n TemplateTests.OuterList = Ember.CollectionView.extend({\n tagName: 'ul',\n contentBinding: 'TemplateTests.contentController',\n itemViewClass: TemplateTests.OuterListItem\n });\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{collection TemplateTests.OuterList class=\"outer\"}}')\n });\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('ul.outer > li').length, 2, \"renders the outer list with correct number of items\");\n equal(view.$('ul.inner').length, 2, \"renders the correct number of inner lists\");\n equal(view.$('ul.inner:first > li').length, 3, \"renders the first inner list with correct number of items\");\n equal(view.$('ul.inner:last > li').length, 3, \"renders the second list with correct number of items\");\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\ntest(\"should allow view objects to be swapped out without throwing an error (#78)\", function() {\n var view, dataset, secondDataset;\n\n Ember.run(function() {\n TemplateTests.datasetController = Ember.Object.create();\n\n TemplateTests.ReportingView = Ember.View.extend({\n datasetBinding: 'TemplateTests.datasetController.dataset',\n readyBinding: 'dataset.ready',\n itemsBinding: 'dataset.items',\n template: Ember.Handlebars.compile(\"{{#if view.ready}}{{collection TemplateTests.CollectionView}}{{else}}Loading{{/if}}\")\n });\n\n TemplateTests.CollectionView = Ember.CollectionView.extend({\n contentBinding: 'parentView.items',\n tagName: 'ul',\n template: Ember.Handlebars.compile(\"{{view.content}}\")\n });\n\n view = TemplateTests.ReportingView.create();\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$().text(), \"Loading\", \"renders the loading text when the dataset is not ready\");\n\n Ember.run(function() {\n dataset = Ember.Object.create({\n ready: true,\n items: Ember.A([1,2,3])\n });\n TemplateTests.datasetController.set('dataset',dataset);\n });\n\n equal(view.$('ul > li').length, 3, \"renders the collection with the correct number of items when the dataset is ready\");\n\n Ember.run(function() {\n secondDataset = Ember.Object.create({ready: false});\n TemplateTests.datasetController.set('dataset',secondDataset);\n });\n\n equal(view.$().text(), \"Loading\", \"renders the loading text when the second dataset is not ready\");\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\ntest(\"context should be content\", function() {\n var App, view;\n\n Ember.run(function() {\n lookup.App = App = Ember.Application.create();\n });\n\n App.items = Ember.A([\n Ember.Object.create({name: 'Dave'}),\n Ember.Object.create({name: 'Mary'}),\n Ember.Object.create({name: 'Sara'})\n ]);\n\n App.AnItemView = Ember.View.extend({\n template: Ember.Handlebars.compile(\"Greetings {{name}}\")\n });\n\n App.AView = Ember.View.extend({\n template: Ember.Handlebars.compile('{{collection contentBinding=\"App.items\" itemViewClass=\"App.AnItemView\"}}')\n });\n\n Ember.run(function() {\n view = App.AView.create();\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$().text(), \"Greetings DaveGreetings MaryGreetings Sara\");\n\n Ember.run(function() {\n view.destroy();\n App.destroy();\n });\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/views/collection_view_test");minispade.register('ember-handlebars/~tests/views/metamorph_view_test', "(function() {var view, childView, metamorphView;\n\nmodule(\"Metamorph views\", {\n setup: function() {\n view = Ember.View.create({\n render: function(buffer) {\n buffer.push(\"

    View

    \");\n this.appendChild(metamorphView);\n }\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n if (childView && !childView.isDestroyed) {\n childView.destroy();\n }\n\n if (metamorphView && !metamorphView.isDestroyed) {\n metamorphView.destroy();\n }\n });\n }\n});\n\nvar get = Ember.get, set = Ember.set;\n\ntest(\"a Metamorph view is not a view's parentView\", function() {\n childView = Ember.View.create({\n render: function(buffer) {\n buffer.push(\"

    Bye bros

    \");\n }\n });\n\n metamorphView = Ember._MetamorphView.create({\n render: function(buffer) {\n buffer.push(\"

    Meta

    \");\n this.appendChild(childView);\n }\n });\n\n Ember.run(function() {\n view.appendTo(\"#qunit-fixture\");\n });\n\n equal(get(childView, 'parentView'), view, \"A child of a metamorph view cannot see the metamorph view as its parent\");\n\n var children = get(view, 'childViews');\n\n equal(get(children, 'length'), 1, \"precond - there is only one child of the main node\");\n equal(children.objectAt(0), childView, \"... and it is not the metamorph\");\n});\n\nmodule(\"Metamorph views correctly handle DOM\", {\n setup: function() {\n view = Ember.View.create({\n render: function(buffer) {\n buffer.push(\"

    View

    \");\n this.appendChild(metamorphView);\n }\n });\n\n metamorphView = Ember._MetamorphView.create({\n powerRanger: \"Jason\",\n\n render: function(buffer) {\n buffer.push(\"

    \"+get(this, 'powerRanger')+\"

    \");\n }\n });\n\n Ember.run(function() {\n view.appendTo(\"#qunit-fixture\");\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n if (!metamorphView.isDestroyed) {\n metamorphView.destroy();\n }\n });\n }\n});\n\ntest(\"a metamorph view generates without a DOM node\", function() {\n var meta = Ember.$(\"> h2\", \"#\" + get(view, 'elementId'));\n\n equal(meta.length, 1, \"The metamorph element should be directly inside its parent\");\n});\n\ntest(\"a metamorph view can be removed from the DOM\", function() {\n Ember.run(function() {\n metamorphView.destroy();\n });\n\n var meta = Ember.$('#from-morph');\n equal(meta.length, 0, \"the associated DOM was removed\");\n});\n\ntest(\"a metamorph view can be rerendered\", function() {\n equal(Ember.$('#from-meta').text(), \"Jason\", \"precond - renders to the DOM\");\n\n set(metamorphView, 'powerRanger', 'Trini');\n Ember.run(function() {\n metamorphView.rerender();\n });\n\n equal(Ember.$('#from-meta').text(), \"Trini\", \"updates value when re-rendering\");\n});\n\n\n// Redefining without setup/teardown\nmodule(\"Metamorph views correctly handle DOM\");\n\ntest(\"a metamorph view calls its childrens' willInsertElement and didInsertElement\", function() {\n var parentView;\n var willInsertElementCalled = false;\n var didInsertElementCalled = false;\n var didInsertElementSawElement = false;\n\n parentView = Ember.View.create({\n ViewWithCallback: Ember.View.extend({\n template: Ember.Handlebars.compile('
    '),\n\n willInsertElement: function() {\n willInsertElementCalled = true;\n },\n didInsertElement: function() {\n didInsertElementCalled = true;\n didInsertElementSawElement = (this.$('div').length === 1);\n }\n }),\n\n template: Ember.Handlebars.compile('{{#if view.condition}}{{view \"view.ViewWithCallback\"}}{{/if}}'),\n condition: false\n });\n\n Ember.run(function() {\n parentView.append();\n });\n Ember.run(function() {\n parentView.set('condition', true);\n });\n\n ok(willInsertElementCalled, \"willInsertElement called\");\n ok(didInsertElementCalled, \"didInsertElement called\");\n ok(didInsertElementSawElement, \"didInsertElement saw element\");\n\n Ember.run(function() {\n parentView.destroy();\n });\n\n});\n\ntest(\"replacing a Metamorph should invalidate childView elements\", function() {\n var elementOnDidChange, elementOnDidInsert;\n\n view = Ember.View.create({\n show: false,\n\n CustomView: Ember.View.extend({\n init: function() {\n this._super();\n // This will be called in preRender\n // We want it to cache a null value\n // Hopefully it will be invalidated when `show` is toggled\n this.get('element');\n },\n\n elementDidChange: Ember.observer('element', function() {\n elementOnDidChange = this.get('element');\n }),\n\n didInsertElement: function() {\n elementOnDidInsert = this.get('element');\n }\n }),\n\n template: Ember.Handlebars.compile(\"{{#if view.show}}{{view view.CustomView}}{{/if}}\")\n });\n\n Ember.run(function() { view.append(); });\n\n Ember.run(function() { view.set('show', true); });\n\n ok(elementOnDidChange, \"should have an element on change\");\n ok(elementOnDidInsert, \"should have an element on insert\");\n\n Ember.run(function() { view.destroy(); });\n});\n\ntest(\"trigger rerender of parent and SimpleHandlebarsView\", function () {\n var view = Ember.View.create({\n show: true,\n foo: 'bar',\n template: Ember.Handlebars.compile(\"{{#if view.show}}{{#if view.foo}}{{view.foo}}{{/if}}{{/if}}\")\n });\n\n Ember.run(function() { view.append(); });\n\n equal(view.$().text(), 'bar');\n\n Ember.run(function() {\n view.set('foo', 'baz'); // schedule render of simple bound\n view.set('show', false); // destroy tree\n });\n\n equal(view.$().text(), '');\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\ntest(\"re-rendering and then changing the property does not raise an exception\", function() {\n view = Ember.View.create({\n show: true,\n foo: 'bar',\n metamorphView: Ember._MetamorphView,\n template: Ember.Handlebars.compile(\"{{#view view.metamorphView}}truth{{/view}}\")\n });\n\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n\n equal(view.$().text(), 'truth');\n\n Ember.run(function() {\n view.get('_childViews')[0].rerender();\n view.get('_childViews')[0].rerender();\n });\n\n equal(view.$().text(), 'truth');\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\n})();\n//@ sourceURL=ember-handlebars/~tests/views/metamorph_view_test");minispade.register('ember-metal/~tests/accessors/getPath_test', "(function() {/*globals Foo:true $foo:true */\n\nvar obj, moduleOpts = {\n setup: function() {\n obj = {\n foo: {\n bar: {\n baz: { biff: 'BIFF' }\n }\n },\n falseValue: false\n };\n\n window.Foo = {\n bar: {\n baz: { biff: 'FooBiff' }\n }\n };\n\n window.$foo = {\n bar: {\n baz: { biff: '$FOOBIFF' }\n }\n };\n },\n\n teardown: function() {\n obj = undefined;\n window.Foo = undefined;\n window.$foo = undefined;\n }\n};\n\nmodule('Ember.get with path', moduleOpts);\n\n// ..........................................................\n// LOCAL PATHS\n//\n\ntest('[obj, foo] -> obj.foo', function() {\n deepEqual(Ember.get(obj, 'foo'), obj.foo);\n});\n\ntest('[obj, foo.bar] -> obj.foo.bar', function() {\n deepEqual(Ember.get(obj, 'foo.bar'), obj.foo.bar);\n});\n\ntest('[obj, this.foo] -> obj.foo', function() {\n deepEqual(Ember.get(obj, 'this.foo'), obj.foo);\n});\n\ntest('[obj, this.foo.bar] -> obj.foo.bar', function() {\n deepEqual(Ember.get(obj, 'this.foo.bar'), obj.foo.bar);\n});\n\ntest('[obj, this.Foo.bar] -> (null)', function() {\n deepEqual(Ember.get(obj, 'this.Foo.bar'), undefined);\n});\n\ntest('[obj, falseValue.notDefined] -> (null)', function() {\n deepEqual(Ember.get(obj, 'falseValue.notDefined'), undefined);\n});\n\n// ..........................................................\n// NO TARGET\n//\n\ntest('[null, Foo] -> Foo', function() {\n deepEqual(Ember.get('Foo'), Foo);\n});\n\ntest('[null, Foo.bar] -> Foo.bar', function() {\n deepEqual(Ember.get('Foo.bar'), Foo.bar);\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/accessors/getPath_test");minispade.register('ember-metal/~tests/accessors/getProperties_test', "(function() {module('Ember.getProperties');\n\ntest('can retrieve a hash of properties from an object via an argument list or array of property names', function() {\n var obj = {\n firstName: \"Steve\",\n lastName: \"Jobs\",\n companyName: \"Apple, Inc.\"\n };\n\n var getProperties = Ember.getProperties;\n deepEqual(getProperties(obj, \"firstName\", \"lastName\"), { firstName: 'Steve', lastName: 'Jobs' });\n deepEqual(getProperties(obj, \"firstName\", \"lastName\"), { firstName: 'Steve', lastName: 'Jobs' });\n deepEqual(getProperties(obj, \"lastName\"), { lastName: 'Jobs' });\n deepEqual(getProperties(obj), {});\n deepEqual(getProperties(obj, [\"firstName\", \"lastName\"]), { firstName: 'Steve', lastName: 'Jobs' });\n deepEqual(getProperties(obj, [\"firstName\"]), { firstName: 'Steve' });\n deepEqual(getProperties(obj, []), {});\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/accessors/getProperties_test");minispade.register('ember-metal/~tests/accessors/get_test', "(function() {minispade.require('ember-metal/~tests/props_helper');\n\nmodule('Ember.get');\n\ntest('should get arbitrary properties on an object', function() {\n var obj = {\n string: 'string',\n number: 23,\n boolTrue: true,\n boolFalse: false,\n nullValue: null\n };\n\n for(var key in obj) {\n if (!obj.hasOwnProperty(key)) continue;\n equal(Ember.get(obj, key), obj[key], key);\n }\n\n});\n\ntestBoth(\"should call unknownProperty on watched values if the value is undefined\", function(get, set) {\n var obj = {\n count: 0,\n unknownProperty: function(key) {\n equal(key, 'foo', \"should pass key\");\n this.count++;\n return \"FOO\";\n }\n };\n\n var count = 0;\n Ember.addObserver(obj, 'foo', function() {\n count++;\n });\n\n equal(get(obj, 'foo'), 'FOO', 'should return value from unknown');\n});\n\ntest('warn on attempts to get a property of undefined', function() {\n expectAssertion(function() {\n Ember.get(undefined, 'aProperty');\n }, /Cannot call get with 'aProperty' on an undefined object/i);\n});\n\ntest('warn on attempts to get a property path of undefined', function() {\n expectAssertion(function() {\n Ember.get(undefined, 'aProperty.on.aPath');\n }, /Cannot call get with 'aProperty.on.aPath' on an undefined object/);\n});\n\ntest('warn on attemps to get a falsy property', function() {\n var obj = {};\n expectAssertion(function() {\n Ember.get(obj, null);\n }, /Cannot call get with null key/);\n expectAssertion(function() {\n Ember.get(obj, NaN);\n }, /Cannot call get with NaN key/);\n expectAssertion(function() {\n Ember.get(obj, undefined);\n }, /Cannot call get with undefined key/);\n expectAssertion(function() {\n Ember.get(obj, false);\n }, /Cannot call get with false key/);\n});\n\n// ..........................................................\n// BUGS\n//\n\ntest('(regression) watched properties on unmodified inherited objects should still return their original value', function() {\n\n var MyMixin = Ember.Mixin.create({\n someProperty: 'foo',\n propertyDidChange: Ember.observer('someProperty', function() {\n // NOTHING TO DO\n })\n });\n\n var baseObject = MyMixin.apply({});\n var theRealObject = Ember.create(baseObject);\n\n equal(Ember.get(theRealObject, 'someProperty'), 'foo', 'should return the set value, not false');\n});\n\nmodule(\"Ember.getWithDefault\");\n\ntest('should get arbitrary properties on an object', function() {\n var obj = {\n string: 'string',\n number: 23,\n boolTrue: true,\n boolFalse: false,\n nullValue: null\n };\n\n for(var key in obj) {\n if (!obj.hasOwnProperty(key)) continue;\n equal(Ember.getWithDefault(obj, key, \"fail\"), obj[key], key);\n }\n\n obj = {\n undef: undefined\n };\n\n equal(Ember.getWithDefault(obj, \"undef\", \"default\"), \"default\", \"explicit undefined retrieves the default\");\n equal(Ember.getWithDefault(obj, \"not-present\", \"default\"), \"default\", \"non-present key retrieves the default\");\n});\n\ntest('should call unknownProperty if defined and value is undefined', function() {\n\n var obj = {\n count: 0,\n unknownProperty: function(key) {\n equal(key, 'foo', 'should pass key');\n this.count++;\n return 'FOO';\n }\n };\n\n equal(Ember.get(obj, 'foo'), 'FOO', 'should return value from unknown');\n equal(obj.count, 1, 'should have invoked');\n});\n\ntestBoth(\"if unknownProperty is present, it is called\", function(get, set) {\n var obj = {\n count: 0,\n unknownProperty: function(key) {\n if (key === \"foo\") {\n equal(key, 'foo', \"should pass key\");\n this.count++;\n return \"FOO\";\n }\n }\n };\n\n var count = 0;\n Ember.addObserver(obj, 'foo', function() {\n count++;\n });\n\n equal(Ember.getWithDefault(obj, 'foo', \"fail\"), 'FOO', 'should return value from unknownProperty');\n equal(Ember.getWithDefault(obj, 'bar', \"default\"), 'default', 'should convert undefined from unknownProperty into default');\n});\n\n// ..........................................................\n// BUGS\n//\n\ntest('(regression) watched properties on unmodified inherited objects should still return their original value', function() {\n\n var MyMixin = Ember.Mixin.create({\n someProperty: 'foo',\n propertyDidChange: Ember.observer('someProperty', function() {\n // NOTHING TO DO\n })\n });\n\n var baseObject = MyMixin.apply({});\n var theRealObject = Ember.create(baseObject);\n\n equal(Ember.getWithDefault(theRealObject, 'someProperty', \"fail\"), 'foo', 'should return the set value, not false');\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/accessors/get_test");minispade.register('ember-metal/~tests/accessors/isGlobalPath_test', "(function() {module('Ember.isGlobalPath');\n\ntest(\"global path's are recognized\", function() {\n ok( Ember.isGlobalPath('App.myProperty') );\n ok( Ember.isGlobalPath('App.myProperty.subProperty') );\n});\n\ntest(\"if there is a 'this' in the path, it's not a global path\", function() {\n ok( !Ember.isGlobalPath('this.myProperty') );\n ok( !Ember.isGlobalPath('this') );\n});\n\ntest(\"if the path starts with a lowercase character, it is not a global path\", function() {\n ok( !Ember.isGlobalPath('myObj') );\n ok( !Ember.isGlobalPath('myObj.SecondProperty') );\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/accessors/isGlobalPath_test");minispade.register('ember-metal/~tests/accessors/normalizeTuple_test', "(function() {/*globals Foo:true $foo:true */\n\nvar obj, moduleOpts = {\n setup: function() {\n obj = {\n foo: {\n bar: {\n baz: {}\n }\n }\n };\n\n window.Foo = {\n bar: {\n baz: {}\n }\n };\n\n window.$foo = {\n bar: {\n baz: {}\n }\n };\n },\n\n teardown: function() {\n obj = undefined;\n window.Foo = undefined;\n window.$foo = undefined;\n }\n};\n\nmodule('Ember.normalizeTuple', moduleOpts);\n\n// ..........................................................\n// LOCAL PATHS\n//\n\ntest('[obj, foo] -> [obj, foo]', function() {\n deepEqual(Ember.normalizeTuple(obj, 'foo'), [obj, 'foo']);\n});\n\ntest('[obj, *] -> [obj, *]', function() {\n deepEqual(Ember.normalizeTuple(obj, '*'), [obj, '*']);\n});\n\ntest('[obj, foo.bar] -> [obj, foo.bar]', function() {\n deepEqual(Ember.normalizeTuple(obj, 'foo.bar'), [obj, 'foo.bar']);\n});\n\ntest('[obj, foo.*] -> [obj, foo.*]', function() {\n deepEqual(Ember.normalizeTuple(obj, 'foo.*'), [obj, 'foo.*']);\n});\n\ntest('[obj, foo.*.baz] -> [obj, foo.*.baz]', function() {\n deepEqual(Ember.normalizeTuple(obj, 'foo.*.baz'), [obj, 'foo.*.baz']);\n});\n\ntest('[obj, this.foo] -> [obj, foo]', function() {\n deepEqual(Ember.normalizeTuple(obj, 'this.foo'), [obj, 'foo']);\n});\n\ntest('[obj, this.foo.bar] -> [obj, foo.bar]', function() {\n deepEqual(Ember.normalizeTuple(obj, 'this.foo.bar'), [obj, 'foo.bar']);\n});\n\ntest('[obj, this.Foo.bar] -> [obj, Foo.bar]', function() {\n deepEqual(Ember.normalizeTuple(obj, 'this.Foo.bar'), [obj, 'Foo.bar']);\n});\n\n// ..........................................................\n// GLOBAL PATHS\n//\n\ntest('[obj, Foo] -> [obj, Foo]', function() {\n deepEqual(Ember.normalizeTuple(obj, 'Foo'), [obj, 'Foo']);\n});\n\ntest('[obj, Foo.bar] -> [Foo, bar]', function() {\n deepEqual(Ember.normalizeTuple(obj, 'Foo.bar'), [Foo, 'bar']);\n});\n\ntest('[obj, $foo.bar.baz] -> [$foo, bar.baz]', function() {\n deepEqual(Ember.normalizeTuple(obj, '$foo.bar.baz'), [$foo, 'bar.baz']);\n});\n\n// ..........................................................\n// NO TARGET\n//\n\ntest('[null, Foo] -> EXCEPTION', function() {\n raises(function() {\n Ember.normalizeTuple(null, 'Foo');\n }, Error);\n});\n\ntest('[null, Foo.bar] -> [Foo, bar]', function() {\n deepEqual(Ember.normalizeTuple(null, 'Foo.bar'), [Foo, 'bar']);\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/accessors/normalizeTuple_test");minispade.register('ember-metal/~tests/accessors/setPath_test', "(function() {var originalLookup = Ember.lookup;\n\nvar obj, moduleOpts = {\n setup: function() {\n obj = {\n foo: {\n bar: {\n baz: { biff: 'BIFF' }\n }\n }\n\n };\n\n Ember.lookup = {\n Foo: {\n bar: {\n baz: { biff: 'FooBiff' }\n }\n },\n\n $foo: {\n bar: {\n baz: { biff: '$FOOBIFF' }\n }\n }\n };\n },\n\n teardown: function() {\n obj = null;\n Ember.lookup = originalLookup;\n }\n};\n\nmodule('Ember.set with path', moduleOpts);\n\ntest('[Foo, bar] -> Foo.bar', function() {\n Ember.lookup.Foo = {toString: function() { return 'Foo'; }}; // Behave like an Ember.Namespace\n\n Ember.set(Ember.lookup.Foo, 'bar', 'baz');\n equal(Ember.get(Ember.lookup.Foo, 'bar'), 'baz');\n});\n\n// ..........................................................\n// LOCAL PATHS\n//\n\ntest('[obj, foo] -> obj.foo', function() {\n Ember.set(obj, 'foo', \"BAM\");\n equal(Ember.get(obj, 'foo'), \"BAM\");\n});\n\ntest('[obj, foo.bar] -> obj.foo.bar', function() {\n Ember.set(obj, 'foo.bar', \"BAM\");\n equal(Ember.get(obj, 'foo.bar'), \"BAM\");\n});\n\ntest('[obj, this.foo] -> obj.foo', function() {\n Ember.set(obj, 'this.foo', \"BAM\");\n equal(Ember.get(obj, 'foo'), \"BAM\");\n});\n\ntest('[obj, this.foo.bar] -> obj.foo.bar', function() {\n Ember.set(obj, 'this.foo.bar', \"BAM\");\n equal(Ember.get(obj, 'foo.bar'), \"BAM\");\n});\n\n// ..........................................................\n// NO TARGET\n//\n\ntest('[null, Foo.bar] -> Foo.bar', function() {\n Ember.set(null, 'Foo.bar', \"BAM\");\n equal(Ember.get(Ember.lookup.Foo, 'bar'), \"BAM\");\n});\n\n// ..........................................................\n// DEPRECATED\n//\n\nmodule(\"Ember.set with path - deprecated\", {\n setup: function() {\n Ember.TESTING_DEPRECATION = true;\n moduleOpts.setup();\n },\n teardown: function() {\n Ember.TESTING_DEPRECATION = false;\n moduleOpts.teardown();\n }\n});\n\ntest('[obj, foo.baz.bat] -> EXCEPTION', function() {\n raises(function() {\n Ember.set(obj, 'foo.baz.bat', \"BAM\");\n }, Error);\n});\n\ntest('[obj, foo.baz.bat] -> EXCEPTION', function() {\n Ember.trySet(obj, 'foo.baz.bat', \"BAM\");\n ok(true, \"does not raise\");\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/accessors/setPath_test");minispade.register('ember-metal/~tests/accessors/set_test', "(function() {module('Ember.set');\n\ntest('should set arbitrary properties on an object', function() {\n var obj = {\n string: 'string',\n number: 23,\n boolTrue: true,\n boolFalse: false,\n nullValue: null\n };\n\n var newObj = {};\n\n for(var key in obj) {\n if (!obj.hasOwnProperty(key)) continue;\n equal(Ember.set(newObj, key, obj[key]), obj[key], 'should return value');\n equal(Ember.get(newObj, key), obj[key], 'should set value');\n }\n\n});\n\ntest('should call setUnknownProperty if defined and value is undefined', function() {\n\n var obj = {\n count: 0,\n\n unknownProperty: function(key, value) {\n ok(false, 'should not invoke unknownProperty if setUnknownProperty is defined');\n },\n\n setUnknownProperty: function(key, value) {\n equal(key, 'foo', 'should pass key');\n equal(value, 'BAR', 'should pass key');\n this.count++;\n return 'FOO';\n }\n };\n\n equal(Ember.set(obj, 'foo', \"BAR\"), 'BAR', 'should return set value');\n equal(obj.count, 1, 'should have invoked');\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/accessors/set_test");minispade.register('ember-metal/~tests/binding/connect_test', "(function() {/*globals GlobalA:true GlobalB:true */\nminispade.require('ember-metal/~tests/props_helper');\n\nfunction performTest(binding, a, b, get, set, connect) {\n if (connect === undefined) connect = function() {binding.connect(a);};\n\n ok(!Ember.run.currentRunLoop, 'performTest should not have a currentRunLoop');\n\n equal(get(a, 'foo'), 'FOO', 'a should not have changed');\n equal(get(b, 'bar'), 'BAR', 'b should not have changed');\n\n connect();\n\n equal(get(a, 'foo'), 'BAR', 'a should have changed');\n equal(get(b, 'bar'), 'BAR', 'b should have changed');\n //\n // make sure changes sync both ways\n Ember.run(function () {\n set(b, 'bar', 'BAZZ');\n });\n equal(get(a, 'foo'), 'BAZZ', 'a should have changed');\n\n Ember.run(function () {\n set(a, 'foo', 'BARF');\n });\n equal(get(b, 'bar'), 'BARF', 'a should have changed');\n}\n\nmodule(\"Ember.Binding\");\n\ntestBoth('Connecting a binding between two properties', function(get, set) {\n var a = { foo: 'FOO', bar: 'BAR' };\n\n // a.bar -> a.foo\n var binding = new Ember.Binding('foo', 'bar');\n\n performTest(binding, a, a, get, set);\n});\n\ntestBoth('Connecting a binding between two objects', function(get, set) {\n var b = { bar: 'BAR' };\n var a = { foo: 'FOO', b: b };\n\n // b.bar -> a.foo\n var binding = new Ember.Binding('foo', 'b.bar');\n\n performTest(binding, a, b, get, set);\n});\n\ntestBoth('Connecting a binding to path', function(get, set) {\n var a = { foo: 'FOO' };\n GlobalB = {\n b: { bar: 'BAR' }\n };\n\n var b = get(GlobalB, 'b');\n\n // globalB.b.bar -> a.foo\n var binding = new Ember.Binding('foo', 'GlobalB.b.bar');\n\n performTest(binding, a, b, get, set);\n\n // make sure modifications update\n b = { bar: 'BIFF' };\n\n Ember.run(function() {\n set(GlobalB, 'b', b);\n });\n\n equal(get(a, 'foo'), 'BIFF', 'a should have changed');\n\n});\n\ntestBoth('Calling connect more than once', function(get, set) {\n var b = { bar: 'BAR' };\n var a = { foo: 'FOO', b: b };\n\n // b.bar -> a.foo\n var binding = new Ember.Binding('foo', 'b.bar');\n\n performTest(binding, a, b, get, set, function () {\n binding.connect(a);\n\n binding.connect(a);\n });\n});\n\ntestBoth('Bindings should be inherited', function(get, set) {\n\n var a = { foo: 'FOO', b: { bar: 'BAR' } };\n var binding = new Ember.Binding('foo', 'b.bar');\n var a2;\n\n Ember.run(function () {\n binding.connect(a);\n\n a2 = Ember.create(a);\n Ember.rewatch(a2);\n });\n\n equal(get(a2, 'foo'), \"BAR\", \"Should have synced binding on child\");\n equal(get(a, 'foo'), \"BAR\", \"Should NOT have synced binding on parent\");\n\n Ember.run(function () {\n set(a2, 'b', { bar: 'BAZZ' });\n });\n\n equal(get(a2, 'foo'), \"BAZZ\", \"Should have synced binding on child\");\n equal(get(a, 'foo'), \"BAR\", \"Should NOT have synced binding on parent\");\n\n});\n\ntest('inherited bindings should sync on create', function() {\n var a;\n Ember.run(function () {\n var A = function() {\n Ember.bind(this, 'foo', 'bar.baz');\n };\n\n a = new A();\n Ember.set(a, 'bar', { baz: 'BAZ' });\n });\n\n equal(Ember.get(a, 'foo'), 'BAZ', 'should have synced binding on new obj');\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/binding/connect_test");minispade.register('ember-metal/~tests/binding/oneWay_test', "(function() {/*globals MyApp:true */\n\nmodule('system/mixin/binding/oneWay_test', {\n setup: function() {\n MyApp = {\n foo: { value: 'FOO' },\n bar: { value: 'BAR' }\n };\n },\n\n teardown: function() {\n MyApp = null;\n }\n});\n\ntest('oneWay(true) should only sync one way', function() {\n var binding;\n Ember.run(function() {\n binding = Ember.oneWay(MyApp, 'bar.value', 'foo.value');\n });\n\n equal(Ember.get('MyApp.foo.value'), 'FOO', 'foo synced');\n equal(Ember.get('MyApp.bar.value'), 'FOO', 'bar synced');\n\n Ember.run(function() {\n Ember.set('MyApp.bar.value', 'BAZ');\n });\n\n equal(Ember.get('MyApp.foo.value'), 'FOO', 'foo synced');\n equal(Ember.get('MyApp.bar.value'), 'BAZ', 'bar not synced');\n\n Ember.run(function() {\n Ember.set('MyApp.foo.value', 'BIFF');\n });\n\n equal(Ember.get('MyApp.foo.value'), 'BIFF', 'foo synced');\n equal(Ember.get('MyApp.bar.value'), 'BIFF', 'foo synced');\n\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/binding/oneWay_test");minispade.register('ember-metal/~tests/binding/sync_test', "(function() {module(\"system/binding/sync_test.js\");\n\ntestBoth(\"bindings should not sync twice in a single run loop\", function(get, set) {\n var a, b, setValue, setCalled=0, getCalled=0;\n\n Ember.run(function() {\n a = {};\n\n Ember.defineProperty(a, 'foo', Ember.computed(function(key, value) {\n if (arguments.length === 2) {\n setCalled++;\n setValue = value;\n return value;\n } else {\n getCalled++;\n return setValue;\n }\n }).volatile());\n\n b = {\n a: a\n };\n Ember.bind(b, 'foo', 'a.foo');\n });\n\n // reset after initial binding synchronization\n getCalled = 0;\n\n Ember.run(function() {\n set(a, 'foo', 'trollface');\n });\n\n equal(get(b, 'foo'), \"trollface\", \"the binding should sync\");\n equal(setCalled, 1, \"Set should only be called once\");\n equal(getCalled, 1, \"Get should only be called once\");\n});\n\ntestBoth(\"bindings should not infinite loop if computed properties return objects\", function(get, set) {\n var a, b, getCalled=0;\n\n Ember.run(function() {\n a = {};\n\n Ember.defineProperty(a, 'foo', Ember.computed(function() {\n getCalled++;\n if (getCalled > 1000) {\n throw 'infinite loop detected';\n }\n return ['foo', 'bar'];\n }));\n\n b = {\n a: a\n };\n Ember.bind(b, 'foo', 'a.foo');\n });\n\n deepEqual(get(b, 'foo'), ['foo', 'bar'], \"the binding should sync\");\n equal(getCalled, 1, \"Get should only be called once\");\n});\n\ntestBoth(\"bindings should do the right thing when observers trigger bindings in the opposite direction\", function(get, set) {\n var a, b, c;\n\n Ember.run(function() {\n a = {\n foo: 'trololol'\n };\n\n b = {\n a: a\n };\n Ember.bind(b, 'foo', 'a.foo');\n\n c = {\n a: a\n };\n Ember.bind(c, 'foo', 'a.foo');\n });\n\n Ember.addObserver(b, 'foo', function() {\n set(c, 'foo', \"what is going on\");\n });\n\n Ember.run(function() {\n set(a, 'foo', 'trollface');\n });\n\n equal(get(a, 'foo'), \"what is going on\");\n});\n\ntestBoth(\"bindings should do the right thing when binding is in prototype\", function(get, set) {\n var obj, proto, a, b, selectionChanged;\n Ember.run(function() {\n obj = {\n selection: null\n };\n\n selectionChanged = 0;\n\n Ember.addObserver(obj, 'selection', function () {\n selectionChanged++;\n });\n\n proto = {\n obj: obj,\n changeSelection: function (value) {\n set(this, 'selection', value);\n }\n };\n Ember.bind(proto, 'selection', 'obj.selection');\n\n a = Ember.create(proto);\n b = Ember.create(proto);\n Ember.rewatch(a);\n Ember.rewatch(b);\n });\n\n Ember.run(function () {\n set(a, 'selection', 'a');\n });\n\n Ember.run(function () {\n set(b, 'selection', 'b');\n });\n\n Ember.run(function () {\n set(a, 'selection', 'a');\n });\n\n equal(selectionChanged, 3);\n equal(get(obj, 'selection'), 'a');\n});\n\ntestBoth(\"bindings should not try to sync destroyed objects\", function(get, set) {\n var a, b;\n\n Ember.run(function() {\n a = {\n foo: 'trololol'\n };\n\n b = {\n a: a\n };\n Ember.bind(b, 'foo', 'a.foo');\n });\n\n Ember.run(function() {\n set(a, 'foo', 'trollface');\n set(b, 'isDestroyed', true);\n ok(true, \"should not raise\");\n });\n\n Ember.run(function() {\n a = {\n foo: 'trololol'\n };\n\n b = {\n a: a\n };\n Ember.bind(b, 'foo', 'a.foo');\n });\n\n Ember.run(function() {\n set(b, 'foo', 'trollface');\n set(a, 'isDestroyed', true);\n ok(true, \"should not raise\");\n });\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/binding/sync_test");minispade.register('ember-metal/~tests/computed_test', "(function() {/*globals Global:true */\nminispade.require('ember-metal/~tests/props_helper');\n\nvar obj, count;\n\nmodule('Ember.computed');\n\ntest('computed property should be an instance of descriptor', function() {\n ok(Ember.computed(function() {}) instanceof Ember.Descriptor);\n});\n\ntest('defining computed property should invoke property on get', function() {\n\n var obj = {};\n var count = 0;\n Ember.defineProperty(obj, 'foo', Ember.computed(function(key) {\n count++;\n return 'computed '+key;\n }));\n\n equal(Ember.get(obj, 'foo'), 'computed foo', 'should return value');\n equal(count, 1, 'should have invoked computed property');\n});\n\ntest('defining computed property should invoke property on set', function() {\n\n var obj = {};\n var count = 0;\n Ember.defineProperty(obj, 'foo', Ember.computed(function(key, value) {\n if (value !== undefined) {\n count++;\n this['__'+key] = 'computed '+value;\n }\n return this['__'+key];\n }));\n\n equal(Ember.set(obj, 'foo', 'bar'), 'bar', 'should return set value');\n equal(count, 1, 'should have invoked computed property');\n equal(Ember.get(obj, 'foo'), 'computed bar', 'should return new value');\n});\n\nvar objA, objB;\nmodule('Ember.computed should inherit through prototype', {\n setup: function() {\n objA = { __foo: 'FOO' } ;\n Ember.defineProperty(objA, 'foo', Ember.computed(function(key, value) {\n if (value !== undefined) {\n this['__'+key] = 'computed '+value;\n }\n return this['__'+key];\n }));\n\n objB = Ember.create(objA);\n objB.__foo = 'FOO'; // make a copy;\n },\n\n teardown: function() {\n objA = objB = null;\n }\n});\n\ntestBoth('using get() and set()', function(get, set) {\n equal(get(objA, 'foo'), 'FOO', 'should get FOO from A');\n equal(get(objB, 'foo'), 'FOO', 'should get FOO from B');\n\n set(objA, 'foo', 'BIFF');\n equal(get(objA, 'foo'), 'computed BIFF', 'should change A');\n equal(get(objB, 'foo'), 'FOO', 'should NOT change B');\n\n set(objB, 'foo', 'bar');\n equal(get(objB, 'foo'), 'computed bar', 'should change B');\n equal(get(objA, 'foo'), 'computed BIFF', 'should NOT change A');\n\n set(objA, 'foo', 'BAZ');\n equal(get(objA, 'foo'), 'computed BAZ', 'should change A');\n equal(get(objB, 'foo'), 'computed bar', 'should NOT change B');\n});\n\nmodule('redefining computed property to normal', {\n setup: function() {\n objA = { __foo: 'FOO' } ;\n Ember.defineProperty(objA, 'foo', Ember.computed(function(key, value) {\n if (value !== undefined) {\n this['__'+key] = 'computed '+value;\n }\n return this['__'+key];\n }));\n\n objB = Ember.create(objA);\n Ember.defineProperty(objB, 'foo'); // make this just a normal property.\n },\n\n teardown: function() {\n objA = objB = null;\n }\n});\n\ntestBoth('using get() and set()', function(get, set) {\n equal(get(objA, 'foo'), 'FOO', 'should get FOO from A');\n equal(get(objB, 'foo'), undefined, 'should get undefined from B');\n\n set(objA, 'foo', 'BIFF');\n equal(get(objA, 'foo'), 'computed BIFF', 'should change A');\n equal(get(objB, 'foo'), undefined, 'should NOT change B');\n\n set(objB, 'foo', 'bar');\n equal(get(objB, 'foo'), 'bar', 'should change B');\n equal(get(objA, 'foo'), 'computed BIFF', 'should NOT change A');\n\n set(objA, 'foo', 'BAZ');\n equal(get(objA, 'foo'), 'computed BAZ', 'should change A');\n equal(get(objB, 'foo'), 'bar', 'should NOT change B');\n});\n\nmodule('redefining computed property to another property', {\n setup: function() {\n objA = { __foo: 'FOO' } ;\n Ember.defineProperty(objA, 'foo', Ember.computed(function(key, value) {\n if (value !== undefined) {\n this['__'+key] = 'A '+value;\n }\n return this['__'+key];\n }));\n\n objB = Ember.create(objA);\n objB.__foo = 'FOO';\n Ember.defineProperty(objB, 'foo', Ember.computed(function(key, value) {\n if (value !== undefined) {\n this['__'+key] = 'B '+value;\n }\n return this['__'+key];\n }));\n },\n\n teardown: function() {\n objA = objB = null;\n }\n});\n\ntestBoth('using get() and set()', function(get, set) {\n equal(get(objA, 'foo'), 'FOO', 'should get FOO from A');\n equal(get(objB, 'foo'), 'FOO', 'should get FOO from B');\n\n set(objA, 'foo', 'BIFF');\n equal(get(objA, 'foo'), 'A BIFF', 'should change A');\n equal(get(objB, 'foo'), 'FOO', 'should NOT change B');\n\n set(objB, 'foo', 'bar');\n equal(get(objB, 'foo'), 'B bar', 'should change B');\n equal(get(objA, 'foo'), 'A BIFF', 'should NOT change A');\n\n set(objA, 'foo', 'BAZ');\n equal(get(objA, 'foo'), 'A BAZ', 'should change A');\n equal(get(objB, 'foo'), 'B bar', 'should NOT change B');\n});\n\nmodule('Ember.computed - metadata');\n\ntest(\"can set metadata on a computed property\", function() {\n var computedProperty = Ember.computed(function() { });\n computedProperty.meta({ key: 'keyValue' });\n\n equal(computedProperty.meta().key, 'keyValue', \"saves passed meta hash to the _meta property\");\n});\n\ntest(\"meta should return an empty hash if no meta is set\", function() {\n var computedProperty = Ember.computed(function() { });\n deepEqual(computedProperty.meta(), {}, \"returned value is an empty hash\");\n});\n\n// ..........................................................\n// CACHEABLE\n//\n\nmodule('Ember.computed - cacheable', {\n setup: function() {\n obj = {};\n count = 0;\n Ember.defineProperty(obj, 'foo', Ember.computed(function(key, value) {\n count++;\n return 'bar '+count;\n }));\n },\n\n teardown: function() {\n obj = count = null;\n }\n});\n\ntestBoth('cacheable should cache', function(get, set) {\n equal(get(obj, 'foo'), 'bar 1', 'first get');\n equal(get(obj, 'foo'), 'bar 1', 'second get');\n equal(count, 1, 'should only invoke once');\n});\n\ntestBoth('modifying a cacheable property should update cache', function(get, set) {\n equal(get(obj, 'foo'), 'bar 1', 'first get');\n equal(get(obj, 'foo'), 'bar 1', 'second get');\n\n equal(set(obj, 'foo', 'baz'), 'baz', 'setting');\n equal(get(obj, 'foo'), 'bar 2', 'third get');\n equal(count, 2, 'should not invoke again');\n});\n\ntestBoth('inherited property should not pick up cache', function(get, set) {\n var objB = Ember.create(obj);\n\n equal(get(obj, 'foo'), 'bar 1', 'obj first get');\n equal(get(objB, 'foo'), 'bar 2', 'objB first get');\n\n equal(get(obj, 'foo'), 'bar 1', 'obj second get');\n equal(get(objB, 'foo'), 'bar 2', 'objB second get');\n\n set(obj, 'foo', 'baz'); // modify A\n equal(get(obj, 'foo'), 'bar 3', 'obj third get');\n equal(get(objB, 'foo'), 'bar 2', 'objB third get');\n});\n\ntestBoth('cacheFor should return the cached value', function(get, set) {\n equal(Ember.cacheFor(obj, 'foo'), undefined, \"should not yet be a cached value\");\n\n get(obj, 'foo');\n\n equal(Ember.cacheFor(obj, 'foo'), \"bar 1\", \"should retrieve cached value\");\n});\n\ntestBoth('cacheFor should return falsy cached values', function(get, set) {\n\n Ember.defineProperty(obj, 'falsy', Ember.computed(function() {\n return false;\n }));\n\n equal(Ember.cacheFor(obj, 'falsy'), undefined, \"should not yet be a cached value\");\n\n get(obj, 'falsy');\n\n equal(Ember.cacheFor(obj, 'falsy'), false, \"should retrieve cached value\");\n});\n\ntestBoth(\"setting a cached computed property passes the old value as the third argument\", function(get, set) {\n var obj = {\n foo: 0\n };\n\n var receivedOldValue;\n\n Ember.defineProperty(obj, 'plusOne', Ember.computed(\n function(key, value, oldValue) {\n receivedOldValue = oldValue;\n return value;\n }).property('foo')\n );\n\n set(obj, 'plusOne', 1);\n strictEqual(receivedOldValue, undefined, \"oldValue should be undefined\");\n\n set(obj, 'plusOne', 2);\n strictEqual(receivedOldValue, 1, \"oldValue should be 1\");\n\n set(obj, 'plusOne', 3);\n strictEqual(receivedOldValue, 2, \"oldValue should be 2\");\n});\n\ntestBoth(\"the old value is only passed in if the computed property specifies three arguments\", function(get, set) {\n var obj = {\n foo: 0\n };\n\n var receivedOldValue;\n\n Ember.defineProperty(obj, 'plusOne', Ember.computed(\n function(key, value) {\n equal(arguments.length, 2, \"computed property is only invoked with two arguments\");\n return value;\n }).property('foo')\n );\n\n set(obj, 'plusOne', 1);\n set(obj, 'plusOne', 2);\n set(obj, 'plusOne', 3);\n});\n\n// ..........................................................\n// DEPENDENT KEYS\n//\n\nmodule('Ember.computed - dependentkey', {\n setup: function() {\n obj = { bar: 'baz' };\n count = 0;\n Ember.defineProperty(obj, 'foo', Ember.computed(function(key, value) {\n count++;\n Ember.get(this, 'bar');\n return 'bar '+count;\n }).property('bar'));\n },\n\n teardown: function() {\n obj = count = null;\n }\n});\n\ntestBoth('should lazily watch dependent keys on set', function (get, set) {\n equal(Ember.isWatching(obj, 'bar'), false, 'precond not watching dependent key');\n set(obj, 'foo', 'bar');\n equal(Ember.isWatching(obj, 'bar'), true, 'lazily watching dependent key');\n});\n\ntestBoth('should lazily watch dependent keys on get', function (get, set) {\n equal(Ember.isWatching(obj, 'bar'), false, 'precond not watching dependent key');\n get(obj, 'foo');\n equal(Ember.isWatching(obj, 'bar'), true, 'lazily watching dependent key');\n});\n\ntestBoth('local dependent key should invalidate cache', function(get, set) {\n equal(Ember.isWatching(obj, 'bar'), false, 'precond not watching dependent key');\n equal(get(obj, 'foo'), 'bar 1', 'get once');\n equal(Ember.isWatching(obj, 'bar'), true, 'lazily setup watching dependent key');\n equal(get(obj, 'foo'), 'bar 1', 'cached retrieve');\n\n set(obj, 'bar', 'BIFF'); // should invalidate foo\n\n equal(get(obj, 'foo'), 'bar 2', 'should recache');\n equal(get(obj, 'foo'), 'bar 2', 'cached retrieve');\n});\n\ntestBoth('should invalidate multiple nested dependent keys', function(get, set) {\n var count = 0;\n Ember.defineProperty(obj, 'bar', Ember.computed(function() {\n count++;\n get(this, 'baz');\n return 'baz '+count;\n }).property('baz'));\n\n equal(Ember.isWatching(obj, 'bar'), false, 'precond not watching dependent key');\n equal(Ember.isWatching(obj, 'baz'), false, 'precond not watching dependent key');\n equal(get(obj, 'foo'), 'bar 1', 'get once');\n equal(Ember.isWatching(obj, 'bar'), true, 'lazily setup watching dependent key');\n equal(Ember.isWatching(obj, 'baz'), true, 'lazily setup watching dependent key');\n equal(get(obj, 'foo'), 'bar 1', 'cached retrieve');\n\n set(obj, 'baz', 'BIFF'); // should invalidate bar -> foo\n equal(Ember.isWatching(obj, 'bar'), false, 'should not be watching dependent key after cache cleared');\n equal(Ember.isWatching(obj, 'baz'), false, 'should not be watching dependent key after cache cleared');\n\n equal(get(obj, 'foo'), 'bar 2', 'should recache');\n equal(get(obj, 'foo'), 'bar 2', 'cached retrieve');\n equal(Ember.isWatching(obj, 'bar'), true, 'lazily setup watching dependent key');\n equal(Ember.isWatching(obj, 'baz'), true, 'lazily setup watching dependent key');\n});\n\ntestBoth('circular keys should not blow up', function(get, set) {\n\n Ember.defineProperty(obj, 'bar', Ember.computed(function(key, value) {\n count++;\n return 'bar '+count;\n }).property('foo'));\n\n Ember.defineProperty(obj, 'foo', Ember.computed(function(key, value) {\n count++;\n return 'foo '+count;\n }).property('bar'));\n\n equal(get(obj, 'foo'), 'foo 1', 'get once');\n equal(get(obj, 'foo'), 'foo 1', 'cached retrieve');\n\n set(obj, 'bar', 'BIFF'); // should invalidate bar -> foo -> bar\n\n equal(get(obj, 'foo'), 'foo 3', 'should recache');\n equal(get(obj, 'foo'), 'foo 3', 'cached retrieve');\n});\n\ntestBoth('redefining a property should undo old depenent keys', function(get ,set) {\n\n equal(Ember.isWatching(obj, 'bar'), false, 'precond not watching dependent key');\n equal(get(obj, 'foo'), 'bar 1');\n equal(Ember.isWatching(obj, 'bar'), true, 'lazily watching dependent key');\n\n Ember.defineProperty(obj, 'foo', Ember.computed(function() {\n count++;\n return 'baz '+count;\n }).property('baz'));\n\n equal(Ember.isWatching(obj, 'bar'), false, 'after redefining should not be watching dependent key');\n\n equal(get(obj, 'foo'), 'baz 2');\n\n set(obj, 'bar', 'BIFF'); // should not kill cache\n equal(get(obj, 'foo'), 'baz 2');\n\n set(obj, 'baz', 'BOP');\n equal(get(obj, 'foo'), 'baz 3');\n});\n\nif (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {\n testBoth('can watch multiple dependent keys specified via brace expansion', function (get, set) {\n Ember.defineProperty(obj, 'foo', Ember.computed(function(key, value) {\n count++;\n return 'foo '+count;\n }).property('{bar,baz}'));\n\n equal(get(obj, 'foo'), 'foo 1', \"get once\");\n equal(get(obj, 'foo'), 'foo 1', \"cached retrieve\");\n\n set(obj, 'bar', 'bar'); // invalidate foo\n\n equal(get(obj, 'foo'), 'foo 2', \"foo invalidated from bar\");\n\n set(obj, 'baz', 'baz'); // invalidate foo\n\n equal(get(obj, 'foo'), 'foo 3', \"foo invalidated from baz\");\n\n set(obj, 'quux', 'quux'); // do not invalidate foo\n\n equal(get(obj, 'foo'), 'foo 3', \"foo not invalidated by quux\");\n });\n}\n\n// ..........................................................\n// CHAINED DEPENDENT KEYS\n//\n\nvar func, moduleOpts = {\n setup: function() {\n obj = {\n foo: {\n bar: {\n baz: {\n biff: \"BIFF\"\n }\n }\n }\n };\n\n Global = {\n foo: {\n bar: {\n baz: {\n biff: \"BIFF\"\n }\n }\n }\n };\n\n count = 0;\n func = function() {\n count++;\n return Ember.get(obj, 'foo.bar.baz.biff')+' '+count;\n };\n },\n\n teardown: function() {\n obj = count = func = Global = null;\n }\n};\n\nmodule('Ember.computed - dependentkey with chained properties', moduleOpts);\n\ntestBoth('depending on simple chain', function(get, set) {\n\n // assign computed property\n Ember.defineProperty(obj, 'prop',\n Ember.computed(func).property('foo.bar.baz.biff'));\n\n equal(get(obj, 'prop'), 'BIFF 1');\n\n set(Ember.get(obj, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(get(obj, 'prop'), 'BUZZ 2');\n equal(get(obj, 'prop'), 'BUZZ 2');\n\n set(Ember.get(obj, 'foo.bar'), 'baz', { biff: 'BLOB' });\n equal(get(obj, 'prop'), 'BLOB 3');\n equal(get(obj, 'prop'), 'BLOB 3');\n\n set(Ember.get(obj, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(get(obj, 'prop'), 'BUZZ 4');\n equal(get(obj, 'prop'), 'BUZZ 4');\n\n set(Ember.get(obj, 'foo'), 'bar', { baz: { biff: 'BOOM' } });\n equal(get(obj, 'prop'), 'BOOM 5');\n equal(get(obj, 'prop'), 'BOOM 5');\n\n set(Ember.get(obj, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(get(obj, 'prop'), 'BUZZ 6');\n equal(get(obj, 'prop'), 'BUZZ 6');\n\n set(obj, 'foo', { bar: { baz: { biff: 'BLARG' } } });\n equal(get(obj, 'prop'), 'BLARG 7');\n equal(get(obj, 'prop'), 'BLARG 7');\n\n set(Ember.get(obj, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(get(obj, 'prop'), 'BUZZ 8');\n equal(get(obj, 'prop'), 'BUZZ 8');\n\n Ember.defineProperty(obj, 'prop');\n set(obj, 'prop', 'NONE');\n equal(get(obj, 'prop'), 'NONE');\n\n set(obj, 'foo', { bar: { baz: { biff: 'BLARG' } } });\n equal(get(obj, 'prop'), 'NONE'); // should do nothing\n equal(count, 8, 'should be not have invoked computed again');\n\n});\n\ntestBoth('depending on Global chain', function(get, set) {\n\n // assign computed property\n Ember.defineProperty(obj, 'prop', Ember.computed(function() {\n count++;\n return Ember.get('Global.foo.bar.baz.biff')+' '+count;\n }).property('Global.foo.bar.baz.biff'));\n\n equal(get(obj, 'prop'), 'BIFF 1');\n\n set(Ember.get(Global, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(get(obj, 'prop'), 'BUZZ 2');\n equal(get(obj, 'prop'), 'BUZZ 2');\n\n set(Ember.get(Global, 'foo.bar'), 'baz', { biff: 'BLOB' });\n equal(get(obj, 'prop'), 'BLOB 3');\n equal(get(obj, 'prop'), 'BLOB 3');\n\n set(Ember.get(Global, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(get(obj, 'prop'), 'BUZZ 4');\n equal(get(obj, 'prop'), 'BUZZ 4');\n\n set(Ember.get(Global, 'foo'), 'bar', { baz: { biff: 'BOOM' } });\n equal(get(obj, 'prop'), 'BOOM 5');\n equal(get(obj, 'prop'), 'BOOM 5');\n\n set(Ember.get(Global, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(get(obj, 'prop'), 'BUZZ 6');\n equal(get(obj, 'prop'), 'BUZZ 6');\n\n set(Global, 'foo', { bar: { baz: { biff: 'BLARG' } } });\n equal(get(obj, 'prop'), 'BLARG 7');\n equal(get(obj, 'prop'), 'BLARG 7');\n\n set(Ember.get(Global, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(get(obj, 'prop'), 'BUZZ 8');\n equal(get(obj, 'prop'), 'BUZZ 8');\n\n Ember.defineProperty(obj, 'prop');\n set(obj, 'prop', 'NONE');\n equal(get(obj, 'prop'), 'NONE');\n\n set(Global, 'foo', { bar: { baz: { biff: 'BLARG' } } });\n equal(get(obj, 'prop'), 'NONE'); // should do nothing\n equal(count, 8, 'should be not have invoked computed again');\n\n});\n\ntestBoth('chained dependent keys should evaluate computed properties lazily', function(get,set) {\n Ember.defineProperty(obj.foo.bar, 'b', Ember.computed(func));\n Ember.defineProperty(obj.foo, 'c', Ember.computed(function() {}).property('bar.b'));\n equal(count, 0, 'b should not run');\n});\n\n\n// ..........................................................\n// BUGS\n//\n\nmodule('computed edge cases');\n\ntest('adding a computed property should show up in key iteration',function() {\n\n var obj = {};\n Ember.defineProperty(obj, 'foo', Ember.computed(function() {}));\n\n var found = [];\n for(var key in obj) found.push(key);\n ok(Ember.EnumerableUtils.indexOf(found, 'foo')>=0, 'should find computed property in iteration found='+found);\n ok('foo' in obj, 'foo in obj should pass');\n});\n\n\nmodule('Ember.computed - setter');\n\ntestBoth('setting a watched computed property', function(get, set) {\n var obj = {\n firstName: 'Yehuda',\n lastName: 'Katz'\n };\n Ember.defineProperty(obj, 'fullName', Ember.computed(\n function(key, value) {\n if (arguments.length > 1) {\n var values = value.split(' ');\n set(this, 'firstName', values[0]);\n set(this, 'lastName', values[1]);\n return value;\n }\n return get(this, 'firstName') + ' ' + get(this, 'lastName');\n }).property('firstName', 'lastName')\n );\n var fullNameWillChange = 0,\n fullNameDidChange = 0,\n firstNameWillChange = 0,\n firstNameDidChange = 0,\n lastNameWillChange = 0,\n lastNameDidChange = 0;\n Ember.addBeforeObserver(obj, 'fullName', function () {\n fullNameWillChange++;\n });\n Ember.addObserver(obj, 'fullName', function () {\n fullNameDidChange++;\n });\n Ember.addBeforeObserver(obj, 'firstName', function () {\n firstNameWillChange++;\n });\n Ember.addObserver(obj, 'firstName', function () {\n firstNameDidChange++;\n });\n Ember.addBeforeObserver(obj, 'lastName', function () {\n lastNameWillChange++;\n });\n Ember.addObserver(obj, 'lastName', function () {\n lastNameDidChange++;\n });\n\n equal(get(obj, 'fullName'), 'Yehuda Katz');\n\n set(obj, 'fullName', 'Yehuda Katz');\n\n set(obj, 'fullName', 'Kris Selden');\n\n equal(get(obj, 'fullName'), 'Kris Selden');\n equal(get(obj, 'firstName'), 'Kris');\n equal(get(obj, 'lastName'), 'Selden');\n\n equal(fullNameWillChange, 1);\n equal(fullNameDidChange, 1);\n equal(firstNameWillChange, 1);\n equal(firstNameDidChange, 1);\n equal(lastNameWillChange, 1);\n equal(lastNameDidChange, 1);\n});\n\ntestBoth('setting a cached computed property that modifies the value you give it', function(get, set) {\n var obj = {\n foo: 0\n };\n Ember.defineProperty(obj, 'plusOne', Ember.computed(\n function(key, value) {\n if (arguments.length > 1) {\n set(this, 'foo', value);\n return value + 1;\n }\n return get(this, 'foo') + 1;\n }).property('foo')\n );\n var plusOneWillChange = 0,\n plusOneDidChange = 0;\n Ember.addBeforeObserver(obj, 'plusOne', function () {\n plusOneWillChange++;\n });\n Ember.addObserver(obj, 'plusOne', function () {\n plusOneDidChange++;\n });\n\n equal(get(obj, 'plusOne'), 1);\n set(obj, 'plusOne', 1);\n equal(get(obj, 'plusOne'), 2);\n set(obj, 'plusOne', 1);\n equal(get(obj, 'plusOne'), 2);\n\n equal(plusOneWillChange, 1);\n equal(plusOneDidChange, 1);\n\n set(obj, 'foo', 5);\n equal(get(obj, 'plusOne'), 6);\n\n equal(plusOneWillChange, 2);\n equal(plusOneDidChange, 2);\n});\n\nmodule('Ember.computed - default setter');\n\ntestBoth(\"when setting a value on a computed property that doesn't handle sets\", function(get, set) {\n var obj = {}, observerFired = false;\n\n Ember.defineProperty(obj, 'foo', Ember.computed(function() {\n return 'foo';\n }));\n\n Ember.addObserver(obj, 'foo', null, function() {\n observerFired = true;\n });\n\n Ember.set(obj, 'foo', 'bar');\n\n equal(Ember.get(obj, 'foo'), 'bar', 'The set value is properly returned');\n ok(!Ember.meta(obj).descs.foo, 'The computed property was removed');\n ok(observerFired, 'The observer was still notified');\n});\n\nmodule('Ember.computed - readOnly');\n\ntest('is chainable', function() {\n var computed = Ember.computed(function() {}).readOnly();\n\n ok(computed instanceof Ember.Descriptor);\n ok(computed instanceof Ember.ComputedProperty);\n});\n\ntestBoth('protects against setting', function(get, set) {\n var obj = { };\n\n Ember.defineProperty(obj, 'bar', Ember.computed(function(key) {\n return 'barValue';\n }).readOnly());\n\n equal(get(obj, 'bar'), 'barValue');\n\n raises(function() {\n set(obj, 'bar', 'newBar');\n }, /Cannot Set: bar on:/ );\n\n equal(get(obj, 'bar'), 'barValue');\n});\n\nmodule('CP macros');\n\ntestBoth('Ember.computed.not', function(get, set) {\n var obj = {foo: true};\n Ember.defineProperty(obj, 'notFoo', Ember.computed.not('foo'));\n equal(get(obj, 'notFoo'), false);\n\n obj = {foo: {bar: true}};\n Ember.defineProperty(obj, 'notFoo', Ember.computed.not('foo.bar'));\n equal(get(obj, 'notFoo'), false);\n});\n\ntestBoth('Ember.computed.empty', function(get, set) {\n var obj = {foo: [], bar: undefined, baz: null, quz: ''};\n Ember.defineProperty(obj, 'fooEmpty', Ember.computed.empty('foo'));\n Ember.defineProperty(obj, 'barEmpty', Ember.computed.empty('bar'));\n Ember.defineProperty(obj, 'bazEmpty', Ember.computed.empty('baz'));\n Ember.defineProperty(obj, 'quzEmpty', Ember.computed.empty('quz'));\n\n equal(get(obj, 'fooEmpty'), true);\n set(obj, 'foo', [1]);\n equal(get(obj, 'fooEmpty'), false);\n equal(get(obj, 'barEmpty'), true);\n equal(get(obj, 'bazEmpty'), true);\n equal(get(obj, 'quzEmpty'), true);\n set(obj, 'quz', 'asdf');\n equal(get(obj, 'quzEmpty'), false);\n});\n\ntestBoth('Ember.computed.bool', function(get, set) {\n var obj = {foo: function() {}, bar: 'asdf', baz: null, quz: false};\n Ember.defineProperty(obj, 'fooBool', Ember.computed.bool('foo'));\n Ember.defineProperty(obj, 'barBool', Ember.computed.bool('bar'));\n Ember.defineProperty(obj, 'bazBool', Ember.computed.bool('baz'));\n Ember.defineProperty(obj, 'quzBool', Ember.computed.bool('quz'));\n equal(get(obj, 'fooBool'), true);\n equal(get(obj, 'barBool'), true);\n equal(get(obj, 'bazBool'), false);\n equal(get(obj, 'quzBool'), false);\n});\n\ntestBoth('Ember.computed.alias', function(get, set) {\n var obj = { bar: 'asdf', baz: null, quz: false};\n Ember.defineProperty(obj, 'bay', Ember.computed(function(key) {\n return 'apple';\n }));\n\n Ember.defineProperty(obj, 'barAlias', Ember.computed.alias('bar'));\n Ember.defineProperty(obj, 'bazAlias', Ember.computed.alias('baz'));\n Ember.defineProperty(obj, 'quzAlias', Ember.computed.alias('quz'));\n Ember.defineProperty(obj, 'bayAlias', Ember.computed.alias('bay'));\n\n equal(get(obj, 'barAlias'), 'asdf');\n equal(get(obj, 'bazAlias'), null);\n equal(get(obj, 'quzAlias'), false);\n equal(get(obj, 'bayAlias'), 'apple');\n\n set(obj, 'barAlias', 'newBar');\n set(obj, 'bazAlias', 'newBaz');\n set(obj, 'quzAlias', null);\n\n equal(get(obj, 'barAlias'), 'newBar');\n equal(get(obj, 'bazAlias'), 'newBaz');\n equal(get(obj, 'quzAlias'), null);\n\n equal(get(obj, 'bar'), 'newBar');\n equal(get(obj, 'baz'), 'newBaz');\n equal(get(obj, 'quz'), null);\n});\n\ntestBoth('Ember.computed.defaultTo', function(get, set) {\n var obj = { source: 'original source value' };\n Ember.defineProperty(obj, 'copy', Ember.computed.defaultTo('source'));\n\n equal(get(obj, 'copy'), 'original source value');\n\n set(obj, 'copy', 'new copy value');\n equal(get(obj, 'source'), 'original source value');\n equal(get(obj, 'copy'), 'new copy value');\n\n set(obj, 'source', 'new source value');\n equal(get(obj, 'copy'), 'new copy value');\n\n set(obj, 'copy', null);\n equal(get(obj, 'copy'), 'new source value');\n});\n\ntestBoth('Ember.computed.match', function(get, set) {\n var obj = { name: 'Paul' };\n Ember.defineProperty(obj, 'isPaul', Ember.computed.match('name', /Paul/));\n\n equal(get(obj, 'isPaul'), true, 'is Paul');\n\n set(obj, 'name', 'Pierre');\n\n equal(get(obj, 'isPaul'), false, 'is not Paul anymore');\n});\n\ntestBoth('Ember.computed.notEmpty', function(get, set) {\n var obj = { items: [1] };\n Ember.defineProperty(obj, 'hasItems', Ember.computed.notEmpty('items'));\n\n equal(get(obj, 'hasItems'), true, 'is not empty');\n\n set(obj, 'items', []);\n\n equal(get(obj, 'hasItems'), false, 'is empty');\n});\n\ntestBoth('Ember.computed.equal', function(get, set) {\n var obj = { name: 'Paul' };\n Ember.defineProperty(obj, 'isPaul', Ember.computed.equal('name', 'Paul'));\n\n equal(get(obj, 'isPaul'), true, 'is Paul');\n\n set(obj, 'name', 'Pierre');\n\n equal(get(obj, 'isPaul'), false, 'is not Paul anymore');\n});\n\ntestBoth('Ember.computed.gt', function(get, set) {\n var obj = { number: 2 };\n Ember.defineProperty(obj, 'isGreaterThenOne', Ember.computed.gt('number', 1));\n\n equal(get(obj, 'isGreaterThenOne'), true, 'is gt');\n\n set(obj, 'number', 1);\n\n equal(get(obj, 'isGreaterThenOne'), false, 'is not gt');\n\n set(obj, 'number', 0);\n\n equal(get(obj, 'isGreaterThenOne'), false, 'is not gt');\n});\n\ntestBoth('Ember.computed.gte', function(get, set) {\n var obj = { number: 2 };\n Ember.defineProperty(obj, 'isGreaterOrEqualThenOne', Ember.computed.gte('number', 1));\n\n equal(get(obj, 'isGreaterOrEqualThenOne'), true, 'is gte');\n\n set(obj, 'number', 1);\n\n equal(get(obj, 'isGreaterOrEqualThenOne'), true, 'is gte');\n\n set(obj, 'number', 0);\n\n equal(get(obj, 'isGreaterOrEqualThenOne'), false, 'is not gte');\n});\n\ntestBoth('Ember.computed.lt', function(get, set) {\n var obj = { number: 0 };\n Ember.defineProperty(obj, 'isLesserThenOne', Ember.computed.lt('number', 1));\n\n equal(get(obj, 'isLesserThenOne'), true, 'is lt');\n\n set(obj, 'number', 1);\n\n equal(get(obj, 'isLesserThenOne'), false, 'is not lt');\n\n set(obj, 'number', 2);\n\n equal(get(obj, 'isLesserThenOne'), false, 'is not lt');\n});\n\ntestBoth('Ember.computed.lte', function(get, set) {\n var obj = { number: 0 };\n Ember.defineProperty(obj, 'isLesserOrEqualThenOne', Ember.computed.lte('number', 1));\n\n equal(get(obj, 'isLesserOrEqualThenOne'), true, 'is lte');\n\n set(obj, 'number', 1);\n\n equal(get(obj, 'isLesserOrEqualThenOne'), true, 'is lte');\n\n set(obj, 'number', 2);\n\n equal(get(obj, 'isLesserOrEqualThenOne'), false, 'is not lte');\n});\n\ntestBoth('Ember.computed.and', function(get, set) {\n var obj = { one: true, two: true };\n Ember.defineProperty(obj, 'oneAndTwo', Ember.computed.and('one', 'two'));\n\n equal(get(obj, 'oneAndTwo'), true, 'one and two');\n\n set(obj, 'one', false);\n\n equal(get(obj, 'oneAndTwo'), false, 'one and not two');\n});\n\ntestBoth('Ember.computed.or', function(get, set) {\n var obj = { one: true, two: true };\n Ember.defineProperty(obj, 'oneOrTwo', Ember.computed.or('one', 'two'));\n\n equal(get(obj, 'oneOrTwo'), true, 'one or two');\n\n set(obj, 'one', false);\n\n equal(get(obj, 'oneOrTwo'), true, 'one or two');\n\n set(obj, 'two', false);\n\n equal(get(obj, 'oneOrTwo'), false, 'nore one nore two');\n\n set(obj, 'one', true);\n\n equal(get(obj, 'oneOrTwo'), true, 'one or two');\n});\n\ntestBoth('Ember.computed.any', function(get, set) {\n var obj = { one: 'foo', two: 'bar' };\n Ember.defineProperty(obj, 'anyOf', Ember.computed.any('one', 'two'));\n\n equal(get(obj, 'anyOf'), 'foo', 'is foo');\n\n set(obj, 'one', false);\n\n equal(get(obj, 'anyOf'), 'bar', 'is bar');\n});\n\ntestBoth('Ember.computed.collect', function(get, set) {\n var obj = { one: 'foo', two: 'bar', three: null };\n Ember.defineProperty(obj, 'all', Ember.computed.collect('one', 'two', 'three', 'four'));\n\n deepEqual(get(obj, 'all'), ['foo', 'bar', null, null], 'have all of them');\n\n set(obj, 'four', true);\n\n deepEqual(get(obj, 'all'), ['foo', 'bar', null, true], 'have all of them');\n\n var a = [];\n set(obj, 'one', 0);\n set(obj, 'three', a);\n\n deepEqual(get(obj, 'all'), [0, 'bar', a, true], 'have all of them');\n});\n\ntestBoth('Ember.computed.oneWay', function(get, set) {\n var obj = {\n firstName: 'Teddy',\n lastName: 'Zeenny'\n };\n\n Ember.defineProperty(obj, 'nickName', Ember.computed.oneWay('firstName'));\n\n equal(get(obj, 'firstName'), 'Teddy');\n equal(get(obj, 'lastName'), 'Zeenny');\n equal(get(obj, 'nickName'), 'Teddy');\n\n set(obj, 'nickName', 'TeddyBear');\n\n equal(get(obj, 'firstName'), 'Teddy');\n equal(get(obj, 'lastName'), 'Zeenny');\n\n equal(get(obj, 'nickName'), 'TeddyBear');\n\n set(obj, 'firstName', 'TEDDDDDDDDYYY');\n\n equal(get(obj, 'nickName'), 'TeddyBear');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/computed_test");minispade.register('ember-metal/~tests/core/is_empty_test', "(function() {module(\"Ember.isEmpty\");\n\ntest(\"Ember.isEmpty\", function() {\n var string = \"string\", fn = function() {},\n object = {length: 0};\n\n equal(true, Ember.isEmpty(null), \"for null\");\n equal(true, Ember.isEmpty(undefined), \"for undefined\");\n equal(true, Ember.isEmpty(\"\"), \"for an empty String\");\n equal(false, Ember.isEmpty(true), \"for true\");\n equal(false, Ember.isEmpty(false), \"for false\");\n equal(false, Ember.isEmpty(string), \"for a String\");\n equal(false, Ember.isEmpty(fn), \"for a Function\");\n equal(false, Ember.isEmpty(0), \"for 0\");\n equal(true, Ember.isEmpty([]), \"for an empty Array\");\n equal(false, Ember.isEmpty({}), \"for an empty Object\");\n equal(true, Ember.isEmpty(object), \"for an Object that has zero 'length'\");\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/core/is_empty_test");minispade.register('ember-metal/~tests/core/is_none_test', "(function() {module(\"Ember.isNone\");\n\ntest(\"Ember.isNone\", function() {\n var string = \"string\", fn = function() {};\n\n equal(true, Ember.isNone(null), \"for null\");\n equal(true, Ember.isNone(undefined), \"for undefined\");\n equal(false, Ember.isNone(\"\"), \"for an empty String\");\n equal(false, Ember.isNone(true), \"for true\");\n equal(false, Ember.isNone(false), \"for false\");\n equal(false, Ember.isNone(string), \"for a String\");\n equal(false, Ember.isNone(fn), \"for a Function\");\n equal(false, Ember.isNone(0), \"for 0\");\n equal(false, Ember.isNone([]), \"for an empty Array\");\n equal(false, Ember.isNone({}), \"for an empty Object\");\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/core/is_none_test");minispade.register('ember-metal/~tests/enumerable_utils_test', "(function() {module('Ember.EnumerableUtils.intersection');\n\ntest('returns an array of objects that appear in both enumerables', function() {\n var a = [1,2,3], b = [2,3,4], result;\n\n result = Ember.EnumerableUtils.intersection(a, b);\n\n deepEqual(result, [2,3]);\n});\n\ntest(\"large replace\", function() {\n expect(0);\n\n // https://code.google.com/p/chromium/issues/detail?id=56588\n Ember.EnumerableUtils.replace([], 0, undefined, new Array(62401)); // max + 1 in Chrome 28.0.1500.71\n Ember.EnumerableUtils.replace([], 0, undefined, new Array(65535)); // max + 1 in Safari 6.0.5 (8536.30.1)\n Ember.EnumerableUtils.replace([], 0, undefined, new Array(491519)); // max + 1 in FireFox 22.0\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/enumerable_utils_test");minispade.register('ember-metal/~tests/error_test', "(function() {module(\"Ember Error Throwing\");\n\ntest(\"new Ember.Error displays provided message\", function() {\n raises( function() {\n throw new Ember.Error('A Message');\n }, function(e) {\n return e.message === 'A Message';\n }, 'the assigned message was displayed' );\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/error_test");minispade.register('ember-metal/~tests/events_test', "(function() {module('system/props/events_test');\n\ntest('listener should receive event - removing should remove', function() {\n var obj = {}, count = 0;\n var F = function() { count++; };\n\n Ember.addListener(obj, 'event!', F);\n equal(count, 0, 'nothing yet');\n\n Ember.sendEvent(obj, 'event!');\n equal(count, 1, 'received event');\n\n Ember.removeListener(obj, 'event!', F);\n\n count = 0;\n Ember.sendEvent(obj, 'event!');\n equal(count, 0, 'received event');\n});\n\ntest('listeners should be inherited', function() {\n var obj = {}, count = 0;\n var F = function() { count++; };\n\n Ember.addListener(obj, 'event!', F);\n\n var obj2 = Ember.create(obj);\n\n equal(count, 0, 'nothing yet');\n\n Ember.sendEvent(obj2, 'event!');\n equal(count, 1, 'received event');\n\n Ember.removeListener(obj2, 'event!', F);\n\n count = 0;\n Ember.sendEvent(obj2, 'event!');\n equal(count, 0, 'did not receive event');\n\n Ember.sendEvent(obj, 'event!');\n equal(count, 1, 'should still invoke on parent');\n\n});\n\n\ntest('adding a listener more than once should only invoke once', function() {\n\n var obj = {}, count = 0;\n var F = function() { count++; };\n Ember.addListener(obj, 'event!', F);\n Ember.addListener(obj, 'event!', F);\n\n Ember.sendEvent(obj, 'event!');\n equal(count, 1, 'should only invoke once');\n});\n\ntest('adding a listener with a target should invoke with target', function() {\n var obj = {}, target;\n\n target = {\n count: 0,\n method: function() { this.count++; }\n };\n\n Ember.addListener(obj, 'event!', target, target.method);\n Ember.sendEvent(obj, 'event!');\n equal(target.count, 1, 'should invoke');\n});\n\ntest('suspending a listener should not invoke during callback', function() {\n var obj = {}, target, otherTarget;\n\n target = {\n count: 0,\n method: function() { this.count++; }\n };\n\n otherTarget = {\n count: 0,\n method: function() { this.count++; }\n };\n\n Ember.addListener(obj, 'event!', target, target.method);\n Ember.addListener(obj, 'event!', otherTarget, otherTarget.method);\n\n function callback() {\n equal(this, target);\n\n Ember.sendEvent(obj, 'event!');\n\n return 'result';\n }\n\n Ember.sendEvent(obj, 'event!');\n\n equal(Ember._suspendListener(obj, 'event!', target, target.method, callback), 'result');\n\n Ember.sendEvent(obj, 'event!');\n\n equal(target.count, 2, 'should invoke');\n equal(otherTarget.count, 3, 'should invoke');\n});\n\ntest('adding a listener with string method should lookup method on event delivery', function() {\n var obj = {}, target;\n\n target = {\n count: 0,\n method: function() {}\n };\n\n Ember.addListener(obj, 'event!', target, 'method');\n Ember.sendEvent(obj, 'event!');\n equal(target.count, 0, 'should invoke but do nothing');\n\n target.method = function() { this.count++; };\n Ember.sendEvent(obj, 'event!');\n equal(target.count, 1, 'should invoke now');\n});\n\ntest('calling sendEvent with extra params should be passed to listeners', function() {\n\n var obj = {}, params = null;\n Ember.addListener(obj, 'event!', function() {\n params = Array.prototype.slice.call(arguments);\n });\n\n Ember.sendEvent(obj, 'event!', ['foo', 'bar']);\n deepEqual(params, ['foo', 'bar'], 'params should be saved');\n});\n\ntest('implementing sendEvent on object should invoke', function() {\n var obj = {\n sendEvent: function(eventName, params) {\n equal(eventName, 'event!', 'eventName');\n deepEqual(params, ['foo', 'bar']);\n this.count++;\n },\n\n count: 0\n };\n\n Ember.addListener(obj, 'event!', obj, function() { this.count++; });\n\n Ember.sendEvent(obj, 'event!', ['foo', 'bar']);\n equal(obj.count, 2, 'should have invoked method & listener');\n});\n\ntest('hasListeners tells you if there are listeners for a given event', function() {\n\n var obj = {}, F = function() {}, F2 = function() {};\n\n equal(Ember.hasListeners(obj, 'event!'), false, 'no listeners at first');\n\n Ember.addListener(obj, 'event!', F);\n Ember.addListener(obj, 'event!', F2);\n\n equal(Ember.hasListeners(obj, 'event!'), true, 'has listeners');\n\n Ember.removeListener(obj, 'event!', F);\n equal(Ember.hasListeners(obj, 'event!'), true, 'has listeners');\n\n Ember.removeListener(obj, 'event!', F2);\n equal(Ember.hasListeners(obj, 'event!'), false, 'has no more listeners');\n\n Ember.addListener(obj, 'event!', F);\n equal(Ember.hasListeners(obj, 'event!'), true, 'has listeners');\n});\n\ntest('calling removeListener without method should remove all listeners', function() {\n var obj = {}, F = function() {}, F2 = function() {};\n\n equal(Ember.hasListeners(obj, 'event!'), false, 'no listeners at first');\n\n Ember.addListener(obj, 'event!', F);\n Ember.addListener(obj, 'event!', F2);\n\n equal(Ember.hasListeners(obj, 'event!'), true, 'has listeners');\n\n Ember.removeListener(obj, 'event!');\n\n equal(Ember.hasListeners(obj, 'event!'), false, 'has no more listeners');\n});\n\ntest('while suspended, it should not be possible to add a duplicate listener', function() {\n var obj = {}, target;\n\n target = {\n count: 0,\n method: function() { this.count++; }\n };\n\n Ember.addListener(obj, 'event!', target, target.method);\n\n function callback() {\n Ember.addListener(obj, 'event!', target, target.method);\n }\n\n Ember.sendEvent(obj, 'event!');\n\n Ember._suspendListener(obj, 'event!', target, target.method, callback);\n\n equal(target.count, 1, 'should invoke');\n equal(Ember.meta(obj).listeners['event!'].length, 3, \"a duplicate listener wasn't added\");\n\n // now test _suspendListeners...\n\n Ember.sendEvent(obj, 'event!');\n\n Ember._suspendListeners(obj, ['event!'], target, target.method, callback);\n\n equal(target.count, 2, 'should have invoked again');\n equal(Ember.meta(obj).listeners['event!'].length, 3, \"a duplicate listener wasn't added\");\n});\n\ntest('a listener can be added as part of a mixin', function() {\n var triggered = 0;\n var MyMixin = Ember.Mixin.create({\n foo1: Ember.on('bar', function() {\n triggered++;\n }),\n\n foo2: Ember.on('bar', function() {\n triggered++;\n })\n });\n\n var obj = {};\n MyMixin.apply(obj);\n\n Ember.sendEvent(obj, 'bar');\n equal(triggered, 2, 'should invoke listeners');\n});\n\ntest('a listener added as part of a mixin may be overridden', function() {\n\n var triggered = 0;\n var FirstMixin = Ember.Mixin.create({\n foo: Ember.on('bar', function() {\n triggered++;\n })\n });\n var SecondMixin = Ember.Mixin.create({\n foo: Ember.on('baz', function() {\n triggered++;\n })\n });\n\n var obj = {};\n FirstMixin.apply(obj);\n SecondMixin.apply(obj);\n\n Ember.sendEvent(obj, 'bar');\n equal(triggered, 0, 'should not invoke from overriden property');\n\n Ember.sendEvent(obj, 'baz');\n equal(triggered, 1, 'should invoke from subclass property');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/events_test");minispade.register('ember-metal/~tests/features_test', "(function() {var isEnabled = Ember.FEATURES.isEnabled,\n origFeatures, origEnableAll, origEnableOptional;\n\nmodule(\"Ember.FEATURES.isEnabled\", {\n setup: function(){\n origFeatures = Ember.FEATURES;\n origEnableAll = Ember.ENV.ENABLE_ALL_FEATURES;\n origEnableOptional = Ember.ENV.ENABLE_OPTIONAL_FEATURES;\n },\n\n teardown: function(){\n Ember.FEATURES = origFeatures;\n Ember.ENV.ENABLE_ALL_FEATURES = origEnableAll;\n Ember.ENV.ENABLE_OPTIONAL_FEATURES = origEnableOptional;\n }\n});\n\ntest(\"ENV.ENABLE_ALL_FEATURES\", function() {\n Ember.ENV.ENABLE_ALL_FEATURES = true;\n Ember.FEATURES['fred'] = false;\n Ember.FEATURES['wilma'] = null;\n\n equal(isEnabled('fred'), true, \"overrides features set to false\");\n equal(isEnabled('wilma'), true, \"enables optional features\");\n equal(isEnabled('betty'), true, \"enables non-specified features\");\n});\n\ntest(\"ENV.ENABLE_OPTIONAL_FEATURES\", function() {\n Ember.ENV.ENABLE_OPTIONAL_FEATURES = true;\n Ember.FEATURES['fred'] = false;\n Ember.FEATURES['barney'] = true;\n Ember.FEATURES['wilma'] = null;\n\n equal(isEnabled('fred'), false, \"returns flag value if false\");\n equal(isEnabled('barney'), true, \"returns flag value if true\");\n equal(isEnabled('wilma'), true, \"returns true if flag is not true|false|undefined\");\n equal(isEnabled('betty'), undefined, \"returns flag value if undefined\");\n});\n\ntest(\"isEnabled without ENV options\", function(){\n Ember.ENV.ENABLE_ALL_FEATURES = false;\n Ember.ENV.ENABLE_OPTIONAL_FEATURES = false;\n\n Ember.FEATURES['fred'] = false;\n Ember.FEATURES['barney'] = true;\n Ember.FEATURES['wilma'] = null;\n\n equal(isEnabled('fred'), false, \"returns flag value if false\");\n equal(isEnabled('barney'), true, \"returns flag value if true\");\n equal(isEnabled('wilma'), false, \"returns false if flag is not set\");\n equal(isEnabled('betty'), undefined, \"returns flag value if undefined\");\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/features_test");minispade.register('ember-metal/~tests/instrumentation_test', "(function() {var instrument = Ember.Instrumentation;\n\nmodule(\"Ember Instrumentation\", {\n setup: function() {\n\n },\n teardown: function() {\n instrument.reset();\n }\n});\n\ntest(\"subscribing to a simple path receives the listener\", function() {\n expect(12);\n\n var sentPayload = {}, count = 0;\n\n instrument.subscribe(\"render\", {\n before: function(name, timestamp, payload) {\n if (count === 0) {\n strictEqual(name, \"render\");\n } else {\n strictEqual(name, \"render.handlebars\");\n }\n\n ok(typeof timestamp === 'number');\n strictEqual(payload, sentPayload);\n },\n\n after: function(name, timestamp, payload) {\n if (count === 0) {\n strictEqual(name, \"render\");\n } else {\n strictEqual(name, \"render.handlebars\");\n }\n\n ok(typeof timestamp === 'number');\n strictEqual(payload, sentPayload);\n\n count++;\n }\n });\n\n instrument.instrument(\"render\", sentPayload, function() {\n\n });\n\n instrument.instrument(\"render.handlebars\", sentPayload, function() {\n\n });\n});\n\ntest(\"returning a value from the before callback passes it to the after callback\", function() {\n expect(2);\n\n var passthru1 = {}, passthru2 = {};\n\n instrument.subscribe(\"render\", {\n before: function(name, timestamp, payload) {\n return passthru1;\n },\n after: function(name, timestamp, payload, beforeValue) {\n strictEqual(beforeValue, passthru1);\n }\n });\n\n instrument.subscribe(\"render\", {\n before: function(name, timestamp, payload) {\n return passthru2;\n },\n after: function(name, timestamp, payload, beforeValue) {\n strictEqual(beforeValue, passthru2);\n }\n });\n\n instrument.instrument(\"render\", null, function() {});\n});\n\ntest(\"raising an exception in the instrumentation attaches it to the payload\", function() {\n expect(2);\n\n var error = new Error(\"Instrumentation\");\n\n instrument.subscribe(\"render\", {\n before: function() {},\n after: function(name, timestamp, payload) {\n strictEqual(payload.exception, error);\n }\n });\n\n instrument.subscribe(\"render\", {\n before: function() {},\n after: function(name, timestamp, payload) {\n strictEqual(payload.exception, error);\n }\n });\n\n instrument.instrument(\"render.handlebars\", null, function() {\n throw error;\n });\n});\n\ntest(\"it is possible to add a new subscriber after the first instrument\", function() {\n instrument.instrument(\"render.handlebars\", null, function() {});\n\n instrument.subscribe(\"render\", {\n before: function() {\n ok(true, \"Before callback was called\");\n },\n after: function() {\n ok(true, \"After callback was called\");\n }\n });\n\n instrument.instrument(\"render.handlebars\", null, function() {});\n});\n\ntest(\"it is possible to remove a subscriber\", function() {\n expect(4);\n\n var count = 0;\n\n var subscriber = instrument.subscribe(\"render\", {\n before: function() {\n equal(count, 0);\n ok(true, \"Before callback was called\");\n },\n after: function() {\n equal(count, 0);\n ok(true, \"After callback was called\");\n count++;\n }\n });\n\n instrument.instrument(\"render.handlebars\", null, function() {});\n\n instrument.unsubscribe(subscriber);\n\n instrument.instrument(\"render.handlebars\", null, function() {});\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/instrumentation_test");minispade.register('ember-metal/~tests/libraries_test', "(function() {var libs = Ember.libraries;\n\ntest('Ember registers itself', function() {\n equal(libs[0].name, \"Ember\");\n});\n\ntest('core libraries come before other libraries', function() {\n var l = libs.length;\n\n libs.register(\"my-lib\", \"2.0.0a\");\n libs.registerCoreLibrary(\"DS\", \"1.0.0-beta.2\");\n\n equal(libs[l].name, \"DS\");\n equal(libs[l+1].name, \"my-lib\");\n\n libs.deRegister(\"my-lib\");\n libs.deRegister(\"DS\");\n});\n\ntest('only the first registration of a library is stored', function() {\n var l = libs.length;\n\n libs.register(\"magic\", 1.23);\n libs.register(\"magic\", 2.23);\n libs.register(\"magic\", 3.23);\n\n equal(libs[l].name, \"magic\");\n equal(libs[l].version, 1.23);\n equal(libs.length, l+1);\n\n libs.deRegister(\"magic\");\n});\n\ntest('libraries can be de-registered', function() {\n var l = libs.length;\n\n libs.register(\"lib1\", \"1.0.0b\");\n libs.register(\"lib2\", \"1.0.0b\");\n libs.register(\"lib3\", \"1.0.0b\");\n\n libs.deRegister(\"lib1\");\n libs.deRegister(\"lib3\");\n\n equal(libs[l].name, \"lib2\");\n equal(libs.length, l+1);\n\n libs.deRegister(\"lib2\");\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/libraries_test");minispade.register('ember-metal/~tests/map_test', "(function() {var object, number, string, map;\n\nvar varieties = ['Map', 'MapWithDefault'], variety;\n\nfunction testMap(variety) {\n module(\"Ember.\" + variety + \" (forEach and get are implicitly tested)\", {\n setup: function() {\n object = {};\n number = 42;\n string = \"foo\";\n\n map = Ember[variety].create();\n }\n });\n\n var mapHasLength = function(expected, theMap) {\n theMap = theMap || map;\n\n var length = 0;\n theMap.forEach(function() {\n length++;\n });\n\n equal(length, expected, \"map should contain \" + expected + \" items\");\n };\n\n var mapHasEntries = function(entries, theMap) {\n theMap = theMap || map;\n\n for (var i = 0, l = entries.length; i < l; i++) {\n equal(theMap.get(entries[i][0]), entries[i][1]);\n equal(theMap.has(entries[i][0]), true);\n }\n\n mapHasLength(entries.length, theMap);\n };\n\n test(\"add\", function() {\n map.set(object, \"winning\");\n map.set(number, \"winning\");\n map.set(string, \"winning\");\n\n mapHasEntries([\n [ object, \"winning\" ],\n [ number, \"winning\" ],\n [ string, \"winning\" ]\n ]);\n\n map.set(object, \"losing\");\n map.set(number, \"losing\");\n map.set(string, \"losing\");\n\n mapHasEntries([\n [ object, \"losing\" ],\n [ number, \"losing\" ],\n [ string, \"losing\" ]\n ]);\n\n equal(map.has(\"nope\"), false);\n equal(map.has({}), false);\n });\n\n test(\"remove\", function() {\n map.set(object, \"winning\");\n map.set(number, \"winning\");\n map.set(string, \"winning\");\n\n map.remove(object);\n map.remove(number);\n map.remove(string);\n\n // doesn't explode\n map.remove({});\n\n mapHasEntries([]);\n });\n\n test(\"copy and then update\", function() {\n map.set(object, \"winning\");\n map.set(number, \"winning\");\n map.set(string, \"winning\");\n\n var map2 = map.copy();\n\n map2.set(object, \"losing\");\n map2.set(number, \"losing\");\n map2.set(string, \"losing\");\n\n mapHasEntries([\n [ object, \"winning\" ],\n [ number, \"winning\" ],\n [ string, \"winning\" ]\n ]);\n\n mapHasEntries([\n [ object, \"losing\" ],\n [ number, \"losing\" ],\n [ string, \"losing\" ]\n ], map2);\n });\n\n test(\"copy and then remove\", function() {\n map.set(object, \"winning\");\n map.set(number, \"winning\");\n map.set(string, \"winning\");\n\n var map2 = map.copy();\n\n map2.remove(object);\n map2.remove(number);\n map2.remove(string);\n\n mapHasEntries([\n [ object, \"winning\" ],\n [ number, \"winning\" ],\n [ string, \"winning\" ]\n ]);\n\n mapHasEntries([ ], map2);\n });\n \n test(\"length\", function() {\n //Add a key twice\n equal(map.length, 0);\n map.set(string, \"a string\");\n equal(map.length, 1);\n map.set(string, \"the same string\");\n equal(map.length, 1);\n \n //Add another\n map.set(number, \"a number\");\n equal(map.length, 2);\n \n //Remove one that doesn't exist\n map.remove('does not exist');\n equal(map.length, 2);\n \n //Check copy\n var copy = map.copy();\n equal(copy.length, 2);\n \n //Remove a key twice\n map.remove(number);\n equal(map.length, 1);\n map.remove(number);\n equal(map.length, 1);\n \n //Remove the last key\n map.remove(string);\n equal(map.length, 0);\n map.remove(string);\n equal(map.length, 0);\n });\n}\n\nfor (var i = 0; i < varieties.length; i++) {\n testMap(varieties[i]);\n}\n\nmodule(\"MapWithDefault - default values\");\n\ntest(\"Retrieving a value that has not been set returns and sets a default value\", function() {\n var map = Ember.MapWithDefault.create({\n defaultValue: function(key) {\n return [key];\n }\n });\n\n var value = map.get('ohai');\n deepEqual(value, [ 'ohai' ]);\n\n strictEqual(value, map.get('ohai'));\n});\n\ntest(\"Copying a MapWithDefault copies the default value\", function() {\n var map = Ember.MapWithDefault.create({\n defaultValue: function(key) {\n return [key];\n }\n });\n\n map.set('ohai', 1);\n map.get('bai');\n\n var map2 = map.copy();\n\n equal(map2.get('ohai'), 1);\n deepEqual(map2.get('bai'), ['bai']);\n\n map2.set('kthx', 3);\n\n deepEqual(map.get('kthx'), ['kthx']);\n equal(map2.get('kthx'), 3);\n\n deepEqual(map2.get('default'), ['default']);\n\n map2.defaultValue = function(key) {\n return ['tom is on', key];\n };\n\n deepEqual(map2.get('drugs'), ['tom is on', 'drugs']);\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/map_test");minispade.register('ember-metal/~tests/mixin/alias_method_test', "(function() {module('Ember.aliasMethod');\n\nfunction validateAliasMethod(obj) {\n equal(obj.fooMethod(), 'FOO', 'obj.fooMethod()');\n equal(obj.barMethod(), 'FOO', 'obj.barMethod should be a copy of foo');\n}\n\ntest('methods of another name are aliased when the mixin is applied', function() {\n\n var MyMixin = Ember.Mixin.create({\n fooMethod: function() { return 'FOO'; },\n barMethod: Ember.aliasMethod('fooMethod')\n });\n\n var obj = MyMixin.apply({});\n validateAliasMethod(obj);\n});\n\ntest('should follow aliasMethods all the way down', function() {\n var MyMixin = Ember.Mixin.create({\n bar: Ember.aliasMethod('foo'), // put first to break ordered iteration\n baz: function() { return 'baz'; },\n foo: Ember.aliasMethod('baz')\n });\n\n var obj = MyMixin.apply({});\n equal(Ember.get(obj, 'bar')(), 'baz', 'should have followed aliasMethods');\n});\n\ntest('should alias methods from other dependent mixins', function() {\n\n var BaseMixin = Ember.Mixin.create({\n fooMethod: function() { return 'FOO'; }\n });\n\n var MyMixin = Ember.Mixin.create(BaseMixin, {\n barMethod: Ember.aliasMethod('fooMethod')\n });\n\n var obj = MyMixin.apply({});\n validateAliasMethod(obj);\n});\n\ntest('should alias methods from other mixins applied at same time', function() {\n\n var BaseMixin = Ember.Mixin.create({\n fooMethod: function() { return 'FOO'; }\n });\n\n var MyMixin = Ember.Mixin.create({\n barMethod: Ember.aliasMethod('fooMethod')\n });\n\n var obj = Ember.mixin({}, BaseMixin, MyMixin);\n validateAliasMethod(obj);\n});\n\ntest('should alias methods from mixins already applied on object', function() {\n\n var BaseMixin = Ember.Mixin.create({\n quxMethod: function() { return 'qux'; }\n });\n\n var MyMixin = Ember.Mixin.create({\n bar: Ember.aliasMethod('foo'),\n barMethod: Ember.aliasMethod('fooMethod')\n });\n\n var obj = {\n fooMethod: function() { return 'FOO'; }\n };\n\n BaseMixin.apply(obj);\n MyMixin.apply(obj);\n\n validateAliasMethod(obj);\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/alias_method_test");minispade.register('ember-metal/~tests/mixin/alias_test', "(function() {module('Ember.alias',{\n setup: function() {\n Ember.TESTING_DEPRECATION = true;\n },\n teardown: function() {\n Ember.TESTING_DEPRECATION = false;\n }\n});\n\nfunction validateAlias(obj) {\n var get = Ember.get;\n equal(get(obj, 'foo'), 'foo', 'obj.foo');\n equal(get(obj, 'bar'), 'foo', 'obj.bar should be a copy of foo');\n\n equal(get(obj, 'computedFoo'), 'cfoo', 'obj.computedFoo');\n equal(get(obj, 'computedBar'), 'cfoo', 'obj.computedBar should be a copy of computedFoo');\n\n equal(obj.fooMethod(), 'FOO', 'obj.fooMethod()');\n equal(obj.barMethod(), 'FOO', 'obj.barMethod should be a copy of foo');\n}\n\ntest('copies the property values from another key when the mixin is applied', function() {\n\n var MyMixin = Ember.Mixin.create({\n foo: 'foo',\n bar: Ember.alias('foo'),\n\n computedFoo: Ember.computed(function() {\n return 'cfoo';\n }),\n\n computedBar: Ember.alias('computedFoo'),\n\n fooMethod: function() { return 'FOO'; },\n barMethod: Ember.alias('fooMethod')\n });\n\n var obj = MyMixin.apply({});\n validateAlias(obj);\n});\n\ntest('should follow aliases all the way down', function() {\n var MyMixin = Ember.Mixin.create({\n bar: Ember.alias('foo'), // put first to break ordered iteration\n baz: 'baz',\n foo: Ember.alias('baz')\n });\n\n var obj = MyMixin.apply({});\n equal(Ember.get(obj, 'bar'), 'baz', 'should have followed aliases');\n});\n\ntest('should copy from other dependent mixins', function() {\n\n var BaseMixin = Ember.Mixin.create({\n foo: 'foo',\n\n computedFoo: Ember.computed(function() {\n return 'cfoo';\n }),\n\n fooMethod: function() { return 'FOO'; }\n });\n\n var MyMixin = Ember.Mixin.create(BaseMixin, {\n bar: Ember.alias('foo'),\n computedBar: Ember.alias('computedFoo'),\n barMethod: Ember.alias('fooMethod')\n });\n\n var obj = MyMixin.apply({});\n validateAlias(obj);\n});\n\ntest('should copy from other mixins applied at same time', function() {\n\n var BaseMixin = Ember.Mixin.create({\n foo: 'foo',\n\n computedFoo: Ember.computed(function() {\n return 'cfoo';\n }),\n\n fooMethod: function() { return 'FOO'; }\n });\n\n var MyMixin = Ember.Mixin.create({\n bar: Ember.alias('foo'),\n computedBar: Ember.alias('computedFoo'),\n barMethod: Ember.alias('fooMethod')\n });\n\n var obj = Ember.mixin({}, BaseMixin, MyMixin);\n validateAlias(obj);\n});\n\ntest('should copy from properties already applied on object', function() {\n\n var BaseMixin = Ember.Mixin.create({\n foo: 'foo',\n\n computedFoo: Ember.computed(function() {\n return 'cfoo';\n })\n\n });\n\n var MyMixin = Ember.Mixin.create({\n bar: Ember.alias('foo'),\n computedBar: Ember.alias('computedFoo'),\n barMethod: Ember.alias('fooMethod')\n });\n\n var obj = {\n fooMethod: function() { return 'FOO'; }\n };\n\n BaseMixin.apply(obj);\n MyMixin.apply(obj);\n\n validateAlias(obj);\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/alias_test");minispade.register('ember-metal/~tests/mixin/apply_test', "(function() {/*globals raises */\n\nmodule('Ember.Mixin.apply');\n\nfunction K() {}\n\ntest('using apply() should apply properties', function() {\n var MixinA = Ember.Mixin.create({ foo: 'FOO', baz: K });\n var obj = {};\n Ember.mixin(obj, MixinA);\n\n equal(Ember.get(obj, 'foo'), \"FOO\", 'should apply foo');\n equal(Ember.get(obj, 'baz'), K, 'should apply foo');\n});\n\ntest('applying anonymous properties', function() {\n var obj = {};\n Ember.mixin(obj, {\n foo: 'FOO',\n baz: K\n });\n\n equal(Ember.get(obj, 'foo'), \"FOO\", 'should apply foo');\n equal(Ember.get(obj, 'baz'), K, 'should apply foo');\n});\n\ntest('applying null values', function() {\n expectAssertion(function() {\n Ember.mixin({}, null);\n });\n});\n\ntest('applying a property with an undefined value', function() {\n var obj = { tagName: '' };\n Ember.mixin(obj, { tagName: undefined });\n\n strictEqual(Ember.get(obj, 'tagName'), '');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/apply_test");minispade.register('ember-metal/~tests/mixin/computed_test', "(function() {var get = Ember.get,\n set = Ember.set;\n\nmodule('Ember.Mixin Computed Properties');\n\ntest('overriding computed properties', function() {\n var MixinA, MixinB, MixinC, MixinD;\n var obj;\n\n MixinA = Ember.Mixin.create({\n aProp: Ember.computed(function() {\n return 'A';\n })\n });\n\n MixinB = Ember.Mixin.create(MixinA, {\n aProp: Ember.computed(function() {\n return this._super()+'B';\n })\n });\n\n MixinC = Ember.Mixin.create(MixinA, {\n aProp: Ember.computed(function() {\n return this._super()+'C';\n })\n });\n\n MixinD = Ember.Mixin.create({\n aProp: Ember.computed(function() {\n return this._super()+'D';\n })\n });\n\n obj = {};\n MixinB.apply(obj);\n equal(get(obj, 'aProp'), 'AB', \"should expose super for B\");\n\n obj = {};\n MixinC.apply(obj);\n equal(get(obj, 'aProp'), 'AC', \"should expose super for C\");\n\n obj = {};\n\n MixinA.apply(obj);\n MixinD.apply(obj);\n equal(get(obj, 'aProp'), 'AD', \"should define super for D\");\n\n obj = { };\n Ember.defineProperty(obj, 'aProp', Ember.computed(function(key, value) {\n return 'obj';\n }));\n MixinD.apply(obj);\n equal(get(obj, 'aProp'), \"objD\", \"should preserve original computed property\");\n});\n\ntest('calling set on overridden computed properties', function() {\n var SuperMixin, SubMixin;\n var obj;\n\n var superGetOccurred = false,\n superSetOccurred = false;\n\n SuperMixin = Ember.Mixin.create({\n aProp: Ember.computed(function(key, val) {\n if (arguments.length === 1) {\n superGetOccurred = true;\n } else {\n superSetOccurred = true;\n }\n return true;\n })\n });\n\n SubMixin = Ember.Mixin.create(SuperMixin, {\n aProp: Ember.computed(function(key, val) {\n return this._super.apply(this, arguments);\n })\n });\n\n obj = {};\n SubMixin.apply(obj);\n\n set(obj, 'aProp', 'set thyself');\n ok(superSetOccurred, 'should pass set to _super');\n\n superSetOccurred = false; // reset the set assertion\n\n obj = {};\n SubMixin.apply(obj);\n\n get(obj, 'aProp');\n ok(superGetOccurred, 'should pass get to _super');\n\n set(obj, 'aProp', 'set thyself');\n ok(superSetOccurred, 'should pass set to _super after getting');\n});\n\ntest('setter behavior works properly when overriding computed properties', function() {\n var obj = {};\n\n var MixinA = Ember.Mixin.create({\n cpWithSetter2: Ember.computed(Ember.K),\n cpWithSetter3: Ember.computed(Ember.K),\n cpWithoutSetter: Ember.computed(Ember.K)\n });\n\n var cpWasCalled = false;\n\n var MixinB = Ember.Mixin.create({\n cpWithSetter2: Ember.computed(function(k, v) {\n cpWasCalled = true;\n }),\n\n cpWithSetter3: Ember.computed(function(k, v) {\n cpWasCalled = true;\n }),\n\n cpWithoutSetter: Ember.computed(function(k) {\n cpWasCalled = true;\n })\n });\n\n MixinA.apply(obj);\n MixinB.apply(obj);\n\n set(obj, 'cpWithSetter2', 'test');\n ok(cpWasCalled, \"The computed property setter was called when defined with two args\");\n cpWasCalled = false;\n\n set(obj, 'cpWithSetter3', 'test');\n ok(cpWasCalled, \"The computed property setter was called when defined with three args\");\n cpWasCalled = false;\n\n set(obj, 'cpWithoutSetter', 'test');\n equal(Ember.get(obj, 'cpWithoutSetter'), 'test', \"The default setter was called, the value is correct\");\n ok(!cpWasCalled, \"The default setter was called, not the CP itself\");\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/computed_test");minispade.register('ember-metal/~tests/mixin/concatenatedProperties_test', "(function() {/*globals setup */\n\nmodule('Ember.Mixin concatenatedProperties');\n\ntest('defining concatenated properties should concat future version', function() {\n\n var MixinA = Ember.Mixin.create({\n concatenatedProperties: ['foo'],\n foo: ['a', 'b', 'c']\n });\n\n var MixinB = Ember.Mixin.create({\n foo: ['d', 'e', 'f']\n });\n\n var obj = Ember.mixin({}, MixinA, MixinB);\n deepEqual(Ember.get(obj, 'foo'), ['a', 'b', 'c', 'd', 'e', 'f']);\n});\n\ntest('concatenatedProperties should be concatenated', function() {\n\n var MixinA = Ember.Mixin.create({\n concatenatedProperties: ['foo'],\n foo: ['a', 'b', 'c']\n });\n\n var MixinB = Ember.Mixin.create({\n concatenatedProperties: 'bar',\n foo: ['d', 'e', 'f'],\n bar: [1,2,3]\n });\n\n var MixinC = Ember.Mixin.create({\n bar: [4,5,6]\n });\n\n var obj = Ember.mixin({}, MixinA, MixinB, MixinC);\n deepEqual(Ember.get(obj, 'concatenatedProperties'), ['foo', 'bar'], 'get concatenatedProperties');\n deepEqual(Ember.get(obj, 'foo'), ['a', 'b', 'c', 'd', 'e', 'f'], 'get foo');\n deepEqual(Ember.get(obj, 'bar'), [1,2,3,4,5,6], 'get bar');\n});\n\ntest('adding a prop that is not an array should make array', function() {\n\n var MixinA = Ember.Mixin.create({\n concatenatedProperties: ['foo'],\n foo: [1,2,3]\n });\n\n var MixinB = Ember.Mixin.create({\n foo: 4\n });\n\n var obj = Ember.mixin({}, MixinA, MixinB);\n deepEqual(Ember.get(obj, 'foo'), [1,2,3,4]);\n});\n\ntest('adding a prop that is not an array should make array', function() {\n\n var MixinA = Ember.Mixin.create({\n concatenatedProperties: ['foo'],\n foo: 'bar'\n });\n\n var obj = Ember.mixin({}, MixinA);\n deepEqual(Ember.get(obj, 'foo'), ['bar']);\n});\n\ntest('adding a non-concatenable property that already has a defined value should result in an array with both values', function() {\n\n var mixinA = Ember.Mixin.create({\n foo: 1\n });\n\n var mixinB = Ember.Mixin.create({\n concatenatedProperties: ['foo'],\n foo: 2\n });\n\n var obj = Ember.mixin({}, mixinA, mixinB);\n deepEqual(Ember.get(obj, 'foo'), [1, 2]);\n});\n\ntest('adding a concatenable property that already has a defined value should result in a concatenated value', function() {\n\n var mixinA = Ember.Mixin.create({\n foobar: 'foo'\n });\n\n var mixinB = Ember.Mixin.create({\n concatenatedProperties: ['foobar'],\n foobar: 'bar'\n });\n\n var obj = Ember.mixin({}, mixinA, mixinB);\n equal(Ember.get(obj, 'foobar'), 'foobar');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/concatenatedProperties_test");minispade.register('ember-metal/~tests/mixin/detect_test', "(function() {module('Mixin.detect');\n\ntest('detect() finds a directly applied mixin', function() {\n\n var MixinA = Ember.Mixin.create();\n var obj = {};\n\n equal(MixinA.detect(obj), false, 'MixinA.detect(obj) before apply()');\n\n MixinA.apply(obj);\n equal(MixinA.detect(obj), true, 'MixinA.detect(obj) after apply()');\n});\n\ntest('detect() finds nested mixins', function() {\n var MixinA = Ember.Mixin.create({});\n var MixinB = Ember.Mixin.create(MixinA);\n var obj = {};\n\n equal(MixinA.detect(obj), false, 'MixinA.detect(obj) before apply()');\n\n MixinB.apply(obj);\n equal(MixinA.detect(obj), true, 'MixinA.detect(obj) after apply()');\n});\n\ntest('detect() finds mixins on other mixins', function() {\n var MixinA = Ember.Mixin.create({});\n var MixinB = Ember.Mixin.create(MixinA);\n equal(MixinA.detect(MixinB), true, 'MixinA is part of MixinB');\n equal(MixinB.detect(MixinA), false, 'MixinB is not part of MixinA');\n});\n\ntest('detect handles null values', function() {\n var MixinA = Ember.Mixin.create();\n equal(MixinA.detect(null), false);\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/detect_test");minispade.register('ember-metal/~tests/mixin/introspection_test', "(function() {// NOTE: A previous iteration differentiated between public and private props\n// as well as methods vs props. We are just keeping these for testing; the\n// current impl doesn't care about the differences as much...\n\nvar PrivateProperty = Ember.Mixin.create({\n _foo: '_FOO'\n});\n\nvar PublicProperty = Ember.Mixin.create({\n foo: 'FOO'\n});\n\nvar PrivateMethod = Ember.Mixin.create({\n _fooMethod: function() {}\n});\n\nvar PublicMethod = Ember.Mixin.create({\n fooMethod: function() {}\n});\n\nvar BarProperties = Ember.Mixin.create({\n _bar: '_BAR',\n bar: 'bar'\n});\n\nvar BarMethods = Ember.Mixin.create({\n _barMethod: function() {},\n barMethod: function() {}\n});\n\nvar Combined = Ember.Mixin.create(BarProperties, BarMethods);\n\nvar obj ;\n\nmodule('Basic introspection', {\n setup: function() {\n obj = {};\n Ember.mixin(obj, PrivateProperty, PublicProperty, PrivateMethod, PublicMethod, Combined);\n }\n});\n\ntest('Ember.mixins()', function() {\n\n function mapGuids(ary) {\n return Ember.EnumerableUtils.map(ary, function(x) { return Ember.guidFor(x); });\n }\n\n deepEqual(mapGuids(Ember.Mixin.mixins(obj)), mapGuids([PrivateProperty, PublicProperty, PrivateMethod, PublicMethod, Combined, BarProperties, BarMethods]), 'should return included mixins');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/introspection_test");minispade.register('ember-metal/~tests/mixin/mergedProperties_test', "(function() {/*globals setup */\n\nmodule('Ember.Mixin mergedProperties');\n\ntest('defining mergedProperties should merge future version', function() {\n\n var MixinA = Ember.Mixin.create({\n mergedProperties: ['foo'],\n foo: { a: true, b: true, c: true }\n });\n\n var MixinB = Ember.Mixin.create({\n foo: { d: true, e: true, f: true }\n });\n\n var obj = Ember.mixin({}, MixinA, MixinB);\n deepEqual(Ember.get(obj, 'foo'), \n { a: true, b: true, c: true, d: true, e: true, f: true });\n});\n\ntest('defining mergedProperties on future mixin should merged into past', function() {\n\n var MixinA = Ember.Mixin.create({\n foo: { a: true, b: true, c: true }\n });\n\n var MixinB = Ember.Mixin.create({\n mergedProperties: ['foo'],\n foo: { d: true, e: true, f: true }\n });\n\n var obj = Ember.mixin({}, MixinA, MixinB);\n deepEqual(Ember.get(obj, 'foo'), \n { a: true, b: true, c: true, d: true, e: true, f: true });\n});\n\ntest('defining mergedProperties with null properties should keep properties null', function() {\n\n var MixinA = Ember.Mixin.create({\n mergedProperties: ['foo'],\n foo: null\n });\n\n var MixinB = Ember.Mixin.create({\n foo: null\n });\n\n var obj = Ember.mixin({}, MixinA, MixinB);\n equal(Ember.get(obj, 'foo'), null);\n});\n\ntest(\"mergedProperties' properties can get overwritten\", function() {\n\n var MixinA = Ember.Mixin.create({\n mergedProperties: ['foo'],\n foo: { a: 1 }\n });\n\n var MixinB = Ember.Mixin.create({\n foo: { a: 2 }\n });\n\n var obj = Ember.mixin({}, MixinA, MixinB);\n deepEqual(Ember.get(obj, 'foo'), { a: 2 });\n});\n\ntest('mergedProperties should be concatenated', function() {\n\n var MixinA = Ember.Mixin.create({\n mergedProperties: ['foo'],\n foo: { a: true, b: true, c: true }\n });\n\n var MixinB = Ember.Mixin.create({\n mergedProperties: 'bar',\n foo: { d: true, e: true, f: true },\n bar: { a: true, l: true }\n });\n\n var MixinC = Ember.Mixin.create({\n bar: { e: true, x: true }\n });\n\n var obj = Ember.mixin({}, MixinA, MixinB, MixinC);\n deepEqual(Ember.get(obj, 'mergedProperties'), ['foo', 'bar'], 'get mergedProperties');\n deepEqual(Ember.get(obj, 'foo'), { a: true, b: true, c: true, d: true, e: true, f: true }, \"get foo\");\n deepEqual(Ember.get(obj, 'bar'), { a: true, l: true, e: true, x: true }, \"get bar\");\n});\n\ntest(\"mergedProperties' overwriting methods can call _super\", function() {\n\n expect(4);\n\n var MixinA = Ember.Mixin.create({\n mergedProperties: ['foo'],\n foo: {\n meth: function(a) {\n equal(a, \"WOOT\", \"_super successfully called MixinA's `foo.meth` method\");\n return \"WAT\";\n }\n }\n });\n\n var MixinB = Ember.Mixin.create({\n foo: {\n meth: function(a) {\n ok(true, \"MixinB's `foo.meth` method called\");\n return this._super.apply(this, arguments);\n }\n }\n });\n\n var MixinC = Ember.Mixin.create({\n foo: {\n meth: function(a) {\n ok(true, \"MixinC's `foo.meth` method called\");\n return this._super(a);\n }\n }\n });\n\n var obj = Ember.mixin({}, MixinA, MixinB, MixinC);\n equal(obj.foo.meth(\"WOOT\"), \"WAT\");\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/mergedProperties_test");minispade.register('ember-metal/~tests/mixin/method_test', "(function() {/*globals raises */\n\nmodule('Mixin Methods');\n\ntest('defining simple methods', function() {\n\n var MixinA, obj, props;\n\n props = {\n publicMethod: function() { return 'publicMethod'; },\n _privateMethod: function() { return 'privateMethod'; }\n };\n\n MixinA = Ember.Mixin.create(props);\n obj = {};\n MixinA.apply(obj);\n\n // but should be defined\n equal(props.publicMethod(), 'publicMethod', 'publicMethod is func');\n equal(props._privateMethod(), 'privateMethod', 'privateMethod is func');\n});\n\ntest('overriding public methods', function() {\n var MixinA, MixinB, MixinC, MixinD, MixinE, MixinF, obj;\n\n MixinA = Ember.Mixin.create({\n publicMethod: function() { return 'A'; }\n });\n\n MixinB = Ember.Mixin.create(MixinA, {\n publicMethod: function() { return this._super()+'B'; }\n });\n\n MixinD = Ember.Mixin.create(MixinA, {\n publicMethod: function() { return this._super()+'D'; }\n });\n\n MixinF = Ember.Mixin.create({\n publicMethod: function() { return this._super()+'F'; }\n });\n\n obj = {};\n MixinB.apply(obj);\n equal(obj.publicMethod(), 'AB', 'should define super for A and B');\n\n obj = {};\n MixinD.apply(obj);\n equal(obj.publicMethod(), 'AD', 'should define super for A and B');\n\n obj = {};\n MixinA.apply(obj);\n MixinF.apply(obj);\n equal(obj.publicMethod(), 'AF', 'should define super for A and F');\n\n obj = { publicMethod: function() { return 'obj'; } };\n MixinF.apply(obj);\n equal(obj.publicMethod(), 'objF', 'should define super for F');\n});\n\n\ntest('overriding inherited objects', function() {\n\n var cnt = 0;\n var MixinA = Ember.Mixin.create({\n foo: function() { cnt++; }\n });\n\n var MixinB = Ember.Mixin.create({\n foo: function() { this._super(); cnt++; }\n });\n\n var objA = {};\n MixinA.apply(objA);\n\n var objB = Ember.create(objA);\n MixinB.apply(objB);\n\n cnt = 0;\n objB.foo();\n equal(cnt, 2, 'should invoke both methods');\n\n cnt = 0;\n objA.foo();\n equal(cnt, 1, 'should not screw w/ parent obj');\n});\n\ntest('Including the same mixin more than once will only run once', function() {\n var cnt = 0;\n var MixinA = Ember.Mixin.create({\n foo: function() { cnt++; }\n });\n\n var MixinB = Ember.Mixin.create(MixinA, {\n foo: function() { this._super(); }\n });\n\n var MixinC = Ember.Mixin.create(MixinA, {\n foo: function() { this._super(); }\n });\n\n var MixinD = Ember.Mixin.create(MixinB, MixinC, MixinA, {\n foo: function() { this._super(); }\n });\n\n var obj = {};\n MixinD.apply(obj);\n MixinA.apply(obj); // try to apply again..\n\n cnt = 0;\n obj.foo();\n\n equal(cnt, 1, 'should invoke MixinA.foo one time');\n});\n\n// ..........................................................\n// CONFLICTS\n//\n\nmodule('Method Conflicts');\n\n\ntest('overriding toString', function() {\n var MixinA = Ember.Mixin.create({\n toString: function() { return 'FOO'; }\n });\n\n var obj = {};\n MixinA.apply(obj);\n equal(obj.toString(), 'FOO', 'should override toString w/o error');\n\n obj = {};\n Ember.mixin(obj, { toString: function() { return 'FOO'; } });\n equal(obj.toString(), 'FOO', 'should override toString w/o error');\n});\n\n// ..........................................................\n// BUGS\n//\n\nmodule('system/mixin/method_test BUGS');\n\ntest('applying several mixins at once with sup already defined causes infinite loop', function() {\n\n var cnt = 0;\n var MixinA = Ember.Mixin.create({\n foo: function() { cnt++; }\n });\n\n var MixinB = Ember.Mixin.create({\n foo: function() { this._super(); cnt++; }\n });\n\n var MixinC = Ember.Mixin.create({\n foo: function() { this._super(); cnt++; }\n });\n\n var obj = {};\n Ember.mixin(obj, MixinA); // sup already exists\n Ember.mixin(obj, MixinB, MixinC); // must be more than one mixin\n\n cnt = 0;\n obj.foo();\n equal(cnt, 3, 'should invoke all 3 methods');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/method_test");minispade.register('ember-metal/~tests/mixin/observer_test', "(function() {/*globals testBoth */\nminispade.require('ember-metal/~tests/props_helper');\n\nmodule('Ember.Mixin observer');\n\ntestBoth('global observer helper', function(get, set) {\n\n var MyMixin = Ember.Mixin.create({\n\n count: 0,\n\n foo: Ember.observer('bar', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n\n });\n\n var obj = Ember.mixin({}, MyMixin);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj, 'bar', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n});\n\ntestBoth('global observer helper takes multiple params', function(get, set) {\n\n var MyMixin = Ember.Mixin.create({\n\n count: 0,\n\n foo: Ember.observer('bar', 'baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n\n });\n\n var obj = Ember.mixin({}, MyMixin);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj, 'bar', \"BAZ\");\n set(obj, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 2, 'should invoke observer after change');\n});\n\n\ntestBoth('replacing observer should remove old observer', function(get, set) {\n\n var MyMixin = Ember.Mixin.create({\n\n count: 0,\n\n foo: Ember.observer('bar', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n\n });\n\n var Mixin2 = Ember.Mixin.create({\n foo: Ember.observer('baz', function() {\n set(this, 'count', get(this, 'count')+10);\n })\n });\n\n var obj = Ember.mixin({}, MyMixin, Mixin2);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj, 'bar', \"BAZ\");\n equal(get(obj, 'count'), 0, 'should not invoke observer after change');\n\n set(obj, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 10, 'should invoke observer after change');\n\n});\n\ntestBoth('observing chain with property before', function(get, set) {\n var obj2 = {baz: 'baz'};\n\n var MyMixin = Ember.Mixin.create({\n count: 0,\n bar: obj2,\n foo: Ember.observer('bar.baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n var obj = Ember.mixin({}, MyMixin);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj2, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n});\n\ntestBoth('observing chain with property after', function(get, set) {\n var obj2 = {baz: 'baz'};\n\n var MyMixin = Ember.Mixin.create({\n count: 0,\n foo: Ember.observer('bar.baz', function() {\n set(this, 'count', get(this, 'count')+1);\n }),\n bar: obj2\n });\n\n var obj = Ember.mixin({}, MyMixin);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj2, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n});\n\ntestBoth('observing chain with property in mixin applied later', function(get, set) {\n var obj2 = {baz: 'baz'};\n\n var MyMixin = Ember.Mixin.create({\n\n count: 0,\n foo: Ember.observer('bar.baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n var MyMixin2 = Ember.Mixin.create({bar: obj2});\n\n var obj = Ember.mixin({}, MyMixin);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n MyMixin2.apply(obj);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj2, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n});\n\ntestBoth('observing chain with existing property', function(get, set) {\n var obj2 = {baz: 'baz'};\n\n var MyMixin = Ember.Mixin.create({\n count: 0,\n foo: Ember.observer('bar.baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n var obj = Ember.mixin({bar: obj2}, MyMixin);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj2, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n});\n\ntestBoth('observing chain with property in mixin before', function(get, set) {\n var obj2 = {baz: 'baz'};\n var MyMixin2 = Ember.Mixin.create({bar: obj2});\n\n var MyMixin = Ember.Mixin.create({\n count: 0,\n foo: Ember.observer('bar.baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n var obj = Ember.mixin({}, MyMixin2, MyMixin);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj2, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n});\n\ntestBoth('observing chain with property in mixin after', function(get, set) {\n var obj2 = {baz: 'baz'};\n var MyMixin2 = Ember.Mixin.create({bar: obj2});\n\n var MyMixin = Ember.Mixin.create({\n count: 0,\n foo: Ember.observer('bar.baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n var obj = Ember.mixin({}, MyMixin, MyMixin2);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj2, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n});\n\ntestBoth('observing chain with overriden property', function(get, set) {\n var obj2 = {baz: 'baz'};\n var obj3 = {baz: 'foo'};\n\n var MyMixin2 = Ember.Mixin.create({bar: obj3});\n\n var MyMixin = Ember.Mixin.create({\n count: 0,\n foo: Ember.observer('bar.baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n var obj = Ember.mixin({bar: obj2}, MyMixin, MyMixin2);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n equal(Ember.isWatching(obj2, 'baz'), false, 'should not be watching baz');\n equal(Ember.isWatching(obj3, 'baz'), true, 'should be watching baz');\n\n set(obj2, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 0, 'should not invoke observer after change');\n\n set(obj3, 'baz', \"BEAR\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/observer_test");minispade.register('ember-metal/~tests/mixin/reopen_test', "(function() {module('Ember.Mixin#reopen');\n\ntest('using reopen() to add more properties to a simple', function() {\n var MixinA = Ember.Mixin.create({ foo: 'FOO', baz: 'BAZ' });\n MixinA.reopen({ bar: 'BAR', foo: 'FOO2' });\n var obj = {};\n MixinA.apply(obj);\n\n equal(Ember.get(obj, 'foo'), 'FOO2', 'mixin() should override');\n equal(Ember.get(obj, 'baz'), 'BAZ', 'preserve MixinA props');\n equal(Ember.get(obj, 'bar'), 'BAR', 'include MixinB props');\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/reopen_test");minispade.register('ember-metal/~tests/mixin/required_test', "(function() {/*globals setup raises */\n\nvar PartialMixin, FinalMixin, obj;\n\nmodule('Module.required', {\n setup: function() {\n PartialMixin = Ember.Mixin.create({\n foo: Ember.required(),\n bar: 'BAR'\n });\n\n FinalMixin = Ember.Mixin.create({\n foo: 'FOO'\n });\n\n obj = {};\n },\n\n teardown: function() {\n PartialMixin = FinalMixin = obj = null;\n }\n});\n\ntest('applying a mixin to meet requirement', function() {\n FinalMixin.apply(obj);\n PartialMixin.apply(obj);\n equal(Ember.get(obj, 'foo'), 'FOO', 'should now be defined');\n});\n\ntest('combined mixins to meet requirement', function() {\n Ember.Mixin.create(PartialMixin, FinalMixin).apply(obj);\n equal(Ember.get(obj, 'foo'), 'FOO', 'should now be defined');\n});\n\ntest('merged mixin', function() {\n Ember.Mixin.create(PartialMixin, { foo: 'FOO' }).apply(obj);\n equal(Ember.get(obj, 'foo'), 'FOO', 'should now be defined');\n});\n\ntest('define property on source object', function() {\n obj.foo = 'FOO';\n PartialMixin.apply(obj);\n equal(Ember.get(obj, 'foo'), 'FOO', 'should now be defined');\n});\n\ntest('using apply', function() {\n Ember.mixin(obj, PartialMixin, { foo: 'FOO' });\n equal(Ember.get(obj, 'foo'), 'FOO', 'should now be defined');\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/required_test");minispade.register('ember-metal/~tests/mixin/without_test', "(function() {/*globals setup */\n\ntest('without should create a new mixin excluding named properties', function() {\n\n var MixinA = Ember.Mixin.create({\n foo: 'FOO',\n bar: 'BAR'\n });\n\n var MixinB = MixinA.without('bar');\n\n var obj = {};\n MixinB.apply(obj);\n\n equal(obj.foo, 'FOO', 'should defined foo');\n equal(obj.bar, undefined, 'should not define bar');\n\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/mixin/without_test");minispade.register('ember-metal/~tests/observer_test', "(function() {/*globals Global:true */\nminispade.require('ember-metal/~tests/props_helper');\n\n// ..........................................................\n// ADD OBSERVER\n//\n\nmodule('Ember.addObserver');\n\ntestBoth('observer should fire when property is modified', function(get,set) {\n\n var obj = {};\n var count = 0;\n\n Ember.addObserver(obj, 'foo', function() {\n equal(get(obj, 'foo'), 'bar', 'should invoke AFTER value changed');\n count++;\n });\n\n set(obj, 'foo', 'bar');\n equal(count, 1, 'should have invoked observer');\n});\n\ntestBoth('observer should fire when dependent property is modified', function(get, set) {\n var obj = { bar: 'bar' };\n Ember.defineProperty(obj, 'foo', Ember.computed(function() {\n return get(this,'bar').toUpperCase();\n }).property('bar'));\n\n get(obj, 'foo');\n\n var count = 0;\n Ember.addObserver(obj, 'foo', function() {\n equal(get(obj, 'foo'), 'BAZ', 'should have invoked after prop change');\n count++;\n });\n\n set(obj, 'bar', 'baz');\n equal(count, 1, 'should have invoked observer');\n});\n\nif (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {\n testBoth('observer added via brace expansion should fire when property changes', function (get, set) {\n var obj = {};\n var count = 0;\n\n Ember.addObserver(obj, '{foo,bar}', function() {\n count++;\n });\n\n set(obj, 'foo', 'foo');\n equal(count, 1, 'observer specified via brace expansion invoked on property change');\n\n set(obj, 'bar', 'bar');\n equal(count, 2, 'observer specified via brace expansion invoked on property change');\n\n set(obj, 'baz', 'baz');\n equal(count, 2, 'observer not invoked on unspecified property');\n });\n\n testBoth('observer specified via brace expansion should fire when dependent property changes', function (get, set) {\n var obj = { baz: 'Initial' };\n var count = 0;\n\n Ember.defineProperty(obj, 'foo', Ember.computed(function() {\n return get(this,'bar').toLowerCase();\n }).property('bar'));\n\n Ember.defineProperty(obj, 'bar', Ember.computed(function() {\n return get(this,'baz').toUpperCase();\n }).property('baz'));\n\n Ember.addObserver(obj, '{foo,bar}', function() {\n count++;\n });\n\n get(obj, 'foo');\n set(obj, 'baz', 'Baz');\n // fire once for foo, once for bar\n equal(count, 2, 'observer specified via brace expansion invoked on dependent property change');\n\n set(obj, 'quux', 'Quux');\n equal(count, 2, 'observer not fired on unspecified property');\n });\n}\n\ntestBoth('nested observers should fire in order', function(get,set) {\n var obj = { foo: 'foo', bar: 'bar' };\n var fooCount = 0, barCount = 0;\n\n Ember.addObserver(obj, 'foo' ,function() { fooCount++; });\n Ember.addObserver(obj, 'bar', function() {\n set(obj, 'foo', 'BAZ');\n equal(fooCount, 1, 'fooCount should have fired already');\n barCount++;\n });\n\n set(obj, 'bar', 'BIFF');\n equal(barCount, 1, 'barCount should have fired');\n equal(fooCount, 1, 'foo should have fired');\n\n});\n\ntestBoth('removing an chain observer on change should not fail', function(get,set) {\n var foo = { bar: 'bar' },\n obj1 = { foo: foo }, obj2 = { foo: foo }, obj3 = { foo: foo }, obj4 = { foo: foo },\n count1=0, count2=0, count3=0, count4=0;\n function observer1() { count1++; }\n function observer2() { count2++; }\n function observer3() {\n count3++;\n Ember.removeObserver(obj1, 'foo.bar', observer1);\n Ember.removeObserver(obj2, 'foo.bar', observer2);\n Ember.removeObserver(obj4, 'foo.bar', observer4);\n }\n function observer4() { count4++; }\n\n Ember.addObserver(obj1, 'foo.bar' , observer1);\n Ember.addObserver(obj2, 'foo.bar' , observer2);\n Ember.addObserver(obj3, 'foo.bar' , observer3);\n Ember.addObserver(obj4, 'foo.bar' , observer4);\n\n set(foo, 'bar', 'baz');\n\n equal(count1, 1, 'observer1 fired');\n equal(count2, 1, 'observer2 fired');\n equal(count3, 1, 'observer3 fired');\n equal(count4, 0, 'observer4 did not fire');\n});\n\ntestBoth('removing an chain before observer on change should not fail', function(get,set) {\n var foo = { bar: 'bar' },\n obj1 = { foo: foo }, obj2 = { foo: foo }, obj3 = { foo: foo }, obj4 = { foo: foo },\n count1=0, count2=0, count3=0, count4=0;\n function observer1() { count1++; }\n function observer2() { count2++; }\n function observer3() {\n count3++;\n Ember.removeBeforeObserver(obj1, 'foo.bar', observer1);\n Ember.removeBeforeObserver(obj2, 'foo.bar', observer2);\n Ember.removeBeforeObserver(obj4, 'foo.bar', observer4);\n }\n function observer4() { count4++; }\n\n Ember.addBeforeObserver(obj1, 'foo.bar' , observer1);\n Ember.addBeforeObserver(obj2, 'foo.bar' , observer2);\n Ember.addBeforeObserver(obj3, 'foo.bar' , observer3);\n Ember.addBeforeObserver(obj4, 'foo.bar' , observer4);\n\n set(foo, 'bar', 'baz');\n\n equal(count1, 1, 'observer1 fired');\n equal(count2, 1, 'observer2 fired');\n equal(count3, 1, 'observer3 fired');\n equal(count4, 0, 'observer4 did not fire');\n});\n\ntestBoth('suspending an observer should not fire during callback', function(get,set) {\n var obj = {}, target, otherTarget;\n\n target = {\n values: [],\n method: function() { this.values.push(get(obj, 'foo')); }\n };\n\n otherTarget = {\n values: [],\n method: function() { this.values.push(get(obj, 'foo')); }\n };\n\n Ember.addObserver(obj, 'foo', target, target.method);\n Ember.addObserver(obj, 'foo', otherTarget, otherTarget.method);\n\n function callback() {\n equal(this, target);\n\n set(obj, 'foo', '2');\n\n return 'result';\n }\n\n set(obj, 'foo', '1');\n\n equal(Ember._suspendObserver(obj, 'foo', target, target.method, callback), 'result');\n\n set(obj, 'foo', '3');\n\n deepEqual(target.values, ['1', '3'], 'should invoke');\n deepEqual(otherTarget.values, ['1', '2', '3'], 'should invoke');\n});\n\n\ntestBoth('suspending an observer should not defer change notifications during callback', function(get,set) {\n var obj = {}, target, otherTarget;\n\n target = {\n values: [],\n method: function() { this.values.push(get(obj, 'foo')); }\n };\n\n otherTarget = {\n values: [],\n method: function() { this.values.push(get(obj, 'foo')); }\n };\n\n Ember.addObserver(obj, 'foo', target, target.method);\n Ember.addObserver(obj, 'foo', otherTarget, otherTarget.method);\n\n function callback() {\n equal(this, target);\n\n set(obj, 'foo', '2');\n\n return 'result';\n }\n\n set(obj, 'foo', '1');\n\n Ember.beginPropertyChanges();\n equal(Ember._suspendObserver(obj, 'foo', target, target.method, callback), 'result');\n Ember.endPropertyChanges();\n\n set(obj, 'foo', '3');\n\n deepEqual(target.values, ['1', '3'], 'should invoke');\n deepEqual(otherTarget.values, ['1', '2', '3'], 'should invoke');\n});\n\ntestBoth('suspending observers should not fire during callback', function(get,set) {\n var obj = {}, target, otherTarget;\n\n target = {\n values: [],\n method: function() { this.values.push(get(obj, 'foo')); }\n };\n\n otherTarget = {\n values: [],\n method: function() { this.values.push(get(obj, 'foo')); }\n };\n\n Ember.addObserver(obj, 'foo', target, target.method);\n Ember.addObserver(obj, 'foo', otherTarget, otherTarget.method);\n\n function callback() {\n equal(this, target);\n\n set(obj, 'foo', '2');\n\n return 'result';\n }\n\n set(obj, 'foo', '1');\n\n equal(Ember._suspendObservers(obj, ['foo'], target, target.method, callback), 'result');\n\n set(obj, 'foo', '3');\n\n deepEqual(target.values, ['1', '3'], 'should invoke');\n deepEqual(otherTarget.values, ['1', '2', '3'], 'should invoke');\n});\n\n\ntestBoth('suspending observers should not defer change notifications during callback', function(get,set) {\n var obj = {}, target, otherTarget;\n\n target = {\n values: [],\n method: function() { this.values.push(get(obj, 'foo')); }\n };\n\n otherTarget = {\n values: [],\n method: function() { this.values.push(get(obj, 'foo')); }\n };\n\n Ember.addObserver(obj, 'foo', target, target.method);\n Ember.addObserver(obj, 'foo', otherTarget, otherTarget.method);\n\n function callback() {\n equal(this, target);\n\n set(obj, 'foo', '2');\n\n return 'result';\n }\n\n set(obj, 'foo', '1');\n\n Ember.beginPropertyChanges();\n equal(Ember._suspendObservers(obj, ['foo'], target, target.method, callback), 'result');\n Ember.endPropertyChanges();\n\n set(obj, 'foo', '3');\n\n deepEqual(target.values, ['1', '3'], 'should invoke');\n deepEqual(otherTarget.values, ['1', '2', '3'], 'should invoke');\n});\n\ntestBoth('deferring property change notifications', function(get,set) {\n var obj = { foo: 'foo' };\n var fooCount = 0;\n\n Ember.addObserver(obj, 'foo' ,function() { fooCount++; });\n\n Ember.beginPropertyChanges(obj);\n set(obj, 'foo', 'BIFF');\n set(obj, 'foo', 'BAZ');\n Ember.endPropertyChanges(obj);\n\n equal(fooCount, 1, 'foo should have fired once');\n});\n\ntestBoth('deferring property change notifications safely despite exceptions', function(get,set) {\n var obj = { foo: 'foo' };\n var fooCount = 0;\n var exc = new Error(\"Something unexpected happened!\");\n\n expect(2);\n Ember.addObserver(obj, 'foo' ,function() { fooCount++; });\n\n try {\n Ember.changeProperties(function() {\n set(obj, 'foo', 'BIFF');\n set(obj, 'foo', 'BAZ');\n throw exc;\n });\n } catch(err) {\n if (err !== exc)\n throw err;\n }\n\n equal(fooCount, 1, 'foo should have fired once');\n\n Ember.changeProperties(function() {\n set(obj, 'foo', 'BIFF2');\n set(obj, 'foo', 'BAZ2');\n });\n\n equal(fooCount, 2, 'foo should have fired again once');\n});\n\ntestBoth('deferring property change notifications will not defer before observers', function(get,set) {\n var obj = { foo: 'foo' };\n var fooCount = 0;\n\n Ember.addBeforeObserver(obj, 'foo' ,function() { fooCount++; });\n\n Ember.beginPropertyChanges(obj);\n set(obj, 'foo', 'BIFF');\n equal(fooCount, 1, 'should fire before observer immediately');\n set(obj, 'foo', 'BAZ');\n Ember.endPropertyChanges(obj);\n\n equal(fooCount, 1, 'should not fire before observer twice');\n});\n\ntestBoth('implementing sendEvent on object should invoke when deferring property change notifications ends', function(get, set) {\n var count = 0, events = [];\n var obj = {\n sendEvent: function(eventName) {\n events.push(eventName);\n },\n foo: 'baz'\n };\n\n Ember.addObserver(obj, 'foo', function() { count++; });\n\n Ember.beginPropertyChanges(obj);\n set(obj, 'foo', 'BAZ');\n\n equal(count, 0, 'should have not invoked observer');\n equal(events.length, 1, 'should have invoked sendEvent for before');\n\n Ember.endPropertyChanges(obj);\n\n equal(count, 1, 'should have invoked observer');\n equal(events.length, 2, 'should have invoked sendEvent');\n equal(events[0], 'foo:before');\n equal(events[1], 'foo:change');\n});\n\ntestBoth('addObserver should propagate through prototype', function(get,set) {\n var obj = { foo: 'foo', count: 0 }, obj2;\n\n Ember.addObserver(obj, 'foo', function() { this.count++; });\n obj2 = Ember.create(obj);\n\n set(obj2, 'foo', 'bar');\n\n equal(obj2.count, 1, 'should have invoked observer on inherited');\n equal(obj.count, 0, 'should not have invoked observer on parent');\n\n obj2.count = 0;\n set(obj, 'foo', 'baz');\n equal(obj.count, 1, 'should have invoked observer on parent');\n equal(obj2.count, 0, 'should not have invoked observer on inherited');\n});\n\ntestBoth('addObserver should respect targets with methods', function(get,set) {\n var observed = { foo: 'foo' };\n\n var target1 = {\n count: 0,\n\n didChange: function(obj, keyName) {\n var value = get(obj, keyName);\n equal(this, target1, 'should invoke with this');\n equal(obj, observed, 'param1 should be observed object');\n equal(keyName, 'foo', 'param2 should be keyName');\n equal(value, 'BAZ', 'param3 should new value');\n this.count++;\n }\n };\n\n var target2 = {\n count: 0,\n\n didChange: function(obj, keyName) {\n var value = get(obj, keyName);\n equal(this, target2, 'should invoke with this');\n equal(obj, observed, 'param1 should be observed object');\n equal(keyName, 'foo', 'param2 should be keyName');\n equal(value, 'BAZ', 'param3 should new value');\n this.count++;\n }\n };\n\n Ember.addObserver(observed, 'foo', target1, 'didChange');\n Ember.addObserver(observed, 'foo', target2, target2.didChange);\n\n set(observed, 'foo', 'BAZ');\n equal(target1.count, 1, 'target1 observer should have fired');\n equal(target2.count, 1, 'target2 observer should have fired');\n\n});\n\ntestBoth('addObserver should allow multiple objects to observe a property', function(get, set) { var observed = { foo: 'foo' };\n\n var target1 = {\n count: 0,\n\n didChange: function(obj, keyName, value) {\n this.count++;\n }\n };\n\n var target2 = {\n count: 0,\n\n didChange: function(obj, keyName, value) {\n this.count++;\n }\n };\n\n Ember.addObserver(observed, 'foo', target1, 'didChange');\n Ember.addObserver(observed, 'foo', target2, 'didChange');\n\n set(observed, 'foo', 'BAZ');\n equal(target1.count, 1, 'target1 observer should have fired');\n equal(target2.count, 1, 'target2 observer should have fired');\n});\n\n// ..........................................................\n// REMOVE OBSERVER\n//\n\nmodule('Ember.removeObserver');\n\ntestBoth('removing observer should stop firing', function(get,set) {\n\n var obj = {};\n var count = 0;\n function F() { count++; }\n Ember.addObserver(obj, 'foo', F);\n\n set(obj, 'foo', 'bar');\n equal(count, 1, 'should have invoked observer');\n\n Ember.removeObserver(obj, 'foo', F);\n\n set(obj, 'foo', 'baz');\n equal(count, 1, \"removed observer shouldn't fire\");\n});\n\nif (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {\n testBoth(\"observers removed via brace expansion should stop firing\", function(get, set) {\n function observer() { count++; }\n function didRemoveListener(eventName) {\n if (eventName === 'foo:change') {\n fooListenerRemoved = true;\n } else if (eventName === 'bar:change') {\n barListenerRemoved = true;\n } else {\n ok(false, \"Unexpected listener removed \" + eventName);\n }\n }\n\n var fooListenerRemoved = false,\n barListenerRemoved = false,\n obj = { didRemoveListener: didRemoveListener },\n count = 0;\n\n Ember.addObserver(obj, 'foo', observer);\n Ember.addObserver(obj, 'bar', observer);\n\n set(obj, 'foo', 'foo');\n equal(count, 1, 'should have invoked observer');\n\n set(obj, 'bar', 'bar');\n equal(count, 2, 'should have invoked observer');\n\n Ember.removeObserver(obj, '{foo,bar}', observer);\n ok(fooListenerRemoved, 'listener was removed');\n ok(barListenerRemoved, 'listener was removed');\n\n set(obj, 'foo', 'foo2');\n equal(count, 2, \"removed observer shouldn't fire\");\n\n set(obj, 'bar', 'bar2');\n equal(count, 2, \"removed observer shouldn't fire\");\n });\n}\n\ntestBoth('local observers can be removed', function(get, set) {\n var barObserved = 0;\n\n var MyMixin = Ember.Mixin.create({\n foo1: Ember.observer('bar', function() {\n barObserved++;\n }),\n\n foo2: Ember.observer('bar', function() {\n barObserved++;\n })\n });\n\n var obj = {};\n MyMixin.apply(obj);\n\n set(obj, 'bar', 'HI!');\n equal(barObserved, 2, 'precond - observers should be fired');\n\n Ember.removeObserver(obj, 'bar', null, 'foo1');\n\n barObserved = 0;\n set(obj, 'bar', 'HI AGAIN!');\n\n equal(barObserved, 1, 'removed observers should not be called');\n});\n\ntestBoth('removeObserver should respect targets with methods', function(get,set) {\n var observed = { foo: 'foo' };\n\n var target1 = {\n count: 0,\n\n didChange: function() {\n this.count++;\n }\n };\n\n var target2 = {\n count: 0,\n\n didChange: function() {\n this.count++;\n }\n };\n\n Ember.addObserver(observed, 'foo', target1, 'didChange');\n Ember.addObserver(observed, 'foo', target2, target2.didChange);\n\n set(observed, 'foo', 'BAZ');\n equal(target1.count, 1, 'target1 observer should have fired');\n equal(target2.count, 1, 'target2 observer should have fired');\n\n Ember.removeObserver(observed, 'foo', target1, 'didChange');\n Ember.removeObserver(observed, 'foo', target2, target2.didChange);\n\n target1.count = target2.count = 0;\n set(observed, 'foo', 'BAZ');\n equal(target1.count, 0, 'target1 observer should not fire again');\n equal(target2.count, 0, 'target2 observer should not fire again');\n});\n\n// ..........................................................\n// BEFORE OBSERVER\n//\n\nmodule('Ember.addBeforeObserver');\n\ntestBoth('observer should fire before a property is modified', function(get,set) {\n\n var obj = { foo: 'foo' };\n var count = 0;\n\n Ember.addBeforeObserver(obj, 'foo', function() {\n equal(get(obj, 'foo'), 'foo', 'should invoke before value changed');\n count++;\n });\n\n set(obj, 'foo', 'bar');\n equal(count, 1, 'should have invoked observer');\n});\n\ntestBoth('observer should fire before dependent property is modified', function(get, set) {\n var obj = { bar: 'bar' };\n Ember.defineProperty(obj, 'foo', Ember.computed(function() {\n return get(this,'bar').toUpperCase();\n }).property('bar'));\n\n get(obj, 'foo');\n\n var count = 0;\n Ember.addBeforeObserver(obj, 'foo', function() {\n equal(get(obj, 'foo'), 'BAR', 'should have invoked after prop change');\n count++;\n });\n\n set(obj, 'bar', 'baz');\n equal(count, 1, 'should have invoked observer');\n});\n\nif (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {\n testBoth('before observer added via brace expansion should fire when property changes', function (get, set) {\n var obj = {};\n var count = 0;\n\n Ember.addBeforeObserver(obj, '{foo,bar}', function() {\n count++;\n });\n\n set(obj, 'foo', 'foo');\n equal(count, 1, 'observer specified via brace expansion invoked on property change');\n\n set(obj, 'bar', 'bar');\n equal(count, 2, 'observer specified via brace expansion invoked on property change');\n\n set(obj, 'baz', 'baz');\n equal(count, 2, 'observer not invoked on unspecified property');\n });\n\n testBoth('before observer specified via brace expansion should fire when dependent property changes', function (get, set) {\n var obj = { baz: 'Initial' };\n var count = 0;\n\n Ember.defineProperty(obj, 'foo', Ember.computed(function() {\n return get(this,'bar').toLowerCase();\n }).property('bar'));\n\n Ember.defineProperty(obj, 'bar', Ember.computed(function() {\n return get(this,'baz').toUpperCase();\n }).property('baz'));\n\n Ember.addBeforeObserver(obj, '{foo,bar}', function() {\n count++;\n });\n\n get(obj, 'foo');\n set(obj, 'baz', 'Baz');\n // fire once for foo, once for bar\n equal(count, 2, 'observer specified via brace expansion invoked on dependent property change');\n\n set(obj, 'quux', 'Quux');\n equal(count, 2, 'observer not fired on unspecified property');\n });\n}\n\ntestBoth('addBeforeObserver should propagate through prototype', function(get,set) {\n var obj = { foo: 'foo', count: 0 }, obj2;\n\n Ember.addBeforeObserver(obj, 'foo', function() { this.count++; });\n obj2 = Ember.create(obj);\n\n set(obj2, 'foo', 'bar');\n equal(obj2.count, 1, 'should have invoked observer on inherited');\n equal(obj.count, 0, 'should not have invoked observer on parent');\n\n obj2.count = 0;\n set(obj, 'foo', 'baz');\n equal(obj.count, 1, 'should have invoked oberver on parent');\n equal(obj2.count, 0, 'should not have invoked observer on inherited');\n});\n\ntestBoth('addBeforeObserver should respect targets with methods', function(get,set) {\n var observed = { foo: 'foo' };\n\n var target1 = {\n count: 0,\n\n willChange: function(obj, keyName) {\n var value = get(obj, keyName);\n equal(this, target1, 'should invoke with this');\n equal(obj, observed, 'param1 should be observed object');\n equal(keyName, 'foo', 'param2 should be keyName');\n equal(value, 'foo', 'param3 should old value');\n this.count++;\n }\n };\n\n var target2 = {\n count: 0,\n\n willChange: function(obj, keyName) {\n var value = get(obj, keyName);\n equal(this, target2, 'should invoke with this');\n equal(obj, observed, 'param1 should be observed object');\n equal(keyName, 'foo', 'param2 should be keyName');\n equal(value, 'foo', 'param3 should old value');\n this.count++;\n }\n };\n\n Ember.addBeforeObserver(observed, 'foo', target1, 'willChange');\n Ember.addBeforeObserver(observed, 'foo', target2, target2.willChange);\n\n set(observed, 'foo', 'BAZ');\n equal(target1.count, 1, 'target1 observer should have fired');\n equal(target2.count, 1, 'target2 observer should have fired');\n\n});\n\n// ..........................................................\n// CHAINED OBSERVERS\n//\n\nvar obj, count;\nvar originalLookup = Ember.lookup, lookup;\n\nmodule('Ember.addObserver - dependentkey with chained properties', {\n setup: function() {\n obj = {\n foo: {\n bar: {\n baz: {\n biff: \"BIFF\"\n }\n }\n }\n };\n\n Ember.lookup = lookup = {\n Global: {\n foo: {\n bar: {\n baz: {\n biff: \"BIFF\"\n }\n }\n }\n }\n };\n\n count = 0;\n },\n\n teardown: function() {\n obj = count = null;\n Ember.lookup = originalLookup;\n }\n});\n\n\ntestBoth('depending on a chain with a computed property', function (get, set){\n Ember.defineProperty(obj, 'computed', Ember.computed(function () {\n return {foo: 'bar'};\n }));\n\n var changed = 0;\n Ember.addObserver(obj, 'computed.foo', function () {\n changed++;\n });\n\n equal(undefined, Ember.cacheFor(obj, 'computed'), 'addObserver should not compute CP');\n\n set(obj, 'computed.foo', 'baz');\n\n equal(changed, 1, 'should fire observer');\n});\n\ntestBoth('depending on a simple chain', function(get, set) {\n\n var val ;\n Ember.addObserver(obj, 'foo.bar.baz.biff', function(target, key) {\n val = Ember.get(target, key);\n count++;\n });\n\n set(Ember.get(obj, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(val, 'BUZZ');\n equal(count, 1);\n\n set(Ember.get(obj, 'foo.bar'), 'baz', { biff: 'BLARG' });\n equal(val, 'BLARG');\n equal(count, 2);\n\n set(Ember.get(obj, 'foo'), 'bar', { baz: { biff: 'BOOM' } });\n equal(val, 'BOOM');\n equal(count, 3);\n\n set(obj, 'foo', { bar: { baz: { biff: 'BLARG' } } });\n equal(val, 'BLARG');\n equal(count, 4);\n\n set(Ember.get(obj, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(val, 'BUZZ');\n equal(count, 5);\n\n var foo = get(obj, 'foo');\n\n set(obj, 'foo', 'BOO');\n equal(val, undefined);\n equal(count, 6);\n\n set(foo.bar.baz, 'biff', \"BOOM\");\n equal(count, 6, 'should be not have invoked observer');\n});\n\ntestBoth('depending on a Global chain', function(get, set) {\n var Global = lookup.Global, val;\n\n Ember.addObserver(obj, 'Global.foo.bar.baz.biff', function(target, key) {\n val = Ember.get(lookup, key);\n count++;\n });\n\n set(Ember.get(Global, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(val, 'BUZZ');\n equal(count, 1);\n\n set(Ember.get(Global, 'foo.bar'), 'baz', { biff: 'BLARG' });\n equal(val, 'BLARG');\n equal(count, 2);\n\n set(Ember.get(Global, 'foo'), 'bar', { baz: { biff: 'BOOM' } });\n equal(val, 'BOOM');\n equal(count, 3);\n\n set(Global, 'foo', { bar: { baz: { biff: 'BLARG' } } });\n equal(val, 'BLARG');\n equal(count, 4);\n\n set(Ember.get(Global, 'foo.bar.baz'), 'biff', 'BUZZ');\n equal(val, 'BUZZ');\n equal(count, 5);\n\n var foo = get(obj, 'foo');\n\n set(Global, 'foo', 'BOO');\n equal(val, undefined);\n equal(count, 6);\n\n set(foo.bar.baz, 'biff', \"BOOM\");\n equal(count, 6, 'should be not have invoked observer');\n});\n\nmodule('Ember.removeBeforeObserver');\n\nif (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {\n testBoth(\"before observers removed via brace expansion should stop firing\", function(get, set) {\n function observer() { count++; }\n function didRemoveListener(eventName) {\n if (eventName === 'foo:before') {\n fooListenerRemoved = true;\n } else if (eventName === 'bar:before') {\n barListenerRemoved = true;\n } else {\n ok(false, \"Unexpected listener removed \" + eventName);\n }\n }\n\n var fooListenerRemoved = false,\n barListenerRemoved = false,\n obj = { didRemoveListener: didRemoveListener },\n count = 0;\n\n Ember.addBeforeObserver(obj, 'foo', observer);\n Ember.addBeforeObserver(obj, 'bar', observer);\n\n set(obj, 'foo', 'foo');\n equal(count, 1, 'should have invoked observer');\n\n set(obj, 'bar', 'bar');\n equal(count, 2, 'should have invoked observer');\n\n Ember.removeBeforeObserver(obj, '{foo,bar}', observer);\n ok(fooListenerRemoved, 'listener was removed');\n ok(barListenerRemoved, 'listener was removed');\n\n set(obj, 'foo', 'foo2');\n equal(count, 2, \"removed observer shouldn't fire\");\n\n set(obj, 'bar', 'bar2');\n equal(count, 2, \"removed observer shouldn't fire\");\n });\n}\n\n// ..........................................................\n// SETTING IDENTICAL VALUES\n//\n\nmodule('props/observer_test - setting identical values');\n\ntestBoth('setting simple prop should not trigger', function(get, set) {\n\n var obj = { foo: 'bar' };\n var count = 0;\n\n Ember.addObserver(obj, 'foo', function() { count++; });\n\n set(obj, 'foo', 'bar');\n equal(count, 0, 'should not trigger observer');\n\n set(obj, 'foo', 'baz');\n equal(count, 1, 'should trigger observer');\n\n set(obj, 'foo', 'baz');\n equal(count, 1, 'should not trigger observer again');\n});\n\n// The issue here is when a computed property is directly set with a value, then has a\n// dependent key change (which triggers a cache expiration and recomputation), observers will\n// not be fired if the CP setter is called with the last set value.\ntestBoth('setting a cached computed property whose value has changed should trigger', function(get, set) {\n var obj = {};\n\n Ember.defineProperty(obj, 'foo', Ember.computed(function(key, value) {\n if (arguments.length === 2) { return value; }\n return get(this, 'baz');\n }).property('baz'));\n\n var count = 0;\n\n Ember.addObserver(obj, 'foo', function() { count++; });\n\n set(obj, 'foo', 'bar');\n equal(count, 1);\n equal(get(obj, 'foo'), 'bar');\n\n set(obj, 'baz', 'qux');\n equal(count, 2);\n equal(get(obj, 'foo'), 'qux');\n\n get(obj, 'foo');\n set(obj, 'foo', 'bar');\n equal(count, 3);\n equal(get(obj, 'foo'), 'bar');\n});\n\nmodule(\"Ember.immediateObserver\");\n\ntestBoth(\"immediate observers should fire synchronously\", function(get, set) {\n var obj = {},\n observerCalled = 0,\n mixin;\n\n // explicitly create a run loop so we do not inadvertently\n // trigger deferred behavior\n Ember.run(function() {\n mixin = Ember.Mixin.create({\n fooDidChange: Ember.immediateObserver('foo', function() {\n observerCalled++;\n equal(get(this, 'foo'), \"barbaz\", \"newly set value is immediately available\");\n })\n });\n\n mixin.apply(obj);\n\n Ember.defineProperty(obj, 'foo', Ember.computed(function(key, value) {\n if (arguments.length > 1) {\n return value;\n }\n return \"yes hello this is foo\";\n }));\n\n equal(get(obj, 'foo'), \"yes hello this is foo\", \"precond - computed property returns a value\");\n equal(observerCalled, 0, \"observer has not yet been called\");\n\n set(obj, 'foo', 'barbaz');\n\n equal(observerCalled, 1, \"observer was called once\");\n });\n});\n\ntestBoth(\"immediate observers are for internal properties only\", function(get, set) {\n expectAssertion(function() {\n Ember.immediateObserver('foo.bar', Ember.K);\n }, 'Immediate observers must observe internal properties only, not properties on other objects.');\n});\n\nmodule(\"Ember.changeProperties\");\n\ntestBoth(\"observers added/removed during changeProperties should do the right thing.\", function(get,set) {\n var obj = {\n foo: 0\n };\n function Observer() {\n this.willChangeCount = 0;\n this.didChangeCount = 0;\n }\n Observer.prototype = {\n add: function () {\n Ember.addBeforeObserver(obj, 'foo', this, 'willChange');\n Ember.addObserver(obj, 'foo', this, 'didChange');\n },\n remove: function() {\n Ember.removeBeforeObserver(obj, 'foo', this, 'willChange');\n Ember.removeObserver(obj, 'foo', this, 'didChange');\n },\n willChange: function () {\n this.willChangeCount++;\n },\n didChange: function () {\n this.didChangeCount++;\n }\n };\n var addedBeforeFirstChangeObserver = new Observer();\n var addedAfterFirstChangeObserver = new Observer();\n var addedAfterLastChangeObserver = new Observer();\n var removedBeforeFirstChangeObserver = new Observer();\n var removedBeforeLastChangeObserver = new Observer();\n var removedAfterLastChangeObserver = new Observer();\n removedBeforeFirstChangeObserver.add();\n removedBeforeLastChangeObserver.add();\n removedAfterLastChangeObserver.add();\n Ember.changeProperties(function () {\n removedBeforeFirstChangeObserver.remove();\n addedBeforeFirstChangeObserver.add();\n\n set(obj, 'foo', 1);\n\n equal(addedBeforeFirstChangeObserver.willChangeCount, 1, 'addBeforeObserver called before the first change invoked immediately');\n equal(addedBeforeFirstChangeObserver.didChangeCount, 0, 'addObserver called before the first change is deferred');\n\n addedAfterFirstChangeObserver.add();\n removedBeforeLastChangeObserver.remove();\n\n set(obj, 'foo', 2);\n\n equal(addedAfterFirstChangeObserver.willChangeCount, 1, 'addBeforeObserver called after the first change invoked immediately');\n equal(addedAfterFirstChangeObserver.didChangeCount, 0, 'addObserver called after the first change is deferred');\n\n addedAfterLastChangeObserver.add();\n removedAfterLastChangeObserver.remove();\n });\n\n equal(removedBeforeFirstChangeObserver.willChangeCount, 0, 'removeBeforeObserver called before the first change sees none');\n equal(removedBeforeFirstChangeObserver.didChangeCount, 0, 'removeObserver called before the first change sees none');\n equal(addedBeforeFirstChangeObserver.willChangeCount, 1, 'addBeforeObserver called before the first change sees only 1');\n equal(addedBeforeFirstChangeObserver.didChangeCount, 1, 'addObserver called before the first change sees only 1');\n equal(addedAfterFirstChangeObserver.willChangeCount, 1, 'addBeforeObserver called after the first change sees 1');\n equal(addedAfterFirstChangeObserver.didChangeCount, 1, 'addObserver called after the first change sees 1');\n equal(addedAfterLastChangeObserver.willChangeCount, 0, 'addBeforeObserver called after the last change sees none');\n equal(addedAfterLastChangeObserver.didChangeCount, 0, 'addObserver called after the last change sees none');\n equal(removedBeforeLastChangeObserver.willChangeCount, 1, 'removeBeforeObserver called before the last change still sees 1');\n equal(removedBeforeLastChangeObserver.didChangeCount, 1, 'removeObserver called before the last change still sees 1');\n equal(removedAfterLastChangeObserver.willChangeCount, 1, 'removeBeforeObserver called after the last change still sees 1');\n equal(removedAfterLastChangeObserver.didChangeCount, 1, 'removeObserver called after the last change still sees 1');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/observer_test");minispade.register('ember-metal/~tests/performance_test', "(function() {/*\n This test file is designed to capture performance regressions related to\n deferred computation. Things like run loops, computed properties, and bindings\n should run the minimum amount of times to achieve best performance, so any\n bugs that cause them to get evaluated more than necessary should be put here.\n*/\n\nmodule(\"Computed Properties - Number of times evaluated\");\n\ntest(\"computed properties that depend on multiple properties should run only once per run loop\", function() {\n var obj = {a: 'a', b: 'b', c: 'c'};\n var cpCount = 0, obsCount = 0;\n\n Ember.defineProperty(obj, 'abc', Ember.computed(function(key) {\n cpCount++;\n return 'computed '+key;\n }).property('a', 'b', 'c'));\n\n Ember.get(obj, 'abc');\n\n cpCount = 0;\n\n Ember.addObserver(obj, 'abc', function() {\n obsCount++;\n });\n\n Ember.beginPropertyChanges();\n Ember.set(obj, 'a', 'aa');\n Ember.set(obj, 'b', 'bb');\n Ember.set(obj, 'c', 'cc');\n Ember.endPropertyChanges();\n\n Ember.get(obj, 'abc');\n\n equal(cpCount, 1, \"The computed property is only invoked once\");\n equal(obsCount, 1, \"The observer is only invoked once\");\n});\n\ntest(\"computed properties are not executed if they are the last segment of an observer chain pain\", function() {\n var foo = { bar: { baz: { } } };\n\n var count = 0;\n\n Ember.defineProperty(foo.bar.baz, 'bam', Ember.computed(function() {\n count++;\n }));\n\n Ember.addObserver(foo, 'bar.baz.bam', function() {});\n\n Ember.propertyDidChange(Ember.get(foo, 'bar.baz'), 'bam');\n\n equal(count, 0, \"should not have recomputed property\");\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/performance_test");minispade.register('ember-metal/~tests/platform/create_test', "(function() {module(\"Ember.create()\");\n\ntest(\"should inherit the properties from the parent object\", function() {\n var obj = { foo: 'FOO' };\n var obj2 = Ember.create(obj);\n ok(obj !== obj2, 'should be a new instance');\n equal(obj2.foo, obj.foo, 'should inherit from parent');\n\n obj2.foo = 'BAR';\n equal(obj2.foo, 'BAR', 'should change foo');\n equal(obj.foo, 'FOO', 'modifying obj2 should not modify obj');\n});\n\n// NOTE: jshint may interfere with this test since it defines its own Object.create if missing\ntest(\"passing additional property descriptors should define\", function() {\n var obj = { foo: 'FOO', repl: 'obj' };\n var obj2 = Ember.create(obj, {\n bar: {\n value: 'BAR'\n },\n\n repl: {\n value: 'obj2'\n }\n });\n\n equal(obj2.bar, 'BAR', 'should have defined');\n equal(obj2.repl, 'obj2', 'should have replaced parent');\n});\n\ntest(\"passing additional property descriptors should not pollute parent object\", function() {\n var obj = { foo: 'FOO', repl: 'obj' };\n var obj2 = Ember.create(obj, {\n repl: {\n value: 'obj2'\n }\n });\n\n notEqual(obj.repl, obj2.repl, 'should not pollute parent object');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/platform/create_test");minispade.register('ember-metal/~tests/platform/defineProperty_test', "(function() {function isEnumerable(obj, keyName) {\n var keys = [];\n for(var key in obj) {\n if (obj.hasOwnProperty(key)) keys.push(key);\n }\n return Ember.EnumerableUtils.indexOf(keys, keyName)>=0;\n}\n\nmodule(\"Ember.platform.defineProperty()\");\n\ntest(\"defining a simple property\", function() {\n var obj = {};\n Ember.platform.defineProperty(obj, 'foo', {\n enumerable: true,\n writable: true,\n value: 'FOO'\n });\n\n equal(obj.foo, 'FOO', 'should have added property');\n\n obj.foo = \"BAR\";\n equal(obj.foo, 'BAR', 'writable defined property should be writable');\n equal(isEnumerable(obj, 'foo'), true, 'foo should be enumerable');\n});\n\ntest('defining a read only property', function() {\n var obj = {};\n Ember.platform.defineProperty(obj, 'foo', {\n enumerable: true,\n writable: false,\n value: 'FOO'\n });\n\n equal(obj.foo, 'FOO', 'should have added property');\n\n obj.foo = \"BAR\";\n if (Ember.platform.defineProperty.isSimulated) {\n equal(obj.foo, 'BAR', 'simulated defineProperty should silently work');\n } else {\n equal(obj.foo, 'FOO', 'real defined property should not be writable');\n }\n\n});\n\ntest('defining a non enumerable property', function() {\n var obj = {};\n Ember.platform.defineProperty(obj, 'foo', {\n enumerable: false,\n writable: true,\n value: 'FOO'\n });\n\n if (Ember.platform.defineProperty.isSimulated) {\n equal(isEnumerable(obj, 'foo'), true, 'simulated defineProperty will leave properties enumerable');\n } else {\n equal(isEnumerable(obj, 'foo'), false, 'real defineProperty will make property not-enumerable');\n }\n});\n\n// If accessors don't exist, behavior that relies on getters\n// and setters don't do anything\nif (Ember.platform.hasPropertyAccessors) {\n test('defining a getter/setter', function() {\n var obj = {}, getCnt = 0, setCnt = 0, v = 'FOO';\n\n var desc = {\n enumerable: true,\n get: function() { getCnt++; return v; },\n set: function(val) { setCnt++; v = val; }\n };\n\n if (Ember.platform.hasPropertyAccessors) {\n Ember.platform.defineProperty(obj, 'foo', desc);\n equal(obj.foo, 'FOO', 'should return getter');\n equal(getCnt, 1, 'should have invoked getter');\n\n obj.foo = 'BAR';\n equal(obj.foo, 'BAR', 'setter should have worked');\n equal(setCnt, 1, 'should have invoked setter');\n\n }\n\n });\n\n test('defining getter/setter along with writable', function() {\n var obj ={};\n raises(function() {\n Ember.platform.defineProperty(obj, 'foo', {\n enumerable: true,\n get: function() {},\n set: function() {},\n writable: true\n });\n }, Error, 'defining writable and get/set should throw exception');\n });\n\n test('defining getter/setter along with value', function() {\n var obj ={};\n raises(function() {\n Ember.platform.defineProperty(obj, 'foo', {\n enumerable: true,\n get: function() {},\n set: function() {},\n value: 'FOO'\n });\n }, Error, 'defining value and get/set should throw exception');\n });\n}\n\n})();\n//@ sourceURL=ember-metal/~tests/platform/defineProperty_test");minispade.register('ember-metal/~tests/properties_test', "(function() {module('Ember.defineProperty');\n\ntest('toString', function() {\n\n var obj = {};\n Ember.defineProperty(obj, 'toString', undefined, function() { return 'FOO'; });\n equal(obj.toString(), 'FOO', 'should replace toString');\n});\n\ntest(\"for data properties, didDefineProperty hook should be called if implemented\", function() {\n expect(2);\n\n var obj = {\n didDefineProperty: function(obj, keyName, value) {\n equal(keyName, 'foo', \"key name should be foo\");\n equal(value, 'bar', \"value should be bar\");\n }\n };\n\n Ember.defineProperty(obj, 'foo', undefined, \"bar\");\n});\n\ntest(\"for descriptor properties, didDefineProperty hook should be called if implemented\", function() {\n expect(2);\n\n var computedProperty = Ember.computed(Ember.K);\n\n var obj = {\n didDefineProperty: function(obj, keyName, value) {\n equal(keyName, 'foo', \"key name should be foo\");\n strictEqual(value, computedProperty, \"value should be passed descriptor\");\n }\n };\n\n Ember.defineProperty(obj, 'foo', computedProperty);\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/properties_test");minispade.register('ember-metal/~tests/props_helper', "(function() {/*global testBoth:true */\n\n// used by unit tests to test both accessor mode and non-accessor mode\ntestBoth = function(testname, callback) {\n test(testname+' using Ember.get()/Ember.set()', function() {\n callback(Ember.get, Ember.set);\n });\n\n // test(testname+' using accessors', function() {\n // if (Ember.USES_ACCESSORS) callback(aget, aset);\n // else ok('SKIPPING ACCESSORS');\n // });\n};\n\n})();\n//@ sourceURL=ember-metal/~tests/props_helper");minispade.register('ember-metal/~tests/run_loop/debounce_test', "(function() {var originalDebounce = Ember.run.backburner.debounce;\nvar wasCalled = false;\nmodule('Ember.run.debounce',{\n setup: function() {\n Ember.run.backburner.debounce = function() { wasCalled = true; };\n },\n teardown: function() {\n Ember.run.backburner.debounce = originalDebounce;\n }\n});\n\ntest('Ember.run.debounce uses Backburner.debounce', function() {\n Ember.run.debounce(function() {});\n ok(wasCalled, 'Ember.run.debounce used');\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/run_loop/debounce_test");minispade.register('ember-metal/~tests/run_loop/join_test', "(function() {module('system/run_loop/join_test');\n\ntest('Ember.run.join brings its own run loop if none provided', function() {\n ok(!Ember.run.currentRunLoop, 'expects no existing run-loop');\n\n Ember.run.join(function() {\n ok(Ember.run.currentRunLoop, 'brings its own run loop');\n });\n});\n\ntest('Ember.run.join joins and existing run-loop, and fires its action queue.', function() {\n var outerRunLoop, wasInvoked;\n\n Ember.run(function() {\n outerRunLoop = Ember.run.currentRunLoop;\n\n Ember.run.join(function() {\n wasInvoked = true;\n deepEqual(outerRunLoop, Ember.run.currentRunLoop, 'joined the existing run-loop');\n });\n\n ok(!wasInvoked, 'expected the joined callback not be invoked yet');\n });\n ok(wasInvoked, 'expected the joined callback to have invoked');\n});\n\ntest('Ember.run.join returns a value if creating a new run-loop', function() {\n var value = 'returned value';\n\n var result = Ember.run.join(function() {\n return value;\n });\n\n equal(value, result, 'returns expected output');\n});\n\ntest('Ember.run.join returns undefined if joining another run-loop', function() {\n var value = 'returned value',\n result;\n\n Ember.run(function() {\n var result = Ember.run.join(function() {\n return value;\n });\n });\n\n equal(result, undefined, 'returns nothing');\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/run_loop/join_test");minispade.register('ember-metal/~tests/run_loop/later_test', "(function() {\nvar originalSetTimeout = window.setTimeout,\n originalDateValueOf = Date.prototype.valueOf;\n\nvar wait = function(callback, maxWaitCount) {\n maxWaitCount = Ember.isNone(maxWaitCount) ? 100 : maxWaitCount;\n\n originalSetTimeout(function() {\n if (maxWaitCount > 0 && (Ember.run.hasScheduledTimers() || Ember.run.currentRunLoop)) {\n wait(callback, maxWaitCount - 1);\n\n return;\n }\n\n callback();\n }, 10);\n};\n\nmodule('Ember.run.later', {\n teardown: function() {\n window.setTimeout = originalSetTimeout;\n Date.prototype.valueOf = originalDateValueOf;\n }\n});\n\nasyncTest('should invoke after specified period of time - function only', function() {\n\n var invoked = false;\n\n Ember.run(function() {\n Ember.run.later(function() { invoked = true; }, 100);\n });\n\n wait(function() {\n start();\n equal(invoked, true, 'should have invoked later item');\n });\n});\n\nasyncTest('should invoke after specified period of time - target/method', function() {\n\n var obj = { invoked: false } ;\n\n Ember.run(function() {\n Ember.run.later(obj, function() { this.invoked = true; }, 100);\n });\n\n wait(function() {\n start();\n equal(obj.invoked, true, 'should have invoked later item');\n });\n});\n\nasyncTest('should invoke after specified period of time - target/method/args', function() {\n\n var obj = { invoked: 0 } ;\n\n Ember.run(function() {\n Ember.run.later(obj, function(amt) { this.invoked += amt; }, 10, 100);\n });\n\n wait(function() {\n start();\n equal(obj.invoked, 10, 'should have invoked later item');\n });\n});\n\nasyncTest('should always invoke within a separate runloop', function() {\n var obj = { invoked: 0 }, firstRunLoop, secondRunLoop;\n\n Ember.run(function() {\n firstRunLoop = Ember.run.currentRunLoop;\n\n Ember.run.later(obj, function(amt) {\n this.invoked += amt;\n secondRunLoop = Ember.run.currentRunLoop;\n }, 10, 1);\n\n // Synchronous \"sleep\". This simulates work being done\n // after run.later was called but before the run loop\n // has flushed. In previous versions, this would have\n // caused the run.later callback to have run from\n // within the run loop flush, since by the time the\n // run loop has to flush, it would have considered\n // the timer already expired.\n var pauseUntil = +new Date() + 100;\n while(+new Date() < pauseUntil) { /* do nothing - sleeping */ }\n });\n\n ok(firstRunLoop, \"first run loop captured\");\n ok(!Ember.run.currentRunLoop, \"shouldn't be in a run loop after flush\");\n equal(obj.invoked, 0, \"shouldn't have invoked later item yet\");\n\n wait(function() {\n start();\n equal(obj.invoked, 10, \"should have invoked later item\");\n ok(secondRunLoop, \"second run loop took place\");\n ok(secondRunLoop !== firstRunLoop, \"two different run loops took place\");\n });\n});\n\n// Our current implementation doesn't allow us to correctly enforce this ordering.\n// We should probably implement a queue to provide this guarantee.\n// See https://github.com/emberjs/ember.js/issues/3526 for more information.\n\n// asyncTest('callback order', function() {\n// var array = [];\n// function fn(val) { array.push(val); }\n\n// Ember.run(function() {\n// Ember.run.later(this, fn, 4, 5);\n// Ember.run.later(this, fn, 1, 1);\n// Ember.run.later(this, fn, 5, 10);\n// Ember.run.later(this, fn, 2, 3);\n// Ember.run.later(this, fn, 3, 3);\n// });\n\n// deepEqual(array, []);\n\n// wait(function() {\n// start();\n// deepEqual(array, [1,2,3,4,5], 'callbacks were called in expected order');\n// });\n// });\n\n\n// Out current implementation doesn't allow us to properly enforce what is tested here.\n// We should probably fix it, but it's not technically a bug right now.\n// See https://github.com/emberjs/ember.js/issues/3522 for more information.\n\n// asyncTest('callbacks coalesce into same run loop if expiring at the same time', function() {\n// var array = [];\n// function fn(val) { array.push(Ember.run.currentRunLoop); }\n\n// Ember.run(function() {\n\n// // Force +new Date to return the same result while scheduling\n// // run.later timers. Otherwise: non-determinism!\n// var now = +new Date();\n// Date.prototype.valueOf = function() { return now; };\n\n// Ember.run.later(this, fn, 10);\n// Ember.run.later(this, fn, 200);\n// Ember.run.later(this, fn, 200);\n\n// Date.prototype.valueOf = originalDateValueOf;\n// });\n\n// deepEqual(array, []);\n\n// wait(function() {\n// start();\n// equal(array.length, 3, 'all callbacks called');\n// ok(array[0] !== array[1], 'first two callbacks have different run loops');\n// ok(array[0], 'first runloop present');\n// ok(array[1], 'second runloop present');\n// equal(array[1], array[2], 'last two callbacks got the same run loop');\n// });\n// });\n\nasyncTest('inception calls to run.later should run callbacks in separate run loops', function() {\n\n var runLoop, finished;\n\n Ember.run(function() {\n runLoop = Ember.run.currentRunLoop;\n ok(runLoop);\n\n Ember.run.later(function() {\n ok(Ember.run.currentRunLoop && Ember.run.currentRunLoop !== runLoop,\n 'first later callback has own run loop');\n runLoop = Ember.run.currentRunLoop;\n\n Ember.run.later(function() {\n ok(Ember.run.currentRunLoop && Ember.run.currentRunLoop !== runLoop,\n 'second later callback has own run loop');\n finished = true;\n }, 40);\n }, 40);\n });\n\n wait(function() {\n start();\n ok(finished, 'all .later callbacks run');\n });\n});\n\nasyncTest('setTimeout should never run with a negative wait', function() {\n\n // Rationale: The old run loop code was susceptible to an occasional\n // bug where invokeLaterTimers would be scheduled with a setTimeout\n // with a negative wait. Modern browsers normalize this to 0, but\n // older browsers (IE <= 8) break with a negative wait, which\n // happens when an expired timer callback takes a while to run,\n // which is what we simulate here.\n var newSetTimeoutUsed;\n window.setTimeout = function() {\n var wait = arguments[arguments.length - 1];\n newSetTimeoutUsed = true;\n ok(!isNaN(wait) && wait >= 0, 'wait is a non-negative number');\n // In IE8, `setTimeout.apply` is `undefined`.\n var apply = Function.prototype.apply;\n return apply.apply(originalSetTimeout, [this, arguments]);\n };\n\n var count = 0;\n Ember.run(function() {\n\n Ember.run.later(function() {\n count++;\n\n // This will get run first. Waste some time.\n // This is intended to break invokeLaterTimers code by taking a\n // long enough time that other timers should technically expire. It's\n // fine that they're not called in this run loop; just need to\n // make sure that invokeLaterTimers doesn't end up scheduling\n // a negative setTimeout.\n var pauseUntil = +new Date() + 60;\n while(+new Date() < pauseUntil) { /* do nothing - sleeping */ }\n }, 1);\n\n Ember.run.later(function() {\n equal(count, 1, 'callbacks called in order');\n }, 50);\n });\n\n wait(function() {\n window.setTimeout = originalSetTimeout;\n start();\n ok(newSetTimeoutUsed, 'stub setTimeout was used');\n });\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/run_loop/later_test");minispade.register('ember-metal/~tests/run_loop/next_test', "(function() {module('Ember.run.next');\n\nasyncTest('should invoke immediately on next timeout', function() {\n\n var invoked = false;\n\n Ember.run(function() {\n Ember.run.next(function() { invoked = true; });\n });\n\n equal(invoked, false, 'should not have invoked yet');\n\n\n setTimeout(function() {\n start();\n equal(invoked, true, 'should have invoked later item');\n }, 20);\n\n});\n\nasyncTest('callback should be called from within separate loop', function() {\n var firstRunLoop, secondRunLoop;\n Ember.run(function() {\n firstRunLoop = Ember.run.currentRunLoop;\n Ember.run.next(function() { secondRunLoop = Ember.run.currentRunLoop; });\n });\n\n setTimeout(function() {\n start();\n ok(secondRunLoop, 'callback was called from within run loop');\n ok(firstRunLoop && secondRunLoop !== firstRunLoop, 'two seperate run loops were invoked');\n }, 20);\n});\n\nasyncTest('multiple calls to Ember.run.next share coalesce callbacks into same run loop', function() {\n var firstRunLoop, secondRunLoop, thirdRunLoop;\n Ember.run(function() {\n firstRunLoop = Ember.run.currentRunLoop;\n Ember.run.next(function() { secondRunLoop = Ember.run.currentRunLoop; });\n Ember.run.next(function() { thirdRunLoop = Ember.run.currentRunLoop; });\n });\n\n setTimeout(function() {\n start();\n ok(secondRunLoop && secondRunLoop === thirdRunLoop, 'callbacks coalesced into same run loop');\n }, 20);\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/run_loop/next_test");minispade.register('ember-metal/~tests/run_loop/once_test', "(function() {module('system/run_loop/once_test');\n\ntest('calling invokeOnce more than once invokes only once', function() {\n\n var count = 0;\n Ember.run(function() {\n var F = function() { count++; };\n Ember.run.once(F);\n Ember.run.once(F);\n Ember.run.once(F);\n });\n\n equal(count, 1, 'should have invoked once');\n});\n\ntest('should differentiate based on target', function() {\n\n var A = { count: 0 }, B = { count: 0 };\n Ember.run(function() {\n var F = function() { this.count++; };\n Ember.run.once(A, F);\n Ember.run.once(B, F);\n Ember.run.once(A, F);\n Ember.run.once(B, F);\n });\n\n equal(A.count, 1, 'should have invoked once on A');\n equal(B.count, 1, 'should have invoked once on B');\n});\n\n\ntest('should ignore other arguments - replacing previous ones', function() {\n\n var A = { count: 0 }, B = { count: 0 };\n Ember.run(function() {\n var F = function(amt) { this.count += amt; };\n Ember.run.once(A, F, 10);\n Ember.run.once(B, F, 20);\n Ember.run.once(A, F, 30);\n Ember.run.once(B, F, 40);\n });\n\n equal(A.count, 30, 'should have invoked once on A');\n equal(B.count, 40, 'should have invoked once on B');\n});\n\ntest('should be inside of a runloop when running', function() {\n\n Ember.run(function() {\n Ember.run.once(function() {\n ok(!!Ember.run.currentRunLoop, 'should have a runloop');\n });\n });\n});\n\n\n\n})();\n//@ sourceURL=ember-metal/~tests/run_loop/once_test");minispade.register('ember-metal/~tests/run_loop/onerror_test', "(function() {module('system/run_loop/onerror_test');\n\ntest('With Ember.onerror undefined, errors in Ember.run are thrown', function () {\n var thrown = new Error('Boom!'),\n caught;\n\n try {\n Ember.run(function() { throw thrown; });\n } catch (error) {\n caught = error;\n }\n\n deepEqual(caught, thrown);\n});\n\ntest('With Ember.onerror set, errors in Ember.run are caught', function () {\n var thrown = new Error('Boom!'),\n caught;\n\n Ember.onerror = function(error) { caught = error; };\n\n Ember.run(function() { throw thrown; });\n\n deepEqual(caught, thrown);\n\n Ember.onerror = undefined;\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/run_loop/onerror_test");minispade.register('ember-metal/~tests/run_loop/run_test', "(function() {module('system/run_loop/run_test');\n\ntest('Ember.run invokes passed function, returning value', function() {\n var obj = {\n foo: function() { return [this.bar, 'FOO']; },\n bar: 'BAR',\n checkArgs: function(arg1, arg2) { return [ arg1, this.bar, arg2 ]; }\n };\n\n equal(Ember.run(function() { return 'FOO'; }), 'FOO', 'pass function only');\n deepEqual(Ember.run(obj, obj.foo), ['BAR', 'FOO'], 'pass obj and obj.method');\n deepEqual(Ember.run(obj, 'foo'), ['BAR', 'FOO'], 'pass obj and \"method\"');\n deepEqual(Ember.run(obj, obj.checkArgs, 'hello', 'world'), ['hello', 'BAR', 'world'], 'pass obj, obj.method, and extra arguments');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/run_loop/run_test");minispade.register('ember-metal/~tests/run_loop/schedule_test', "(function() {module('system/run_loop/schedule_test');\n\ntest('scheduling item in queue should defer until finished', function() {\n var cnt = 0;\n\n Ember.run(function() {\n Ember.run.schedule('actions', function() { cnt++; });\n Ember.run.schedule('actions', function() { cnt++; });\n equal(cnt, 0, 'should not run action yet') ;\n });\n\n equal(cnt, 2, 'should flush actions now');\n\n});\n\ntest('nested runs should queue each phase independently', function() {\n var cnt = 0;\n\n Ember.run(function() {\n Ember.run.schedule('actions', function() { cnt++; });\n equal(cnt, 0, 'should not run action yet') ;\n\n Ember.run(function() {\n Ember.run.schedule('actions', function() { cnt++; });\n });\n equal(cnt, 1, 'should not run action yet') ;\n\n });\n\n equal(cnt, 2, 'should flush actions now');\n\n});\n\ntest('prior queues should be flushed before moving on to next queue', function() {\n var order = [];\n\n Ember.run(function() {\n var runLoop = Ember.run.currentRunLoop;\n ok(runLoop, 'run loop present');\n\n Ember.run.schedule('sync', function() {\n order.push('sync');\n equal(runLoop, Ember.run.currentRunLoop, 'same run loop used');\n });\n Ember.run.schedule('actions', function() {\n order.push('actions');\n equal(runLoop, Ember.run.currentRunLoop, 'same run loop used');\n\n Ember.run.schedule('actions', function() {\n order.push('actions');\n equal(runLoop, Ember.run.currentRunLoop, 'same run loop used');\n });\n\n Ember.run.schedule('sync', function() {\n order.push('sync');\n equal(runLoop, Ember.run.currentRunLoop, 'same run loop used');\n });\n });\n Ember.run.schedule('destroy', function() {\n order.push('destroy');\n equal(runLoop, Ember.run.currentRunLoop, 'same run loop used');\n });\n });\n\n deepEqual(order, ['sync', 'actions', 'sync', 'actions', 'destroy']);\n});\n\ntest('makes sure it does not trigger an autorun during testing', function() {\n expectAssertion(function() {\n Ember.run.schedule('actions', function() {});\n }, /wrap any code with asynchronous side-effects in an Ember.run/);\n\n // make sure not just the first violation is asserted.\n expectAssertion(function() {\n Ember.run.schedule('actions', function() {});\n }, /wrap any code with asynchronous side-effects in an Ember.run/);\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/run_loop/schedule_test");minispade.register('ember-metal/~tests/run_loop/sync_test', "(function() {module('system/run_loop/sync_test');\n\ntest('sync() will immediately flush the sync queue only', function() {\n var cnt = 0;\n\n Ember.run(function() {\n\n function cntup() { cnt++; }\n\n function syncfunc() {\n if (++cnt<5) Ember.run.schedule('sync', syncfunc);\n Ember.run.schedule('actions', cntup);\n }\n\n syncfunc();\n\n equal(cnt, 1, 'should not run action yet') ;\n Ember.run.sync();\n\n equal(cnt, 5, 'should have run sync queue continuously');\n });\n\n equal(cnt, 10, 'should flush actions now too');\n\n});\n\ntest('calling sync() outside a run loop does not cause an error', function() {\n expect(0);\n\n Ember.run.sync();\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/run_loop/sync_test");minispade.register('ember-metal/~tests/run_loop/unwind_test', "(function() {module('system/run_loop/unwind_test');\n\ntest('RunLoop unwinds despite unhandled exception', function() {\n var initialRunLoop = Ember.run.currentRunLoop;\n\n raises(function() {\n Ember.run(function() {\n Ember.run.schedule('actions', function() { throw new Ember.Error(\"boom!\"); });\n });\n }, Error, \"boom!\");\n\n // The real danger at this point is that calls to autorun will stick\n // tasks into the already-dead runloop, which will never get\n // flushed. I can't easily demonstrate this in a unit test because\n // autorun explicitly doesn't work in test mode. - ef4\n equal(Ember.run.currentRunLoop, initialRunLoop, \"Previous run loop should be cleaned up despite exception\");\n\n // Prevent a failure in this test from breaking subsequent tests.\n Ember.run.currentRunLoop = initialRunLoop;\n\n});\n\ntest('Ember.run unwinds despite unhandled exception', function() {\n var initialRunLoop = Ember.run.currentRunLoop;\n\n raises(function() {\n Ember.run(function() {\n throw new Ember.Error(\"boom!\");\n });\n }, Ember.Error, \"boom!\");\n\n equal(Ember.run.currentRunLoop, initialRunLoop, \"Previous run loop should be cleaned up despite exception\");\n\n // Prevent a failure in this test from breaking subsequent tests.\n Ember.run.currentRunLoop = initialRunLoop;\n\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/run_loop/unwind_test");minispade.register('ember-metal/~tests/utils/can_invoke_test', "(function() {var obj;\n\nmodule(\"Ember.canInvoke\", {\n setup: function() {\n obj = {\n foobar: \"foobar\",\n aMethodThatExists: function() {}\n };\n },\n\n teardown: function() {\n obj = undefined;\n }\n});\n\ntest(\"should return false if the object doesn't exist\", function() {\n equal(Ember.canInvoke(undefined, 'aMethodThatDoesNotExist'), false);\n});\n\ntest(\"should return true if the method exists on the object\", function() {\n equal(Ember.canInvoke(obj, 'aMethodThatExists'), true);\n});\n\ntest(\"should return false if the method doesn't exist on the object\", function() {\n equal(Ember.canInvoke(obj, 'aMethodThatDoesNotExist'), false);\n});\n\ntest(\"should return false if the property exists on the object but is a non-function\", function() {\n equal(Ember.canInvoke(obj, 'foobar'), false);\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/utils/can_invoke_test");minispade.register('ember-metal/~tests/utils/generate_guid_test', "(function() {module(\"Ember.generateGuid\");\n\ntest(\"Prefix\", function() {\n var a = {};\n \n ok( Ember.generateGuid(a, 'tyrell').indexOf('tyrell') > -1, \"guid can be prefixed\" );\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/utils/generate_guid_test");minispade.register('ember-metal/~tests/utils/guidFor_test', "(function() {module(\"Ember.guidFor\");\n\nvar sameGuid = function(a, b, message) {\n equal( Ember.guidFor(a), Ember.guidFor(b), message );\n};\n\nvar diffGuid = function(a, b, message) {\n ok( Ember.guidFor(a) !== Ember.guidFor(b), message);\n};\n\nvar nanGuid = function(obj) {\n var type = typeof obj;\n ok( isNaN(parseInt(Ember.guidFor(obj), 0)), \"guids for \" + type + \"don't parse to numbers\");\n};\n\ntest(\"Object\", function() {\n var a = {}, b = {};\n\n sameGuid( a, a, \"same object always yields same guid\" );\n diffGuid( a, b, \"different objects yield different guids\" );\n nanGuid( a );\n});\n\ntest(\"Object with prototype\", function() {\n var Class = function() { };\n\n Ember.guidFor(Class.prototype);\n\n var a = new Class();\n var b = new Class();\n\n sameGuid( a, b , \"without calling rewatch, objects copy the guid from their prototype\");\n\n Ember.rewatch(a);\n Ember.rewatch(b);\n\n diffGuid( a, b, \"after calling rewatch, objects don't share guids\" );\n});\n\ntest(\"strings\", function() {\n var a = \"string A\", aprime = \"string A\", b = \"String B\";\n\n sameGuid( a, a, \"same string always yields same guid\" );\n sameGuid( a, aprime, \"identical strings always yield the same guid\" );\n diffGuid( a, b, \"different strings yield different guids\" );\n nanGuid( a );\n});\n\ntest(\"numbers\", function() {\n var a = 23, aprime = 23, b = 34;\n\n sameGuid( a, a, \"same numbers always yields same guid\" );\n sameGuid( a, aprime, \"identical numbers always yield the same guid\" );\n diffGuid( a, b, \"different numbers yield different guids\" );\n nanGuid( a );\n});\n\ntest(\"numbers\", function() {\n var a = true, aprime = true, b = false;\n\n sameGuid( a, a, \"same booleans always yields same guid\" );\n sameGuid( a, aprime, \"identical booleans always yield the same guid\" );\n diffGuid( a, b, \"different boolean yield different guids\" );\n nanGuid( a );\n nanGuid( b );\n});\n\ntest(\"null and undefined\", function() {\n var a = null, aprime = null, b;\n\n sameGuid( a, a, \"null always returns the same guid\" );\n sameGuid( b, b, \"undefined always returns the same guid\" );\n sameGuid( a, aprime, \"different nulls return the same guid\" );\n diffGuid( a, b, \"null and undefined return different guids\" );\n nanGuid( a );\n nanGuid( b );\n});\n\ntest(\"arrays\", function() {\n var a = [\"a\", \"b\", \"c\"], aprime = [\"a\", \"b\", \"c\"], b = [\"1\", \"2\", \"3\"];\n\n sameGuid( a, a, \"same instance always yields same guid\" );\n diffGuid( a, aprime, \"identical arrays always yield the same guid\" );\n diffGuid( a, b, \"different arrays yield different guids\" );\n nanGuid( a );\n});\n\n\n})();\n//@ sourceURL=ember-metal/~tests/utils/guidFor_test");minispade.register('ember-metal/~tests/utils/is_array_test', "(function() {module(\"Ember Type Checking\");\n\nvar global = this;\n\ntest(\"Ember.isArray\" ,function() {\n var numarray = [1,2,3],\n number = 23,\n strarray = [\"Hello\", \"Hi\"],\n string = \"Hello\",\n object = {},\n length = {length: 12},\n fn = function() {};\n\n equal( Ember.isArray(numarray), true, \"[1,2,3]\" );\n equal( Ember.isArray(number), false, \"23\" );\n equal( Ember.isArray(strarray), true, '[\"Hello\", \"Hi\"]' );\n equal( Ember.isArray(string), false, '\"Hello\"' );\n equal( Ember.isArray(object), false, \"{}\" );\n equal( Ember.isArray(length), true, \"{length: 12}\" );\n equal( Ember.isArray(global), false, \"global\" );\n equal( Ember.isArray(fn), false, \"function() {}\" );\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/utils/is_array_test");minispade.register('ember-metal/~tests/utils/meta_test', "(function() {/*global jQuery*/\n\nmodule(\"Ember.meta\");\n\ntest(\"should return the same hash for an object\", function() {\n var obj = {};\n\n Ember.meta(obj).foo = \"bar\";\n\n equal(Ember.meta(obj).foo, \"bar\", \"returns same hash with multiple calls to Ember.meta()\");\n});\n\nmodule(\"Ember.metaPath\", {\n setup: function() {\n Ember.TESTING_DEPRECATION = true;\n },\n teardown: function() {\n Ember.TESTING_DEPRECATION = false;\n }\n});\n\ntest(\"should not create nested objects if writable is false\", function() {\n var obj = {};\n\n ok(!Ember.meta(obj).foo, \"precond - foo property on meta does not yet exist\");\n equal(Ember.metaPath(obj, ['foo', 'bar', 'baz'], false), undefined, \"should return undefined when writable is false and doesn't already exist\") ;\n equal(Ember.meta(obj).foo, undefined, \"foo property is not created\");\n});\n\ntest(\"should create nested objects if writable is true\", function() {\n var obj = {};\n\n ok(!Ember.meta(obj).foo, \"precond - foo property on meta does not yet exist\");\n\n equal(typeof Ember.metaPath(obj, ['foo', 'bar', 'baz'], true), \"object\", \"should return hash when writable is true and doesn't already exist\") ;\n ok(Ember.meta(obj).foo.bar.baz['bat'] = true, \"can set a property on the newly created hash\");\n});\n\ntest(\"getMeta and setMeta\", function() {\n var obj = {};\n\n ok(!Ember.getMeta(obj, 'foo'), \"precond - foo property on meta does not yet exist\");\n Ember.setMeta(obj, 'foo', \"bar\");\n equal(Ember.getMeta(obj, 'foo'), \"bar\", \"foo property on meta now exists\");\n});\n\nmodule(\"Ember.meta enumerable\");\n// Tests fix for https://github.com/emberjs/ember.js/issues/344\n// This is primarily for older browsers such as IE8\nif (Ember.platform.defineProperty.isSimulated) {\n if (Ember.imports.jQuery) {\n test(\"meta is not jQuery.isPlainObject\", function () {\n var proto, obj;\n proto = {foo: 'bar'};\n equal(jQuery.isPlainObject(Ember.meta(proto)), false, 'meta should not be isPlainObject when meta property cannot be marked as enumerable: false');\n obj = Ember.create(proto);\n equal(jQuery.isPlainObject(Ember.meta(obj)), false, 'meta should not be isPlainObject when meta property cannot be marked as enumerable: false');\n });\n }\n} else {\n test(\"meta is not enumerable\", function () {\n var proto, obj, props, prop;\n proto = {foo: 'bar'};\n Ember.meta(proto);\n obj = Ember.create(proto);\n Ember.meta(obj);\n obj.bar = 'baz';\n props = [];\n for (prop in obj) {\n props.push(prop);\n }\n deepEqual(props.sort(), ['bar', 'foo']);\n if (typeof JSON !== 'undefined' && 'stringify' in JSON) {\n try {\n JSON.stringify(obj);\n } catch (e) {\n ok(false, 'meta should not fail JSON.stringify');\n }\n }\n });\n}\n\n})();\n//@ sourceURL=ember-metal/~tests/utils/meta_test");minispade.register('ember-metal/~tests/utils/try_catch_finally_test', "(function() {var tryCount, catchCount, finalizeCount, tryable, catchable, finalizer, error,\ntryableResult, catchableResult, finalizerResult;\n\nmodule(\"Ember.tryFinally\", {\n setup: function() {\n error = new Error('Test Error');\n tryCount = 0;\n finalizeCount = 0;\n catchCount = 0;\n tryableResult = 'tryable return value';\n catchableResult = 'catchable return value';\n finalizerResult = undefined;\n\n tryable = function() { tryCount++; return tryableResult; };\n catchable = function() { catchCount++; return catchableResult; };\n finalizer = function() { finalizeCount++; return finalizerResult; };\n },\n\n teardown: function() {\n tryCount = catchCount, finalizeCount = tryable = catchable = finalizer =\n finalizeCount =tryableResult = null;\n }\n});\n\nfunction callTryCatchFinallyWithError() {\n var errorWasThrown;\n try {\n Ember.tryCatchFinally(tryable, catchable, finalizer);\n } catch(e) {\n errorWasThrown = true;\n equal(e, error, 'correct error was thrown');\n }\n\n equal(errorWasThrown, true, 'error was thrown');\n}\n\ntest(\"no failure\", function() {\n equal(Ember.tryCatchFinally(tryable, catchable, finalizer), tryableResult, 'correct return value');\n\n equal(tryCount, 1, 'tryable was called once');\n equal(catchCount, 0, 'catchable was never called');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"no failure, return from finally\", function() {\n finalizerResult = 'finalizer return value';\n\n equal(Ember.tryCatchFinally(tryable, catchable, finalizer), finalizerResult, 'correct return value');\n\n equal(tryCount, 1, 'tryable was called once');\n equal(catchCount, 0, 'catchable was never called');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"try failed\", function() {\n tryable = function() { tryCount++; throw error; };\n\n var result = Ember.tryCatchFinally(tryable, catchable, finalizer);\n\n equal(result, catchableResult, 'correct return value');\n\n equal(tryCount, 1, 'tryable was called once');\n equal(catchCount, 1, 'catchable was called once');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"catch failed\", function() {\n catchable = function() { catchCount++; throw error; };\n\n Ember.tryCatchFinally(tryable, catchable, finalizer);\n\n equal(tryCount, 1, 'tryable was called once');\n equal(catchCount, 0, 'catchable was called once');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"try and catch failed\", function() {\n tryable = function() { tryCount++; throw error; };\n catchable = function() { catchCount++; throw error; };\n\n callTryCatchFinallyWithError();\n\n equal(tryCount, 1, 'tryable was called once');\n equal(catchCount, 1, 'catchable was called once');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"finally failed\", function() {\n finalizer = function() { finalizeCount++; throw error; };\n\n callTryCatchFinallyWithError();\n\n equal(tryCount, 1, 'tryable was called once');\n equal(catchCount, 0, 'catchable was never called');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"finally and try failed\", function() {\n tryable = function() { tryCount++; throw error; };\n finalizer = function() { finalizeCount++; throw error; };\n\n callTryCatchFinallyWithError();\n\n equal(tryCount, 1, 'tryable was called once');\n equal(catchCount, 1, 'catchable was called once');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"finally, catch and try failed\", function() {\n tryable = function() { tryCount++; throw error; };\n catchable = function() { catchCount++; throw error; };\n finalizer = function() { finalizeCount++; throw error; };\n\n callTryCatchFinallyWithError();\n\n equal(tryCount, 1, 'tryable was called once');\n equal(catchCount, 1, 'catchable was called once');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/utils/try_catch_finally_test");minispade.register('ember-metal/~tests/utils/try_finally_test', "(function() {var tryCount, finalizeCount, tryable, finalizer, error, tryableResult, finalizerResult;\n\nmodule(\"Ember.tryFinally\", {\n setup: function() {\n error = new Error('Test Error');\n tryCount = 0;\n finalizeCount = 0;\n tryableResult = 'tryable return value';\n finalizerResult = undefined;\n\n tryable = function() { tryCount++; return tryableResult; };\n finalizer = function() { finalizeCount++; return finalizerResult; };\n },\n\n teardown: function() {\n tryCount = finalizeCount = tryable = finalizer = finalizeCount, tryableResult = null;\n }\n});\n\nfunction callTryFinallyWithError() {\n var errorWasThrown;\n try {\n Ember.tryFinally(tryable, finalizer);\n } catch(e) {\n errorWasThrown = true;\n equal(e, error, 'correct error was thrown');\n }\n\n equal(errorWasThrown, true, 'error was thrown');\n}\n\ntest(\"no failure\", function() {\n equal(Ember.tryFinally(tryable, finalizer), tryableResult, 'correct return value');\n\n equal(tryCount, 1, 'tryable was called once');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"no failure, return from finally\", function() {\n finalizerResult = 'finalizer return value';\n\n equal(Ember.tryFinally(tryable, finalizer), finalizerResult, 'crrect return value');\n\n equal(tryCount, 1, 'tryable was called once');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"try failed\", function() {\n tryable = function() { tryCount++; throw error; };\n\n callTryFinallyWithError();\n\n equal(tryCount, 1, 'tryable was called once');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"finally failed\", function() {\n finalizer = function() { finalizeCount++; throw error; };\n\n callTryFinallyWithError();\n\n equal(tryCount, 1, 'tryable was called once');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\ntest(\"finally and try failed\", function() {\n tryable = function() { tryCount++; throw error; };\n finalizer = function() { finalizeCount++; throw error; };\n\n callTryFinallyWithError();\n\n equal(tryCount, 1, 'tryable was called once');\n equal(finalizeCount, 1, 'finalize was called once');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/utils/try_finally_test");minispade.register('ember-metal/~tests/utils/try_invoke_test', "(function() {var obj;\n\nmodule(\"Ember.tryInvoke\", {\n setup: function() {\n obj = {\n aMethodThatExists: function() { return true; },\n aMethodThatTakesArguments: function(arg1, arg2) { return arg1 === arg2; }\n };\n },\n\n teardown: function() {\n obj = undefined;\n }\n});\n\ntest(\"should return undefined when the object doesn't exist\", function() {\n equal(Ember.tryInvoke(undefined, 'aMethodThatDoesNotExist'), undefined);\n});\n\ntest(\"should return undefined when asked to perform a method that doesn't exist on the object\", function() {\n equal(Ember.tryInvoke(obj, 'aMethodThatDoesNotExist'), undefined);\n});\n\ntest(\"should return what the method returns when asked to perform a method that exists on the object\", function() {\n equal(Ember.tryInvoke(obj, 'aMethodThatExists'), true);\n});\n\ntest(\"should return what the method returns when asked to perform a method that takes arguments and exists on the object\", function() {\n equal(Ember.tryInvoke(obj, 'aMethodThatTakesArguments', [true, true]), true);\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/utils/try_invoke_test");minispade.register('ember-metal/~tests/watching/isWatching_test', "(function() {module('Ember.isWatching');\n\nvar testObserver = function(setup, teardown, key) {\n var obj = {}, fn = function() {};\n key = key || 'foo';\n\n equal(Ember.isWatching(obj, key), false, \"precond - isWatching is false by default\");\n setup(obj, key, fn);\n equal(Ember.isWatching(obj, key), true, \"isWatching is true when observers are added\");\n teardown(obj, key, fn);\n equal(Ember.isWatching(obj, key), false, \"isWatching is false after observers are removed\");\n};\n\ntest(\"isWatching is true for regular local observers\", function() {\n testObserver(function(obj, key, fn) {\n Ember.Mixin.create({\n didChange: Ember.observer(key, fn)\n }).apply(obj);\n }, function(obj, key, fn) {\n Ember.removeObserver(obj, key, obj, fn);\n });\n});\n\ntest(\"isWatching is true for nonlocal observers\", function() {\n testObserver(function(obj, key, fn) {\n Ember.addObserver(obj, key, obj, fn);\n }, function(obj, key, fn) {\n Ember.removeObserver(obj, key, obj, fn);\n });\n});\n\ntest(\"isWatching is true for chained observers\", function() {\n testObserver(function(obj, key, fn) {\n Ember.addObserver(obj, key + '.bar', obj, fn);\n }, function(obj, key, fn) {\n Ember.removeObserver(obj, key + '.bar', obj, fn);\n });\n});\n\ntest(\"isWatching is true for computed properties\", function() {\n testObserver(function(obj, key, fn) {\n Ember.defineProperty(obj, 'computed', Ember.computed(fn).property(key));\n Ember.get(obj, 'computed');\n }, function(obj, key, fn) {\n Ember.defineProperty(obj, 'computed', null);\n });\n});\n\ntest(\"isWatching is true for chained computed properties\", function() {\n testObserver(function(obj, key, fn) {\n Ember.defineProperty(obj, 'computed', Ember.computed(fn).property(key + '.bar'));\n Ember.get(obj, 'computed');\n }, function(obj, key, fn) {\n Ember.defineProperty(obj, 'computed', null);\n });\n});\n\n// can't watch length on Array - it is special...\n// But you should be able to watch a length property of an object\ntest(\"isWatching is true for 'length' property on object\", function() {\n testObserver(function(obj, key, fn) {\n Ember.defineProperty(obj, 'length', null, '26.2 miles');\n Ember.addObserver(obj, 'length', obj, fn);\n }, function(obj, key, fn) {\n Ember.removeObserver(obj, 'length', obj, fn);\n }, 'length');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/watching/isWatching_test");minispade.register('ember-metal/~tests/watching/unwatch_test', "(function() {/*globals testBoth */\nminispade.require('ember-metal/~tests/props_helper');\n\nvar willCount = 0 , didCount = 0,\n willChange = Ember.propertyWillChange,\n didChange = Ember.propertyDidChange;\n\nmodule('Ember.unwatch', {\n setup: function() {\n willCount = didCount = 0;\n Ember.propertyWillChange = function(cur, keyName) {\n willCount++;\n willChange.call(this, cur, keyName);\n };\n\n Ember.propertyDidChange = function(cur, keyName) {\n didCount++;\n didChange.call(this, cur, keyName);\n };\n },\n\n teardown: function() {\n Ember.propertyWillChange = willChange;\n Ember.propertyDidChange = didChange;\n }\n});\n\nif (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {\n testBoth(\"unwatching multiple properties specified via brace expansion\", function(get, set) {\n var obj = { foo: null, bar: null, baz: null };\n\n Ember.watch(obj, 'foo');\n Ember.watch(obj, 'bar');\n Ember.watch(obj, 'baz');\n \n equal(Ember.isWatching(obj, 'foo'), true, \"precond - initially watching foo\");\n equal(Ember.isWatching(obj, 'bar'), true, \"precond - initially watching bar\");\n equal(Ember.isWatching(obj, 'baz'), true, \"precond - initially watching baz\");\n\n Ember.unwatch(obj, '{foo,bar,baz}');\n\n equal(Ember.isWatching(obj, 'foo'), false, \"unwatching foo from brace expansion\");\n equal(Ember.isWatching(obj, 'bar'), false, \"unwatching bar from brace expansion\");\n equal(Ember.isWatching(obj, 'baz'), false, \"unwatching baz from brace expansion\");\n });\n}\n\ntestBoth('unwatching a computed property - regular get/set', function(get, set) {\n\n var obj = {};\n Ember.defineProperty(obj, 'foo', Ember.computed(function(keyName, value) {\n if (value !== undefined) this.__foo = value;\n return this.__foo;\n }));\n\n Ember.watch(obj, 'foo');\n set(obj, 'foo', 'bar');\n equal(willCount, 1, 'should have invoked willCount');\n equal(didCount, 1, 'should have invoked didCount');\n\n Ember.unwatch(obj, 'foo');\n willCount = didCount = 0;\n set(obj, 'foo', 'BAZ');\n equal(willCount, 0, 'should NOT have invoked willCount');\n equal(didCount, 0, 'should NOT have invoked didCount');\n});\n\n\ntestBoth('unwatching a regular property - regular get/set', function(get, set) {\n\n var obj = { foo: 'BIFF' };\n\n Ember.watch(obj, 'foo');\n set(obj, 'foo', 'bar');\n equal(willCount, 1, 'should have invoked willCount');\n equal(didCount, 1, 'should have invoked didCount');\n\n Ember.unwatch(obj, 'foo');\n willCount = didCount = 0;\n set(obj, 'foo', 'BAZ');\n equal(willCount, 0, 'should NOT have invoked willCount');\n equal(didCount, 0, 'should NOT have invoked didCount');\n});\n\ntest('unwatching should be nested', function() {\n\n var obj = { foo: 'BIFF' };\n\n Ember.watch(obj, 'foo');\n Ember.watch(obj, 'foo');\n Ember.set(obj, 'foo', 'bar');\n equal(willCount, 1, 'should have invoked willCount');\n equal(didCount, 1, 'should have invoked didCount');\n\n Ember.unwatch(obj, 'foo');\n willCount = didCount = 0;\n Ember.set(obj, 'foo', 'BAZ');\n equal(willCount, 1, 'should NOT have invoked willCount');\n equal(didCount, 1, 'should NOT have invoked didCount');\n\n Ember.unwatch(obj, 'foo');\n willCount = didCount = 0;\n Ember.set(obj, 'foo', 'BAZ');\n equal(willCount, 0, 'should NOT have invoked willCount');\n equal(didCount, 0, 'should NOT have invoked didCount');\n});\n\ntestBoth('unwatching \"length\" property on an object', function(get, set) {\n\n var obj = { foo: 'RUN' };\n\n // Can watch length when it is undefined\n Ember.watch(obj, 'length');\n set(obj, 'length', '10k');\n equal(willCount, 1, 'should have invoked willCount');\n equal(didCount, 1, 'should have invoked didCount');\n\n // Should stop watching despite length now being defined (making object 'array-like')\n Ember.unwatch(obj, 'length');\n willCount = didCount = 0;\n set(obj, 'length', '5k');\n equal(willCount, 0, 'should NOT have invoked willCount');\n equal(didCount, 0, 'should NOT have invoked didCount');\n\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/watching/unwatch_test");minispade.register('ember-metal/~tests/watching/watch_test', "(function() {/*globals Global:true */\nminispade.require('ember-metal/~tests/props_helper');\n\nvar willCount, didCount,\n willKeys, didKeys,\n indexOf = Ember.EnumerableUtils.indexOf;\n\nmodule('Ember.watch', {\n setup: function() {\n willCount = didCount = 0;\n willKeys = [];\n didKeys = [];\n }\n});\n\nfunction addListeners(obj, keyPath) {\n Ember.addListener(obj, keyPath + ':before', function() {\n willCount++;\n willKeys.push(keyPath);\n });\n Ember.addListener(obj, keyPath + ':change', function() {\n didCount++;\n didKeys.push(keyPath);\n });\n}\n\nif (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {\n testBoth(\"watching multiple properties specified via brace expansion\", function(get, set) {\n var obj = { foo: null, bar: null, baz: null };\n\n equal(Ember.isWatching(obj, 'foo'), false, \"precond - not initially watching foo\");\n equal(Ember.isWatching(obj, 'bar'), false, \"precond - not initially watching bar\");\n equal(Ember.isWatching(obj, 'baz'), false, \"precond - not initially watching baz\");\n\n Ember.watch(obj, '{foo,bar,baz}');\n\n equal(Ember.isWatching(obj, 'foo'), true, \"watching foo from brace expansion\");\n equal(Ember.isWatching(obj, 'bar'), true, \"watching bar from brace expansion\");\n equal(Ember.isWatching(obj, 'baz'), true, \"watching baz from brace expansion\");\n });\n}\n\ntestBoth('watching a computed property', function(get, set) {\n\n var obj = {};\n Ember.defineProperty(obj, 'foo', Ember.computed(function(keyName, value) {\n if (value !== undefined) this.__foo = value;\n return this.__foo;\n }));\n addListeners(obj, 'foo');\n\n Ember.watch(obj, 'foo');\n set(obj, 'foo', 'bar');\n equal(willCount, 1, 'should have invoked willCount');\n equal(didCount, 1, 'should have invoked didCount');\n});\n\ntestBoth('watching a regular defined property', function(get, set) {\n\n var obj = { foo: 'baz' };\n addListeners(obj, 'foo');\n\n Ember.watch(obj, 'foo');\n equal(get(obj, 'foo'), 'baz', 'should have original prop');\n\n set(obj, 'foo', 'bar');\n equal(willCount, 1, 'should have invoked willCount');\n equal(didCount, 1, 'should have invoked didCount');\n\n equal(get(obj, 'foo'), 'bar', 'should get new value');\n equal(obj.foo, 'bar', 'property should be accessible on obj');\n});\n\ntestBoth('watching a regular undefined property', function(get, set) {\n\n var obj = { };\n addListeners(obj, 'foo');\n\n Ember.watch(obj, 'foo');\n\n equal('foo' in obj, false, 'precond undefined');\n\n set(obj, 'foo', 'bar');\n\n equal(willCount, 1, 'should have invoked willCount');\n equal(didCount, 1, 'should have invoked didCount');\n\n equal(get(obj, 'foo'), 'bar', 'should get new value');\n equal(obj.foo, 'bar', 'property should be accessible on obj');\n});\n\ntestBoth('watches should inherit', function(get, set) {\n\n var obj = { foo: 'baz' };\n var objB = Ember.create(obj);\n\n addListeners(obj, 'foo');\n Ember.watch(obj, 'foo');\n equal(get(obj, 'foo'), 'baz', 'should have original prop');\n\n set(obj, 'foo', 'bar');\n set(objB, 'foo', 'baz');\n equal(willCount, 2, 'should have invoked willCount once only');\n equal(didCount, 2, 'should have invoked didCount once only');\n});\n\ntest(\"watching an object THEN defining it should work also\", function() {\n\n var obj = {};\n addListeners(obj, 'foo');\n\n Ember.watch(obj, 'foo');\n\n Ember.defineProperty(obj, 'foo');\n Ember.set(obj, 'foo', 'bar');\n\n equal(Ember.get(obj, 'foo'), 'bar', 'should have set');\n equal(willCount, 1, 'should have invoked willChange once');\n equal(didCount, 1, 'should have invoked didChange once');\n\n});\n\ntest(\"watching a chain then defining the property\", function () {\n var obj = {};\n var foo = {bar: 'bar'};\n addListeners(obj, 'foo.bar');\n addListeners(foo, 'bar');\n\n Ember.watch(obj, 'foo.bar');\n\n Ember.defineProperty(obj, 'foo', undefined, foo);\n Ember.set(foo, 'bar', 'baz');\n\n deepEqual(willKeys, ['foo.bar', 'bar'], 'should have invoked willChange with bar, foo.bar');\n deepEqual(didKeys, ['foo.bar', 'bar'], 'should have invoked didChange with bar, foo.bar');\n equal(willCount, 2, 'should have invoked willChange twice');\n equal(didCount, 2, 'should have invoked didChange twice');\n});\n\ntest(\"watching a chain then defining the nested property\", function () {\n var bar = {};\n var obj = {foo: bar};\n var baz = {baz: 'baz'};\n addListeners(obj, 'foo.bar.baz');\n addListeners(baz, 'baz');\n\n Ember.watch(obj, 'foo.bar.baz');\n\n Ember.defineProperty(bar, 'bar', undefined, baz);\n Ember.set(baz, 'baz', 'BOO');\n\n deepEqual(willKeys, ['foo.bar.baz', 'baz'], 'should have invoked willChange with bar, foo.bar');\n deepEqual(didKeys, ['foo.bar.baz', 'baz'], 'should have invoked didChange with bar, foo.bar');\n equal(willCount, 2, 'should have invoked willChange twice');\n equal(didCount, 2, 'should have invoked didChange twice');\n});\n\ntestBoth('watching an object value then unwatching should restore old value', function(get, set) {\n\n var obj = { foo: { bar: { baz: { biff: 'BIFF' } } } };\n addListeners(obj, 'foo.bar.baz.biff');\n\n Ember.watch(obj, 'foo.bar.baz.biff');\n\n var foo = Ember.get(obj, 'foo');\n equal(get(get(get(foo, 'bar'), 'baz'), 'biff'), 'BIFF', 'biff should exist');\n\n Ember.unwatch(obj, 'foo.bar.baz.biff');\n equal(get(get(get(foo, 'bar'), 'baz'), 'biff'), 'BIFF', 'biff should exist');\n});\n\ntestBoth('watching a global object that does not yet exist should queue', function(get, set) {\n Global = null;\n\n var obj = {};\n addListeners(obj, 'Global.foo');\n\n Ember.watch(obj, 'Global.foo'); // only works on global chained props\n\n equal(willCount, 0, 'should not have fired yet');\n equal(didCount, 0, 'should not have fired yet');\n\n Global = { foo: 'bar' };\n addListeners(Global, 'foo');\n\n Ember.watch.flushPending(); // this will also be invoked automatically on ready\n\n equal(willCount, 0, 'should not have fired yet');\n equal(didCount, 0, 'should not have fired yet');\n\n set(Global, 'foo', 'baz');\n\n // should fire twice because this is a chained property (once on key, once\n // on path)\n equal(willCount, 2, 'should be watching');\n equal(didCount, 2, 'should be watching');\n\n Global = null; // reset\n});\n\ntest('when watching a global object, destroy should remove chain watchers from the global object', function() {\n\n Global = { foo: 'bar' };\n var obj = {};\n addListeners(obj, 'Global.foo');\n\n Ember.watch(obj, 'Global.foo');\n\n var meta_Global = Ember.meta(Global);\n var chainNode = Ember.meta(obj).chains._chains.Global._chains.foo;\n var index = indexOf(meta_Global.chainWatchers.foo, chainNode);\n\n equal(meta_Global.watching.foo, 1, 'should be watching foo');\n strictEqual(meta_Global.chainWatchers.foo[index], chainNode, 'should have chain watcher');\n\n Ember.destroy(obj);\n\n index = indexOf(meta_Global.chainWatchers.foo, chainNode);\n equal(meta_Global.watching.foo, 0, 'should not be watching foo');\n equal(index, -1, 'should not have chain watcher');\n\n Global = null; // reset\n});\n\ntest('when watching another object, destroy should remove chain watchers from the other object', function() {\n\n var objA = {};\n var objB = {foo: 'bar'};\n objA.b = objB;\n addListeners(objA, 'b.foo');\n\n Ember.watch(objA, 'b.foo');\n\n var meta_objB = Ember.meta(objB);\n var chainNode = Ember.meta(objA).chains._chains.b._chains.foo;\n var index = indexOf(meta_objB.chainWatchers.foo, chainNode);\n\n equal(meta_objB.watching.foo, 1, 'should be watching foo');\n strictEqual(meta_objB.chainWatchers.foo[index], chainNode, 'should have chain watcher');\n\n Ember.destroy(objA);\n\n index = indexOf(meta_objB.chainWatchers.foo, chainNode);\n equal(meta_objB.watching.foo, 0, 'should not be watching foo');\n equal(index, -1, 'should not have chain watcher');\n});\n\n// TESTS for length property\n\ntestBoth('watching \"length\" property on an object', function(get, set) {\n\n var obj = { length: '26.2 miles' };\n addListeners(obj, 'length');\n\n Ember.watch(obj, 'length');\n equal(get(obj, 'length'), '26.2 miles', 'should have original prop');\n\n set(obj, 'length', '10k');\n equal(willCount, 1, 'should have invoked willCount');\n equal(didCount, 1, 'should have invoked didCount');\n\n equal(get(obj, 'length'), '10k', 'should get new value');\n equal(obj.length, '10k', 'property should be accessible on obj');\n});\n\ntestBoth('watching \"length\" property on an array', function(get, set) {\n\n var arr = [];\n addListeners(arr, 'length');\n\n Ember.watch(arr, 'length');\n equal(get(arr, 'length'), 0, 'should have original prop');\n\n set(arr, 'length', '10');\n equal(willCount, 0, 'should NOT have invoked willCount');\n equal(didCount, 0, 'should NOT have invoked didCount');\n\n equal(get(arr, 'length'), 10, 'should get new value');\n equal(arr.length, 10, 'property should be accessible on arr');\n});\n\n})();\n//@ sourceURL=ember-metal/~tests/watching/watch_test");minispade.register('ember-routing/~tests/helpers/action_test', "(function() {var dispatcher, view,\n ActionHelper = Ember.Handlebars.ActionHelper,\n originalRegisterAction = ActionHelper.registerAction;\n\nvar appendView = function() {\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n};\n\nmodule(\"Ember.Handlebars - action helper\", {\n setup: function() {\n dispatcher = Ember.EventDispatcher.create();\n dispatcher.setup();\n },\n\n teardown: function() {\n Ember.run(function() {\n dispatcher.destroy();\n if (view) { view.destroy(); }\n });\n }\n});\n\ntest(\"should output a data attribute with a guid\", function() {\n view = Ember.View.create({\n template: Ember.Handlebars.compile('edit')\n });\n\n appendView();\n\n ok(view.$('a').attr('data-ember-action').match(/\\d+/), \"A data-ember-action attribute with a guid was added\");\n});\n\ntest(\"should by default register a click event\", function() {\n var registeredEventName;\n\n ActionHelper.registerAction = function(actionName, options) {\n registeredEventName = options.eventName;\n };\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('edit')\n });\n\n appendView();\n\n equal(registeredEventName, 'click', \"The click event was properly registered\");\n\n ActionHelper.registerAction = originalRegisterAction;\n});\n\ntest(\"should allow alternative events to be handled\", function() {\n var registeredEventName;\n\n ActionHelper.registerAction = function(actionName, options) {\n registeredEventName = options.eventName;\n };\n\n view = Ember.View.create({\n template: Ember.Handlebars.compile('edit')\n });\n\n appendView();\n\n equal(registeredEventName, 'mouseUp', \"The alternative mouseUp event was properly registered\");\n\n ActionHelper.registerAction = originalRegisterAction;\n});\n\ntest(\"should by default target the view's controller\", function() {\n var registeredTarget, controller = {};\n\n ActionHelper.registerAction = function(actionName, options) {\n registeredTarget = options.target;\n };\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('edit')\n });\n\n appendView();\n\n equal(registeredTarget.root, controller, \"The controller was registered as the target\");\n\n ActionHelper.registerAction = originalRegisterAction;\n});\n\ntest(\"Inside a yield, the target points at the original target\", function() {\n var controller = {}, watted = false;\n\n var component = Ember.Component.extend({\n boundText: \"inner\",\n truthy: true,\n obj: {},\n layout: Ember.Handlebars.compile(\"

    {{boundText}}

    {{#if truthy}}{{#with obj}}{{yield}}{{/with}}{{/if}}

    \")\n });\n\n view = Ember.View.create({\n controller: {\n boundText: \"outer\",\n truthy: true,\n wat: function() {\n watted = true;\n },\n obj: {\n component: component,\n truthy: true,\n boundText: 'insideWith'\n }\n },\n template: Ember.Handlebars.compile('{{#with obj}}{{#if truthy}}{{#view component}}{{#if truthy}}

    {{boundText}}

    {{/if}}{{/view}}{{/if}}{{/with}}')\n });\n\n appendView();\n\n Ember.run(function() {\n view.$(\".wat\").click();\n });\n\n equal(watted, true, \"The action was called on the right context\");\n});\n\ntest(\"should target the current controller inside an {{each}} loop\", function() {\n var registeredTarget;\n\n ActionHelper.registerAction = function(actionName, options) {\n registeredTarget = options.target;\n };\n\n var itemController = Ember.ObjectController.create();\n\n var ArrayController = Ember.ArrayController.extend({\n itemController: 'stub',\n controllerAt: function(idx, object) {\n return itemController;\n }\n });\n\n var controller = ArrayController.create({\n model: Ember.A([1])\n });\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('{{#each controller}}{{action \"editTodo\"}}{{/each}}')\n });\n\n appendView();\n\n equal(registeredTarget.root, itemController, \"the item controller is the target of action\");\n\n ActionHelper.registerAction = originalRegisterAction;\n});\n\ntest(\"should allow a target to be specified\", function() {\n var registeredTarget;\n\n ActionHelper.registerAction = function(actionName, options) {\n registeredTarget = options.target;\n };\n\n var anotherTarget = Ember.View.create();\n\n view = Ember.View.create({\n controller: {},\n template: Ember.Handlebars.compile('edit'),\n anotherTarget: anotherTarget\n });\n\n appendView();\n\n equal(registeredTarget.options.data.keywords.view, view, \"The specified target was registered\");\n equal(registeredTarget.target, 'view.anotherTarget', \"The specified target was registered\");\n\n ActionHelper.registerAction = originalRegisterAction;\n\n Ember.run(function() {\n anotherTarget.destroy();\n });\n});\n\ntest(\"should lazily evaluate the target\", function() {\n var firstEdit = 0, secondEdit = 0;\n\n var controller = {};\n var first = {\n edit: function() {\n firstEdit++;\n }\n };\n\n var second = {\n edit: function() {\n secondEdit++;\n }\n };\n\n controller.theTarget = first;\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('edit')\n });\n\n appendView();\n\n Ember.run(function() {\n Ember.$('a').trigger('click');\n });\n\n equal(firstEdit, 1);\n\n Ember.set(controller, 'theTarget', second);\n\n Ember.run(function() {\n Ember.$('a').trigger('click');\n });\n\n equal(firstEdit, 1);\n equal(secondEdit, 1);\n});\n\ntest(\"should register an event handler\", function() {\n var eventHandlerWasCalled = false;\n\n var controller = Ember.Controller.extend({\n actions: { edit: function() { eventHandlerWasCalled = true; } }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('click me')\n });\n\n appendView();\n\n var actionId = view.$('a[data-ember-action]').attr('data-ember-action');\n\n ok(Ember.Handlebars.ActionHelper.registeredActions[actionId], \"The action was registered\");\n\n view.$('a').trigger('click');\n\n ok(eventHandlerWasCalled, \"The event handler was called\");\n});\n\ntest(\"handles whitelisted modifier keys\", function() {\n var eventHandlerWasCalled = false, shortcutHandlerWasCalled = false;\n\n var controller = Ember.Controller.extend({\n actions: {\n edit: function() { eventHandlerWasCalled = true; },\n shortcut: function() { shortcutHandlerWasCalled = true; }\n }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('click me
    click me too
    ')\n });\n\n appendView();\n\n var actionId = view.$('a[data-ember-action]').attr('data-ember-action');\n\n ok(Ember.Handlebars.ActionHelper.registeredActions[actionId], \"The action was registered\");\n\n var e = Ember.$.Event('click');\n e.altKey = true;\n view.$('a').trigger(e);\n\n ok(eventHandlerWasCalled, \"The event handler was called\");\n\n e = Ember.$.Event('click');\n e.ctrlKey = true;\n view.$('div').trigger(e);\n\n ok(shortcutHandlerWasCalled, \"The \\\"any\\\" shortcut's event handler was called\");\n});\n\ntest(\"should be able to use action more than once for the same event within a view\", function() {\n var editWasCalled = false,\n deleteWasCalled = false,\n originalEventHandlerWasCalled = false;\n\n var controller = Ember.Controller.extend({\n actions: {\n edit: function() { editWasCalled = true; },\n \"delete\": function() { deleteWasCalled = true; }\n }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile(\n 'editdelete'\n ),\n click: function() { originalEventHandlerWasCalled = true; }\n });\n\n appendView();\n\n view.$('#edit').trigger('click');\n\n equal(editWasCalled, true, \"The edit action was called\");\n equal(deleteWasCalled, false, \"The delete action was not called\");\n\n editWasCalled = deleteWasCalled = originalEventHandlerWasCalled = false;\n\n view.$('#delete').trigger('click');\n\n equal(editWasCalled, false, \"The edit action was not called\");\n equal(deleteWasCalled, true, \"The delete action was called\");\n\n editWasCalled = deleteWasCalled = originalEventHandlerWasCalled = false;\n\n view.$().trigger('click');\n\n equal(editWasCalled, false, \"The edit action was not called\");\n equal(deleteWasCalled, false, \"The delete action was not called\");\n});\n\ntest(\"the event should not bubble if `bubbles=false` is passed\", function() {\n var editWasCalled = false,\n deleteWasCalled = false,\n originalEventHandlerWasCalled = false;\n\n var controller = Ember.Controller.extend({\n actions: {\n edit: function() { editWasCalled = true; },\n \"delete\": function() { deleteWasCalled = true; }\n }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile(\n 'editdelete'\n ),\n click: function() { originalEventHandlerWasCalled = true; }\n });\n\n appendView();\n\n view.$('#edit').trigger('click');\n\n equal(editWasCalled, true, \"The edit action was called\");\n equal(deleteWasCalled, false, \"The delete action was not called\");\n equal(originalEventHandlerWasCalled, false, \"The original event handler was not called\");\n\n editWasCalled = deleteWasCalled = originalEventHandlerWasCalled = false;\n\n view.$('#delete').trigger('click');\n\n equal(editWasCalled, false, \"The edit action was not called\");\n equal(deleteWasCalled, true, \"The delete action was called\");\n equal(originalEventHandlerWasCalled, false, \"The original event handler was not called\");\n\n editWasCalled = deleteWasCalled = originalEventHandlerWasCalled = false;\n\n view.$().trigger('click');\n\n equal(editWasCalled, false, \"The edit action was not called\");\n equal(deleteWasCalled, false, \"The delete action was not called\");\n equal(originalEventHandlerWasCalled, true, \"The original event handler was called\");\n});\n\ntest(\"should work properly in an #each block\", function() {\n var eventHandlerWasCalled = false;\n\n var controller = Ember.Controller.extend({\n actions: { edit: function() { eventHandlerWasCalled = true; } }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n items: Ember.A([1, 2, 3, 4]),\n template: Ember.Handlebars.compile('{{#each view.items}}click me{{/each}}')\n });\n\n appendView();\n\n view.$('a').trigger('click');\n\n ok(eventHandlerWasCalled, \"The event handler was called\");\n});\n\ntest(\"should work properly in a #with block\", function() {\n var eventHandlerWasCalled = false;\n\n var controller = Ember.Controller.extend({\n actions: { edit: function() { eventHandlerWasCalled = true; } }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n something: {ohai: 'there'},\n template: Ember.Handlebars.compile('{{#with view.something}}click me{{/with}}')\n });\n\n appendView();\n\n view.$('a').trigger('click');\n\n ok(eventHandlerWasCalled, \"The event handler was called\");\n});\n\ntest(\"should unregister event handlers on rerender\", function() {\n var eventHandlerWasCalled = false;\n\n view = Ember.View.extend({\n template: Ember.Handlebars.compile('click me'),\n actions: { edit: function() { eventHandlerWasCalled = true; } }\n }).create();\n\n appendView();\n\n var previousActionId = view.$('a[data-ember-action]').attr('data-ember-action');\n\n Ember.run(function() {\n view.rerender();\n });\n\n ok(!Ember.Handlebars.ActionHelper.registeredActions[previousActionId], \"On rerender, the event handler was removed\");\n\n var newActionId = view.$('a[data-ember-action]').attr('data-ember-action');\n\n ok(Ember.Handlebars.ActionHelper.registeredActions[newActionId], \"After rerender completes, a new event handler was added\");\n});\n\ntest(\"should unregister event handlers on inside virtual views\", function() {\n var things = Ember.A([\n {\n name: 'Thingy'\n }\n ]);\n view = Ember.View.create({\n template: Ember.Handlebars.compile('{{#each view.things}}click me{{/each}}'),\n things: things\n });\n\n appendView();\n\n var actionId = view.$('a[data-ember-action]').attr('data-ember-action');\n\n Ember.run(function() {\n things.removeAt(0);\n });\n\n ok(!Ember.Handlebars.ActionHelper.registeredActions[actionId], \"After the virtual view was destroyed, the action was unregistered\");\n});\n\ntest(\"should properly capture events on child elements of a container with an action\", function() {\n var eventHandlerWasCalled = false;\n\n var controller = Ember.Controller.extend({\n actions: { edit: function() { eventHandlerWasCalled = true; } }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('
    ')\n });\n\n appendView();\n\n view.$('button').trigger('click');\n\n ok(eventHandlerWasCalled, \"Event on a child element triggered the action of it's parent\");\n});\n\ntest(\"should allow bubbling of events from action helper to original parent event\", function() {\n var eventHandlerWasCalled = false,\n originalEventHandlerWasCalled = false;\n\n var controller = Ember.Controller.extend({\n actions: { edit: function() { eventHandlerWasCalled = true; } }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('click me'),\n click: function() { originalEventHandlerWasCalled = true; }\n });\n\n appendView();\n\n view.$('a').trigger('click');\n\n ok(eventHandlerWasCalled && originalEventHandlerWasCalled, \"Both event handlers were called\");\n});\n\ntest(\"should not bubble an event from action helper to original parent event if `bubbles=false` is passed\", function() {\n var eventHandlerWasCalled = false,\n originalEventHandlerWasCalled = false;\n\n var controller = Ember.Controller.extend({\n actions: { edit: function() { eventHandlerWasCalled = true; } }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('click me'),\n click: function() { originalEventHandlerWasCalled = true; }\n });\n\n appendView();\n\n view.$('a').trigger('click');\n\n ok(eventHandlerWasCalled, \"The child handler was called\");\n ok(!originalEventHandlerWasCalled, \"The parent handler was not called\");\n});\n\ntest(\"should allow 'send' as action name (#594)\", function() {\n var eventHandlerWasCalled = false;\n var eventObjectSent;\n\n var controller = Ember.Controller.extend({\n send: function() { eventHandlerWasCalled = true; }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('send')\n });\n\n appendView();\n\n view.$('a').trigger('click');\n\n ok(eventHandlerWasCalled, \"The view's send method was called\");\n});\n\n\ntest(\"should send the view, event and current Handlebars context to the action\", function() {\n var passedTarget;\n var passedContext;\n\n var aTarget = Ember.Controller.extend({\n actions: {\n edit: function(context) {\n passedTarget = this;\n passedContext = context;\n }\n }\n }).create();\n\n var aContext = { aTarget: aTarget };\n\n view = Ember.View.create({\n aContext: aContext,\n template: Ember.Handlebars.compile('{{#with view.aContext}}edit{{/with}}')\n });\n\n appendView();\n\n view.$('#edit').trigger('click');\n\n strictEqual(passedTarget, aTarget, \"the action is called with the target as this\");\n strictEqual(passedContext, aContext, \"the parameter is passed along\");\n});\n\ntest(\"should only trigger actions for the event they were registered on\", function() {\n var editWasCalled = false;\n\n view = Ember.View.extend({\n template: Ember.Handlebars.compile('edit'),\n actions: { edit: function() { editWasCalled = true; } }\n }).create();\n\n appendView();\n\n view.$('a').trigger('mouseover');\n\n ok(!editWasCalled, \"The action wasn't called\");\n});\n\ntest(\"should unwrap controllers passed as a context\", function() {\n var passedContext,\n model = Ember.Object.create(),\n controller = Ember.ObjectController.extend({\n model: model,\n actions: {\n edit: function(context) {\n passedContext = context;\n }\n }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('')\n });\n\n appendView();\n\n view.$('button').trigger('click');\n\n equal(passedContext, model, \"the action was passed the unwrapped model\");\n});\n\ntest(\"should allow multiple contexts to be specified\", function() {\n var passedContexts,\n models = [Ember.Object.create(), Ember.Object.create()];\n\n var controller = Ember.Controller.extend({\n actions: {\n edit: function() {\n passedContexts = [].slice.call(arguments);\n }\n }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n modelA: models[0],\n modelB: models[1],\n template: Ember.Handlebars.compile('')\n });\n\n appendView();\n\n view.$('button').trigger('click');\n\n deepEqual(passedContexts, models, \"the action was called with the passed contexts\");\n});\n\ntest(\"should allow multiple contexts to be specified mixed with string args\", function() {\n var passedParams,\n model = Ember.Object.create();\n\n var controller = Ember.Controller.extend({\n actions: {\n edit: function() {\n passedParams = [].slice.call(arguments);\n }\n }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n modelA: model,\n template: Ember.Handlebars.compile('')\n });\n\n appendView();\n\n view.$('button').trigger('click');\n\n deepEqual(passedParams, [\"herp\", model], \"the action was called with the passed contexts\");\n});\n\nvar namespace = {\n \"Component\": {\n toString: function() { return \"Component\"; },\n find: function() { return { id: 1 }; }\n }\n};\n\nvar compile = function(string) {\n return Ember.Handlebars.compile(string);\n};\n\ntest(\"it does not trigger action with special clicks\", function() {\n var showCalled = false;\n\n view = Ember.View.create({\n template: compile(\"Hi\")\n });\n\n var controller = Ember.Controller.extend({\n actions: {\n show: function() {\n showCalled = true;\n }\n }\n }).create();\n\n Ember.run(function() {\n view.set('controller', controller);\n view.appendTo('#qunit-fixture');\n });\n\n function checkClick(prop, value, expected) {\n var event = Ember.$.Event(\"click\");\n event[prop] = value;\n view.$('a').trigger(event);\n if (expected) {\n ok(showCalled, \"should call action with \"+prop+\":\"+value);\n ok(event.isDefaultPrevented(), \"should prevent default\");\n } else {\n ok(!showCalled, \"should not call action with \"+prop+\":\"+value);\n ok(!event.isDefaultPrevented(), \"should not prevent default\");\n }\n }\n\n checkClick('ctrlKey', true, false);\n checkClick('altKey', true, false);\n checkClick('metaKey', true, false);\n checkClick('shiftKey', true, false);\n checkClick('which', 2, false);\n\n checkClick('which', 1, true);\n checkClick('which', undefined, true); // IE <9\n});\n\ntest(\"it can trigger actions for keyboard events\", function() {\n var showCalled = false;\n\n view = Ember.View.create({\n template: compile(\"\")\n });\n\n var controller = Ember.Controller.extend({\n actions: {\n show: function() {\n showCalled = true;\n }\n }\n }).create();\n\n Ember.run(function() {\n view.set('controller', controller);\n view.appendTo('#qunit-fixture');\n });\n\n var event = Ember.$.Event(\"keyup\");\n event.char = 'a';\n event.which = 65;\n view.$('input').trigger(event);\n ok(showCalled, \"should call action with keyup\");\n});\n\nmodule(\"Ember.Handlebars - action helper - deprecated invoking directly on target\", {\n setup: function() {\n dispatcher = Ember.EventDispatcher.create();\n dispatcher.setup();\n Ember.TESTING_DEPRECATION = true;\n },\n\n teardown: function() {\n Ember.run(function() {\n dispatcher.destroy();\n if (view) { view.destroy(); }\n });\n Ember.TESTING_DEPRECATION = false;\n }\n});\n\ntest(\"should invoke a handler defined directly on the target (DEPRECATED)\", function() {\n var eventHandlerWasCalled,\n model = Ember.Object.create();\n\n var controller = Ember.Controller.extend({\n edit: function() {\n eventHandlerWasCalled = true;\n }\n }).create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile('')\n });\n\n appendView();\n\n view.$('button').trigger('click');\n\n ok(eventHandlerWasCalled, \"the action was called\");\n});\n\n\n})();\n//@ sourceURL=ember-routing/~tests/helpers/action_test");minispade.register('ember-routing/~tests/helpers/control_test', "(function() {/*global QUnit*/\n\nvar container, view;\nvar compile = Ember.Handlebars.compile;\n\nfunction destroy(object) {\n Ember.run(function() {\n object.destroy();\n });\n}\n\nfunction appendView(attrs) {\n view = Ember.View.create(attrs);\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n}\n\nfunction renderedText(expected, msg) {\n var actual = view.$().text();\n QUnit.push(actual === expected, actual, expected, msg);\n}\n\nif (Ember.ENV.EXPERIMENTAL_CONTROL_HELPER) {\n module(\"Handlebars {{control}} helper\", {\n setup: function() {\n container = new Ember.Container();\n container.options('template', { instantiate: false });\n container.options('view', { singleton: false });\n container.register('controller:parent', Ember.ObjectController.extend());\n container.register('controller:widget', Ember.Controller.extend());\n container.register('view:widget', Ember.View.extend());\n\n container.lookup('controller:parent').set('content', {});\n },\n\n teardown: function() {\n destroy(view);\n destroy(container);\n }\n });\n\n test(\"A control raises an error when a view cannot be found\", function() {\n container = new Ember.Container();\n container.options('template', { instantiate: false });\n container.options('view', { singleton: false });\n container.register('controller:parent', Ember.Controller.extend());\n container.register('controller:widget', Ember.Controller.extend());\n container.register('template:widget', compile(\"Hello\"));\n\n expectAssertion(function() {\n appendView({\n controller: container.lookup('controller:parent'),\n template: compile(\"{{control widget}}\")\n });\n }, /find view/, \"Must raise an error if no view is defined\");\n });\n\n test(\"A control raises an error when a controller cannot be found\", function() {\n container = new Ember.Container();\n container.options('template', { instantiate: false });\n container.options('view', { singleton: false });\n container.register('controller:parent', Ember.Controller.extend());\n container.register('view:widget', Ember.View.extend());\n container.register('template:widget', compile(\"Hello\"));\n\n expectAssertion(function() {\n appendView({\n controller: container.lookup('controller:parent'),\n template: compile(\"{{control widget}}\")\n });\n }, /find controller/, \"Must raise an error when no controller is defined\");\n\n // The assertion causes some views to be left behind\n Ember.run(function() {\n for (var viewId in Ember.View.views) {\n Ember.View.views[viewId].destroy();\n }\n });\n });\n\n test(\"A control renders a template with a new instance of the named controller and view\", function() {\n container.register('template:widget', compile(\"Hello\"));\n\n appendView({\n controller: container.lookup('controller:parent'),\n template: compile(\"{{control widget}}\")\n });\n\n renderedText(\"Hello\");\n });\n\n test(\"A control's controller and view are lookuped up via template name\", function() {\n container.register('template:widgets/foo', compile(\"Hello\"));\n container.register('controller:widgets.foo', Ember.Controller.extend());\n container.register('view:widgets.foo', Ember.View.extend());\n\n appendView({\n controller: container.lookup('controller:parent'),\n template: compile(\"{{control 'widgets/foo'}}\")\n });\n\n renderedText(\"Hello\");\n });\n\n test(\"A control defaults to the default view\", function() {\n container.register('template:widgets/foo', compile(\"Hello\"));\n container.register('controller:widgets.foo', Ember.Controller.extend());\n container.register('view:default', Ember.View.extend());\n\n appendView({\n controller: container.lookup('controller:parent'),\n template: compile(\"{{control 'widgets/foo'}}\")\n });\n\n renderedText(\"Hello\");\n });\n\n test(\"A control with a default view survives re-render\", function() {\n container.register('template:widgets/foo', compile(\"Hello\"));\n container.register('controller:widgets.foo', Ember.Controller.extend());\n container.register('view:default', Ember.View.extend());\n\n appendView({\n controller: container.lookup('controller:parent'),\n template: compile(\"{{control 'widgets/foo'}}\")\n });\n\n renderedText(\"Hello\");\n\n Ember.run(function() {\n view.rerender();\n });\n\n renderedText(\"Hello\");\n });\n\n test(\"A control can specify a model to use in its template\", function() {\n container.register('template:widget', compile(\"{{model.name}}\"));\n\n var controller = container.lookup('controller:parent');\n controller.set('person', { name: \"Tom Dale\" });\n\n appendView({\n controller: controller,\n template: compile(\"{{control 'widget' person}}\")\n });\n\n renderedText(\"Tom Dale\");\n });\n\n test(\"A control can be used multiple times\", function() {\n container.register('template:widget', compile(\"{{model.name}}\"));\n\n var controller = container.lookup('controller:parent');\n controller.set('person1', { name: \"Tom Dale\" });\n controller.set('person2', { name: \"Peter Wagenet\" });\n\n appendView({\n controller: controller,\n template: compile(\"{{control 'widget' person1}}{{control 'widget' person2}}\")\n });\n\n renderedText(\"Tom DalePeter Wagenet\");\n });\n\n test(\"A control's state is persisted if the view is destroyed and re-rendered\", function() {\n container.register('template:widget', compile(\"{{randomValue}}{{model.name}}\"));\n\n var controller = container.lookup('controller:parent');\n controller.set('person1', { name: \"Tom Dale\" });\n controller.set('person2', { name: \"Peter Wagenet\" });\n\n container.register('controller:widget', Ember.Controller.extend({\n randomValue: Ember.computed(function() {\n return Math.random() + '' + (+new Date());\n })\n }));\n\n var template = compile(\"{{control 'widget' person1}}{{control 'widget' person2}}\");\n\n appendView({\n controller: controller,\n template: template\n });\n\n var text = view.$().text();\n ok(text.match(/^.*Tom Dale.*Peter Wagenet.*$/), \"The view rendered\");\n\n destroy(view);\n\n appendView({\n controller: controller,\n template: template\n });\n\n equal(view.$().text(), text);\n });\n\n test(\"if a controller's model changes, its child controllers are destroyed\", function() {\n container.register('template:widget', compile(\"{{randomValue}}{{model.name}}\"));\n\n var controller = container.lookup('controller:parent');\n controller.set('model', { name: \"Tom Dale\" });\n\n container.register('controller:widget', Ember.Controller.extend({\n randomValue: Ember.computed(function() {\n return Math.random() + '' + (+new Date());\n })\n }));\n\n appendView({\n controller: controller,\n template: compile(\"{{control 'widget' model}}\")\n });\n\n var childController = view.get('childViews').objectAt(0).get('controller');\n\n ok(view.$().text().match(/^.*Tom Dale.*$/), \"The view rendered\");\n\n if (Ember.create.isSimulated) {\n equal(childController.get('model').name, \"Tom Dale\");\n } else {\n deepEqual(childController.get('model'), { name: \"Tom Dale\" });\n }\n\n Ember.run(function() {\n controller.set('model', { name: \"Yehuda Katz\" });\n });\n\n equal(childController.isDestroying, true);\n ok(view.$().text().match(/^.*Yehuda Katz.*$/), \"The view rendered\");\n });\n\n test(\"A control should correctly remove model observers\", function() {\n var Controller = Ember.Controller.extend({\n message: 'bro'\n });\n\n container.register('template:widget', compile(\"{{content}}\"));\n container.register('controller:bro', Controller);\n\n appendView({\n controller: container.lookup('controller:bro'),\n template: compile(\"{{control widget message}}\")\n });\n\n renderedText(\"bro\");\n\n Ember.run(function() {\n view.destroy();\n });\n\n Ember.run(function() {\n Ember.set(container.lookup('controller:bro'), 'message', 'grammer');\n });\n });\n\n test(\"If no `modelPath` is specified, changing the model on the controller does not result in an error (#2268)\", function() {\n expect(0);\n\n container.register('template:widget', compile(\"{{randomValue}}{{name}}\"));\n\n var controller = container.lookup('controller:parent');\n controller.set('model', { name: \"Tom Dale\" });\n\n container.register('controller:widget', Ember.Controller.extend({\n randomValue: Ember.computed(function() {\n return Math.random() + '' + (+new Date());\n })\n }));\n\n appendView({\n controller: controller,\n template: compile(\"{{control 'widget'}}\")\n });\n\n Ember.addObserver(controller, 'content.name', function () {});\n\n Ember.run(function() {\n controller.set('model', { name: \"Yehuda Katz\" });\n });\n });\n}\n\n})();\n//@ sourceURL=ember-routing/~tests/helpers/control_test");minispade.register('ember-routing/~tests/helpers/outlet_test', "(function() {var appendView = function(view) {\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n};\n\nvar compile = function(template) {\n return Ember.Handlebars.compile(template);\n};\n\nvar view;\n\nmodule(\"Handlebars {{outlet}} helpers\", {\n teardown: function() {\n Ember.run(function () {\n if (view) {\n view.destroy();\n }\n });\n }\n});\n\ntest(\"view should support connectOutlet for the main outlet\", function() {\n var template = \"

    HI

    {{outlet}}\";\n view = Ember.View.create({\n template: Ember.Handlebars.compile(template)\n });\n\n appendView(view);\n\n equal(view.$().text(), 'HI');\n\n Ember.run(function() {\n view.connectOutlet('main', Ember.View.create({\n template: compile(\"

    BYE

    \")\n }));\n });\n\n // Replace whitespace for older IE\n equal(view.$().text().replace(/\\s+/,''), 'HIBYE');\n});\n\ntest(\"outlet should support connectOutlet in slots in prerender state\", function() {\n var template = \"

    HI

    {{outlet}}\";\n view = Ember.View.create({\n template: Ember.Handlebars.compile(template)\n });\n\n view.connectOutlet('main', Ember.View.create({\n template: compile(\"

    BYE

    \")\n }));\n\n appendView(view);\n\n equal(view.$().text(), 'HIBYE');\n});\n\ntest(\"outlet should support an optional name\", function() {\n var template = \"

    HI

    {{outlet mainView}}\";\n view = Ember.View.create({\n template: Ember.Handlebars.compile(template)\n });\n\n appendView(view);\n\n equal(view.$().text(), 'HI');\n\n Ember.run(function() {\n view.connectOutlet('mainView', Ember.View.create({\n template: compile(\"

    BYE

    \")\n }));\n });\n\n // Replace whitespace for older IE\n equal(view.$().text().replace(/\\s+/,''), 'HIBYE');\n});\n\n\ntest(\"outlet should support an optional view class\", function() {\n var template = \"

    HI

    {{outlet viewClass=view.outletView}}\";\n view = Ember.View.create({\n template: Ember.Handlebars.compile(template),\n outletView: Ember.ContainerView.extend()\n });\n\n appendView(view);\n\n equal(view.$().text(), 'HI');\n\n var childView = Ember.View.create({\n template: compile(\"

    BYE

    \")\n });\n\n Ember.run(function() {\n view.connectOutlet('main', childView);\n });\n\n ok(view.outletView.detectInstance(childView.get('_parentView')), \"The custom view class should be used for the outlet\");\n\n // Replace whitespace for older IE\n equal(view.$().text().replace(/\\s+/,''), 'HIBYE');\n});\n\n\ntest(\"Outlets bind to the current view, not the current concrete view\", function() {\n var parentTemplate = \"

    HI

    {{outlet}}\";\n var middleTemplate = \"

    MIDDLE

    {{outlet}}\";\n var bottomTemplate = \"

    BOTTOM

    \";\n\n view = Ember.View.create({\n template: compile(parentTemplate)\n });\n\n var middleView = Ember._MetamorphView.create({\n template: compile(middleTemplate)\n });\n\n var bottomView = Ember._MetamorphView.create({\n template: compile(bottomTemplate)\n });\n\n appendView(view);\n\n Ember.run(function() {\n view.connectOutlet('main', middleView);\n });\n\n Ember.run(function() {\n middleView.connectOutlet('main', bottomView);\n });\n\n var output = Ember.$('#qunit-fixture h1 ~ h2 ~ h3').text();\n equal(output, \"BOTTOM\", \"all templates were rendered\");\n});\n\ntest(\"view should support disconnectOutlet for the main outlet\", function() {\n var template = \"

    HI

    {{outlet}}\";\n view = Ember.View.create({\n template: Ember.Handlebars.compile(template)\n });\n\n appendView(view);\n\n equal(view.$().text(), 'HI');\n\n Ember.run(function() {\n view.connectOutlet('main', Ember.View.create({\n template: compile(\"

    BYE

    \")\n }));\n });\n\n // Replace whitespace for older IE\n equal(view.$().text().replace(/\\s+/,''), 'HIBYE');\n\n Ember.run(function() {\n view.disconnectOutlet('main');\n });\n\n // Replace whitespace for older IE\n equal(view.$().text().replace(/\\s+/,''), 'HI');\n});\n\ntest(\"Outlets bind to the current template's view, not inner contexts\", function() {\n var parentTemplate = \"

    HI

    {{#if view.alwaysTrue}}{{#with this}}{{outlet}}{{/with}}{{/if}}\";\n var bottomTemplate = \"

    BOTTOM

    \";\n\n view = Ember.View.create({\n alwaysTrue: true,\n template: compile(parentTemplate)\n });\n\n var bottomView = Ember._MetamorphView.create({\n template: compile(bottomTemplate)\n });\n\n appendView(view);\n\n Ember.run(function() {\n view.connectOutlet('main', bottomView);\n });\n\n var output = Ember.$('#qunit-fixture h1 ~ h3').text();\n equal(output, \"BOTTOM\", \"all templates were rendered\");\n});\n\ntest(\"should support layouts\", function() {\n var template = \"{{outlet}}\",\n layout = \"

    HI

    {{yield}}\";\n view = Ember.View.create({\n template: Ember.Handlebars.compile(template),\n layout: Ember.Handlebars.compile(layout)\n });\n\n appendView(view);\n\n equal(view.$().text(), 'HI');\n\n Ember.run(function() {\n view.connectOutlet('main', Ember.View.create({\n template: compile(\"

    BYE

    \")\n }));\n });\n // Replace whitespace for older IE\n equal(view.$().text().replace(/\\s+/,''), 'HIBYE');\n});\n\n})();\n//@ sourceURL=ember-routing/~tests/helpers/outlet_test");minispade.register('ember-routing/~tests/helpers/render_test', "(function() {var appendView = function(view) {\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n};\n\nvar set = function(object, key, value) {\n Ember.run(function() { Ember.set(object, key, value); });\n};\n\nvar compile = function(template) {\n return Ember.Handlebars.compile(template);\n};\n\nvar buildContainer = function(namespace) {\n var container = new Ember.Container();\n\n container.set = Ember.set;\n container.resolver = resolverFor(namespace);\n container.optionsForType('view', { singleton: false });\n container.optionsForType('template', { instantiate: false });\n container.register('application:main', namespace, { instantiate: false });\n container.injection('router:main', 'namespace', 'application:main');\n\n container.register('controller:basic', Ember.Controller, { instantiate: false });\n container.register('controller:object', Ember.ObjectController, { instantiate: false });\n container.register('controller:array', Ember.ArrayController, { instantiate: false });\n\n container.typeInjection('route', 'router', 'router:main');\n\n return container;\n};\n\nfunction resolverFor(namespace) {\n return function(fullName) {\n var nameParts = fullName.split(\":\"),\n type = nameParts[0], name = nameParts[1];\n\n if (type === 'template') {\n var templateName = Ember.String.decamelize(name);\n if (Ember.TEMPLATES[templateName]) {\n return Ember.TEMPLATES[templateName];\n }\n }\n\n var className = Ember.String.classify(name) + Ember.String.classify(type);\n var factory = Ember.get(namespace, className);\n\n if (factory) { return factory; }\n };\n}\n\nvar view, container;\n\nmodule(\"Handlebars {{render}} helper\", {\n setup: function() {\n var namespace = Ember.Namespace.create();\n container = buildContainer(namespace);\n container.register('view:default', Ember.View.extend());\n container.register('router:main', Ember.Router.extend());\n },\n teardown: function() {\n Ember.run(function () {\n if (container) {\n container.destroy();\n }\n if (view) {\n view.destroy();\n }\n });\n\n Ember.TEMPLATES = {};\n }\n});\n\ntest(\"{{render}} helper should render given template\", function() {\n var template = \"

    HI

    {{render home}}\";\n var controller = Ember.Controller.extend({container: container});\n view = Ember.View.create({\n controller: controller.create(),\n template: Ember.Handlebars.compile(template)\n });\n\n Ember.TEMPLATES['home'] = compile(\"

    BYE

    \");\n\n appendView(view);\n\n equal(view.$().text(), 'HIBYE');\n ok(container.lookup('router:main')._lookupActiveView('home'), 'should register home as active view');\n});\n\ntest(\"{{render}} helper should render given template with a supplied model\", function() {\n var template = \"

    HI

    {{render 'post' post}}\";\n var post = {\n title: \"Rails is omakase\"\n };\n\n var Controller = Ember.Controller.extend({\n container: container,\n post: post\n });\n\n var controller = Controller.create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile(template)\n });\n\n var PostController = Ember.ObjectController.extend();\n container.register('controller:post', PostController);\n\n Ember.TEMPLATES['post'] = compile(\"

    {{title}}

    \");\n\n appendView(view);\n\n var postController = view.get('_childViews')[0].get('controller');\n\n equal(view.$().text(), 'HIRails is omakase');\n equal(postController.get('model'), post);\n\n set(controller, 'post', { title: \"Rails is unagi\" });\n\n equal(view.$().text(), 'HIRails is unagi');\n if (Ember.create.isSimulated) {\n equal(postController.get('model').title, \"Rails is unagi\");\n } else {\n deepEqual(postController.get('model'), { title: \"Rails is unagi\" });\n }\n});\n\ntest(\"{{render}} helper should raise an error when a given controller name does not resolve to a controller\", function() {\n var template = '

    HI

    {{render home controller=\"postss\"}}';\n var controller = Ember.Controller.extend({container: container});\n container.register('controller:posts', Ember.ArrayController.extend());\n view = Ember.View.create({\n controller: controller.create(),\n template: Ember.Handlebars.compile(template)\n });\n\n Ember.TEMPLATES['home'] = compile(\"

    BYE

    \");\n\n expectAssertion(function() {\n appendView(view);\n }, 'The controller name you supplied \\'postss\\' did not resolve to a controller.');\n});\n\ntest(\"{{render}} helper should render with given controller\", function() {\n var template = '

    HI

    {{render home controller=\"posts\"}}';\n var controller = Ember.Controller.extend({container: container});\n container.register('controller:posts', Ember.ArrayController.extend());\n view = Ember.View.create({\n controller: controller.create(),\n template: Ember.Handlebars.compile(template)\n });\n\n Ember.TEMPLATES['home'] = compile(\"

    BYE

    \");\n\n appendView(view);\n\n var renderedView = container.lookup('router:main')._lookupActiveView('home');\n equal(container.lookup('controller:posts'), renderedView.get('controller'), 'rendered with correct controller');\n});\n\ntest(\"{{render}} helper should render a template without a model only once\", function() {\n var template = \"

    HI

    {{render home}}
    {{render home}}\";\n var controller = Ember.Controller.extend({container: container});\n view = Ember.View.create({\n controller: controller.create(),\n template: Ember.Handlebars.compile(template)\n });\n\n Ember.TEMPLATES['home'] = compile(\"

    BYE

    \");\n\n expectAssertion(function() {\n appendView(view);\n }, /\\{\\{render\\}\\} helper once/i);\n});\n\ntest(\"{{render}} helper should render templates with models multiple times\", function() {\n var template = \"

    HI

    {{render 'post' post1}} {{render 'post' post2}}\";\n var post1 = {\n title: \"Me first\"\n };\n var post2 = {\n title: \"Then me\"\n };\n\n var Controller = Ember.Controller.extend({\n container: container,\n post1: post1,\n post2: post2\n });\n\n var controller = Controller.create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile(template)\n });\n\n var PostController = Ember.ObjectController.extend();\n container.register('controller:post', PostController, {singleton: false});\n\n Ember.TEMPLATES['post'] = compile(\"

    {{title}}

    \");\n\n appendView(view);\n\n var postController1 = view.get('_childViews')[0].get('controller');\n var postController2 = view.get('_childViews')[1].get('controller');\n\n ok(view.$().text().match(/^HI ?Me first ?Then me$/));\n equal(postController1.get('model'), post1);\n equal(postController2.get('model'), post2);\n\n set(controller, 'post1', { title: \"I am new\" });\n\n ok(view.$().text().match(/^HI ?I am new ?Then me$/));\n if (Ember.create.isSimulated) {\n equal(postController1.get('model').title, \"I am new\");\n } else {\n deepEqual(postController1.get('model'), { title: \"I am new\" });\n }\n});\n\ntest(\"{{render}} helper should not treat invocations with falsy contexts as context-less\", function() {\n var template = \"

    HI

    {{render 'post' zero}} {{render 'post' nonexistent}}\";\n\n view = Ember.View.create({\n controller: Ember.Controller.createWithMixins({\n container: container,\n zero: false\n }),\n template: Ember.Handlebars.compile(template)\n });\n\n var PostController = Ember.ObjectController.extend();\n container.register('controller:post', PostController, {singleton: false});\n\n Ember.TEMPLATES['post'] = compile(\"

    {{#unless content}}NOTHING{{/unless}}

    \");\n\n appendView(view);\n\n var postController1 = view.get('_childViews')[0].get('controller');\n var postController2 = view.get('_childViews')[1].get('controller');\n\n ok(view.$().text().match(/^HI ?NOTHING ?NOTHING$/));\n equal(postController1.get('model'), 0);\n equal(postController2.get('model'), undefined);\n});\n\ntest(\"{{render}} helper should render templates both with and without models\", function() {\n var template = \"

    HI

    {{render 'post'}} {{render 'post' post}}\";\n var post = {\n title: \"Rails is omakase\"\n };\n\n var Controller = Ember.Controller.extend({\n container: container,\n post: post\n });\n\n var controller = Controller.create();\n\n view = Ember.View.create({\n controller: controller,\n template: Ember.Handlebars.compile(template)\n });\n\n var PostController = Ember.ObjectController.extend();\n container.register('controller:post', PostController, {singleton: false});\n\n Ember.TEMPLATES['post'] = compile(\"

    Title:{{title}}

    \");\n\n appendView(view);\n\n var postController1 = view.get('_childViews')[0].get('controller');\n var postController2 = view.get('_childViews')[1].get('controller');\n\n ok(view.$().text().match(/^HI ?Title: ?Title:Rails is omakase$/));\n equal(postController1.get('model'), null);\n equal(postController2.get('model'), post);\n\n set(controller, 'post', { title: \"Rails is unagi\" });\n\n ok(view.$().text().match(/^HI ?Title: ?Title:Rails is unagi$/));\n if (Ember.create.isSimulated) {\n equal(postController2.get('model').title, \"Rails is unagi\");\n } else {\n deepEqual(postController2.get('model'), { title: \"Rails is unagi\" });\n }\n});\n\ntest(\"{{render}} helper should link child controllers to the parent controller\", function() {\n var parentTriggered = 0;\n\n var template = '

    HI

    {{render \"posts\"}}';\n var controller = Ember.Controller.extend({\n container: container,\n actions: {\n parentPlease: function() {\n parentTriggered++;\n }\n }\n });\n\n container.register('controller:posts', Ember.ArrayController.extend());\n\n view = Ember.View.create({\n controller: controller.create(),\n template: Ember.Handlebars.compile(template)\n });\n\n Ember.TEMPLATES['posts'] = compile('');\n\n appendView(view);\n\n var actionId = Ember.$(\"#parent-action\").data('ember-action'),\n action = Ember.Handlebars.ActionHelper.registeredActions[actionId],\n handler = action.handler;\n\n Ember.run(null, handler, new Ember.$.Event(\"click\"));\n\n equal(parentTriggered, 1, \"The event bubbled to the parent\");\n});\n\ntest(\"{{render}} helper should be able to render a template again when it was removed\", function() {\n var template = \"

    HI

    {{outlet}}\";\n var controller = Ember.Controller.extend({container: container});\n view = Ember.View.create({\n template: Ember.Handlebars.compile(template)\n });\n\n Ember.TEMPLATES['home'] = compile(\"

    BYE

    \");\n\n appendView(view);\n\n Ember.run(function() {\n view.connectOutlet('main', Ember.View.create({\n controller: controller.create(),\n template: compile(\"

    1{{render home}}

    \")\n }));\n });\n\n equal(view.$().text(), 'HI1BYE');\n\n Ember.run(function() {\n view.connectOutlet('main', Ember.View.create({\n controller: controller.create(),\n template: compile(\"

    2{{render home}}

    \")\n }));\n });\n\n equal(view.$().text(), 'HI2BYE');\n});\n\ntest(\"{{render}} works with dot notation\", function() {\n var template = '

    BLOG

    {{render blog.post}}';\n\n var controller = Ember.Controller.extend({container: container});\n container.register('controller:blog.post', Ember.ObjectController.extend());\n\n view = Ember.View.create({\n controller: controller.create(),\n template: Ember.Handlebars.compile(template)\n });\n\n Ember.TEMPLATES['blog/post'] = compile(\"

    POST

    \");\n\n appendView(view);\n\n var renderedView = container.lookup('router:main')._lookupActiveView('blog.post');\n equal(renderedView.get('viewName'), 'blogPost', 'camelizes the view name');\n equal(container.lookup('controller:blog.post'), renderedView.get('controller'), 'rendered with correct controller');\n});\n\ntest(\"{{render}} works with slash notation\", function() {\n var template = '

    BLOG

    {{render \"blog/post\"}}';\n\n var controller = Ember.Controller.extend({container: container});\n container.register('controller:blog.post', Ember.ObjectController.extend());\n\n view = Ember.View.create({\n controller: controller.create(),\n template: Ember.Handlebars.compile(template)\n });\n\n Ember.TEMPLATES['blog/post'] = compile(\"

    POST

    \");\n\n appendView(view);\n\n var renderedView = container.lookup('router:main')._lookupActiveView('blog.post');\n equal(renderedView.get('viewName'), 'blogPost', 'camelizes the view name');\n equal(container.lookup('controller:blog.post'), renderedView.get('controller'), 'rendered with correct controller');\n});\n\n})();\n//@ sourceURL=ember-routing/~tests/helpers/render_test");minispade.register('ember-routing/~tests/system/controller_for_test', "(function() {var buildContainer = function(namespace) {\n var container = new Ember.Container();\n\n container.set = Ember.set;\n container.resolver = resolverFor(namespace);\n container.optionsForType('view', { singleton: false });\n\n container.register('application:main', namespace, { instantiate: false });\n\n container.register('controller:basic', Ember.Controller, { instantiate: false });\n container.register('controller:object', Ember.ObjectController, { instantiate: false });\n container.register('controller:array', Ember.ArrayController, { instantiate: false });\n\n return container;\n};\n\nfunction resolverFor(namespace) {\n return function(fullName) {\n var nameParts = fullName.split(\":\"),\n type = nameParts[0], name = nameParts[1];\n\n if (name === 'basic') {\n name = '';\n }\n var className = Ember.String.classify(name) + Ember.String.classify(type);\n var factory = Ember.get(namespace, className);\n\n\n\n if (factory) { return factory; }\n };\n}\n\nvar container, appController, namespace;\n\nmodule(\"Ember.controllerFor\", {\n setup: function() {\n namespace = Ember.Namespace.create();\n container = buildContainer(namespace);\n container.register('controller:app', Ember.Controller.extend());\n appController = container.lookup('controller:app');\n },\n teardown: function() {\n Ember.run(function () {\n container.destroy();\n namespace.destroy();\n });\n }\n});\n\ntest(\"controllerFor should lookup for registered controllers\", function() {\n var controller = Ember.controllerFor(container, 'app');\n\n equal(appController, controller, 'should find app controller');\n});\n\nmodule(\"Ember.generateController\", {\n setup: function() {\n namespace = Ember.Namespace.create();\n container = buildContainer(namespace);\n },\n teardown: function() {\n Ember.run(function () {\n container.destroy();\n namespace.destroy();\n });\n }\n});\n\ntest(\"generateController should create Ember.Controller\", function() {\n var controller = Ember.generateController(container, 'home');\n\n ok(controller instanceof Ember.Controller, 'should create controller');\n});\n\ntest(\"generateController should create Ember.ObjectController\", function() {\n var context = {};\n var controller = Ember.generateController(container, 'home', context);\n\n ok(controller instanceof Ember.ObjectController, 'should create controller');\n});\n\ntest(\"generateController should create Ember.ArrayController\", function() {\n var context = Ember.A();\n var controller = Ember.generateController(container, 'home', context);\n\n ok(controller instanceof Ember.ArrayController, 'should create controller');\n});\n\ntest(\"generateController should create App.Controller if provided\", function() {\n var controller;\n namespace.Controller = Ember.Controller.extend();\n\n controller = Ember.generateController(container, 'home');\n\n ok(controller instanceof namespace.Controller, 'should create controller');\n});\n\ntest(\"generateController should create App.ObjectController if provided\", function() {\n var context = {}, controller;\n namespace.ObjectController = Ember.ObjectController.extend();\n\n controller = Ember.generateController(container, 'home', context);\n\n ok(controller instanceof namespace.ObjectController, 'should create controller');\n\n});\n\ntest(\"generateController should create App.ArrayController if provided\", function() {\n var context = Ember.A(), controller;\n namespace.ArrayController = Ember.ArrayController.extend();\n\n controller = Ember.generateController(container, 'home', context);\n\n ok(controller instanceof namespace.ArrayController, 'should create controller');\n\n});\n\n})();\n//@ sourceURL=ember-routing/~tests/system/controller_for_test");minispade.register('ember-routing/~tests/system/route_test', "(function() {var route, routeOne, routeTwo, router, container, lookupHash;\n\nmodule(\"Ember.Route\", {\n setup: function() {\n route = Ember.Route.create();\n },\n\n teardown: function() {\n Ember.run(route, 'destroy');\n }\n});\n\ntest(\"default store utilizes the container to acquire the model factory\", function() {\n var Post, post;\n\n expect(4);\n\n post = {};\n\n Post = Ember.Object.extend();\n Post.reopenClass({\n find: function(id) {\n return post;\n }\n });\n\n container = {\n lookupFactory: lookupFactory\n };\n\n route.container = container;\n\n equal(route.model({ post_id: 1}), post);\n equal(route.findModel('post', 1), post, '#findModel returns the correct post');\n\n function lookupFactory(fullName) {\n equal(fullName, \"model:post\", \"correct factory was looked up\");\n\n return Post;\n }\n\n});\n\ntest(\"'store' can be injected by data persistence frameworks\", function() {\n expect(8);\n Ember.run(route, 'destroy'); \n\n var container = new Ember.Container();\n var post = {\n id: 1\n };\n\n var Store = Ember.Object.extend({\n find: function(type, value){\n ok(true, 'injected model was called');\n equal(type, 'post', 'correct type was called');\n equal(value, 1, 'correct value was called');\n return post;\n }\n });\n\n container.register('route:index', Ember.Route);\n container.register('store:main', Store);\n\n container.injection('route', 'store', 'store:main');\n\n route = container.lookup('route:index');\n\n equal(route.model({ post_id: 1}), post, '#model returns the correct post');\n equal(route.findModel('post', 1), post, '#findModel returns the correct post');\n});\n\nmodule(\"Ember.Route interaction\", {\n setup: function() {\n container = {\n lookup: function(fullName) {\n return lookupHash[fullName];\n }\n };\n\n routeOne = Ember.Route.create({ container: container, routeName: 'one' });\n routeTwo = Ember.Route.create({ container: container, routeName: 'two' });\n\n lookupHash = {\n 'route:one': routeOne,\n 'route:two': routeTwo\n };\n },\n\n teardown: function() {\n Ember.run(function() {\n routeOne.destroy();\n routeTwo.destroy();\n });\n }\n});\n\ntest(\"controllerFor uses route's controllerName if specified\", function() {\n var testController = {};\n lookupHash['controller:test'] = testController;\n\n routeOne.controllerName = 'test';\n\n equal(routeTwo.controllerFor('one'), testController);\n});\n\n})();\n//@ sourceURL=ember-routing/~tests/system/route_test");minispade.register('ember-routing/~tests/system/router_test', "(function() {var Router;\n\nmodule(\"Ember Router\", {\n setup: function() {\n Router = Ember.Router.extend();\n },\n teardown: function() {\n Router = null;\n }\n});\n\ntest(\"should create a router if one does not exist on the constructor\", function() {\n var router = Router.create();\n ok(router.router);\n});\n\ntest(\"should destroy its location upon Router.destroy.\", function(){\n var router = Router.create(),\n location = router.get('location');\n\n Ember.run(router, 'destroy');\n\n ok(router.isDestroyed, \"router should be destroyed\");\n ok(location.isDestroyed, \"location should be destroyed\");\n});\n\n})();\n//@ sourceURL=ember-routing/~tests/system/router_test");minispade.register('ember-runtime/~tests/computed/reduce_computed_macros_test', "(function() {var map = Ember.EnumerableUtils.map,\n a_forEach = Ember.ArrayPolyfills.forEach,\n get = Ember.get,\n set = Ember.set,\n setProperties = Ember.setProperties,\n ObjectProxy = Ember.ObjectProxy,\n obj, sorted, sortProps, items, userFnCalls, todos, filtered;\n\nmodule('Ember.computed.map', {\n setup: function() {\n Ember.run(function() {\n userFnCalls = 0;\n obj = Ember.Object.createWithMixins({\n array: Ember.A([{ v: 1 }, { v: 3}, { v: 2 }, { v: 1 }]),\n\n mapped: Ember.computed.map('array.@each.v', function(item) {\n ++userFnCalls;\n return item.v;\n }),\n\n arrayObjects: Ember.A([\n Ember.Object.create({ v: { name: 'Robert' }}),\n Ember.Object.create({ v: { name: 'Leanna' }})]),\n mappedObjects: Ember.computed.map('arrayObjects.@each.v', function (item) {\n return {\n name: item.v.name\n };\n })\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"it maps simple properties\", function() {\n deepEqual(get(obj, 'mapped'), [1, 3, 2, 1]);\n\n Ember.run(function() {\n obj.get('array').pushObject({ v: 5 });\n });\n\n deepEqual(get(obj, 'mapped'), [1, 3, 2, 1, 5]);\n\n Ember.run(function() {\n obj.get('array').removeAt(3);\n });\n\n deepEqual(get(obj, 'mapped'), [1, 3, 2, 5]);\n});\n\ntest(\"it caches properly\", function() {\n var array = get(obj, 'array'),\n mapped = get(obj, 'mapped');\n\n equal(userFnCalls, 4, \"precond - mapper called expected number of times\");\n\n Ember.run(function() {\n array.addObject({v: 7});\n });\n\n equal(userFnCalls, 5, \"precond - mapper called expected number of times\");\n\n get(obj, 'mapped');\n\n equal(userFnCalls, 5, \"Ember.computed.map caches properly\");\n});\n\ntest(\"it maps simple unshifted properties\", function() {\n var array = Ember.A([]);\n\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n array: array,\n mapped: Ember.computed.map('array', function (item) { return item.toUpperCase(); })\n });\n get(obj, 'mapped');\n });\n\n Ember.run(function() {\n array.unshiftObject('c');\n array.unshiftObject('b');\n array.unshiftObject('a');\n\n array.popObject();\n });\n\n deepEqual(get(obj, 'mapped'), ['A', 'B'], \"properties unshifted in sequence are mapped correctly\");\n});\n\ntest(\"it maps objects\", function() {\n deepEqual(get(obj, 'mappedObjects'), [{ name: 'Robert'}, { name: 'Leanna' }]);\n\n Ember.run(function() {\n obj.get('arrayObjects').pushObject({ v: { name: 'Eddard' }});\n });\n\n deepEqual(get(obj, 'mappedObjects'), [{ name: 'Robert' }, { name: 'Leanna' }, { name: 'Eddard' }]);\n\n Ember.run(function() {\n obj.get('arrayObjects').removeAt(1);\n });\n\n deepEqual(get(obj, 'mappedObjects'), [{ name: 'Robert' }, { name: 'Eddard' }]);\n\n Ember.run(function() {\n obj.get('arrayObjects').objectAt(0).set('v', { name: 'Stannis' });\n });\n\n deepEqual(get(obj, 'mappedObjects'), [{ name: 'Stannis' }, { name: 'Eddard' }]);\n});\n\ntest(\"it maps unshifted objects with property observers\", function() {\n var array = Ember.A([]),\n cObj = { v: 'c' };\n\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n array: array,\n mapped: Ember.computed.map('array.@each.v', function (item) {\n return get(item, 'v').toUpperCase();\n })\n });\n get(obj, 'mapped');\n });\n\n Ember.run(function() {\n array.unshiftObject(cObj);\n array.unshiftObject({ v: 'b' });\n array.unshiftObject({ v: 'a' });\n\n set(cObj, 'v', 'd');\n });\n\n deepEqual(array.mapBy('v'), ['a', 'b', 'd'], \"precond - unmapped array is correct\");\n deepEqual(get(obj, 'mapped'), ['A', 'B', 'D'], \"properties unshifted in sequence are mapped correctly\");\n});\n\nmodule('Ember.computed.mapBy', {\n setup: function() {\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n array: Ember.A([{ v: 1 }, { v: 3}, { v: 2 }, { v: 1 }]),\n mapped: Ember.computed.mapBy('array', 'v')\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"it maps properties\", function() {\n var mapped = get(obj, 'mapped');\n\n deepEqual(get(obj, 'mapped'), [1, 3, 2, 1]);\n\n Ember.run(function() {\n obj.get('array').pushObject({ v: 5 });\n });\n\n deepEqual(get(obj, 'mapped'), [1, 3, 2, 1, 5]);\n\n Ember.run(function() {\n obj.get('array').removeAt(3);\n });\n\n deepEqual(get(obj, 'mapped'), [1, 3, 2, 5]);\n});\n\ntest(\"it is observerable\", function() {\n var mapped = get(obj, 'mapped'),\n calls = 0;\n\n deepEqual(get(obj, 'mapped'), [1, 3, 2, 1]);\n\n Ember.addObserver(obj, 'mapped.@each', function() {\n calls++;\n });\n\n Ember.run(function() {\n obj.get('array').pushObject({ v: 5 });\n });\n\n equal(calls, 1, 'Ember.computed.mapBy is observerable');\n});\n\n\nmodule('Ember.computed.filter', {\n setup: function() {\n Ember.run(function() {\n userFnCalls = 0;\n obj = Ember.Object.createWithMixins({\n array: Ember.A([1, 2, 3, 4, 5, 6, 7, 8]),\n filtered: Ember.computed.filter('array', function(item) {\n ++userFnCalls;\n return item % 2 === 0;\n })\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"it filters according to the specified filter function\", function() {\n var filtered = get(obj, 'filtered');\n\n deepEqual(filtered, [2,4,6,8], \"Ember.computed.filter filters by the specified function\");\n});\n\ntest(\"it caches properly\", function() {\n var array = get(obj, 'array'),\n filtered = get(obj, 'filtered');\n\n equal(userFnCalls, 8, \"precond - filter called expected number of times\");\n\n Ember.run(function() {\n array.addObject(11);\n });\n\n equal(userFnCalls, 9, \"precond - filter called expected number of times\");\n\n get(obj, 'filtered');\n\n equal(userFnCalls, 9, \"Ember.computed.filter caches properly\");\n});\n\ntest(\"it updates as the array is modified\", function() {\n var array = get(obj, 'array'),\n filtered = get(obj, 'filtered');\n\n deepEqual(filtered, [2,4,6,8], \"precond - filtered array is initially correct\");\n\n Ember.run(function() {\n array.addObject(11);\n });\n deepEqual(filtered, [2,4,6,8], \"objects not passing the filter are not added\");\n\n Ember.run(function() {\n array.addObject(12);\n });\n deepEqual(filtered, [2,4,6,8,12], \"objects passing the filter are added\");\n\n Ember.run(function() {\n array.removeObject(3);\n array.removeObject(4);\n });\n deepEqual(filtered, [2,6,8,12], \"objects removed from the dependent array are removed from the computed array\");\n});\n\ntest(\"the dependent array can be cleared one at a time\", function() {\n var array = get(obj, 'array'),\n filtered = get(obj, 'filtered');\n\n deepEqual(filtered, [2,4,6,8], \"precond - filtered array is initially correct\");\n\n Ember.run(function() {\n // clear 1-8 but in a random order\n array.removeObject(3);\n array.removeObject(1);\n array.removeObject(2);\n array.removeObject(4);\n array.removeObject(8);\n array.removeObject(6);\n array.removeObject(5);\n array.removeObject(7);\n });\n\n deepEqual(filtered, [], \"filtered array cleared correctly\");\n});\n\ntest(\"the dependent array can be `clear`ed directly (#3272)\", function() {\n var array = get(obj, 'array'),\n filtered = get(obj, 'filtered');\n\n deepEqual(filtered, [2,4,6,8], \"precond - filtered array is initially correct\");\n\n Ember.run(function() {\n array.clear();\n });\n\n deepEqual(filtered, [], \"filtered array cleared correctly\");\n});\n\ntest(\"it updates as the array is replaced\", function() {\n var array = get(obj, 'array'),\n filtered = get(obj, 'filtered');\n\n deepEqual(filtered, [2,4,6,8], \"precond - filtered array is initially correct\");\n\n Ember.run(function() {\n set(obj, 'array', Ember.A([20,21,22,23,24]));\n });\n deepEqual(filtered, [20,22,24], \"computed array is updated when array is changed\");\n});\n\nmodule('Ember.computed.filterBy', {\n setup: function() {\n obj = Ember.Object.createWithMixins({\n array: Ember.A([\n {name: \"one\", a:1, b:false},\n {name: \"two\", a:2, b:false},\n {name: \"three\", a:1, b:true},\n {name: \"four\", b:true}\n ]),\n a1s: Ember.computed.filterBy('array', 'a', 1),\n as: Ember.computed.filterBy('array', 'a'),\n bs: Ember.computed.filterBy('array', 'b')\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"properties can be filtered by truthiness\", function() {\n var array = get(obj, 'array'),\n as = get(obj, 'as'),\n bs = get(obj, 'bs');\n\n deepEqual(as.mapBy('name'), ['one', 'two', 'three'], \"properties can be filtered by existence\");\n deepEqual(bs.mapBy('name'), ['three', 'four'], \"booleans can be filtered\");\n\n Ember.run(function() {\n set(array.objectAt(0), 'a', undefined);\n set(array.objectAt(3), 'a', true);\n\n set(array.objectAt(0), 'b', true);\n set(array.objectAt(3), 'b', false);\n });\n deepEqual(as.mapBy('name'), ['two', 'three', 'four'], \"arrays computed by filter property respond to property changes\");\n deepEqual(bs.mapBy('name'), ['one', 'three'], \"arrays computed by filtered property respond to property changes\");\n\n Ember.run(function() {\n array.pushObject({name:\"five\", a:6, b:true});\n });\n deepEqual(as.mapBy('name'), ['two', 'three', 'four', 'five'], \"arrays computed by filter property respond to added objects\");\n deepEqual(bs.mapBy('name'), ['one', 'three', 'five'], \"arrays computed by filtered property respond to added objects\");\n\n Ember.run(function() {\n array.popObject();\n });\n deepEqual(as.mapBy('name'), ['two', 'three', 'four'], \"arrays computed by filter property respond to removed objects\");\n deepEqual(bs.mapBy('name'), ['one', 'three'], \"arrays computed by filtered property respond to removed objects\");\n\n Ember.run(function() {\n set(obj, 'array', Ember.A([{name: \"six\", a:12, b:true}]));\n });\n deepEqual(as.mapBy('name'), ['six'], \"arrays computed by filter property respond to array changes\");\n deepEqual(bs.mapBy('name'), ['six'], \"arrays computed by filtered property respond to array changes\");\n});\n\ntest(\"properties can be filtered by values\", function() {\n var array = get(obj, 'array'),\n a1s = get(obj, 'a1s');\n\n deepEqual(a1s.mapBy('name'), ['one', 'three'], \"properties can be filtered by matching value\");\n\n Ember.run(function() {\n array.pushObject({ name: \"five\", a:1 });\n });\n deepEqual(a1s.mapBy('name'), ['one', 'three', 'five'], \"arrays computed by matching value respond to added objects\");\n\n Ember.run(function() {\n array.popObject();\n });\n deepEqual(a1s.mapBy('name'), ['one', 'three'], \"arrays computed by matching value respond to removed objects\");\n\n Ember.run(function() {\n set(array.objectAt(1), 'a', 1);\n set(array.objectAt(2), 'a', 2);\n });\n deepEqual(a1s.mapBy('name'), ['one', 'two'], \"arrays computed by matching value respond to modified properties\");\n});\n\na_forEach.call(['uniq', 'union'], function (alias) {\n module('Ember.computed.' + alias, {\n setup: function() {\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n array: Ember.A([1,2,3,4,5,6]),\n array2: Ember.A([4,5,6,7,8,9,4,5,6,7,8,9]),\n array3: Ember.A([1,8,10]),\n union: Ember.computed[alias]('array', 'array2', 'array3')\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n });\n\n test(\"does not include duplicates\", function() {\n var array = get(obj, 'array'),\n array2 = get(obj, 'array2'),\n array3 = get(obj, 'array3'),\n union = get(obj, 'union');\n\n deepEqual(union, [1,2,3,4,5,6,7,8,9,10], alias + \" does not include duplicates\");\n\n Ember.run(function() {\n array.pushObject(8);\n });\n\n deepEqual(union, [1,2,3,4,5,6,7,8,9,10], alias + \" does not add existing items\");\n\n Ember.run(function() {\n array.pushObject(11);\n });\n\n deepEqual(union, [1,2,3,4,5,6,7,8,9,10,11], alias + \" adds new items\");\n\n Ember.run(function() {\n array2.removeAt(6); // remove 7\n });\n\n deepEqual(union, [1,2,3,4,5,6,7,8,9,10,11], alias + \" does not remove items that are still in the dependent array\");\n\n Ember.run(function() {\n array2.removeObject(7);\n });\n\n deepEqual(union, [1,2,3,4,5,6,8,9,10,11], alias + \" removes items when their last instance is gone\");\n });\n\n test(\"has set-union semantics\", function() {\n var array = get(obj, 'array'),\n array2 = get(obj, 'array2'),\n array3 = get(obj, 'array3'),\n union = get(obj, 'union');\n\n deepEqual(union, [1,2,3,4,5,6,7,8,9,10], alias + \" is initially correct\");\n\n Ember.run(function() {\n array.removeObject(6);\n });\n\n deepEqual(union, [1,2,3,4,5,6,7,8,9,10], \"objects are not removed if they exist in other dependent arrays\");\n\n Ember.run(function() {\n array.clear();\n });\n\n deepEqual(union, [1,4,5,6,7,8,9,10], \"objects are removed when they are no longer in any dependent array\");\n });\n});\n\nmodule('Ember.computed.intersect', {\n setup: function() {\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n array: Ember.A([1,2,3,4,5,6]),\n array2: Ember.A([3,3,3,4,5]),\n array3: Ember.A([3,5,6,7,8]),\n intersection: Ember.computed.intersect('array', 'array2', 'array3')\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"it has set-intersection semantics\", function() {\n var array = get(obj, 'array'),\n array2 = get(obj, 'array2'),\n array3 = get(obj, 'array3'),\n intersection = get(obj, 'intersection');\n\n deepEqual(intersection, [3,5], \"intersection is initially correct\");\n\n Ember.run(function() {\n array2.shiftObject();\n });\n deepEqual(intersection, [3,5], \"objects are not removed when they are still in all dependent arrays\");\n\n Ember.run(function() {\n array2.shiftObject();\n });\n deepEqual(intersection, [3,5], \"objects are not removed when they are still in all dependent arrays\");\n\n Ember.run(function() {\n array2.shiftObject();\n });\n deepEqual(intersection, [5], \"objects are removed once they are gone from all dependent arrays\");\n\n Ember.run(function() {\n array2.pushObject(1);\n });\n deepEqual(intersection, [5], \"objects are not added as long as they are missing from any dependent array\");\n\n Ember.run(function() {\n array3.pushObject(1);\n });\n deepEqual(intersection, [5,1], \"objects added once they belong to all dependent arrays\");\n});\n\n\nmodule('Ember.computed.setDiff', {\n setup: function() {\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n array: Ember.A([1,2,3,4,5,6,7]),\n array2: Ember.A([3,4,5,10]),\n diff: Ember.computed.setDiff('array', 'array2')\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"it throws an error if given fewer or more than two dependent properties\", function() {\n throws(function () {\n Ember.Object.createWithMixins({\n array: Ember.A([1,2,3,4,5,6,7]),\n array2: Ember.A([3,4,5]),\n diff: Ember.computed.setDiff('array')\n });\n }, /requires exactly two dependent arrays/, \"setDiff requires two dependent arrays\");\n\n throws(function () {\n Ember.Object.createWithMixins({\n array: Ember.A([1,2,3,4,5,6,7]),\n array2: Ember.A([3,4,5]),\n array3: Ember.A([7]),\n diff: Ember.computed.setDiff('array', 'array2', 'array3')\n });\n }, /requires exactly two dependent arrays/, \"setDiff requires two dependent arrays\");\n});\n\n\ntest(\"it has set-diff semantics\", function() {\n var array1 = get(obj, 'array'),\n array2 = get(obj, 'array2'),\n diff = get(obj, 'diff');\n\n deepEqual(diff, [1, 2, 6, 7], \"set-diff is initially correct\");\n\n Ember.run(function() {\n array2.popObject();\n });\n deepEqual(diff, [1,2,6,7], \"removing objects from the remove set has no effect if the object is not in the keep set\");\n\n Ember.run(function() {\n array2.shiftObject();\n });\n deepEqual(diff, [1, 2, 6, 7, 3], \"removing objects from the remove set adds them if they're in the keep set\");\n\n Ember.run(function() {\n array1.removeObject(3);\n });\n deepEqual(diff, [1, 2, 6, 7], \"removing objects from the keep array removes them from the computed array\");\n\n Ember.run(function() {\n array1.pushObject(5);\n });\n deepEqual(diff, [1, 2, 6, 7], \"objects added to the keep array that are in the remove array are not added to the computed array\");\n\n Ember.run(function() {\n array1.pushObject(22);\n });\n deepEqual(diff, [1, 2, 6, 7, 22], \"objects added to the keep array not in the remove array are added to the computed array\");\n});\n\n\nfunction commonSortTests() {\n test(\"arrays are initially sorted\", function() {\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"array is initially sorted\");\n });\n\n test(\"changing the dependent array updates the sorted array\", function() {\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n set(obj, 'items', Ember.A([{\n fname: 'Roose', lname: 'Bolton'\n }, {\n fname: 'Theon', lname: 'Greyjoy'\n }, {\n fname: 'Ramsey', lname: 'Bolton'\n }, {\n fname: 'Stannis', lname: 'Baratheon'\n }]));\n });\n\n deepEqual(sorted.mapBy('fname'), ['Stannis', 'Ramsey', 'Roose', 'Theon'], \"changing dependent array updates sorted array\");\n });\n\n test(\"adding to the dependent array updates the sorted array\", function() {\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n items = get(obj, 'items');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n items.pushObject({ fname: 'Tyrion', lname: 'Lannister' });\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Tyrion', 'Bran', 'Robb'], \"Adding to the dependent array updates the sorted array\");\n });\n\n test(\"removing from the dependent array updates the sorted array\", function() {\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n items = get(obj, 'items');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n items.popObject();\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Robb'], \"Removing from the dependent array updates the sorted array\");\n });\n\n test(\"distinct items may be sort-equal, although their relative order will not be guaranteed\", function() {\n var jaime, jaimeInDisguise;\n\n Ember.run(function() {\n // We recreate jaime and \"Cersei\" here only for test stability: we want\n // their guid-ordering to be deterministic\n jaimeInDisguise = Ember.Object.create({\n fname: 'Cersei', lname: 'Lannister', age: 34\n });\n jaime = Ember.Object.create({\n fname: 'Jaime', lname: 'Lannister', age: 34\n });\n items = get(obj, 'items');\n\n items.replace(0, 1, jaime);\n items.replace(1, 1, jaimeInDisguise);\n sorted = get(obj, 'sortedItems');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n // comparator will now return 0.\n // Apparently it wasn't a very good disguise.\n jaimeInDisguise.set('fname', 'Jaime');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Jaime', 'Jaime', 'Bran', 'Robb'], \"sorted array is updated\");\n\n Ember.run(function() {\n // comparator will again return non-zero\n jaimeInDisguise.set('fname', 'Cersei');\n });\n\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"sorted array is updated\");\n });\n\n test(\"guid sort-order fallback with a serach proxy is not confused by non-search ObjectProxys\", function() {\n var tyrion = { fname: \"Tyrion\", lname: \"Lannister\" },\n tyrionInDisguise = ObjectProxy.create({\n fname: \"Yollo\",\n lname: \"\",\n content: tyrion\n });\n\n items = get(obj, 'items');\n sorted = get(obj, 'sortedItems');\n\n Ember.run(function() {\n items.pushObject(tyrion);\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Tyrion', 'Bran', 'Robb']);\n\n Ember.run(function() {\n items.pushObject(tyrionInDisguise);\n });\n\n deepEqual(sorted.mapBy('fname'), ['Yollo', 'Cersei', 'Jaime', 'Tyrion', 'Bran', 'Robb']);\n });\n}\n\nmodule('Ember.computed.sort - sortProperties', {\n setup: function() {\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n itemSorting: Ember.A(['lname', 'fname']),\n items: Ember.A([{\n fname: \"Jaime\", lname: \"Lannister\", age: 34\n }, {\n fname: \"Cersei\", lname: \"Lannister\", age: 34\n }, {\n fname: \"Robb\", lname: \"Stark\", age: 16\n }, {\n fname: \"Bran\", lname: \"Stark\", age: 8\n }]),\n\n sortedItems: Ember.computed.sort('items', 'itemSorting')\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ncommonSortTests();\n\ntest(\"updating sort properties updates the sorted array\", function() {\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n set(obj, 'itemSorting', Ember.A(['fname:desc']));\n });\n\n deepEqual(sorted.mapBy('fname'), ['Robb', 'Jaime', 'Cersei', 'Bran'], \"after updating sort properties array is updated\");\n});\n\ntest(\"updating sort properties in place updates the sorted array\", function() {\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n sortProps = get(obj, 'itemSorting');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n \n Ember.run(function() {\n sortProps.clear();\n sortProps.pushObject('fname');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Bran', 'Cersei', 'Jaime', 'Robb'], \"after updating sort properties array is updated\");\n});\n\ntest(\"updating new sort properties in place updates the sorted array\", function() {\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n set(obj, 'itemSorting', Ember.A(['age:desc', 'fname:asc']));\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Robb', 'Bran'], \"precond - array is correct after item sorting is changed\");\n\n Ember.run(function() {\n items = get(obj, 'items');\n\n var cersei = items.objectAt(1);\n set(cersei, 'age', 29); // how vain\n });\n\n deepEqual(sorted.mapBy('fname'), ['Jaime', 'Cersei', 'Robb', 'Bran'], \"after updating sort properties array is updated\");\n});\n\ntest(\"sort direction defaults to ascending\", function() {\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n set(obj, 'itemSorting', Ember.A(['fname']));\n });\n\n deepEqual(sorted.mapBy('fname'), ['Bran', 'Cersei', 'Jaime', 'Robb'], \"sort direction defaults to ascending\");\n});\n\ntest(\"updating an item's sort properties updates the sorted array\", function() {\n var tyrionInDisguise;\n\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n items = get(obj, 'items');\n });\n\n tyrionInDisguise = items.objectAt(1);\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n set(tyrionInDisguise, 'fname', 'Tyrion');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Jaime', 'Tyrion', 'Bran', 'Robb'], \"updating an item's sort properties updates the sorted array\");\n});\n\ntest(\"updating several of an item's sort properties updated the sorted array\", function() {\n var sansaInDisguise;\n\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n items = get(obj, 'items');\n });\n\n sansaInDisguise = items.objectAt(1);\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n setProperties(sansaInDisguise, {\n fname: 'Sansa',\n lname: 'Stark'\n });\n });\n\n deepEqual(sorted.mapBy('fname'), ['Jaime', 'Bran', 'Robb', 'Sansa'], \"updating an item's sort properties updates the sorted array\");\n});\n\ntest(\"updating an item's sort properties does not error when binary search does a self compare (#3273)\", function() {\n var jaime, cersei;\n\n Ember.run(function() {\n jaime = Ember.Object.create({\n name: 'Jaime',\n status: 1\n });\n cersei = Ember.Object.create({\n name: 'Cersei',\n status: 2\n });\n\n obj = Ember.Object.createWithMixins({\n people: Ember.A([jaime, cersei]),\n sortProps: Ember.A(['status']),\n sortedPeople: Ember.computed.sort('people', 'sortProps')\n });\n });\n\n deepEqual(get(obj, 'sortedPeople'), [jaime, cersei], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n cersei.set('status', 3);\n });\n\n deepEqual(get(obj, 'sortedPeople'), [jaime, cersei], \"array is sorted correctly\");\n\n Ember.run(function() {\n cersei.set('status', 2);\n });\n\n deepEqual(get(obj, 'sortedPeople'), [jaime, cersei], \"array is sorted correctly\");\n});\n\n\nfunction sortByLnameFname(a, b) {\n var lna = get(a, 'lname'),\n lnb = get(b, 'lname');\n\n if (lna !== lnb) {\n return lna > lnb ? 1 : -1;\n }\n\n return sortByFnameAsc(a,b);\n}\n\nfunction sortByFnameAsc(a, b) {\n var fna = get(a, 'fname'),\n fnb = get(b, 'fname');\n\n if (fna === fnb) {\n return 0;\n }\n return fna > fnb ? 1 : -1;\n}\n\nfunction sortByFnameDesc(a, b) {\n return -sortByFnameAsc(a,b);\n}\n\nmodule('Ember.computed.sort - sort function', {\n setup: function() {\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n items: Ember.A([{\n fname: \"Jaime\", lname: \"Lannister\", age: 34\n }, {\n fname: \"Cersei\", lname: \"Lannister\", age: 34\n }, {\n fname: \"Robb\", lname: \"Stark\", age: 16\n }, {\n fname: \"Bran\", lname: \"Stark\", age: 8\n }]),\n\n sortedItems: Ember.computed.sort('items.@each.fname', sortByLnameFname)\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ncommonSortTests();\n\ntest(\"changing item properties specified via @each triggers a resort of the modified item\", function() {\n var tyrionInDisguise;\n\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n items = get(obj, 'items');\n });\n\n tyrionInDisguise = items.objectAt(1);\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n set(tyrionInDisguise, 'fname', 'Tyrion');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Jaime', 'Tyrion', 'Bran', 'Robb'], \"updating a specified property on an item resorts it\");\n});\n\ntest(\"changing item properties not specified via @each does not trigger a resort\", function() {\n var cersei;\n\n Ember.run(function() {\n sorted = get(obj, 'sortedItems');\n items = get(obj, 'items');\n });\n\n cersei = items.objectAt(1);\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"precond - array is initially sorted\");\n\n Ember.run(function() {\n set(cersei, 'lname', 'Stark'); // plot twist! (possibly not canon)\n });\n\n // The array has become unsorted. If your sort function is sensitive to\n // properties, they *must* be specified as dependent item property keys or\n // we'll be doing binary searches on unsorted arrays.\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime', 'Bran', 'Robb'], \"updating an unspecified property on an item does not resort it\");\n});\n\nmodule('Ember.computed.max', {\n setup: function() {\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n items: Ember.A([1,2,3]),\n max: Ember.computed.max('items')\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"max tracks the max number as objects are added\", function() {\n equal(get(obj, 'max'), 3, \"precond - max is initially correct\");\n\n Ember.run(function() {\n items = get(obj, 'items');\n });\n\n Ember.run(function() {\n items.pushObject(5);\n });\n\n equal(get(obj, 'max'), 5, \"max updates when a larger number is added\");\n\n Ember.run(function() {\n items.pushObject(2);\n });\n\n equal(get(obj, 'max'), 5, \"max does not update when a smaller number is added\");\n});\n\ntest(\"max recomputes when the current max is removed\", function() {\n equal(get(obj, 'max'), 3, \"precond - max is initially correct\");\n\n Ember.run(function() {\n items = get(obj, 'items');\n items.removeObject(2);\n });\n\n equal(get(obj, 'max'), 3, \"max is unchanged when a non-max item is removed\");\n\n Ember.run(function() {\n items.removeObject(3);\n });\n\n equal(get(obj, 'max'), 1, \"max is recomputed when the current max is removed\");\n});\n\nmodule('Ember.computed.min', {\n setup: function() {\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n items: Ember.A([1,2,3]),\n min: Ember.computed.min('items')\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"min tracks the min number as objects are added\", function() {\n equal(get(obj, 'min'), 1, \"precond - min is initially correct\");\n\n Ember.run(function() {\n items = get(obj, 'items');\n });\n\n Ember.run(function() {\n items.pushObject(-2);\n });\n\n equal(get(obj, 'min'), -2, \"min updates when a smaller number is added\");\n\n Ember.run(function() {\n items.pushObject(2);\n });\n\n equal(get(obj, 'min'), -2, \"min does not update when a larger number is added\");\n});\n\ntest(\"min recomputes when the current min is removed\", function() {\n equal(get(obj, 'min'), 1, \"precond - min is initially correct\");\n\n Ember.run(function() {\n items = get(obj, 'items');\n items.removeObject(2);\n });\n\n equal(get(obj, 'min'), 1, \"min is unchanged when a non-min item is removed\");\n\n Ember.run(function() {\n items.removeObject(1);\n });\n\n equal(get(obj, 'min'), 3, \"min is recomputed when the current min is removed\");\n});\n\nmodule('Ember.arrayComputed - mixed sugar', {\n setup: function() {\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n items: Ember.A([{\n fname: \"Jaime\", lname: \"Lannister\", age: 34\n }, {\n fname: \"Cersei\", lname: \"Lannister\", age: 34\n }, {\n fname: \"Robb\", lname: \"Stark\", age: 16\n }, {\n fname: \"Bran\", lname: \"Stark\", age: 8\n }]),\n\n lannisters: Ember.computed.filterBy('items', 'lname', 'Lannister'),\n lannisterSorting: Ember.A(['fname']),\n sortedLannisters: Ember.computed.sort('lannisters', 'lannisterSorting'),\n\n\n starks: Ember.computed.filterBy('items', 'lname', 'Stark'),\n starkAges: Ember.computed.mapBy('starks', 'age'),\n oldestStarkAge: Ember.computed.max('starkAges')\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"filtering and sorting can be combined\", function() {\n Ember.run(function() {\n items = get(obj, 'items');\n sorted = get(obj, 'sortedLannisters');\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Jaime'], \"precond - array is initially filtered and sorted\");\n\n Ember.run(function() {\n items.pushObject({fname: 'Tywin', lname: 'Lannister'});\n items.pushObject({fname: 'Lyanna', lname: 'Stark'});\n items.pushObject({fname: 'Gerion', lname: 'Lannister'});\n });\n\n deepEqual(sorted.mapBy('fname'), ['Cersei', 'Gerion', 'Jaime', 'Tywin'], \"updates propagate to array\");\n});\n\ntest(\"filtering, sorting and reduce (max) can be combined\", function() {\n Ember.run(function() {\n items = get(obj, 'items');\n });\n\n equal(16, get(obj, 'oldestStarkAge'), \"precond - end of chain is initially correct\");\n\n Ember.run(function() {\n items.pushObject({fname: 'Rickon', lname: 'Stark', age: 5});\n });\n\n equal(16, get(obj, 'oldestStarkAge'), \"chain is updated correctly\");\n\n Ember.run(function() {\n items.pushObject({fname: 'Eddard', lname: 'Stark', age: 35});\n });\n\n equal(35, get(obj, 'oldestStarkAge'), \"chain is updated correctly\");\n});\n\nfunction todo(name, priority) {\n return Ember.Object.create({name: name, priority: priority});\n}\n\nfunction priorityComparator(todoA, todoB) {\n var pa = parseInt(get(todoA, 'priority'), 10),\n pb = parseInt(get(todoB, 'priority'), 10);\n\n return pa - pb;\n}\n\nfunction evenPriorities(todo) {\n var p = parseInt(get(todo, 'priority'), 10);\n\n return p % 2 === 0;\n}\n\nmodule('Ember.arrayComputed - chains', {\n setup: function() {\n obj = Ember.Object.createWithMixins({\n todos: Ember.A([todo('E', 4), todo('D', 3), todo('C', 2), todo('B', 1), todo('A', 0)]),\n sorted: Ember.computed.sort('todos.@each.priority', priorityComparator),\n filtered: Ember.computed.filter('sorted.@each.priority', evenPriorities)\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"it can filter and sort when both depend on the same item property\", function() {\n filtered = get(obj, 'filtered');\n sorted = get(obj, 'sorted');\n todos = get(obj, 'todos');\n\n deepEqual(todos.mapProperty('name'), ['E', 'D', 'C', 'B', 'A'], \"precond - todos initially correct\");\n deepEqual(sorted.mapProperty('name'), ['A', 'B', 'C', 'D', 'E'], \"precond - sorted initially correct\");\n deepEqual(filtered.mapProperty('name'), ['A', 'C', 'E'], \"precond - filtered initially correct\");\n\n Ember.run(function() {\n Ember.beginPropertyChanges();\n // here we trigger several changes\n // A. D.priority 3 -> 6\n // 1. updated sorted from item property change\n // a. remove D; reinsert D\n // b. update filtered from sorted change\n // 2. update filtered from item property change\n //\n // If 1.b happens before 2 it should invalidate 2\n todos.objectAt(1).set('priority', 6);\n Ember.endPropertyChanges();\n });\n\n deepEqual(todos.mapProperty('name'), ['E', 'D', 'C', 'B', 'A'], \"precond - todos remain correct\");\n deepEqual(sorted.mapProperty('name'), ['A', 'B', 'C', 'E', 'D'], \"precond - sorted updated correctly\");\n deepEqual(filtered.mapProperty('name'), ['A', 'C', 'E', 'D'], \"filtered updated correctly\");\n});\n\nmodule('Chaining array and reduced CPs', {\n setup: function() {\n Ember.run(function() {\n userFnCalls = 0;\n obj = Ember.Object.createWithMixins({\n array: Ember.A([{ v: 1 }, { v: 3}, { v: 2 }, { v: 1 }]),\n mapped: Ember.computed.mapBy('array', 'v'),\n max: Ember.computed.max('mapped'),\n maxDidChange: Ember.observer('max', function(){\n userFnCalls++;\n })\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"it computes interdependent array computed properties\", function() {\n var mapped = get(obj, 'mapped');\n\n equal(get(obj, 'max'), 3, 'sanity - it properly computes the maximum value');\n equal(userFnCalls, 0, 'observer is not called on initialisation');\n\n var calls = 0;\n Ember.addObserver(obj, 'max', function(){ calls++; });\n\n Ember.run(function() {\n obj.get('array').pushObject({ v: 5 });\n });\n\n equal(get(obj, 'max'), 5, 'maximum value is updated correctly');\n equal(userFnCalls, 1, 'object defined observers fire');\n equal(calls, 1, 'runtime created observers fire');\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/computed/reduce_computed_macros_test");minispade.register('ember-runtime/~tests/computed/reduce_computed_test', "(function() {\nvar obj, addCalls, removeCalls, map = Ember.EnumerableUtils.map, get = Ember.get, set = Ember.set, callbackItems;\nmodule('Ember.arrayComputed', {\n setup: function () {\n addCalls = removeCalls = 0;\n\n obj = Ember.Object.createWithMixins({\n numbers: Ember.A([ 1, 2, 3, 4, 5, 6 ]),\n otherNumbers: Ember.A([ 7, 8, 9 ]),\n\n // Users would obviously just use `Ember.computed.map`\n // This implemantion is fine for these tests, but doesn't properly work as\n // it's not index based.\n evenNumbers: Ember.arrayComputed('numbers', {\n addedItem: function (array, item) {\n addCalls++;\n if (item % 2 === 0) {\n array.pushObject(item);\n }\n return array;\n },\n removedItem: function (array, item) {\n removeCalls++;\n array.removeObject(item);\n return array;\n }\n }),\n\n evenNumbersMultiDep: Ember.arrayComputed('numbers', 'otherNumbers', {\n addedItem: function (array, item) {\n if (item % 2 === 0) {\n array.pushObject(item);\n }\n return array;\n }\n }),\n\n nestedNumbers: Ember.A(map([1,2,3,4,5,6], function (n) {\n return Ember.Object.create({ p: 'otherProperty', v: n });\n })),\n\n evenNestedNumbers: Ember.arrayComputed({\n addedItem: function (array, item, keyName) {\n var value = item.get('v');\n if (value % 2 === 0) {\n array.pushObject(value);\n }\n return array;\n },\n removedItem: function (array, item, keyName) {\n array.removeObject(item.get('v'));\n return array;\n }\n }).property('nestedNumbers.@each.v')\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\n\ntest(\"array computed properties are instances of Ember.ComputedProperty\", function() {\n ok(Ember.arrayComputed({}) instanceof Ember.ComputedProperty);\n});\n\ntest(\"when the dependent array is null or undefined, `addedItem` is not called and only the initial value is returned\", function() {\n obj = Ember.Object.createWithMixins({\n numbers: null,\n doubledNumbers: Ember.arrayComputed('numbers', {\n addedItem: function (array, n) {\n addCalls++;\n array.pushObject(n * 2);\n return array;\n }\n })\n });\n\n deepEqual(get(obj, 'doubledNumbers'), [], \"When the dependent array is null, the initial value is returned\");\n equal(addCalls, 0, \"`addedItem` is not called when the dependent array is null\");\n\n Ember.run(function() {\n set(obj, 'numbers', Ember.A([1,2]));\n });\n\n deepEqual(get(obj, 'doubledNumbers'), [2,4], \"An initially null dependent array can still be set later\");\n equal(addCalls, 2, \"`addedItem` is called when the dependent array is initially set\");\n});\n\ntest(\"on first retrieval, array computed properties are computed\", function() {\n deepEqual(get(obj, 'evenNumbers'), [2,4,6], \"array computed properties are correct on first invocation\");\n});\n\ntest(\"on first retrieval, array computed properties with multiple dependent keys are computed\", function() {\n deepEqual(get(obj, 'evenNumbersMultiDep'), [2, 4, 6, 8], \"array computed properties are correct on first invocation\");\n});\n\ntest(\"on first retrieval, array computed properties dependent on nested objects are computed\", function() {\n deepEqual(get(obj, 'evenNestedNumbers'), [2,4,6], \"array computed properties are correct on first invocation\");\n});\n\ntest(\"after the first retrieval, array computed properties observe additions to dependent arrays\", function() {\n var numbers = get(obj, 'numbers'),\n // set up observers\n evenNumbers = get(obj, 'evenNumbers');\n\n Ember.run(function() {\n numbers.pushObjects([7, 8]);\n });\n\n deepEqual(evenNumbers, [2, 4, 6, 8], \"array computed properties watch dependent arrays\");\n});\n\ntest(\"after the first retrieval, array computed properties observe removals from dependent arrays\", function() {\n var numbers = get(obj, 'numbers'),\n // set up observers\n evenNumbers = get(obj, 'evenNumbers');\n\n Ember.run(function() {\n numbers.removeObjects([3, 4]);\n });\n\n deepEqual(evenNumbers, [2, 6], \"array computed properties watch dependent arrays\");\n});\n\ntest(\"after first retrieval, array computed properties can observe properties on array items\", function() {\n var nestedNumbers = get(obj, 'nestedNumbers'),\n evenNestedNumbers = get(obj, 'evenNestedNumbers');\n\n deepEqual(evenNestedNumbers, [2, 4, 6], 'precond -- starts off with correct values');\n\n Ember.run(function() {\n nestedNumbers.objectAt(0).set('v', 22);\n });\n\n deepEqual(nestedNumbers.mapBy('v'), [22, 2, 3, 4, 5, 6], 'nested numbers is updated');\n deepEqual(evenNestedNumbers, [2, 4, 6, 22], 'adds new number');\n});\n\ntest(\"changes to array computed properties happen synchronously\", function() {\n var nestedNumbers = get(obj, 'nestedNumbers'),\n evenNestedNumbers = get(obj, 'evenNestedNumbers');\n\n deepEqual(evenNestedNumbers, [2, 4, 6], 'precond -- starts off with correct values');\n\n Ember.run(function() {\n nestedNumbers.objectAt(0).set('v', 22);\n deepEqual(nestedNumbers.mapBy('v'), [22, 2, 3, 4, 5, 6], 'nested numbers is updated');\n deepEqual(evenNestedNumbers, [2, 4, 6, 22], 'adds new number');\n });\n});\n\nif (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {\n test(\"multiple dependent keys can be specified via brace expansion\", function() {\n var obj = Ember.Object.createWithMixins({\n bar: Ember.A(),\n baz: Ember.A(),\n foo: Ember.reduceComputed({\n initialValue: Ember.A(),\n addedItem: function(array, item) { array.pushObject('a:' + item); return array; },\n removedItem: function(array, item) { array.pushObject('r:' + item); return array; }\n }).property('{bar,baz}')\n });\n\n deepEqual(get(obj, 'foo'), [], \"initially empty\");\n\n get(obj, 'bar').pushObject(1);\n\n deepEqual(get(obj, 'foo'), ['a:1'], \"added item from brace-expanded dependency\");\n\n get(obj, 'baz').pushObject(2);\n\n deepEqual(get(obj, 'foo'), ['a:1', 'a:2'], \"added item from brace-expanded dependency\");\n\n get(obj, 'bar').popObject();\n\n deepEqual(get(obj, 'foo'), ['a:1', 'a:2', 'r:1'], \"removed item from brace-expanded dependency\");\n\n get(obj, 'baz').popObject();\n\n deepEqual(get(obj, 'foo'), ['a:1', 'a:2', 'r:1', 'r:2'], \"removed item from brace-expanded dependency\");\n });\n\n test(\"multiple item property keys can be specified via brace expansion\", function() {\n var addedCalls = 0,\n removedCalls = 0,\n expected = Ember.A(),\n item = { propA: 'A', propB: 'B', propC: 'C' },\n obj = Ember.Object.createWithMixins({\n bar: Ember.A([item]),\n foo: Ember.reduceComputed({\n initialValue: Ember.A(),\n addedItem: function(array, item, changeMeta) {\n array.pushObject('a:' + get(item, 'propA') + ':' + get(item, 'propB') + ':' + get(item, 'propC'));\n return array;\n },\n removedItem: function(array, item, changeMeta) {\n array.pushObject('r:' + get(item, 'propA') + ':' + get(item, 'propB') + ':' + get(item, 'propC'));\n return array;\n }\n }).property('bar.@each.{propA,propB}')\n });\n\n expected.pushObjects(['a:A:B:C']);\n deepEqual(get(obj, 'foo'), expected, \"initially added dependent item\");\n\n set(item, 'propA', 'AA');\n\n expected.pushObjects(['r:AA:B:C', 'a:AA:B:C']);\n deepEqual(get(obj, 'foo'), expected, \"observing item property key specified via brace expansion\");\n\n set(item, 'propB', 'BB');\n\n expected.pushObjects(['r:AA:BB:C', 'a:AA:BB:C']);\n deepEqual(get(obj, 'foo'), expected, \"observing item property key specified via brace expansion\");\n\n set(item, 'propC', 'CC');\n\n deepEqual(get(obj, 'foo'), expected, \"not observing unspecified item properties\");\n });\n}\n\ntest(\"doubly nested item property keys (@each.foo.@each) are not supported\", function() {\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n peopleByOrdinalPosition: Ember.A([{ first: Ember.A([Ember.Object.create({ name: \"Jaime Lannister\" })])}]),\n people: Ember.arrayComputed({\n addedItem: function (array, item) {\n array.pushObject(get(item, 'first.firstObject'));\n return array;\n }\n }).property('peopleByOrdinalPosition.@each.first'),\n names: Ember.arrayComputed({\n addedItem: function (array, item) {\n equal(get(item, 'name'), 'Jaime Lannister');\n array.pushObject(item.get('name'));\n return array;\n }\n }).property('people.@each.name')\n });\n });\n\n equal(obj.get('names.firstObject'), 'Jaime Lannister', \"Doubly nested item properties can be retrieved manually\");\n\n throws(function() {\n obj = Ember.Object.createWithMixins({\n people: [{ first: Ember.A([Ember.Object.create({ name: \"Jaime Lannister\" })])}],\n names: Ember.arrayComputed({\n addedItem: function (array, item) {\n array.pushObject(item);\n return array;\n }\n }).property('people.@each.first.@each.name')\n });\n }, /Nested @each/, \"doubly nested item property keys are not supported\");\n});\n\ntest(\"after the first retrieval, array computed properties observe dependent arrays\", function() {\n var numbers = get(obj, 'numbers'),\n evenNumbers = get(obj, 'evenNumbers');\n\n deepEqual(evenNumbers, [2, 4, 6], 'precond -- starts off with correct values');\n\n Ember.run(function() {\n set(obj, 'numbers', Ember.A([20, 23, 28]));\n });\n\n deepEqual(evenNumbers, [20, 28], \"array computed properties watch dependent arrays\");\n});\n\ntest(\"array observers are torn down when dependent arrays change\", function() {\n var numbers = get(obj, 'numbers'),\n evenNumbers = get(obj, 'evenNumbers');\n\n equal(addCalls, 6, 'precond - add has been called for each item in the array');\n equal(removeCalls, 0, 'precond - removed has not been called');\n\n Ember.run(function() {\n set(obj, 'numbers', Ember.A([20, 23, 28]));\n });\n\n equal(addCalls, 9, 'add is called for each item in the new array');\n equal(removeCalls, 0, 'remove is not called when the array is reset');\n\n numbers.replace(0, numbers.get('length'), Ember.A([7,8,9,10]));\n\n equal(addCalls, 9, 'add is not called');\n equal(removeCalls, 0, 'remove is not called');\n});\n\ntest(\"modifying properties on dependent array items triggers observers exactly once\", function() {\n var numbers = get(obj, 'numbers'),\n evenNumbers = get(obj, 'evenNumbers');\n\n equal(addCalls, 6, 'precond - add has not been called for each item in the array');\n equal(removeCalls, 0, 'precond - removed has not been called');\n\n Ember.run(function() {\n numbers.replace(0,2,[7,8,9,10]);\n });\n\n equal(addCalls, 10, 'add is called for each item added');\n equal(removeCalls, 2, 'removed is called for each item removed');\n deepEqual(evenNumbers, [4,6,8,10], 'sanity check - dependent arrays are updated');\n});\n\ntest(\"multiple array computed properties on the same object can observe dependent arrays\", function() {\n var numbers = get(obj, 'numbers'),\n otherNumbers = get(obj, 'otherNumbers');\n\n deepEqual(get(obj, 'evenNumbers'), [2,4,6], \"precond - evenNumbers is initially correct\");\n deepEqual(get(obj, 'evenNumbersMultiDep'), [2, 4, 6, 8], \"precond - evenNumbersMultiDep is initially correct\");\n\n Ember.run(function() {\n numbers.pushObject(12);\n otherNumbers.pushObject(14);\n });\n\n deepEqual(get(obj, 'evenNumbers'), [2,4,6,12], \"evenNumbers is updated\");\n deepEqual(get(obj, 'evenNumbersMultiDep'), [2, 4, 6, 8, 12, 14], \"evenNumbersMultiDep is updated\");\n});\n\ntest(\"an error is thrown when a reduceComputed is defined without an initialValue property\", function() {\n var defineExploder = function() {\n Ember.Object.createWithMixins({\n collection: Ember.A(),\n exploder: Ember.reduceComputed('collection', {\n initialize: function(initialValue, changeMeta, instanceMeta) {},\n\n addedItem: function(accumulatedValue,item,changeMeta,instanceMeta) {\n return item;\n },\n\n removedItem: function(accumulatedValue,item,changeMeta,instanceMeta) {\n return item;\n }\n })\n });\n };\n\n throws(defineExploder, /declared\\ without\\ an\\ initial\\ value/, \"an error is thrown when the reduceComputed is defined without an initialValue\");\n});\n\ntest(\"dependent arrays with multiple item properties are not double-counted\", function() {\n var obj = Ember.Object.extend({\n items: Ember.A([{ foo: true }, { bar: false }, { bar: true }]),\n countFooOrBar: Ember.reduceComputed({\n initialValue: 0,\n addedItem: function (acc) {\n ++addCalls;\n return acc;\n },\n\n removedItem: function (acc) {\n ++removeCalls;\n return acc;\n }\n }).property('items.@each.foo', 'items.@each.bar', 'items')\n }).create();\n\n equal(0, addCalls, \"precond - no adds yet\");\n equal(0, removeCalls, \"precond - no removes yet\");\n\n get(obj, 'countFooOrBar');\n\n equal(3, addCalls, \"all items added once\");\n equal(0, removeCalls, \"no removes yet\");\n});\n\ntest(\"dependent arrays can use `replace` with an out of bounds index to add items\", function() {\n var dependentArray = Ember.A(),\n array;\n\n obj = Ember.Object.extend({\n dependentArray: dependentArray,\n computed: Ember.arrayComputed('dependentArray', {\n addedItem: function (acc, item, changeMeta) {\n acc.insertAt(changeMeta.index, item);\n return acc;\n },\n removedItem: function (acc) { return acc; }\n })\n }).create();\n\n array = get(obj, 'computed');\n\n deepEqual(array, [], \"precond - computed array is initially empty\");\n\n dependentArray.replace(100, 0, [1, 2]);\n\n deepEqual(array, [1, 2], \"index >= length treated as a push\");\n\n dependentArray.replace(-100, 0, [3, 4]);\n\n deepEqual(array, [3, 4, 1, 2], \"index < 0 treated as an unshift\");\n});\n\ntest(\"dependent arrays can use `replace` with a negative index to remove items indexed from the right\", function() {\n var dependentArray = Ember.A([1,2,3,4,5]),\n array;\n\n obj = Ember.Object.extend({\n dependentArray: dependentArray,\n computed: Ember.arrayComputed('dependentArray', {\n addedItem: function (acc, item) { return acc; },\n removedItem: function (acc, item) { acc.pushObject(item); return acc; }\n })\n }).create();\n\n array = get(obj, 'computed');\n\n deepEqual(array, [], \"precond - no items have been removed initially\");\n\n dependentArray.replace(-3, 2);\n\n deepEqual(array, [4,3], \"index < 0 used as a right index for removal\");\n});\n\ntest(\"dependent arrays that call `replace` with an out of bounds index to remove items is a no-op\", function() {\n var dependentArray = Ember.A([1, 2]),\n array;\n\n obj = Ember.Object.extend({\n dependentArray: dependentArray,\n computed: Ember.arrayComputed('dependentArray', {\n addedItem: function (acc, item, changeMeta) { return acc; },\n removedItem: function (acc) {\n ok(false, \"no items have been removed\");\n }\n })\n }).create();\n\n array = get(obj, 'computed');\n\n deepEqual(array, [], \"precond - computed array is initially empty\");\n\n dependentArray.replace(100, 2);\n});\n\ntest(\"dependent arrays that call `replace` with a too-large removedCount a) works and b) still right-truncates\", function() {\n var dependentArray = Ember.A([1, 2]),\n array;\n\n obj = Ember.Object.extend({\n dependentArray: dependentArray,\n computed: Ember.arrayComputed('dependentArray', {\n addedItem: function (acc, item) { return acc; },\n removedItem: function (acc, item) { acc.pushObject(item); return acc; }\n })\n }).create();\n\n array = get(obj, 'computed');\n\n deepEqual(array, [], \"precond - computed array is initially empty\");\n\n dependentArray.replace(1, 200);\n\n deepEqual(array, [2], \"array was correctly right-truncated\");\n});\n\ntest(\"removedItem is not erroneously called for dependent arrays during a recomputation\", function() {\n function addedItem(array, item, changeMeta) {\n array.insertAt(changeMeta.index, item);\n return array;\n }\n\n function removedItem(array, item, changeMeta) {\n ok(get(array, 'length') > changeMeta.index, \"removedItem not called with invalid index\");\n array.removeAt(changeMeta.index, 1);\n return array;\n }\n\n var dependentArray = Ember.A(),\n options = {\n addedItem: addedItem,\n removedItem: removedItem\n };\n\n obj = Ember.Object.extend({\n dependentArray: Ember.A([1, 2]),\n identity0: Ember.arrayComputed('dependentArray', options),\n identity1: Ember.arrayComputed('identity0', options)\n }).create();\n\n get(obj, 'identity1');\n Ember.run(function() {\n obj.notifyPropertyChange('dependentArray');\n });\n\n ok(true, \"removedItem not invoked with invalid index\");\n});\n\n\nif (Ember.FEATURES.isEnabled('reduceComputedSelf')) {\n module('Ember.arryComputed - self chains', {\n setup: function() {\n var a = Ember.Object.create({ name: 'a' }),\n b = Ember.Object.create({ name: 'b' });\n\n obj = Ember.ArrayProxy.createWithMixins({\n content: Ember.A([a, b]),\n names: Ember.arrayComputed('@this.@each.name', {\n addedItem: function (array, item, changeMeta, instanceMeta) {\n var mapped = get(item, 'name');\n array.insertAt(changeMeta.index, mapped);\n return array;\n },\n removedItem: function(array, item, changeMeta, instanceMeta) {\n array.removeAt(changeMeta.index, 1);\n return array;\n }\n })\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n });\n\n test(\"@this can be used to treat the object as the array itself\", function() {\n var names = get(obj, 'names');\n\n deepEqual(names, ['a', 'b'], \"precond - names is initially correct\");\n\n Ember.run(function() {\n obj.objectAt(1).set('name', 'c');\n });\n\n deepEqual(names, ['a', 'c'], \"@this can be used with item property observers\");\n\n Ember.run(function() {\n obj.pushObject({ name: 'd' });\n });\n\n deepEqual(names, ['a', 'c', 'd'], \"@this observes new items\");\n });\n\n}\nmodule('Ember.arrayComputed - changeMeta property observers', {\n setup: function() {\n callbackItems = [];\n Ember.run(function() {\n obj = Ember.Object.createWithMixins({\n items: Ember.A([Ember.Object.create({ n: 'zero' }), Ember.Object.create({ n: 'one' })]),\n itemsN: Ember.arrayComputed('items.@each.n', {\n addedItem: function (array, item, changeMeta, instanceMeta) {\n callbackItems.push('add:' + changeMeta.index + \":\" + get(changeMeta.item, 'n'));\n },\n removedItem: function (array, item, changeMeta, instanceMeta) {\n callbackItems.push('remove:' + changeMeta.index + \":\" + get(changeMeta.item, 'n'));\n }\n })\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n obj.destroy();\n });\n }\n});\n\ntest(\"changeMeta includes item and index\", function() {\n var expected, items, item;\n\n items = get(obj, 'items');\n\n // initial computation add0 add1\n Ember.run(function() {\n obj.get('itemsN');\n });\n\n // add2\n Ember.run(function() {\n items.pushObject(Ember.Object.create({ n: 'two' }));\n });\n\n // remove2\n Ember.run(function() {\n items.popObject();\n });\n\n // remove0 add0\n Ember.run(function() {\n set(get(items, 'firstObject'), 'n', \"zero'\");\n });\n\n expected = [\"add:0:zero\", \"add:1:one\", \"add:2:two\", \"remove:2:two\", \"remove:0:zero'\", \"add:0:zero'\"];\n deepEqual(callbackItems, expected, \"changeMeta includes items\");\n\n // [zero', one] -> [zero', one, five, six]\n // add2 add3\n Ember.run(function() {\n items.pushObject(Ember.Object.create({ n: 'five' }));\n items.pushObject(Ember.Object.create({ n: 'six' }));\n });\n\n // remove0 add0\n Ember.run(function() {\n items.objectAt(0).set('n', \"zero''\");\n });\n\n expected = expected.concat(['add:2:five', 'add:3:six', \"remove:0:zero''\", \"add:0:zero''\"]);\n deepEqual(callbackItems, expected, \"changeMeta includes items\");\n\n // [zero'', one, five, six] -> [zero'', five, six]\n // remove1\n Ember.run(function() {\n item = items.objectAt(1);\n items.removeAt(1, 1);\n });\n\n Ember.run(function() {\n // observer should have been removed from the deleted item\n item.set('n', 'ten thousand');\n });\n\n // [zero'', five, six] -> [zero'', five, seven]\n // remove2 add2\n Ember.run(function() {\n items.objectAt(2).set('n', \"seven\");\n });\n\n // observer should have been added to the new item\n expected = expected.concat(['remove:1:one', 'remove:2:seven', 'add:2:seven']);\n deepEqual(callbackItems, expected, \"changeMeta includes items\");\n\n // reset (does not call remove)\n Ember.run(function() {\n item = items.objectAt(1);\n set(obj, 'items', Ember.A([]));\n });\n\n Ember.run(function() {\n // observers should have been removed from the items in the old array\n set(item, 'n', 'eleven thousand');\n });\n\n deepEqual(callbackItems, expected, \"items removed from the array had observers removed\");\n});\n\ntest(\"when initialValue is undefined, everything works as advertised\", function() {\n var chars = Ember.Object.createWithMixins({\n letters: Ember.A(),\n firstUpper: Ember.reduceComputed('letters', {\n initialValue: undefined,\n\n initialize: function(initialValue, changeMeta, instanceMeta) {\n instanceMeta.matchingItems = Ember.A();\n instanceMeta.subArray = new Ember.SubArray();\n instanceMeta.firstMatch = function() {\n return Ember.getWithDefault(instanceMeta.matchingItems, 'firstObject', initialValue);\n };\n },\n\n addedItem: function(accumulatedValue,item,changeMeta,instanceMeta) {\n var filterIndex;\n filterIndex = instanceMeta.subArray.addItem(changeMeta.index, item.toUpperCase() === item);\n if (filterIndex > -1) {\n instanceMeta.matchingItems.insertAt(filterIndex, item);\n }\n return instanceMeta.firstMatch();\n },\n\n removedItem: function(accumulatedValue,item,changeMeta,instanceMeta) {\n var filterIndex = instanceMeta.subArray.removeItem(changeMeta.index);\n if (filterIndex > -1) {\n instanceMeta.matchingItems.removeAt(filterIndex);\n }\n return instanceMeta.firstMatch();\n }\n })\n });\n equal(get(chars, 'firstUpper'), undefined, \"initialValue is undefined\");\n\n get(chars, 'letters').pushObjects(['a', 'b', 'c']);\n\n equal(get(chars, 'firstUpper'), undefined, \"result is undefined when no matches are present\");\n\n get(chars, 'letters').pushObjects(['A', 'B', 'C']);\n\n equal(get(chars, 'firstUpper'), 'A', \"result is the first match when matching objects are present\");\n\n get(chars, 'letters').removeAt(3);\n\n equal(get(chars, 'firstUpper'), 'B', \"result is the next match when the first matching object is removed\");\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/computed/reduce_computed_test");minispade.register('ember-runtime/~tests/controllers/array_controller_test', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nmodule(\"ember-runtime/controllers/array_controller_test\");\n\nEmber.MutableArrayTests.extend({\n\n name: 'Ember.ArrayController',\n\n newObject: function(ary) {\n var ret = ary ? ary.slice() : this.newFixture(3);\n return Ember.ArrayController.create({\n content: Ember.A(ret)\n });\n },\n\n mutate: function(obj) {\n obj.pushObject(Ember.get(obj, 'length')+1);\n },\n\n toArray: function(obj) {\n return obj.toArray ? obj.toArray() : obj.slice();\n }\n}).run();\n\ntest(\"defaults it's `content` to an empty array\", function () {\n var Controller = Ember.ArrayController.extend();\n deepEqual(Controller.create().get(\"content\"), [], \"`ArrayController` defaults it's content to an empty array\");\n equal(Controller.create().get('firstObject'), undefined, 'can fetch firstObject');\n equal(Controller.create().get('lastObject'), undefined, 'can fetch lastObject');\n});\n\n\ntest(\"Ember.ArrayController length property works even if content was not set initially\", function() {\n var controller = Ember.ArrayController.create();\n controller.pushObject('item');\n equal(controller.get('length'), 1);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/controllers/array_controller_test");minispade.register('ember-runtime/~tests/controllers/controller_test', "(function() {module('Ember.Controller event handling');\n\ntest(\"Action can be handled by a function on actions object\", function() {\n expect(1);\n var TestController = Ember.Controller.extend({\n actions: {\n poke: function() {\n ok(true, 'poked');\n }\n }\n });\n var controller = TestController.create({});\n controller.send(\"poke\");\n});\n\n// TODO: Can we support this?\n// test(\"Actions handlers can be configured to use another name\", function() {\n// expect(1);\n// var TestController = Ember.Controller.extend({\n// actionsProperty: 'actionHandlers',\n// actionHandlers: {\n// poke: function() {\n// ok(true, 'poked');\n// }\n// }\n// });\n// var controller = TestController.create({});\n// controller.send(\"poke\");\n// });\n\ntest(\"When `_actions` is provided, `actions` is left alone\", function() {\n expect(2);\n var TestController = Ember.Controller.extend({\n actions: ['foo', 'bar'],\n _actions: {\n poke: function() {\n ok(true, 'poked');\n }\n }\n });\n var controller = TestController.create({});\n controller.send(\"poke\");\n equal('foo', controller.get(\"actions\")[0], 'actions property is not untouched');\n});\n\ntest(\"Actions object doesn't shadow a proxied object's 'actions' property\", function() {\n var TestController = Ember.ObjectController.extend({\n content: {\n actions: 'foo'\n },\n actions: {\n poke: function() {\n console.log('ouch');\n }\n }\n });\n var controller = TestController.create({});\n equal(controller.get(\"actions\"), 'foo', \"doesn't shadow the content's actions property\");\n});\n\ntest(\"A handled action can be bubbled to the target for continued processing\", function() {\n expect(2);\n var TestController = Ember.Controller.extend({\n actions: {\n poke: function() {\n ok(true, 'poked 1');\n return true;\n }\n }\n });\n\n var controller = TestController.create({\n target: Ember.Controller.extend({\n actions: {\n poke: function() {\n ok(true, 'poked 2');\n }\n }\n }).create()\n });\n controller.send(\"poke\");\n});\n\ntest(\"Action can be handled by a superclass' actions object\", function() {\n expect(4);\n\n var SuperController = Ember.Controller.extend({\n actions: {\n foo: function() {\n ok(true, 'foo');\n },\n bar: function(msg) {\n equal(msg, \"HELLO\");\n }\n }\n });\n\n var BarControllerMixin = Ember.Mixin.create({\n actions: {\n bar: function(msg) {\n equal(msg, \"HELLO\");\n this._super(msg);\n }\n }\n });\n\n var IndexController = SuperController.extend(BarControllerMixin, {\n actions: {\n baz: function() {\n ok(true, 'baz');\n }\n }\n });\n\n var controller = IndexController.create({});\n controller.send(\"foo\");\n controller.send(\"bar\", \"HELLO\");\n controller.send(\"baz\");\n});\n\nmodule('Ember.Controller deprecations',{\n setup: function() {\n Ember.TESTING_DEPRECATION = true;\n },\n teardown: function() {\n Ember.TESTING_DEPRECATION = false;\n }\n});\n\ntest(\"Action can be handled by method directly on controller (DEPRECATED)\", function() {\n expect(1);\n var TestController = Ember.Controller.extend({\n poke: function() {\n ok(true, 'poked');\n }\n });\n var controller = TestController.create({});\n controller.send(\"poke\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/controllers/controller_test");minispade.register('ember-runtime/~tests/controllers/item_controller_class_test', "(function() {var lannisters, arrayController, controllerClass, otherControllerClass, container, itemControllerCount,\n tywin, jaime, cersei, tyrion,\n get = Ember.get;\n\nmodule(\"Ember.ArrayController - itemController\", {\n setup: function() {\n container = new Ember.Container();\n\n tywin = Ember.Object.create({ name: 'Tywin' });\n jaime = Ember.Object.create({ name: 'Jaime' });\n cersei = Ember.Object.create({ name: 'Cersei' });\n tyrion = Ember.Object.create({ name: 'Tyrion' });\n lannisters = Ember.A([ tywin, jaime, cersei ]);\n\n itemControllerCount = 0;\n controllerClass = Ember.ObjectController.extend({\n init: function() {\n ++itemControllerCount;\n this._super();\n },\n\n toString: function() {\n return \"itemController for \" + this.get('name');\n }\n });\n\n otherControllerClass = Ember.ObjectController.extend({\n toString: function() {\n return \"otherItemController for \" + this.get('name');\n }\n });\n\n container.register(\"controller:Item\", controllerClass);\n container.register(\"controller:OtherItem\", otherControllerClass);\n },\n teardown: function() {\n Ember.run(function() {\n container.destroy();\n });\n }\n});\n\nfunction createUnwrappedArrayController() {\n arrayController = Ember.ArrayController.create({\n container: container,\n content: lannisters\n });\n}\n\nfunction createArrayController() {\n arrayController = Ember.ArrayController.create({\n container: container,\n itemController: 'Item',\n content: lannisters\n });\n}\n\nfunction createDynamicArrayController() {\n arrayController = Ember.ArrayController.create({\n container: container,\n lookupItemController: function(object) {\n if (\"Tywin\" === object.get(\"name\")) {\n return \"Item\";\n } else {\n return \"OtherItem\";\n }\n },\n content: lannisters\n });\n}\n\ntest(\"when no `itemController` is set, `objectAtContent` returns objects directly\", function() {\n createUnwrappedArrayController();\n\n strictEqual(arrayController.objectAtContent(1), jaime, \"No controller is returned when itemController is not set\");\n});\n\ntest(\"when `itemController` is set, `objectAtContent` returns an instance of the controller\", function() {\n createArrayController();\n\n var jaimeController = arrayController.objectAtContent(1);\n\n ok(controllerClass.detectInstance(jaimeController), \"A controller is returned when itemController is set\");\n});\n\n\ntest(\"when `idx` is out of range, `objectAtContent` does not create a controller\", function() {\n controllerClass.reopen({\n init: function() {\n ok(false, \"Controllers should not be created when `idx` is out of range\");\n }\n });\n\n createArrayController();\n strictEqual(arrayController.objectAtContent(50), undefined, \"no controllers are created for out of range indexes\");\n});\n\ntest(\"when the underlying object is null, a controller is still returned\", function() {\n createArrayController();\n arrayController.unshiftObject(null);\n var firstController = arrayController.objectAtContent(0);\n ok(controllerClass.detectInstance(firstController), \"A controller is still created for null objects\");\n});\n\ntest(\"the target of item controllers is the parent controller\", function() {\n createArrayController();\n\n var jaimeController = arrayController.objectAtContent(1);\n\n equal(jaimeController.get('target'), arrayController, \"Item controllers' targets are their parent controller\");\n});\n\ntest(\"the parentController property of item controllers is set to the parent controller\", function() {\n createArrayController();\n\n var jaimeController = arrayController.objectAtContent(1);\n\n equal(jaimeController.get('parentController'), arrayController, \"Item controllers' targets are their parent controller\");\n});\n\ntest(\"when the underlying object has not changed, `objectAtContent` always returns the same instance\", function() {\n createArrayController();\n\n strictEqual(arrayController.objectAtContent(1), arrayController.objectAtContent(1), \"Controller instances are reused\");\n});\n\ntest(\"when the index changes, `objectAtContent` still returns the same instance\", function() {\n createArrayController();\n var jaimeController = arrayController.objectAtContent(1);\n arrayController.unshiftObject(tyrion);\n\n strictEqual(arrayController.objectAtContent(2), jaimeController, \"Controller instances are reused\");\n});\n\ntest(\"when the underlying array changes, old subcontainers are destroyed\", function() {\n createArrayController();\n // cause some controllers to be instantiated\n arrayController.objectAtContent(1);\n arrayController.objectAtContent(2);\n\n // Not a public API; just checking for cleanup\n var subControllers = get(arrayController, '_subControllers'),\n jaimeController = subControllers[1],\n cerseiController = subControllers[2];\n\n equal(!!jaimeController.isDestroying, false, \"precond - nobody is destroyed yet\");\n equal(!!cerseiController.isDestroying, false, \"precond - nobody is destroyed yet\");\n\n Ember.run(function() {\n arrayController.set('content', Ember.A());\n });\n\n equal(!!jaimeController.isDestroying, true, \"old subcontainers are destroyed\");\n equal(!!cerseiController.isDestroying, true, \"old subcontainers are destroyed\");\n});\n\n\ntest(\"item controllers are created lazily\", function() {\n createArrayController();\n\n equal(itemControllerCount, 0, \"precond - no item controllers yet\");\n\n arrayController.objectAtContent(1);\n\n equal(itemControllerCount, 1, \"item controllers are created lazily\");\n});\n\ntest(\"when items are removed from the arrayController, their respective subcontainers are destroyed\", function() {\n createArrayController();\n var jaimeController = arrayController.objectAtContent(1),\n cerseiController = arrayController.objectAtContent(2),\n subControllers = get(arrayController, '_subControllers');\n\n equal(!!jaimeController.isDestroyed, false, \"precond - nobody is destroyed yet\");\n equal(!!cerseiController.isDestroyed, false, \"precond - nobody is destroyed yet\");\n\n Ember.run(function() {\n arrayController.removeObject(cerseiController);\n });\n\n equal(!!cerseiController.isDestroying, true, \"Removed objects' containers are cleaned up\");\n equal(!!jaimeController.isDestroying, false, \"Retained objects' containers are not cleaned up\");\n});\n\ntest(\"one cannot remove wrapped content directly when specifying `itemController`\", function() {\n createArrayController();\n var jaimeController = arrayController.objectAtContent(1),\n cerseiController = arrayController.objectAtContent(2);\n\n equal(arrayController.get('length'), 3, \"precondition - array is in initial state\");\n arrayController.removeObject(cersei);\n\n equal(arrayController.get('length'), 3, \"cannot remove wrapped objects directly\");\n\n Ember.run(function() {\n arrayController.removeObject(cerseiController);\n });\n equal(arrayController.get('length'), 2, \"can remove wrapper objects\");\n});\n\ntest(\"when items are removed from the underlying array, their respective subcontainers are destroyed\", function() {\n createArrayController();\n var jaimeController = arrayController.objectAtContent(1),\n cerseiController = arrayController.objectAtContent(2),\n subContainers = get(arrayController, 'subContainers');\n\n equal(!!jaimeController.isDestroying, false, \"precond - nobody is destroyed yet\");\n equal(!!cerseiController.isDestroying, false, \"precond - nobody is destroyed yet\");\n\n Ember.run(function() {\n lannisters.removeObject(cersei); // if only it were that easy\n });\n\n equal(!!jaimeController.isDestroyed, false, \"Retained objects' containers are not cleaned up\");\n equal(!!cerseiController.isDestroyed, true, \"Removed objects' containers are cleaned up\");\n});\n\ntest(\"`itemController` can be dynamic by overwriting `lookupItemController`\", function() {\n createDynamicArrayController();\n\n var tywinController = arrayController.objectAtContent(0),\n jaimeController = arrayController.objectAtContent(1);\n\n ok(controllerClass.detectInstance(tywinController), \"lookupItemController can return different classes for different objects\");\n ok(otherControllerClass.detectInstance(jaimeController), \"lookupItemController can return different classes for different objects\");\n});\n\ntest(\"when `idx` is out of range, `lookupItemController` is not called\", function() {\n arrayController = Ember.ArrayController.create({\n container: container,\n lookupItemController: function(object) {\n ok(false, \"`lookupItemController` should not be called when `idx` is out of range\");\n },\n content: lannisters\n });\n\n strictEqual(arrayController.objectAtContent(50), undefined, \"no controllers are created for indexes that are superior to the length\");\n strictEqual(arrayController.objectAtContent(-1), undefined, \"no controllers are created for indexes less than zero\");\n});\n\ntest(\"if `lookupItemController` returns a string, it must be resolvable by the container\", function() {\n arrayController = Ember.ArrayController.create({\n container: container,\n lookupItemController: function(object) {\n return \"NonExistant\";\n },\n content: lannisters\n });\n\n throws(function() {\n arrayController.objectAtContent(1);\n },\n /NonExistant/,\n \"`lookupItemController` must return either null or a valid controller name\");\n});\n\ntest(\"array observers can invoke `objectAt` without overwriting existing item controllers\", function() {\n createArrayController();\n\n var tywinController = arrayController.objectAtContent(0),\n arrayObserverCalled = false;\n\n arrayController.reopen({\n lannistersWillChange: Ember.K,\n lannistersDidChange: function(_, idx, removedAmt, addedAmt) {\n arrayObserverCalled = true;\n equal(this.objectAt(idx).get('name'), \"Tyrion\", \"Array observers get the right object via `objectAt`\");\n }\n });\n arrayController.addArrayObserver(arrayController, {\n willChange: 'lannistersWillChange',\n didChange: 'lannistersDidChange'\n });\n\n Ember.run(function() {\n lannisters.unshiftObject(tyrion);\n });\n\n equal(arrayObserverCalled, true, \"Array observers are called normally\");\n equal(tywinController.get('name'), \"Tywin\", \"Array observers calling `objectAt` does not overwrite existing controllers' content\");\n});\n\nif (Ember.FEATURES.isEnabled('reduceComputedSelf')) {\n module('Ember.ArrayController - itemController with arrayComputed', {\n setup: function() {\n container = new Ember.Container();\n\n cersei = Ember.Object.create({ name: 'Cersei' });\n jaime = Ember.Object.create({ name: 'Jaime' });\n lannisters = Ember.A([ jaime, cersei ]);\n\n controllerClass = Ember.ObjectController.extend({\n title: Ember.computed(function () {\n switch (get(this, 'name')) {\n case 'Jaime': return 'Kingsguard';\n case 'Cersei': return 'Queen';\n }\n }).property('name'),\n\n toString: function() {\n return \"itemController for \" + this.get('name');\n }\n });\n\n container.register(\"controller:Item\", controllerClass);\n },\n teardown: function() {\n Ember.run(function() {\n container.destroy();\n });\n }\n });\n\n test(\"item controllers can be used to provide properties for array computed macros\", function() {\n createArrayController();\n\n ok(Ember.compare(Ember.guidFor(cersei), Ember.guidFor(jaime)) < 0, \"precond - guid tiebreaker would fail test\");\n\n arrayController.reopen({\n sortProperties: Ember.A(['title']),\n sorted: Ember.computed.sort('@this', 'sortProperties')\n });\n\n deepEqual(arrayController.get('sorted').mapProperty('name'), ['Jaime', 'Cersei'], \"ArrayController items can be sorted on itemController properties\");\n });\n}\n\n})();\n//@ sourceURL=ember-runtime/~tests/controllers/item_controller_class_test");minispade.register('ember-runtime/~tests/controllers/object_controller_tests', "(function() {module(\"Ember.ObjectController\");\n\n\ntest(\"should be able to set the target property of an ObjectController\", function() {\n var controller = Ember.ObjectController.create();\n var target = {};\n\n controller.set('target', target);\n equal(controller.get('target'), target, \"able to set the target property\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/controllers/object_controller_tests");minispade.register('ember-runtime/~tests/core/compare_test', "(function() {/*globals module ok equals same test MyApp */\n\n// test parsing of query string\nvar v = [];\nmodule(\"Ember.compare()\", {\n setup: function() {\n // setup dummy data\n v[0] = null;\n v[1] = false;\n v[2] = true;\n v[3] = -12;\n v[4] = 3.5;\n v[5] = 'a string';\n v[6] = 'another string';\n v[7] = 'last string';\n v[8] = [1,2];\n v[9] = [1,2,3];\n v[10] = [1,3];\n v[11] = {a: 'hash'};\n v[12] = Ember.Object.create();\n v[13] = function (a) {return a;};\n v[14] = new Date('2012/01/01');\n v[15] = new Date('2012/06/06');\n }\n});\n\n\n// ..........................................................\n// TESTS\n//\n\ntest(\"ordering should work\", function() {\n for (var j=0; j < v.length; j++) {\n equal(Ember.compare(v[j],v[j]), 0, j +' should equal itself');\n for (var i=j+1; i < v.length; i++) {\n equal(Ember.compare(v[j],v[i]), -1, 'v[' + j + '] (' + Ember.typeOf(v[j]) + ') should be smaller than v[' + i + '] (' + Ember.typeOf(v[i]) + ')' );\n }\n\n }\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/core/compare_test");minispade.register('ember-runtime/~tests/core/copy_test', "(function() {module(\"Ember Copy Method\");\n\ntest(\"Ember.copy null\", function() {\n var obj = {field: null};\n equal(Ember.copy(obj, true).field, null, \"null should still be null\");\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/core/copy_test");minispade.register('ember-runtime/~tests/core/inspect_test', "(function() {module(\"Ember.inspect\");\n\nvar inspect = Ember.inspect;\n\ntest(\"strings\", function() {\n equal(inspect(\"foo\"), \"foo\");\n});\n\ntest(\"numbers\", function() {\n equal(inspect(2.6), \"2.6\");\n});\n\ntest(\"null\", function() {\n equal(inspect(null), \"null\");\n});\n\ntest(\"undefined\", function() {\n equal(inspect(undefined), \"undefined\");\n});\n\ntest(\"true\", function() {\n equal(inspect(true), \"true\");\n});\n\ntest(\"false\", function() {\n equal(inspect(false), \"false\");\n});\n\ntest(\"object\", function() {\n equal(inspect({}), \"{}\");\n equal(inspect({ foo: 'bar' }), \"{foo: bar}\");\n equal(inspect({ foo: Ember.K }), \"{foo: function() { ... }}\");\n});\n\ntest(\"array\", function() {\n equal(inspect([1,2,3]), \"[1,2,3]\");\n});\n\ntest(\"regexp\", function() {\n equal(inspect(/regexp/), \"/regexp/\");\n});\n\ntest(\"date\", function() {\n var inspected = inspect(new Date(\"Sat Apr 30 2011 13:24:11\"));\n ok(inspected.match(/Sat Apr 30/), \"The inspected date has its date\");\n ok(inspected.match(/2011/), \"The inspected date has its year\");\n ok(inspected.match(/13:24:11/), \"The inspected date has its time\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/core/inspect_test");minispade.register('ember-runtime/~tests/core/isEqual_test', "(function() {// ========================================================================\n// Ember.isEqual Tests\n// ========================================================================\n/*globals module test */\n\nmodule(\"isEqual\");\n\ntest(\"undefined and null\", function() {\n ok( Ember.isEqual(undefined, undefined), \"undefined is equal to undefined\" );\n ok( !Ember.isEqual(undefined, null), \"undefined is not equal to null\" );\n ok( Ember.isEqual(null, null), \"null is equal to null\" );\n ok( !Ember.isEqual(null, undefined), \"null is not equal to undefined\" );\n});\n\ntest(\"strings should be equal\",function() {\n\tok( !Ember.isEqual(\"Hello\", \"Hi\"), \"different Strings are unequal\" );\n\tok( Ember.isEqual(\"Hello\", \"Hello\"), \"same Strings are equal\" );\n});\n\ntest(\"numericals should be equal\",function() {\n ok( Ember.isEqual(24, 24), \"same numbers are equal\" );\n\tok( !Ember.isEqual(24, 21), \"different numbers are inequal\" );\n});\n\ntest(\"array should be equal\",function() {\n\t// NOTE: We don't test for array contents -- that would be too expensive.\n\tok( !Ember.isEqual( [1,2], [1,2] ), 'two array instances with the same values should not be equal' );\n\tok( !Ember.isEqual( [1,2], [1] ), 'two array instances with different values should not be equal' );\n});\n\ntest(\"first object implements isEqual should use it\", function() {\n ok(Ember.isEqual({ isEqual: function() { return true; } }, null), 'should return true always');\n\n var obj = { isEqual: function() { return false; } };\n equal(Ember.isEqual(obj, obj), false, 'should return false because isEqual returns false');\n});\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/core/isEqual_test");minispade.register('ember-runtime/~tests/core/is_array_test', "(function() {module(\"Ember Type Checking\");\n\ntest(\"Ember.isArray\" ,function() {\n var arrayProxy = Ember.ArrayProxy.create({ content: Ember.A() });\n\n equal(Ember.isArray(arrayProxy), true, \"[]\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/core/is_array_test");minispade.register('ember-runtime/~tests/core/is_empty_test', "(function() {module(\"Ember.isEmpty\");\n\ntest(\"Ember.isEmpty\", function() {\n var arrayProxy = Ember.ArrayProxy.create({ content: Ember.A() });\n\n equal(true, Ember.isEmpty(arrayProxy), \"for an ArrayProxy that has empty content\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/core/is_empty_test");minispade.register('ember-runtime/~tests/core/keys_test', "(function() {// ========================================================================\n// Ember.keys Tests\n// ========================================================================\n/*globals module test */\n\nmodule(\"Fetch Keys \");\n\ntest(\"should get a key array for a specified object\", function() {\n var object1 = {};\n\n object1.names = \"Rahul\";\n object1.age = \"23\";\n object1.place = \"Mangalore\";\n\n var object2 = Ember.keys(object1);\n\n deepEqual(object2, ['names','age','place']);\n});\n\ntest(\"should get a key array for a specified Ember.Object\", function() {\n var object1 = Ember.Object.create({\n names: \"Rahul\",\n age: \"23\",\n place: \"Mangalore\"\n });\n\n var object2 = Ember.keys(object1);\n\n deepEqual(object2, ['names','age','place']);\n});\n\n// This test is for IE8.\ntest(\"should get a key array for property that is named the same as prototype property\", function() {\n var object1 = {\n toString: function() {}\n };\n\n var object2 = Ember.keys(object1);\n\n deepEqual(object2, ['toString']);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/core/keys_test");minispade.register('ember-runtime/~tests/core/type_test', "(function() {module(\"Ember Type Checking\");\n\ntest(\"Ember.typeOf\", function() {\n\tvar a = null,\n arr = [1,2,3],\n obj = {},\n object = Ember.Object.create({ method: function() {} });\n\n equal(Ember.typeOf(undefined), 'undefined', \"item of type undefined\");\n equal(Ember.typeOf(a), 'null', \"item of type null\");\n\tequal(Ember.typeOf(arr), 'array', \"item of type array\");\n\tequal(Ember.typeOf(obj), 'object', \"item of type object\");\n\tequal(Ember.typeOf(object), 'instance', \"item of type instance\");\n\tequal(Ember.typeOf(object.method), 'function', \"item of type function\") ;\n\tequal(Ember.typeOf(Ember.Object), 'class', \"item of type class\");\n equal(Ember.typeOf(new Error()), 'error', \"item of type error\");\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/core/type_test");minispade.register('ember-runtime/~tests/ext/function_test', "(function() {/*globals testBoth */\nminispade.require('ember-runtime/~tests/props_helper');\n\nmodule('Function.prototype.observes() helper');\n\ntestBoth('global observer helper takes multiple params', function(get, set) {\n\n if (Ember.EXTEND_PROTOTYPES === false) {\n ok('Function.prototype helper disabled');\n return ;\n }\n\n var MyMixin = Ember.Mixin.create({\n\n count: 0,\n\n foo: function() {\n set(this, 'count', get(this, 'count')+1);\n }.observes('bar', 'baz')\n\n });\n\n var obj = Ember.mixin({}, MyMixin);\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj, 'bar', \"BAZ\");\n set(obj, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 2, 'should invoke observer after change');\n});\n\nmodule('Function.prototype.on() helper');\n\ntestBoth('sets up an event listener, and can trigger the function on multiple events', function(get, set) {\n\n if (Ember.EXTEND_PROTOTYPES === false) {\n ok('Function.prototype helper disabled');\n return ;\n }\n\n var MyMixin = Ember.Mixin.create({\n\n count: 0,\n\n foo: function() {\n set(this, 'count', get(this, 'count')+1);\n }.on('bar', 'baz')\n\n });\n\n var obj = Ember.mixin({}, Ember.Evented, MyMixin);\n equal(get(obj, 'count'), 0, 'should not invoke listener immediately');\n\n obj.trigger('bar');\n obj.trigger('baz');\n equal(get(obj, 'count'), 2, 'should invoke listeners when events trigger');\n});\n\ntestBoth('can be chained with observes', function(get, set) {\n\n if (Ember.EXTEND_PROTOTYPES === false) {\n ok('Function.prototype helper disabled');\n return ;\n }\n\n var MyMixin = Ember.Mixin.create({\n\n count: 0,\n bay: 'bay',\n foo: function() {\n set(this, 'count', get(this, 'count')+1);\n }.observes('bay').on('bar')\n });\n\n var obj = Ember.mixin({}, Ember.Evented, MyMixin);\n equal(get(obj, 'count'), 0, 'should not invoke listener immediately');\n\n set(obj, 'bay', 'BAY');\n obj.trigger('bar');\n equal(get(obj, 'count'), 2, 'should invoke observer and listener');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/ext/function_test");minispade.register('ember-runtime/~tests/ext/mixin_test', "(function() {module('system/mixin/binding_test');\n\ntest('Defining a property ending in Binding should setup binding when applied', function() {\n\n var MyMixin = Ember.Mixin.create({\n fooBinding: 'bar.baz'\n });\n\n var obj = { bar: { baz: 'BIFF' } };\n\n Ember.run(function() {\n MyMixin.apply(obj);\n });\n\n ok(Ember.get(obj, 'fooBinding') instanceof Ember.Binding, 'should be a binding object');\n equal(Ember.get(obj, 'foo'), 'BIFF', 'binding should be created and synced');\n\n});\n\ntest('Defining a property ending in Binding should apply to prototype children', function() {\n var MyMixin, obj, obj2;\n\n Ember.run(function() {\n MyMixin = Ember.Mixin.create({\n fooBinding: 'bar.baz'\n });\n });\n\n obj = { bar: { baz: 'BIFF' } };\n\n Ember.run(function() {\n MyMixin.apply(obj);\n });\n\n\n obj2 = Ember.create(obj);\n Ember.run(function() {\n Ember.set(Ember.get(obj2, 'bar'), 'baz', 'BARG');\n });\n\n\n ok(Ember.get(obj2, 'fooBinding') instanceof Ember.Binding, 'should be a binding object');\n equal(Ember.get(obj2, 'foo'), 'BARG', 'binding should be created and synced');\n\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/ext/mixin_test");minispade.register('ember-runtime/~tests/legacy_1x/mixins/observable/chained_test', "(function() {/*\n NOTE: This test is adapted from the 1.x series of unit tests. The tests\n are the same except for places where we intend to break the API we instead\n validate that we warn the developer appropriately.\n\n CHANGES FROM 1.6:\n\n * changed obj.set() and obj.get() to Ember.set() and Ember.get()\n * changed obj.addObserver() to Ember.addObserver()\n*/\n\nvar get = Ember.get, set = Ember.set;\n\nmodule(\"Ember.Observable - Observing with @each\");\n\ntest(\"chained observers on enumerable properties are triggered when the observed property of any item changes\", function() {\n var family = Ember.Object.create({ momma: null });\n var momma = Ember.Object.create({ children: [] });\n\n var child1 = Ember.Object.create({ name: \"Bartholomew\" });\n var child2 = Ember.Object.create({ name: \"Agnes\" });\n var child3 = Ember.Object.create({ name: \"Dan\" });\n var child4 = Ember.Object.create({ name: \"Nancy\" });\n\n set(family, 'momma', momma);\n set(momma, 'children', Ember.A([child1, child2, child3]));\n\n var observerFiredCount = 0;\n Ember.addObserver(family, 'momma.children.@each.name', this, function() {\n observerFiredCount++;\n });\n\n observerFiredCount = 0;\n Ember.run(function() { get(momma, 'children').setEach('name', 'Juan'); });\n equal(observerFiredCount, 3, \"observer fired after changing child names\");\n\n observerFiredCount = 0;\n Ember.run(function() { get(momma, 'children').pushObject(child4); });\n equal(observerFiredCount, 1, \"observer fired after adding a new item\");\n\n observerFiredCount = 0;\n Ember.run(function() { set(child4, 'name', \"Herbert\"); });\n equal(observerFiredCount, 1, \"observer fired after changing property on new object\");\n\n set(momma, 'children', []);\n\n observerFiredCount = 0;\n Ember.run(function() { set(child1, 'name', \"Hanna\"); });\n equal(observerFiredCount, 0, \"observer did not fire after removing changing property on a removed object\");\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/legacy_1x/mixins/observable/chained_test");minispade.register('ember-runtime/~tests/legacy_1x/mixins/observable/observable_test', "(function() {/*global Namespace:true DepObj:true*/\n\nvar get = Ember.get, set = Ember.set;\nvar forEach = Ember.EnumerableUtils.forEach;\n\n/*\n NOTE: This test is adapted from the 1.x series of unit tests. The tests\n are the same except for places where we intend to break the API we instead\n validate that we warn the developer appropriately.\n\n CHANGES FROM 1.6:\n\n * Added ObservableObject which applies the Ember.Observable mixin.\n * Changed reference to Ember.T_FUNCTION to 'function'\n * Changed all references to sc_super to this._super()\n * Changed Ember.objectForPropertyPath() to Ember.getPath()\n * Removed allPropertiesDidChange test - no longer supported\n * Changed test that uses 'ObjectE' as path to 'objectE' to reflect new\n rule on using capital letters for property paths.\n * Removed test passing context to addObserver. context param is no longer\n supported.\n * Changed calls to Ember.Binding.flushPendingChanges() -> Ember.run.sync()\n * removed test in observer around line 862 that expected key/value to be\n the last item in the chained path. Should be root and chained path\n\n*/\n\n// ========================================================================\n// Ember.Observable Tests\n// ========================================================================\n\nvar object, ObjectC, ObjectD, objectA, objectB ;\n\nvar ObservableObject = Ember.Object.extend(Ember.Observable);\nvar originalLookup = Ember.lookup, lookup;\n\n// ..........................................................\n// GET()\n//\n\nmodule(\"object.get()\", {\n\n setup: function() {\n object = ObservableObject.createWithMixins(Ember.Observable, {\n\n normal: 'value',\n numberVal: 24,\n toggleVal: true,\n\n computed: Ember.computed(function() { return 'value'; }).volatile(),\n\n method: function() { return \"value\"; },\n\n nullProperty: null,\n\n unknownProperty: function(key, value) {\n this.lastUnknownProperty = key ;\n return \"unknown\" ;\n }\n\n });\n }\n\n});\n\ntest(\"should get normal properties\", function() {\n equal(object.get('normal'), 'value') ;\n});\n\ntest(\"should call computed properties and return their result\", function() {\n equal(object.get(\"computed\"), \"value\") ;\n});\n\ntest(\"should return the function for a non-computed property\", function() {\n var value = object.get(\"method\") ;\n equal(Ember.typeOf(value), 'function') ;\n});\n\ntest(\"should return null when property value is null\", function() {\n equal(object.get(\"nullProperty\"), null) ;\n});\n\ntest(\"should call unknownProperty when value is undefined\", function() {\n equal(object.get(\"unknown\"), \"unknown\") ;\n equal(object.lastUnknownProperty, \"unknown\") ;\n});\n\n// ..........................................................\n// Ember.GET()\n//\nmodule(\"Ember.get()\", {\n setup: function() {\n objectA = ObservableObject.createWithMixins({\n\n normal: 'value',\n numberVal: 24,\n toggleVal: true,\n\n computed: Ember.computed(function() { return 'value'; }).volatile(),\n\n method: function() { return \"value\"; },\n\n nullProperty: null,\n\n unknownProperty: function(key, value) {\n this.lastUnknownProperty = key ;\n return \"unknown\" ;\n }\n\n });\n\n objectB = {\n normal: 'value',\n\n nullProperty: null\n };\n }\n});\n\ntest(\"should get normal properties on Ember.Observable\", function() {\n equal(Ember.get(objectA, 'normal'), 'value') ;\n});\n\ntest(\"should call computed properties on Ember.Observable and return their result\", function() {\n equal(Ember.get(objectA, \"computed\"), \"value\") ;\n});\n\ntest(\"should return the function for a non-computed property on Ember.Observable\", function() {\n var value = Ember.get(objectA, \"method\") ;\n equal(Ember.typeOf(value), 'function') ;\n});\n\ntest(\"should return null when property value is null on Ember.Observable\", function() {\n equal(Ember.get(objectA, \"nullProperty\"), null) ;\n});\n\ntest(\"should call unknownProperty when value is undefined on Ember.Observable\", function() {\n equal(Ember.get(object, \"unknown\"), \"unknown\") ;\n equal(object.lastUnknownProperty, \"unknown\") ;\n});\n\ntest(\"should get normal properties on standard objects\", function() {\n equal(Ember.get(objectB, 'normal'), 'value');\n});\n\ntest(\"should return null when property is null on standard objects\", function() {\n equal(Ember.get(objectB, 'nullProperty'), null);\n});\n\n/*\ntest(\"raise if the provided object is null\", function() {\n raises(function() {\n Ember.get(null, 'key');\n });\n});\n*/\n\ntest(\"raise if the provided object is undefined\", function() {\n expectAssertion(function() {\n Ember.get(undefined, 'key');\n }, /Cannot call get with 'key' on an undefined object/i);\n});\n\ntest(\"should work when object is Ember (used in Ember.get)\", function() {\n equal(Ember.get('Ember.RunLoop'), Ember.RunLoop, 'Ember.get');\n equal(Ember.get(Ember, 'RunLoop'), Ember.RunLoop, 'Ember.get(Ember, RunLoop)');\n});\n\nmodule(\"Ember.get() with paths\", {\n setup: function() {\n lookup = Ember.lookup = {};\n },\n\n teardown: function() {\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"should return a property at a given path relative to the lookup\", function() {\n lookup.Foo = ObservableObject.create({\n Bar: ObservableObject.createWithMixins({\n Baz: Ember.computed(function() { return \"blargh\"; }).volatile()\n })\n });\n\n equal(Ember.get('Foo.Bar.Baz'), \"blargh\");\n});\n\ntest(\"should return a property at a given path relative to the passed object\", function() {\n var foo = ObservableObject.create({\n bar: ObservableObject.createWithMixins({\n baz: Ember.computed(function() { return \"blargh\"; }).volatile()\n })\n });\n\n equal(Ember.get(foo, 'bar.baz'), \"blargh\");\n});\n\ntest(\"should return a property at a given path relative to the lookup - JavaScript hash\", function() {\n lookup.Foo = {\n Bar: {\n Baz: \"blargh\"\n }\n };\n\n equal(Ember.get('Foo.Bar.Baz'), \"blargh\");\n});\n\ntest(\"should return a property at a given path relative to the passed object - JavaScript hash\", function() {\n var foo = {\n bar: {\n baz: \"blargh\"\n }\n };\n\n equal(Ember.get(foo, 'bar.baz'), \"blargh\");\n});\n\n// ..........................................................\n// SET()\n//\n\nmodule(\"object.set()\", {\n\n setup: function() {\n object = ObservableObject.createWithMixins({\n\n // normal property\n normal: 'value',\n\n // computed property\n _computed: \"computed\",\n computed: Ember.computed(function(key, value) {\n if (value !== undefined) {\n this._computed = value ;\n }\n return this._computed ;\n }).volatile(),\n\n // method, but not a property\n _method: \"method\",\n method: function(key, value) {\n if (value !== undefined) {\n this._method = value ;\n }\n return this._method ;\n },\n\n // null property\n nullProperty: null,\n\n // unknown property\n _unknown: 'unknown',\n unknownProperty: function(key) {\n return this._unknown ;\n },\n\n setUnknownProperty: function(key, value) {\n this._unknown = value ;\n return this._unknown ;\n }\n });\n }\n\n});\n\ntest(\"should change normal properties and return this\", function() {\n var ret = object.set(\"normal\", \"changed\") ;\n equal(object.normal, \"changed\") ;\n equal(ret, object) ;\n});\n\ntest(\"should call computed properties passing value and return this\", function() {\n var ret = object.set(\"computed\", \"changed\") ;\n equal(object._computed, \"changed\") ;\n equal(ret, object) ;\n});\n\ntest(\"should change normal properties when passing undefined\", function() {\n var ret = object.set('normal', undefined);\n equal(object.normal, undefined);\n equal(ret, object);\n});\n\ntest(\"should replace the function for a non-computed property and return this\", function() {\n var ret = object.set(\"method\", \"changed\") ;\n equal(object._method, \"method\") ; // make sure this was NOT run\n ok(Ember.typeOf(object.method) !== 'function') ;\n equal(ret, object) ;\n});\n\ntest(\"should replace prover when property value is null\", function() {\n var ret = object.set(\"nullProperty\", \"changed\") ;\n equal(object.nullProperty, \"changed\") ;\n equal(ret, object) ;\n});\n\ntest(\"should call unknownProperty with value when property is undefined\", function() {\n var ret = object.set(\"unknown\", \"changed\") ;\n equal(object._unknown, \"changed\") ;\n equal(ret, object) ;\n});\n\n// ..........................................................\n// COMPUTED PROPERTIES\n//\n\nmodule(\"Computed properties\", {\n setup: function() {\n lookup = Ember.lookup = {};\n\n object = ObservableObject.createWithMixins({\n\n // REGULAR\n\n computedCalls: [],\n computed: Ember.computed(function(key, value) {\n this.computedCalls.push(value);\n return 'computed';\n }).volatile(),\n\n computedCachedCalls: [],\n computedCached: Ember.computed(function(key, value) {\n this.computedCachedCalls.push(value);\n return 'computedCached';\n }),\n\n\n // DEPENDENT KEYS\n\n changer: 'foo',\n\n dependentCalls: [],\n dependent: Ember.computed(function(key, value) {\n this.dependentCalls.push(value);\n return 'dependent';\n }).property('changer').volatile(),\n\n dependentFrontCalls: [],\n dependentFront: Ember.computed('changer', function(key, value) {\n this.dependentFrontCalls.push(value);\n return 'dependentFront';\n }).volatile(),\n\n dependentCachedCalls: [],\n dependentCached: Ember.computed(function(key, value) {\n this.dependentCachedCalls.push(value);\n return 'dependentCached';\n }).property('changer'),\n\n // everytime it is recomputed, increments call\n incCallCount: 0,\n inc: Ember.computed(function() {\n return this.incCallCount++;\n }).property('changer'),\n\n // depends on cached property which depends on another property...\n nestedIncCallCount: 0,\n nestedInc: Ember.computed(function(key, value) {\n Ember.get(this, 'inc');\n return this.nestedIncCallCount++;\n }).property('inc'),\n\n // two computed properties that depend on a third property\n state: 'on',\n isOn: Ember.computed(function(key, value) {\n if (value !== undefined) this.set('state', 'on');\n return this.get('state') === 'on';\n }).property('state').volatile(),\n\n isOff: Ember.computed(function(key, value) {\n if (value !== undefined) this.set('state', 'off');\n return this.get('state') === 'off';\n }).property('state').volatile()\n\n }) ;\n },\n teardown: function() {\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"getting values should call function return value\", function() {\n\n // get each property twice. Verify return.\n var keys = Ember.String.w('computed computedCached dependent dependentFront dependentCached');\n\n forEach(keys, function(key) {\n equal(object.get(key), key, Ember.String.fmt('Try #1: object.get(%@) should run function', [key]));\n equal(object.get(key), key, Ember.String.fmt('Try #2: object.get(%@) should run function', [key]));\n });\n\n // verify each call count. cached should only be called once\n forEach(Ember.String.w('computedCalls dependentFrontCalls dependentCalls'), function(key) {\n equal(object[key].length, 2, Ember.String.fmt('non-cached property %@ should be called 2x', [key]));\n });\n\n forEach(Ember.String.w('computedCachedCalls dependentCachedCalls'), function(key) {\n equal(object[key].length, 1, Ember.String.fmt('non-cached property %@ should be called 1x', [key]));\n });\n\n});\n\ntest(\"setting values should call function return value\", function() {\n\n // get each property twice. Verify return.\n var keys = Ember.String.w('computed dependent dependentFront computedCached dependentCached');\n var values = Ember.String.w('value1 value2');\n\n forEach(keys, function(key) {\n\n equal(object.set(key, values[0]), object, Ember.String.fmt('Try #1: object.set(%@, %@) should run function', [key, values[0]]));\n\n equal(object.set(key, values[1]), object, Ember.String.fmt('Try #2: object.set(%@, %@) should run function', [key, values[1]]));\n\n equal(object.set(key, values[1]), object, Ember.String.fmt('Try #3: object.set(%@, %@) should not run function since it is setting same value as before', [key, values[1]]));\n\n });\n\n\n // verify each call count. cached should only be called once\n forEach(keys, function(key) {\n var calls = object[key + 'Calls'], idx;\n var expectedLength;\n\n // Cached properties first check their cached value before setting the\n // property. Other properties blindly call set.\n expectedLength = 3;\n equal(calls.length, expectedLength, Ember.String.fmt('set(%@) should be called the right amount of times', [key]));\n for(idx=0;idx<2;idx++) {\n equal(calls[idx], values[idx], Ember.String.fmt('call #%@ to set(%@) should have passed value %@', [idx+1, key, values[idx]]));\n }\n });\n\n});\n\ntest(\"notify change should clear cache\", function() {\n\n // call get several times to collect call count\n object.get('computedCached'); // should run func\n object.get('computedCached'); // should not run func\n\n object.propertyWillChange('computedCached')\n .propertyDidChange('computedCached');\n\n object.get('computedCached'); // should run again\n equal(object.computedCachedCalls.length, 2, 'should have invoked method 2x');\n});\n\ntest(\"change dependent should clear cache\", function() {\n\n // call get several times to collect call count\n var ret1 = object.get('inc'); // should run func\n equal(object.get('inc'), ret1, 'multiple calls should not run cached prop');\n\n object.set('changer', 'bar');\n\n equal(object.get('inc'), ret1+1, 'should increment after dependent key changes'); // should run again\n});\n\ntest(\"just notifying change of dependent should clear cache\", function() {\n\n // call get several times to collect call count\n var ret1 = object.get('inc'); // should run func\n equal(object.get('inc'), ret1, 'multiple calls should not run cached prop');\n\n object.notifyPropertyChange('changer');\n\n equal(object.get('inc'), ret1+1, 'should increment after dependent key changes'); // should run again\n});\n\ntest(\"changing dependent should clear nested cache\", function() {\n\n // call get several times to collect call count\n var ret1 = object.get('nestedInc'); // should run func\n equal(object.get('nestedInc'), ret1, 'multiple calls should not run cached prop');\n\n object.set('changer', 'bar');\n\n equal(object.get('nestedInc'), ret1+1, 'should increment after dependent key changes'); // should run again\n\n});\n\ntest(\"just notifying change of dependent should clear nested cache\", function() {\n\n // call get several times to collect call count\n var ret1 = object.get('nestedInc'); // should run func\n equal(object.get('nestedInc'), ret1, 'multiple calls should not run cached prop');\n\n object.notifyPropertyChange('changer');\n\n equal(object.get('nestedInc'), ret1+1, 'should increment after dependent key changes'); // should run again\n\n});\n\n\n// This verifies a specific bug encountered where observers for computed\n// properties would fire before their prop caches were cleared.\ntest(\"change dependent should clear cache when observers of dependent are called\", function() {\n\n // call get several times to collect call count\n var ret1 = object.get('inc'); // should run func\n equal(object.get('inc'), ret1, 'multiple calls should not run cached prop');\n\n // add observer to verify change...\n object.addObserver('inc', this, function() {\n equal(object.get('inc'), ret1+1, 'should increment after dependent key changes'); // should run again\n });\n\n // now run\n object.set('changer', 'bar');\n\n});\n\ntest('setting one of two computed properties that depend on a third property should clear the kvo cache', function() {\n // we have to call set twice to fill up the cache\n object.set('isOff', true);\n object.set('isOn', true);\n\n // setting isOff to true should clear the kvo cache\n object.set('isOff', true);\n equal(object.get('isOff'), true, 'object.isOff should be true');\n equal(object.get('isOn'), false, 'object.isOn should be false');\n});\n\ntest(\"dependent keys should be able to be specified as property paths\", function() {\n var depObj = ObservableObject.createWithMixins({\n menu: ObservableObject.create({\n price: 5\n }),\n\n menuPrice: Ember.computed(function() {\n return this.get('menu.price');\n }).property('menu.price')\n });\n\n equal(depObj.get('menuPrice'), 5, \"precond - initial value returns 5\");\n\n depObj.set('menu.price', 6);\n\n equal(depObj.get('menuPrice'), 6, \"cache is properly invalidated after nested property changes\");\n});\n\ntest(\"nested dependent keys should propagate after they update\", function() {\n var bindObj;\n Ember.run(function () {\n lookup.DepObj = ObservableObject.createWithMixins({\n restaurant: ObservableObject.create({\n menu: ObservableObject.create({\n price: 5\n })\n }),\n\n price: Ember.computed(function() {\n return this.get('restaurant.menu.price');\n }).property('restaurant.menu.price')\n });\n\n bindObj = ObservableObject.createWithMixins({\n priceBinding: \"DepObj.price\"\n });\n });\n\n equal(bindObj.get('price'), 5, \"precond - binding propagates\");\n\n Ember.run(function () {\n lookup.DepObj.set('restaurant.menu.price', 10);\n });\n\n equal(bindObj.get('price'), 10, \"binding propagates after a nested dependent keys updates\");\n\n Ember.run(function () {\n lookup.DepObj.set('restaurant.menu', ObservableObject.create({\n price: 15\n }));\n });\n\n equal(bindObj.get('price'), 15, \"binding propagates after a middle dependent keys updates\");\n});\n\ntest(\"cacheable nested dependent keys should clear after their dependencies update\", function() {\n ok(true);\n\n var DepObj;\n\n Ember.run(function() {\n lookup.DepObj = DepObj = ObservableObject.createWithMixins({\n restaurant: ObservableObject.create({\n menu: ObservableObject.create({\n price: 5\n })\n }),\n\n price: Ember.computed(function() {\n return this.get('restaurant.menu.price');\n }).property('restaurant.menu.price')\n });\n });\n\n equal(DepObj.get('price'), 5, \"precond - computed property is correct\");\n\n Ember.run(function() {\n DepObj.set('restaurant.menu.price', 10);\n });\n equal(DepObj.get('price'), 10, \"cacheable computed properties are invalidated even if no run loop occurred\");\n\n Ember.run(function() {\n DepObj.set('restaurant.menu.price', 20);\n });\n equal(DepObj.get('price'), 20, \"cacheable computed properties are invalidated after a second get before a run loop\");\n equal(DepObj.get('price'), 20, \"precond - computed properties remain correct after a run loop\");\n\n Ember.run(function() {\n DepObj.set('restaurant.menu', ObservableObject.create({\n price: 15\n }));\n });\n\n\n equal(DepObj.get('price'), 15, \"cacheable computed properties are invalidated after a middle property changes\");\n\n Ember.run(function() {\n DepObj.set('restaurant.menu', ObservableObject.create({\n price: 25\n }));\n });\n\n equal(DepObj.get('price'), 25, \"cacheable computed properties are invalidated after a middle property changes again, before a run loop\");\n});\n\n\n\n// ..........................................................\n// OBSERVABLE OBJECTS\n//\n\nmodule(\"Observable objects & object properties \", {\n\n setup: function() {\n object = ObservableObject.createWithMixins({\n\n normal: 'value',\n abnormal: 'zeroValue',\n numberVal: 24,\n toggleVal: true,\n observedProperty: 'beingWatched',\n testRemove: 'observerToBeRemoved',\n normalArray: Ember.A([1,2,3,4,5]),\n\n getEach: function() {\n var keys = ['normal','abnormal'];\n var ret = [];\n for(var idx=0; idx Ember.run.sync();\n * changes obj.set() and obj.get() to Ember.set() and Ember.get()\n * Fixed an actual bug in unit tests around line 133\n * fixed 'bindings should disconnect on destroy' test to use Ember.destroy.\n*/\n\n// ========================================================================\n// Ember.Object bindings Tests\n// ========================================================================\n\nvar testObject, fromObject, extraObject, TestObject;\n\nvar set = Ember.set, get = Ember.get;\n\nvar bindModuleOpts = {\n\n setup: function() {\n testObject = Ember.Object.create({\n foo: \"bar\",\n bar: \"foo\",\n extraObject: null\n });\n\n fromObject = Ember.Object.create({\n bar: \"foo\",\n extraObject: null\n }) ;\n\n extraObject = Ember.Object.create({\n foo: \"extraObjectValue\"\n }) ;\n\n TestNamespace = {\n fromObject: fromObject,\n testObject: testObject\n } ;\n },\n\n teardown: function() {\n testObject = fromObject = extraObject = null ;\n }\n\n};\n\nmodule(\"bind() method\", bindModuleOpts);\n\ntest(\"bind(TestNamespace.fromObject.bar) should follow absolute path\", function() {\n Ember.run(function() {\n // create binding\n testObject.bind(\"foo\", \"TestNamespace.fromObject.bar\");\n\n // now make a change to see if the binding triggers.\n set(fromObject, \"bar\", \"changedValue\");\n });\n\n equal(\"changedValue\", get(testObject, \"foo\"), \"testObject.foo\");\n});\n\ntest(\"bind(.bar) should bind to relative path\", function() {\n Ember.run(function() {\n // create binding\n testObject.bind(\"foo\", \"bar\") ;\n\n // now make a change to see if the binding triggers.\n set(testObject, \"bar\", \"changedValue\") ;\n });\n\n equal(\"changedValue\", get(testObject, \"foo\"), \"testObject.foo\");\n});\n\nvar fooBindingModuleOpts = {\n\n setup: function() {\n TestObject = Ember.Object.extend({\n foo: \"bar\",\n bar: \"foo\",\n extraObject: null\n });\n\n fromObject = Ember.Object.create({\n bar: \"foo\",\n extraObject: null\n }) ;\n\n extraObject = Ember.Object.create({\n foo: \"extraObjectValue\"\n }) ;\n\n TestNamespace = {\n fromObject: fromObject,\n testObject: TestObject\n } ;\n },\n\n teardown: function() {\n TestObject = fromObject = extraObject = null ;\n // delete TestNamespace ;\n }\n\n};\n\nmodule(\"fooBinding method\", fooBindingModuleOpts);\n\n\ntest(\"fooBinding: TestNamespace.fromObject.bar should follow absolute path\", function() {\n // create binding\n Ember.run(function() {\n testObject = TestObject.createWithMixins({\n fooBinding: \"TestNamespace.fromObject.bar\"\n }) ;\n\n // now make a change to see if the binding triggers.\n set(fromObject, \"bar\", \"changedValue\") ;\n });\n\n\n equal(\"changedValue\", get(testObject, \"foo\"), \"testObject.foo\");\n});\n\ntest(\"fooBinding: .bar should bind to relative path\", function() {\n Ember.run(function() {\n testObject = TestObject.createWithMixins({\n fooBinding: \"bar\"\n });\n // now make a change to see if the binding triggers.\n set(testObject, \"bar\", \"changedValue\");\n });\n\n equal(\"changedValue\", get(testObject, \"foo\"), \"testObject.foo\");\n});\n\ntest('fooBinding: should disconnect bindings when destroyed', function () {\n Ember.run(function() {\n testObject = TestObject.createWithMixins({\n fooBinding: \"TestNamespace.fromObject.bar\"\n });\n\n set(TestNamespace.fromObject, 'bar', 'BAZ');\n });\n\n equal(get(testObject, 'foo'), 'BAZ', 'binding should have synced');\n\n Ember.destroy(testObject);\n\n Ember.run(function() {\n set(TestNamespace.fromObject, 'bar', 'BIFF');\n });\n\n ok(get(testObject, 'foo') !== 'bar', 'binding should not have synced');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/legacy_1x/system/object/bindings_test");minispade.register('ember-runtime/~tests/legacy_1x/system/object/concatenated_test', "(function() {/*\n NOTE: This test is adapted from the 1.x series of unit tests. The tests\n are the same except for places where we intend to break the API we instead\n validate that we warn the developer appropriately.\n\n CHANGES FROM 1.6:\n\n * changed get(obj, ) and set(obj, ) to Ember.get() and Ember.set()\n * converted uses of obj.isEqual() to use deepEqual() test since isEqual is not\n always defined\n*/\n\n\n\n var klass, get = Ember.get, set = Ember.set;\n\n module(\"Ember.Object Concatenated Properties\", {\n setup: function() {\n klass = Ember.Object.extend({\n concatenatedProperties: ['values', 'functions'],\n values: ['a', 'b', 'c'],\n functions: [Ember.K]\n });\n }\n });\n\n test(\"concatenates instances\", function() {\n var obj = klass.create({\n values: ['d', 'e', 'f']\n });\n\n var values = get(obj, 'values'),\n expected = ['a', 'b', 'c', 'd', 'e', 'f'];\n deepEqual(values, expected, Ember.String.fmt(\"should concatenate values property (expected: %@, got: %@)\", [expected, values]));\n });\n\n test(\"concatenates subclasses\", function() {\n var subKlass = klass.extend({\n values: ['d', 'e', 'f']\n });\n var obj = subKlass.create();\n\n var values = get(obj, 'values'),\n expected = ['a', 'b', 'c', 'd', 'e', 'f'];\n deepEqual(values, expected, Ember.String.fmt(\"should concatenate values property (expected: %@, got: %@)\", [expected, values]));\n });\n\n test(\"concatenates reopen\", function() {\n klass.reopen({\n values: ['d', 'e', 'f']\n });\n var obj = klass.create();\n\n var values = get(obj, 'values'),\n expected = ['a', 'b', 'c', 'd', 'e', 'f'];\n deepEqual(values, expected, Ember.String.fmt(\"should concatenate values property (expected: %@, got: %@)\", [expected, values]));\n });\n\n test(\"concatenates mixin\", function() {\n var mixin = {\n values: ['d', 'e']\n };\n var subKlass = klass.extend(mixin, {\n values: ['f']\n });\n var obj = subKlass.create();\n\n var values = get(obj, 'values'),\n expected = ['a', 'b', 'c', 'd', 'e', 'f'];\n deepEqual(values, expected, Ember.String.fmt(\"should concatenate values property (expected: %@, got: %@)\", [expected, values]));\n });\n\n test(\"concatenates reopen, subclass, and instance\", function() {\n klass.reopen({ values: ['d'] });\n var subKlass = klass.extend({ values: ['e'] });\n var obj = subKlass.create({ values: ['f'] });\n\n var values = get(obj, 'values'),\n expected = ['a', 'b', 'c', 'd', 'e', 'f'];\n deepEqual(values, expected, Ember.String.fmt(\"should concatenate values property (expected: %@, got: %@)\", [expected, values]));\n });\n\n test(\"concatenates subclasses when the values are functions\", function() {\n var subKlass = klass.extend({\n functions: Ember.K\n });\n var obj = subKlass.create();\n\n var values = get(obj, 'functions'),\n expected = [Ember.K, Ember.K];\n deepEqual(values, expected, Ember.String.fmt(\"should concatenate functions property (expected: %@, got: %@)\", [expected, values]));\n });\n\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/legacy_1x/system/object/concatenated_test");minispade.register('ember-runtime/~tests/legacy_1x/system/run_loop_test', "(function() {/*\n NOTE: This test is adapted from the 1.x series of unit tests. The tests\n are the same except for places where we intend to break the API we instead\n validate that we warn the developer appropriately.\n\n CHANGES FROM 1.6:\n\n * Updated the API usage for setting up and syncing Ember.Binding since these\n are not the APIs this file is testing.\n\n * Disabled a call to invokeOnce() around line 127 because it appeared to be\n broken anyway. I don't think it ever even worked.\n*/\n\nvar MyApp, binding1, binding2, previousPreventRunloop;\n\nmodule(\"System:run_loop() - chained binding\", {\n setup: function() {\n MyApp = {};\n MyApp.first = Ember.Object.createWithMixins(Ember.Observable, {\n output: 'MyApp.first'\n }) ;\n\n MyApp.second = Ember.Object.createWithMixins(Ember.Observable, {\n input: 'MyApp.second',\n output: 'MyApp.second',\n\n inputDidChange: Ember.observer(\"input\", function() {\n this.set(\"output\", this.get(\"input\")) ;\n })\n\n }) ;\n\n MyApp.third = Ember.Object.createWithMixins(Ember.Observable, {\n input: \"MyApp.third\"\n }) ;\n }\n});\n\ntest(\"Should propagate bindings after the RunLoop completes (using Ember.RunLoop)\", function() {\n Ember.run(function () {\n\n //Binding of output of MyApp.first object to input of MyApp.second object\n binding1 = Ember.Binding.from(\"first.output\")\n .to(\"second.input\").connect(MyApp) ;\n\n //Binding of output of MyApp.second object to input of MyApp.third object\n binding2 = Ember.Binding.from(\"second.output\")\n .to(\"third.input\").connect(MyApp) ;\n\n });\n Ember.run(function () {\n // Based on the above binding if you change the output of MyApp.first\n // object it should change the all the variable of\n // MyApp.first,MyApp.second and MyApp.third object\n MyApp.first.set(\"output\", \"change\") ;\n\n //Changes the output of the MyApp.first object\n equal(MyApp.first.get(\"output\"), \"change\") ;\n\n //since binding has not taken into effect the value still remains as change.\n equal(MyApp.second.get(\"output\"), \"MyApp.first\") ;\n\n }); // allows bindings to trigger...\n\n //Value of the output variable changed to 'change'\n equal(MyApp.first.get(\"output\"), \"change\") ;\n\n //Since binding triggered after the end loop the value changed to 'change'.\n equal(MyApp.second.get(\"output\"), \"change\") ;\n});\n\ntest(\"Should propagate bindings after the RunLoop completes\", function() {\n Ember.run(function () {\n //Binding of output of MyApp.first object to input of MyApp.second object\n binding1 = Ember.Binding.from(\"first.output\")\n .to(\"second.input\").connect(MyApp) ;\n\n //Binding of output of MyApp.second object to input of MyApp.third object\n binding2 = Ember.Binding.from(\"second.output\")\n .to(\"third.input\").connect(MyApp) ;\n });\n\n Ember.run(function () {\n //Based on the above binding if you change the output of MyApp.first object it should\n //change the all the variable of MyApp.first,MyApp.second and MyApp.third object\n MyApp.first.set(\"output\", \"change\") ;\n\n //Changes the output of the MyApp.first object\n equal(MyApp.first.get(\"output\"), \"change\") ;\n\n //since binding has not taken into effect the value still remains as change.\n equal(MyApp.second.get(\"output\"), \"MyApp.first\") ;\n });\n\n //Value of the output variable changed to 'change'\n equal(MyApp.first.get(\"output\"), \"change\") ;\n\n //Since binding triggered after the end loop the value changed to 'change'.\n equal(MyApp.second.get(\"output\"), \"change\") ;\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/legacy_1x/system/run_loop_test");minispade.register('ember-runtime/~tests/legacy_1x/system/set_test', "(function() {// NOTE: This test is adapted from the 1.x series of unit tests. The tests\n// are the same except for places where we intend to break the API we instead\n// validate that we warn the developer appropriately.\n//\n// * Changed Ember.Set.clone() call to Ember.Set.copy()\n\n// ========================================================================\n// Ember.Set Tests\n// ========================================================================\n\nvar a, b, c ; // global variables\n\nmodule(\"creating Ember.Set instances\", {\n\n setup: function() {\n // create objects...\n a = { name: \"a\" } ;\n b = { name: \"b\" } ;\n c = { name: \"c\" } ;\n },\n\n teardown: function() {\n a = undefined ;\n b = undefined ;\n c = undefined ;\n }\n\n});\n\ntest(\"new Ember.Set() should create empty set\", function() {\n var set = new Ember.Set() ;\n equal(set.length, 0) ;\n});\n\ntest(\"new Ember.Set([1,2,3]) should create set with three items in them\", function() {\n var set = new Ember.Set(Ember.A([a,b,c])) ;\n equal(set.length, 3) ;\n equal(set.contains(a), true) ;\n equal(set.contains(b), true) ;\n equal(set.contains(c), true) ;\n});\n\ntest(\"new Ember.Set() should accept anything that implements Ember.Array\", function() {\n var arrayLikeObject = Ember.Object.createWithMixins(Ember.Array, {\n _content: [a,b,c],\n length: 3,\n objectAt: function(idx) { return this._content[idx]; }\n }) ;\n\n var set = new Ember.Set(arrayLikeObject) ;\n equal(set.length, 3) ;\n equal(set.contains(a), true) ;\n equal(set.contains(b), true) ;\n equal(set.contains(c), true) ;\n});\n\nvar set ; // global variables\n\n// The tests below also end up testing the contains() method pretty\n// exhaustively.\nmodule(\"Ember.Set.add + Ember.Set.contains\", {\n\n setup: function() {\n set = new Ember.Set() ;\n },\n\n teardown: function() {\n set = undefined ;\n }\n\n});\n\ntest(\"should add an Ember.Object\", function() {\n var obj = Ember.Object.create() ;\n\n var oldLength = set.length ;\n set.add(obj) ;\n equal(set.contains(obj), true, \"contains()\") ;\n equal(set.length, oldLength+1, \"new set length\") ;\n});\n\ntest(\"should add a regular hash\", function() {\n var obj = {} ;\n\n var oldLength = set.length ;\n set.add(obj) ;\n equal(set.contains(obj), true, \"contains()\") ;\n equal(set.length, oldLength+1, \"new set length\") ;\n});\n\ntest(\"should add a string\", function() {\n var obj = \"String!\" ;\n\n var oldLength = set.length ;\n set.add(obj) ;\n equal(set.contains(obj), true, \"contains()\") ;\n equal(set.length, oldLength+1, \"new set length\") ;\n});\n\ntest(\"should add a number\", function() {\n var obj = 23 ;\n\n var oldLength = set.length ;\n set.add(obj) ;\n equal(set.contains(obj), true, \"contains()\") ;\n equal(set.length, oldLength+1, \"new set length\") ;\n});\n\ntest(\"should add bools\", function() {\n var oldLength = set.length ;\n\n set.add(true) ;\n equal(set.contains(true), true, \"contains(true)\");\n equal(set.length, oldLength+1, \"new set length\");\n\n set.add(false);\n equal(set.contains(false), true, \"contains(false)\");\n equal(set.length, oldLength+2, \"new set length\");\n});\n\ntest(\"should add 0\", function() {\n var oldLength = set.length ;\n\n set.add(0) ;\n equal(set.contains(0), true, \"contains(0)\");\n equal(set.length, oldLength+1, \"new set length\");\n});\n\ntest(\"should add a function\", function() {\n var obj = function() { return \"Test function\"; } ;\n\n var oldLength = set.length ;\n set.add(obj) ;\n equal(set.contains(obj), true, \"contains()\") ;\n equal(set.length, oldLength+1, \"new set length\") ;\n});\n\ntest(\"should NOT add a null\", function() {\n set.add(null) ;\n equal(set.length, 0) ;\n equal(set.contains(null), false) ;\n});\n\ntest(\"should NOT add an undefined\", function() {\n set.add(undefined) ;\n equal(set.length, 0) ;\n equal(set.contains(undefined), false) ;\n});\n\ntest(\"adding an item, removing it, adding another item\", function() {\n var item1 = \"item1\" ;\n var item2 = \"item2\" ;\n\n set.add(item1) ; // add to set\n set.remove(item1) ; //remove from set\n set.add(item2) ;\n\n equal(set.contains(item1), false, \"set.contains(item1)\") ;\n\n set.add(item1) ; // re-add to set\n equal(set.length, 2, \"set.length\") ;\n});\n\nmodule(\"Ember.Set.remove + Ember.Set.contains\", {\n\n // generate a set with every type of object, but none of the specific\n // ones we add in the tests below...\n setup: function() {\n set = new Ember.Set(Ember.A([\n Ember.Object.create({ dummy: true }),\n { isHash: true },\n \"Not the String\",\n 16, true, false, 0])) ;\n },\n\n teardown: function() {\n set = undefined ;\n }\n\n});\n\ntest(\"should remove an Ember.Object and reduce length\", function() {\n var obj = Ember.Object.create() ;\n set.add(obj) ;\n equal(set.contains(obj), true) ;\n var oldLength = set.length ;\n\n set.remove(obj) ;\n equal(set.contains(obj), false, \"should be removed\") ;\n equal(set.length, oldLength-1, \"should be 1 shorter\") ;\n});\n\ntest(\"should remove a regular hash and reduce length\", function() {\n var obj = {} ;\n set.add(obj) ;\n equal(set.contains(obj), true) ;\n var oldLength = set.length ;\n\n set.remove(obj) ;\n equal(set.contains(obj), false, \"should be removed\") ;\n equal(set.length, oldLength-1, \"should be 1 shorter\") ;\n});\n\ntest(\"should remove a string and reduce length\", function() {\n var obj = \"String!\" ;\n set.add(obj) ;\n equal(set.contains(obj), true) ;\n var oldLength = set.length ;\n\n set.remove(obj) ;\n equal(set.contains(obj), false, \"should be removed\") ;\n equal(set.length, oldLength-1, \"should be 1 shorter\") ;\n});\n\ntest(\"should remove a number and reduce length\", function() {\n var obj = 23 ;\n set.add(obj) ;\n equal(set.contains(obj), true) ;\n var oldLength = set.length ;\n\n set.remove(obj) ;\n equal(set.contains(obj), false, \"should be removed\") ;\n equal(set.length, oldLength-1, \"should be 1 shorter\") ;\n});\n\ntest(\"should remove a bools and reduce length\", function() {\n var oldLength = set.length ;\n set.remove(true) ;\n equal(set.contains(true), false, \"should be removed\") ;\n equal(set.length, oldLength-1, \"should be 1 shorter\") ;\n\n set.remove(false);\n equal(set.contains(false), false, \"should be removed\") ;\n equal(set.length, oldLength-2, \"should be 2 shorter\") ;\n});\n\ntest(\"should remove 0 and reduce length\", function() {\n var oldLength = set.length;\n set.remove(0) ;\n equal(set.contains(0), false, \"should be removed\") ;\n equal(set.length, oldLength-1, \"should be 1 shorter\") ;\n});\n\ntest(\"should remove a function and reduce length\", function() {\n var obj = function() { return \"Test function\"; } ;\n set.add(obj) ;\n equal(set.contains(obj), true) ;\n var oldLength = set.length ;\n\n set.remove(obj) ;\n equal(set.contains(obj), false, \"should be removed\") ;\n equal(set.length, oldLength-1, \"should be 1 shorter\") ;\n});\n\ntest(\"should NOT remove a null\", function() {\n var oldLength = set.length ;\n set.remove(null) ;\n equal(set.length, oldLength) ;\n});\n\ntest(\"should NOT remove an undefined\", function() {\n var oldLength = set.length ;\n set.remove(undefined) ;\n equal(set.length, oldLength) ;\n});\n\ntest(\"should ignore removing an object not in the set\", function() {\n var obj = Ember.Object.create() ;\n var oldLength = set.length ;\n set.remove(obj) ;\n equal(set.length, oldLength) ;\n});\n\nmodule(\"Ember.Set.pop + Ember.Set.copy\", {\n// generate a set with every type of object, but none of the specific\n// ones we add in the tests below...\n setup: function() {\n set = new Ember.Set(Ember.A([\n Ember.Object.create({ dummy: true }),\n { isHash: true },\n \"Not the String\",\n 16, false])) ;\n },\n\n teardown: function() {\n set = undefined ;\n }\n});\n\ntest(\"the pop() should remove an arbitrary object from the set\", function() {\n var oldLength = set.length ;\n var obj = set.pop();\n ok(!Ember.isNone(obj), 'pops up an item');\n equal(set.length, oldLength-1, 'length shorter by 1');\n});\n\ntest(\"should pop false and 0\", function() {\n set = new Ember.Set(Ember.A([false]));\n ok(set.pop() === false, \"should pop false\");\n\n set = new Ember.Set(Ember.A([0]));\n ok(set.pop() === 0, \"should pop 0\");\n});\n\ntest(\"the copy() should return an indentical set\", function() {\n var oldLength = set.length ;\n var obj = set.copy();\n equal(oldLength,obj.length,'length of the clone should be same');\n equal(obj.contains(set[0]), true);\n equal(obj.contains(set[1]), true);\n equal(obj.contains(set[2]), true);\n equal(obj.contains(set[3]), true);\n equal(obj.contains(set[4]), true);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/legacy_1x/system/set_test");minispade.register('ember-runtime/~tests/mixins/array_test', "(function() {/*globals testBoth */\nminispade.require('ember-runtime/~tests/props_helper');\nminispade.require('ember-runtime/~tests/suites/array');\n\n/*\n Implement a basic fake mutable array. This validates that any non-native\n enumerable can impl this API.\n*/\nvar TestArray = Ember.Object.extend(Ember.Array, {\n\n _content: null,\n\n init: function(ary) {\n this._content = ary || [];\n },\n\n // some methods to modify the array so we can test changes. Note that\n // arrays can be modified even if they don't implement MutableArray. The\n // MutableArray is just a standard API for mutation but not required.\n addObject: function(obj) {\n var idx = this._content.length;\n this.arrayContentWillChange(idx, 0, 1);\n this._content.push(obj);\n this.arrayContentDidChange(idx, 0, 1);\n },\n\n removeFirst: function(idx) {\n this.arrayContentWillChange(0, 1, 0);\n this._content.shift();\n this.arrayContentDidChange(0, 1, 0);\n },\n\n objectAt: function(idx) {\n return this._content[idx];\n },\n\n length: Ember.computed(function() {\n return this._content.length;\n })\n});\n\n\nEmber.ArrayTests.extend({\n\n name: 'Basic Mutable Array',\n\n newObject: function(ary) {\n ary = ary ? ary.slice() : this.newFixture(3);\n return new TestArray(ary);\n },\n\n // allows for testing of the basic enumerable after an internal mutation\n mutate: function(obj) {\n obj.addObject(this.getFixture(1)[0]);\n },\n\n toArray: function(obj) {\n return obj.slice();\n }\n\n}).run();\n\ntest(\"the return value of slice has Ember.Array applied\", function() {\n var x = Ember.Object.createWithMixins(Ember.Array, {\n length: 0\n });\n var y = x.slice(1);\n equal(Ember.Array.detect(y), true, \"mixin should be applied\");\n});\n\ntest(\"slice supports negative index arguments\", function() {\n var testArray = new TestArray([1,2,3,4]);\n\n deepEqual(testArray.slice(-2), [3, 4], 'slice(-2)');\n deepEqual(testArray.slice(-2, -1), [3], 'slice(-2, -1');\n deepEqual(testArray.slice(-2, -2), [], 'slice(-2, -2)');\n deepEqual(testArray.slice(-1, -2), [], 'slice(-1, -2)');\n\n deepEqual(testArray.slice(-4, 1), [1], 'slice(-4, 1)');\n deepEqual(testArray.slice(-4, 5), [1,2,3,4], 'slice(-4, 5)');\n deepEqual(testArray.slice(-4), [1,2,3,4], 'slice(-4)');\n\n deepEqual(testArray.slice(0, -1), [1,2,3], 'slice(0, -1)');\n deepEqual(testArray.slice(0, -4), [], 'slice(0, -4)');\n deepEqual(testArray.slice(0, -3), [1], 'slice(0, -3)');\n\n});\n\n// ..........................................................\n// CONTENT DID CHANGE\n//\n\nvar DummyArray = Ember.Object.extend(Ember.Array, {\n nextObject: function() {},\n length: 0,\n objectAt: function(idx) { return 'ITEM-'+idx; }\n});\n\nvar obj, observer;\n\n\n// ..........................................................\n// NOTIFY ARRAY OBSERVERS\n//\n\nmodule('mixins/array/arrayContent[Will|Did]Change');\n\ntest('should notify observers of []', function() {\n\n obj = DummyArray.createWithMixins({\n _count: 0,\n enumerablePropertyDidChange: Ember.observer('[]', function() {\n this._count++;\n })\n });\n\n equal(obj._count, 0, 'should not have invoked yet');\n\n obj.arrayContentWillChange(0, 1, 1);\n obj.arrayContentDidChange(0, 1, 1);\n\n equal(obj._count, 1, 'should have invoked');\n\n});\n\n// ..........................................................\n// NOTIFY CHANGES TO LENGTH\n//\n\nmodule('notify observers of length', {\n setup: function() {\n obj = DummyArray.createWithMixins({\n _after: 0,\n lengthDidChange: Ember.observer('length', function() {\n this._after++;\n })\n\n });\n\n equal(obj._after, 0, 'should not have fired yet');\n },\n\n teardown: function() {\n obj = null;\n }\n});\n\ntest('should notify observers when call with no params', function() {\n obj.arrayContentWillChange();\n equal(obj._after, 0);\n\n obj.arrayContentDidChange();\n equal(obj._after, 1);\n});\n\n// API variation that included items only\ntest('should not notify when passed lengths are same', function() {\n obj.arrayContentWillChange(0, 1, 1);\n equal(obj._after, 0);\n\n obj.arrayContentDidChange(0, 1, 1);\n equal(obj._after, 0);\n});\n\ntest('should notify when passed lengths are different', function() {\n obj.arrayContentWillChange(0, 1, 2);\n equal(obj._after, 0);\n\n obj.arrayContentDidChange(0, 1, 2);\n equal(obj._after, 1);\n});\n\n\n// ..........................................................\n// NOTIFY ARRAY OBSERVER\n//\n\nmodule('notify array observers', {\n setup: function() {\n obj = DummyArray.create();\n\n observer = Ember.Object.createWithMixins({\n _before: null,\n _after: null,\n\n arrayWillChange: function() {\n equal(this._before, null); // should only call once\n this._before = Array.prototype.slice.call(arguments);\n },\n\n arrayDidChange: function() {\n equal(this._after, null); // should only call once\n this._after = Array.prototype.slice.call(arguments);\n }\n });\n\n obj.addArrayObserver(observer);\n },\n\n teardown: function() {\n obj = observer = null;\n }\n});\n\ntest('should notify enumerable observers when called with no params', function() {\n obj.arrayContentWillChange();\n deepEqual(observer._before, [obj, 0, -1, -1]);\n\n obj.arrayContentDidChange();\n deepEqual(observer._after, [obj, 0, -1, -1]);\n});\n\n// API variation that included items only\ntest('should notify when called with same length items', function() {\n obj.arrayContentWillChange(0, 1, 1);\n deepEqual(observer._before, [obj, 0, 1, 1]);\n\n obj.arrayContentDidChange(0, 1, 1);\n deepEqual(observer._after, [obj, 0, 1, 1]);\n});\n\ntest('should notify when called with diff length items', function() {\n obj.arrayContentWillChange(0, 2, 1);\n deepEqual(observer._before, [obj, 0, 2, 1]);\n\n obj.arrayContentDidChange(0, 2, 1);\n deepEqual(observer._after, [obj, 0, 2, 1]);\n});\n\ntest('removing enumerable observer should disable', function() {\n obj.removeArrayObserver(observer);\n obj.arrayContentWillChange();\n deepEqual(observer._before, null);\n\n obj.arrayContentDidChange();\n deepEqual(observer._after, null);\n});\n\n// ..........................................................\n// NOTIFY ENUMERABLE OBSERVER\n//\n\nmodule('notify enumerable observers as well', {\n setup: function() {\n obj = DummyArray.create();\n\n observer = Ember.Object.createWithMixins({\n _before: null,\n _after: null,\n\n enumerableWillChange: function() {\n equal(this._before, null); // should only call once\n this._before = Array.prototype.slice.call(arguments);\n },\n\n enumerableDidChange: function() {\n equal(this._after, null); // should only call once\n this._after = Array.prototype.slice.call(arguments);\n }\n });\n\n obj.addEnumerableObserver(observer);\n },\n\n teardown: function() {\n obj = observer = null;\n }\n});\n\ntest('should notify enumerable observers when called with no params', function() {\n obj.arrayContentWillChange();\n deepEqual(observer._before, [obj, null, null], 'before');\n\n obj.arrayContentDidChange();\n deepEqual(observer._after, [obj, null, null], 'after');\n});\n\n// API variation that included items only\ntest('should notify when called with same length items', function() {\n obj.arrayContentWillChange(0, 1, 1);\n deepEqual(observer._before, [obj, ['ITEM-0'], 1], 'before');\n\n obj.arrayContentDidChange(0, 1, 1);\n deepEqual(observer._after, [obj, 1, ['ITEM-0']], 'after');\n});\n\ntest('should notify when called with diff length items', function() {\n obj.arrayContentWillChange(0, 2, 1);\n deepEqual(observer._before, [obj, ['ITEM-0', 'ITEM-1'], 1], 'before');\n\n obj.arrayContentDidChange(0, 2, 1);\n deepEqual(observer._after, [obj, 2, ['ITEM-0']], 'after');\n});\n\ntest('removing enumerable observer should disable', function() {\n obj.removeEnumerableObserver(observer);\n obj.arrayContentWillChange();\n deepEqual(observer._before, null, 'before');\n\n obj.arrayContentDidChange();\n deepEqual(observer._after, null, 'after');\n});\n\n// ..........................................................\n// @each\n//\n\nvar ary;\n\nmodule('Ember.Array.@each support', {\n setup: function() {\n ary = new TestArray([\n { isDone: true, desc: 'Todo 1' },\n { isDone: false, desc: 'Todo 2' },\n { isDone: true, desc: 'Todo 3' },\n { isDone: false, desc: 'Todo 4' }\n ]);\n },\n\n teardown: function() {\n ary = null;\n }\n});\n\ntest('adding an object should notify (@each)', function() {\n\n var get = Ember.get, set = Ember.set;\n var called = 0;\n\n var observerObject = Ember.Object.create({\n wasCalled: function() {\n called++;\n }\n });\n\n // Ember.get(ary, '@each');\n Ember.addObserver(ary, '@each', observerObject, 'wasCalled');\n\n ary.addObject(Ember.Object.create({\n desc: \"foo\",\n isDone: false\n }));\n\n equal(called, 1, \"calls observer when object is pushed\");\n\n});\n\ntest('adding an object should notify (@each.isDone)', function() {\n\n var get = Ember.get, set = Ember.set;\n var called = 0;\n\n var observerObject = Ember.Object.create({\n wasCalled: function() {\n called++;\n }\n });\n\n Ember.addObserver(ary, '@each.isDone', observerObject, 'wasCalled');\n\n ary.addObject(Ember.Object.create({\n desc: \"foo\",\n isDone: false\n }));\n\n equal(called, 1, \"calls observer when object is pushed\");\n\n});\n\ntest('using @each to observe arrays that does not return objects raise error', function() {\n\n var get = Ember.get, set = Ember.set;\n var called = 0;\n\n var observerObject = Ember.Object.create({\n wasCalled: function() {\n called++;\n }\n });\n\n ary = TestArray.create({\n objectAt: function(idx) {\n return get(this._content[idx], 'desc');\n }\n });\n\n Ember.addObserver(ary, '@each.isDone', observerObject, 'wasCalled');\n\n expectAssertion(function() {\n ary.addObject(Ember.Object.create({\n desc: \"foo\",\n isDone: false\n }));\n }, /When using @each to observe the array/);\n\n equal(called, 0, 'not calls observer when object is pushed');\n});\n\ntest('modifying the array should also indicate the isDone prop itself has changed', function() {\n // NOTE: we never actually get the '@each.isDone' property here. This is\n // important because it tests the case where we don't have an isDone\n // EachArray materialized but just want to know when the property has\n // changed.\n\n var get = Ember.get, set = Ember.set;\n var each = get(ary, '@each');\n var count = 0;\n\n Ember.addObserver(each, 'isDone', function() { count++; });\n\n count = 0;\n var item = ary.objectAt(2);\n set(item, 'isDone', !get(item, 'isDone'));\n equal(count, 1, '@each.isDone should have notified');\n});\n\n\ntestBoth(\"should be clear caches for computed properties that have dependent keys on arrays that are changed after object initialization\", function(get, set) {\n var obj = Ember.Object.createWithMixins({\n init: function() {\n set(this, 'resources', Ember.A());\n },\n\n common: Ember.computed(function() {\n return get(get(this, 'resources').objectAt(0), 'common');\n }).property('resources.@each.common')\n });\n\n get(obj, 'resources').pushObject(Ember.Object.create({ common: \"HI!\" }));\n equal(\"HI!\", get(obj, 'common'));\n\n set(get(obj, 'resources').objectAt(0), 'common', \"BYE!\");\n equal(\"BYE!\", get(obj, 'common'));\n});\n\ntestBoth(\"observers that contain @each in the path should fire only once the first time they are accessed\", function(get, set) {\n var count = 0;\n\n var obj = Ember.Object.createWithMixins({\n init: function() {\n // Observer does not fire on init\n set(this, 'resources', Ember.A());\n },\n\n commonDidChange: Ember.observer('resources.@each.common', function() {\n count++;\n })\n });\n\n // Observer fires second time when new object is added\n get(obj, 'resources').pushObject(Ember.Object.create({ common: \"HI!\" }));\n // Observer fires third time when property on an object is changed\n set(get(obj, 'resources').objectAt(0), 'common', \"BYE!\");\n\n equal(count, 2, \"observers should only be called once\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/array_test");minispade.register('ember-runtime/~tests/mixins/comparable_test', "(function() {/*globals module test ok isObj equals expects */\n\nvar Rectangle = Ember.Object.extend(Ember.Comparable, {\n length: 0,\n width: 0,\n\n area: function() {\n return Ember.get(this,'length') * Ember.get(this, 'width');\n },\n\n compare: function(a, b) {\n return Ember.compare(a.area(), b.area());\n }\n\n});\n\nvar r1, r2;\n\nmodule(\"Comparable\", {\n\n setup: function() {\n r1 = Rectangle.create({length: 6, width: 12});\n r2 = Rectangle.create({length: 6, width: 13});\n },\n\n teardown: function() {\n }\n\n});\n\ntest(\"should be comparable and return the correct result\", function() {\n equal(Ember.Comparable.detect(r1), true);\n equal(Ember.compare(r1, r1), 0);\n equal(Ember.compare(r1, r2), -1);\n equal(Ember.compare(r2, r1), 1);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/comparable_test");minispade.register('ember-runtime/~tests/mixins/copyable_test', "(function() {minispade.require('ember-runtime/~tests/suites/copyable');\n\n// NOTE: See debug/suites/copyable.js for mosts tests\n\nvar CopyableObject = Ember.Object.extend(Ember.Copyable, {\n\n id: null,\n\n init: function() {\n this._super();\n Ember.set(this, 'id', Ember.generateGuid());\n },\n\n copy: function() {\n var ret = new CopyableObject();\n Ember.set(ret, 'id', Ember.get(this, 'id'));\n return ret;\n }\n});\n\nEmber.CopyableTests.extend({\n\n name: 'Ember.Copyable Basic Test',\n\n newObject: function() {\n return new CopyableObject();\n },\n\n isEqual: function(a, b) {\n if (!(a instanceof CopyableObject) || !(b instanceof CopyableObject)) return false;\n return Ember.get(a, 'id') === Ember.get(b,'id');\n }\n}).run();\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/copyable_test");minispade.register('ember-runtime/~tests/mixins/deferred_test', "(function() {module(\"Ember.DeferredMixin\");\n\ntest(\"can resolve deferred\", function() {\n var deferred, count = 0;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(function(a) {\n count++;\n });\n\n Ember.run(deferred, 'resolve', deferred);\n\n equal(count, 1, \"was fulfilled\");\n});\n\ntest(\"can reject deferred\", function() {\n\n var deferred, count = 0;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(null, function() {\n count++;\n });\n\n Ember.run(deferred, 'reject');\n\n equal(count, 1, \"fail callback was called\");\n});\n\ntest(\"can resolve with then\", function() {\n\n var deferred, count1 = 0 ,count2 = 0;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(function() {\n count1++;\n }, function() {\n count2++;\n });\n\n Ember.run(deferred, 'resolve', deferred);\n\n equal(count1, 1, \"then were resolved\");\n equal(count2, 0, \"then was not rejected\");\n});\n\ntest(\"can reject with then\", function() {\n\n var deferred, count1 = 0 ,count2 = 0;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(function() {\n count1++;\n }, function() {\n count2++;\n });\n\n Ember.run(deferred, 'reject');\n\n equal(count1, 0, \"then was not resolved\");\n equal(count2, 1, \"then were rejected\");\n});\n\ntest(\"can call resolve multiple times\", function() {\n\n var deferred, count = 0;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(function() {\n count++;\n });\n\n Ember.run(function() {\n deferred.resolve(deferred);\n deferred.resolve(deferred);\n deferred.resolve(deferred);\n });\n\n equal(count, 1, \"calling resolve multiple times has no effect\");\n});\n\ntest(\"resolve prevent reject\", function() {\n var deferred, resolved = false, rejected = false, progress = 0;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(function() {\n resolved = true;\n }, function() {\n rejected = true;\n });\n\n Ember.run(deferred, 'resolve', deferred);\n Ember.run(deferred, 'reject');\n\n equal(resolved, true, \"is resolved\");\n equal(rejected, false, \"is not rejected\");\n});\n\ntest(\"reject prevent resolve\", function() {\n var deferred, resolved = false, rejected = false, progress = 0;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(function() {\n resolved = true;\n }, function() {\n rejected = true;\n });\n\n Ember.run(deferred, 'reject');\n Ember.run(deferred, 'reject', deferred);\n\n equal(resolved, false, \"is not resolved\");\n equal(rejected, true, \"is rejected\");\n});\n\ntest(\"will call callbacks if they are added after resolution\", function() {\n\n var deferred, count1 = 0;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n Ember.run(deferred, 'resolve', 'toto');\n\n Ember.run(function() {\n deferred.then(function(context) {\n if (context === 'toto') {\n count1++;\n }\n });\n\n deferred.then(function(context) {\n if (context === 'toto') {\n count1++;\n }\n });\n });\n\n equal(count1, 2, \"callbacks called after resolution\");\n});\n\ntest(\"then is chainable\", function() {\n var deferred, count = 0;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(function() {\n eval('error'); // Use eval to pass JSHint\n }).then(null, function() {\n count++;\n });\n\n Ember.run(deferred, 'resolve', deferred);\n\n equal(count, 1, \"chained callback was called\");\n});\n\n\n\ntest(\"can self fulfill\", function() {\n expect(1);\n var deferred;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(function(value) {\n equal(value, deferred, \"successfully resolved to itself\");\n });\n\n Ember.run(deferred, 'resolve', deferred);\n});\n\n\ntest(\"can self reject\", function() {\n expect(1);\n var deferred;\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(function() {\n ok(false, 'should not fulfill'); \n },function(value) {\n equal(value, deferred, \"successfully rejected to itself\");\n });\n\n Ember.run(deferred, 'reject', deferred);\n});\n\ntest(\"can fulfill to a custom value\", function() {\n expect(1);\n var deferred, obj = {};\n\n Ember.run(function() {\n deferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then(function(value) {\n equal(value, obj, \"successfully resolved to given value\");\n });\n\n Ember.run(deferred, 'resolve', obj);\n});\n\n\ntest(\"can chain self fulfilling objects\", function() {\n expect(2);\n var firstDeferred, secondDeferred;\n\n Ember.run(function() {\n firstDeferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n secondDeferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n firstDeferred.then(function(value) {\n equal(value, firstDeferred, \"successfully resolved to the first deferred\");\n return secondDeferred;\n }).then(function(value) {\n equal(value, secondDeferred, \"successfully resolved to the second deferred\");\n });\n\n Ember.run(function() {\n firstDeferred.resolve(firstDeferred);\n secondDeferred.resolve(secondDeferred);\n });\n});\n\ntest(\"can do multi level assimilation\", function() {\n expect(1);\n var firstDeferred, secondDeferred, firstDeferredResolved = false;\n\n Ember.run(function() {\n firstDeferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n secondDeferred = Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n firstDeferred.then(function() {\n firstDeferredResolved = true;\n });\n\n secondDeferred.then(function() {\n ok(firstDeferredResolved, \"first deferred already resolved\");\n });\n\n Ember.run(secondDeferred, 'resolve', firstDeferred);\n Ember.run(firstDeferred, 'resolve', firstDeferred);\n});\n\n\ntest(\"can handle rejection without rejection handler\", function() {\n expect(2);\n\n var reason = 'some reason';\n\n var deferred = Ember.run(function() {\n return Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then().then(function() {\n ok(false, 'expected rejection, got fulfillment');\n }, function(actualReason) {\n ok(true, 'expected fulfillment');\n equal(actualReason, reason);\n });\n\n Ember.run(deferred, 'reject', reason);\n});\n\ntest(\"can handle fulfillment without fulfillment handler\", function() {\n expect(2);\n\n var fulfillment = 'some fulfillment';\n\n var deferred = Ember.run(function() {\n return Ember.Object.createWithMixins(Ember.DeferredMixin);\n });\n\n deferred.then().then(function(actualFulfillment) {\n ok(true, 'expected fulfillment');\n equal(fulfillment, actualFulfillment);\n }, function(reason) {\n ok(false, 'expected fulfillment, got reason' + reason);\n });\n\n Ember.run(deferred, 'resolve', fulfillment);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/deferred_test");minispade.register('ember-runtime/~tests/mixins/enumerable_test', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar indexOf = Ember.EnumerableUtils.indexOf;\n\n/*\n Implement a basic fake enumerable. This validates that any non-native\n enumerable can impl this API.\n*/\nvar TestEnumerable = Ember.Object.extend(Ember.Enumerable, {\n\n _content: null,\n\n init: function(ary) {\n this._content = ary || [];\n },\n\n addObject: function(obj) {\n if (indexOf(this._content, obj)>=0) return this;\n this._content.push(obj);\n this.enumerableContentDidChange();\n },\n\n nextObject: function(idx) {\n return idx >= Ember.get(this, 'length') ? undefined : this._content[idx];\n },\n\n length: Ember.computed(function() {\n return this._content.length;\n }),\n\n slice: function() {\n return this._content.slice();\n }\n\n});\n\n\nEmber.EnumerableTests.extend({\n\n name: 'Basic Enumerable',\n\n newObject: function(ary) {\n ary = ary ? ary.slice() : this.newFixture(3);\n return new TestEnumerable(ary);\n },\n\n // allows for testing of the basic enumerable after an internal mutation\n mutate: function(obj) {\n obj.addObject(obj._content.length+1);\n },\n\n toArray: function(obj) {\n return obj.slice();\n }\n\n}).run();\n\ntest(\"should apply Ember.Array to return value of map\", function() {\n var x = Ember.Object.createWithMixins(Ember.Enumerable);\n var y = x.map(Ember.K);\n equal(Ember.Array.detect(y), true, \"should have mixin applied\");\n});\n\ntest(\"should apply Ember.Array to return value of filter\", function() {\n var x = Ember.Object.createWithMixins(Ember.Enumerable);\n var y = x.filter(Ember.K);\n equal(Ember.Array.detect(y), true, \"should have mixin applied\");\n});\n\ntest(\"should apply Ember.Array to return value of invoke\", function() {\n var x = Ember.Object.createWithMixins(Ember.Enumerable);\n var y = x.invoke(Ember.K);\n equal(Ember.Array.detect(y), true, \"should have mixin applied\");\n});\n\ntest(\"should apply Ember.Array to return value of toArray\", function() {\n var x = Ember.Object.createWithMixins(Ember.Enumerable);\n var y = x.toArray(Ember.K);\n equal(Ember.Array.detect(y), true, \"should have mixin applied\");\n});\n\ntest(\"should apply Ember.Array to return value of without\", function() {\n var x = Ember.Object.createWithMixins(Ember.Enumerable, {\n contains: function() {\n return true;\n }\n });\n var y = x.without(Ember.K);\n equal(Ember.Array.detect(y), true, \"should have mixin applied\");\n});\n\ntest(\"should apply Ember.Array to return value of uniq\", function() {\n var x = Ember.Object.createWithMixins(Ember.Enumerable);\n var y = x.uniq(Ember.K);\n equal(Ember.Array.detect(y), true, \"should have mixin applied\");\n});\n\n\n\n// ..........................................................\n// CONTENT DID CHANGE\n//\n\nvar DummyEnum = Ember.Object.extend(Ember.Enumerable, {\n nextObject: function() {},\n length: 0\n});\n\nvar obj, observer;\n\n// ..........................................................\n// NOTIFY ENUMERABLE PROPERTY\n//\n\nmodule('mixins/enumerable/enumerableContentDidChange');\n\ntest('should notify observers of []', function() {\n\n var obj = Ember.Object.createWithMixins(Ember.Enumerable, {\n nextObject: function() {}, // avoid exceptions\n\n _count: 0,\n enumerablePropertyDidChange: Ember.observer('[]', function() {\n this._count++;\n })\n });\n\n equal(obj._count, 0, 'should not have invoked yet');\n obj.enumerableContentWillChange();\n obj.enumerableContentDidChange();\n equal(obj._count, 1, 'should have invoked');\n\n});\n\n// ..........................................................\n// NOTIFY CHANGES TO LENGTH\n//\n\nmodule('notify observers of length', {\n setup: function() {\n obj = DummyEnum.createWithMixins({\n _after: 0,\n lengthDidChange: Ember.observer('length', function() {\n this._after++;\n })\n\n });\n\n equal(obj._after, 0, 'should not have fired yet');\n },\n\n teardown: function() {\n obj = null;\n }\n});\n\ntest('should notify observers when call with no params', function() {\n obj.enumerableContentWillChange();\n equal(obj._after, 0);\n\n obj.enumerableContentDidChange();\n equal(obj._after, 1);\n});\n\n// API variation that included items only\ntest('should not notify when passed arrays of same length', function() {\n var added = ['foo'], removed = ['bar'];\n obj.enumerableContentWillChange(removed, added);\n equal(obj._after, 0);\n\n obj.enumerableContentDidChange(removed, added);\n equal(obj._after, 0);\n});\n\ntest('should notify when passed arrays of different length', function() {\n var added = ['foo'], removed = ['bar', 'baz'];\n obj.enumerableContentWillChange(removed, added);\n equal(obj._after, 0);\n\n obj.enumerableContentDidChange(removed, added);\n equal(obj._after, 1);\n});\n\n// API variation passes indexes only\ntest('should not notify when passed with indexes', function() {\n obj.enumerableContentWillChange(1, 1);\n equal(obj._after, 0);\n\n obj.enumerableContentDidChange(1, 1);\n equal(obj._after, 0);\n});\n\ntest('should notify when passed old index API with delta', function() {\n obj.enumerableContentWillChange(1, 2);\n equal(obj._after, 0);\n\n obj.enumerableContentDidChange(1, 2);\n equal(obj._after, 1);\n});\n\n\n// ..........................................................\n// NOTIFY ENUMERABLE OBSERVER\n//\n\nmodule('notify enumerable observers', {\n setup: function() {\n obj = DummyEnum.create();\n\n observer = Ember.Object.createWithMixins({\n _before: null,\n _after: null,\n\n enumerableWillChange: function() {\n equal(this._before, null); // should only call once\n this._before = Array.prototype.slice.call(arguments);\n },\n\n enumerableDidChange: function() {\n equal(this._after, null); // should only call once\n this._after = Array.prototype.slice.call(arguments);\n }\n });\n\n obj.addEnumerableObserver(observer);\n },\n\n teardown: function() {\n obj = observer = null;\n }\n});\n\ntest('should notify enumerable observers when called with no params', function() {\n obj.enumerableContentWillChange();\n deepEqual(observer._before, [obj, null, null]);\n\n obj.enumerableContentDidChange();\n deepEqual(observer._after, [obj, null, null]);\n});\n\n// API variation that included items only\ntest('should notify when called with same length items', function() {\n var added = ['foo'], removed = ['bar'];\n obj.enumerableContentWillChange(removed, added);\n deepEqual(observer._before, [obj, removed, added]);\n\n obj.enumerableContentDidChange(removed, added);\n deepEqual(observer._after, [obj, removed, added]);\n});\n\ntest('should notify when called with diff length items', function() {\n var added = ['foo', 'baz'], removed = ['bar'];\n obj.enumerableContentWillChange(removed, added);\n deepEqual(observer._before, [obj, removed, added]);\n\n obj.enumerableContentDidChange(removed, added);\n deepEqual(observer._after, [obj, removed, added]);\n});\n\ntest('should not notify when passed with indexes only', function() {\n obj.enumerableContentWillChange(1, 2);\n deepEqual(observer._before, [obj, 1, 2]);\n\n obj.enumerableContentDidChange(1, 2);\n deepEqual(observer._after, [obj, 1, 2]);\n});\n\ntest('removing enumerable observer should disable', function() {\n obj.removeEnumerableObserver(observer);\n obj.enumerableContentWillChange();\n deepEqual(observer._before, null);\n\n obj.enumerableContentDidChange();\n deepEqual(observer._after, null);\n});\n\n\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/enumerable_test");minispade.register('ember-runtime/~tests/mixins/mutable_array_test', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\n/*\n Implement a basic fake mutable array. This validates that any non-native\n enumerable can impl this API.\n*/\nvar TestMutableArray = Ember.Object.extend(Ember.MutableArray, {\n\n _content: null,\n\n init: function(ary) {\n this._content = Ember.A(ary || []);\n },\n\n replace: function(idx, amt, objects) {\n\n var args = objects ? objects.slice() : [],\n removeAmt = amt,\n addAmt = args.length;\n\n this.arrayContentWillChange(idx, removeAmt, addAmt);\n\n args.unshift(amt);\n args.unshift(idx);\n this._content.splice.apply(this._content, args);\n this.arrayContentDidChange(idx, removeAmt, addAmt);\n return this;\n },\n\n objectAt: function(idx) {\n return this._content[idx];\n },\n\n length: Ember.computed(function() {\n return this._content.length;\n }),\n\n slice: function() {\n return this._content.slice();\n }\n\n});\n\n\nEmber.MutableArrayTests.extend({\n\n name: 'Basic Mutable Array',\n\n newObject: function(ary) {\n ary = ary ? ary.slice() : this.newFixture(3);\n return new TestMutableArray(ary);\n },\n\n // allows for testing of the basic enumerable after an internal mutation\n mutate: function(obj) {\n obj.addObject(this.getFixture(1)[0]);\n },\n\n toArray: function(obj) {\n return obj.slice();\n }\n\n}).run();\n\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/mutable_array_test");minispade.register('ember-runtime/~tests/mixins/mutable_enumerable_test', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_enumerable');\n\nvar indexOf = Ember.EnumerableUtils.indexOf;\n\n/*\n Implement a basic fake mutable array. This validates that any non-native\n enumerable can impl this API.\n*/\nvar TestMutableEnumerable = Ember.Object.extend(Ember.MutableEnumerable, {\n\n _content: null,\n\n addObject: function(obj) {\n if (indexOf(this._content, obj)>=0) return this;\n this.enumerableContentWillChange(null, [obj]);\n this._content.push(obj);\n this.enumerableContentDidChange(null, [obj]);\n },\n\n removeObject: function(obj) {\n var idx = indexOf(this._content, obj);\n if (idx<0) return this;\n\n this.enumerableContentWillChange([obj], null);\n this._content.splice(idx, 1);\n this.enumerableContentDidChange([obj], null);\n return this;\n },\n\n init: function(ary) {\n this._content = ary || [];\n },\n\n nextObject: function(idx) {\n return idx>=Ember.get(this, 'length') ? undefined : this._content[idx];\n },\n\n length: Ember.computed(function() {\n return this._content.length;\n }),\n\n slice: function() {\n return this._content.slice();\n }\n});\n\n\nEmber.MutableEnumerableTests.extend({\n\n name: 'Basic Mutable Array',\n\n newObject: function(ary) {\n ary = ary ? ary.slice() : this.newFixture(3);\n return new TestMutableEnumerable(ary);\n },\n\n // allows for testing of the basic enumerable after an internal mutation\n mutate: function(obj) {\n obj.addObject(this.getFixture(1)[0]);\n },\n\n toArray: function(obj) {\n return obj.slice();\n }\n\n}).run();\n\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/mutable_enumerable_test");minispade.register('ember-runtime/~tests/mixins/observable_test', "(function() {module('mixins/observable');\n\ntest('should be able to use getProperties to get a POJO of provided keys', function() {\n var obj = Ember.Object.create({\n firstName: \"Steve\",\n lastName: \"Jobs\",\n companyName: \"Apple, Inc.\"\n });\n\n var pojo = obj.getProperties(\"firstName\", \"lastName\");\n equal(\"Steve\", pojo.firstName);\n equal(\"Jobs\", pojo.lastName);\n});\n\ntest('should be able to use getProperties with array parameter to get a POJO of provided keys', function() {\n var obj = Ember.Object.create({\n firstName: \"Steve\",\n lastName: \"Jobs\",\n companyName: \"Apple, Inc.\"\n });\n\n var pojo = obj.getProperties([\"firstName\", \"lastName\"]);\n equal(\"Steve\", pojo.firstName);\n equal(\"Jobs\", pojo.lastName);\n});\n\ntest('should be able to use setProperties to set multiple properties at once', function() {\n var obj = Ember.Object.create({\n firstName: \"Steve\",\n lastName: \"Jobs\",\n companyName: \"Apple, Inc.\"\n });\n\n obj.setProperties({firstName: \"Tim\", lastName: \"Cook\"});\n equal(\"Tim\", obj.get(\"firstName\"));\n equal(\"Cook\", obj.get(\"lastName\"));\n});\n\ntestBoth('calling setProperties completes safely despite exceptions', function(get,set) {\n var exc = new Error(\"Something unexpected happened!\");\n var obj = Ember.Object.createWithMixins({\n firstName: \"Steve\",\n lastName: \"Jobs\",\n companyName: Ember.computed(function(key, value) {\n if (value !== undefined) {\n throw exc;\n }\n return \"Apple, Inc.\";\n })\n });\n\n var firstNameChangedCount = 0;\n\n Ember.addObserver(obj, 'firstName', function() { firstNameChangedCount++; });\n\n try {\n obj.setProperties({\n firstName: 'Tim',\n lastName: 'Cook',\n companyName: 'Fruit Co., Inc.'\n });\n } catch(err) {\n if (err !== exc) {\n throw err;\n }\n }\n\n equal(firstNameChangedCount, 1, 'firstName should have fired once');\n});\n\ntestBoth(\"should be able to retrieve cached values of computed properties without invoking the computed property\", function(get) {\n var obj = Ember.Object.createWithMixins({\n foo: Ember.computed(function() {\n return \"foo\";\n }),\n\n bar: \"bar\"\n });\n\n equal(obj.cacheFor('foo'), undefined, \"should return undefined if no value has been cached\");\n get(obj, 'foo');\n\n equal(get(obj, 'foo'), \"foo\", \"precond - should cache the value\");\n equal(obj.cacheFor('foo'), \"foo\", \"should return the cached value after it is invoked\");\n\n equal(obj.cacheFor('bar'), undefined, \"returns undefined if the value is not a computed property\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/observable_test");minispade.register('ember-runtime/~tests/mixins/promise_proxy_test', "(function() {var proxy, deferred, ObjectPromiseProxy;\nvar get = Ember.get;\nvar originalRethrow = Ember.RSVP.rethrow;\nmodule(\"Ember.PromiseProxyMixin\", {\n teardown: function() {\n Ember.RSVP.rethrow = originalRethrow;\n }\n});\n\ntest(\"present on ember namespace\", function(){\n ok(Ember.PromiseProxyMixin, \"expected Ember.PromiseProxyMixin to exist\");\n});\n\nmodule(\"Ember.PromiseProxy - ObjectProxy\", {\n setup: function() {\n ObjectPromiseProxy = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin);\n deferred = Ember.RSVP.defer();\n proxy = ObjectPromiseProxy.create({\n promise: deferred.promise\n });\n },\n teardown: function() {\n proxy = deferred = null;\n }\n});\n\ntest(\"no promise, invoking then should raise\", function(){\n var value = {\n firstName: 'stef',\n lastName: 'penner'\n };\n\n var proxy = ObjectPromiseProxy.create();\n\n raises(function(){\n proxy.then(Ember.K, Ember.K);\n }, new RegExp(\"PromiseProxy's promise must be set\"));\n});\n\ntest(\"fulfillment\", function(){\n var value = {\n firstName: 'stef',\n lastName: 'penner'\n };\n\n var proxy = ObjectPromiseProxy.create({\n promise: deferred.promise\n });\n\n var didFulfillCount = 0;\n var didRejectCount = 0;\n\n proxy.then(function(){\n didFulfillCount++;\n }, function(){\n didRejectCount++;\n });\n\n equal(get(proxy, 'content'), undefined, 'expects the proxy to have no content');\n equal(get(proxy, 'reason'), undefined, 'expects the proxy to have no reason');\n equal(get(proxy, 'isPending'), true, 'expects the proxy to indicate that it is loading');\n equal(get(proxy, 'isSettled'), false, 'expects the proxy to indicate that it is not settled');\n equal(get(proxy, 'isRejected'), false, 'expects the proxy to indicate that it is not rejected');\n equal(get(proxy, 'isFulfilled'), false, 'expects the proxy to indicate that it is not fulfilled');\n\n equal(didFulfillCount, 0, 'should not yet have been fulfilled');\n equal(didRejectCount, 0, 'should not yet have been rejected');\n\n Ember.run(deferred, 'resolve', value);\n\n equal(didFulfillCount, 1, 'should have been fulfilled');\n equal(didRejectCount, 0, 'should not have been rejected');\n\n equal(get(proxy, 'content'), value, 'expects the proxy to have content');\n equal(get(proxy, 'reason'), undefined, 'expects the proxy to still have no reason');\n equal(get(proxy, 'isPending'), false, 'expects the proxy to indicate that it is no longer loading');\n equal(get(proxy, 'isSettled'), true, 'expects the proxy to indicate that it is settled');\n equal(get(proxy, 'isRejected'), false, 'expects the proxy to indicate that it is not rejected');\n equal(get(proxy, 'isFulfilled'), true, 'expects the proxy to indicate that it is fulfilled');\n\n Ember.run(deferred, 'resolve', value);\n\n equal(didFulfillCount, 1, 'should still have been only fulfilled once');\n equal(didRejectCount, 0, 'should still not have been rejected');\n\n Ember.run(deferred, 'reject', value);\n\n equal(didFulfillCount, 1, 'should still have been only fulfilled once');\n equal(didRejectCount, 0, 'should still not have been rejected');\n\n equal(get(proxy, 'content'), value, 'expects the proxy to have still have same content');\n equal(get(proxy, 'reason'), undefined, 'expects the proxy still to have no reason');\n equal(get(proxy, 'isPending'), false, 'expects the proxy to indicate that it is no longer loading');\n equal(get(proxy, 'isSettled'), true, 'expects the proxy to indicate that it is settled');\n equal(get(proxy, 'isRejected'), false, 'expects the proxy to indicate that it is not rejected');\n equal(get(proxy, 'isFulfilled'), true, 'expects the proxy to indicate that it is fulfilled');\n\n // rest of the promise semantics are tested in directly in RSVP\n});\n\ntest(\"rejection\", function(){\n var reason = new Error(\"failure\");\n\n var proxy = ObjectPromiseProxy.create({\n promise: deferred.promise\n });\n\n var didFulfillCount = 0;\n var didRejectCount = 0;\n\n proxy.then(function(){\n didFulfillCount++;\n }, function(){\n didRejectCount++;\n });\n\n equal(get(proxy, 'content'), undefined, 'expects the proxy to have no content');\n equal(get(proxy, 'reason'), undefined, 'expects the proxy to have no reason');\n equal(get(proxy, 'isPending'), true, 'expects the proxy to indicate that it is loading');\n equal(get(proxy, 'isSettled'), false, 'expects the proxy to indicate that it is not settled');\n equal(get(proxy, 'isRejected'), false, 'expects the proxy to indicate that it is not rejected');\n equal(get(proxy, 'isFulfilled'), false, 'expects the proxy to indicate that it is not fulfilled');\n\n equal(didFulfillCount, 0, 'should not yet have been fulfilled');\n equal(didRejectCount, 0, 'should not yet have been rejected');\n\n Ember.run(deferred, 'reject', reason);\n\n equal(didFulfillCount, 0, 'should not yet have been fulfilled');\n equal(didRejectCount, 1, 'should have been rejected');\n\n equal(get(proxy, 'content'), undefined, 'expects the proxy to have no content');\n equal(get(proxy, 'reason'), reason, 'expects the proxy to have a reason');\n equal(get(proxy, 'isPending'), false, 'expects the proxy to indicate that it is not longer loading');\n equal(get(proxy, 'isSettled'), true, 'expects the proxy to indicate that it is settled');\n equal(get(proxy, 'isRejected'), true, 'expects the proxy to indicate that it is rejected');\n equal(get(proxy, 'isFulfilled'), false, 'expects the proxy to indicate that it is not fulfilled');\n\n Ember.run(deferred, 'reject', reason);\n\n equal(didFulfillCount, 0, 'should stll not yet have been fulfilled');\n equal(didRejectCount, 1, 'should still remain rejected');\n\n Ember.run(deferred, 'resolve', 1);\n\n equal(didFulfillCount, 0, 'should stll not yet have been fulfilled');\n equal(didRejectCount, 1, 'should still remain rejected');\n\n equal(get(proxy, 'content'), undefined, 'expects the proxy to have no content');\n equal(get(proxy, 'reason'), reason, 'expects the proxy to have a reason');\n equal(get(proxy, 'isPending'), false, 'expects the proxy to indicate that it is not longer loading');\n equal(get(proxy, 'isSettled'), true, 'expects the proxy to indicate that it is settled');\n equal(get(proxy, 'isRejected'), true, 'expects the proxy to indicate that it is rejected');\n equal(get(proxy, 'isFulfilled'), false, 'expects the proxy to indicate that it is not fulfilled');\n});\n\ntest(\"unhandled rejects still propogate to RSVP.configure('onerror', ...) \", function(){\n expect(2);\n\n var expectedReason = new Error(\"failure\");\n var deferred = Ember.RSVP.defer();\n\n var proxy = ObjectPromiseProxy.create({\n promise: deferred.promise\n });\n\n var promise = proxy.get('promise');\n // # internal promise behaviour, not to be used elsewhere..\n equal(1, promise._promiseCallbacks.error.length, '1 error handler should be subscirbed');\n promise.on('error', function(reason) {\n equal(reason.detail, expectedReason, 'expected reason');\n });\n // / internal promise behaviour, not to be used elsewhere..\n\n // force synchronous promise rejection\n Ember.run(deferred, 'reject', expectedReason);\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/promise_proxy_test");minispade.register('ember-runtime/~tests/mixins/sortable_test', "(function() {var get = Ember.get, set = Ember.set;\n\nvar unsortedArray, sortedArrayController;\n\nmodule(\"Ember.Sortable\");\n\nmodule(\"Ember.Sortable with content\", {\n setup: function() {\n Ember.run(function() {\n var array = [{ id: 1, name: \"Scumbag Dale\" }, { id: 2, name: \"Scumbag Katz\" }, { id: 3, name: \"Scumbag Bryn\" }];\n\n unsortedArray = Ember.A(Ember.A(array).copy());\n\n sortedArrayController = Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, {\n content: unsortedArray\n });\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n sortedArrayController.set('content', null);\n sortedArrayController.destroy();\n });\n }\n});\n\ntest(\"if you do not specify `sortProperties` sortable have no effect\", function() {\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n equal(sortedArrayController.objectAt(0).name, 'Scumbag Dale', 'array is in it natural order');\n\n unsortedArray.pushObject({id: 4, name: 'Scumbag Chavard'});\n\n equal(sortedArrayController.get('length'), 4, 'array has 4 items');\n equal(sortedArrayController.objectAt(3).name, 'Scumbag Chavard', 'a new object was inserted in the natural order');\n});\n\ntest(\"you can change sorted properties\", function() {\n sortedArrayController.set('sortProperties', ['id']);\n\n equal(sortedArrayController.objectAt(0).name, 'Scumbag Dale', 'array is sorted by id');\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n\n sortedArrayController.set('sortAscending', false);\n\n equal(sortedArrayController.objectAt(0).name, 'Scumbag Bryn', 'array is sorted by id in DESC order');\n equal(sortedArrayController.objectAt(2).name, 'Scumbag Dale', 'array is sorted by id in DESC order');\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n\n sortedArrayController.set('sortProperties', ['name']);\n\n equal(sortedArrayController.objectAt(0).name, 'Scumbag Katz', 'array is sorted by name in DESC order');\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n});\n\ntest(\"changing sort order triggers observers\", function() {\n var observer, changeCount = 0;\n observer = Ember.Object.createWithMixins({\n array: sortedArrayController,\n arrangedDidChange: Ember.observer('array.[]', function() {\n changeCount++;\n })\n });\n\n equal(changeCount, 0, 'precond - changeCount starts at 0');\n\n sortedArrayController.set('sortProperties', ['id']);\n\n equal(changeCount, 1, 'setting sortProperties increments changeCount');\n\n sortedArrayController.set('sortAscending', false);\n\n equal(changeCount, 2, 'changing sortAscending increments changeCount');\n\n sortedArrayController.set('sortAscending', true);\n\n equal(changeCount, 3, 'changing sortAscending again increments changeCount');\n\n Ember.run(function() { observer.destroy(); });\n});\n\nmodule(\"Ember.Sortable with content and sortProperties\", {\n setup: function() {\n Ember.run(function() {\n var array = [{ id: 1, name: \"Scumbag Dale\" }, { id: 2, name: \"Scumbag Katz\" }, { id: 3, name: \"Scumbag Bryn\" }];\n\n unsortedArray = Ember.A(Ember.A(array).copy());\n\n sortedArrayController = Ember.ArrayController.create({\n content: unsortedArray,\n sortProperties: ['name']\n });\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n sortedArrayController.destroy();\n });\n }\n});\n\ntest(\"sortable object will expose associated content in the right order\", function() {\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n equal(sortedArrayController.objectAt(0).name, 'Scumbag Bryn', 'array is sorted by name');\n});\n\ntest(\"you can add objects in sorted order\", function() {\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n\n unsortedArray.pushObject({id: 4, name: 'Scumbag Chavard'});\n\n equal(sortedArrayController.get('length'), 4, 'array has 4 items');\n equal(sortedArrayController.objectAt(1).name, 'Scumbag Chavard', 'a new object added to content was inserted according to given constraint');\n\n sortedArrayController.addObject({id: 5, name: 'Scumbag Fucs'});\n\n equal(sortedArrayController.get('length'), 5, 'array has 5 items');\n equal(sortedArrayController.objectAt(3).name, 'Scumbag Fucs', 'a new object added to controller was inserted according to given constraint');\n});\n\ntest(\"you can push objects in sorted order\", function() {\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n\n unsortedArray.pushObject({id: 4, name: 'Scumbag Chavard'});\n\n equal(sortedArrayController.get('length'), 4, 'array has 4 items');\n equal(sortedArrayController.objectAt(1).name, 'Scumbag Chavard', 'a new object added to content was inserted according to given constraint');\n\n sortedArrayController.pushObject({id: 5, name: 'Scumbag Fucs'});\n\n equal(sortedArrayController.get('length'), 5, 'array has 5 items');\n equal(sortedArrayController.objectAt(3).name, 'Scumbag Fucs', 'a new object added to controller was inserted according to given constraint');\n});\n\ntest(\"you can unshift objects in sorted order\", function() {\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n\n unsortedArray.unshiftObject({id: 4, name: 'Scumbag Chavard'});\n\n equal(sortedArrayController.get('length'), 4, 'array has 4 items');\n equal(sortedArrayController.objectAt(1).name, 'Scumbag Chavard', 'a new object added to content was inserted according to given constraint');\n\n sortedArrayController.addObject({id: 5, name: 'Scumbag Fucs'});\n\n equal(sortedArrayController.get('length'), 5, 'array has 5 items');\n equal(sortedArrayController.objectAt(3).name, 'Scumbag Fucs', 'a new object added to controller was inserted according to given constraint');\n});\n\ntest(\"addObject does not insert duplicates\", function() {\n var sortedArrayProxy, obj = {};\n sortedArrayProxy = Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, {\n content: Ember.A([obj])\n });\n\n equal(sortedArrayProxy.get('length'), 1, 'array has 1 item');\n\n sortedArrayProxy.addObject(obj);\n\n equal(sortedArrayProxy.get('length'), 1, 'array still has 1 item');\n});\n\ntest(\"you can change a sort property and the content will rearrenge\", function() {\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n equal(sortedArrayController.objectAt(0).name, 'Scumbag Bryn', 'bryn is first');\n\n set(sortedArrayController.objectAt(0), 'name', 'Scumbag Fucs');\n equal(sortedArrayController.objectAt(0).name, 'Scumbag Dale', 'dale is first now');\n equal(sortedArrayController.objectAt(1).name, 'Scumbag Fucs', 'foucs is second');\n});\n\ntest(\"you can change the position of the middle item\", function() {\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n\n equal(sortedArrayController.objectAt(1).name, 'Scumbag Dale', 'Dale is second');\n set(sortedArrayController.objectAt(1), 'name', 'Alice'); // Change Dale to Alice\n\n equal(sortedArrayController.objectAt(0).name, 'Alice', 'Alice (previously Dale) is first now');\n});\n\ntest(\"don't remove and insert if position didn't change\", function() {\n var insertItemSortedCalled = false;\n\n sortedArrayController.reopen({\n insertItemSorted: function(item) {\n insertItemSortedCalled = true;\n this._super(item);\n }\n });\n\n sortedArrayController.set('sortProperties', ['name']);\n\n Ember.set(sortedArrayController.objectAt(0), 'name', 'Scumbag Brynjolfsson');\n\n ok(!insertItemSortedCalled, \"insertItemSorted should not have been called\");\n});\n\ntest(\"sortProperties observers removed on content removal\", function() {\n var removedObject = unsortedArray.objectAt(2);\n equal(Ember.listenersFor(removedObject, 'name:change').length, 1,\n \"Before removal, there should be one listener for sortProperty change.\");\n unsortedArray.replace(2, 1, []);\n equal(Ember.listenersFor(removedObject, 'name:change').length, 0,\n \"After removal, there should be no listeners for sortProperty change.\");\n});\n\nmodule(\"Ember.Sortable with sortProperties\", {\n setup: function() {\n Ember.run(function() {\n sortedArrayController = Ember.ArrayController.create({\n sortProperties: ['name']\n });\n var array = [{ id: 1, name: \"Scumbag Dale\" }, { id: 2, name: \"Scumbag Katz\" }, { id: 3, name: \"Scumbag Bryn\" }];\n unsortedArray = Ember.A(Ember.A(array).copy());\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n sortedArrayController.destroy();\n });\n }\n});\n\ntest(\"you can set content later and it will be sorted\", function() {\n equal(sortedArrayController.get('length'), 0, 'array has 0 items');\n\n Ember.run(function() {\n sortedArrayController.set('content', unsortedArray);\n });\n\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n equal(sortedArrayController.objectAt(0).name, 'Scumbag Bryn', 'array is sorted by name');\n});\n\nmodule(\"Ember.Sortable with sortFunction and sortProperties\", {\n setup: function() {\n Ember.run(function() {\n sortedArrayController = Ember.ArrayController.create({\n sortProperties: ['name'],\n sortFunction: function(v, w) {\n var lowerV = v.toLowerCase(),\n lowerW = w.toLowerCase();\n\n if (lowerV < lowerW) {\n return -1;\n }\n if (lowerV > lowerW) {\n return 1;\n }\n return 0;\n }\n });\n var array = [{ id: 1, name: \"Scumbag Dale\" },\n { id: 2, name: \"Scumbag Katz\" },\n { id: 3, name: \"Scumbag bryn\" }];\n unsortedArray = Ember.A(Ember.A(array).copy());\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n sortedArrayController.destroy();\n });\n }\n});\n\ntest(\"you can sort with custom sorting function\", function() {\n equal(sortedArrayController.get('length'), 0, 'array has 0 items');\n\n Ember.run(function() {\n sortedArrayController.set('content', unsortedArray);\n });\n\n equal(sortedArrayController.get('length'), 3, 'array has 3 items');\n equal(sortedArrayController.objectAt(0).name, 'Scumbag bryn', 'array is sorted by custom sort');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/sortable_test");minispade.register('ember-runtime/~tests/mixins/target_action_support_test', "(function() {/*global Test:true*/\n\nvar originalLookup;\n\nmodule(\"Ember.TargetActionSupport\", {\n setup: function() {\n originalLookup = Ember.lookup;\n },\n teardown: function() {\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"it should return false if no target or action are specified\", function() {\n expect(1);\n\n var obj = Ember.Object.createWithMixins(Ember.TargetActionSupport);\n\n ok(false === obj.triggerAction(), \"no target or action was specified\");\n});\n\ntest(\"it should support actions specified as strings\", function() {\n expect(2);\n\n var obj = Ember.Object.createWithMixins(Ember.TargetActionSupport, {\n target: Ember.Object.create({\n anEvent: function() {\n ok(true, \"anEvent method was called\");\n }\n }),\n\n action: 'anEvent'\n });\n\n ok(true === obj.triggerAction(), \"a valid target and action were specified\");\n});\n\ntest(\"it should invoke the send() method on objects that implement it\", function() {\n expect(3);\n\n var obj = Ember.Object.createWithMixins(Ember.TargetActionSupport, {\n target: Ember.Object.create({\n send: function(evt, context) {\n equal(evt, 'anEvent', \"send() method was invoked with correct event name\");\n equal(context, obj, \"send() method was invoked with correct context\");\n }\n }),\n\n action: 'anEvent'\n });\n\n ok(true === obj.triggerAction(), \"a valid target and action were specified\");\n});\n\ntest(\"it should find targets specified using a property path\", function() {\n expect(2);\n\n var Test = {};\n Ember.lookup = { Test: Test };\n\n Test.targetObj = Ember.Object.create({\n anEvent: function() {\n ok(true, \"anEvent method was called on global object\");\n }\n });\n\n var myObj = Ember.Object.createWithMixins(Ember.TargetActionSupport, {\n target: 'Test.targetObj',\n action: 'anEvent'\n });\n\n ok(true === myObj.triggerAction(), \"a valid target and action were specified\");\n});\n\ntest(\"it should use an actionContext object specified as a property on the object\", function() {\n expect(2);\n var obj = Ember.Object.createWithMixins(Ember.TargetActionSupport,{\n action: 'anEvent',\n actionContext: {},\n target: Ember.Object.create({\n anEvent: function(ctx) {\n ok(obj.actionContext === ctx, \"anEvent method was called with the expected context\");\n }\n })\n });\n ok(true === obj.triggerAction(), \"a valid target and action were specified\");\n});\n\ntest(\"it should find an actionContext specified as a property path\", function() {\n expect(2);\n\n var Test = {};\n Ember.lookup = { Test: Test };\n Test.aContext = {};\n\n var obj = Ember.Object.createWithMixins(Ember.TargetActionSupport,{\n action: 'anEvent',\n actionContext: 'Test.aContext',\n target: Ember.Object.create({\n anEvent: function(ctx) {\n ok(Test.aContext === ctx, \"anEvent method was called with the expected context\");\n }\n })\n });\n ok(true === obj.triggerAction(), \"a valid target and action were specified\");\n});\n\ntest(\"it should use the target specified in the argument\", function() {\n expect(2);\n var targetObj = Ember.Object.create({\n anEvent: function() {\n ok(true, \"anEvent method was called\");\n }\n }),\n obj = Ember.Object.createWithMixins(Ember.TargetActionSupport,{\n action: 'anEvent'\n });\n ok(true === obj.triggerAction({target: targetObj}), \"a valid target and action were specified\");\n});\n\ntest(\"it should use the action specified in the argument\", function() {\n expect(2);\n\n var obj = Ember.Object.createWithMixins(Ember.TargetActionSupport,{\n target: Ember.Object.create({\n anEvent: function() {\n ok(true, \"anEvent method was called\");\n }\n })\n });\n ok(true === obj.triggerAction({action: 'anEvent'}), \"a valid target and action were specified\");\n});\n\ntest(\"it should use the actionContext specified in the argument\", function() {\n expect(2);\n var context = {},\n obj = Ember.Object.createWithMixins(Ember.TargetActionSupport,{\n target: Ember.Object.create({\n anEvent: function(ctx) {\n ok(context === ctx, \"anEvent method was called with the expected context\");\n }\n }),\n action: 'anEvent'\n });\n ok(true === obj.triggerAction({actionContext: context}), \"a valid target and action were specified\");\n});\n\ntest(\"it should allow multiple arguments from actionContext\", function() {\n expect(3);\n var param1 = 'someParam',\n param2 = 'someOtherParam',\n obj = Ember.Object.createWithMixins(Ember.TargetActionSupport,{\n target: Ember.Object.create({\n anEvent: function(first, second) {\n ok(first === param1, \"anEvent method was called with the expected first argument\");\n ok(second === param2, \"anEvent method was called with the expected second argument\");\n }\n }),\n action: 'anEvent'\n });\n ok(true === obj.triggerAction({actionContext: [param1, param2]}), \"a valid target and action were specified\");\n});\n\ntest(\"it should use a null value specified in the actionContext argument\", function() {\n expect(2);\n var obj = Ember.Object.createWithMixins(Ember.TargetActionSupport,{\n target: Ember.Object.create({\n anEvent: function(ctx) {\n ok(null === ctx, \"anEvent method was called with the expected context (null)\");\n }\n }),\n action: 'anEvent'\n });\n ok(true === obj.triggerAction({actionContext: null}), \"a valid target and action were specified\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/mixins/target_action_support_test");minispade.register('ember-runtime/~tests/props_helper', "(function() {// used by unit tests to test both accessor mode and non-accessor mode\ntestBoth = function(testname, callback) {\n\n function emberget(x,y) { return Ember.get(x,y); }\n function emberset(x,y,z) { return Ember.set(x,y,z); }\n function aget(x,y) { return x[y]; }\n function aset(x,y,z) { return (x[y] = z); }\n\n test(testname+' using Ember.get()/Ember.set()', function() {\n callback(emberget, emberset);\n });\n\n test(testname+' using accessors', function() {\n if (Ember.USES_ACCESSORS) callback(aget, aset);\n else ok('SKIPPING ACCESSORS');\n });\n};\n\ntestWithDefault = function(testname, callback) {\n function get(x,y) { return x.get(y); }\n function emberget(x,y) { return Ember.get(x,y); }\n function embergetwithdefault(x,y,z) { return Ember.getWithDefault(x,y,z); }\n function getwithdefault(x,y,z) { return x.getWithDefault(y,z); }\n function emberset(x,y,z) { return Ember.set(x,y,z); }\n function aget(x,y) { return x[y]; }\n function aset(x,y,z) { return (x[y] = z); }\n\n test(testname+' using obj.get()', function() {\n callback(emberget, emberset);\n });\n\n test(testname+' using obj.getWithDefault()', function() {\n callback(getwithdefault, emberset);\n });\n\n test(testname+' using Ember.get()', function() {\n callback(emberget, emberset);\n });\n\n test(testname+' using Ember.getWithDefault()', function() {\n callback(embergetwithdefault, emberset);\n });\n\n test(testname+' using accessors', function() {\n if (Ember.USES_ACCESSORS) callback(aget, aset);\n else ok('SKIPPING ACCESSORS');\n });\n};\n\n})();\n//@ sourceURL=ember-runtime/~tests/props_helper");minispade.register('ember-runtime/~tests/suites/array', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\n\n\nvar ObserverClass = Ember.EnumerableTests.ObserverClass.extend({\n\n observeArray: function(obj) {\n obj.addArrayObserver(this);\n return this;\n },\n\n stopObserveArray: function(obj) {\n obj.removeArrayObserver(this);\n return this;\n },\n\n arrayWillChange: function() {\n equal(this._before, null, 'should only call once');\n this._before = Array.prototype.slice.call(arguments);\n },\n\n arrayDidChange: function() {\n equal(this._after, null, 'should only call once');\n this._after = Array.prototype.slice.call(arguments);\n }\n\n});\n\nEmber.ArrayTests = Ember.EnumerableTests.extend({\n\n observerClass: ObserverClass\n\n});\n\nEmber.ArrayTests.ObserverClass = ObserverClass;\nminispade.require('ember-runtime/~tests/suites/array/indexOf');\nminispade.require('ember-runtime/~tests/suites/array/lastIndexOf');\nminispade.require('ember-runtime/~tests/suites/array/objectAt');\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/array");minispade.register('ember-runtime/~tests/suites/array/indexOf', "(function() {minispade.require('ember-runtime/~tests/suites/array');\n\nvar suite = Ember.ArrayTests;\n\nsuite.module('indexOf');\n\nsuite.test(\"should return index of object\", function() {\n var expected = this.newFixture(3),\n obj = this.newObject(expected),\n len = 3,\n idx;\n\n for(idx=0;idx=0) obj.addBeforeObserver(keys[loc], this, 'propertyWillChange');\n }\n return this;\n },\n\n /**\n Begins observing the passed key names on the passed object. Any changes\n on the named properties will be recorded.\n\n @param {Ember.Enumerable} obj\n The enumerable to observe.\n\n @returns {Object} receiver\n */\n observe: function(obj) {\n if (obj.addObserver) {\n var keys = Array.prototype.slice.call(arguments, 1),\n loc = keys.length;\n while(--loc>=0) obj.addObserver(keys[loc], this, 'propertyDidChange');\n } else {\n this.isEnabled = false;\n }\n return this;\n },\n\n /**\n Returns true if the passed key was invoked. If you pass a value as\n well then validates that the values match.\n\n @param {String} key\n Key to validate\n\n @param {Object} value\n (Optional) value\n\n @returns {Boolean}\n */\n validate: function(key, value) {\n if (!this.isEnabled) return true;\n if (!this._keys[key]) return false;\n if (arguments.length>1) return this._values[key] === value;\n else return true;\n },\n\n /**\n Returns times the before observer as invoked.\n\n @param {String} key\n Key to check\n */\n timesCalledBefore: function(key) {\n return this._keysBefore[key] || 0;\n },\n\n /**\n Returns times the observer as invoked.\n\n @param {String} key\n Key to check\n */\n timesCalled: function(key) {\n return this._keys[key] || 0;\n },\n\n /**\n begins acting as an enumerable observer.\n */\n observeEnumerable: function(obj) {\n obj.addEnumerableObserver(this);\n return this;\n },\n\n stopObserveEnumerable: function(obj) {\n obj.removeEnumerableObserver(this);\n return this;\n },\n\n enumerableWillChange: function() {\n equal(this._before, null, 'should only call once');\n this._before = Array.prototype.slice.call(arguments);\n },\n\n enumerableDidChange: function() {\n equal(this._after, null, 'should only call once');\n this._after = Array.prototype.slice.call(arguments);\n }\n\n});\n\n\n/**\n Defines a test suite that can be used to test any object for compliance\n with any enumerable. To use, extend this object and define the required\n methods to generate new object instances for testing, etc.\n\n You can also add your own tests by defining new methods beginning with the\n word 'test'\n*/\nvar EnumerableTests = Ember.Object.extend({\n\n /**\n Define a name for these tests - all modules are prefixed w/ it.\n\n @type String\n */\n name: Ember.required(String),\n\n /**\n Implement to return a new enumerable object for testing. Should accept\n either no parameters, a single number (indicating the desired length of\n the collection) or an array of objects.\n\n @param {Array} content\n An array of items to include in the enumerable optionally.\n\n @returns {Ember.Enumerable} a new enumerable\n */\n newObject: Ember.required(Function),\n\n /**\n Implement to return a set of new fixture objects that can be applied to\n the enumerable. This may be passed into the newObject method.\n\n @param {Number} count\n The number of items required.\n\n @returns {Array} array of items\n */\n newFixture: function(cnt) {\n var ret = [];\n while(--cnt>=0) ret.push(Ember.generateGuid());\n return ret;\n },\n\n /**\n Implement accept an instance of the enumerable and return an array\n containing the objects in the enumerable. This is used only for testing\n so performance is not important.\n\n @param {Ember.Enumerable} enumerable\n The enumerable to convert.\n\n @returns {Array} array of items\n */\n toArray: Ember.required(Function),\n\n /**\n Implement this method if your object can mutate internally (even if it\n does not support the MutableEnumerable API). The method should accept\n an object of your desired type and modify it somehow. Suite tests will\n use this to ensure that all appropriate caches, etc. clear when the\n mutation occurs.\n\n If you do not define this optional method, then mutation-related tests\n will be skipped.\n\n @param {Ember.Enumerable} enumerable\n The enumerable to mutate\n\n @returns {void}\n */\n mutate: function() {},\n\n /**\n Becomes true when you define a new mutate() method, indicating that\n mutation tests should run. This is calculated automatically.\n\n @type Boolean\n */\n canTestMutation: Ember.computed(function() {\n return this.mutate !== EnumerableTests.prototype.mutate;\n }),\n\n /**\n Invoked to actually run the test - overridden by mixins\n */\n run: function() {},\n\n\n /**\n Creates a new observer object for testing. You can add this object as an\n observer on an array and it will record results anytime it is invoked.\n After running the test, call the validate() method on the observer to\n validate the results.\n */\n newObserver: function(obj) {\n var ret = Ember.get(this, 'observerClass').create();\n if (arguments.length>0) ret.observeBefore.apply(ret, arguments);\n if (arguments.length>0) ret.observe.apply(ret, arguments);\n return ret;\n },\n\n observerClass: ObserverClass\n\n});\n\nEnumerableTests.reopenClass({\n\n plan: null,\n\n run: function() {\n var C = this;\n return new C().run();\n },\n\n module: function(desc, opts) {\n if (!opts) opts = {};\n var setup = opts.setup, teardown = opts.teardown;\n this.reopen({\n run: function() {\n this._super();\n var title = Ember.get(this,'name')+': '+desc, ctx = this;\n module(title, {\n setup: function() {\n if (setup) setup.call(ctx);\n },\n\n teardown: function() {\n if (teardown) teardown.call(ctx);\n }\n });\n }\n });\n },\n\n test: function(name, func) {\n this.reopen({\n run: function() {\n this._super();\n var ctx = this;\n if (!func) test(name); // output warning\n else test(name, function() { func.call(ctx); });\n }\n });\n },\n\n // convert to guids to minimize logging.\n same: function(actual, exp, message) {\n actual = (actual && actual.map) ? actual.map(function(x) { return Ember.guidFor(x); }) : actual;\n exp = (exp && exp.map) ? exp.map(function(x) { return Ember.guidFor(x); }) : exp;\n return deepEqual(actual, exp, message);\n },\n\n // easy way to disable tests\n notest: function() {}\n\n});\n\nEmber.EnumerableTests = EnumerableTests;\nEmber.EnumerableTests.ObserverClass = ObserverClass;\nminispade.require('ember-runtime/~tests/suites/enumerable/any');\nminispade.require('ember-runtime/~tests/suites/enumerable/compact');\nminispade.require('ember-runtime/~tests/suites/enumerable/contains');\nminispade.require('ember-runtime/~tests/suites/enumerable/every');\nminispade.require('ember-runtime/~tests/suites/enumerable/filter');\nminispade.require('ember-runtime/~tests/suites/enumerable/find');\nminispade.require('ember-runtime/~tests/suites/enumerable/firstObject');\nminispade.require('ember-runtime/~tests/suites/enumerable/forEach');\nminispade.require('ember-runtime/~tests/suites/enumerable/mapBy');\nminispade.require('ember-runtime/~tests/suites/enumerable/invoke');\nminispade.require('ember-runtime/~tests/suites/enumerable/lastObject');\nminispade.require('ember-runtime/~tests/suites/enumerable/map');\nminispade.require('ember-runtime/~tests/suites/enumerable/reduce');\nminispade.require('ember-runtime/~tests/suites/enumerable/reject');\nminispade.require('ember-runtime/~tests/suites/enumerable/sortBy');\nminispade.require('ember-runtime/~tests/suites/enumerable/toArray');\nminispade.require('ember-runtime/~tests/suites/enumerable/uniq');\nminispade.require('ember-runtime/~tests/suites/enumerable/without');\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable");minispade.register('ember-runtime/~tests/suites/enumerable/any', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\n// ..........................................................\n// any()\n//\n\nsuite.module('any');\n\nsuite.test('any should should invoke callback on each item as long as you return false', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n found = [], result;\n\n result = obj.any(function(i) { found.push(i); return false; });\n equal(result, false, 'return value of obj.any');\n deepEqual(found, ary, 'items passed during any() should match');\n});\n\nsuite.test('any should stop invoking when you return true', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n cnt = ary.length - 2,\n exp = cnt,\n found = [], result;\n\n result = obj.any(function(i) { found.push(i); return --cnt <= 0; });\n equal(result, true, 'return value of obj.any');\n equal(found.length, exp, 'should invoke proper number of times');\n deepEqual(found, ary.slice(0,-2), 'items passed during any() should match');\n});\n\nsuite.test('any should be aliased to some', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n anyFound = [], anyResult,\n someFound = [], someResult,\n cnt = ary.length - 2,\n exp = cnt;\n\n anyResult = obj.any(function(i) { anyFound.push(i); return false; });\n someResult = obj.some(function(i) { someFound.push(i); return false; });\n equal(someResult, anyResult);\n\n anyFound = [];\n someFound = [];\n\n cnt = ary.length - 2;\n anyResult = obj.any(function(i) { anyFound.push(i); return --cnt <= 0; });\n cnt = ary.length - 2;\n someResult = obj.some(function(i) { someFound.push(i); return --cnt <= 0; });\n\n equal(someResult, anyResult);\n});\n\n// ..........................................................\n// anyBy()\n//\n\nsuite.module('anyBy');\n\nsuite.test('should return true of any property matches', function() {\n var obj = this.newObject([\n { foo: 'foo', bar: 'BAZ' },\n Ember.Object.create({ foo: 'foo', bar: 'bar' })\n ]);\n\n equal(obj.anyBy('foo', 'foo'), true, 'anyBy(foo)');\n equal(obj.anyBy('bar', 'bar'), true, 'anyBy(bar)');\n equal(obj.anyBy('bar', 'BIFF'), false, 'anyBy(BIFF)');\n});\n\nsuite.test('should return true of any property is true', function() {\n var obj = this.newObject([\n { foo: 'foo', bar: true },\n Ember.Object.create({ foo: 'bar', bar: false })\n ]);\n\n // different values - all eval to true\n equal(obj.anyBy('foo'), true, 'anyBy(foo)');\n equal(obj.anyBy('bar'), true, 'anyBy(bar)');\n equal(obj.anyBy('BIFF'), false, 'anyBy(biff)');\n});\n\nsuite.test('should return true if any property matches null', function() {\n var obj = this.newObject([\n { foo: null, bar: 'bar' },\n Ember.Object.create({ foo: 'foo', bar: null })\n ]);\n\n equal(obj.anyBy('foo', null), true, \"anyBy('foo', null)\");\n equal(obj.anyBy('bar', null), true, \"anyBy('bar', null)\");\n});\n\nsuite.test('should return true if any property is undefined', function() {\n var obj = this.newObject([\n { foo: undefined, bar: 'bar' },\n Ember.Object.create({ foo: 'foo' })\n ]);\n\n equal(obj.anyBy('foo', undefined), true, \"anyBy('foo', undefined)\");\n equal(obj.anyBy('bar', undefined), true, \"anyBy('bar', undefined)\");\n});\n\nsuite.test('should not match undefined properties without second argument', function() {\n var obj = this.newObject([\n { foo: undefined },\n Ember.Object.create({ })\n ]);\n\n equal(obj.anyBy('foo'), false, \"anyBy('foo', undefined)\");\n});\n\nsuite.test('anyBy should be aliased to someProperty', function() {\n var obj = this.newObject();\n equal(obj.someProperty, obj.anyBy);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/any");minispade.register('ember-runtime/~tests/suites/enumerable/compact', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\nsuite.module('compact');\n\nsuite.test('removes null and undefined values from enumerable', function() {\n var obj = this.newObject([null, 1, false, '', undefined, 0, null]);\n var ary = obj.compact();\n deepEqual(ary, [1, false, '', 0]);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/compact");minispade.register('ember-runtime/~tests/suites/enumerable/contains', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\nsuite.module('contains');\n\nsuite.test('contains returns true if items is in enumerable', function() {\n var data = this.newFixture(3);\n var obj = this.newObject(data);\n equal(obj.contains(data[1]), true, 'should return true if contained');\n});\n\nsuite.test('contains returns false if item is not in enumerable', function() {\n var data = this.newFixture(1);\n var obj = this.newObject(this.newFixture(3));\n equal(obj.contains(data[0]), false, 'should return false if not contained');\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/contains");minispade.register('ember-runtime/~tests/suites/enumerable/every', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\n// ..........................................................\n// every()\n//\n\nsuite.module('every');\n\nsuite.test('every should should invoke callback on each item as long as you return true', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n found = [], result;\n\n result = obj.every(function(i) { found.push(i); return true; });\n equal(result, true, 'return value of obj.every');\n deepEqual(found, ary, 'items passed during every() should match');\n});\n\nsuite.test('every should stop invoking when you return false', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n cnt = ary.length - 2,\n exp = cnt,\n found = [], result;\n\n result = obj.every(function(i) { found.push(i); return --cnt>0; });\n equal(result, false, 'return value of obj.every');\n equal(found.length, exp, 'should invoke proper number of times');\n deepEqual(found, ary.slice(0,-2), 'items passed during every() should match');\n});\n\n// ..........................................................\n// everyBy()\n//\n\nsuite.module('everyBy');\n\nsuite.test('should return true of every property matches', function() {\n var obj = this.newObject([\n { foo: 'foo', bar: 'BAZ' },\n Ember.Object.create({ foo: 'foo', bar: 'bar' })\n ]);\n\n equal(obj.everyBy('foo', 'foo'), true, 'everyBy(foo)');\n equal(obj.everyBy('bar', 'bar'), false, 'everyBy(bar)');\n});\n\nsuite.test('should return true of every property is true', function() {\n var obj = this.newObject([\n { foo: 'foo', bar: true },\n Ember.Object.create({ foo: 'bar', bar: false })\n ]);\n\n // different values - all eval to true\n equal(obj.everyBy('foo'), true, 'everyBy(foo)');\n equal(obj.everyBy('bar'), false, 'everyBy(bar)');\n});\n\nsuite.test('should return true if every property matches null', function() {\n var obj = this.newObject([\n { foo: null, bar: 'BAZ' },\n Ember.Object.create({ foo: null, bar: null })\n ]);\n\n equal(obj.everyBy('foo', null), true, \"everyBy('foo', null)\");\n equal(obj.everyBy('bar', null), false, \"everyBy('bar', null)\");\n});\n\nsuite.test('should return true if every property is undefined', function() {\n var obj = this.newObject([\n { foo: undefined, bar: 'BAZ' },\n Ember.Object.create({ bar: undefined })\n ]);\n\n equal(obj.everyBy('foo', undefined), true, \"everyBy('foo', undefined)\");\n equal(obj.everyBy('bar', undefined), false, \"everyBy('bar', undefined)\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/every");minispade.register('ember-runtime/~tests/suites/enumerable/filter', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\n// ..........................................................\n// filter()\n//\n\nsuite.module('filter');\n\nsuite.test('filter should invoke on each item', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n cnt = ary.length - 2,\n found = [], result;\n\n // return true on all but the last two\n result = obj.filter(function(i) { found.push(i); return --cnt>=0; });\n deepEqual(found, ary, 'should have invoked on each item');\n deepEqual(result, ary.slice(0,-2), 'filtered array should exclude items');\n});\n\n// ..........................................................\n// filterBy()\n//\n\nsuite.module('filterBy');\n\nsuite.test('should filter based on object', function() {\n var obj, ary;\n\n ary = [\n { foo: 'foo', bar: 'BAZ' },\n Ember.Object.create({ foo: 'foo', bar: 'bar' })\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.filterBy('foo', 'foo'), ary, 'filterBy(foo)');\n deepEqual(obj.filterBy('bar', 'bar'), [ary[1]], 'filterBy(bar)');\n});\n\nsuite.test('should include in result if property is true', function() {\n var obj, ary;\n\n ary = [\n { foo: 'foo', bar: true },\n Ember.Object.create({ foo: 'bar', bar: false })\n ];\n\n obj = this.newObject(ary);\n\n // different values - all eval to true\n deepEqual(obj.filterBy('foo'), ary, 'filterBy(foo)');\n deepEqual(obj.filterBy('bar'), [ary[0]], 'filterBy(bar)');\n});\n\nsuite.test('should filter on second argument if provided', function() {\n var obj, ary;\n\n ary = [\n { name: 'obj1', foo: 3},\n Ember.Object.create({ name: 'obj2', foo: 2}),\n { name: 'obj3', foo: 2},\n Ember.Object.create({ name: 'obj4', foo: 3})\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.filterBy('foo', 3), [ary[0], ary[3]], \"filterBy('foo', 3)')\");\n});\n\nsuite.test('should correctly filter null second argument', function() {\n var obj, ary;\n\n ary = [\n { name: 'obj1', foo: 3},\n Ember.Object.create({ name: 'obj2', foo: null}),\n { name: 'obj3', foo: null},\n Ember.Object.create({ name: 'obj4', foo: 3})\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.filterBy('foo', null), [ary[1], ary[2]], \"filterBy('foo', 3)')\");\n});\n\nsuite.test('should not return all objects on undefined second argument', function() {\n var obj, ary;\n\n ary = [\n { name: 'obj1', foo: 3},\n Ember.Object.create({ name: 'obj2', foo: 2})\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.filterBy('foo', undefined), [], \"filterBy('foo', 3)')\");\n});\n\nsuite.test('should correctly filter explicit undefined second argument', function() {\n var obj, ary;\n\n ary = [\n { name: 'obj1', foo: 3},\n Ember.Object.create({ name: 'obj2', foo: 3}),\n { name: 'obj3', foo: undefined},\n Ember.Object.create({ name: 'obj4', foo: undefined}),\n { name: 'obj5'},\n Ember.Object.create({ name: 'obj6'})\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.filterBy('foo', undefined), ary.slice(2), \"filterBy('foo', 3)')\");\n});\n\nsuite.test('should not match undefined properties without second argument', function() {\n var obj, ary;\n\n ary = [\n { name: 'obj1', foo: 3},\n Ember.Object.create({ name: 'obj2', foo: 3}),\n { name: 'obj3', foo: undefined},\n Ember.Object.create({ name: 'obj4', foo: undefined}),\n { name: 'obj5'},\n Ember.Object.create({ name: 'obj6'})\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.filterBy('foo'), ary.slice(0, 2), \"filterBy('foo', 3)')\");\n});\n\nsuite.test('should be aliased to filterProperty', function() {\n var ary = [];\n\n equal(ary.filterProperty, ary.filterBy);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/filter");minispade.register('ember-runtime/~tests/suites/enumerable/find', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\n// ..........................................................\n// find()\n//\n\nsuite.module('find');\n\nsuite.test('find should invoke callback on each item as long as you return false', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n found = [], result;\n\n result = obj.find(function(i) { found.push(i); return false; });\n equal(result, undefined, 'return value of obj.find');\n deepEqual(found, ary, 'items passed during find() should match');\n});\n\nsuite.test('every should stop invoking when you return true', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n cnt = ary.length - 2,\n exp = cnt,\n found = [], result;\n\n result = obj.find(function(i) { found.push(i); return --cnt >= 0; });\n equal(result, ary[exp-1], 'return value of obj.find');\n equal(found.length, exp, 'should invoke proper number of times');\n deepEqual(found, ary.slice(0,-2), 'items passed during find() should match');\n});\n\n// ..........................................................\n// findBy()\n//\n\nsuite.module('findBy');\n\nsuite.test('should return first object of property matches', function() {\n var ary, obj;\n\n ary = [\n { foo: 'foo', bar: 'BAZ' },\n Ember.Object.create({ foo: 'foo', bar: 'bar' })\n ];\n\n obj = this.newObject(ary);\n\n equal(obj.findBy('foo', 'foo'), ary[0], 'findBy(foo)');\n equal(obj.findBy('bar', 'bar'), ary[1], 'findBy(bar)');\n});\n\nsuite.test('should return first object with truthy prop', function() {\n var ary, obj ;\n\n ary = [\n { foo: 'foo', bar: false },\n Ember.Object.create({ foo: 'bar', bar: true })\n ];\n\n obj = this.newObject(ary);\n\n // different values - all eval to true\n equal(obj.findBy('foo'), ary[0], 'findBy(foo)');\n equal(obj.findBy('bar'), ary[1], 'findBy(bar)');\n});\n\nsuite.test('should return first null property match', function() {\n var ary, obj;\n\n ary = [\n { foo: null, bar: 'BAZ' },\n Ember.Object.create({ foo: null, bar: null })\n ];\n\n obj = this.newObject(ary);\n\n equal(obj.findBy('foo', null), ary[0], \"findBy('foo', null)\");\n equal(obj.findBy('bar', null), ary[1], \"findBy('bar', null)\");\n});\n\nsuite.test('should return first undefined property match', function() {\n var ary, obj;\n\n ary = [\n { foo: undefined, bar: 'BAZ' },\n Ember.Object.create({ })\n ];\n\n obj = this.newObject(ary);\n\n equal(obj.findBy('foo', undefined), ary[0], \"findBy('foo', undefined)\");\n equal(obj.findBy('bar', undefined), ary[1], \"findBy('bar', undefined)\");\n});\n\nsuite.test('should be aliased to findProperty', function() {\n var obj;\n\n obj = this.newObject([]);\n\n equal(obj.findProperty, obj.findBy);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/find");minispade.register('ember-runtime/~tests/suites/enumerable/firstObject', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\nsuite.module('firstObject');\n\nsuite.test('returns first item in enumerable', function() {\n var obj = this.newObject();\n equal(Ember.get(obj, 'firstObject'), this.toArray(obj)[0]);\n});\n\nsuite.test('returns undefined if enumerable is empty', function() {\n var obj = this.newObject([]);\n equal(Ember.get(obj, 'firstObject'), undefined);\n});\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/firstObject");minispade.register('ember-runtime/~tests/suites/enumerable/forEach', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests, global = this;\n\nsuite.module('forEach');\n\nsuite.test('forEach should iterate over list', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n found = [];\n\n obj.forEach(function(i) { found.push(i); });\n deepEqual(found, ary, 'items passed during forEach should match');\n});\n\n\nsuite.test('forEach should iterate over list after mutation', function() {\n if (Ember.get(this, 'canTestMutation')) {\n expect(0);\n return ;\n }\n\n var obj = this.newObject(),\n ary = this.toArray(obj),\n found = [];\n\n obj.forEach(function(i) { found.push(i); });\n deepEqual(found, ary, 'items passed during forEach should match');\n\n this.mutate(obj);\n ary = this.toArray(obj);\n found = [];\n\n obj.forEach(function(i) { found.push(i); });\n deepEqual(found, ary, 'items passed during forEach should match');\n});\n\nsuite.test('2nd target parameter', function() {\n var obj = this.newObject(), target = this;\n\n obj.forEach(function() {\n equal(Ember.guidFor(this), Ember.guidFor(global), 'should pass the global object as this if no context');\n });\n\n obj.forEach(function() {\n equal(Ember.guidFor(this), Ember.guidFor(target), 'should pass target as this if context');\n }, target);\n\n});\n\n\nsuite.test('callback params', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n loc = 0;\n\n\n obj.forEach(function(item, idx, enumerable) {\n equal(item, ary[loc], 'item param');\n equal(idx, loc, 'idx param');\n equal(Ember.guidFor(enumerable), Ember.guidFor(obj), 'enumerable param');\n loc++;\n });\n\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/forEach");minispade.register('ember-runtime/~tests/suites/enumerable/invoke', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\nsuite.module('invoke');\n\nsuite.test('invoke should call on each object that implements', function() {\n var cnt, ary, obj;\n\n function F(amt) {\n cnt += amt===undefined ? 1 : amt;\n }\n cnt = 0;\n ary = [\n { foo: F },\n Ember.Object.create({ foo: F }),\n\n // NOTE: does not impl foo - invoke should just skip\n Ember.Object.create({ bar: F }),\n\n { foo: F }\n ];\n\n obj = this.newObject(ary);\n obj.invoke('foo');\n equal(cnt, 3, 'should have invoked 3 times');\n\n cnt = 0;\n obj.invoke('foo', 2);\n equal(cnt, 6, 'should have invoked 3 times, passing param');\n});\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/invoke");minispade.register('ember-runtime/~tests/suites/enumerable/lastObject', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\nsuite.module('lastObject');\n\nsuite.test('returns last item in enumerable', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj);\n equal(Ember.get(obj, 'lastObject'), ary[ary.length-1]);\n});\n\nsuite.test('returns undefined if enumerable is empty', function() {\n var obj = this.newObject([]);\n equal(Ember.get(obj, 'lastObject'), undefined);\n});\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/lastObject");minispade.register('ember-runtime/~tests/suites/enumerable/map', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests, global = this;\n\nsuite.module('map');\n\nfunction mapFunc(item) { return item ? item.toString() : null; }\n\nsuite.test('map should iterate over list', function() {\n var obj = this.newObject(),\n ary = Ember.EnumerableUtils.map(this.toArray(obj), mapFunc),\n found = [];\n\n found = obj.map(mapFunc);\n deepEqual(found, ary, 'mapped arrays should match');\n});\n\n\nsuite.test('map should iterate over list after mutation', function() {\n if (Ember.get(this, 'canTestMutation')) {\n expect(0);\n return ;\n }\n\n var obj = this.newObject(),\n ary = this.toArray(obj).map(mapFunc),\n found;\n\n found = obj.map(mapFunc);\n deepEqual(found, ary, 'items passed during forEach should match');\n\n this.mutate(obj);\n ary = this.toArray(obj).map(mapFunc);\n found = obj.map(mapFunc);\n deepEqual(found, ary, 'items passed during forEach should match');\n});\n\nsuite.test('2nd target parameter', function() {\n var obj = this.newObject(), target = this;\n\n\n obj.map(function() {\n equal(Ember.guidFor(this), Ember.guidFor(global), 'should pass the global object as this if no context');\n });\n\n obj.map(function() {\n equal(Ember.guidFor(this), Ember.guidFor(target), 'should pass target as this if context');\n }, target);\n\n});\n\n\nsuite.test('callback params', function() {\n var obj = this.newObject(),\n ary = this.toArray(obj),\n loc = 0;\n\n\n obj.map(function(item, idx, enumerable) {\n equal(item, ary[loc], 'item param');\n equal(idx, loc, 'idx param');\n equal(Ember.guidFor(enumerable), Ember.guidFor(obj), 'enumerable param');\n loc++;\n });\n\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/map");minispade.register('ember-runtime/~tests/suites/enumerable/mapBy', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\nsuite.module('mapBy');\n\nsuite.test('get value of each property', function() {\n var obj = this.newObject([{a: 1},{a: 2}]);\n equal(obj.mapBy('a').join(''), '12');\n});\n\nsuite.test('should work also through getEach alias', function() {\n var obj = this.newObject([{a: 1},{a: 2}]);\n equal(obj.getEach('a').join(''), '12');\n});\n\nsuite.test('should be aliased to mapProperty', function() {\n var obj = this.newObject([]);\n equal(obj.mapProperty, obj.mapBy);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/mapBy");minispade.register('ember-runtime/~tests/suites/enumerable/reduce', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\nsuite.module('reduce');\n\nsuite.test('collectes a summary value from an enumeration', function() {\n var obj = this.newObject([1, 2, 3]);\n var res = obj.reduce(function(previousValue, item, index, enumerable) { return previousValue + item; }, 0);\n equal(res, 6);\n});\n\nsuite.test('passes index of item to callback', function() {\n var obj = this.newObject([1, 2, 3]);\n var res = obj.reduce(function(previousValue, item, index, enumerable) { return previousValue + index; }, 0);\n equal(res, 3);\n});\n\nsuite.test('passes enumerable object to callback', function() {\n var obj = this.newObject([1, 2, 3]);\n var res = obj.reduce(function(previousValue, item, index, enumerable) { return enumerable; }, 0);\n equal(res, obj);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/reduce");minispade.register('ember-runtime/~tests/suites/enumerable/reject', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\n// ..........................................................\n// reject()\n//\n\nsuite.module('reject');\n\nsuite.test('should reject any item that does not meet the condition', function() {\n var obj = this.newObject([1,2,3,4]),\n result;\n\n result = obj.reject(function(i) { return i < 3; });\n deepEqual(result, [3,4], 'reject the correct items');\n});\n\nsuite.test('should be the inverse of filter', function() {\n var obj = this.newObject([1,2,3,4]),\n isEven = function(i) { return i % 2 === 0; },\n filtered, rejected;\n\n filtered = obj.filter(isEven);\n rejected = obj.reject(isEven);\n\n deepEqual(filtered, [2,4], 'filtered evens');\n deepEqual(rejected, [1,3], 'rejected evens');\n});\n\n// ..........................................................\n// rejectBy()\n//\n\nsuite.module('rejectBy');\n\nsuite.test('should reject based on object', function() {\n var obj, ary;\n\n ary = [\n { foo: 'foo', bar: 'BAZ' },\n Ember.Object.create({ foo: 'foo', bar: 'bar' })\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.rejectBy('foo', 'foo'), [], 'rejectBy(foo)');\n deepEqual(obj.rejectBy('bar', 'bar'), [ary[0]], 'rejectBy(bar)');\n});\n\nsuite.test('should include in result if property is false', function() {\n var obj, ary;\n\n ary = [\n { foo: false, bar: true },\n Ember.Object.create({ foo: false, bar: false })\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.rejectBy('foo'), ary, 'rejectBy(foo)');\n deepEqual(obj.rejectBy('bar'), [ary[1]], 'rejectBy(bar)');\n});\n\nsuite.test('should reject on second argument if provided', function() {\n var obj, ary;\n\n ary = [\n { name: 'obj1', foo: 3},\n Ember.Object.create({ name: 'obj2', foo: 2}),\n { name: 'obj3', foo: 2},\n Ember.Object.create({ name: 'obj4', foo: 3})\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.rejectBy('foo', 3), [ary[1], ary[2]], \"rejectBy('foo', 3)')\");\n});\n\nsuite.test('should correctly reject null second argument', function() {\n var obj, ary;\n\n ary = [\n { name: 'obj1', foo: 3},\n Ember.Object.create({ name: 'obj2', foo: null}),\n { name: 'obj3', foo: null},\n Ember.Object.create({ name: 'obj4', foo: 3})\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.rejectBy('foo', null), [ary[0], ary[3]], \"rejectBy('foo', null)')\");\n});\n\nsuite.test('should correctly reject undefined second argument', function() {\n var obj, ary;\n\n ary = [\n { name: 'obj1', foo: 3},\n Ember.Object.create({ name: 'obj2', foo: 2})\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.rejectBy('bar', undefined), [], \"rejectBy('bar', undefined)')\");\n});\n\nsuite.test('should correctly reject explicit undefined second argument', function() {\n var obj, ary;\n\n ary = [\n { name: 'obj1', foo: 3},\n Ember.Object.create({ name: 'obj2', foo: 3}),\n { name: 'obj3', foo: undefined},\n Ember.Object.create({ name: 'obj4', foo: undefined}),\n { name: 'obj5'},\n Ember.Object.create({ name: 'obj6'})\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.rejectBy('foo', undefined), ary.slice(0, 2), \"rejectBy('foo', undefined)')\");\n});\n\nsuite.test('should match undefined, null, or false properties without second argument', function() {\n var obj, ary;\n\n ary = [\n { name: 'obj1', foo: 3},\n Ember.Object.create({ name: 'obj2', foo: 3}),\n { name: 'obj3', foo: undefined},\n Ember.Object.create({ name: 'obj4', foo: undefined}),\n { name: 'obj5'},\n Ember.Object.create({ name: 'obj6'}),\n { name: 'obj7', foo: null },\n Ember.Object.create({ name: 'obj8', foo: null }),\n { name: 'obj9', foo: false },\n Ember.Object.create({ name: 'obj10', foo: false })\n ];\n\n obj = this.newObject(ary);\n\n deepEqual(obj.rejectBy('foo'), ary.slice(2), \"rejectBy('foo')')\");\n});\n\nsuite.test('should be aliased to rejectProperty', function() {\n var ary =[];\n\n equal(ary.rejectProperty, ary.rejectBy);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/reject");minispade.register('ember-runtime/~tests/suites/enumerable/sortBy', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\nvar get = Ember.get;\n\nvar suite = Ember.EnumerableTests;\n\nif (Ember.FEATURES.isEnabled(\"ember-runtime-sortBy\")) {\n suite.module('sortBy');\n\n suite.test('sort by value of property', function() {\n var obj = this.newObject([{a: 2},{a: 1}]),\n sorted = obj.sortBy('a');\n equal(get(sorted[0], 'a'), 1);\n equal(get(sorted[1], 'a'), 2);\n });\n\n suite.test('supports multiple propertyNames', function() {\n var obj = this.newObject([{a: 1, b: 2},{a: 1, b: 1}]),\n sorted = obj.sortBy('a', 'b');\n equal(get(sorted[0], 'b'), 1);\n equal(get(sorted[1], 'b'), 2);\n });\n}\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/sortBy");minispade.register('ember-runtime/~tests/suites/enumerable/toArray', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\nsuite.module('toArray');\n\nsuite.test('toArray should convert to an array', function() {\n var obj = this.newObject();\n deepEqual(obj.toArray(), this.toArray(obj));\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/toArray");minispade.register('ember-runtime/~tests/suites/enumerable/uniq', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\nsuite.module('uniq');\n\nsuite.test('should return new instance with duplicates removed', function() {\n var before, after, obj, ret;\n\n after = this.newFixture(3);\n before = [after[0], after[1], after[2], after[1], after[0]];\n obj = this.newObject(before);\n before = obj.toArray(); // in case of set before will be different...\n\n ret = obj.uniq();\n deepEqual(this.toArray(ret), after, 'should have removed item');\n deepEqual(this.toArray(obj), before, 'should not have changed original');\n});\n\nsuite.test('should return duplicate of same content if no duplicates found', function() {\n var item, obj, ret;\n obj = this.newObject(this.newFixture(3));\n ret = obj.uniq(item);\n ok(ret !== obj, 'should not be same object');\n deepEqual(this.toArray(ret), this.toArray(obj), 'should be the same content');\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/uniq");minispade.register('ember-runtime/~tests/suites/enumerable/without', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nvar suite = Ember.EnumerableTests;\n\nsuite.module('without');\n\nsuite.test('should return new instance with item removed', function() {\n var before, after, obj, ret;\n\n before = this.newFixture(3);\n after = [before[0], before[2]];\n obj = this.newObject(before);\n\n ret = obj.without(before[1]);\n deepEqual(this.toArray(ret), after, 'should have removed item');\n deepEqual(this.toArray(obj), before, 'should not have changed original');\n});\n\nsuite.test('should return same instance if object not found', function() {\n var item, obj, ret;\n\n item = this.newFixture(1)[0];\n obj = this.newObject(this.newFixture(3));\n\n ret = obj.without(item);\n equal(ret, obj, 'should be same instance');\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/enumerable/without");minispade.register('ember-runtime/~tests/suites/mutable_array', "(function() {minispade.require('ember-runtime/~tests/suites/array');\n\nEmber.MutableArrayTests = Ember.ArrayTests.extend();\nminispade.require('ember-runtime/~tests/suites/mutable_array/insertAt');\nminispade.require('ember-runtime/~tests/suites/mutable_array/popObject');\nminispade.require('ember-runtime/~tests/suites/mutable_array/pushObject');\nminispade.require('ember-runtime/~tests/suites/mutable_array/pushObjects');\nminispade.require('ember-runtime/~tests/suites/mutable_array/removeAt');\nminispade.require('ember-runtime/~tests/suites/mutable_array/replace');\nminispade.require('ember-runtime/~tests/suites/mutable_array/shiftObject');\nminispade.require('ember-runtime/~tests/suites/mutable_array/unshiftObject');\nminispade.require('ember-runtime/~tests/suites/mutable_array/reverseObjects');\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array");minispade.register('ember-runtime/~tests/suites/mutable_array/addObject', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('addObject');\n\nsuite.test(\"should return receiver\", function() {\n var before, obj;\n before = this.newFixture(3);\n obj = this.newObject(before);\n equal(obj.addObject(before[1]), obj, 'should return receiver');\n});\n\nsuite.test(\"[A,B].addObject(C) => [A,B,C] + notify\", function() {\n var obj, before, after, observer, item;\n\n before = this.newFixture(2);\n item = this.newFixture(1)[0];\n after = [before[0], before[1], item];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.addObject(item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n if (observer.isEnabled) {\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n }\n});\n\nsuite.test(\"[A,B,C].addObject(A) => [A,B,C] + NO notify\", function() {\n var obj, before, after, observer, item;\n\n before = this.newFixture(3);\n after = before;\n item = before[0];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.addObject(item); // note: item in set\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n if (observer.isEnabled) {\n equal(observer.validate('[]'), false, 'should NOT have notified []');\n equal(observer.validate('@each'), false, 'should NOT have notified @each');\n equal(observer.validate('length'), false, 'should NOT have notified length');\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n }\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/addObject");minispade.register('ember-runtime/~tests/suites/mutable_array/clear', "(function() {/*globals raises */\nminispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('clear');\n\nsuite.test(\"[].clear() => [] + notify\", function () {\n var obj, before, after, observer;\n\n before = [];\n after = [];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.clear(), obj, 'return self');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.validate('[]'), false, 'should NOT have notified [] once');\n equal(observer.validate('@each'), false, 'should NOT have notified @each once');\n equal(observer.validate('length'), false, 'should NOT have notified length once');\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n});\n\nsuite.test(\"[X].clear() => [] + notify\", function () {\n var obj, before, after, observer;\n\n before = this.newFixture(1);\n after = [];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.clear(), obj, 'return self');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/clear");minispade.register('ember-runtime/~tests/suites/mutable_array/insertAt', "(function() {/*globals raises */\nminispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('insertAt');\n\nsuite.test(\"[].insertAt(0, X) => [X] + notify\", function() {\n var obj, after, observer;\n\n after = this.newFixture(1);\n obj = this.newObject([]);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.insertAt(0, after[0]);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n\n equal(observer.timesCalledBefore('[]'), 1, 'should have notified [] will change once');\n equal(observer.timesCalledBefore('@each'), 1, 'should have notified @each will change once');\n equal(observer.timesCalledBefore('length'), 1, 'should have notified length will change once');\n equal(observer.timesCalledBefore('firstObject'), 1, 'should have notified firstObject will change once');\n equal(observer.timesCalledBefore('lastObject'), 1, 'should have notified lastObject will change once');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] did change once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each did change once');\n equal(observer.timesCalled('length'), 1, 'should have notified length did change once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject did change once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject did change once');\n});\n\nsuite.test(\"[].insertAt(200,X) => OUT_OF_RANGE_EXCEPTION exception\", function() {\n var obj = this.newObject([]), that = this;\n raises(function() {\n obj.insertAt(200, that.newFixture(1)[0]);\n }, Error);\n});\n\nsuite.test(\"[A].insertAt(0, X) => [X,A] + notify\", function() {\n var obj, item, after, before, observer;\n\n item = this.newFixture(1)[0];\n before = this.newFixture(1);\n after = [item, before[0]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.insertAt(0, item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalledBefore('[]'), 1, 'should have notified [] will change once');\n equal(observer.timesCalledBefore('@each'), 1, 'should have notified @each will change once');\n equal(observer.timesCalledBefore('length'), 1, 'should have notified length will change once');\n equal(observer.timesCalledBefore('firstObject'), 1, 'should have notified firstObject will change once');\n equal(observer.timesCalledBefore('lastObject'), 0, 'should NOT have notified lastObject will change once');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n});\n\nsuite.test(\"[A].insertAt(1, X) => [A,X] + notify\", function() {\n var obj, item, after, before, observer;\n\n item = this.newFixture(1)[0];\n before = this.newFixture(1);\n after = [before[0], item];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.insertAt(1, item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalledBefore('[]'), 1, 'should have notified [] will change once');\n equal(observer.timesCalledBefore('@each'), 1, 'should have notified @each will change once');\n equal(observer.timesCalledBefore('length'), 1, 'should have notified length will change once');\n equal(observer.timesCalledBefore('firstObject'), 0, 'should NOT have notified firstObject will change once');\n equal(observer.timesCalledBefore('lastObject'), 1, 'should have notified lastObject will change once');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n});\n\nsuite.test(\"[A].insertAt(200,X) => OUT_OF_RANGE exception\", function() {\n var obj = this.newObject(this.newFixture(1)), that = this;\n raises(function() {\n obj.insertAt(200, that.newFixture(1)[0]);\n }, Error);\n});\n\nsuite.test(\"[A,B,C].insertAt(0,X) => [X,A,B,C] + notify\", function() {\n var obj, item, after, before, observer;\n\n item = this.newFixture(1)[0];\n before = this.newFixture(3);\n after = [item, before[0], before[1], before[2]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.insertAt(0, item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalledBefore('[]'), 1, 'should have notified [] will change once');\n equal(observer.timesCalledBefore('@each'), 1, 'should have notified @each will change once');\n equal(observer.timesCalledBefore('length'), 1, 'should have notified length will change once');\n equal(observer.timesCalledBefore('firstObject'), 1, 'should have notified firstObject will change once');\n equal(observer.timesCalledBefore('lastObject'), 0, 'should NOT have notified lastObject will change once');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n});\n\nsuite.test(\"[A,B,C].insertAt(1,X) => [A,X,B,C] + notify\", function() {\n var obj, item, after, before, observer;\n\n item = this.newFixture(1)[0];\n before = this.newFixture(3);\n after = [before[0], item, before[1], before[2]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.insertAt(1, item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalledBefore('[]'), 1, 'should have notified [] will change once');\n equal(observer.timesCalledBefore('@each'), 1, 'should have notified @each will change once');\n equal(observer.timesCalledBefore('length'), 1, 'should have notified length will change once');\n equal(observer.timesCalledBefore('firstObject'), 0, 'should NOT have notified firstObject will change once');\n equal(observer.timesCalledBefore('lastObject'), 0, 'should NOT have notified lastObject will change once');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n});\n\nsuite.test(\"[A,B,C].insertAt(3,X) => [A,B,C,X] + notify\", function() {\n var obj, item, after, before, observer;\n\n item = this.newFixture(1)[0];\n before = this.newFixture(3);\n after = [before[0], before[1], before[2], item];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.insertAt(3, item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalledBefore('[]'), 1, 'should have notified [] will change once');\n equal(observer.timesCalledBefore('@each'), 1, 'should have notified @each will change once');\n equal(observer.timesCalledBefore('length'), 1, 'should have notified length will change once');\n equal(observer.timesCalledBefore('firstObject'), 0, 'should NOT have notified firstObject will change once');\n equal(observer.timesCalledBefore('lastObject'), 1, 'should have notified lastObject will change once');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/insertAt");minispade.register('ember-runtime/~tests/suites/mutable_array/popObject', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('popObject');\n\nsuite.test(\"[].popObject() => [] + returns undefined + NO notify\", function() {\n var obj, observer;\n\n obj = this.newObject([]);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.popObject(), undefined, 'popObject results');\n\n deepEqual(this.toArray(obj), [], 'post item results');\n\n equal(observer.validate('[]'), false, 'should NOT have notified []');\n equal(observer.validate('@each'), false, 'should NOT have notified @each');\n equal(observer.validate('length'), false, 'should NOT have notified length');\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n});\n\nsuite.test(\"[X].popObject() => [] + notify\", function() {\n var obj, before, after, observer, ret;\n\n before = this.newFixture(1);\n after = [];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n ret = obj.popObject();\n\n equal(ret, before[0], 'return object');\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n\nsuite.test(\"[A,B,C].popObject() => [A,B] + notify\", function() {\n var obj, before, after, observer, ret;\n\n before = this.newFixture(3);\n after = [before[0], before[1]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n ret = obj.popObject();\n\n equal(ret, before[2], 'return object');\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/popObject");minispade.register('ember-runtime/~tests/suites/mutable_array/pushObject', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('pushObject');\n\nsuite.test(\"returns pushed object\", function() {\n var exp = this.newFixture(1)[0];\n var obj = this.newObject([]);\n equal(obj.pushObject(exp), exp, 'should return pushed object');\n});\n\nsuite.test(\"[].pushObject(X) => [X] + notify\", function() {\n var obj, before, after, observer;\n\n before = [];\n after = this.newFixture(1);\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.pushObject(after[0]);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n\nsuite.test(\"[A,B,C].pushObject(X) => [A,B,C,X] + notify\", function() {\n var obj, before, after, item, observer;\n\n before = this.newFixture(3);\n item = this.newFixture(1)[0];\n after = [before[0], before[1], before[2], item];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.pushObject(item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/pushObject");minispade.register('ember-runtime/~tests/suites/mutable_array/pushObjects', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('pushObjects');\n\nsuite.test(\"should raise exception if not Ember.Enumerable is passed to pushObjects\", function() {\n var obj = this.newObject([]);\n\n raises(function() {\n obj.pushObjects( \"string\" );\n });\n});\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/pushObjects");minispade.register('ember-runtime/~tests/suites/mutable_array/removeAt', "(function() {/*globals raises */\nminispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('removeAt');\n\nsuite.test(\"[X].removeAt(0) => [] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(1);\n after = [];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.removeAt(0), obj, 'return self');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n\nsuite.test(\"[].removeAt(200) => OUT_OF_RANGE_EXCEPTION exception\", function() {\n var obj = this.newObject([]);\n raises(function() {\n obj.removeAt(200);\n }, Error);\n});\n\nsuite.test(\"[A,B].removeAt(0) => [B] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(2);\n after = [before[1]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.removeAt(0), obj, 'return self');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n});\n\nsuite.test(\"[A,B].removeAt(1) => [A] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(2);\n after = [before[0]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.removeAt(1), obj, 'return self');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n});\n\nsuite.test(\"[A,B,C].removeAt(1) => [A,C] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(3);\n after = [before[0], before[2]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.removeAt(1), obj, 'return self');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n});\n\nsuite.test(\"[A,B,C,D].removeAt(1,2) => [A,D] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(4);\n after = [before[0], before[3]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.removeAt(1,2), obj, 'return self');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/removeAt");minispade.register('ember-runtime/~tests/suites/mutable_array/removeObject', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('removeObject');\n\nsuite.test(\"should return receiver\", function() {\n var before, obj;\n before = this.newFixture(3);\n obj = this.newObject(before);\n equal(obj.removeObject(before[1]), obj, 'should return receiver');\n});\n\nsuite.test(\"[A,B,C].removeObject(B) => [A,C] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(3);\n after = [before[0], before[2]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.removeObject(before[1]);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n if (observer.isEnabled) {\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n }\n});\n\nsuite.test(\"[A,B,C].removeObject(D) => [A,B,C]\", function() {\n var obj, before, after, observer, item;\n\n before = this.newFixture(3);\n after = before;\n item = this.newFixture(1)[0];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.removeObject(item); // note: item not in set\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n if (observer.isEnabled) {\n equal(observer.validate('[]'), false, 'should NOT have notified []');\n equal(observer.validate('@each'), false, 'should NOT have notified @each');\n equal(observer.validate('length'), false, 'should NOT have notified length');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n }\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/removeObject");minispade.register('ember-runtime/~tests/suites/mutable_array/replace', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('replace');\n\nsuite.test(\"[].replace(0,0,'X') => ['X'] + notify\", function() {\n\n var obj, exp, observer;\n exp = this.newFixture(1);\n obj = this.newObject([]);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.replace(0,0,exp) ;\n\n deepEqual(this.toArray(obj), exp, 'post item results');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n\nsuite.test(\"[A,B,C,D].replace(1,2,X) => [A,X,D] + notify\", function() {\n var obj, observer, before, replace, after;\n\n before = this.newFixture(4);\n replace = this.newFixture(1);\n after = [before[0], replace[0], before[3]];\n\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.replace(1,2,replace) ;\n\n deepEqual(this.toArray(obj), after, 'post item results');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n});\n\nsuite.test(\"[A,B,C,D].replace(1,2,[X,Y]) => [A,X,Y,D] + notify\", function() {\n var obj, observer, before, replace, after;\n\n before = this.newFixture(4);\n replace = this.newFixture(2);\n after = [before[0], replace[0], replace[1], before[3]];\n\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.replace(1,2,replace) ;\n\n deepEqual(this.toArray(obj), after, 'post item results');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.validate('length'), false, 'should NOT have notified length');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n});\n\nsuite.test(\"[A,B].replace(1,0,[X,Y]) => [A,X,Y,B] + notify\", function() {\n var obj, observer, before, replace, after;\n\n before = this.newFixture(2);\n replace = this.newFixture(2);\n after = [before[0], replace[0], replace[1], before[1]];\n\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.replace(1,0,replace) ;\n\n deepEqual(this.toArray(obj), after, 'post item results');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n});\n\nsuite.test(\"[A,B,C,D].replace(2,2) => [A,B] + notify\", function() {\n var obj, observer, before, replace, after;\n\n before = this.newFixture(4);\n after = [before[0], before[1]];\n\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.replace(2,2);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n});\n\nsuite.test('Adding object should notify enumerable observer', function() {\n\n var fixtures = this.newFixture(4);\n var obj = this.newObject(fixtures);\n var observer = this.newObserver(obj).observeEnumerable(obj);\n var item = this.newFixture(1)[0];\n\n obj.replace(2, 2, [item]);\n\n deepEqual(observer._before, [obj, [fixtures[2], fixtures[3]], 1], 'before');\n deepEqual(observer._after, [obj, 2, [item]], 'after');\n});\n\nsuite.test('Adding object should notify array observer', function() {\n\n var fixtures = this.newFixture(4);\n var obj = this.newObject(fixtures);\n var observer = this.newObserver(obj).observeArray(obj);\n var item = this.newFixture(1)[0];\n\n obj.replace(2, 2, [item]);\n\n deepEqual(observer._before, [obj, 2, 2, 1], 'before');\n deepEqual(observer._after, [obj, 2, 2, 1], 'after');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/replace");minispade.register('ember-runtime/~tests/suites/mutable_array/reverseObjects', "(function() {/*globals raises */\nminispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('reverseObjects');\n\nsuite.test(\"[A,B,C].reverseObjects() => [] + notify\", function () {\n var obj, before, after, observer;\n\n before = this.newFixture(3);\n after = [before[2], before[1], before[0]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.reverseObjects(), obj, 'return self');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 0, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/reverseObjects");minispade.register('ember-runtime/~tests/suites/mutable_array/setObjects', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('setObjects');\n\nsuite.test(\"[A,B,C].setObjects([]) = > [] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(3);\n after = [];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.setObjects(after), obj, 'return self');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n\nsuite.test(\"[A,B,C].setObjects([D, E, F, G]) = > [D, E, F, G] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(3);\n after = this.newFixture(4);\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.setObjects(after), obj, 'return self');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/setObjects");minispade.register('ember-runtime/~tests/suites/mutable_array/shiftObject', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('shiftObject');\n\nsuite.test(\"[].shiftObject() => [] + returns undefined + NO notify\", function() {\n var obj, before, after, observer;\n\n before = [];\n after = [];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.shiftObject(), undefined);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.validate('[]', undefined, 1), false, 'should NOT have notified [] once');\n equal(observer.validate('@each', undefined, 1), false, 'should NOT have notified @each once');\n equal(observer.validate('length', undefined, 1), false, 'should NOT have notified length once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject once');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n});\n\nsuite.test(\"[X].shiftObject() => [] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(1);\n after = [];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.shiftObject(), before[0], 'should return object');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n\nsuite.test(\"[A,B,C].shiftObject() => [B,C] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(3);\n after = [before[1], before[2]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n equal(obj.shiftObject(), before[0], 'should return object');\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject once');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/shiftObject");minispade.register('ember-runtime/~tests/suites/mutable_array/unshiftObject', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('unshiftObject');\n\nsuite.test(\"returns unshifted object\", function() {\n var obj = this.newObject([]);\n var item = this.newFixture(1)[0];\n equal(obj.unshiftObject(item), item, 'should return unshifted object');\n});\n\n\nsuite.test(\"[].unshiftObject(X) => [X] + notify\", function() {\n var obj, before, after, item, observer;\n\n before = [];\n item = this.newFixture(1)[0];\n after = [item];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.unshiftObject(item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n\nsuite.test(\"[A,B,C].unshiftObject(X) => [X,A,B,C] + notify\", function() {\n var obj, before, after, item, observer;\n\n before = this.newFixture(3);\n item = this.newFixture(1)[0];\n after = [item, before[0], before[1], before[2]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.unshiftObject(item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n});\n\nsuite.test(\"[A,B,C].unshiftObject(A) => [A,A,B,C] + notify\", function() {\n var obj, before, after, item, observer;\n\n before = this.newFixture(3);\n item = before[0]; // note same object as current head. should end up twice\n after = [item, before[0], before[1], before[2]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.unshiftObject(item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/unshiftObject");minispade.register('ember-runtime/~tests/suites/mutable_array/unshiftObjects', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_array');\n\nvar suite = Ember.MutableArrayTests;\n\nsuite.module('unshiftObjects');\n\nsuite.test(\"returns receiver\", function() {\n var obj = this.newObject([]);\n var items = this.newFixture(3);\n equal(obj.unshiftObjects(items), obj, 'should return receiver');\n});\n\nsuite.test(\"[].unshiftObjects([A,B,C]) => [A,B,C] + notify\", function() {\n var obj, before, items, observer;\n\n before = [];\n items = this.newFixture(3);\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.unshiftObjects(items);\n\n deepEqual(this.toArray(obj), items, 'post item results');\n equal(Ember.get(obj, 'length'), items.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n});\n\nsuite.test(\"[A,B,C].unshiftObjects([X,Y]) => [X,Y,A,B,C] + notify\", function() {\n var obj, before, items, after, observer;\n\n before = this.newFixture(3);\n items = this.newFixture(2);\n after = items.concat(before);\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.unshiftObjects(items);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n});\n\nsuite.test(\"[A,B,C].unshiftObjects([A,B]) => [A,B,A,B,C] + notify\", function() {\n var obj, before, after, items, observer;\n\n before = this.newFixture(3);\n items = [before[0], before[1]]; // note same object as current head. should end up twice\n after = items.concat(before);\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');\n obj.getProperties('firstObject', 'lastObject'); /* Prime the cache */\n\n obj.unshiftObjects(items);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('@each'), 1, 'should have notified @each once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_array/unshiftObjects");minispade.register('ember-runtime/~tests/suites/mutable_enumerable', "(function() {minispade.require('ember-runtime/~tests/suites/enumerable');\n\nEmber.MutableEnumerableTests = Ember.EnumerableTests.extend();\nminispade.require('ember-runtime/~tests/suites/mutable_enumerable/addObject');\nminispade.require('ember-runtime/~tests/suites/mutable_enumerable/removeObject');\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_enumerable");minispade.register('ember-runtime/~tests/suites/mutable_enumerable/addObject', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_enumerable');\n\nvar suite = Ember.MutableEnumerableTests;\n\nsuite.module('addObject');\n\nsuite.test(\"should return receiver\", function() {\n var before, obj;\n before = this.newFixture(3);\n obj = this.newObject(before);\n equal(obj.addObject(before[1]), obj, 'should return receiver');\n});\n\nsuite.test(\"[A,B].addObject(C) => [A,B,C] + notify\", function() {\n var obj, before, after, observer, item;\n\n before = this.newFixture(2);\n item = this.newFixture(1)[0];\n after = [before[0], before[1], item];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', 'length', 'firstObject', 'lastObject');\n Ember.get(obj, 'firstObject');\n Ember.get(obj, 'lastObject');\n\n obj.addObject(item);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n if (observer.isEnabled) {\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n equal(observer.timesCalled('lastObject'), 1, 'should have notified lastObject once');\n // This gets called since MutableEnumerable is naive about changes\n equal(observer.timesCalled('firstObject'), 1, 'should have notified firstObject once');\n }\n});\n\nsuite.test(\"[A,B,C].addObject(A) => [A,B,C] + NO notify\", function() {\n var obj, before, after, observer, item;\n\n before = this.newFixture(3);\n after = before;\n item = before[0];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', 'length', 'firstObject', 'lastObject');\n\n obj.addObject(item); // note: item in set\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n if (observer.isEnabled) {\n equal(observer.validate('[]'), false, 'should NOT have notified []');\n equal(observer.validate('length'), false, 'should NOT have notified length');\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n }\n});\n\nsuite.test('Adding object should notify enumerable observer', function() {\n var obj = this.newObject(this.newFixture(3));\n var observer = this.newObserver(obj).observeEnumerable(obj);\n var item = this.newFixture(1)[0];\n\n obj.addObject(item);\n\n deepEqual(observer._before, [obj, null, [item]]);\n deepEqual(observer._after, [obj, null, [item]]);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_enumerable/addObject");minispade.register('ember-runtime/~tests/suites/mutable_enumerable/removeObject', "(function() {minispade.require('ember-runtime/~tests/suites/mutable_enumerable');\n\nvar suite = Ember.MutableEnumerableTests;\n\nsuite.module('removeObject');\n\nsuite.test(\"should return receiver\", function() {\n var before, obj;\n before = this.newFixture(3);\n obj = this.newObject(before);\n equal(obj.removeObject(before[1]), obj, 'should return receiver');\n});\n\nsuite.test(\"[A,B,C].removeObject(B) => [A,C] + notify\", function() {\n var obj, before, after, observer;\n\n before = this.newFixture(3);\n after = [before[0], before[2]];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', 'length');\n\n obj.removeObject(before[1]);\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n if (observer.isEnabled) {\n equal(observer.timesCalled('[]'), 1, 'should have notified [] once');\n equal(observer.timesCalled('length'), 1, 'should have notified length once');\n\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n }\n});\n\nsuite.test(\"[A,B,C].removeObject(D) => [A,B,C]\", function() {\n var obj, before, after, observer, item;\n\n before = this.newFixture(3);\n after = before;\n item = this.newFixture(1)[0];\n obj = this.newObject(before);\n observer = this.newObserver(obj, '[]', 'length');\n\n obj.removeObject(item); // note: item not in set\n\n deepEqual(this.toArray(obj), after, 'post item results');\n equal(Ember.get(obj, 'length'), after.length, 'length');\n\n if (observer.isEnabled) {\n equal(observer.validate('[]'), false, 'should NOT have notified []');\n equal(observer.validate('length'), false, 'should NOT have notified length');\n equal(observer.validate('firstObject'), false, 'should NOT have notified firstObject');\n equal(observer.validate('lastObject'), false, 'should NOT have notified lastObject');\n }\n});\n\nsuite.test('Removing object should notify enumerable observer', function() {\n\n var fixtures = this.newFixture(3);\n var obj = this.newObject(fixtures);\n var observer = this.newObserver(obj).observeEnumerable(obj);\n var item = fixtures[1];\n\n obj.removeObject(item);\n\n deepEqual(observer._before, [obj, [item], null]);\n deepEqual(observer._after, [obj, [item], null]);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/mutable_enumerable/removeObject");minispade.register('ember-runtime/~tests/suites/suite', "(function() {/**\n @class\n A Suite can be used to define a reusable set of unit tests that can be\n applied to any object. Suites are most useful for defining tests that\n work against a mixin or plugin API. Developers implementing objects that\n use the mixin or support the API can then run these tests against their\n own code to verify compliance.\n\n To define a suite, you need to define the tests themselves as well as a\n callback API implementors can use to tie your tests to thier specific class.\n\n ## Defining a Callback API\n\n To define the callback API, just extend this class and add your properties\n or methods that must be provided. Use Ember.required() placeholders for\n any properties that implementors must define themselves.\n\n ## Defining Unit Tests\n\n To add unit tests, use the suite.module() or suite.test() methods instead\n of a regular module() or test() method when defining your tests. This will\n add the tests to the suite.\n\n ## Using a Suite\n\n To use a Suite to test your own objects, extend the suite subclass and\n define any required methods. Then call run() on the new subclass. This\n will create an instance of your class and then defining the unit tests.\n\n @extends Ember.Object\n @private\n*/\nEmber.Suite = Ember.Object.extend(/** @scope Ember.Suite.prototype */ {\n\n /**\n Define a name for these tests - all modules are prefixed w/ it.\n\n @type String\n */\n name: Ember.required(String),\n\n /**\n Invoked to actually run the test - overridden by mixins\n */\n run: function() {}\n\n});\n\nEmber.Suite.reopenClass({\n\n plan: null,\n\n run: function() {\n var C = this;\n return new C().run();\n },\n\n module: function(desc, opts) {\n if (!opts) opts = {};\n var setup = opts.setup, teardown = opts.teardown;\n this.reopen({\n run: function() {\n this._super();\n var title = Ember.get(this, 'name')+': '+desc, ctx = this;\n module(title, {\n setup: function() {\n if (setup) setup.call(ctx);\n },\n\n teardown: function() {\n if (teardown) teardown.call(ctx);\n }\n });\n }\n });\n },\n\n test: function(name, func) {\n this.reopen({\n run: function() {\n this._super();\n var ctx = this;\n if (!func) test(name); // output warning\n else test(name, function() { func.call(ctx); });\n }\n });\n },\n\n // convert to guids to minimize logging.\n same: function(actual, exp, message) {\n actual = (actual && actual.map) ? actual.map(function(x) { return Ember.guidFor(x); }) : actual;\n exp = (exp && exp.map) ? exp.map(function(x) { return Ember.guidFor(x); }) : exp;\n return deepEqual(actual, exp, message);\n },\n\n // easy way to disable tests\n notest: function() {}\n\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/suites/suite");minispade.register('ember-runtime/~tests/system/application/base_test', "(function() {module('Ember.Application');\n\ntest('Ember.Application should be a subclass of Ember.Namespace', function() {\n\n ok(Ember.Namespace.detect(Ember.Application), 'Ember.Application subclass of Ember.Namespace');\n\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/application/base_test");minispade.register('ember-runtime/~tests/system/array_proxy/arranged_content_test', "(function() {var array;\n\nmodule(\"Ember.ArrayProxy - arrangedContent\", {\n setup: function() {\n Ember.run(function() {\n array = Ember.ArrayProxy.createWithMixins({\n content: Ember.A([1,2,4,5]),\n arrangedContent: Ember.computed(function() {\n var content = this.get('content');\n return content && Ember.A(content.slice().sort(function(a,b) {\n if (a == null) { a = -1; }\n if (b == null) { b = -1; }\n return b - a;\n }));\n }).property('content.[]')\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n array.destroy();\n });\n }\n});\n\ntest(\"addObject - adds to end of 'content' if not present\", function() {\n Ember.run(function() { array.addObject(3); });\n deepEqual(array.get('content'), [1,2,4,5,3], 'adds to end of content');\n deepEqual(array.get('arrangedContent'), [5,4,3,2,1], 'arrangedContent stays sorted');\n\n Ember.run(function() { array.addObject(1); });\n deepEqual(array.get('content'), [1,2,4,5,3], 'does not add existing number to content');\n});\n\ntest(\"addObjects - adds to end of 'content' if not present\", function() {\n Ember.run(function() { array.addObjects([1,3,6]); });\n deepEqual(array.get('content'), [1,2,4,5,3,6], 'adds to end of content');\n deepEqual(array.get('arrangedContent'), [6,5,4,3,2,1], 'arrangedContent stays sorted');\n});\n\ntest(\"compact - returns arrangedContent without nulls and undefined\", function() {\n Ember.run(function() { array.set('content', Ember.A([1,3,null,2,undefined])); });\n deepEqual(array.compact(), [3,2,1]);\n});\n\ntest(\"indexOf - returns index of object in arrangedContent\", function() {\n equal(array.indexOf(4), 1, 'returns arranged index');\n});\n\ntest(\"insertAt - raises, indeterminate behavior\", function() {\n raises(function() {\n Ember.run(function() { array.insertAt(2,3); });\n });\n});\n\ntest(\"lastIndexOf - returns last index of object in arrangedContent\", function() {\n Ember.run(function() { array.pushObject(4); });\n equal(array.lastIndexOf(4), 2, 'returns last arranged index');\n});\n\ntest(\"nextObject - returns object at index in arrangedContent\", function() {\n equal(array.nextObject(1), 4, 'returns object at index');\n});\n\ntest(\"objectAt - returns object at index in arrangedContent\", function() {\n equal(array.objectAt(1), 4, 'returns object at index');\n});\n\n// Not sure if we need a specific test for it, since it's internal\ntest(\"objectAtContent - returns object at index in arrangedContent\", function() {\n equal(array.objectAtContent(1), 4, 'returns object at index');\n});\n\ntest(\"objectsAt - returns objects at indices in arrangedContent\", function() {\n deepEqual(array.objectsAt([0,2,4]), [5,2,undefined], 'returns objects at indices');\n});\n\ntest(\"popObject - removes last object in arrangedContent\", function() {\n var popped;\n Ember.run(function() { popped = array.popObject(); });\n equal(popped, 1, 'returns last object');\n deepEqual(array.get('content'), [2,4,5], 'removes from content');\n});\n\ntest(\"pushObject - adds to end of content even if it already exists\", function() {\n Ember.run(function() { array.pushObject(1); });\n deepEqual(array.get('content'), [1,2,4,5,1], 'adds to end of content');\n});\n\ntest(\"pushObjects - adds multiple to end of content even if it already exists\", function() {\n Ember.run(function() { array.pushObjects([1,2,4]); });\n deepEqual(array.get('content'), [1,2,4,5,1,2,4], 'adds to end of content');\n});\n\ntest(\"removeAt - removes from index in arrangedContent\", function() {\n Ember.run(function() { array.removeAt(1,2); });\n deepEqual(array.get('content'), [1,5]);\n});\n\ntest(\"removeObject - removes object from content\", function() {\n Ember.run(function() { array.removeObject(2); });\n deepEqual(array.get('content'), [1,4,5]);\n});\n\ntest(\"removeObjects - removes objects from content\", function() {\n Ember.run(function() { array.removeObjects([2,4,6]); });\n deepEqual(array.get('content'), [1,5]);\n});\n\ntest(\"replace - raises, indeterminate behavior\", function() {\n raises(function() {\n Ember.run(function() { array.replace(1, 2, [3]); });\n });\n});\n\ntest(\"replaceContent - does a standard array replace on content\", function() {\n Ember.run(function() { array.replaceContent(1, 2, [3]); });\n deepEqual(array.get('content'), [1,3,5]);\n});\n\ntest(\"reverseObjects - raises, use Sortable#sortAscending\", function() {\n raises(function() {\n Ember.run(function() { array.reverseObjects(); });\n });\n});\n\ntest(\"setObjects - replaces entire content\", function() {\n Ember.run(function() { array.setObjects([6,7,8]); });\n deepEqual(array.get('content'), [6,7,8], 'replaces content');\n});\n\ntest(\"shiftObject - removes from start of arrangedContent\", function() {\n var shifted;\n Ember.run(function() { shifted = array.shiftObject(); });\n equal(shifted, 5, 'returns first object');\n deepEqual(array.get('content'), [1,2,4], 'removes object from content');\n});\n\ntest(\"slice - returns a slice of the arrangedContent\", function() {\n deepEqual(array.slice(1,3), [4,2], 'returns sliced arrangedContent');\n});\n\ntest(\"toArray - returns copy of arrangedContent\", function() {\n deepEqual(array.toArray(), [5,4,2,1]);\n});\n\ntest(\"unshiftObject - adds to start of content\", function() {\n Ember.run(function() { array.unshiftObject(6); });\n deepEqual(array.get('content'), [6,1,2,4,5], 'adds to start of content');\n});\n\ntest(\"unshiftObjects - adds to start of content\", function() {\n Ember.run(function() { array.unshiftObjects([6,7]); });\n deepEqual(array.get('content'), [6,7,1,2,4,5], 'adds to start of content');\n});\n\ntest(\"without - returns arrangedContent without object\", function() {\n deepEqual(array.without(2), [5,4,1], 'returns arranged without object');\n});\n\ntest(\"lastObject - returns last arranged object\", function() {\n equal(array.get('lastObject'), 1, 'returns last arranged object');\n});\n\ntest(\"firstObject - returns first arranged object\", function() {\n equal(array.get('firstObject'), 5, 'returns first arranged object');\n});\n\n\nmodule(\"Ember.ArrayProxy - arrangedContent matching content\", {\n setup: function() {\n Ember.run(function() {\n array = Ember.ArrayProxy.createWithMixins({\n content: Ember.A([1,2,4,5])\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n array.destroy();\n });\n }\n});\n\ntest(\"insertAt - inserts object at specified index\", function() {\n Ember.run(function() { array.insertAt(2, 3); });\n deepEqual(array.get('content'), [1,2,3,4,5]);\n});\n\ntest(\"replace - does a standard array replace\", function() {\n Ember.run(function() { array.replace(1, 2, [3]); });\n deepEqual(array.get('content'), [1,3,5]);\n});\n\ntest(\"reverseObjects - reverses content\", function() {\n Ember.run(function() { array.reverseObjects(); });\n deepEqual(array.get('content'), [5,4,2,1]);\n});\n\nmodule(\"Ember.ArrayProxy - arrangedContent with transforms\", {\n setup: function() {\n Ember.run(function() {\n array = Ember.ArrayProxy.createWithMixins({\n content: Ember.A([1,2,4,5]),\n\n arrangedContent: Ember.computed(function() {\n var content = this.get('content');\n return content && Ember.A(content.slice().sort(function(a,b) {\n if (a == null) { a = -1; }\n if (b == null) { b = -1; }\n return b - a;\n }));\n }).property('content.[]'),\n\n objectAtContent: function(idx) {\n var obj = this.get('arrangedContent').objectAt(idx);\n return obj && obj.toString();\n }\n });\n });\n },\n teardown: function() {\n Ember.run(function() {\n array.destroy();\n });\n }\n});\n\ntest(\"indexOf - returns index of object in arrangedContent\", function() {\n equal(array.indexOf('4'), 1, 'returns arranged index');\n});\n\ntest(\"lastIndexOf - returns last index of object in arrangedContent\", function() {\n Ember.run(function() { array.pushObject(4); });\n equal(array.lastIndexOf('4'), 2, 'returns last arranged index');\n});\n\ntest(\"nextObject - returns object at index in arrangedContent\", function() {\n equal(array.nextObject(1), '4', 'returns object at index');\n});\n\ntest(\"objectAt - returns object at index in arrangedContent\", function() {\n equal(array.objectAt(1), '4', 'returns object at index');\n});\n\n// Not sure if we need a specific test for it, since it's internal\ntest(\"objectAtContent - returns object at index in arrangedContent\", function() {\n equal(array.objectAtContent(1), '4', 'returns object at index');\n});\n\ntest(\"objectsAt - returns objects at indices in arrangedContent\", function() {\n deepEqual(array.objectsAt([0,2,4]), ['5','2',undefined], 'returns objects at indices');\n});\n\ntest(\"popObject - removes last object in arrangedContent\", function() {\n var popped;\n Ember.run(function() { popped = array.popObject(); });\n equal(popped, '1', 'returns last object');\n deepEqual(array.get('content'), [2,4,5], 'removes from content');\n});\n\ntest(\"removeObject - removes object from content\", function() {\n Ember.run(function() { array.removeObject('2'); });\n deepEqual(array.get('content'), [1,4,5]);\n});\n\ntest(\"removeObjects - removes objects from content\", function() {\n Ember.run(function() { array.removeObjects(['2','4','6']); });\n deepEqual(array.get('content'), [1,5]);\n});\n\ntest(\"shiftObject - removes from start of arrangedContent\", function() {\n var shifted;\n Ember.run(function() { shifted = array.shiftObject(); });\n equal(shifted, '5', 'returns first object');\n deepEqual(array.get('content'), [1,2,4], 'removes object from content');\n});\n\ntest(\"slice - returns a slice of the arrangedContent\", function() {\n deepEqual(array.slice(1,3), ['4','2'], 'returns sliced arrangedContent');\n});\n\ntest(\"toArray - returns copy of arrangedContent\", function() {\n deepEqual(array.toArray(), ['5','4','2','1']);\n});\n\ntest(\"without - returns arrangedContent without object\", function() {\n deepEqual(array.without('2'), ['5','4','1'], 'returns arranged without object');\n});\n\ntest(\"lastObject - returns last arranged object\", function() {\n equal(array.get('lastObject'), '1', 'returns last arranged object');\n});\n\ntest(\"firstObject - returns first arranged object\", function() {\n equal(array.get('firstObject'), '5', 'returns first arranged object');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/array_proxy/arranged_content_test");minispade.register('ember-runtime/~tests/system/array_proxy/content_change_test', "(function() {module(\"Ember.ArrayProxy - content change\");\n\ntest(\"should update length for null content\", function() {\n var proxy = Ember.ArrayProxy.create({\n content: Ember.A([1,2,3])\n });\n\n equal(proxy.get('length'), 3, \"precond - length is 3\");\n\n proxy.set('content', null);\n\n equal(proxy.get('length'), 0, \"length updates\");\n});\n\ntest(\"The `arrangedContentWillChange` method is invoked before `content` is changed.\", function() {\n var callCount = 0,\n expectedLength;\n\n var proxy = Ember.ArrayProxy.extend({\n content: Ember.A([1, 2, 3]),\n\n arrangedContentWillChange: function() {\n equal(this.get('arrangedContent.length'), expectedLength, \"hook should be invoked before array has changed\");\n callCount++;\n }\n }).create();\n\n proxy.pushObject(4);\n equal(callCount, 0, \"pushing content onto the array doesn't trigger it\");\n\n proxy.get('content').pushObject(5);\n equal(callCount, 0, \"pushing content onto the content array doesn't trigger it\");\n\n expectedLength = 5;\n proxy.set('content', Ember.A(['a', 'b']));\n equal(callCount, 1, \"replacing the content array triggers the hook\");\n});\n\ntest(\"The `arrangedContentDidChange` method is invoked after `content` is changed.\", function() {\n var callCount = 0,\n expectedLength;\n\n var proxy = Ember.ArrayProxy.extend({\n content: Ember.A([1, 2, 3]),\n\n arrangedContentDidChange: function() {\n equal(this.get('arrangedContent.length'), expectedLength, \"hook should be invoked after array has changed\");\n callCount++;\n }\n }).create();\n\n equal(callCount, 0, \"hook is not called after creating the object\");\n\n proxy.pushObject(4);\n equal(callCount, 0, \"pushing content onto the array doesn't trigger it\");\n\n proxy.get('content').pushObject(5);\n equal(callCount, 0, \"pushing content onto the content array doesn't trigger it\");\n\n expectedLength = 2;\n proxy.set('content', Ember.A(['a', 'b']));\n equal(callCount, 1, \"replacing the content array triggers the hook\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/array_proxy/content_change_test");minispade.register('ember-runtime/~tests/system/array_proxy/content_update_test', "(function() {// ==========================================================================\n// Project: Ember Runtime\n// Copyright: ©2011 Strobe Inc. and contributors.\n// License: Licensed under MIT license (see license.js)\n// ==========================================================================\n\nmodule(\"Ember.ArrayProxy - content update\");\n\ntest(\"The `contentArrayDidChange` method is invoked after `content` is updated.\", function() {\n\n var proxy, observerCalled = false;\n\n proxy = Ember.ArrayProxy.createWithMixins({\n content: Ember.A(),\n\n arrangedContent: Ember.computed('content', function(key, value) {\n // setup arrangedContent as a different object than content,\n // which is the default\n return Ember.A(this.get('content').slice());\n }),\n\n contentArrayDidChange: function(array, idx, removedCount, addedCount) {\n observerCalled = true;\n return this._super(array, idx, removedCount, addedCount);\n }\n });\n\n proxy.pushObject(1);\n\n ok(observerCalled, \"contentArrayDidChange is invoked\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/array_proxy/content_update_test");minispade.register('ember-runtime/~tests/system/array_proxy/suite_test', "(function() {Ember.MutableArrayTests.extend({\n\n name: 'Ember.ArrayProxy',\n\n newObject: function(ary) {\n var ret = ary ? ary.slice() : this.newFixture(3);\n return Ember.ArrayProxy.create({ content: Ember.A(ret) });\n },\n\n mutate: function(obj) {\n obj.pushObject(Ember.get(obj, 'length')+1);\n },\n\n toArray: function(obj) {\n return obj.toArray ? obj.toArray() : obj.slice();\n }\n\n}).run();\n\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/array_proxy/suite_test");minispade.register('ember-runtime/~tests/system/deferred_test', "(function() {module(\"Ember.Deferred all-in-one\");\n\nasyncTest(\"Can resolve a promise\", function() {\n var value = { value: true };\n\n var promise = Ember.Deferred.promise(function(deferred) {\n setTimeout(function() {\n Ember.run(function() { deferred.resolve(value); });\n });\n });\n\n promise.then(function(resolveValue) {\n start();\n equal(resolveValue, value, \"The resolved value should be correct\");\n });\n});\n\nasyncTest(\"Can reject a promise\", function() {\n var rejected = { rejected: true };\n\n var promise = Ember.Deferred.promise(function(deferred) {\n setTimeout(function() {\n Ember.run(function() { deferred.reject(rejected); });\n });\n });\n\n promise.then(null, function(rejectedValue) {\n start();\n equal(rejectedValue, rejected, \"The resolved value should be correct\");\n });\n});\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/deferred_test");minispade.register('ember-runtime/~tests/system/lazy_load_test', "(function() {module(\"Lazy Loading\");\n\ntest(\"if a load hook is registered, it is executed when runLoadHooks are exected\", function() {\n var count = 0;\n\n Ember.run(function() {\n Ember.onLoad(\"__test_hook__\", function(object) {\n count += object;\n });\n });\n\n Ember.run(function() {\n Ember.runLoadHooks(\"__test_hook__\", 1);\n });\n\n equal(count, 1, \"the object was passed into the load hook\");\n});\n\ntest(\"if runLoadHooks was already run, it executes newly added hooks immediately\", function() {\n var count = 0;\n Ember.run(function() {\n Ember.onLoad(\"__test_hook__\", function(object) {\n count += object;\n });\n });\n\n Ember.run(function() {\n Ember.runLoadHooks(\"__test_hook__\", 1);\n });\n\n count = 0;\n Ember.run(function() {\n Ember.onLoad(\"__test_hook__\", function(object) {\n count += object;\n });\n });\n\n equal(count, 1, \"the original object was passed into the load hook\");\n});\n\ntest(\"hooks in ENV.EMBER_LOAD_HOOKS['hookName'] get executed\", function() {\n\n // Note that the necessary code to perform this test is run before\n // the Ember lib is loaded in tests/index.html\n\n Ember.run(function() {\n Ember.runLoadHooks(\"__before_ember_test_hook__\", 1);\n });\n\n equal(window.ENV.__test_hook_count__, 1, \"the object was passed into the load hook\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/lazy_load_test");minispade.register('ember-runtime/~tests/system/namespace/base_test', "(function() {// ==========================================================================\n// Project: Ember Runtime\n// ==========================================================================\n\nvar get = Ember.get, originalLookup = Ember.lookup, lookup;\n\nmodule('Ember.Namespace', {\n setup: function() {\n Ember.BOOTED = false;\n\n lookup = Ember.lookup = {};\n },\n teardown: function() {\n Ember.BOOTED = false;\n\n if (lookup.NamespaceA) { Ember.run(function() { lookup.NamespaceA.destroy(); }); }\n if (lookup.NamespaceB) { Ember.run(function() { lookup.NamespaceB.destroy(); }); }\n if (lookup.namespaceC) {\n try {\n Ember.TESTING_DEPRECATION = true;\n Ember.run(function() {\n lookup.namespaceC.destroy();\n });\n } finally {\n Ember.TESTING_DEPRECATION = false;\n }\n }\n\n Ember.lookup = originalLookup;\n }\n});\n\ntest('Ember.Namespace should be a subclass of Ember.Object', function() {\n ok(Ember.Object.detect(Ember.Namespace));\n});\n\ntest(\"Ember.Namespace should be duck typed\", function() {\n ok(get(Ember.Namespace.create(), 'isNamespace'), \"isNamespace property is true\");\n});\n\ntest('Ember.Namespace is found and named', function() {\n var nsA = lookup.NamespaceA = Ember.Namespace.create();\n equal(nsA.toString(), \"NamespaceA\", \"namespaces should have a name if they are on lookup\");\n\n var nsB = lookup.NamespaceB = Ember.Namespace.create();\n equal(nsB.toString(), \"NamespaceB\", \"namespaces work if created after the first namespace processing pass\");\n});\n\ntest(\"Classes under an Ember.Namespace are properly named\", function() {\n var nsA = lookup.NamespaceA = Ember.Namespace.create();\n nsA.Foo = Ember.Object.extend();\n equal(nsA.Foo.toString(), \"NamespaceA.Foo\", \"Classes pick up their parent namespace\");\n\n nsA.Bar = Ember.Object.extend();\n equal(nsA.Bar.toString(), \"NamespaceA.Bar\", \"New Classes get the naming treatment too\");\n\n var nsB = lookup.NamespaceB = Ember.Namespace.create();\n nsB.Foo = Ember.Object.extend();\n equal(nsB.Foo.toString(), \"NamespaceB.Foo\", \"Classes in new namespaces get the naming treatment\");\n});\n\ntest(\"Classes under Ember are properly named\", function() {\n equal(Ember.Array.toString(), \"Ember.Array\", \"precond - existing classes are processed\");\n\n Ember.TestObject = Ember.Object.extend({});\n equal(Ember.TestObject.toString(), \"Ember.TestObject\", \"class under Ember is given a string representation\");\n});\n\ntest(\"Lowercase namespaces should be deprecated\", function() {\n lookup.namespaceC = Ember.Namespace.create();\n\n var originalWarn = Ember.Logger.warn,\n loggerWarning;\n\n Ember.Logger.warn = function(msg) { loggerWarning = msg; };\n\n try {\n lookup.namespaceC.toString();\n } finally {\n Ember.Logger.warn = originalWarn;\n }\n\n // Ignore backtrace\n equal(loggerWarning.split(\"\\n\")[0], \"DEPRECATION: Namespaces should not begin with lowercase.\");\n});\n\ntest(\"A namespace can be assigned a custom name\", function() {\n var nsA = Ember.Namespace.create({\n name: \"NamespaceA\"\n });\n\n var nsB = lookup.NamespaceB = Ember.Namespace.create({\n name: \"CustomNamespaceB\"\n });\n\n nsA.Foo = Ember.Object.extend();\n nsB.Foo = Ember.Object.extend();\n\n equal(nsA.Foo.toString(), \"NamespaceA.Foo\", \"The namespace's name is used when the namespace is not in the lookup object\");\n equal(nsB.Foo.toString(), \"CustomNamespaceB.Foo\", \"The namespace's name is used when the namespace is in the lookup object\");\n});\n\ntest(\"Calling namespace.nameClasses() eagerly names all classes\", function() {\n Ember.BOOTED = true;\n\n var namespace = lookup.NS = Ember.Namespace.create();\n\n namespace.ClassA = Ember.Object.extend();\n namespace.ClassB = Ember.Object.extend();\n\n Ember.Namespace.processAll();\n\n equal(namespace.ClassA.toString(), \"NS.ClassA\");\n equal(namespace.ClassB.toString(), \"NS.ClassB\");\n});\n\ntest(\"A namespace can be looked up by its name\", function() {\n var NS = lookup.NS = Ember.Namespace.create();\n var UI = lookup.UI = Ember.Namespace.create();\n var CF = lookup.CF = Ember.Namespace.create();\n\n equal(Ember.Namespace.byName('NS'), NS);\n equal(Ember.Namespace.byName('UI'), UI);\n equal(Ember.Namespace.byName('CF'), CF);\n});\n\ntest(\"A nested namespace can be looked up by its name\", function() {\n var UI = lookup.UI = Ember.Namespace.create();\n UI.Nav = Ember.Namespace.create();\n\n equal(Ember.Namespace.byName('UI.Nav'), UI.Nav);\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/namespace/base_test");minispade.register('ember-runtime/~tests/system/native_array/copyable_suite_test', "(function() {// ..........................................................\n// COPYABLE TESTS\n//\nEmber.CopyableTests.extend({\n name: 'NativeArray Copyable',\n\n newObject: function() {\n return Ember.A([Ember.generateGuid()]);\n },\n\n isEqual: function(a,b) {\n if (!(a instanceof Array)) return false;\n if (!(b instanceof Array)) return false;\n if (a.length !== b.length) return false;\n return a[0]===b[0];\n },\n\n shouldBeFreezable: false\n}).run();\n\nmodule(\"NativeArray Copyable\");\n\ntest(\"deep copy is respected\", function() {\n var array = Ember.A([ { id: 1 }, { id: 2 }, { id: 3 } ]);\n\n var copiedArray = array.copy(true);\n\n deepEqual(copiedArray, array, \"copied array is equivalent\");\n ok(copiedArray[0] !== array[0], \"objects inside should be unique\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/native_array/copyable_suite_test");minispade.register('ember-runtime/~tests/system/native_array/suite_test', "(function() {Ember.MutableArrayTests.extend({\n\n name: 'Native Array',\n\n newObject: function(ary) {\n return Ember.A(ary ? ary.slice() : this.newFixture(3));\n },\n\n mutate: function(obj) {\n obj.pushObject(obj.length+1);\n },\n\n toArray: function(obj) {\n return obj.slice(); // make a copy.\n }\n\n}).run();\n\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/native_array/suite_test");minispade.register('ember-runtime/~tests/system/object/computed_test', "(function() {minispade.require('ember-runtime/~tests/props_helper');\n\nmodule('Ember.Object computed property');\n\ntestWithDefault('computed property on instance', function(get, set) {\n\n var MyClass = Ember.Object.extend({\n foo: Ember.computed(function() { return 'FOO'; })\n });\n\n equal(get(new MyClass(), 'foo'), 'FOO');\n\n});\n\n\ntestWithDefault('computed property on subclass', function(get, set) {\n\n var MyClass = Ember.Object.extend({\n foo: Ember.computed(function() { return 'FOO'; })\n });\n\n var Subclass = MyClass.extend({\n foo: Ember.computed(function() { return 'BAR'; })\n });\n\n equal(get(new Subclass(), 'foo'), 'BAR');\n\n});\n\n\ntestWithDefault('replacing computed property with regular val', function(get, set) {\n\n var MyClass = Ember.Object.extend({\n foo: Ember.computed(function() { return 'FOO'; })\n });\n\n var Subclass = MyClass.extend({\n foo: 'BAR'\n });\n\n equal(get(new Subclass(), 'foo'), 'BAR');\n\n});\n\ntestWithDefault('complex depndent keys', function(get, set) {\n\n var MyClass = Ember.Object.extend({\n\n init: function() {\n this._super();\n set(this, 'bar', { baz: 'BIFF' });\n },\n\n count: 0,\n\n foo: Ember.computed(function() {\n set(this, 'count', get(this, 'count')+1);\n return Ember.get(get(this, 'bar'), 'baz') + ' ' + get(this, 'count');\n }).property('bar.baz')\n\n });\n\n var Subclass = MyClass.extend({\n count: 20\n });\n\n var obj1 = new MyClass(),\n obj2 = new Subclass();\n\n equal(get(obj1, 'foo'), 'BIFF 1');\n equal(get(obj2, 'foo'), 'BIFF 21');\n\n set(get(obj1, 'bar'), 'baz', 'BLARG');\n\n equal(get(obj1, 'foo'), 'BLARG 2');\n equal(get(obj2, 'foo'), 'BIFF 21');\n\n set(get(obj2, 'bar'), 'baz', 'BOOM');\n\n equal(get(obj1, 'foo'), 'BLARG 2');\n equal(get(obj2, 'foo'), 'BOOM 22');\n});\n\ntestWithDefault('complex depndent keys changing complex dependent keys', function(get, set) {\n\n var MyClass = Ember.Object.extend({\n\n init: function() {\n this._super();\n set(this, 'bar', { baz: 'BIFF' });\n },\n\n count: 0,\n\n foo: Ember.computed(function() {\n set(this, 'count', get(this, 'count')+1);\n return Ember.get(get(this, 'bar'), 'baz') + ' ' + get(this, 'count');\n }).property('bar.baz')\n\n });\n\n var Subclass = MyClass.extend({\n\n init: function() {\n this._super();\n set(this, 'bar2', { baz: 'BIFF2' });\n },\n\n count: 0,\n\n foo: Ember.computed(function() {\n set(this, 'count', get(this, 'count')+1);\n return Ember.get(get(this, 'bar2'), 'baz') + ' ' + get(this, 'count');\n }).property('bar2.baz')\n });\n\n var obj2 = new Subclass();\n\n equal(get(obj2, 'foo'), 'BIFF2 1');\n\n set(get(obj2, 'bar'), 'baz', 'BLARG');\n equal(get(obj2, 'foo'), 'BIFF2 1', 'should not invalidate property');\n\n set(get(obj2, 'bar2'), 'baz', 'BLARG');\n equal(get(obj2, 'foo'), 'BLARG 2', 'should invalidate property');\n});\n\ntest(\"can retrieve metadata for a computed property\", function() {\n var get = Ember.get;\n\n var MyClass = Ember.Object.extend({\n computedProperty: Ember.computed(function() {\n }).meta({ key: 'keyValue' })\n });\n\n equal(get(MyClass.metaForProperty('computedProperty'), 'key'), 'keyValue', \"metadata saved on the computed property can be retrieved\");\n\n var ClassWithNoMetadata = Ember.Object.extend({\n computedProperty: Ember.computed(function() {\n }).volatile(),\n\n staticProperty: 12\n });\n\n equal(typeof ClassWithNoMetadata.metaForProperty('computedProperty'), \"object\", \"returns empty hash if no metadata has been saved\");\n\n expectAssertion(function() {\n ClassWithNoMetadata.metaForProperty('nonexistentProperty');\n }, \"metaForProperty() could not find a computed property with key 'nonexistentProperty'.\");\n\n expectAssertion(function() {\n ClassWithNoMetadata.metaForProperty('staticProperty');\n }, \"metaForProperty() could not find a computed property with key 'staticProperty'.\");\n});\n\ntestBoth(\"can iterate over a list of computed properties for a class\", function(get, set) {\n var MyClass = Ember.Object.extend({\n foo: Ember.computed(function() {\n\n }),\n\n fooDidChange: Ember.observer('foo', function() {\n\n }),\n\n bar: Ember.computed(function() {\n\n })\n });\n\n var SubClass = MyClass.extend({\n baz: Ember.computed(function() {\n\n })\n });\n\n SubClass.reopen({\n bat: Ember.computed(function() {\n\n }).meta({ iAmBat: true })\n });\n\n var list = [];\n\n MyClass.eachComputedProperty(function(name) {\n list.push(name);\n });\n\n deepEqual(list.sort(), ['bar', 'foo'], \"watched and unwatched computed properties are iterated\");\n\n list = [];\n\n SubClass.eachComputedProperty(function(name, meta) {\n list.push(name);\n\n if (name === 'bat') {\n deepEqual(meta, { iAmBat: true });\n } else {\n deepEqual(meta, {});\n }\n });\n\n deepEqual(list.sort(), ['bar', 'bat', 'baz', 'foo'], \"all inherited properties are included\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/computed_test");minispade.register('ember-runtime/~tests/system/object/create_test', "(function() {/*globals TestObject:true */\n\nmodule('Ember.Object.create');\n\ntest(\"simple properties are set\", function() {\n var o = Ember.Object.create({ohai: 'there'});\n equal(o.get('ohai'), 'there');\n});\n\ntest(\"calls computed property setters\", function() {\n var MyClass = Ember.Object.extend({\n foo: Ember.computed(function(key, val) {\n if (arguments.length === 2) { return val; }\n return \"this is not the value you're looking for\";\n })\n });\n\n var o = MyClass.create({foo: 'bar'});\n equal(o.get('foo'), 'bar');\n});\n\ntest(\"sets up mandatory setters for watched simple properties\", function() {\n var MyClass = Ember.Object.extend({\n foo: null,\n bar: null,\n fooDidChange: Ember.observer('foo', function() {})\n });\n\n var o = MyClass.create({foo: 'bar', bar: 'baz'});\n equal(o.get('foo'), 'bar');\n\n // Catch IE8 where Object.getOwnPropertyDescriptor exists but only works on DOM elements\n try {\n Object.getOwnPropertyDescriptor({}, 'foo');\n } catch(e) {\n return;\n }\n\n var descriptor = Object.getOwnPropertyDescriptor(o, 'foo');\n ok(descriptor.set, 'Mandatory setter was setup');\n\n descriptor = Object.getOwnPropertyDescriptor(o, 'bar');\n ok(!descriptor.set, 'Mandatory setter was not setup');\n});\n\ntest(\"allows bindings to be defined\", function() {\n var obj = Ember.Object.create({\n foo: 'foo',\n barBinding: 'foo'\n });\n\n equal(obj.get('bar'), 'foo', 'The binding value is correct');\n});\n\ntest(\"calls setUnknownProperty if defined\", function() {\n var setUnknownPropertyCalled = false;\n\n var MyClass = Ember.Object.extend({\n setUnknownProperty: function(key, value) {\n setUnknownPropertyCalled = true;\n }\n });\n\n var o = MyClass.create({foo: 'bar'});\n ok(setUnknownPropertyCalled, 'setUnknownProperty was called');\n});\n\ntest(\"throws if you try to define a computed property\", function() {\n expectAssertion(function() {\n Ember.Object.create({\n foo: Ember.computed(function() {})\n });\n }, 'Ember.Object.create no longer supports defining computed properties.');\n});\n\ntest(\"throws if you try to call _super in a method\", function() {\n expectAssertion(function() {\n Ember.Object.create({\n foo: function() {\n this._super();\n }\n });\n }, 'Ember.Object.create no longer supports defining methods that call _super.');\n});\n\ntest(\"throws if you try to 'mixin' a definition\", function() {\n var myMixin = Ember.Mixin.create({\n adder: function(arg1, arg2) {\n return arg1 + arg2;\n }\n });\n\n expectAssertion(function() {\n var o = Ember.Object.create(myMixin);\n }, \"Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.\");\n});\n\n// This test is for IE8.\ntest(\"property name is the same as own prototype property\", function() {\n var MyClass = Ember.Object.extend({\n toString: function() { return 'MyClass'; }\n });\n\n equal(MyClass.create().toString(), 'MyClass', \"should inherit property from the arguments of `Ember.Object.create`\");\n});\n\ntest(\"inherits properties from passed in Ember.Object\", function() {\n var baseObj = Ember.Object.create({ foo: 'bar' }),\n secondaryObj = Ember.Object.create(baseObj);\n\n equal(secondaryObj.foo, baseObj.foo, \"Em.O.create inherits properties from Ember.Object parameter\");\n});\n\ntest(\"throws if you try to pass anything other than an object or instance of Ember.Object\", function(){\n var expected = \"Ember.Object.create only accepts objects.\";\n\n expectAssertion(function() {\n var o = Ember.Object.create(\"some-string\");\n }, expected);\n\n expectAssertion(function() {\n var o = Ember.Object.create(null);\n }, expected);\n});\n\nmodule('Ember.Object.createWithMixins');\n\ntest(\"Creates a new object that contains passed properties\", function() {\n\n var called = false;\n var obj = Ember.Object.createWithMixins({\n prop: 'FOO',\n method: function() { called=true; }\n });\n\n equal(Ember.get(obj, 'prop'), 'FOO', 'obj.prop');\n obj.method();\n ok(called, 'method executed');\n});\n\n// ..........................................................\n// WORKING WITH MIXINS\n//\n\ntest(\"Creates a new object that includes mixins and properties\", function() {\n\n var MixinA = Ember.Mixin.create({ mixinA: 'A' });\n var obj = Ember.Object.createWithMixins(MixinA, { prop: 'FOO' });\n\n equal(Ember.get(obj, 'mixinA'), 'A', 'obj.mixinA');\n equal(Ember.get(obj, 'prop'), 'FOO', 'obj.prop');\n});\n\n// ..........................................................\n// LIFECYCLE\n//\n\ntest(\"Configures _super() on methods with override\", function() {\n var completed = false;\n var MixinA = Ember.Mixin.create({ method: function() {} });\n var obj = Ember.Object.createWithMixins(MixinA, {\n method: function() {\n this._super();\n completed = true;\n }\n });\n\n obj.method();\n ok(completed, 'should have run method without error');\n});\n\ntest(\"Calls init if defined\", function() {\n var completed = false;\n var obj = Ember.Object.createWithMixins({\n init: function() {\n this._super();\n completed = true;\n }\n });\n\n ok(completed, 'should have run init without error');\n});\n\ntest(\"Calls all mixin inits if defined\", function() {\n var completed = 0;\n var Mixin1 = Ember.Mixin.create({\n init: function() { this._super(); completed++; }\n });\n\n var Mixin2 = Ember.Mixin.create({\n init: function() { this._super(); completed++; }\n });\n\n Ember.Object.createWithMixins(Mixin1, Mixin2);\n equal(completed, 2, 'should have called init for both mixins.');\n});\n\ntest(\"Triggers init\", function() {\n var completed = false;\n var obj = Ember.Object.createWithMixins({\n markAsCompleted: Ember.on(\"init\", function(){\n completed = true;\n })\n });\n\n ok(completed, 'should have triggered init which should have run markAsCompleted');\n});\n\ntest('creating an object with required properties', function() {\n var ClassA = Ember.Object.extend({\n foo: Ember.required()\n });\n\n var obj = ClassA.createWithMixins({ foo: 'FOO' }); // should not throw\n equal(Ember.get(obj,'foo'), 'FOO');\n});\n\n\n// ..........................................................\n// BUGS\n//\n\ntest('create should not break observed values', function() {\n\n var CountObject = Ember.Object.extend({\n value: null,\n\n _count: 0,\n\n reset: function() {\n this._count = 0;\n return this;\n },\n\n valueDidChange: Ember.observer('value', function() {\n this._count++;\n })\n });\n\n var obj = CountObject.createWithMixins({ value: 'foo' });\n equal(obj._count, 0, 'should not fire yet');\n\n Ember.set(obj, 'value', 'BAR');\n equal(obj._count, 1, 'should fire');\n});\n\ntest('bindings on a class should only sync on instances', function() {\n TestObject = Ember.Object.createWithMixins({\n foo: 'FOO'\n });\n\n var Class, inst;\n\n Ember.run(function() {\n Class = Ember.Object.extend({\n fooBinding: 'TestObject.foo'\n });\n\n inst = Class.createWithMixins();\n });\n\n equal(Ember.get(Class.prototype, 'foo'), undefined, 'should not sync binding');\n equal(Ember.get(inst, 'foo'), 'FOO', 'should sync binding');\n\n});\n\n\ntest('inherited bindings should only sync on instances', function() {\n TestObject = Ember.Object.createWithMixins({\n foo: 'FOO'\n });\n\n var Class, Subclass, inst;\n\n Ember.run(function() {\n Class = Ember.Object.extend({\n fooBinding: 'TestObject.foo'\n });\n });\n\n Ember.run(function() {\n Subclass = Class.extend();\n inst = Subclass.createWithMixins();\n });\n\n equal(Ember.get(Class.prototype, 'foo'), undefined, 'should not sync binding on Class');\n equal(Ember.get(Subclass.prototype, 'foo'), undefined, 'should not sync binding on Subclass');\n equal(Ember.get(inst, 'foo'), 'FOO', 'should sync binding on inst');\n\n Ember.run(function() {\n Ember.set(TestObject, 'foo', 'BAR');\n });\n\n equal(Ember.get(Class.prototype, 'foo'), undefined, 'should not sync binding on Class');\n equal(Ember.get(Subclass.prototype, 'foo'), undefined, 'should not sync binding on Subclass');\n equal(Ember.get(inst, 'foo'), 'BAR', 'should sync binding on inst');\n\n});\n\ntest(\"created objects should not share a guid with their superclass\", function() {\n ok(Ember.guidFor(Ember.Object), \"Ember.Object has a guid\");\n\n var objA = Ember.Object.createWithMixins(),\n objB = Ember.Object.createWithMixins();\n\n ok(Ember.guidFor(objA) !== Ember.guidFor(objB), \"two instances do not share a guid\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/create_test");minispade.register('ember-runtime/~tests/system/object/destroy_test', "(function() {/*globals raises */\n\nmodule('ember-runtime/system/object/destroy_test');\n\ntestBoth(\"should schedule objects to be destroyed at the end of the run loop\", function(get, set) {\n var obj = Ember.Object.create(), meta;\n\n Ember.run(function() {\n obj.destroy();\n meta = obj[Ember.META_KEY];\n ok(meta, \"meta is not destroyed immediately\");\n ok(get(obj, 'isDestroying'), \"object is marked as destroying immediately\");\n ok(!get(obj, 'isDestroyed'), \"object is not destroyed immediately\");\n });\n\n meta = obj[Ember.META_KEY];\n ok(!meta, \"meta is destroyed after run loop finishes\");\n ok(get(obj, 'isDestroyed'), \"object is destroyed after run loop finishes\");\n});\n\ntest(\"should raise an exception when modifying watched properties on a destroyed object\", function() {\n if (Ember.platform.hasAccessors) {\n var obj = Ember.Object.createWithMixins({\n foo: \"bar\",\n fooDidChange: Ember.observer('foo', function() { })\n });\n\n Ember.run(function() {\n obj.destroy();\n });\n\n raises(function() {\n Ember.set(obj, 'foo', 'baz');\n }, Error, \"raises an exception\");\n } else {\n expect(0);\n }\n});\n\ntest(\"observers should not fire after an object has been destroyed\", function() {\n var count = 0;\n var obj = Ember.Object.createWithMixins({\n fooDidChange: Ember.observer('foo', function() {\n count++;\n })\n });\n\n obj.set('foo', 'bar');\n\n equal(count, 1, \"observer was fired once\");\n\n Ember.run(function() {\n Ember.beginPropertyChanges();\n obj.set('foo', 'quux');\n obj.destroy();\n Ember.endPropertyChanges();\n });\n\n equal(count, 1, \"observer was not called after object was destroyed\");\n});\n\ntest(\"destroyed objects should not see each others changes during teardown but a long lived object should\", function () {\n var shouldChange = 0, shouldNotChange = 0;\n\n var objs = {};\n\n var A = Ember.Object.extend({\n objs: objs,\n isAlive: true,\n willDestroy: function () {\n this.set('isAlive', false);\n },\n bDidChange: Ember.observer('objs.b.isAlive', function () {\n shouldNotChange++;\n }),\n cDidChange: Ember.observer('objs.c.isAlive', function () {\n shouldNotChange++;\n })\n });\n\n var B = Ember.Object.extend({\n objs: objs,\n isAlive: true,\n willDestroy: function () {\n this.set('isAlive', false);\n },\n aDidChange: Ember.observer('objs.a.isAlive', function () {\n shouldNotChange++;\n }),\n cDidChange: Ember.observer('objs.c.isAlive', function () {\n shouldNotChange++;\n })\n });\n\n var C = Ember.Object.extend({\n objs: objs,\n isAlive: true,\n willDestroy: function () {\n this.set('isAlive', false);\n },\n aDidChange: Ember.observer('objs.a.isAlive', function () {\n shouldNotChange++;\n }),\n bDidChange: Ember.observer('objs.b.isAlive', function () {\n shouldNotChange++;\n })\n });\n\n var LongLivedObject = Ember.Object.extend({\n objs: objs,\n isAliveDidChange: Ember.observer('objs.a.isAlive', function () {\n shouldChange++;\n })\n });\n\n objs.a = new A();\n\n objs.b = new B();\n\n objs.c = new C();\n\n var longLivedObject = new LongLivedObject();\n\n Ember.run(function () {\n var keys = Ember.keys(objs);\n for (var i = 0, l = keys.length; i < l; i++) {\n objs[keys[i]].destroy();\n }\n });\n\n equal(shouldNotChange, 0, 'destroyed graph objs should not see change in willDestroy');\n equal(shouldChange, 1, 'long lived should see change in willDestroy');\n});\n\ntest(\"bindings should be synced when are updated in the willDestroy hook\", function() {\n var bar = Ember.Object.create({\n value: false,\n willDestroy: function() {\n this.set('value', true);\n }\n });\n\n var foo = Ember.Object.create({\n value: null,\n bar: bar\n });\n\n Ember.run(function() {\n Ember.bind(foo, 'value', 'bar.value');\n });\n\n ok(bar.get('value') === false, 'the initial value has been bound');\n\n Ember.run(function() {\n bar.destroy();\n });\n\n ok(foo.get('value'), 'foo is synced when the binding is updated in the willDestroy hook');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/destroy_test");minispade.register('ember-runtime/~tests/system/object/detectInstance_test', "(function() {module('system/object/detectInstance');\n\ntest('detectInstance detects instances correctly', function() {\n\n var A = Ember.Object.extend();\n var B = A.extend();\n var C = A.extend();\n\n var o = Ember.Object.create(),\n a = A.create(),\n b = B.create(),\n c = C.create();\n\n ok( Ember.Object.detectInstance(o), 'o is an instance of Ember.Object' );\n ok( Ember.Object.detectInstance(a), 'a is an instance of Ember.Object' );\n ok( Ember.Object.detectInstance(b), 'b is an instance of Ember.Object' );\n ok( Ember.Object.detectInstance(c), 'c is an instance of Ember.Object' );\n\n ok( !A.detectInstance(o), 'o is not an instance of A');\n ok( A.detectInstance(a), 'a is an instance of A' );\n ok( A.detectInstance(b), 'b is an instance of A' );\n ok( A.detectInstance(c), 'c is an instance of A' );\n\n ok( !B.detectInstance(o), 'o is not an instance of B' );\n ok( !B.detectInstance(a), 'a is not an instance of B' );\n ok( B.detectInstance(b), 'b is an instance of B' );\n ok( !B.detectInstance(c), 'c is not an instance of B' );\n\n ok( !C.detectInstance(o), 'o is not an instance of C' );\n ok( !C.detectInstance(a), 'a is not an instance of C' );\n ok( !C.detectInstance(b), 'b is not an instance of C' );\n ok( C.detectInstance(c), 'c is an instance of C' );\n\n});\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/detectInstance_test");minispade.register('ember-runtime/~tests/system/object/detect_test', "(function() {module('system/object/detect');\n\ntest('detect detects classes correctly', function() {\n\n var A = Ember.Object.extend();\n var B = A.extend();\n var C = A.extend();\n\n ok( Ember.Object.detect(Ember.Object), 'Ember.Object is an Ember.Object class' );\n ok( Ember.Object.detect(A), 'A is an Ember.Object class' );\n ok( Ember.Object.detect(B), 'B is an Ember.Object class' );\n ok( Ember.Object.detect(C), 'C is an Ember.Object class' );\n\n ok( !A.detect(Ember.Object), 'Ember.Object is not an A class' );\n ok( A.detect(A), 'A is an A class' );\n ok( A.detect(B), 'B is an A class' );\n ok( A.detect(C), 'C is an A class' );\n\n ok( !B.detect(Ember.Object), 'Ember.Object is not a B class' );\n ok( !B.detect(A), 'A is not a B class' );\n ok( B.detect(B), 'B is a B class' );\n ok( !B.detect(C), 'C is not a B class' );\n\n ok( !C.detect(Ember.Object), 'Ember.Object is not a C class' );\n ok( !C.detect(A), 'A is not a C class' );\n ok( !C.detect(B), 'B is not a C class' );\n ok( C.detect(C), 'C is a C class' );\n\n});\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/detect_test");minispade.register('ember-runtime/~tests/system/object/events_test', "(function() {module(\"Object events\");\n\ntest(\"a listener can be added to an object\", function() {\n var count = 0;\n var F = function() { count++; };\n\n var obj = Ember.Object.createWithMixins(Ember.Evented);\n\n obj.on('event!', F);\n obj.trigger('event!');\n\n equal(count, 1, \"the event was triggered\");\n\n obj.trigger('event!');\n\n equal(count, 2, \"the event was triggered\");\n});\n\ntest(\"a listener can be added and removed automatically the first time it is triggered\", function() {\n var count = 0;\n var F = function() { count++; };\n\n var obj = Ember.Object.createWithMixins(Ember.Evented);\n\n obj.one('event!', F);\n obj.trigger('event!');\n\n equal(count, 1, \"the event was triggered\");\n\n obj.trigger('event!');\n\n equal(count, 1, \"the event was not triggered again\");\n});\n\ntest(\"triggering an event can have arguments\", function() {\n var self, args;\n\n var obj = Ember.Object.createWithMixins(Ember.Evented);\n\n obj.on('event!', function() {\n args = [].slice.call(arguments);\n self = this;\n });\n\n obj.trigger('event!', \"foo\", \"bar\");\n\n deepEqual(args, [ \"foo\", \"bar\" ]);\n equal(self, obj);\n});\n\ntest(\"a listener can be added and removed automatically and have arguments\", function() {\n var self, args, count = 0;\n\n var obj = Ember.Object.createWithMixins(Ember.Evented);\n\n obj.one('event!', function() {\n args = [].slice.call(arguments);\n self = this;\n count++;\n });\n\n obj.trigger('event!', \"foo\", \"bar\");\n\n deepEqual(args, [ \"foo\", \"bar\" ]);\n equal(self, obj);\n equal(count, 1, \"the event is triggered once\");\n\n obj.trigger('event!', \"baz\", \"bat\");\n\n deepEqual(args, [ \"foo\", \"bar\" ]);\n equal(count, 1, \"the event was not triggered again\");\n equal(self, obj);\n});\n\ntest(\"binding an event can specify a different target\", function() {\n var self, args;\n\n var obj = Ember.Object.createWithMixins(Ember.Evented);\n var target = {};\n\n obj.on('event!', target, function() {\n args = [].slice.call(arguments);\n self = this;\n });\n\n obj.trigger('event!', \"foo\", \"bar\");\n\n deepEqual(args, [ \"foo\", \"bar\" ]);\n equal(self, target);\n});\n\ntest(\"a listener registered with one can take method as string and can be added with different target\", function() {\n var count = 0;\n var target = {};\n target.fn = function() { count++; };\n\n var obj = Ember.Object.createWithMixins(Ember.Evented);\n\n obj.one('event!', target, 'fn');\n obj.trigger('event!');\n\n equal(count, 1, \"the event was triggered\");\n\n obj.trigger('event!');\n\n equal(count, 1, \"the event was not triggered again\");\n});\n\ntest(\"a listener registered with one can be removed with off\", function() {\n var obj = Ember.Object.createWithMixins(Ember.Evented, {\n F: function() {}\n });\n var F = function() {};\n\n obj.one('event!', F);\n obj.one('event!', obj, 'F');\n\n equal(obj.has('event!'), true, 'has events');\n\n obj.off('event!', F);\n obj.off('event!', obj, 'F');\n\n equal(obj.has('event!'), false, 'has no more events');\n});\n\ntest(\"adding and removing listeners should be chainable\", function() {\n var obj = Ember.Object.createWithMixins(Ember.Evented);\n var F = function() {};\n\n var ret = obj.on('event!', F);\n equal(ret, obj, '#on returns self');\n\n ret = obj.off('event!', F);\n equal(ret, obj, '#off returns self');\n\n ret = obj.one('event!', F);\n equal(ret, obj, '#one returns self');\n});\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/events_test");minispade.register('ember-runtime/~tests/system/object/extend_test', "(function() {var get = Ember.get;\n\nmodule('Ember.Object.extend');\n\ntest('Basic extend', function() {\n var SomeClass = Ember.Object.extend({ foo: 'BAR' });\n ok(SomeClass.isClass, \"A class has isClass of true\");\n var obj = new SomeClass();\n equal(obj.foo, 'BAR');\n});\n\ntest('Sub-subclass', function() {\n var SomeClass = Ember.Object.extend({ foo: 'BAR' });\n var AnotherClass = SomeClass.extend({ bar: 'FOO' });\n var obj = new AnotherClass();\n equal(obj.foo, 'BAR');\n equal(obj.bar, 'FOO');\n});\n\ntest('Overriding a method several layers deep', function() {\n var SomeClass = Ember.Object.extend({\n fooCnt: 0,\n foo: function() { this.fooCnt++; },\n\n barCnt: 0,\n bar: function() { this.barCnt++; }\n });\n\n var AnotherClass = SomeClass.extend({\n barCnt: 0,\n bar: function() { this.barCnt++; this._super(); }\n });\n\n var FinalClass = AnotherClass.extend({\n fooCnt: 0,\n foo: function() { this.fooCnt++; this._super(); }\n });\n\n var obj = new FinalClass();\n obj.foo();\n obj.bar();\n equal(obj.fooCnt, 2, 'should invoke both');\n equal(obj.barCnt, 2, 'should invoke both');\n\n // Try overriding on create also\n obj = FinalClass.createWithMixins({\n foo: function() { this.fooCnt++; this._super(); }\n });\n\n obj.foo();\n obj.bar();\n equal(obj.fooCnt, 3, 'should invoke final as well');\n equal(obj.barCnt, 2, 'should invoke both');\n});\n\ntest('With concatenatedProperties', function(){\n var SomeClass = Ember.Object.extend({ things: 'foo', concatenatedProperties: ['things'] });\n var AnotherClass = SomeClass.extend({ things: 'bar' });\n var YetAnotherClass = SomeClass.extend({ things: 'baz' });\n var some = new SomeClass();\n var another = new AnotherClass();\n var yetAnother = new YetAnotherClass();\n deepEqual(some.get('things'), ['foo'], 'base class should have just its value');\n deepEqual(another.get('things'), ['foo', 'bar'], \"subclass should have base class' and it's own\");\n deepEqual(yetAnother.get('things'), ['foo', 'baz'], \"subclass should have base class' and it's own\");\n});\n\ntest('With concatenatedProperties class properties', function(){\n var SomeClass = Ember.Object.extend();\n SomeClass.reopenClass({\n concatenatedProperties: ['things'],\n things: 'foo'\n });\n var AnotherClass = SomeClass.extend();\n AnotherClass.reopenClass({ things: 'bar' });\n var YetAnotherClass = SomeClass.extend();\n YetAnotherClass.reopenClass({ things: 'baz' });\n var some = new SomeClass();\n var another = new AnotherClass();\n var yetAnother = new YetAnotherClass();\n deepEqual(get(some.constructor, 'things'), ['foo'], 'base class should have just its value');\n deepEqual(get(another.constructor, 'things'), ['foo', 'bar'], \"subclass should have base class' and it's own\");\n deepEqual(get(yetAnother.constructor, 'things'), ['foo', 'baz'], \"subclass should have base class' and it's own\");\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/extend_test");minispade.register('ember-runtime/~tests/system/object/observer_test', "(function() {/*globals testBoth */\nminispade.require('ember-runtime/~tests/props_helper');\n\nmodule('Ember.Object observer');\n\ntestBoth('observer on class', function(get, set) {\n\n var MyClass = Ember.Object.extend({\n\n count: 0,\n\n foo: Ember.observer('bar', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n\n });\n\n var obj = new MyClass();\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj, 'bar', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n\n});\n\ntestBoth('observer on subclass', function(get, set) {\n\n var MyClass = Ember.Object.extend({\n\n count: 0,\n\n foo: Ember.observer('bar', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n\n });\n\n var Subclass = MyClass.extend({\n foo: Ember.observer('baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n var obj = new Subclass();\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj, 'bar', \"BAZ\");\n equal(get(obj, 'count'), 0, 'should not invoke observer after change');\n\n set(obj, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n\n});\n\ntestBoth('observer on instance', function(get, set) {\n\n var obj = Ember.Object.createWithMixins({\n\n count: 0,\n\n foo: Ember.observer('bar', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n\n });\n\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj, 'bar', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n\n});\n\ntestBoth('observer on instance overridding class', function(get, set) {\n\n var MyClass = Ember.Object.extend({\n\n count: 0,\n\n foo: Ember.observer('bar', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n\n });\n\n var obj = MyClass.createWithMixins({\n foo: Ember.observer('baz', function() { // <-- change property we observe\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n equal(get(obj, 'count'), 0, 'should not invoke observer immediately');\n\n set(obj, 'bar', \"BAZ\");\n equal(get(obj, 'count'), 0, 'should not invoke observer after change');\n\n set(obj, 'baz', \"BAZ\");\n equal(get(obj, 'count'), 1, 'should invoke observer after change');\n\n});\n\ntestBoth('observer should not fire after being destroyed', function(get, set) {\n\n var obj = Ember.Object.createWithMixins({\n count: 0,\n foo: Ember.observer('bar', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n equal(get(obj, 'count'), 0, 'precond - should not invoke observer immediately');\n\n Ember.run(function() { obj.destroy(); });\n\n if (Ember.assert) {\n expectAssertion(function() {\n set(obj, 'bar', \"BAZ\");\n }, \"calling set on destroyed object\");\n } else {\n set(obj, 'bar', \"BAZ\");\n }\n\n equal(get(obj, 'count'), 0, 'should not invoke observer after change');\n});\n// ..........................................................\n// COMPLEX PROPERTIES\n//\n\n\ntestBoth('chain observer on class', function(get, set) {\n\n var MyClass = Ember.Object.extend({\n count: 0,\n\n foo: Ember.observer('bar.baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n var obj1 = MyClass.create({\n bar: { baz: 'biff' }\n });\n\n var obj2 = MyClass.create({\n bar: { baz: 'biff2' }\n });\n\n equal(get(obj1, 'count'), 0, 'should not invoke yet');\n equal(get(obj2, 'count'), 0, 'should not invoke yet');\n\n set(get(obj1, 'bar'), 'baz', 'BIFF1');\n equal(get(obj1, 'count'), 1, 'should invoke observer on obj1');\n equal(get(obj2, 'count'), 0, 'should not invoke yet');\n\n set(get(obj2, 'bar'), 'baz', 'BIFF2');\n equal(get(obj1, 'count'), 1, 'should not invoke again');\n equal(get(obj2, 'count'), 1, 'should invoke observer on obj2');\n});\n\n\ntestBoth('chain observer on class', function(get, set) {\n\n var MyClass = Ember.Object.extend({\n count: 0,\n\n foo: Ember.observer('bar.baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n var obj1 = MyClass.createWithMixins({\n bar: { baz: 'biff' }\n });\n\n var obj2 = MyClass.createWithMixins({\n bar: { baz: 'biff2' },\n bar2: { baz: 'biff3' },\n\n foo: Ember.observer('bar2.baz', function() {\n set(this, 'count', get(this, 'count')+1);\n })\n });\n\n equal(get(obj1, 'count'), 0, 'should not invoke yet');\n equal(get(obj2, 'count'), 0, 'should not invoke yet');\n\n set(get(obj1, 'bar'), 'baz', 'BIFF1');\n equal(get(obj1, 'count'), 1, 'should invoke observer on obj1');\n equal(get(obj2, 'count'), 0, 'should not invoke yet');\n\n set(get(obj2, 'bar'), 'baz', 'BIFF2');\n equal(get(obj1, 'count'), 1, 'should not invoke again');\n equal(get(obj2, 'count'), 0, 'should not invoke yet');\n\n set(get(obj2, 'bar2'), 'baz', 'BIFF3');\n equal(get(obj1, 'count'), 1, 'should not invoke again');\n equal(get(obj2, 'count'), 1, 'should invoke observer on obj2');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/observer_test");minispade.register('ember-runtime/~tests/system/object/reopenClass_test', "(function() {module('system/object/reopenClass');\n\ntest('adds new properties to subclass', function() {\n\n var Subclass = Ember.Object.extend();\n Subclass.reopenClass({\n foo: function() { return 'FOO'; },\n bar: 'BAR'\n });\n\n equal(Subclass.foo(), 'FOO', 'Adds method');\n equal(Ember.get(Subclass, 'bar'), 'BAR', 'Adds property');\n});\n\ntest('class properties inherited by subclasses', function() {\n\n var Subclass = Ember.Object.extend();\n Subclass.reopenClass({\n foo: function() { return 'FOO'; },\n bar: 'BAR'\n });\n\n var SubSub = Subclass.extend();\n\n equal(SubSub.foo(), 'FOO', 'Adds method');\n equal(Ember.get(SubSub, 'bar'), 'BAR', 'Adds property');\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/reopenClass_test");minispade.register('ember-runtime/~tests/system/object/reopen_test', "(function() {module('system/core_object/reopen');\n\ntest('adds new properties to subclass instance', function() {\n\n var Subclass = Ember.Object.extend();\n Subclass.reopen({\n foo: function() { return 'FOO'; },\n bar: 'BAR'\n });\n\n equal( new Subclass().foo(), 'FOO', 'Adds method');\n equal(Ember.get(new Subclass(), 'bar'), 'BAR', 'Adds property');\n});\n\ntest('reopened properties inherited by subclasses', function() {\n\n var Subclass = Ember.Object.extend();\n var SubSub = Subclass.extend();\n\n Subclass.reopen({\n foo: function() { return 'FOO'; },\n bar: 'BAR'\n });\n\n\n equal( new SubSub().foo(), 'FOO', 'Adds method');\n equal(Ember.get(new SubSub(), 'bar'), 'BAR', 'Adds property');\n});\n\n// We plan to allow this in the future\ntest('does not allow reopening already instantiated classes', function() {\n var Subclass = Ember.Object.extend();\n\n Subclass.create();\n\n Subclass.reopen({\n trololol: true\n });\n\n equal(Subclass.create().get('trololol'), true, \"reopen works\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/reopen_test");minispade.register('ember-runtime/~tests/system/object/subclasses_test', "(function() {module('system/object/subclasses');\n\ntest('chains should copy forward to subclasses when prototype created', function () {\n var ObjectWithChains, objWithChains, SubWithChains, SubSub, subSub;\n Ember.run(function () {\n ObjectWithChains = Ember.Object.extend({\n obj: {\n a: 'a',\n hi: 'hi'\n },\n aBinding: 'obj.a' // add chain\n });\n // realize prototype\n objWithChains = ObjectWithChains.create();\n // should not copy chains from parent yet\n SubWithChains = ObjectWithChains.extend({\n hiBinding: 'obj.hi', // add chain\n hello: Ember.computed(function() {\n return this.get('obj.hi') + ' world';\n }).property('hi'), // observe chain\n greetingBinding: 'hello'\n });\n SubSub = SubWithChains.extend();\n // should realize prototypes and copy forward chains\n subSub = SubSub.create();\n });\n equal(subSub.get('greeting'), 'hi world');\n Ember.run(function () {\n objWithChains.set('obj.hi', 'hello');\n });\n equal(subSub.get('greeting'), 'hello world');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/subclasses_test");minispade.register('ember-runtime/~tests/system/object/toString_test', "(function() {var guidFor = Ember.guidFor, originalLookup = Ember.lookup, lookup;\n\nmodule('system/object/toString', {\n setup: function() {\n lookup = Ember.lookup = {};\n },\n teardown: function() {\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"toString() returns the same value if called twice\", function() {\n var Foo = Ember.Namespace.create();\n Foo.toString = function() { return \"Foo\"; };\n\n Foo.Bar = Ember.Object.extend();\n\n equal(Foo.Bar.toString(), \"Foo.Bar\");\n equal(Foo.Bar.toString(), \"Foo.Bar\");\n\n var obj = Foo.Bar.create();\n\n equal(obj.toString(), \"\");\n equal(obj.toString(), \"\");\n\n equal(Foo.Bar.toString(), \"Foo.Bar\");\n});\n\ntest(\"toString on a class returns a useful value when nested in a namespace\", function() {\n var obj;\n\n var Foo = Ember.Namespace.create();\n Foo.toString = function() { return \"Foo\"; };\n\n Foo.Bar = Ember.Object.extend();\n equal(Foo.Bar.toString(), \"Foo.Bar\");\n\n obj = Foo.Bar.create();\n equal(obj.toString(), \"\");\n\n Foo.Baz = Foo.Bar.extend();\n equal(Foo.Baz.toString(), \"Foo.Baz\");\n\n obj = Foo.Baz.create();\n equal(obj.toString(), \"\");\n\n obj = Foo.Bar.create();\n equal(obj.toString(), \"\");\n});\n\ntest(\"toString on a namespace finds the namespace in Ember.lookup\", function() {\n var Foo = lookup.Foo = Ember.Namespace.create();\n\n equal(Foo.toString(), \"Foo\");\n});\n\ntest(\"toString on a namespace finds the namespace in Ember.lookup\", function() {\n var Foo = lookup.Foo = Ember.Namespace.create(), obj;\n\n Foo.Bar = Ember.Object.extend();\n\n equal(Foo.Bar.toString(), \"Foo.Bar\");\n\n obj = Foo.Bar.create();\n equal(obj.toString(), \"\");\n});\n\ntest('toString includes toStringExtension if defined', function() {\n var Foo = Ember.Object.extend({\n toStringExtension: function() {\n return \"fooey\";\n }\n }),\n foo = Foo.create(),\n Bar = Ember.Object.extend({}),\n bar = Bar.create();\n // simulate these classes being defined on a Namespace\n Foo[Ember.GUID_KEY+'_name'] = 'Foo';\n Bar[Ember.GUID_KEY+'_name'] = 'Bar';\n\n equal(bar.toString(), '', 'does not include toStringExtension part');\n equal(foo.toString(), '', 'Includes toStringExtension result');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/object/toString_test");minispade.register('ember-runtime/~tests/system/object_proxy_test', "(function() {module(\"Ember.ObjectProxy\");\n\ntestBoth(\"should not proxy properties passed to create\", function (get, set) {\n var Proxy = Ember.ObjectProxy.extend({\n cp: Ember.computed(function (key, value) {\n if (value) {\n this._cp = value;\n }\n return this._cp;\n })\n });\n var proxy = Proxy.create({\n prop: 'Foo',\n cp: 'Bar'\n });\n\n equal(get(proxy, 'prop'), 'Foo', 'should not have tried to proxy set');\n equal(proxy._cp, 'Bar', 'should use CP setter');\n});\n\ntestBoth(\"should proxy properties to content\", function(get, set) {\n var content = {\n firstName: 'Tom',\n lastName: 'Dale',\n unknownProperty: function (key) { return key + ' unknown';}\n },\n proxy = Ember.ObjectProxy.create();\n\n equal(get(proxy, 'firstName'), undefined, 'get on proxy without content should return undefined');\n expectAssertion(function () {\n set(proxy, 'firstName', 'Foo');\n }, /Cannot delegate set\\('firstName', Foo\\) to the 'content'/i);\n\n set(proxy, 'content', content);\n\n equal(get(proxy, 'firstName'), 'Tom', 'get on proxy with content should forward to content');\n equal(get(proxy, 'lastName'), 'Dale', 'get on proxy with content should forward to content');\n equal(get(proxy, 'foo'), 'foo unknown', 'get on proxy with content should forward to content');\n\n set(proxy, 'lastName', 'Huda');\n\n equal(get(content, 'lastName'), 'Huda', 'content should have new value from set on proxy');\n equal(get(proxy, 'lastName'), 'Huda', 'proxy should have new value from set on proxy');\n\n set(proxy, 'content', {firstName: 'Yehuda', lastName: 'Katz'});\n\n equal(get(proxy, 'firstName'), 'Yehuda', 'proxy should reflect updated content');\n equal(get(proxy, 'lastName'), 'Katz', 'proxy should reflect updated content');\n});\n\ntestBoth(\"should work with watched properties\", function(get, set) {\n var content1 = {firstName: 'Tom', lastName: 'Dale'},\n content2 = {firstName: 'Yehuda', lastName: 'Katz'},\n Proxy,\n proxy,\n count = 0,\n last;\n\n Proxy = Ember.ObjectProxy.extend({\n fullName: Ember.computed(function () {\n var firstName = this.get('firstName'),\n lastName = this.get('lastName');\n if (firstName && lastName) {\n return firstName + ' ' + lastName;\n }\n return firstName || lastName;\n }).property('firstName', 'lastName')\n });\n\n proxy = Proxy.create();\n\n Ember.addObserver(proxy, 'fullName', function () {\n last = get(proxy, 'fullName');\n count++;\n });\n\n // proxy without content returns undefined\n equal(get(proxy, 'fullName'), undefined);\n\n // setting content causes all watched properties to change\n set(proxy, 'content', content1);\n // both dependent keys changed\n equal(count, 2);\n equal(last, 'Tom Dale');\n\n // setting property in content causes proxy property to change\n set(content1, 'lastName', 'Huda');\n equal(count, 3);\n equal(last, 'Tom Huda');\n\n // replacing content causes all watched properties to change\n set(proxy, 'content', content2);\n // both dependent keys changed\n equal(count, 5);\n equal(last, 'Yehuda Katz');\n // content1 is no longer watched\n ok(!Ember.isWatching(content1, 'firstName'), 'not watching firstName');\n ok(!Ember.isWatching(content1, 'lastName'), 'not watching lastName');\n\n // setting property in new content\n set(content2, 'firstName', 'Tomhuda');\n equal(last, 'Tomhuda Katz');\n equal(count, 6);\n\n // setting property in proxy syncs with new content\n set(proxy, 'lastName', 'Katzdale');\n equal(count, 7);\n equal(last, 'Tomhuda Katzdale');\n equal(get(content2, 'firstName'), 'Tomhuda');\n equal(get(content2, 'lastName'), 'Katzdale');\n});\n\ntest(\"set and get should work with paths\", function () {\n var content = {foo: {bar: 'baz'}},\n proxy = Ember.ObjectProxy.create({content: content}),\n count = 0;\n proxy.set('foo.bar', 'hello');\n equal(proxy.get('foo.bar'), 'hello');\n equal(proxy.get('content.foo.bar'), 'hello');\n\n proxy.addObserver('foo.bar', function () {\n count++;\n });\n\n proxy.set('foo.bar', 'bye');\n\n equal(count, 1);\n equal(proxy.get('foo.bar'), 'bye');\n equal(proxy.get('content.foo.bar'), 'bye');\n});\n\ntestBoth(\"should transition between watched and unwatched strategies\", function(get, set) {\n var content = {foo: 'foo'},\n proxy = Ember.ObjectProxy.create({content: content}),\n count = 0;\n\n function observer() {\n count++;\n }\n\n equal(get(proxy, 'foo'), 'foo');\n\n set(content, 'foo', 'bar');\n\n equal(get(proxy, 'foo'), 'bar');\n\n set(proxy, 'foo', 'foo');\n\n equal(get(content, 'foo'), 'foo');\n equal(get(proxy, 'foo'), 'foo');\n\n Ember.addObserver(proxy, 'foo', observer);\n\n equal(count, 0);\n equal(get(proxy, 'foo'), 'foo');\n\n set(content, 'foo', 'bar');\n\n equal(count, 1);\n equal(get(proxy, 'foo'), 'bar');\n\n set(proxy, 'foo', 'foo');\n\n equal(count, 2);\n equal(get(content, 'foo'), 'foo');\n equal(get(proxy, 'foo'), 'foo');\n\n Ember.removeObserver(proxy, 'foo', observer);\n\n set(content, 'foo', 'bar');\n\n equal(get(proxy, 'foo'), 'bar');\n\n set(proxy, 'foo', 'foo');\n\n equal(get(content, 'foo'), 'foo');\n equal(get(proxy, 'foo'), 'foo');\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/object_proxy_test");minispade.register('ember-runtime/~tests/system/set/copyable_suite_test', "(function() {// ..........................................................\n// COPYABLE TESTS\n//\nEmber.CopyableTests.extend({\n name: 'Ember.Set Copyable',\n\n newObject: function() {\n var set = new Ember.Set();\n set.addObject(Ember.generateGuid());\n return set;\n },\n\n isEqual: function(a,b) {\n if (!(a instanceof Ember.Set)) return false;\n if (!(b instanceof Ember.Set)) return false;\n return Ember.get(a, 'firstObject') === Ember.get(b, 'firstObject');\n },\n\n shouldBeFreezable: true\n}).run();\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/set/copyable_suite_test");minispade.register('ember-runtime/~tests/system/set/enumerable_suite_test', "(function() {// ..........................................................\n// MUTABLE ENUMERABLE TESTS\n//\nEmber.MutableEnumerableTests.extend({\n\n name: 'Ember.Set',\n\n newObject: function(ary) {\n ary = ary ? ary.slice() : this.newFixture(3);\n var ret = new Ember.Set();\n ret.addObjects(ary);\n return ret;\n },\n\n mutate: function(obj) {\n obj.addObject(Ember.get(obj, 'length')+1);\n },\n\n toArray: function(obj) {\n return obj.toArray ? obj.toArray() : obj.slice(); // make a copy.\n }\n\n}).run();\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/set/enumerable_suite_test");minispade.register('ember-runtime/~tests/system/set/extra_test', "(function() {// ..........................................................\n// Ember.Set.init\n//\n\nmodule('Ember.Set.init');\n\ntest('passing an array to new Ember.Set() should instantiate w/ items', function() {\n\n var get = Ember.get;\n var ary = [1,2,3];\n var aSet = new Ember.Set(ary);\n var count = 0;\n\n equal(get(aSet, 'length'), 3, 'should have three items');\n aSet.forEach(function(x) {\n ok(Ember.EnumerableUtils.indexOf(ary, x)>=0, 'should find passed item in array');\n count++;\n });\n equal(count, 3, 'iterating should have returned three objects');\n});\n\n\n// ..........................................................\n// Ember.Set.clear\n//\n\nmodule('Ember.Set.clear');\n\ntest('should clear a set of its content', function() {\n\n var get = Ember.get, set = Ember.set;\n var aSet = new Ember.Set([1,2,3]);\n var count = 0;\n\n equal(get(aSet, 'length'), 3, 'should have three items');\n ok(get(aSet, 'firstObject'), 'firstObject should return an object');\n ok(get(aSet, 'lastObject'), 'lastObject should return an object');\n Ember.addObserver(aSet, '[]', function() { count++; });\n\n aSet.clear();\n equal(get(aSet, 'length'), 0, 'should have 0 items');\n equal(count, 1, 'should have notified of content change');\n equal(get(aSet, 'firstObject'), null, 'firstObject should return nothing');\n equal(get(aSet, 'lastObject'), null, 'lastObject should return nothing');\n\n count = 0;\n aSet.forEach(function() { count++; });\n equal(count, 0, 'iterating over items should not invoke callback');\n\n});\n\n// ..........................................................\n// Ember.Set.pop\n//\n\nmodule('Ember.Set.pop');\n\ntest('calling pop should return an object and remove it', function() {\n\n var aSet = new Ember.Set([1,2,3]);\n var count = 0, obj;\n while(count<10 && (obj = aSet.pop())) {\n equal(aSet.contains(obj), false, 'set should no longer contain object');\n count++;\n equal(Ember.get(aSet, 'length'), 3-count, 'length should be shorter');\n }\n\n equal(count, 3, 'should only pop 3 objects');\n equal(Ember.get(aSet, 'length'), 0, 'final length should be zero');\n equal(aSet.pop(), null, 'extra pops should do nothing');\n});\n\n// ..........................................................\n// Ember.Set.aliases\n//\n\nmodule('Ember.Set aliases');\n\ntest('method aliases', function() {\n var aSet = new Ember.Set();\n equal(aSet.add, aSet.addObject, 'add -> addObject');\n equal(aSet.remove, aSet.removeObject, 'remove -> removeObject');\n equal(aSet.addEach, aSet.addObjects, 'addEach -> addObjects');\n equal(aSet.removeEach, aSet.removeObjects, 'removeEach -> removeObjects');\n\n equal(aSet.push, aSet.addObject, 'push -> addObject');\n equal(aSet.unshift, aSet.addObject, 'unshift -> addObject');\n equal(aSet.shift, aSet.pop, 'shift -> pop');\n});\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/set/extra_test");minispade.register('ember-runtime/~tests/system/string/camelize', "(function() {module('Ember.String.camelize');\n\ntest(\"camelize normal string\", function() {\n deepEqual(Ember.String.camelize('my favorite items'), 'myFavoriteItems');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('my favorite items'.camelize(), 'myFavoriteItems');\n }\n});\n\ntest(\"camelize capitalized string\", function() {\n deepEqual(Ember.String.camelize('I Love Ramen'), 'iLoveRamen');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('I Love Ramen'.camelize(), 'iLoveRamen');\n }\n});\n\ntest(\"camelize dasherized string\", function() {\n deepEqual(Ember.String.camelize('css-class-name'), 'cssClassName');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('css-class-name'.camelize(), 'cssClassName');\n }\n});\n\ntest(\"camelize underscored string\", function() {\n deepEqual(Ember.String.camelize('action_name'), 'actionName');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('action_name'.camelize(), 'actionName');\n }\n});\n\ntest(\"camelize dot notation string\", function() {\n deepEqual(Ember.String.camelize('action.name'), 'actionName');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('action.name'.camelize(), 'actionName');\n }\n});\n\ntest(\"does nothing with camelcased string\", function() {\n deepEqual(Ember.String.camelize('innerHTML'), 'innerHTML');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('innerHTML'.camelize(), 'innerHTML');\n }\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/string/camelize");minispade.register('ember-runtime/~tests/system/string/capitalize', "(function() {// ==========================================================================\n// Project: Ember Runtime\n// Copyright: ©2006-2011 Strobe Inc. and contributors.\n// ©2008-2011 Apple Inc. All rights reserved.\n// License: Licensed under MIT license (see license.js)\n// ==========================================================================\n\nmodule('Ember.String.capitalize');\n\ntest(\"capitalize normal string\", function() {\n deepEqual(Ember.String.capitalize('my favorite items'), 'My favorite items');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('my favorite items'.capitalize(), 'My favorite items');\n }\n});\n\ntest(\"capitalize dasherized string\", function() {\n deepEqual(Ember.String.capitalize('css-class-name'), 'Css-class-name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('css-class-name'.capitalize(), 'Css-class-name');\n }\n});\n\ntest(\"capitalize underscored string\", function() {\n deepEqual(Ember.String.capitalize('action_name'), 'Action_name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('action_name'.capitalize(), 'Action_name');\n }\n});\n\ntest(\"capitalize camelcased string\", function() {\n deepEqual(Ember.String.capitalize('innerHTML'), 'InnerHTML');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('innerHTML'.capitalize(), 'InnerHTML');\n }\n});\n\ntest(\"does nothing with capitalized string\", function() {\n deepEqual(Ember.String.capitalize('Capitalized string'), 'Capitalized string');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('Capitalized string'.capitalize(), 'Capitalized string');\n }\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/string/capitalize");minispade.register('ember-runtime/~tests/system/string/classify', "(function() {module('Ember.String.classify');\n\ntest(\"classify normal string\", function() {\n deepEqual(Ember.String.classify('my favorite items'), 'MyFavoriteItems');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('my favorite items'.classify(), 'MyFavoriteItems');\n }\n});\n\ntest(\"classify dasherized string\", function() {\n deepEqual(Ember.String.classify('css-class-name'), 'CssClassName');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('css-class-name'.classify(), 'CssClassName');\n }\n});\n\ntest(\"classify underscored string\", function() {\n deepEqual(Ember.String.classify('action_name'), 'ActionName');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('action_name'.classify(), 'ActionName');\n }\n});\n\ntest(\"does nothing with classified string\", function() {\n deepEqual(Ember.String.classify('InnerHTML'), 'InnerHTML');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('InnerHTML'.classify(), 'InnerHTML');\n }\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/string/classify");minispade.register('ember-runtime/~tests/system/string/dasherize', "(function() {module('Ember.String.dasherize');\n\ntest(\"dasherize normal string\", function() {\n deepEqual(Ember.String.dasherize('my favorite items'), 'my-favorite-items');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('my favorite items'.dasherize(), 'my-favorite-items');\n }\n});\n\ntest(\"does nothing with dasherized string\", function() {\n deepEqual(Ember.String.dasherize('css-class-name'), 'css-class-name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('css-class-name'.dasherize(), 'css-class-name');\n }\n});\n\ntest(\"dasherize underscored string\", function() {\n deepEqual(Ember.String.dasherize('action_name'), 'action-name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('action_name'.dasherize(), 'action-name');\n }\n});\n\ntest(\"dasherize camelcased string\", function() {\n deepEqual(Ember.String.dasherize('innerHTML'), 'inner-html');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('innerHTML'.dasherize(), 'inner-html');\n }\n});\n\ntest(\"dasherize string that is the property name of Object.prototype\", function() {\n deepEqual(Ember.String.dasherize('toString'), 'to-string');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('toString'.dasherize(), 'to-string');\n }\n});\n\ntest(\"after call with the same passed value take object from cache\", function() {\n var res = Ember.String.dasherize('innerHTML');\n\n var callCount = 0;\n var decamelize = Ember.String.decamelize;\n\n try {\n Ember.String.decamelize = function() {\n callCount++;\n };\n Ember.String.dasherize('innerHTML');\n } finally {\n Ember.String.decamelize = decamelize;\n }\n\n equal(callCount, 0, \"decamelize is not called again\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/string/dasherize");minispade.register('ember-runtime/~tests/system/string/decamelize', "(function() {module('Ember.String.decamelize');\n\ntest(\"does nothing with normal string\", function() {\n deepEqual(Ember.String.decamelize('my favorite items'), 'my favorite items');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('my favorite items'.decamelize(), 'my favorite items');\n }\n});\n\ntest(\"does nothing with dasherized string\", function() {\n deepEqual(Ember.String.decamelize('css-class-name'), 'css-class-name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('css-class-name'.decamelize(), 'css-class-name');\n }\n});\n\ntest(\"does nothing with underscored string\", function() {\n deepEqual(Ember.String.decamelize('action_name'), 'action_name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('action_name'.decamelize(), 'action_name');\n }\n});\n\ntest(\"converts a camelized string into all lower case separated by underscores.\", function() {\n deepEqual(Ember.String.decamelize('innerHTML'), 'inner_html');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('innerHTML'.decamelize(), 'inner_html');\n }\n});\n\ntest(\"decamelizes strings with numbers\", function() {\n deepEqual(Ember.String.decamelize('size160Url'), 'size160_url');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('size160Url'.decamelize(), 'size160_url');\n }\n});\n})();\n//@ sourceURL=ember-runtime/~tests/system/string/decamelize");minispade.register('ember-runtime/~tests/system/string/fmt_string', "(function() {module('Ember.String.fmt');\n\ntest(\"'Hello %@ %@'.fmt('John', 'Doe') => 'Hello John Doe'\", function() {\n equal(Ember.String.fmt('Hello %@ %@', ['John', 'Doe']), 'Hello John Doe');\n if (Ember.EXTEND_PROTOTYPES) {\n equal('Hello %@ %@'.fmt('John', 'Doe'), 'Hello John Doe');\n }\n});\n\ntest(\"'Hello %@2 %@1'.fmt('John', 'Doe') => 'Hello Doe John'\", function() {\n equal(Ember.String.fmt('Hello %@2 %@1', ['John', 'Doe']), 'Hello Doe John');\n if (Ember.EXTEND_PROTOTYPES) {\n equal('Hello %@2 %@1'.fmt('John', 'Doe'), 'Hello Doe John');\n }\n});\n\ntest(\"'%@08 %@07 %@06 %@05 %@04 %@03 %@02 %@01'.fmt('One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight') => 'Eight Seven Six Five Four Three Two One'\", function() {\n equal(Ember.String.fmt('%@08 %@07 %@06 %@05 %@04 %@03 %@02 %@01', ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight']), 'Eight Seven Six Five Four Three Two One');\n\n if (Ember.EXTEND_PROTOTYPES) {\n equal('%@08 %@07 %@06 %@05 %@04 %@03 %@02 %@01'.fmt('One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight'), 'Eight Seven Six Five Four Three Two One');\n }\n});\n\ntest(\"'data: %@'.fmt({id: 3}) => 'data: {id: 3}'\", function() {\n equal(Ember.String.fmt('data: %@', [{id: 3}]), 'data: {id: 3}');\n if (Ember.EXTEND_PROTOTYPES) {\n equal('data: %@'.fmt({id: 3}), 'data: {id: 3}');\n }\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/string/fmt_string");minispade.register('ember-runtime/~tests/system/string/humanize', "(function() {if (Ember.FEATURES.isEnabled(\"string-humanize\")) {\n module('Ember.String.humanize');\n\n test(\"with underscored string\", function() {\n deepEqual(Ember.String.humanize('first_name'), 'First name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('first_name'.humanize(), 'First name');\n }\n });\n\n test(\"with multiple underscored string\", function() {\n deepEqual(Ember.String.humanize('first_and_last_name'), 'First and last name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('first_and_last_name'.humanize(), 'First and last name');\n }\n });\n\n test(\"with underscored id string\", function() {\n deepEqual(Ember.String.humanize('user_id'), 'User');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('user_id'.humanize(), 'User');\n }\n });\n\n test(\"with humanized string\", function() {\n deepEqual(Ember.String.humanize('First name'), 'First name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('First name'.humanize(), 'First name');\n }\n });\n}\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/string/humanize");minispade.register('ember-runtime/~tests/system/string/loc_test', "(function() {var oldString;\n\nmodule('Ember.String.loc', {\n setup: function() {\n oldString = Ember.STRINGS;\n Ember.STRINGS = {\n '_Hello World': 'Bonjour le monde',\n '_Hello %@ %@': 'Bonjour %@ %@',\n '_Hello %@# %@#': 'Bonjour %@2 %@1'\n };\n },\n\n teardown: function() {\n Ember.STRINGS = oldString;\n }\n});\n\ntest(\"'_Hello World'.loc() => 'Bonjour le monde'\", function() {\n equal(Ember.String.loc('_Hello World'), 'Bonjour le monde');\n if (Ember.EXTEND_PROTOTYPES) {\n equal('_Hello World'.loc(), 'Bonjour le monde');\n }\n});\n\ntest(\"'_Hello %@ %@'.loc('John', 'Doe') => 'Bonjour John Doe'\", function() {\n equal(Ember.String.loc('_Hello %@ %@', ['John', 'Doe']), 'Bonjour John Doe');\n if (Ember.EXTEND_PROTOTYPES) {\n equal('_Hello %@ %@'.loc('John', 'Doe'), 'Bonjour John Doe');\n }\n});\n\ntest(\"'_Hello %@# %@#'.loc('John', 'Doe') => 'Bonjour Doe John'\", function() {\n equal(Ember.String.loc('_Hello %@# %@#', ['John', 'Doe']), 'Bonjour Doe John');\n if (Ember.EXTEND_PROTOTYPES) {\n equal('_Hello %@# %@#'.loc('John', 'Doe'), 'Bonjour Doe John');\n }\n});\n\ntest(\"'_Not In Strings'.loc() => '_Not In Strings'\", function() {\n equal(Ember.String.loc('_Not In Strings'), '_Not In Strings');\n if (Ember.EXTEND_PROTOTYPES) {\n equal('_Not In Strings'.loc(), '_Not In Strings');\n }\n});\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/string/loc_test");minispade.register('ember-runtime/~tests/system/string/underscore', "(function() {module('Ember.String.underscore');\n\ntest(\"with normal string\", function() {\n deepEqual(Ember.String.underscore('my favorite items'), 'my_favorite_items');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('my favorite items'.underscore(), 'my_favorite_items');\n }\n});\n\ntest(\"with dasherized string\", function() {\n deepEqual(Ember.String.underscore('css-class-name'), 'css_class_name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('css-class-name'.underscore(), 'css_class_name');\n }\n});\n\ntest(\"does nothing with underscored string\", function() {\n deepEqual(Ember.String.underscore('action_name'), 'action_name');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('action_name'.underscore(), 'action_name');\n }\n});\n\ntest(\"with camelcased string\", function() {\n deepEqual(Ember.String.underscore('innerHTML'), 'inner_html');\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('innerHTML'.underscore(), 'inner_html');\n }\n});\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/string/underscore");minispade.register('ember-runtime/~tests/system/string/w_test', "(function() {module('Ember.String.w');\n\ntest(\"'one two three'.w() => ['one','two','three']\", function() {\n deepEqual(Ember.String.w('one two three'), ['one','two','three']);\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('one two three'.w(), ['one','two','three']);\n }\n});\n\ntest(\"'one two three'.w() with extra spaces between words => ['one','two','three']\", function() {\n deepEqual(Ember.String.w('one two three'), ['one','two','three']);\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('one two three'.w(), ['one','two','three']);\n }\n});\n\ntest(\"'one two three'.w() with tabs\", function() {\n deepEqual(Ember.String.w('one\\ttwo three'), ['one','two','three']);\n if (Ember.EXTEND_PROTOTYPES) {\n deepEqual('one\\ttwo three'.w(), ['one','two','three']);\n }\n});\n\n\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/string/w_test");minispade.register('ember-runtime/~tests/system/subarray_test', "(function() {var forEach = Ember.EnumerableUtils.forEach, subarray;\n\nmodule('Ember.SubArray', {\n setup: function () {\n subarray = new Ember.SubArray();\n }\n});\n\nfunction operationsString() {\n var str = \"\";\n forEach(subarray._operations, function (operation) {\n str += \" \" + operation.type + \":\" + operation.count;\n });\n return str.substring(1);\n}\n\ntest(\"Subarray operations are initially retain:n\", function() {\n subarray = new Ember.SubArray(10);\n\n equal(operationsString(), \"r:10\", \"subarray operations are initially retain n\");\n});\n\ntest(\"Retains compose with retains on insert\", function() {\n subarray.addItem(0, true);\n subarray.addItem(1, true);\n subarray.addItem(2, true);\n\n equal(operationsString(), \"r:3\", \"Retains compose with retains on insert.\");\n});\n\ntest(\"Retains compose with retains on removal\", function() {\n subarray.addItem(0, true);\n subarray.addItem(1, false);\n subarray.addItem(2, true);\n\n equal(operationsString(), \"r:1 f:1 r:1\", \"precond - operations are initially correct.\");\n\n subarray.removeItem(1);\n\n equal(operationsString(), \"r:2\", \"Retains compose with retains on removal.\");\n});\n\ntest(\"Filters compose with filters on insert\", function() {\n subarray.addItem(0, false);\n subarray.addItem(1, false);\n subarray.addItem(2, false);\n\n equal(operationsString(), \"f:3\", \"Retains compose with retains on insert.\");\n});\n\ntest(\"Filters compose with filters on removal\", function() {\n subarray.addItem(0, false);\n subarray.addItem(1, true);\n subarray.addItem(2, false);\n\n equal(operationsString(), \"f:1 r:1 f:1\", \"precond - operations are initially correct.\");\n\n subarray.removeItem(1);\n\n equal(operationsString(), \"f:2\", \"Filters compose with filters on removal.\");\n});\n\ntest(\"Filters split retains\", function() {\n subarray.addItem(0, true);\n subarray.addItem(1, true);\n subarray.addItem(1, false);\n\n equal(operationsString(), \"r:1 f:1 r:1\", \"Filters split retains.\");\n});\n\ntest(\"Retains split filters\", function() {\n subarray.addItem(0, false);\n subarray.addItem(1, false);\n subarray.addItem(1, true);\n\n equal(operationsString(), \"f:1 r:1 f:1\", \"Retains split filters.\");\n});\n\ntest(\"`addItem` returns the index of the item in the subarray\", function() {\n var indexes = [];\n\n equal(subarray.addItem(0, true), 0, \"`addItem` returns the index of the item in the subarray\");\n subarray.addItem(1, false);\n equal(subarray.addItem(2, true), 1, \"`addItem` returns the index of the item in the subarray\");\n\n equal(operationsString(), \"r:1 f:1 r:1\", \"Operations are correct.\");\n});\n\ntest(\"`addItem` returns -1 if the new item is not in the subarray\", function() {\n equal(subarray.addItem(0, false), -1, \"`addItem` returns -1 if the item is not in the subarray\");\n});\n\ntest(\"`removeItem` returns the index of the item in the subarray\", function() {\n subarray.addItem(0, true);\n subarray.addItem(1, false);\n subarray.addItem(2, true);\n\n equal(subarray.removeItem(2), 1, \"`removeItem` returns the index of the item in the subarray\");\n equal(subarray.removeItem(0), 0, \"`removeItem` returns the index of the item in the subarray\");\n});\n\ntest(\"`removeItem` returns -1 if the item was not in the subarray\", function() {\n subarray.addItem(0, true);\n subarray.addItem(1, false);\n\n equal(subarray.removeItem(1), -1, \"`removeItem` returns -1 if the item is not in the subarray\");\n});\n\ntest(\"`removeItem` raises a sensible exception when there are no operations in the subarray\", function() {\n var subarrayExploder = function() {\n subarray.removeItem(9);\n };\n throws(subarrayExploder, /never\\ been\\ added/, \"`removeItem` raises a sensible exception when there are no operations in the subarray\");\n});\n\ntest(\"left composition does not confuse a subsequent right non-composition\", function() {\n subarray.addItem(0, true);\n subarray.addItem(1, false);\n subarray.addItem(2, true);\n equal(operationsString(), \"r:1 f:1 r:1\", \"precond - initial state of subarray is as expected\");\n\n subarray.addItem(1, true);\n equal(operationsString(), \"r:2 f:1 r:1\", \"left-composition does not confuse right non-composition\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/subarray_test");minispade.register('ember-runtime/~tests/system/tracked_array_test', "(function() {var forEach = Ember.EnumerableUtils.forEach, trackedArray,\n RETAIN = Ember.TrackedArray.RETAIN,\n INSERT = Ember.TrackedArray.INSERT,\n DELETE = Ember.TrackedArray.DELETE;\n\nmodule('Ember.TrackedArray');\n\ntest(\"operations for a tracked array of length n are initially retain:n\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n\n equal(\"r:4\", trackedArray.toString(), \"initial mutation is retain n\");\n});\n\ntest(\"insert zero items is a no-op\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n\n trackedArray.addItems(2, []);\n\n equal(trackedArray.toString(), \"r:4\", \"insert:0 is a no-op\");\n\n deepEqual(trackedArray._operations[0].items, [1,2,3,4], \"after a no-op, existing operation has right items\");\n});\n\ntest(\"inserts can split retains\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n\n trackedArray.addItems(2, ['a']);\n\n equal(trackedArray.toString(), \"r:2 i:1 r:2\", \"inserts can split retains\");\n\n deepEqual(trackedArray._operations[0].items, [1,2], \"split retains have the right items\");\n deepEqual(trackedArray._operations[1].items, ['a'], \"inserts have the right items\");\n deepEqual(trackedArray._operations[2].items, [3,4], \"split retains have the right items\");\n});\n\ntest(\"inserts can expand (split/compose) inserts\", function() {\n trackedArray = new Ember.TrackedArray([]);\n\n trackedArray.addItems(0, [1,2,3,4]);\n trackedArray.addItems(2, ['a']);\n\n equal(trackedArray.toString(), \"i:5\", \"inserts can expand inserts\");\n\n deepEqual(trackedArray._operations[0].items, [1,2,'a',3,4], \"expanded inserts have the right items\");\n});\n\ntest(\"inserts left of inserts compose\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n\n trackedArray.addItems(2, ['b']);\n trackedArray.addItems(2, ['a']);\n\n equal(trackedArray.toString(), \"r:2 i:2 r:2\", \"inserts left of inserts compose\");\n\n deepEqual(trackedArray._operations[0].items, [1,2], \"split retains have the right items\");\n deepEqual(trackedArray._operations[1].items, ['a', 'b'], \"composed inserts have the right items\");\n deepEqual(trackedArray._operations[2].items, [3,4], \"split retains have the right items\");\n});\n\ntest(\"inserts right of inserts compose\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n\n trackedArray.addItems(2, ['a']);\n trackedArray.addItems(3, ['b']);\n\n equal(trackedArray.toString(), \"r:2 i:2 r:2\", \"inserts right of inserts compose\");\n\n deepEqual(trackedArray._operations[0].items, [1,2], \"split retains have the right items\");\n deepEqual(trackedArray._operations[1].items, ['a', 'b'], \"composed inserts have the right items\");\n deepEqual(trackedArray._operations[2].items, [3,4], \"split retains have the right items\");\n});\n\ntest(\"delete zero items is a no-op\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n\n trackedArray.addItems(2, []);\n\n equal(trackedArray.toString(), \"r:4\", \"insert:0 is a no-op\");\n\n deepEqual(trackedArray._operations[0].items, [1,2,3,4], \"after a no-op, existing operation has right items\");\n});\n\ntest(\"deletes compose with several inserts and retains\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n\n trackedArray.addItems(4, ['e']);\n trackedArray.addItems(3, ['d']);\n trackedArray.addItems(2, ['c']);\n trackedArray.addItems(1, ['b']);\n trackedArray.addItems(0, ['a']); // a1b2c3d4e i1r1i1r1i1r1i1r1i1\n\n trackedArray.removeItems(0, 9);\n equal(trackedArray.toString(), \"d:4\", \"deletes compose with several inserts and retains\");\n});\n\ntest(\"deletes compose with several inserts and retains and an adjacent delete\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4,5]);\n\n trackedArray.removeItems(0, 1);\n trackedArray.addItems(4, ['e']);\n trackedArray.addItems(3, ['d']);\n trackedArray.addItems(2, ['c']);\n trackedArray.addItems(1, ['b']);\n trackedArray.addItems(0, ['a']); // a2b3c4d5e d1i1r1i1r1i1r1i1r1i1\n\n trackedArray.removeItems(0, 9);\n equal(trackedArray.toString(), \"d:5\", \"deletes compose with several inserts, retains, and a single prior delete\");\n});\n\ntest(\"deletes compose with several inserts and retains and can reduce the last one\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n\n trackedArray.addItems(4, ['e', 'f']);\n trackedArray.addItems(3, ['d']);\n trackedArray.addItems(2, ['c']);\n trackedArray.addItems(1, ['b']);\n trackedArray.addItems(0, ['a']); // a1b2c3d4e i1r1i1r1i1r1i1r1i2\n\n trackedArray.removeItems(0, 9);\n equal(trackedArray.toString(), \"d:4 i:1\", \"deletes compose with several inserts and retains, reducing the last one\");\n deepEqual(trackedArray._operations[1].items, ['f'], \"last mutation's items is correct\");\n});\n\ntest(\"deletes can split retains\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n trackedArray.removeItems(0, 2);\n\n equal(trackedArray.toString(), \"d:2 r:2\", \"deletes can split retains\");\n deepEqual(trackedArray._operations[1].items, [3,4], \"retains reduced by delete have the right items\");\n});\n\ntest(\"deletes can trim retains on the right\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3]);\n trackedArray.removeItems(2, 1);\n\n equal(trackedArray.toString(), \"r:2 d:1\", \"deletes can trim retains on the right\");\n deepEqual(trackedArray._operations[0].items, [1,2], \"retains reduced by delete have the right items\");\n});\n\ntest(\"deletes can trim retains on the left\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3]);\n trackedArray.removeItems(0, 1);\n\n equal(trackedArray.toString(), \"d:1 r:2\", \"deletes can trim retains on the left\");\n deepEqual(trackedArray._operations[1].items, [2,3], \"retains reduced by delete have the right items\");\n});\n\ntest(\"deletes can split inserts\", function() {\n trackedArray = new Ember.TrackedArray([]);\n trackedArray.addItems(0, ['a','b','c']);\n trackedArray.removeItems(0, 1);\n\n equal(trackedArray.toString(), \"i:2\", \"deletes can split inserts\");\n deepEqual(trackedArray._operations[0].items, ['b', 'c'], \"inserts reduced by delete have the right items\");\n});\n\ntest(\"deletes can trim inserts on the right\", function() {\n trackedArray = new Ember.TrackedArray([]);\n trackedArray.addItems(0, ['a','b','c']);\n trackedArray.removeItems(2, 1);\n\n equal(trackedArray.toString(), \"i:2\", \"deletes can trim inserts on the right\");\n deepEqual(trackedArray._operations[0].items, ['a', 'b'], \"inserts reduced by delete have the right items\");\n});\n\ntest(\"deletes can trim inserts on the left\", function() {\n trackedArray = new Ember.TrackedArray([]);\n trackedArray.addItems(0, ['a','b','c']);\n trackedArray.removeItems(0, 1);\n\n equal(trackedArray.toString(), \"i:2\", \"deletes can trim inserts on the right\");\n deepEqual(trackedArray._operations[0].items, ['b', 'c'], \"inserts reduced by delete have the right items\");\n});\n\ntest(\"deletes can trim inserts on the left while composing with a delete on the left\", function() {\n trackedArray = new Ember.TrackedArray(['a']);\n trackedArray.removeItems(0, 1);\n trackedArray.addItems(0, ['b', 'c']);\n trackedArray.removeItems(0, 1);\n\n equal(trackedArray.toString(), \"d:1 i:1\", \"deletes can trim inserts and compose with a delete on the left\");\n deepEqual(trackedArray._operations[1].items, ['c'], \"inserts reduced by delete have the right items\");\n});\n\ntest(\"deletes can reduce an insert or retain, compose with several mutations of different types and reduce the last mutation if it is non-delete\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n\n trackedArray.addItems(4, ['e', 'f']); // 1234ef\n trackedArray.addItems(3, ['d']); // 123d4ef\n trackedArray.addItems(2, ['c']); // 12c3d4ef\n trackedArray.addItems(1, ['b']); // 1b2c3d4ef\n trackedArray.addItems(0, ['a','a','a']); // aaa1b2c3d4ef i3r1i1r1i1r1i1r1i2\n\n trackedArray.removeItems(1, 10);\n equal(trackedArray.toString(), \"i:1 d:4 i:1\", \"deletes reduce an insert, compose with several inserts and retains, reducing the last one\");\n deepEqual(trackedArray._operations[0].items, ['a'], \"first reduced mutation's items is correct\");\n deepEqual(trackedArray._operations[2].items, ['f'], \"last reduced mutation's items is correct\");\n});\n\ntest(\"removeItems returns the removed items\", function() {\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n deepEqual(trackedArray.removeItems(1, 2), [2,3], \"`removeItems` returns the removed items\");\n});\n\ntest(\"apply invokes the callback with each group of items and the mutation's calculated offset\", function() {\n var i = 0;\n trackedArray = new Ember.TrackedArray([1,2,3,4]);\n\n trackedArray.addItems(2, ['a','b','c']); // 12abc34\n trackedArray.removeItems(4, 2); // 12ab4\n trackedArray.addItems(1, ['d']); // 1d2ab4 r1 i1 r1 i2 d1 r1\n\n equal(trackedArray.toString(), \"r:1 i:1 r:1 i:2 d:1 r:1\", \"precond - trackedArray is in expected state\");\n\n trackedArray.apply(function (items, offset, operation) {\n switch (i++) {\n case 0:\n deepEqual(items, [1], \"callback passed right items\");\n equal(offset, 0, \"callback passed right offset\");\n equal(operation, RETAIN, \"callback passed right operation\");\n break;\n case 1:\n deepEqual(items, ['d'], \"callback passed right items\");\n equal(offset, 1, \"callback passed right offset\");\n equal(operation, INSERT, \"callback passed right operation\");\n break;\n case 2:\n deepEqual(items, [2], \"callback passed right items\");\n equal(offset, 2, \"callback passed right offset\");\n equal(operation, RETAIN, \"callback passed right operation\");\n break;\n case 3:\n deepEqual(items, ['a','b'], \"callback passed right items\");\n equal(offset, 3, \"callback passed right offset\");\n equal(operation, INSERT, \"callback passed right operation\");\n break;\n case 4:\n // deletes not passed items at the moment; that might need to be added\n // if TrackedArray is used more widely\n equal(offset, 5, \"callback passed right offset\");\n equal(operation, DELETE, \"callback passed right operation\");\n break;\n case 5:\n deepEqual(items, [4], \"callback passed right items\");\n equal(offset, 5, \"callback passed right offset\");\n equal(operation, RETAIN, \"callback passed right operation\");\n break;\n }\n });\n equal(i, 6, \"`apply` invoked callback right number of times\");\n\n equal(trackedArray.toString(), \"r:6\", \"after `apply` operations become retain:n\");\n});\n\n})();\n//@ sourceURL=ember-runtime/~tests/system/tracked_array_test");minispade.register('ember-testing/~tests/acceptance_test', "(function() {var App, find, click, fillIn, currentRoute, visit, originalAdapter, andThen;\n\nmodule(\"ember-testing Acceptance\", {\n setup: function() {\n Ember.$('').appendTo('head');\n Ember.$('
    ').appendTo('body');\n Ember.run(function() {\n App = Ember.Application.create({\n rootElement: '#ember-testing'\n });\n\n App.Router.map(function() {\n this.route('posts');\n this.route('comments');\n\n this.route('abort_transition');\n });\n\n App.PostsRoute = Ember.Route.extend({\n renderTemplate: function() {\n currentRoute = 'posts';\n this._super();\n }\n });\n\n App.PostsView = Ember.View.extend({\n defaultTemplate: Ember.Handlebars.compile(\"
    {{#linkTo 'comments'}}Comments{{/linkTo}}
    \"),\n classNames: ['posts-view']\n });\n\n App.CommentsRoute = Ember.Route.extend({\n renderTemplate: function() {\n currentRoute = 'comments';\n this._super();\n }\n });\n\n App.CommentsView = Ember.View.extend({\n defaultTemplate: Ember.Handlebars.compile(\"{{input type=text}}\")\n });\n\n App.AbortTransitionRoute = Ember.Route.extend({\n beforeModel: function(transition) {\n transition.abort();\n }\n });\n\n App.setupForTesting();\n });\n\n Ember.run(function() {\n App.advanceReadiness();\n });\n\n App.injectTestHelpers();\n\n find = window.find;\n click = window.click;\n fillIn = window.fillIn;\n visit = window.visit;\n andThen = window.andThen;\n\n originalAdapter = Ember.Test.adapter;\n },\n\n teardown: function() {\n App.removeTestHelpers();\n Ember.$('#ember-testing-container, #ember-testing').remove();\n Ember.run(App, App.destroy);\n App = null;\n Ember.Test.adapter = originalAdapter;\n }\n});\n\ntest(\"helpers can be chained with then\", function() {\n expect(5);\n\n currentRoute = 'index';\n\n visit('/posts').then(function() {\n equal(currentRoute, 'posts', \"Successfully visited posts route\");\n return click('a:contains(\"Comments\")');\n }).then(function() {\n equal(currentRoute, 'comments', \"visit chained with click\");\n return fillIn('.ember-text-field', \"yeah\");\n }).then(function() {\n equal(Ember.$('.ember-text-field').val(), 'yeah', \"chained with fillIn\");\n return fillIn('.ember-text-field', '#ember-testing-container', \"context working\");\n }).then(function() {\n equal(Ember.$('.ember-text-field').val(), 'context working', \"chained with fillIn\");\n click(\".does-not-exist\");\n }).then(null, function(e) {\n equal(e.message, \"Element .does-not-exist not found.\", \"Non-existent click exception caught\");\n });\n});\n\n\n\n// Keep this for backwards compatibility\n\ntest(\"helpers can be chained to each other\", function() {\n expect(4);\n\n currentRoute = 'index';\n\n visit('/posts')\n .click('a:first', '#comments-link')\n .fillIn('.ember-text-field', \"hello\")\n .then(function() {\n equal(currentRoute, 'comments', \"Successfully visited comments route\");\n equal(Ember.$('.ember-text-field').val(), 'hello', \"Fillin successfully works\");\n find('.ember-text-field').one('keypress', function(e) {\n equal(e.keyCode, 13, \"keyevent chained with correct keyCode.\");\n });\n })\n .keyEvent('.ember-text-field', 'keypress', 13)\n .visit('/posts')\n .then(function() {\n equal(currentRoute, 'posts', \"Thens can also be chained to helpers\");\n });\n});\n\ntest(\"helpers don't need to be chained\", function() {\n expect(3);\n\n currentRoute = 'index';\n\n visit('/posts');\n\n click('a:first', '#comments-link');\n\n fillIn('.ember-text-field', \"hello\");\n\n andThen(function() {\n equal(currentRoute, 'comments', \"Successfully visited comments route\");\n equal(find('.ember-text-field').val(), 'hello', \"Fillin successfully works\");\n });\n\n visit('/posts');\n\n andThen(function() {\n equal(currentRoute, 'posts');\n });\n});\n\ntest(\"Nested async helpers\", function() {\n expect(3);\n\n currentRoute = 'index';\n\n visit('/posts');\n\n andThen(function() {\n click('a:first', '#comments-link');\n\n fillIn('.ember-text-field', \"hello\");\n });\n\n andThen(function() {\n equal(currentRoute, 'comments', \"Successfully visited comments route\");\n equal(find('.ember-text-field').val(), 'hello', \"Fillin successfully works\");\n });\n\n visit('/posts');\n\n andThen(function() {\n equal(currentRoute, 'posts');\n });\n});\n\ntest(\"Helpers nested in thens\", function() {\n expect(3);\n\n currentRoute = 'index';\n\n visit('/posts').then(function() {\n click('a:first', '#comments-link');\n });\n\n andThen(function() {\n fillIn('.ember-text-field', \"hello\");\n });\n\n andThen(function() {\n equal(currentRoute, 'comments', \"Successfully visited comments route\");\n equal(find('.ember-text-field').val(), 'hello', \"Fillin successfully works\");\n });\n\n visit('/posts');\n\n andThen(function() {\n equal(currentRoute, 'posts');\n });\n});\n\ntest(\"Aborted transitions are not logged via Ember.Test.adapter#exception\", function () {\n expect(0);\n\n Ember.Test.adapter = Ember.Test.QUnitAdapter.create({\n exception: function(error) {\n ok(false, \"aborted transitions are not logged\");\n }\n });\n\n visit(\"/abort_transition\");\n});\n\ntest(\"Unhandled exceptions are logged via Ember.Test.adapter#exception\", function () {\n expect(2);\n\n Ember.Test.adapter = Ember.Test.QUnitAdapter.create({\n exception: function(error) {\n equal(error.message, \"Element .does-not-exist not found.\", \"Exception successfully caught and passed to Ember.Test.adapter.exception\");\n }\n });\n\n visit('/posts');\n\n click(\".invalid-element\").then(null, function(error) {\n equal(error.message, \"Element .invalid-element not found.\", \"Exception successfully handled in the rejection handler\");\n });\n\n click(\".does-not-exist\");\n});\n\n})();\n//@ sourceURL=ember-testing/~tests/acceptance_test");minispade.register('ember-testing/~tests/adapters_test', "(function() {var App;\n\nmodule(\"ember-testing Adapters\", {\n teardown: function() {\n Ember.run(App, App.destroy);\n App.removeTestHelpers();\n App = null;\n }\n});\n\ntest(\"Setting a test adapter manually\", function() {\n expect(1);\n var originalAdapter = Ember.Test.adapter, CustomAdapter;\n\n CustomAdapter = Ember.Test.Adapter.extend({\n asyncStart: function() {\n ok(true, \"Correct adapter was used\");\n }\n });\n\n Ember.run(function() {\n App = Ember.Application.create();\n Ember.Test.adapter = CustomAdapter.create();\n App.setupForTesting();\n });\n\n Ember.Test.adapter.asyncStart();\n\n Ember.Test.adapter = originalAdapter;\n});\n\ntest(\"QUnitAdapter is used by default\", function() {\n expect(1);\n var originalAdapter = Ember.Test.adapter, CustomAdapter;\n\n Ember.Test.adapter = null;\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n ok(Ember.Test.adapter instanceof Ember.Test.QUnitAdapter);\n\n Ember.Test.adapter = originalAdapter;\n});\n\n})();\n//@ sourceURL=ember-testing/~tests/adapters_test");minispade.register('ember-testing/~tests/helpers_test', "(function() {var App;\n\nfunction cleanup(){\n if (App) {\n Ember.run(App, App.destroy);\n App.removeTestHelpers();\n App = null;\n }\n\n Ember.run(function(){\n Ember.$(document).off('ajaxStart');\n Ember.$(document).off('ajaxStop');\n });\n\n Ember.TEMPLATES = {};\n}\n\nfunction assertHelpers(application, helperContainer, expected){\n if (!helperContainer) { helperContainer = window; }\n if (expected === undefined) { expected = true; }\n\n function checkHelperPresent(helper, expected){\n var presentInHelperContainer = !!helperContainer[helper],\n presentInTestHelpers = !!application.testHelpers[helper];\n\n ok(presentInHelperContainer === expected, \"Expected '\" + helper + \"' to be present in the helper container (defaults to window).\");\n ok(presentInTestHelpers === expected, \"Expected '\" + helper + \"' to be present in App.testHelpers.\");\n }\n\n checkHelperPresent('visit', expected);\n checkHelperPresent('click', expected);\n checkHelperPresent('keyEvent', expected);\n checkHelperPresent('fillIn', expected);\n checkHelperPresent('wait', expected);\n}\n\nfunction assertNoHelpers(application, helperContainer) {\n assertHelpers(application, helperContainer, false);\n}\n\nmodule(\"ember-testing Helpers\", {\n setup: function(){ cleanup(); },\n teardown: function() { cleanup(); }\n});\n\ntest(\"Ember.Application#injectTestHelpers/#removeTestHelpers\", function() {\n App = Ember.run(Ember.Application, Ember.Application.create);\n assertNoHelpers(App);\n\n App.injectTestHelpers();\n assertHelpers(App);\n\n App.removeTestHelpers();\n assertNoHelpers(App);\n});\n\ntest(\"Ember.Application#setupForTesting\", function() {\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n equal(App.__container__.lookup('router:main').location.implementation, 'none');\n});\n\ntest(\"Ember.Test.registerHelper/unregisterHelper\", function() {\n expect(5);\n var appBooted = false;\n\n Ember.Test.registerHelper('boot', function(app) {\n Ember.run(app, app.advanceReadiness);\n appBooted = true;\n return window.wait();\n });\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n App.injectTestHelpers();\n });\n\n ok(App.testHelpers.boot);\n ok(window.boot);\n\n window.boot().then(function() {\n ok(appBooted);\n\n App.removeTestHelpers();\n Ember.Test.unregisterHelper('boot');\n\n ok(!App.testHelpers.boot);\n ok(!window.boot);\n });\n\n});\n\ntest(\"`wait` helper can be passed a resolution value\", function() {\n expect(4);\n\n var promise, wait;\n\n promise = new Ember.RSVP.Promise(function(resolve) {\n Ember.run(null, resolve, 'promise');\n });\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n App.injectTestHelpers();\n\n Ember.run(App, App.advanceReadiness);\n\n wait = App.testHelpers.wait;\n\n wait('text').then(function(val) {\n equal(val, 'text', 'can resolve to a string');\n return wait(1);\n }).then(function(val) {\n equal(val, 1, 'can resolve to an integer');\n return wait({ age: 10 });\n }).then(function(val) {\n deepEqual(val, { age: 10 }, 'can resolve to an object');\n return wait(promise);\n }).then(function(val) {\n equal(val, 'promise', 'can resolve to a promise resolution value');\n });\n\n});\n\ntest(\"`click` triggers appropriate events in order\", function() {\n expect(4);\n\n var click, wait, events;\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n App.IndexView = Ember.View.extend({\n classNames: 'index-view',\n\n didInsertElement: function() {\n this.$().on('mousedown focusin mouseup click', function(e) {\n events.push(e.type);\n });\n },\n\n Checkbox: Ember.Checkbox.extend({\n click: function() {\n events.push('click:' + this.get('checked'));\n },\n\n change: function() {\n events.push('change:' + this.get('checked'));\n }\n })\n });\n\n Ember.TEMPLATES.index = Ember.Handlebars.compile('{{input type=\"text\"}} {{view view.Checkbox}} {{textarea}}');\n\n App.injectTestHelpers();\n\n Ember.run(App, App.advanceReadiness);\n\n click = App.testHelpers.click;\n wait = App.testHelpers.wait;\n\n wait().then(function() {\n events = [];\n return click('.index-view');\n }).then(function() {\n deepEqual(events,\n ['mousedown', 'mouseup', 'click'],\n 'fires events in order');\n }).then(function() {\n events = [];\n return click('.index-view input[type=text]');\n }).then(function() {\n deepEqual(events,\n ['mousedown', 'focusin', 'mouseup', 'click'],\n 'fires focus events on inputs');\n }).then(function() {\n events = [];\n return click('.index-view textarea');\n }).then(function() {\n deepEqual(events,\n ['mousedown', 'focusin', 'mouseup', 'click'],\n 'fires focus events on textareas');\n }).then(function() {\n // In IE (< 8), the change event only fires when the value changes before element focused.\n Ember.$('.index-view input[type=checkbox]').focus();\n events = [];\n return click('.index-view input[type=checkbox]');\n }).then(function() {\n // i.e. mousedown, mouseup, change:true, click, click:true\n // Firefox differs so we can't assert the exact ordering here.\n // See https://bugzilla.mozilla.org/show_bug.cgi?id=843554.\n equal(events.length, 5, 'fires click and change on checkboxes');\n });\n});\n\ntest(\"Ember.Application#injectTestHelpers\", function() {\n var documentEvents;\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n documentEvents = Ember.$._data(document, 'events');\n\n if (!documentEvents) {\n documentEvents = {};\n }\n\n ok(documentEvents['ajaxStart'] === undefined, 'there are no ajaxStart listers setup prior to calling injectTestHelpers');\n ok(documentEvents['ajaxStop'] === undefined, 'there are no ajaxStop listers setup prior to calling injectTestHelpers');\n\n App.injectTestHelpers();\n documentEvents = Ember.$._data(document, 'events');\n\n equal(documentEvents['ajaxStart'].length, 1, 'calling injectTestHelpers registers an ajaxStart handler');\n equal(documentEvents['ajaxStop'].length, 1, 'calling injectTestHelpers registers an ajaxStop handler');\n});\n\ntest(\"Ember.Application#injectTestHelpers calls callbacks registered with onInjectHelpers\", function(){\n var injected = 0;\n\n Ember.Test.onInjectHelpers(function(){\n injected++;\n });\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n equal(injected, 0, 'onInjectHelpers are not called before injectTestHelpers');\n\n App.injectTestHelpers();\n\n equal(injected, 1, 'onInjectHelpers are called after injectTestHelpers');\n});\n\ntest(\"Ember.Application#injectTestHelpers adds helpers to provided object.\", function(){\n var helpers = {};\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n App.injectTestHelpers(helpers);\n assertHelpers(App, helpers);\n\n App.removeTestHelpers();\n assertNoHelpers(App, helpers);\n});\n\nif (Ember.FEATURES.isEnabled(\"ember-testing-wait-hooks\")) {\n test(\"`wait` respects registerWaiters\", function() {\n expect(2);\n\n var counter=0;\n function waiter() {\n return ++counter > 2;\n }\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n App.injectTestHelpers();\n\n Ember.run(App, App.advanceReadiness);\n Ember.Test.registerWaiter(waiter);\n\n App.testHelpers.wait().then(function() {\n equal(waiter(), true, 'should not resolve until our waiter is ready');\n Ember.Test.unregisterWaiter(waiter);\n equal(Ember.Test.waiters.length, 0, 'should not leave a waiter registered');\n });\n });\n\n test(\"`wait` waits for outstanding timers\", function() {\n expect(1);\n\n var wait_done = false;\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n App.injectTestHelpers();\n\n Ember.run(App, App.advanceReadiness);\n\n Ember.run.later(this, function() {\n wait_done = true;\n }, 500);\n\n App.testHelpers.wait().then(function() {\n equal(wait_done, true, 'should wait for the timer to be fired.');\n });\n });\n\n\n test(\"`wait` respects registerWaiters with optional context\", function() {\n expect(2);\n\n var obj = {\n counter: 0,\n ready: function() {\n\treturn ++this.counter > 2;\n }\n };\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n App.injectTestHelpers();\n\n Ember.run(App, App.advanceReadiness);\n Ember.Test.registerWaiter(obj, obj.ready);\n\n App.testHelpers.wait().then(function() {\n equal(obj.ready(), true, 'should not resolve until our waiter is ready');\n Ember.Test.unregisterWaiter(obj, obj.ready);\n equal(Ember.Test.waiters.length, 0, 'should not leave a waiter registered');\n });\n\n\n });\n}\n\nmodule(\"ember-testing pendingAjaxRequests\", {\n setup: function(){\n cleanup();\n\n Ember.run(function() {\n App = Ember.Application.create();\n App.setupForTesting();\n });\n\n App.injectTestHelpers();\n },\n\n teardown: function() { cleanup(); }\n});\n\ntest(\"pendingAjaxRequests is incremented on each document ajaxStart event\", function() {\n Ember.Test.pendingAjaxRequests = 0;\n\n Ember.run(function(){\n Ember.$(document).trigger('ajaxStart');\n });\n\n equal(Ember.Test.pendingAjaxRequests, 1, 'Ember.Test.pendingAjaxRequests was incremented');\n});\n\ntest(\"pendingAjaxRequests is decremented on each document ajaxStop event\", function() {\n Ember.Test.pendingAjaxRequests = 1;\n\n Ember.run(function(){\n Ember.$(document).trigger('ajaxStop');\n });\n\n equal(Ember.Test.pendingAjaxRequests, 0, 'Ember.Test.pendingAjaxRequests was decremented');\n});\n\ntest(\"it should raise an assertion error if ajaxStop is called without pendingAjaxRequests\", function() {\n Ember.Test.pendingAjaxRequests = 0;\n\n expectAssertion(function() {\n Ember.run(function(){\n Ember.$(document).trigger('ajaxStop');\n });\n });\n});\n\n})();\n//@ sourceURL=ember-testing/~tests/helpers_test");minispade.register('ember-testing/~tests/integration_test', "(function() {var App, find, visit, originalAdapter;\n\nmodule(\"ember-testing Integration\", {\n setup: function() {\n Ember.$('
    ').appendTo('body');\n Ember.run(function() {\n App = Ember.Application.create({\n rootElement: '#ember-testing'\n });\n\n App.Router.map(function() {\n this.resource(\"people\", { path: \"/\" });\n });\n\n App.PeopleRoute = Ember.Route.extend({\n model: function() {\n return App.Person.find();\n }\n });\n\n App.PeopleView = Ember.View.extend({\n defaultTemplate: Ember.Handlebars.compile(\"{{#each person in controller}}
    {{person.firstName}}
    {{/each}}\")\n });\n\n App.PeopleController = Ember.ArrayController.extend({});\n\n App.Person = Ember.Object.extend({\n firstName: ''\n });\n\n App.Person.reopenClass({\n find: function() {\n return Ember.A(); \n }\n });\n\n App.ApplicationView = Ember.View.extend({\n defaultTemplate: Ember.Handlebars.compile(\"{{outlet}}\")\n });\n\n App.setupForTesting();\n });\n\n Ember.run(function() {\n App.reset();\n App.deferReadiness();\n });\n\n App.injectTestHelpers();\n\n find = window.find;\n visit = window.visit;\n\n originalAdapter = Ember.Test.adapter;\n },\n\n teardown: function() {\n App.removeTestHelpers();\n Ember.$('#ember-testing-container, #ember-testing').remove();\n Ember.run(App, App.destroy);\n App = null;\n Ember.Test.adapter = originalAdapter;\n }\n});\n\ntest(\"template is bound to empty array of people\", function() {\n App.Person.find = function() {\n return Ember.A();\n };\n Ember.run(App, 'advanceReadiness');\n visit(\"/\").then(function() {\n var rows = find(\".name\").length;\n equal(rows, 0, \"successfully stubbed an empty array of people\");\n });\n});\n\ntest(\"template is bound to array of 2 people\", function() {\n App.Person.find = function() {\n var people = Ember.A();\n var first = App.Person.create({firstName: \"x\"});\n var last = App.Person.create({firstName: \"y\"});\n Ember.run(people, people.pushObject, first);\n Ember.run(people, people.pushObject, last);\n return people;\n };\n Ember.run(App, 'advanceReadiness');\n visit(\"/\").then(function() {\n var rows = find(\".name\").length;\n equal(rows, 2, \"successfully stubbed a non empty array of people\");\n });\n});\n\ntest(\"template is again bound to empty array of people\", function() {\n App.Person.find = function() {\n return Ember.A();\n };\n Ember.run(App, 'advanceReadiness');\n visit(\"/\").then(function() {\n var rows = find(\".name\").length;\n equal(rows, 0, \"successfully stubbed another empty array of people\");\n });\n});\n\n})();\n//@ sourceURL=ember-testing/~tests/integration_test");minispade.register('ember-views/~tests/mixins/view_target_action_support_test', "(function() {/*global Test:true*/\n\nvar originalLookup;\n\nmodule(\"Ember.ViewTargetActionSupport\", {\n setup: function() {\n originalLookup = Ember.lookup;\n },\n teardown: function() {\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"it should return false if no action is specified\", function() {\n expect(1);\n\n var view = Ember.View.createWithMixins(Ember.ViewTargetActionSupport, {\n controller: Ember.Object.create()\n });\n\n ok(false === view.triggerAction(), \"a valid target and action were specified\");\n});\n\ntest(\"it should support actions specified as strings\", function() {\n expect(2);\n\n var view = Ember.View.createWithMixins(Ember.ViewTargetActionSupport, {\n controller: Ember.Object.create({\n anEvent: function() {\n ok(true, \"anEvent method was called\");\n }\n }),\n action: 'anEvent'\n });\n\n ok(true === view.triggerAction(), \"a valid target and action were specified\");\n});\n\ntest(\"it should invoke the send() method on the controller with the view's context\", function() {\n expect(3);\n\n var view = Ember.View.createWithMixins(Ember.ViewTargetActionSupport, {\n context: {},\n controller: Ember.Object.create({\n send: function(evt, context) {\n equal(evt, 'anEvent', \"send() method was invoked with correct event name\");\n equal(context, view.context, \"send() method was invoked with correct context\");\n }\n }),\n action: 'anEvent'\n });\n\n ok(true === view.triggerAction(), \"a valid target and action were specified\");\n});\n\n})();\n//@ sourceURL=ember-views/~tests/mixins/view_target_action_support_test");minispade.register('ember-views/~tests/system/event_dispatcher_test', "(function() {var view;\nvar dispatcher;\nvar set = Ember.set, get = Ember.get;\n\nmodule(\"Ember.EventDispatcher\", {\n setup: function() {\n Ember.run(function() {\n dispatcher = Ember.EventDispatcher.create();\n dispatcher.setup();\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n if (view) { view.destroy(); }\n dispatcher.destroy();\n });\n }\n});\n\ntest(\"should dispatch events to views\", function() {\n var receivedEvent;\n var parentMouseDownCalled = 0;\n var childKeyDownCalled = 0;\n var parentKeyDownCalled = 0;\n\n view = Ember.ContainerView.createWithMixins({\n childViews: ['child'],\n\n child: Ember.View.extend({\n render: function(buffer) {\n buffer.push('ewot');\n },\n\n keyDown: function(evt) {\n childKeyDownCalled++;\n\n return false;\n }\n }),\n\n render: function(buffer) {\n buffer.push('some awesome content');\n this._super(buffer);\n },\n\n mouseDown: function(evt) {\n parentMouseDownCalled++;\n receivedEvent = evt;\n },\n\n keyDown: function(evt) {\n parentKeyDownCalled++;\n }\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n view.$().trigger('mousedown');\n\n ok(receivedEvent, \"passes event to associated event method\");\n receivedEvent = null;\n parentMouseDownCalled = 0;\n\n view.$('span#awesome').trigger('mousedown');\n ok(receivedEvent, \"event bubbles up to nearest Ember.View\");\n equal(parentMouseDownCalled, 1, \"does not trigger the parent handlers twice because of browser bubbling\");\n receivedEvent = null;\n\n Ember.$('#wot').trigger('mousedown');\n ok(receivedEvent, \"event bubbles up to nearest Ember.View\");\n\n Ember.$('#wot').trigger('keydown');\n equal(childKeyDownCalled, 1, \"calls keyDown on child view\");\n equal(parentKeyDownCalled, 0, \"does not call keyDown on parent if child handles event\");\n});\n\ntest(\"should not dispatch events to views not inDOM\", function() {\n var receivedEvent;\n\n view = Ember.View.createWithMixins({\n render: function(buffer) {\n buffer.push('some awesome content');\n this._super(buffer);\n },\n\n mouseDown: function(evt) {\n receivedEvent = evt;\n }\n });\n\n Ember.run(function() {\n view.append();\n });\n\n var $element = view.$();\n\n Ember.run(function() {\n view.set('element', null); // Force into preRender\n });\n\n $element.trigger('mousedown');\n\n ok(!receivedEvent, \"does not pass event to associated event method\");\n receivedEvent = null;\n\n $element.find('span#awesome').trigger('mousedown');\n ok(!receivedEvent, \"event does not bubble up to nearest Ember.View\");\n receivedEvent = null;\n\n // Cleanup\n $element.remove();\n});\n\ntest(\"should send change events up view hierarchy if view contains form elements\", function() {\n var receivedEvent;\n view = Ember.View.create({\n render: function(buffer) {\n buffer.push('');\n },\n\n change: function(evt) {\n receivedEvent = evt;\n }\n });\n\n Ember.run(function() {\n view.append();\n });\n\n Ember.$('#is-done').trigger('change');\n ok(receivedEvent, \"calls change method when a child element is changed\");\n equal(receivedEvent.target, Ember.$('#is-done')[0], \"target property is the element that was clicked\");\n});\n\ntest(\"events should stop propagating if the view is destroyed\", function() {\n var parentViewReceived, receivedEvent;\n\n var parentView = Ember.ContainerView.create({\n change: function(evt) {\n parentViewReceived = true;\n }\n });\n\n view = parentView.createChildView(Ember.View, {\n render: function(buffer) {\n buffer.push('');\n },\n\n change: function(evt) {\n receivedEvent = true;\n var self = this;\n Ember.run(function() {\n get(self, 'parentView').destroy();\n });\n }\n });\n\n parentView.pushObject(view);\n\n Ember.run(function() {\n parentView.append();\n });\n\n ok(Ember.$('#is-done').length, \"precond - view is in the DOM\");\n Ember.$('#is-done').trigger('change');\n ok(!Ember.$('#is-done').length, \"precond - view is not in the DOM\");\n ok(receivedEvent, \"calls change method when a child element is changed\");\n ok(!parentViewReceived, \"parent view does not receive the event\");\n});\n\ntest(\"should not interfere with event propagation\", function() {\n var receivedEvent;\n view = Ember.View.create({\n render: function(buffer) {\n buffer.push('
    ');\n }\n });\n\n Ember.run(function() {\n view.append();\n });\n\n Ember.$(window).bind('click', function(evt) {\n receivedEvent = evt;\n });\n\n Ember.$('#propagate-test-div').click();\n\n ok(receivedEvent, \"allowed event to propagate outside Ember\");\n deepEqual(receivedEvent.target, Ember.$('#propagate-test-div')[0], \"target property is the element that was clicked\");\n});\n\ntest(\"should dispatch events to nearest event manager\", function() {\n var receivedEvent=0;\n view = Ember.ContainerView.create({\n render: function(buffer) {\n buffer.push('');\n },\n\n eventManager: Ember.Object.create({\n mouseDown: function() {\n receivedEvent++;\n }\n }),\n\n mouseDown: function() {}\n });\n\n Ember.run(function() {\n view.append();\n });\n\n Ember.$('#is-done').trigger('mousedown');\n equal(receivedEvent, 1, \"event should go to manager and not view\");\n});\n\ntest(\"event manager should be able to re-dispatch events to view\", function() {\n\n var receivedEvent=0;\n view = Ember.ContainerView.createWithMixins({\n elementId: 'containerView',\n\n eventManager: Ember.Object.create({\n mouseDown: function(evt, view) {\n // Re-dispatch event when you get it.\n //\n // The second parameter tells the dispatcher\n // that this event has been handled. This\n // API will clearly need to be reworked since\n // multiple eventManagers in a single view\n // hierarchy would break, but it shows that\n // re-dispatching works\n view.$().trigger('mousedown',this);\n }\n }),\n\n childViews: ['child'],\n\n child: Ember.View.extend({\n elementId: 'nestedView',\n\n mouseDown: function(evt) {\n receivedEvent++;\n }\n }),\n\n mouseDown: function(evt) {\n receivedEvent++;\n }\n });\n\n Ember.run(function() { view.append(); });\n\n Ember.$('#nestedView').trigger('mousedown');\n equal(receivedEvent, 2, \"event should go to manager and not view\");\n});\n\ntest(\"event handlers should be wrapped in a run loop\", function() {\n expect(1);\n\n view = Ember.View.createWithMixins({\n elementId: 'test-view',\n\n eventManager: Ember.Object.create({\n mouseDown: function() {\n ok(Ember.run.currentRunLoop, 'a run loop should have started');\n }\n })\n });\n\n Ember.run(function() { view.append(); });\n\n Ember.$('#test-view').trigger('mousedown');\n});\n\n})();\n//@ sourceURL=ember-views/~tests/system/event_dispatcher_test");minispade.register('ember-views/~tests/system/ext_test', "(function() {module(\"Ember.View additions to run queue\");\n\ntest(\"View hierarchy is done rendering to DOM when functions queued in afterRender execute\", function() {\n var lookup1, lookup2;\n var childView = Ember.View.create({\n elementId: 'child_view',\n render: function(buffer) {\n buffer.push('child');\n },\n didInsertElement: function() {\n this.$().addClass('extra-class');\n }\n });\n var parentView = Ember.View.create({\n elementId: 'parent_view',\n render: function(buffer) {\n buffer.push('parent');\n this.appendChild(childView);\n },\n didInsertElement: function() {\n lookup1 = this.$('.extra-class');\n Ember.run.scheduleOnce('afterRender', this, function() {\n lookup2 = this.$('.extra-class');\n });\n }\n });\n\n Ember.run(function() {\n parentView.appendTo('#qunit-fixture');\n });\n\n equal(lookup1.length, 0, \"doesn't not find child in DOM on didInsertElement\");\n equal(lookup2.length, 1, \"finds child in DOM afterRender\");\n\n Ember.run(function() {\n parentView.destroy();\n });\n});\n\n})();\n//@ sourceURL=ember-views/~tests/system/ext_test");minispade.register('ember-views/~tests/system/jquery_ext_test', "(function() {var view, dispatcher;\n\n// Adapted from https://github.com/jquery/jquery/blob/f30f7732e7775b6e417c4c22ced7adb2bf76bf89/test/data/testinit.js\nvar canDataTransfer,\n fireNativeWithDataTransfer;\nif (document.createEvent) {\n canDataTransfer = !!document.createEvent('HTMLEvents').dataTransfer;\n fireNativeWithDataTransfer = function(node, type, dataTransfer) {\n var event = document.createEvent('HTMLEvents');\n event.initEvent(type, true, true);\n event.dataTransfer = dataTransfer;\n node.dispatchEvent(event);\n };\n} else {\n canDataTransfer = !!document.createEventObject().dataTransfer;\n fireNativeWithDataTransfer = function(node, type, dataTransfer) {\n var event = document.createEventObject();\n event.dataTransfer = dataTransfer;\n node.fireEvent('on' + type, event);\n };\n}\n\nmodule(\"Ember.EventDispatcher\", {\n setup: function() {\n Ember.run(function() {\n dispatcher = Ember.EventDispatcher.create();\n dispatcher.setup();\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n if (view) { view.destroy(); }\n dispatcher.destroy();\n });\n }\n});\n\nif (canDataTransfer) {\n test(\"jQuery.event.fix copies over the dataTransfer property\", function() {\n var originalEvent;\n var receivedEvent;\n\n originalEvent = {\n type: 'drop',\n dataTransfer: 'success',\n target: document.body\n };\n\n receivedEvent = Ember.$.event.fix(originalEvent);\n\n ok(receivedEvent !== originalEvent, \"attributes are copied to a new event object\");\n equal(receivedEvent.dataTransfer, originalEvent.dataTransfer, \"copies dataTransfer property to jQuery event\");\n });\n\n test(\"drop handler should receive event with dataTransfer property\", function() {\n var receivedEvent;\n var dropCalled = 0;\n\n view = Ember.View.createWithMixins({\n render: function(buffer) {\n buffer.push('please drop stuff on me');\n this._super(buffer);\n },\n\n drop: function(evt) {\n receivedEvent = evt;\n dropCalled++;\n }\n });\n\n Ember.run(function() {\n view.append();\n });\n\n fireNativeWithDataTransfer(view.$().get(0), 'drop', 'success');\n\n equal(dropCalled, 1, \"called drop handler once\");\n equal(receivedEvent.dataTransfer, 'success', \"copies dataTransfer property to jQuery event\");\n });\n}\n\n})();\n//@ sourceURL=ember-views/~tests/system/jquery_ext_test");minispade.register('ember-views/~tests/system/render_buffer_test', "(function() {var set = Ember.set, get = Ember.get;\n\n// .......................................................\n// render()\n//\nmodule(\"Ember.RenderBuffer\");\n\ntest(\"RenderBuffers combine strings\", function() {\n var buffer = new Ember.RenderBuffer('div');\n buffer.pushOpeningTag();\n\n buffer.push('a');\n buffer.push('b');\n\n // IE8 returns `element name as upper case with extra whitespace.\n equal(\"
    ab
    \", buffer.string().toLowerCase().replace(/\\s+/g, ''), \"Multiple pushes should concatenate\");\n});\n\ntest(\"value of 0 is included in output\", function() {\n var buffer, $el;\n\n buffer = new Ember.RenderBuffer('input');\n buffer.prop('value', 0);\n buffer.pushOpeningTag();\n $el = buffer.element();\n\n strictEqual($el.value, '0', \"generated element has value of '0'\");\n\n buffer = new Ember.RenderBuffer('input');\n buffer.prop('value', 0);\n buffer.push('
    ');\n buffer.pushOpeningTag();\n buffer.push('
    ');\n $el = Ember.$(buffer.innerString());\n\n strictEqual($el.find('input').val(), '0', \"raw tag has value of '0'\");\n});\n\ntest(\"prevents XSS injection via `id`\", function() {\n var buffer = new Ember.RenderBuffer('div');\n\n buffer.push(''); // We need the buffer to not be empty so we use the string path\n buffer.id('hacked\" megahax=\"yes');\n buffer.pushOpeningTag();\n\n equal('
    ', buffer.string());\n});\n\ntest(\"prevents XSS injection via `attr`\", function() {\n var buffer = new Ember.RenderBuffer('div');\n\n buffer.push(''); // We need the buffer to not be empty so we use the string path\n buffer.attr('id', 'trololol\" onmouseover=\"pwn()');\n buffer.attr('class', \"hax>
    ', buffer.string());\n});\n\ntest(\"prevents XSS injection via `addClass`\", function() {\n var buffer = new Ember.RenderBuffer('div');\n\n buffer.push(''); // We need the buffer to not be empty so we use the string path\n buffer.addClass('megahax\" xss=\"true');\n buffer.pushOpeningTag();\n\n // Regular check then check for IE\n equal('
    ', buffer.string());\n});\n\ntest(\"prevents XSS injection via `style`\", function() {\n var buffer = new Ember.RenderBuffer('div');\n\n buffer.push(''); // We need the buffer to not be empty so we use the string path\n buffer.style('color', 'blue;\" xss=\"true\" style=\"color:red');\n buffer.pushOpeningTag();\n\n equal('
    ', buffer.string());\n});\n\ntest(\"prevents XSS injection via `tagName`\", function() {\n var buffer = new Ember.RenderBuffer('cool-div>
    '); // We need the buffer to not be empty so we use the string path\n buffer.pushOpeningTag();\n buffer.begin('span>', buffer.string());\n});\n\ntest(\"handles null props - Issue #2019\", function() {\n var buffer = new Ember.RenderBuffer('div');\n\n buffer.push(''); // We need the buffer to not be empty so we use the string path\n buffer.prop('value', null);\n buffer.pushOpeningTag();\n\n equal('
    ', buffer.string());\n});\n\ntest(\"handles browsers like Firefox < 11 that don't support outerHTML Issue #1952\", function() {\n var buffer = new Ember.RenderBuffer('div');\n buffer.pushOpeningTag();\n // Make sure element.outerHTML is falsy to trigger the fallback.\n var elementStub = '
    ';\n buffer.element = function() { return elementStub; };\n // IE8 returns `element name as upper case with extra whitespace.\n equal(elementStub, buffer.string().toLowerCase().replace(/\\s/g, ''));\n});\n\nmodule(\"Ember.RenderBuffer - without tagName\");\n\ntest(\"It is possible to create a RenderBuffer without a tagName\", function() {\n var buffer = new Ember.RenderBuffer();\n buffer.push('a');\n buffer.push('b');\n buffer.push('c');\n\n equal(buffer.string(), \"abc\", \"Buffers without tagNames do not wrap the content in a tag\");\n});\n\nmodule(\"Ember.RenderBuffer#element\");\n\ntest(\"properly handles old IE's zero-scope bug\", function() {\n var buffer = new Ember.RenderBuffer('div');\n buffer.pushOpeningTag();\n buffer.push('foo');\n\n var element = buffer.element();\n ok(Ember.$(element).html().match(/script/i), \"should have script tag\");\n ok(!Ember.$(element).html().match(/­/), \"should not have ­\");\n});\n\n})();\n//@ sourceURL=ember-views/~tests/system/render_buffer_test");minispade.register('ember-views/~tests/views/collection_test', "(function() {var set = Ember.set, get = Ember.get;\nvar forEach = Ember.EnumerableUtils.forEach;\nvar view;\n\nmodule(\"Ember.CollectionView\", {\n setup: function() {\n Ember.CollectionView.CONTAINER_MAP.del = 'em';\n },\n teardown: function() {\n delete Ember.CollectionView.CONTAINER_MAP.del;\n Ember.run(function() {\n if (view) { view.destroy(); }\n });\n }\n});\n\ntest(\"should render a view for each item in its content array\", function() {\n view = Ember.CollectionView.create({\n content: Ember.A([1, 2, 3, 4])\n });\n\n Ember.run(function() {\n view.append();\n });\n equal(view.$('div').length, 4);\n});\n\ntest(\"should render the emptyView if content array is empty (view class)\", function() {\n view = Ember.CollectionView.create({\n tagName: 'del',\n content: Ember.A(),\n\n emptyView: Ember.View.extend({\n tagName: 'kbd',\n render: function(buf) {\n buf.push(\"OY SORRY GUVNAH NO NEWS TODAY EH\");\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().find('kbd:contains(\"OY SORRY GUVNAH\")').length, \"displays empty view\");\n});\n\ntest(\"should render the emptyView if content array is empty (view instance)\", function() {\n view = Ember.CollectionView.create({\n tagName: 'del',\n content: Ember.A(),\n\n emptyView: Ember.View.create({\n tagName: 'kbd',\n render: function(buf) {\n buf.push(\"OY SORRY GUVNAH NO NEWS TODAY EH\");\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().find('kbd:contains(\"OY SORRY GUVNAH\")').length, \"displays empty view\");\n});\n\ntest(\"should be able to override the tag name of itemViewClass even if tag is in default mapping\", function() {\n view = Ember.CollectionView.create({\n tagName: 'del',\n content: Ember.A(['NEWS GUVNAH']),\n\n itemViewClass: Ember.View.extend({\n tagName: 'kbd',\n render: function(buf) {\n buf.push(get(this, 'content'));\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().find('kbd:contains(\"NEWS GUVNAH\")').length, \"displays the item view with proper tag name\");\n});\n\ntest(\"should allow custom item views by setting itemViewClass\", function() {\n var passedContents = [];\n view = Ember.CollectionView.create({\n content: Ember.A(['foo', 'bar', 'baz']),\n\n itemViewClass: Ember.View.extend({\n render: function(buf) {\n passedContents.push(get(this, 'content'));\n buf.push(get(this, 'content'));\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n deepEqual(passedContents, ['foo', 'bar', 'baz'], \"sets the content property on each item view\");\n\n forEach(passedContents, function(item) {\n equal(view.$(':contains(\"'+item+'\")').length, 1);\n });\n});\n\ntest(\"should insert a new item in DOM when an item is added to the content array\", function() {\n var content = Ember.A(['foo', 'bar', 'baz']);\n\n view = Ember.CollectionView.create({\n content: content,\n\n itemViewClass: Ember.View.extend({\n render: function(buf) {\n buf.push(get(this, 'content'));\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n forEach(content, function(item) {\n equal(view.$(':contains(\"'+item+'\")').length, 1, \"precond - generates pre-existing items\");\n });\n\n Ember.run(function() {\n content.insertAt(1, 'quux');\n });\n\n equal(Ember.$.trim(view.$(':nth-child(2)').text()), 'quux');\n});\n\ntest(\"should remove an item from DOM when an item is removed from the content array\", function() {\n var content = Ember.A(['foo', 'bar', 'baz']);\n\n view = Ember.CollectionView.create({\n content: content,\n\n itemViewClass: Ember.View.extend({\n render: function(buf) {\n buf.push(get(this, 'content'));\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n forEach(content, function(item) {\n equal(view.$(':contains(\"'+item+'\")').length, 1, \"precond - generates pre-existing items\");\n });\n\n Ember.run(function() {\n content.removeAt(1);\n });\n\n forEach(content, function(item, idx) {\n equal(view.$(Ember.String.fmt(':nth-child(%@)', [String(idx+1)])).text(), item);\n });\n});\n\ntest(\"it updates the view if an item is replaced\", function() {\n var content = Ember.A(['foo', 'bar', 'baz']);\n view = Ember.CollectionView.create({\n content: content,\n\n itemViewClass: Ember.View.extend({\n render: function(buf) {\n buf.push(get(this, 'content'));\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n forEach(content, function(item) {\n equal(view.$(':contains(\"'+item+'\")').length, 1, \"precond - generates pre-existing items\");\n });\n\n Ember.run(function() {\n content.removeAt(1);\n content.insertAt(1, \"Kazuki\" );\n });\n\n forEach(content, function(item, idx) {\n equal(Ember.$.trim(view.$(Ember.String.fmt(':nth-child(%@)', [String(idx+1)])).text()), item, \"postcond - correct array update\");\n });\n});\n\ntest(\"can add and replace in the same runloop\", function() {\n var content = Ember.A(['foo', 'bar', 'baz']);\n view = Ember.CollectionView.create({\n content: content,\n\n itemViewClass: Ember.View.extend({\n render: function(buf) {\n buf.push(get(this, 'content'));\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n forEach(content, function(item) {\n equal(view.$(':contains(\"'+item+'\")').length, 1, \"precond - generates pre-existing items\");\n });\n\n Ember.run(function() {\n content.pushObject(\"Tom Dale\" );\n content.removeAt(0);\n content.insertAt(0, \"Kazuki\" );\n });\n\n forEach(content, function(item, idx) {\n equal(Ember.$.trim(view.$(Ember.String.fmt(':nth-child(%@)', [String(idx+1)])).text()), item, \"postcond - correct array update\");\n });\n\n});\n\ntest(\"can add and replace the object before the add in the same runloop\", function() {\n var content = Ember.A(['foo', 'bar', 'baz']);\n view = Ember.CollectionView.create({\n content: content,\n\n itemViewClass: Ember.View.extend({\n render: function(buf) {\n buf.push(get(this, 'content'));\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n forEach(content, function(item) {\n equal(view.$(':contains(\"'+item+'\")').length, 1, \"precond - generates pre-existing items\");\n });\n\n Ember.run(function() {\n content.pushObject(\"Tom Dale\" );\n content.removeAt(1);\n content.insertAt(1, \"Kazuki\" );\n });\n\n forEach(content, function(item, idx) {\n equal(Ember.$.trim(view.$(Ember.String.fmt(':nth-child(%@)', [String(idx+1)])).text()), item, \"postcond - correct array update\");\n });\n});\n\ntest(\"can add and replace complicatedly\", function() {\n var content = Ember.A(['foo', 'bar', 'baz']);\n view = Ember.CollectionView.create({\n content: content,\n\n itemViewClass: Ember.View.extend({\n render: function(buf) {\n buf.push(get(this, 'content'));\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n forEach(content, function(item) {\n equal(view.$(':contains(\"'+item+'\")').length, 1, \"precond - generates pre-existing items\");\n });\n\n Ember.run(function() {\n content.pushObject(\"Tom Dale\" );\n content.removeAt(1);\n content.insertAt(1, \"Kazuki\" );\n content.pushObject(\"Firestone\" );\n content.pushObject(\"McMunch\" );\n });\n\n forEach(content, function(item, idx) {\n equal(Ember.$.trim(view.$(Ember.String.fmt(':nth-child(%@)', [String(idx+1)])).text()), item, \"postcond - correct array update: \"+item.name+\"!=\"+view.$(Ember.String.fmt(':nth-child(%@)', [String(idx+1)])).text());\n });\n});\n\ntest(\"can add and replace complicatedly harder\", function() {\n var content = Ember.A(['foo', 'bar', 'baz']);\n view = Ember.CollectionView.create({\n content: content,\n\n itemViewClass: Ember.View.extend({\n render: function(buf) {\n buf.push(get(this, 'content'));\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n forEach(content, function(item) {\n equal(view.$(':contains(\"'+item+'\")').length, 1, \"precond - generates pre-existing items\");\n });\n\n Ember.run(function() {\n content.pushObject(\"Tom Dale\" );\n content.removeAt(1);\n content.insertAt(1, \"Kazuki\" );\n content.pushObject(\"Firestone\" );\n content.pushObject(\"McMunch\" );\n content.removeAt(2);\n });\n\n forEach(content, function(item, idx) {\n equal(Ember.$.trim(view.$(Ember.String.fmt(':nth-child(%@)', [String(idx+1)])).text()), item, \"postcond - correct array update\");\n });\n});\n\ntest(\"should allow changes to content object before layer is created\", function() {\n view = Ember.CollectionView.create({\n content: null\n });\n\n\n Ember.run(function() {\n set(view, 'content', Ember.A());\n set(view, 'content', Ember.A([1, 2, 3]));\n set(view, 'content', Ember.A([1, 2]));\n view.append();\n });\n\n ok(view.$().children().length);\n});\n\ntest(\"should fire life cycle events when elements are added and removed\", function() {\n var view,\n didInsertElement = 0,\n willDestroyElement = 0,\n willDestroy = 0,\n destroy = 0,\n content = Ember.A([1, 2, 3]);\n Ember.run(function () {\n view = Ember.CollectionView.create({\n content: content,\n itemViewClass: Ember.View.extend({\n render: function(buf) {\n buf.push(get(this, 'content'));\n },\n didInsertElement: function () {\n didInsertElement++;\n },\n willDestroyElement: function () {\n willDestroyElement++;\n },\n willDestroy: function () {\n willDestroy++;\n this._super();\n },\n destroy: function() {\n destroy++;\n this._super();\n }\n })\n });\n view.appendTo('#qunit-fixture');\n });\n\n equal(didInsertElement, 3);\n equal(willDestroyElement, 0);\n equal(willDestroy, 0);\n equal(destroy, 0);\n equal(view.$().text(), '123');\n\n Ember.run(function () {\n content.pushObject(4);\n content.unshiftObject(0);\n });\n\n\n equal(didInsertElement, 5);\n equal(willDestroyElement, 0);\n equal(willDestroy, 0);\n equal(destroy, 0);\n // Remove whitspace added by IE 8\n equal(view.$().text().replace(/\\s+/g,''), '01234');\n\n Ember.run(function () {\n content.popObject();\n content.shiftObject();\n });\n\n equal(didInsertElement, 5);\n equal(willDestroyElement, 2);\n equal(willDestroy, 2);\n equal(destroy, 2);\n // Remove whitspace added by IE 8\n equal(view.$().text().replace(/\\s+/g,''), '123');\n\n Ember.run(function () {\n view.set('content', Ember.A([7,8,9]));\n });\n\n equal(didInsertElement, 8);\n equal(willDestroyElement, 5);\n equal(willDestroy, 5);\n equal(destroy, 5);\n // Remove whitspace added by IE 8\n equal(view.$().text().replace(/\\s+/g,''), '789');\n\n Ember.run(function () {\n view.destroy();\n });\n\n equal(didInsertElement, 8);\n equal(willDestroyElement, 8);\n equal(willDestroy, 8);\n equal(destroy, 8);\n});\n\ntest(\"should allow changing content property to be null\", function() {\n view = Ember.CollectionView.create({\n content: Ember.A([1, 2, 3]),\n\n emptyView: Ember.View.extend({\n template: function() { return \"(empty)\"; }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n equal(view.$().children().length, 3, \"precond - creates three elements\");\n\n Ember.run(function() {\n set(view, 'content', null);\n });\n\n equal(Ember.$.trim(view.$().children().text()), \"(empty)\", \"should display empty view\");\n});\n\ntest(\"should allow items to access to the CollectionView's current index in the content array\", function() {\n view = Ember.CollectionView.create({\n content: Ember.A(['zero', 'one', 'two']),\n itemViewClass: Ember.View.extend({\n render: function(buf) {\n buf.push(get(this, 'contentIndex'));\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n deepEqual(view.$(':nth-child(1)').text(), \"0\");\n deepEqual(view.$(':nth-child(2)').text(), \"1\");\n deepEqual(view.$(':nth-child(3)').text(), \"2\");\n});\n\ntest(\"should allow declaration of itemViewClass as a string\", function() {\n view = Ember.CollectionView.create({\n content: Ember.A([1, 2, 3]),\n itemViewClass: 'Ember.View'\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('.ember-view').length, 3);\n});\n\ntest(\"should not render the emptyView if content is emptied and refilled in the same run loop\", function() {\n view = Ember.CollectionView.create({\n tagName: 'div',\n content: Ember.A(['NEWS GUVNAH']),\n\n emptyView: Ember.View.extend({\n tagName: 'kbd',\n render: function(buf) {\n buf.push(\"OY SORRY GUVNAH NO NEWS TODAY EH\");\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n equal(view.$().find('kbd:contains(\"OY SORRY GUVNAH\")').length, 0);\n\n Ember.run(function() {\n view.get('content').popObject();\n view.get('content').pushObject(['NEWS GUVNAH']);\n });\n equal(view.$('div').length, 1);\n equal(view.$().find('kbd:contains(\"OY SORRY GUVNAH\")').length, 0);\n});\n\ntest(\"a array_proxy that backs an sorted array_controller that backs a collection view functions properly\", function() {\n\n var array = Ember.A([{ name: \"Other Katz\" }]);\n var arrayProxy = Ember.ArrayProxy.create({content: array});\n\n var sortedController = Ember.ArrayController.create({\n content: arrayProxy,\n sortProperties: ['name']\n });\n\n var container = Ember.CollectionView.create({\n content: sortedController\n });\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n Ember.run(function() {\n arrayProxy.addObjects([{ name: \"Scumbag Demon\" }, { name: \"Lord British\" }]);\n });\n\n equal(container.get('content.length'), 3, 'ArrayController should have 3 entries');\n equal(container.get('content.content.length'), 3, 'RecordArray should have 3 entries');\n equal(container.get('childViews.length'), 3, 'CollectionView should have 3 entries');\n\n Ember.run(function() {\n container.destroy();\n });\n});\n\ntest(\"when a collection view is emptied, deeply nested views elements are not removed from the DOM and then destroyed again\", function() {\n var assertProperDestruction = Ember.Mixin.create({\n destroyElement: function() {\n if (this.state === 'inDOM') {\n ok(this.get('element'), this + ' still exists in DOM');\n }\n return this._super();\n }\n });\n\n var ChildView = Ember.View.extend(assertProperDestruction, {\n render: function(buf) {\n // emulate nested template\n this.appendChild(Ember.View.createWithMixins(assertProperDestruction, {\n template: function() { return \"
    \"; }\n }));\n }\n });\n\n var view = Ember.CollectionView.create({\n content: Ember.A([1]),\n itemViewClass: ChildView\n });\n\n\n Ember.run(function() {\n view.append();\n });\n equal(Ember.$('.inner_element').length, 1, \"precond - generates inner element\");\n\n Ember.run(function() {\n view.get('content').clear();\n });\n equal(Ember.$('.inner_element').length, 0, \"elements removed\");\n\n Ember.run(function() {\n view.remove();\n });\n});\n\ntest(\"should render the emptyView if content array is empty and emptyView is given as string\", function() {\n Ember.lookup = {\n App: {\n EmptyView: Ember.View.extend({\n tagName: 'kbd',\n render: function(buf) {\n buf.push(\"THIS IS AN EMPTY VIEW\");\n }\n })\n }\n };\n view = Ember.CollectionView.create({\n tagName: 'del',\n content: Ember.A(),\n\n emptyView: 'App.EmptyView'\n });\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().find('kbd:contains(\"THIS IS AN EMPTY VIEW\")').length, \"displays empty view\");\n});\n\ntest(\"should lookup against the container if itemViewClass is given as a string\", function() {\n\n var ItemView = Ember.View.extend({\n render: function(buf) {\n buf.push(get(this, 'content'));\n }\n });\n\n var container = {\n lookupFactory: lookupFactory\n };\n\n view = Ember.CollectionView.create({\n container: container,\n content: Ember.A([1, 2, 3, 4]),\n itemViewClass: 'item'\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(view.$('.ember-view').length, 4);\n\n function lookupFactory(fullName) {\n equal(fullName, 'view:item');\n\n return ItemView;\n }\n});\n\ntest(\"should lookup against the container and render the emptyView if emptyView is given as string and content array is empty \", function() {\n var EmptyView = Ember.View.extend({\n tagName: 'kbd',\n render: function(buf) {\n buf.push(\"THIS IS AN EMPTY VIEW\");\n }\n });\n\n var container = {\n lookupFactory: lookupFactory\n };\n\n view = Ember.CollectionView.create({\n container: container,\n tagName: 'del',\n content: Ember.A(),\n\n emptyView: 'empty'\n });\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().find('kbd:contains(\"THIS IS AN EMPTY VIEW\")').length, \"displays empty view\");\n\n function lookupFactory(fullName) {\n equal(fullName, 'view:empty');\n\n return EmptyView;\n }\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/collection_test");minispade.register('ember-views/~tests/views/component_test', "(function() {var get = Ember.get, set = Ember.set,\n a_slice = Array.prototype.slice;\n\nmodule(\"Ember.Component\");\n\nvar Component = Ember.Component.extend();\n\ntest(\"The context of an Ember.Component is itself\", function() {\n var control = Component.create();\n strictEqual(control, control.get('context'), \"A control's context is itself\");\n});\n\ntest(\"The controller (target of `action`) of an Ember.Component is itself\", function() {\n var control = Component.create();\n strictEqual(control, control.get('controller'), \"A control's controller is itself\");\n});\n\nvar component, controller, actionCounts, sendCount, actionArguments;\n\nmodule(\"Ember.Component - Actions\", {\n setup: function() {\n actionCounts = {};\n sendCount = 0;\n actionArguments = null;\n\n controller = Ember.Object.create({\n send: function(actionName) {\n sendCount++;\n actionCounts[actionName] = actionCounts[actionName] || 0;\n actionCounts[actionName]++;\n actionArguments = a_slice.call(arguments, 1);\n }\n });\n\n component = Ember.Component.create({\n _parentView: Ember.View.create({\n controller: controller\n })\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n component.destroy();\n controller.destroy();\n });\n }\n});\n\ntest(\"Calling sendAction on a component without an action defined does nothing\", function() {\n component.sendAction();\n equal(sendCount, 0, \"addItem action was not invoked\");\n});\n\ntest(\"Calling sendAction on a component with an action defined calls send on the controller\", function() {\n set(component, 'action', \"addItem\");\n\n component.sendAction();\n\n equal(sendCount, 1, \"send was called once\");\n equal(actionCounts['addItem'], 1, \"addItem event was sent once\");\n});\n\ntest(\"Calling sendAction with a named action uses the component's property as the action name\", function() {\n set(component, 'playing', \"didStartPlaying\");\n set(component, 'action', \"didDoSomeBusiness\");\n\n component.sendAction('playing');\n\n equal(sendCount, 1, \"send was called once\");\n equal(actionCounts['didStartPlaying'], 1, \"named action was sent\");\n\n component.sendAction('playing');\n\n equal(sendCount, 2, \"send was called twice\");\n equal(actionCounts['didStartPlaying'], 2, \"named action was sent\");\n\n component.sendAction();\n\n equal(sendCount, 3, \"send was called three times\");\n equal(actionCounts['didDoSomeBusiness'], 1, \"default action was sent\");\n});\n\ntest(\"Calling sendAction when the action name is not a string raises an exception\", function() {\n set(component, 'action', {});\n set(component, 'playing', {});\n\n expectAssertion(function() {\n component.sendAction();\n });\n\n expectAssertion(function() {\n component.sendAction('playing');\n });\n});\n\ntest(\"Calling sendAction on a component with a context\", function() {\n set(component, 'playing', \"didStartPlaying\");\n\n var testContext = {song: 'She Broke My Ember'};\n\n component.sendAction('playing', testContext);\n\n deepEqual(actionArguments, [testContext], \"context was sent with the action\");\n});\n\ntest(\"Calling sendAction on a component with multiple parameters\", function() {\n set(component, 'playing', \"didStartPlaying\");\n\n var firstContext = {song: 'She Broke My Ember'},\n secondContext = {song: 'My Achey Breaky Ember'};\n\n component.sendAction('playing', firstContext, secondContext);\n\n deepEqual(actionArguments, [firstContext, secondContext], \"arguments were sent to the action\");\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/component_test");minispade.register('ember-views/~tests/views/container_view_test', "(function() {var get = Ember.get, set = Ember.set, container, view, otherContainer;\n\nmodule(\"ember-views/views/container_view_test\", {\n teardown: function() {\n Ember.run(function() {\n container.destroy();\n if (view) { view.destroy(); }\n if (otherContainer) { otherContainer.destroy(); }\n });\n }\n});\n\ntest(\"should be able to insert views after the DOM representation is created\", function() {\n container = Ember.ContainerView.create({\n classNameBindings: ['name'],\n name: 'foo',\n container: {}\n });\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n view = Ember.View.create({\n template: function() {\n return \"This is my moment\";\n }\n });\n\n Ember.run(function() {\n container.pushObject(view);\n });\n\n equal(view.container, container.container, 'view gains its containerViews container');\n equal(view._parentView, container, 'view\\'s _parentView is the container');\n equal(Ember.$.trim(container.$().text()), \"This is my moment\");\n\n Ember.run(function() {\n container.destroy();\n });\n\n});\n\ntest(\"should be able to observe properties that contain child views\", function() {\n Ember.run(function() {\n var Container = Ember.ContainerView.extend({\n childViews: ['displayView'],\n displayIsDisplayed: Ember.computed.alias('displayView.isDisplayed'),\n\n displayView: Ember.View.extend({\n isDisplayed: true\n })\n });\n\n container = Container.create();\n container.appendTo('#qunit-fixture');\n });\n equal(container.get('displayIsDisplayed'), true, \"can bind to child view\");\n\n Ember.run(function () {\n container.set('displayView.isDisplayed', false);\n });\n\n equal(container.get('displayIsDisplayed'), false, \"can bind to child view\");\n});\n\ntest(\"childViews inherit their parents iocContainer, and retain the original container even when moved\", function() {\n container = Ember.ContainerView.create({\n container: {}\n });\n\n otherContainer = Ember.ContainerView.create({\n container: {}\n });\n\n view = Ember.View.create();\n\n container.pushObject(view);\n\n equal(view.get('parentView'), container, \"sets the parent view after the childView is appended\");\n equal(get(view, 'container'), container.container, \"inherits its parentViews iocContainer\");\n\n container.removeObject(view);\n\n equal(get(view, 'container'), container.container, \"leaves existing iocContainer alone\");\n\n otherContainer.pushObject(view);\n\n equal(view.get('parentView'), otherContainer, \"sets the new parent view after the childView is appended\");\n equal(get(view, 'container'), container.container, \"still inherits its original parentViews iocContainer\");\n});\n\ntest(\"should set the parentView property on views that are added to the child views array\", function() {\n container = Ember.ContainerView.create();\n\n var View = Ember.View.extend({\n template: function() {\n return \"This is my moment\";\n }\n });\n\n view = View.create();\n\n container.pushObject(view);\n equal(view.get('parentView'), container, \"sets the parent view after the childView is appended\");\n\n Ember.run(function() {\n container.removeObject(view);\n });\n equal(get(view, 'parentView'), null, \"sets parentView to null when a view is removed\");\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n Ember.run(function() {\n container.pushObject(view);\n });\n\n equal(get(view, 'parentView'), container, \"sets the parent view after the childView is appended\");\n\n var secondView = View.create(),\n thirdView = View.create(),\n fourthView = View.create();\n\n Ember.run(function() {\n container.pushObject(secondView);\n container.replace(1, 0, [thirdView, fourthView]);\n });\n\n equal(get(secondView, 'parentView'), container, \"sets the parent view of the second view\");\n equal(get(thirdView, 'parentView'), container, \"sets the parent view of the third view\");\n equal(get(fourthView, 'parentView'), container, \"sets the parent view of the fourth view\");\n\n Ember.run(function() {\n container.replace(2, 2);\n });\n\n equal(get(view, 'parentView'), container, \"doesn't change non-removed view\");\n equal(get(thirdView, 'parentView'), container, \"doesn't change non-removed view\");\n equal(get(secondView, 'parentView'), null, \"clears the parent view of the third view\");\n equal(get(fourthView, 'parentView'), null, \"clears the parent view of the fourth view\");\n\n Ember.run(function() {\n secondView.destroy();\n thirdView.destroy();\n fourthView.destroy();\n });\n});\n\ntest(\"should trigger parentViewDidChange when parentView is changed\", function() {\n container = Ember.ContainerView.create();\n\n var secondContainer = Ember.ContainerView.create();\n var parentViewChanged = 0;\n\n var View = Ember.View.extend({\n parentViewDidChange: function() { parentViewChanged++; }\n });\n\n view = View.create();\n\n container.pushObject(view);\n container.removeChild(view);\n secondContainer.pushObject(view);\n\n equal(parentViewChanged, 3);\n\n Ember.run(function() {\n secondContainer.destroy();\n });\n});\n\ntest(\"should be able to push initial views onto the ContainerView and have it behave\", function() {\n var Container = Ember.ContainerView.extend({\n init: function () {\n this._super();\n this.pushObject(Ember.View.create({\n name: 'A',\n template: function () {\n return 'A';\n }\n }));\n this.pushObject(Ember.View.create({\n name: 'B',\n template: function () {\n return 'B';\n }\n }));\n },\n lengthSquared: Ember.computed(function () {\n return this.get('length') * this.get('length');\n }).property('length'),\n\n names: Ember.computed(function () {\n return this.mapBy('name');\n }).property('@each.name')\n });\n\n container = Container.create();\n\n equal(container.get('lengthSquared'), 4);\n\n deepEqual(container.get('names'), ['A','B']);\n\n Ember.run(container, 'appendTo', '#qunit-fixture');\n\n equal(container.$().text(), 'AB');\n\n Ember.run(function () {\n container.pushObject(Ember.View.create({\n name: 'C',\n template: function () {\n return 'C';\n }\n }));\n });\n\n equal(container.get('lengthSquared'), 9);\n\n deepEqual(container.get('names'), ['A','B','C']);\n\n equal(container.$().text(), 'ABC');\n\n Ember.run(container, 'destroy');\n});\n\ntest(\"views that are removed from a ContainerView should have their child views cleared\", function() {\n container = Ember.ContainerView.create();\n view = Ember.View.createWithMixins({\n remove: function() {\n this._super();\n },\n template: function(context, options) {\n options.data.view.appendChild(Ember.View);\n }\n });\n\n container.pushObject(view);\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n equal(get(view, 'childViews.length'), 1, \"precond - renders one child view\");\n Ember.run(function() {\n container.removeObject(view);\n });\n equal(get(view, 'childViews.length'), 0, \"child views are cleared when removed from container view\");\n equal(container.$().html(),'', \"the child view is removed from the DOM\");\n});\n\ntest(\"if a ContainerView starts with an empy currentView, nothing is displayed\", function() {\n container = Ember.ContainerView.create();\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n equal(container.$().text(), '', \"has a empty contents\");\n equal(get(container, 'childViews.length'), 0, \"should not have any child views\");\n});\n\ntest(\"if a ContainerView starts with a currentView, it is rendered as a child view\", function() {\n var controller = Ember.Controller.create();\n container = Ember.ContainerView.create({\n controller: controller\n });\n var context = null;\n var templateData = null;\n var mainView = Ember.View.create({\n template: function(ctx, opts) {\n context = ctx;\n templateData = opts.data;\n return \"This is the main view.\";\n }\n });\n\n set(container, 'currentView', mainView);\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n equal(Ember.$.trim(container.$().text()), \"This is the main view.\", \"should render its child\");\n equal(get(container, 'length'), 1, \"should have one child view\");\n equal(container.objectAt(0), mainView, \"should have the currentView as the only child view\");\n equal(mainView.get('parentView'), container, \"parentView is setup\");\n equal(context, container.get('context'), 'context preserved');\n equal(templateData.keywords.controller, controller, 'templateData is setup');\n equal(templateData.keywords.view, mainView, 'templateData is setup');\n});\n\ntest(\"if a ContainerView is created with a currentView, it is rendered as a child view\", function() {\n var context = null;\n var templateData = null;\n var mainView = Ember.View.create({\n template: function(ctx, opts) {\n context = ctx;\n templateData = opts.data;\n return \"This is the main view.\";\n }\n });\n\n var controller = Ember.Controller.create();\n\n container = Ember.ContainerView.create({\n currentView: mainView,\n controller: controller\n });\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n equal(container.$().text(), \"This is the main view.\", \"should render its child\");\n equal(get(container, 'length'), 1, \"should have one child view\");\n equal(container.objectAt(0), mainView, \"should have the currentView as the only child view\");\n equal(mainView.get('parentView'), container, \"parentView is setup\");\n equal(context, container.get('context'), 'context preserved');\n equal(templateData.keywords.controller, controller, 'templateData is setup');\n equal(templateData.keywords.view, mainView, 'templateData is setup');\n});\n\ntest(\"if a ContainerView starts with no currentView and then one is set, the ContainerView is updated\", function() {\n var context = null;\n var templateData = null;\n var mainView = Ember.View.create({\n template: function(ctx, opts) {\n context = ctx;\n templateData = opts.data;\n return \"This is the main view.\";\n }\n });\n\n var controller = Ember.Controller.create();\n\n container = Ember.ContainerView.create({\n controller: controller\n });\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n equal(container.$().text(), '', \"has a empty contents\");\n equal(get(container, 'childViews.length'), 0, \"should not have any child views\");\n\n Ember.run(function() {\n set(container, 'currentView', mainView);\n });\n\n equal(container.$().text(), \"This is the main view.\", \"should render its child\");\n equal(get(container, 'length'), 1, \"should have one child view\");\n equal(container.objectAt(0), mainView, \"should have the currentView as the only child view\");\n equal(mainView.get('parentView'), container, \"parentView is setup\");\n equal(context, container.get('context'), 'context preserved');\n equal(templateData.keywords.controller, controller, 'templateData is setup');\n equal(templateData.keywords.view, mainView, 'templateData is setup');\n});\n\ntest(\"if a ContainerView starts with a currentView and then is set to null, the ContainerView is updated\", function() {\n var context = null;\n var templateData = null;\n var mainView = Ember.View.create({\n template: function(ctx, opts) {\n context = ctx;\n templateData = opts.data;\n return \"This is the main view.\";\n }\n });\n\n var controller = Ember.Controller.create();\n\n container = Ember.ContainerView.create({\n controller: controller\n });\n\n container.set('currentView', mainView);\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n equal(container.$().text(), \"This is the main view.\", \"should render its child\");\n equal(get(container, 'length'), 1, \"should have one child view\");\n equal(container.objectAt(0), mainView, \"should have the currentView as the only child view\");\n equal(mainView.get('parentView'), container, \"parentView is setup\");\n equal(context, container.get('context'), 'context preserved');\n equal(templateData.keywords.controller, controller, 'templateData is setup');\n equal(templateData.keywords.view, mainView, 'templateData is setup');\n\n Ember.run(function() {\n set(container, 'currentView', null);\n });\n\n equal(container.$().text(), '', \"has a empty contents\");\n equal(get(container, 'childViews.length'), 0, \"should not have any child views\");\n});\n\ntest(\"if a ContainerView starts with a currentView and then is set to null, the ContainerView is updated and the previous currentView is destroyed\", function() {\n var context = null;\n var templateData = null;\n var mainView = Ember.View.create({\n template: function(ctx, opts) {\n context = ctx;\n templateData = opts.data;\n return \"This is the main view.\";\n }\n });\n\n var controller = Ember.Controller.create();\n\n container = Ember.ContainerView.create({\n controller: controller\n });\n\n container.set('currentView', mainView);\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n equal(container.$().text(), \"This is the main view.\", \"should render its child\");\n equal(get(container, 'length'), 1, \"should have one child view\");\n equal(container.objectAt(0), mainView, \"should have the currentView as the only child view\");\n equal(mainView.get('parentView'), container, \"parentView is setup\");\n equal(context, container.get('context'), 'context preserved');\n equal(templateData.keywords.controller, controller, 'templateData is setup');\n equal(templateData.keywords.view, mainView, 'templateData is setup');\n\n Ember.run(function() {\n set(container, 'currentView', null);\n });\n\n equal(mainView.isDestroyed, true, 'should destroy the previous currentView.');\n\n equal(container.$().text(), '', \"has a empty contents\");\n equal(get(container, 'childViews.length'), 0, \"should not have any child views\");\n});\n\ntest(\"if a ContainerView starts with a currentView and then a different currentView is set, the old view is destroyed and the new one is added\", function() {\n container = Ember.ContainerView.create();\n var mainView = Ember.View.create({\n template: function() {\n return \"This is the main view.\";\n }\n });\n\n var secondaryView = Ember.View.create({\n template: function() {\n return \"This is the secondary view.\";\n }\n });\n\n var tertiaryView = Ember.View.create({\n template: function() {\n return \"This is the tertiary view.\";\n }\n });\n\n container.set('currentView', mainView);\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n equal(container.$().text(), \"This is the main view.\", \"should render its child\");\n equal(get(container, 'length'), 1, \"should have one child view\");\n equal(container.objectAt(0), mainView, \"should have the currentView as the only child view\");\n\n Ember.run(function() {\n set(container, 'currentView', secondaryView);\n });\n\n\n equal(get(container, 'length'), 1, \"should have one child view\");\n equal(container.objectAt(0), secondaryView, \"should have the currentView as the only child view\");\n equal(mainView.isDestroyed, true, 'should destroy the previous currentView: mainView.');\n\n equal(Ember.$.trim(container.$().text()), \"This is the secondary view.\", \"should render its child\");\n\n Ember.run(function() {\n set(container, 'currentView', tertiaryView);\n });\n\n equal(get(container, 'length'), 1, \"should have one child view\");\n equal(container.objectAt(0), tertiaryView, \"should have the currentView as the only child view\");\n equal(secondaryView.isDestroyed, true, 'should destroy the previous currentView: secondaryView.');\n\n equal(Ember.$.trim(container.$().text()), \"This is the tertiary view.\", \"should render its child\");\n});\n\ntest(\"should be able to modify childViews many times during an run loop\", function () {\n\n container = Ember.ContainerView.create();\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n var one = Ember.View.create({\n template: function() {\n return 'one';\n }\n });\n\n var two = Ember.View.create({\n template: function() {\n return 'two';\n }\n });\n\n var three = Ember.View.create({\n template: function() {\n return 'three';\n }\n });\n\n Ember.run(function() {\n // initial order\n container.pushObjects([three, one, two]);\n // sort\n container.removeObject(three);\n container.pushObject(three);\n });\n\n // Remove whitespace added by IE 8\n equal(container.$().text().replace(/\\s+/g,''), 'onetwothree');\n});\n\ntest(\"should be able to modify childViews then remove the ContainerView in same run loop\", function () {\n container = Ember.ContainerView.create();\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n var count = 0;\n var child = Ember.View.create({\n template: function () { count++; return 'child'; }\n });\n\n Ember.run(function() {\n container.pushObject(child);\n container.remove();\n });\n\n equal(count, 0, 'did not render child');\n});\n\ntest(\"should be able to modify childViews then destroy the ContainerView in same run loop\", function () {\n container = Ember.ContainerView.create();\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n var count = 0;\n var child = Ember.View.create({\n template: function () { count++; return 'child'; }\n });\n\n Ember.run(function() {\n container.pushObject(child);\n container.destroy();\n });\n\n equal(count, 0, 'did not render child');\n});\n\n\ntest(\"should be able to modify childViews then rerender the ContainerView in same run loop\", function () {\n container = Ember.ContainerView.create();\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n var count = 0;\n var child = Ember.View.create({\n template: function () { count++; return 'child'; }\n });\n\n Ember.run(function() {\n container.pushObject(child);\n container.rerender();\n });\n\n equal(count, 1, 'rendered child only once');\n});\n\ntest(\"should be able to modify childViews then rerender then modify again the ContainerView in same run loop\", function () {\n container = Ember.ContainerView.create();\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n var Child = Ember.View.extend({\n count: 0,\n render: function (buffer) {\n this.count++;\n buffer.push(this.label);\n }\n });\n var one = Child.create({label: 'one'});\n var two = Child.create({label: 'two'});\n\n Ember.run(function() {\n container.pushObject(one);\n container.pushObject(two);\n });\n\n equal(one.count, 1, 'rendered child only once');\n equal(two.count, 1, 'rendered child only once');\n // Remove whitespace added by IE 8\n equal(container.$().text().replace(/\\s+/g, ''), 'onetwo');\n});\n\ntest(\"should be able to modify childViews then rerender again the ContainerView in same run loop and then modify again\", function () {\n container = Ember.ContainerView.create();\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n var Child = Ember.View.extend({\n count: 0,\n render: function (buffer) {\n this.count++;\n buffer.push(this.label);\n }\n });\n var one = Child.create({label: 'one'});\n var two = Child.create({label: 'two'});\n\n Ember.run(function() {\n container.pushObject(one);\n container.rerender();\n });\n\n equal(one.count, 1, 'rendered child only once');\n equal(container.$().text(), 'one');\n\n Ember.run(function () {\n container.pushObject(two);\n });\n\n equal(one.count, 1, 'rendered child only once');\n equal(two.count, 1, 'rendered child only once');\n // IE 8 adds a line break but this shouldn't affect validity\n equal(container.$().text().replace(/\\s/g, ''), 'onetwo');\n});\n\ntest(\"should invalidate `element` on itself and childViews when being rendered by ensureChildrenAreInDOM\", function () {\n var root = Ember.ContainerView.create();\n\n view = Ember.View.create({ template: function() {} });\n container = Ember.ContainerView.create({ childViews: ['child'], child: view });\n\n Ember.run(function() {\n root.appendTo('#qunit-fixture');\n });\n\n Ember.run(function() {\n root.pushObject(container);\n\n // Get the parent and child's elements to cause them to be cached as null\n container.get('element');\n view.get('element');\n });\n\n ok(!!container.get('element'), \"Parent's element should have been recomputed after being rendered\");\n ok(!!view.get('element'), \"Child's element should have been recomputed after being rendered\");\n\n Ember.run(function() {\n root.destroy();\n });\n});\n\ntest(\"Child view can only be added to one container at a time\", function () {\n expect(2);\n\n container = Ember.ContainerView.create();\n var secondContainer = Ember.ContainerView.create();\n\n Ember.run(function() {\n container.appendTo('#qunit-fixture');\n });\n\n var view = Ember.View.create();\n\n Ember.run(function() {\n container.set('currentView', view);\n });\n\n expectAssertion(function() {\n Ember.run(function() {\n secondContainer.set('currentView', view);\n });\n });\n\n expectAssertion(function() {\n Ember.run(function() {\n secondContainer.pushObject(view);\n });\n });\n\n Ember.run(function() {\n secondContainer.destroy();\n });\n});\n\ntest(\"if a containerView appends a child in its didInsertElement event, the didInsertElement event of the child view should be fired once\", function () {\n\n var counter = 0,\n root = Ember.ContainerView.create({});\n\n container = Ember.ContainerView.create({\n\n didInsertElement: function() {\n\n var view = Ember.ContainerView.create({\n didInsertElement: function() {\n counter++;\n }\n });\n\n this.pushObject(view);\n\n }\n\n });\n\n\n Ember.run(function() {\n root.appendTo('#qunit-fixture');\n });\n\n Ember.run(function() {\n root.pushObject(container);\n });\n\n equal(container.get('childViews').get('length'), 1 , \"containerView should only have a child\");\n equal(counter, 1 , \"didInsertElement should be fired once\");\n\n Ember.run(function() {\n root.destroy();\n });\n\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/container_view_test");minispade.register('ember-views/~tests/views/view/actions_test', "(function() {var set = Ember.set, get = Ember.get, view;\n\nmodule(\"Ember.View action handling\", {\n teardown: function() {\n Ember.run(function() {\n if (view) { view.destroy(); }\n });\n }\n});\n\ntest(\"Action can be handled by a function on actions object\", function() {\n expect(1);\n view = Ember.View.extend({\n actions: {\n poke: function() {\n ok(true, 'poked');\n }\n }\n }).create();\n view.send(\"poke\");\n});\n\ntest(\"Action can be handled by a function on the view (DEPRECATED)\", function() {\n Ember.TESTING_DEPRECATION = true;\n expect(1);\n view = Ember.View.extend({\n poke: function() {\n ok(true, 'poked');\n Ember.TESTING_DEPRECATION = true;\n }\n }).create();\n view.send(\"poke\");\n});\n\ntest(\"A handled action can be bubbled to the target for continued processing\", function() {\n expect(2);\n view = Ember.View.extend({\n actions: {\n poke: function() {\n ok(true, 'poked 1');\n return true;\n }\n },\n target: Ember.Controller.extend({\n actions: {\n poke: function() {\n ok(true, 'poked 2');\n }\n }\n }).create()\n }).create();\n view.send(\"poke\");\n});\n\ntest(\"Action can be handled by a superclass' actions object\", function() {\n expect(4);\n\n var SuperView = Ember.View.extend({\n actions: {\n foo: function() {\n ok(true, 'foo');\n },\n bar: function(msg) {\n equal(msg, \"HELLO\");\n }\n }\n });\n\n var BarViewMixin = Ember.Mixin.create({\n actions: {\n bar: function(msg) {\n equal(msg, \"HELLO\");\n this._super(msg);\n }\n }\n });\n\n var IndexView = SuperView.extend(BarViewMixin, {\n actions: {\n baz: function() {\n ok(true, 'baz');\n }\n }\n });\n\n view = IndexView.create();\n view.send(\"foo\");\n view.send(\"bar\", \"HELLO\");\n view.send(\"baz\");\n});\n\ntest(\"Actions cannot be provided at create time\", function() {\n expectAssertion(function() {\n view = Ember.View.create({\n actions: {\n foo: function() {\n ok(true, 'foo');\n }\n }\n });\n });\n // but should be OK on an object that doesn't mix in Ember.ActionHandler\n var obj = Ember.Object.create({\n actions: ['foo']\n });\n});\n\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/actions_test");minispade.register('ember-views/~tests/views/view/append_to_test', "(function() {var set = Ember.set, get = Ember.get;\n\nvar View, view, willDestroyCalled, childView;\n\nmodule(\"Ember.View - append() and appendTo()\", {\n setup: function() {\n View = Ember.View.extend({});\n },\n\n teardown: function() {\n Ember.run(function() {\n if (!view.isDestroyed) { view.destroy(); }\n });\n }\n});\n\ntest(\"should be added to the specified element when calling appendTo()\", function() {\n Ember.$(\"#qunit-fixture\").html('
    ');\n\n view = View.create();\n\n ok(!get(view, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.appendTo('#menu');\n });\n\n var viewElem = Ember.$('#menu').children();\n ok(viewElem.length > 0, \"creates and appends the view's element\");\n});\n\ntest(\"should be added to the document body when calling append()\", function() {\n view = View.create({\n render: function(buffer) {\n buffer.push(\"foo bar baz\");\n }\n });\n\n ok(!get(view, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.append();\n });\n\n var viewElem = Ember.$(document.body).find(':contains(\"foo bar baz\")');\n ok(viewElem.length > 0, \"creates and appends the view's element\");\n});\n\ntest(\"raises an assert when a target does not exist in the DOM\", function() {\n view = View.create();\n\n expectAssertion(function() {\n Ember.run(function() {\n view.appendTo('does-not-exist-in-dom');\n });\n });\n});\n\ntest(\"append calls willInsertElement and didInsertElement callbacks\", function() {\n var willInsertElementCalled = false;\n var willInsertElementCalledInChild = false;\n var didInsertElementCalled = false;\n\n var ViewWithCallback = View.extend({\n willInsertElement: function() {\n willInsertElementCalled = true;\n },\n didInsertElement: function() {\n didInsertElementCalled = true;\n },\n render: function(buffer) {\n this.appendChild(Ember.View.create({\n willInsertElement: function() {\n willInsertElementCalledInChild = true;\n }\n }));\n }\n });\n\n view = ViewWithCallback.create();\n\n Ember.run(function() {\n view.append();\n });\n\n ok(willInsertElementCalled, \"willInsertElement called\");\n ok(willInsertElementCalledInChild, \"willInsertElement called in child\");\n ok(didInsertElementCalled, \"didInsertElement called\");\n});\n\ntest(\"remove removes an element from the DOM\", function() {\n willDestroyCalled = 0;\n\n view = View.create({\n willDestroyElement: function() {\n willDestroyCalled++;\n }\n });\n\n ok(!get(view, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.append();\n });\n\n ok(Ember.$(\"#\" + get(view, 'elementId')).length === 1, \"precond - element was inserted\");\n\n Ember.run(function() {\n view.remove();\n });\n\n ok(Ember.$(\"#\" + get(view, 'elementId')).length === 0, \"remove removes an element from the DOM\");\n ok(Ember.View.views[get(view, 'elementId')] === undefined, \"remove does not remove the view from the view hash\");\n ok(!get(view, 'element'), \"remove nulls out the element\");\n equal(willDestroyCalled, 1, \"the willDestroyElement hook was called once\");\n});\n\ntest(\"destroy more forcibly removes the view\", function() {\n willDestroyCalled = 0;\n\n view = View.create({\n willDestroyElement: function() {\n willDestroyCalled++;\n }\n });\n\n ok(!get(view, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.append();\n });\n\n ok(Ember.$(\"#\" + get(view, 'elementId')).length === 1, \"precond - element was inserted\");\n\n Ember.run(function() {\n view.destroy();\n });\n\n ok(Ember.$(\"#\" + get(view, 'elementId')).length === 0, \"destroy removes an element from the DOM\");\n ok(Ember.View.views[get(view, 'elementId')] === undefined, \"destroy removes a view from the global views hash\");\n equal(get(view, 'isDestroyed'), true, \"the view is marked as destroyed\");\n ok(!get(view, 'element'), \"the view no longer has an element\");\n equal(willDestroyCalled, 1, \"the willDestroyElement hook was called once\");\n});\n\nmodule(\"Ember.View - append() and appendTo() in a view hierarchy\", {\n setup: function() {\n View = Ember.ContainerView.extend({\n childViews: ['child'],\n child: Ember.View.extend({\n elementId: 'child'\n })\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n if (!view.isDestroyed) { view.destroy(); }\n });\n }\n});\n\ntest(\"should be added to the specified element when calling appendTo()\", function() {\n Ember.$(\"#qunit-fixture\").html('
    ');\n\n view = View.create();\n\n ok(!get(view, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.appendTo('#menu');\n });\n\n var viewElem = Ember.$('#menu #child');\n ok(viewElem.length > 0, \"creates and appends the view's element\");\n});\n\ntest(\"should be added to the document body when calling append()\", function() {\n Ember.$(\"#qunit-fixture\").html('
    ');\n\n view = View.create();\n\n ok(!get(view, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.append();\n });\n\n var viewElem = Ember.$('#child');\n ok(viewElem.length > 0, \"creates and appends the view's element\");\n});\n\nmodule(\"Ember.View - removing views in a view hierarchy\", {\n setup: function() {\n willDestroyCalled = 0;\n\n view = Ember.ContainerView.create({\n childViews: ['child'],\n child: Ember.View.create({\n willDestroyElement: function() {\n willDestroyCalled++;\n }\n })\n });\n\n childView = get(view, 'child');\n },\n\n teardown: function() {\n Ember.run(function() {\n if (!view.isDestroyed) { view.destroy(); }\n });\n }\n});\n\ntest(\"remove removes child elements from the DOM\", function() {\n ok(!get(childView, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.append();\n });\n\n ok(Ember.$(\"#\" + get(childView, 'elementId')).length === 1, \"precond - element was inserted\");\n\n // remove parent view\n Ember.run(function() {\n view.remove();\n });\n\n ok(Ember.$(\"#\" + get(childView, 'elementId')).length === 0, \"remove removes child elements the DOM\");\n ok(Ember.View.views[get(childView, 'elementId')] === undefined, \"remove does not remove child views from the view hash\");\n ok(!get(childView, 'element'), \"remove nulls out child elements\");\n equal(willDestroyCalled, 1, \"the willDestroyElement hook was called once\");\n});\n\ntest(\"destroy more forcibly removes child views\", function() {\n ok(!get(childView, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.append();\n });\n\n ok(Ember.$(\"#\" + get(childView, 'elementId')).length === 1, \"precond - child element was inserted\");\n\n willDestroyCalled = 0;\n\n Ember.run(function() {\n view.destroy();\n });\n\n ok(Ember.$(\"#\" + get(childView, 'elementId')).length === 0, \"destroy removes child elements from the DOM\");\n ok(Ember.View.views[get(childView, 'elementId')] === undefined, \"destroy removes a child views from the global views hash\");\n equal(get(childView, 'isDestroyed'), true, \"child views are marked as destroyed\");\n ok(!get(childView, 'element'), \"child views no longer have an element\");\n equal(willDestroyCalled, 1, \"the willDestroyElement hook was called once on children\");\n});\n\ntest(\"destroy removes a child view from its parent\", function() {\n ok(!get(childView, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.append();\n });\n\n ok(Ember.$(\"#\" + get(childView, 'elementId')).length === 1, \"precond - child element was inserted\");\n\n Ember.run(function() {\n childView.destroy();\n });\n\n ok(get(view, 'childViews.length') === 0, \"Destroyed child views should be removed from their parent\");\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/append_to_test");minispade.register('ember-views/~tests/views/view/attribute_bindings_test', "(function() {/*global Test:true*/\nvar set = Ember.set, get = Ember.get;\n\nvar originalLookup = Ember.lookup, lookup, view;\n\nvar appendView = function() {\n Ember.run(function() { view.appendTo('#qunit-fixture'); });\n};\n\nmodule(\"Ember.View - Attribute Bindings\", {\n setup: function() {\n Ember.lookup = lookup = {};\n },\n teardown: function() {\n if (view) {\n Ember.run(function() {\n view.destroy();\n });\n view = null;\n }\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"should render attribute bindings\", function() {\n view = Ember.View.create({\n classNameBindings: ['priority', 'isUrgent', 'isClassified:classified', 'canIgnore'],\n attributeBindings: ['type', 'isDisabled:disabled', 'exploded', 'destroyed', 'exists', 'nothing', 'notDefined', 'notNumber', 'explosions'],\n\n type: 'submit',\n isDisabled: true,\n exploded: false,\n destroyed: false,\n exists: true,\n nothing: null,\n notDefined: undefined,\n notNumber: NaN\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.$().attr('type'), 'submit', \"updates type attribute\");\n ok(view.$().prop('disabled'), \"supports customizing attribute name for Boolean values\");\n ok(!view.$().prop('exploded'), \"removes exploded attribute when false\");\n ok(!view.$().prop('destroyed'), \"removes destroyed attribute when false\");\n ok(view.$().prop('exists'), \"adds exists attribute when true\");\n ok(!view.$().attr('nothing'), \"removes nothing attribute when null\");\n ok(!view.$().attr('notDefined'), \"removes notDefined attribute when undefined\");\n ok(!view.$().attr('notNumber'), \"removes notNumber attribute when NaN\");\n});\n\ntest(\"should update attribute bindings\", function() {\n view = Ember.View.create({\n classNameBindings: ['priority', 'isUrgent', 'isClassified:classified', 'canIgnore'],\n attributeBindings: ['type', 'isDisabled:disabled', 'exploded', 'destroyed', 'exists', 'nothing', 'notDefined', 'notNumber', 'explosions'],\n\n type: 'reset',\n isDisabled: true,\n exploded: true,\n destroyed: true,\n exists: false,\n nothing: true,\n notDefined: true,\n notNumber: true,\n explosions: 15\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.$().attr('type'), 'reset', \"adds type attribute\");\n ok(view.$().prop('disabled'), \"adds disabled attribute when true\");\n ok(view.$().prop('exploded'), \"adds exploded attribute when true\");\n ok(view.$().prop('destroyed'), \"adds destroyed attribute when true\");\n ok(!view.$().prop('exists'), \"does not add exists attribute when false\");\n ok(view.$().prop('nothing'), \"adds nothing attribute when true\");\n ok(view.$().prop('notDefined'), \"adds notDefined attribute when true\");\n ok(view.$().prop('notNumber'), \"adds notNumber attribute when true\");\n equal(view.$().attr('explosions'), \"15\", \"adds integer attributes\");\n\n Ember.run(function() {\n view.set('type', 'submit');\n view.set('isDisabled', false);\n view.set('exploded', false);\n view.set('destroyed', false);\n view.set('exists', true);\n view.set('nothing', null);\n view.set('notDefined', undefined);\n view.set('notNumber', NaN);\n });\n\n equal(view.$().attr('type'), 'submit', \"updates type attribute\");\n ok(!view.$().prop('disabled'), \"removes disabled attribute when false\");\n ok(!view.$().prop('exploded'), \"removes exploded attribute when false\");\n ok(!view.$().prop('destroyed'), \"removes destroyed attribute when false\");\n ok(view.$().prop('exists'), \"adds exists attribute when true\");\n ok(!view.$().attr('nothing'), \"removes nothing attribute when null\");\n ok(!view.$().attr('notDefined'), \"removes notDefined attribute when undefined\");\n ok(!view.$().attr('notNumber'), \"removes notNumber attribute when NaN\");\n});\n\n// This comes into play when using the {{#each}} helper. If the\n// passed array item is a String, it will be converted into a\n// String object instead of a normal string.\ntest(\"should allow binding to String objects\", function() {\n view = Ember.View.create({\n attributeBindings: ['foo'],\n // JSHint doesn't like `new String` so we'll create it the same way it gets created in practice\n foo: (function() { return this; }).call(\"bar\")\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n\n equal(view.$().attr('foo'), 'bar', \"should convert String object to bare string\");\n});\n\ntest(\"should teardown observers on rerender\", function() {\n view = Ember.View.create({\n attributeBindings: ['foo'],\n classNameBindings: ['foo'],\n foo: 'bar'\n });\n\n appendView();\n\n equal(Ember.observersFor(view, 'foo').length, 2);\n\n Ember.run(function() {\n view.rerender();\n });\n\n equal(Ember.observersFor(view, 'foo').length, 2);\n});\n\ntest(\"handles attribute bindings for properties\", function() {\n view = Ember.View.create({\n attributeBindings: ['checked'],\n checked: null\n });\n\n appendView();\n\n equal(!!view.$().prop('checked'), false, 'precond - is not checked');\n\n Ember.run(function() {\n view.set('checked', true);\n });\n\n equal(view.$().prop('checked'), true, 'changes to checked');\n\n Ember.run(function() {\n view.set('checked', false);\n });\n\n equal(view.$().prop('checked'), false, 'changes to unchecked');\n});\n\ntest(\"handles `undefined` value for properties\", function() {\n view = Ember.View.create({\n attributeBindings: ['value'],\n value: \"test\"\n });\n\n appendView();\n\n equal(view.$().prop('value'), \"test\", \"value is defined\");\n\n Ember.run(function() {\n view.set('value', undefined);\n });\n\n equal(!!view.$().prop('value'), false, \"value is not defined\");\n});\n\ntest(\"handles null value for attributes on text fields\", function() {\n view = Ember.View.create({\n tagName: 'input',\n attributeBindings: ['value']\n });\n\n appendView();\n\n view.$().attr('value', 'test');\n\n equal(view.$().attr('value'), \"test\", \"value is defined\");\n\n Ember.run(function() {\n view.set('value', null);\n });\n\n equal(!!view.$().prop('value'), false, \"value is not defined\");\n});\n\ntest(\"handles a 0 value attribute on text fields\", function() {\n view = Ember.View.create({\n tagName: 'input',\n attributeBindings: ['value']\n });\n\n appendView();\n\n view.$().attr('value', 'test');\n equal(view.$().attr('value'), \"test\", \"value is defined\");\n\n Ember.run(function() {\n view.set('value', 0);\n });\n strictEqual(view.$().prop('value'), \"0\", \"value should be 0\");\n});\n\ntest(\"attributeBindings should not fail if view has been removed\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n attributeBindings: ['checked'],\n checked: true\n });\n });\n Ember.run(function() {\n view.createElement();\n });\n var error;\n try {\n Ember.run(function() {\n Ember.changeProperties(function() {\n view.set('checked', false);\n view.remove();\n });\n });\n } catch(e) {\n error = e;\n }\n ok(!error, error);\n});\n\ntest(\"attributeBindings should not fail if view has been destroyed\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n attributeBindings: ['checked'],\n checked: true\n });\n });\n Ember.run(function() {\n view.createElement();\n });\n var error;\n try {\n Ember.run(function() {\n Ember.changeProperties(function() {\n view.set('checked', false);\n view.destroy();\n });\n });\n } catch(e) {\n error = e;\n }\n ok(!error, error);\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/attribute_bindings_test");minispade.register('ember-views/~tests/views/view/child_views_test', "(function() {(function() {\n var parentView, childView, childViews;\n var get = Ember.get;\n\n module('tests/views/view/child_views_tests.js', {\n setup: function() {\n parentView = Ember.View.create({\n render: function(buffer) {\n buffer.push('Em');\n this.appendChild(childView);\n }\n });\n\n childView = Ember.View.create({\n template: function() { return 'ber'; }\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n parentView.destroy();\n childView.destroy();\n });\n\n childViews = null;\n }\n });\n\n // no parent element, buffer, no element\n // parent element\n\n // no parent element, no buffer, no element\n test(\"should render an inserted child view when the child is inserted before a DOM element is created\", function() {\n Ember.run(function() {\n parentView.append();\n });\n\n equal(parentView.$().text(), 'Ember', 'renders the child view after the parent view');\n });\n\n test(\"should not duplicate childViews when rerendering in buffer\", function() {\n\n var Inner = Ember.View.extend({\n template: function() { return ''; }\n });\n\n var Inner2 = Ember.View.extend({\n template: function() { return ''; }\n });\n\n var Middle = Ember.View.extend({\n render: function(buffer) {\n this.appendChild(Inner);\n this.appendChild(Inner2);\n }\n });\n\n var outer = Ember.View.create({\n render: function(buffer) {\n this.middle = this.appendChild(Middle);\n }\n });\n\n Ember.run(function() {\n outer.renderToBuffer();\n });\n\n equal(outer.get('middle.childViews.length'), 2, 'precond middle has 2 child views rendered to buffer');\n\n raises(function() {\n Ember.run(function() {\n outer.middle.rerender();\n });\n }, /Something you did caused a view to re-render after it rendered but before it was inserted into the DOM./);\n\n equal(outer.get('middle.childViews.length'), 2, 'middle has 2 child views rendered to buffer');\n\n Ember.run(function() {\n outer.destroy();\n });\n });\n\n})();\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/child_views_test");minispade.register('ember-views/~tests/views/view/class_name_bindings_test', "(function() {var set = Ember.set, get = Ember.get, view;\n\nmodule(\"Ember.View - Class Name Bindings\", {\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n }\n});\n\ntest(\"should apply bound class names to the element\", function() {\n view = Ember.View.create({\n classNameBindings: ['priority', 'isUrgent', 'isClassified:classified',\n 'canIgnore', 'messages.count', 'messages.resent:is-resent',\n 'isNumber:is-number', 'isFalsy::is-falsy', 'isTruthy::is-not-truthy',\n 'isEnabled:enabled:disabled'],\n\n priority: 'high',\n isUrgent: true,\n isClassified: true,\n canIgnore: false,\n isNumber: 5,\n isFalsy: 0,\n isTruthy: 'abc',\n isEnabled: true,\n\n messages: {\n count: 'five-messages',\n resent: true\n }\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n ok(view.$().hasClass('high'), \"adds string values as class name\");\n ok(view.$().hasClass('is-urgent'), \"adds true Boolean values by dasherizing\");\n ok(view.$().hasClass('classified'), \"supports customizing class name for Boolean values\");\n ok(view.$().hasClass('five-messages'), \"supports paths in bindings\");\n ok(view.$().hasClass('is-resent'), \"supports customing class name for paths\");\n ok(view.$().hasClass('is-number'), \"supports colon syntax with truthy properties\");\n ok(view.$().hasClass('is-falsy'), \"supports colon syntax with falsy properties\");\n ok(!view.$().hasClass('abc'), \"does not add values as classes when falsy classes have been specified\");\n ok(!view.$().hasClass('is-not-truthy'), \"does not add falsy classes when values are truthy\");\n ok(!view.$().hasClass('can-ignore'), \"does not add false Boolean values as class\");\n ok(view.$().hasClass('enabled'), \"supports customizing class name for Boolean values with negation\");\n ok(!view.$().hasClass('disabled'), \"does not add class name for negated binding\");\n});\n\ntest(\"should add, remove, or change class names if changed after element is created\", function() {\n view = Ember.View.create({\n classNameBindings: ['priority', 'isUrgent', 'isClassified:classified',\n 'canIgnore', 'messages.count', 'messages.resent:is-resent',\n 'isEnabled:enabled:disabled'],\n\n priority: 'high',\n isUrgent: true,\n isClassified: true,\n canIgnore: false,\n isEnabled: true,\n\n messages: Ember.Object.create({\n count: 'five-messages',\n resent: false\n })\n });\n\n Ember.run(function() {\n view.createElement();\n set(view, 'priority', 'orange');\n set(view, 'isUrgent', false);\n set(view, 'canIgnore', true);\n set(view, 'isEnabled', false);\n set(view, 'messages.count', 'six-messages');\n set(view, 'messages.resent', true );\n });\n\n ok(view.$().hasClass('orange'), \"updates string values\");\n ok(!view.$().hasClass('high'), \"removes old string value\");\n\n ok(!view.$().hasClass('is-urgent', \"removes dasherized class when changed from true to false\"));\n ok(view.$().hasClass('can-ignore'), \"adds dasherized class when changed from false to true\");\n\n ok(view.$().hasClass('six-messages'), \"adds new value when path changes\");\n ok(!view.$().hasClass('five-messages'), \"removes old value when path changes\");\n\n ok(view.$().hasClass('is-resent'), \"adds customized class name when path changes\");\n\n ok(!view.$().hasClass('enabled'), \"updates class name for negated binding\");\n ok(view.$().hasClass('disabled'), \"adds negated class name for negated binding\");\n});\n\ntest(\":: class name syntax works with an empty true class\", function() {\n view = Ember.View.create({\n isEnabled: false,\n classNameBindings: ['isEnabled::not-enabled']\n });\n\n Ember.run(function() { view.createElement(); });\n\n equal(view.$().attr('class'), 'ember-view not-enabled', \"false class is rendered when property is false\");\n\n Ember.run(function() { view.set('isEnabled', true); });\n\n equal(view.$().attr('class'), 'ember-view', \"no class is added when property is true and the class is empty\");\n});\n\ntest(\"classNames should not be duplicated on rerender\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n classNameBindings: ['priority'],\n priority: 'high'\n });\n });\n\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.$().attr('class'), 'ember-view high');\n\n Ember.run(function() {\n view.rerender();\n });\n\n equal(view.$().attr('class'), 'ember-view high');\n});\n\ntest(\"classNameBindings should work when the binding property is updated and the view has been removed of the DOM\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n classNameBindings: ['priority'],\n priority: 'high'\n });\n });\n\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.$().attr('class'), 'ember-view high');\n\n Ember.run(function() {\n view.remove();\n });\n\n view.set('priority', 'low');\n\n Ember.run(function() {\n view.append();\n });\n\n equal(view.$().attr('class'), 'ember-view low');\n\n});\n\ntest(\"classNames removed by a classNameBindings observer should not re-appear on rerender\", function() {\n view = Ember.View.create({\n classNameBindings: ['isUrgent'],\n isUrgent: true\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.$().attr('class'), 'ember-view is-urgent');\n\n Ember.run(function() {\n view.set('isUrgent', false);\n });\n\n equal(view.$().attr('class'), 'ember-view');\n\n Ember.run(function() {\n view.rerender();\n });\n\n equal(view.$().attr('class'), 'ember-view');\n});\n\ntest(\"classNameBindings lifecycle test\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n classNameBindings: ['priority'],\n priority: 'high'\n });\n });\n\n equal(Ember.isWatching(view, 'priority'), false);\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.$().attr('class'), 'ember-view high');\n equal(Ember.isWatching(view, 'priority'), true);\n\n Ember.run(function() {\n view.remove();\n view.set('priority', 'low');\n });\n\n equal(Ember.isWatching(view, 'priority'), false);\n});\n\ntest(\"classNameBindings should not fail if view has been removed\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n classNameBindings: ['priority'],\n priority: 'high'\n });\n });\n Ember.run(function() {\n view.createElement();\n });\n var error;\n try {\n Ember.run(function() {\n Ember.changeProperties(function() {\n view.set('priority', 'low');\n view.remove();\n });\n });\n } catch(e) {\n error = e;\n }\n ok(!error, error);\n});\n\ntest(\"classNameBindings should not fail if view has been destroyed\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n classNameBindings: ['priority'],\n priority: 'high'\n });\n });\n Ember.run(function() {\n view.createElement();\n });\n var error;\n try {\n Ember.run(function() {\n Ember.changeProperties(function() {\n view.set('priority', 'low');\n view.destroy();\n });\n });\n } catch(e) {\n error = e;\n }\n ok(!error, error);\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/class_name_bindings_test");minispade.register('ember-views/~tests/views/view/class_string_for_value_test', "(function() {module(\"Ember.View - _classStringForValue\");\n\nvar cSFV = Ember.View._classStringForValue;\n\ntest(\"returns dasherized version of last path part if value is true\", function() {\n equal(cSFV(\"propertyName\", true), \"property-name\", \"class is dasherized\");\n equal(cSFV(\"content.propertyName\", true), \"property-name\", \"class is dasherized\");\n});\n\ntest(\"returns className if value is true and className is specified\", function() {\n equal(cSFV(\"propertyName\", true, \"truthyClass\"), \"truthyClass\", \"returns className if given\");\n equal(cSFV(\"content.propertyName\", true, \"truthyClass\"), \"truthyClass\", \"returns className if given\");\n});\n\ntest(\"returns falsyClassName if value is false and falsyClassName is specified\", function() {\n equal(cSFV(\"propertyName\", false, \"truthyClass\", \"falsyClass\"), \"falsyClass\", \"returns falsyClassName if given\");\n equal(cSFV(\"content.propertyName\", false, \"truthyClass\", \"falsyClass\"), \"falsyClass\", \"returns falsyClassName if given\");\n});\n\ntest(\"returns null if value is false and falsyClassName is not specified\", function() {\n equal(cSFV(\"propertyName\", false, \"truthyClass\"), null, \"returns null if falsyClassName is not specified\");\n equal(cSFV(\"content.propertyName\", false, \"truthyClass\"), null, \"returns null if falsyClassName is not specified\");\n});\n\ntest(\"returns null if value is false\", function() {\n equal(cSFV(\"propertyName\", false), null, \"returns null if value is false\");\n equal(cSFV(\"content.propertyName\", false), null, \"returns null if value is false\");\n});\n\ntest(\"returns null if value is true and className is not specified and falsyClassName is specified\", function() {\n equal(cSFV(\"propertyName\", true, undefined, \"falsyClassName\"), null, \"returns null if value is true\");\n equal(cSFV(\"content.propertyName\", true, undefined, \"falsyClassName\"), null, \"returns null if value is true\");\n});\n\ntest(\"returns the value if the value is truthy\", function() {\n equal(cSFV(\"propertyName\", \"myString\"), \"myString\", \"returns value if the value is truthy\");\n equal(cSFV(\"content.propertyName\", \"myString\"), \"myString\", \"returns value if the value is truthy\");\n\n equal(cSFV(\"propertyName\", \"123\"), 123, \"returns value if the value is truthy\");\n equal(cSFV(\"content.propertyName\", 123), 123, \"returns value if the value is truthy\");\n});\n})();\n//@ sourceURL=ember-views/~tests/views/view/class_string_for_value_test");minispade.register('ember-views/~tests/views/view/context_test', "(function() {module(\"Ember.View - context property\");\n\ntest(\"setting a controller on an inner view should change it context\", function() {\n var App = {};\n var a = { name: 'a' };\n var b = { name: 'b' };\n\n var innerView = Ember.View.create();\n var middleView = Ember.ContainerView.create();\n var outerView = App.outerView = Ember.ContainerView.create({\n controller: a\n });\n\n Ember.run(function() {\n outerView.appendTo('#qunit-fixture');\n });\n\n Ember.run(function () {\n outerView.set('currentView', middleView);\n });\n\n Ember.run(function () {\n innerView.set('controller', b);\n middleView.set('currentView', innerView);\n });\n\n // assert\n equal(outerView.get('context'), a, 'outer context correct');\n equal(middleView.get('context'), a, 'middle context correct');\n equal(innerView.get('context'), b, 'inner context correct');\n\n Ember.run(function() {\n innerView.destroy();\n middleView.destroy();\n outerView.destroy();\n });\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/context_test");minispade.register('ember-views/~tests/views/view/controller_test', "(function() {module(\"Ember.View - controller property\");\n\ntest(\"controller property should be inherited from nearest ancestor with controller\", function() {\n var grandparent = Ember.ContainerView.create();\n var parent = Ember.ContainerView.create();\n var child = Ember.ContainerView.create();\n var grandchild = Ember.ContainerView.create();\n\n var grandparentController = {};\n var parentController = {};\n\n Ember.run(function() {\n grandparent.set('controller', grandparentController);\n parent.set('controller', parentController);\n\n grandparent.pushObject(parent);\n parent.pushObject(child);\n });\n\n strictEqual(grandparent.get('controller'), grandparentController);\n strictEqual(parent.get('controller'), parentController);\n strictEqual(child.get('controller'), parentController);\n strictEqual(grandchild.get('controller'), null);\n\n Ember.run(function() {\n child.pushObject(grandchild);\n });\n\n strictEqual(grandchild.get('controller'), parentController);\n\n var newController = {};\n Ember.run(function() {\n parent.set('controller', newController);\n });\n\n strictEqual(parent.get('controller'), newController);\n strictEqual(child.get('controller'), newController);\n strictEqual(grandchild.get('controller'), newController);\n\n Ember.run(function() {\n grandparent.destroy();\n parent.destroy();\n child.destroy();\n grandchild.destroy();\n });\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/controller_test");minispade.register('ember-views/~tests/views/view/create_child_view_test', "(function() {var set = Ember.set, get = Ember.get;\n\nvar view, myViewClass, newView, container;\n\nmodule(\"Ember.View#createChildView\", {\n setup: function() {\n container = { };\n\n view = Ember.View.create({\n container: container\n });\n\n myViewClass = Ember.View.extend({ isMyView: true, foo: 'bar' });\n },\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n if(newView) { newView.destroy(); }\n });\n }\n});\n\ntest(\"should create view from class with any passed attributes\", function() {\n var attrs = {\n foo: \"baz\"\n };\n\n newView = view.createChildView(myViewClass, attrs);\n\n equal(newView.container, container, 'expects to share container with parent');\n ok(get(newView, 'isMyView'), 'newView is instance of myView');\n equal(get(newView, 'foo'), 'baz', 'view did get custom attributes');\n ok(!attrs.parentView, \"the original attributes hash was not mutated\");\n});\n\ntest(\"should set newView.parentView to receiver\", function() {\n newView = view.createChildView(myViewClass) ;\n\n equal(newView.container, container, 'expects to share container with parent');\n equal(get(newView, 'parentView'), view, 'newView.parentView == view');\n});\n\ntest(\"should create property on parentView to a childView instance if provided a viewName\", function() {\n var attrs = {\n viewName: \"someChildView\"\n };\n\n newView = view.createChildView(myViewClass, attrs);\n equal(newView.container, container, 'expects to share container with parent');\n\n equal(get(view, 'someChildView'), newView);\n});\n\ntest(\"should update a view instances attributes, including the _parentView and container properties\", function() {\n var attrs = {\n foo: \"baz\"\n };\n\n var myView = myViewClass.create();\n newView = view.createChildView(myView, attrs);\n\n equal(newView.container, container, 'expects to share container with parent');\n equal(newView._parentView, view, 'expects to have the correct parent');\n equal(get(newView, 'foo'), 'baz', 'view did get custom attributes');\n\n deepEqual(newView, myView);\n});\n\ntest(\"should create from string via container lookup\", function() {\n var ChildViewClass = Ember.View.extend(),\n fullName = 'view:bro';\n\n view.container.lookupFactory = function(viewName) {\n equal(fullName, viewName);\n\n return ChildViewClass.extend({\n container: container\n });\n };\n\n newView = view.createChildView('bro');\n\n equal(newView.container, container, 'expects to share container with parent');\n equal(newView._parentView, view, 'expects to have the correct parent');\n});\n\ntest(\"should assert when trying to create childView from string, but no such view is registered\", function() {\n view.container.lookupFactory = function() {};\n\n expectAssertion(function(){\n view.createChildView('bro');\n });\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/create_child_view_test");minispade.register('ember-views/~tests/views/view/create_element_test', "(function() {var set = Ember.set, get = Ember.get, view;\n\nmodule(\"Ember.View#createElement\", {\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n }\n});\n\ntest(\"returns the receiver\", function() {\n var ret;\n\n view = Ember.View.create();\n\n Ember.run(function() {\n ret = view.createElement();\n });\n\n equal(ret, view, 'returns receiver');\n});\n\ntest(\"calls render and turns resultant string into element\", function() {\n view = Ember.View.create({\n tagName: 'span',\n\n render: function(buffer) {\n buffer.push(\"foo\");\n }\n });\n\n equal(get(view, 'element'), null, 'precondition - has no element');\n Ember.run(function() {\n view.createElement();\n });\n\n\n var elem = get(view, 'element');\n ok(elem, 'has element now');\n equal(elem.innerHTML, 'foo', 'has innerHTML from context');\n equal(elem.tagName.toString().toLowerCase(), 'span', 'has tagName from view');\n});\n\ntest(\"generated element include HTML from child views as well\", function() {\n view = Ember.ContainerView.create({\n childViews: [ Ember.View.create({ elementId: \"foo\" })]\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n ok(view.$('#foo').length, 'has element with child elementId');\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/create_element_test");minispade.register('ember-views/~tests/views/view/destroy_element_test', "(function() {var set = Ember.set, get = Ember.get, view;\n\nmodule(\"Ember.View#destroyElement\", {\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n }\n});\n\ntest(\"if it has no element, does nothing\", function() {\n var callCount = 0;\n view = Ember.View.create({\n willDestroyElement: function() { callCount++; }\n });\n\n ok(!get(view, 'element'), 'precond - does NOT have element');\n\n Ember.run(function() {\n view.destroyElement();\n });\n\n equal(callCount, 0, 'did not invoke callback');\n});\n\ntest(\"if it has a element, calls willDestroyElement on receiver and child views then deletes the element\", function() {\n var parentCount = 0, childCount = 0;\n\n view = Ember.ContainerView.create({\n willDestroyElement: function() { parentCount++; },\n childViews: [Ember.ContainerView.extend({\n // no willDestroyElement here... make sure no errors are thrown\n childViews: [Ember.View.extend({\n willDestroyElement: function() { childCount++; }\n })]\n })]\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n ok(get(view, 'element'), 'precond - view has element');\n\n Ember.run(function() {\n view.destroyElement();\n });\n\n equal(parentCount, 1, 'invoked destroy element on the parent');\n equal(childCount, 1, 'invoked destroy element on the child');\n ok(!get(view, 'element'), 'view no longer has element');\n ok(!get(get(view, 'childViews').objectAt(0), 'element'), 'child no longer has an element');\n});\n\ntest(\"returns receiver\", function() {\n var ret;\n view = Ember.View.create();\n\n Ember.run(function() {\n view.createElement();\n ret = view.destroyElement();\n });\n\n equal(ret, view, 'returns receiver');\n});\n\ntest(\"removes element from parentNode if in DOM\", function() {\n view = Ember.View.create();\n\n Ember.run(function() {\n view.append();\n });\n\n var parent = view.$().parent();\n\n ok(get(view, 'element'), 'precond - has element');\n\n Ember.run(function() {\n view.destroyElement();\n });\n\n equal(view.$(), undefined, 'view has no selector');\n ok(!parent.find('#'+view.get('elementId')).length, 'element no longer in parent node');\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/destroy_element_test");minispade.register('ember-views/~tests/views/view/destroy_test', "(function() {var set = Ember.set, get = Ember.get;\n\nmodule(\"Ember.View#destroy\");\n\ntest(\"should teardown viewName on parentView when childView is destroyed\", function() {\n var viewName = \"someChildView\",\n parentView = Ember.View.create(),\n childView = parentView.createChildView(Ember.View, {viewName: viewName});\n\n equal(get(parentView, viewName), childView, \"Precond - child view was registered on parent\");\n\n Ember.run(function() {\n childView.destroy();\n });\n\n equal(get(parentView, viewName), null, \"viewName reference was removed on parent\");\n\n Ember.run(function() {\n parentView.destroy();\n });\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/destroy_test");minispade.register('ember-views/~tests/views/view/element_test', "(function() {var set = Ember.set, get = Ember.get;\n\nvar parentView, child, parentDom, childDom, view;\n\nmodule(\"Ember.View#element\", {\n teardown: function() {\n Ember.run(function() {\n if (parentView) { parentView.destroy(); }\n view.destroy();\n });\n }\n});\n\ntest(\"returns null if the view has no element and no parent view\", function() {\n view = Ember.View.create() ;\n equal(get(view, 'parentView'), null, 'precond - has no parentView');\n equal(get(view, 'element'), null, 'has no element');\n});\n\ntest(\"returns null if the view has no element and parent view has no element\", function() {\n parentView = Ember.ContainerView.create({\n childViews: [ Ember.View.extend() ]\n });\n view = get(parentView, 'childViews').objectAt(0);\n\n equal(get(view, 'parentView'), parentView, 'precond - has parent view');\n equal(get(parentView, 'element'), null, 'parentView has no element');\n equal(get(view, 'element'), null, ' has no element');\n});\n\ntest(\"returns element if you set the value\", function() {\n view = Ember.View.create();\n equal(get(view, 'element'), null, 'precond- has no element');\n\n var dom = document.createElement('div');\n set(view, 'element', dom);\n\n equal(get(view, 'element'), dom, 'now has set element');\n});\n\n\nmodule(\"Ember.View#element - autodiscovery\", {\n setup: function() {\n parentView = Ember.ContainerView.create({\n childViews: [ Ember.View.extend({\n elementId: 'child-view'\n }) ]\n });\n\n child = get(parentView, 'childViews').objectAt(0);\n\n // setup parent/child dom\n parentDom = Ember.$(\"
    \")[0];\n\n // set parent element...\n set(parentView, 'element', parentDom);\n },\n\n teardown: function() {\n Ember.run(function() {\n parentView.destroy();\n if (view) { view.destroy(); }\n });\n parentView = child = parentDom = childDom = null ;\n }\n});\n\ntest(\"discovers element if has no element but parent view does have element\", function() {\n equal(get(parentView, 'element'), parentDom, 'precond - parent has element');\n ok(parentDom.firstChild, 'precond - parentDom has first child');\n\n equal(child.$().attr('id'), 'child-view', 'view discovered child');\n});\n\ntest(\"should not allow the elementId to be changed after inserted\", function() {\n view = Ember.View.create({\n elementId: 'one'\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n raises(function() {\n view.set('elementId', 'two');\n }, \"raises elementId changed exception\");\n\n equal(view.get('elementId'), 'one', 'elementId is still \"one\"');\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/element_test");minispade.register('ember-views/~tests/views/view/evented_test', "(function() {var set = Ember.set, get = Ember.get, view;\n\nmodule(\"Ember.View evented helpers\", {\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n }\n});\n\ntest(\"fire should call method sharing event name if it exists on the view\", function() {\n var eventFired = false;\n\n view = Ember.View.create({\n fireMyEvent: function() {\n this.trigger('myEvent');\n },\n\n myEvent: function() {\n eventFired = true;\n }\n });\n\n Ember.run(function() {\n view.fireMyEvent();\n });\n\n equal(eventFired, true, \"fired the view method sharing the event name\");\n});\n\ntest(\"fire does not require a view method with the same name\", function() {\n var eventFired = false;\n\n view = Ember.View.create({\n fireMyEvent: function() {\n this.trigger('myEvent');\n }\n });\n\n var listenObject = Ember.Object.create({\n onMyEvent: function() {\n eventFired = true;\n }\n });\n\n view.on('myEvent', listenObject, 'onMyEvent');\n\n Ember.run(function() {\n view.fireMyEvent();\n });\n\n equal(eventFired, true, \"fired the event without a view method sharing its name\");\n\n Ember.run(function() {\n listenObject.destroy();\n });\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/evented_test");minispade.register('ember-views/~tests/views/view/init_test', "(function() {/*global TestApp:true*/\nvar set = Ember.set, get = Ember.get;\n\nvar originalLookup = Ember.lookup, lookup, view;\n\nmodule(\"Ember.View.create\", {\n setup: function() {\n Ember.lookup = lookup = {};\n },\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n\n Ember.lookup = originalLookup;\n }\n});\n\ntest(\"registers view in the global views hash using layerId for event targeted\", function() {\n view = Ember.View.create();\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n equal(Ember.View.views[get(view, 'elementId')], view, 'registers view');\n});\n\nmodule(\"Ember.View.createWithMixins\");\n\ntest(\"should warn if a non-array is used for classNames\", function() {\n expectAssertion(function() {\n Ember.View.createWithMixins({\n elementId: 'test',\n classNames: Ember.computed(function() {\n return ['className'];\n }).volatile()\n });\n }, /Only arrays are allowed/i);\n});\n\ntest(\"should warn if a non-array is used for classNamesBindings\", function() {\n expectAssertion(function() {\n Ember.View.createWithMixins({\n elementId: 'test',\n classNameBindings: Ember.computed(function() {\n return ['className'];\n }).volatile()\n });\n }, /Only arrays are allowed/i);\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/init_test");minispade.register('ember-views/~tests/views/view/is_visible_test', "(function() {var get = Ember.get, set = Ember.set;\n\nvar View, view, parentBecameVisible, childBecameVisible, grandchildBecameVisible;\nvar parentBecameHidden, childBecameHidden, grandchildBecameHidden;\n\nmodule(\"Ember.View#isVisible\", {\n setup: function() {\n parentBecameVisible=0;\n childBecameVisible=0;\n grandchildBecameVisible=0;\n parentBecameHidden=0;\n childBecameHidden=0;\n grandchildBecameHidden=0;\n\n View = Ember.ContainerView.extend({\n childViews: ['child'],\n becameVisible: function() { parentBecameVisible++; },\n becameHidden: function() { parentBecameHidden++; },\n\n child: Ember.ContainerView.extend({\n childViews: ['grandchild'],\n becameVisible: function() { childBecameVisible++; },\n becameHidden: function() { childBecameHidden++; },\n\n grandchild: Ember.View.extend({\n template: function() { return \"seems weird bro\"; },\n becameVisible: function() { grandchildBecameVisible++; },\n becameHidden: function() { grandchildBecameHidden++; }\n })\n })\n });\n },\n\n teardown: function() {\n if (view) {\n Ember.run(function() { view.destroy(); });\n }\n }\n});\n\ntest(\"should hide views when isVisible is false\", function() {\n view = Ember.View.create({\n isVisible: false\n });\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().is(':hidden'), \"the view is hidden\");\n\n set(view, 'isVisible', true);\n ok(view.$().is(':visible'), \"the view is visible\");\n Ember.run(function() {\n view.remove();\n });\n});\n\ntest(\"should hide element if isVisible is false before element is created\", function() {\n view = Ember.View.create({\n isVisible: false\n });\n\n ok(!get(view, 'isVisible'), \"precond - view is not visible\");\n\n set(view, 'template', function() { return \"foo\"; });\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().is(':hidden'), \"should be hidden\");\n\n Ember.run(function() {\n view.remove();\n });\n\n set(view, 'isVisible', true);\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().is(':visible'), \"view should be visible\");\n\n Ember.run(function() {\n view.remove();\n });\n});\n\ntest(\"view should be notified after isVisible is set to false and the element has been hidden\", function() {\n Ember.run(function() {\n view = View.create({ isVisible: false });\n view.append();\n });\n\n ok(view.$().is(':hidden'), \"precond - view is hidden when appended\");\n\n Ember.run(function() {\n view.set('isVisible', true);\n });\n\n ok(view.$().is(':visible'), \"precond - view is now visible\");\n equal(parentBecameVisible, 1);\n equal(childBecameVisible, 1);\n equal(grandchildBecameVisible, 1);\n});\n\ntest(\"view should be notified after isVisible is set to false and the element has been hidden\", function() {\n view = View.create({ isVisible: true });\n var childView = view.get('childViews').objectAt(0);\n var grandchildView = childView.get('childViews').objectAt(0);\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().is(':visible'), \"precond - view is visible when appended\");\n\n Ember.run(function() {\n childView.set('isVisible', false);\n });\n\n ok(childView.$().is(':hidden'), \"precond - view is now hidden\");\n\n equal(childBecameHidden, 1);\n equal(grandchildBecameHidden, 1);\n});\n\ntest(\"view should be notified after isVisible is set to true and the element has been shown\", function() {\n view = View.create({ isVisible: false });\n var childView = view.get('childViews').objectAt(0);\n var grandchildView = childView.get('childViews').objectAt(0);\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().is(':hidden'), \"precond - view is hidden when appended\");\n\n Ember.run(function() {\n view.set('isVisible', true);\n });\n\n ok(view.$().is(':visible'), \"precond - view is now visible\");\n\n equal(parentBecameVisible, 1);\n equal(childBecameVisible, 1);\n equal(grandchildBecameVisible, 1);\n});\n\ntest(\"if a view descends from a hidden view, making isVisible true should not trigger becameVisible\", function() {\n view = View.create({ isVisible: true });\n var childView = view.get('childViews').objectAt(0);\n var grandchildView = childView.get('childViews').objectAt(0);\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().is(':visible'), \"precond - view is visible when appended\");\n\n Ember.run(function() {\n childView.set('isVisible', false);\n });\n\n Ember.run(function() {\n view.set('isVisible', false);\n });\n\n childBecameVisible = 0;\n grandchildBecameVisible = 0;\n\n Ember.run(function() {\n childView.set('isVisible', true);\n });\n\n equal(childBecameVisible, 0, \"the child did not become visible\");\n equal(grandchildBecameVisible, 0, \"the grandchild did not become visible\");\n});\n\ntest(\"if a child view becomes visible while its parent is hidden, if its parent later becomes visible, it receives a becameVisible callback\", function() {\n view = View.create({ isVisible: false });\n var childView = view.get('childViews').objectAt(0);\n var grandchildView = childView.get('childViews').objectAt(0);\n\n Ember.run(function() {\n view.append();\n });\n\n ok(view.$().is(':hidden'), \"precond - view is hidden when appended\");\n\n Ember.run(function() {\n childView.set('isVisible', true);\n });\n\n equal(childBecameVisible, 0, \"child did not become visible since parent is hidden\");\n equal(grandchildBecameVisible, 0, \"grandchild did not become visible since parent is hidden\");\n\n Ember.run(function() {\n view.set('isVisible', true);\n });\n\n equal(parentBecameVisible, 1);\n equal(childBecameVisible, 1);\n equal(grandchildBecameVisible, 1);\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/is_visible_test");minispade.register('ember-views/~tests/views/view/jquery_test', "(function() {var set = Ember.set, get = Ember.get;\n\nvar view ;\nmodule(\"Ember.View#$\", {\n setup: function() {\n view = Ember.View.extend({\n render: function(context, firstTime) {\n context.push('');\n }\n }).create();\n\n Ember.run(function() {\n view.append();\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n }\n});\n\ntest(\"returns undefined if no element\", function() {\n var view = Ember.View.create();\n ok(!get(view, 'element'), 'precond - should have no element');\n equal(view.$(), undefined, 'should return undefined');\n equal(view.$('span'), undefined, 'should undefined if filter passed');\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\ntest(\"returns jQuery object selecting element if provided\", function() {\n ok(get(view, 'element'), 'precond - should have element');\n\n var jquery = view.$();\n equal(jquery.length, 1, 'view.$() should have one element');\n equal(jquery[0], get(view, 'element'), 'element should be element');\n});\n\ntest(\"returns jQuery object selecting element inside element if provided\", function() {\n ok(get(view, 'element'), 'precond - should have element');\n\n var jquery = view.$('span');\n equal(jquery.length, 1, 'view.$() should have one element');\n equal(jquery[0].parentNode, get(view, 'element'), 'element should be in element');\n});\n\ntest(\"returns empty jQuery object if filter passed that does not match item in parent\", function() {\n ok(get(view, 'element'), 'precond - should have element');\n\n var jquery = view.$('body'); // would normally work if not scoped to view\n equal(jquery.length, 0, 'view.$(body) should have no elements');\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/jquery_test");minispade.register('ember-views/~tests/views/view/layout_test', "(function() {var set = Ember.set, get = Ember.get, container, view;\n\nmodule(\"Ember.View - Layout Functionality\", {\n setup: function() {\n container = new Ember.Container();\n container.optionsForType('template', { instantiate: false });\n },\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n }\n});\n\ntest(\"should call the function of the associated layout\", function() {\n var templateCalled = 0, layoutCalled = 0;\n\n container.register('template:template', function() { templateCalled++; });\n container.register('template:layout', function() { layoutCalled++; });\n\n view = Ember.View.create({\n container: container,\n layoutName: 'layout',\n templateName: 'template'\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(templateCalled, 0, \"template is not called when layout is present\");\n equal(layoutCalled, 1, \"layout is called when layout is present\");\n});\n\ntest(\"should call the function of the associated template with itself as the context\", function() {\n container.register('template:testTemplate', function(dataSource) {\n return \"

    template was called for \" + get(dataSource, 'personName') + \"

    \";\n });\n\n view = Ember.View.create({\n container: container,\n layoutName: 'testTemplate',\n\n context: {\n personName: \"Tom DAAAALE\"\n }\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(\"template was called for Tom DAAAALE\", view.$('#twas-called').text(), \"the named template was called with the view as the data source\");\n});\n\ntest(\"should fall back to defaultTemplate if neither template nor templateName are provided\", function() {\n var View;\n\n View = Ember.View.extend({\n defaultLayout: function(dataSource) { return \"

    template was called for \" + get(dataSource, 'personName') + \"

    \"; }\n });\n\n view = View.create({\n context: {\n personName: \"Tom DAAAALE\"\n }\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(\"template was called for Tom DAAAALE\", view.$('#twas-called').text(), \"the named template was called with the view as the data source\");\n});\n\ntest(\"should not use defaultLayout if layout is provided\", function() {\n var View;\n\n View = Ember.View.extend({\n layout: function() { return \"foo\"; },\n defaultLayout: function(dataSource) { return \"

    template was called for \" + get(dataSource, 'personName') + \"

    \"; }\n });\n\n view = View.create();\n Ember.run(function() {\n view.createElement();\n });\n\n\n equal(\"foo\", view.$().text(), \"default layout was not printed\");\n});\n\ntest(\"the template property is available to the layout template\", function() {\n view = Ember.View.create({\n template: function(context, options) {\n options.data.buffer.push(\" derp\");\n },\n\n layout: function(context, options) {\n options.data.buffer.push(\"Herp\");\n get(options.data.view, 'template')(context, options);\n }\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(\"Herp derp\", view.$().text(), \"the layout has access to the template\");\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/layout_test");minispade.register('ember-views/~tests/views/view/nearest_of_type_test', "(function() {var set = Ember.set, get = Ember.get, parentView, view;\n\nmodule(\"Ember.View#nearest*\", {\n teardown: function() {\n Ember.run(function() {\n if (parentView) { parentView.destroy(); }\n if (view) { view.destroy(); }\n });\n }\n});\n\n(function() {\n var Mixin = Ember.Mixin.create({}),\n Parent = Ember.View.extend(Mixin, {\n render: function(buffer) {\n this.appendChild( Ember.View.create() );\n }\n });\n\n test(\"nearestOfType should find the closest view by view class\", function() {\n var child;\n\n Ember.run(function() {\n parentView = Parent.create();\n parentView.appendTo('#qunit-fixture');\n });\n\n child = parentView.get('childViews')[0];\n equal(child.nearestOfType(Parent), parentView, \"finds closest view in the hierarchy by class\");\n });\n\n test(\"nearestOfType should find the closest view by mixin\", function() {\n var child;\n\n Ember.run(function() {\n parentView = Parent.create();\n parentView.appendTo('#qunit-fixture');\n });\n\n child = parentView.get('childViews')[0];\n equal(child.nearestOfType(Mixin), parentView, \"finds closest view in the hierarchy by class\");\n });\n\ntest(\"nearestWithProperty should search immediate parent\", function() {\n var childView;\n\n view = Ember.View.create({\n myProp: true,\n\n render: function(buffer) {\n this.appendChild(Ember.View.create());\n }\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n childView = view.get('childViews')[0];\n equal(childView.nearestWithProperty('myProp'), view);\n\n});\n\n}());\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/nearest_of_type_test");minispade.register('ember-views/~tests/views/view/parse_property_path_test', "(function() {module(\"Ember.View - _parsePropertyPath\");\n\ntest(\"it works with a simple property path\", function() {\n var parsed = Ember.View._parsePropertyPath(\"simpleProperty\");\n\n equal(parsed.path, \"simpleProperty\", \"path is parsed correctly\");\n equal(parsed.className, undefined, \"there is no className\");\n equal(parsed.falsyClassName, undefined, \"there is no falsyClassName\");\n equal(parsed.classNames, \"\", \"there is no classNames\");\n});\n\ntest(\"it works with a more complex property path\", function() {\n var parsed = Ember.View._parsePropertyPath(\"content.simpleProperty\");\n\n equal(parsed.path, \"content.simpleProperty\", \"path is parsed correctly\");\n equal(parsed.className, undefined, \"there is no className\");\n equal(parsed.falsyClassName, undefined, \"there is no falsyClassName\");\n equal(parsed.classNames, \"\", \"there is no classNames\");\n});\n\ntest(\"className is extracted\", function() {\n var parsed = Ember.View._parsePropertyPath(\"content.simpleProperty:class\");\n\n equal(parsed.path, \"content.simpleProperty\", \"path is parsed correctly\");\n equal(parsed.className, \"class\", \"className is extracted\");\n equal(parsed.falsyClassName, undefined, \"there is no falsyClassName\");\n equal(parsed.classNames, \":class\", \"there is a classNames\");\n});\n\ntest(\"falsyClassName is extracted\", function() {\n var parsed = Ember.View._parsePropertyPath(\"content.simpleProperty:class:falsyClass\");\n\n equal(parsed.path, \"content.simpleProperty\", \"path is parsed correctly\");\n equal(parsed.className, \"class\", \"className is extracted\");\n equal(parsed.falsyClassName, \"falsyClass\", \"falsyClassName is extracted\");\n equal(parsed.classNames, \":class:falsyClass\", \"there is a classNames\");\n});\n\ntest(\"it works with an empty true class\", function() {\n var parsed = Ember.View._parsePropertyPath(\"content.simpleProperty::falsyClass\");\n\n equal(parsed.path, \"content.simpleProperty\", \"path is parsed correctly\");\n equal(parsed.className, undefined, \"className is undefined\");\n equal(parsed.falsyClassName, \"falsyClass\", \"falsyClassName is extracted\");\n equal(parsed.classNames, \"::falsyClass\", \"there is a classNames\");\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/parse_property_path_test");minispade.register('ember-views/~tests/views/view/remove_test', "(function() {var set = Ember.set, get = Ember.get;\nvar indexOf = Ember.EnumerableUtils.indexOf;\n\n// .......................................................\n// removeChild()\n//\n\nvar parentView, child;\nmodule(\"Ember.View#removeChild\", {\n setup: function() {\n parentView = Ember.ContainerView.create({ childViews: [Ember.View] });\n child = get(parentView, 'childViews').objectAt(0);\n },\n teardown: function() {\n Ember.run(function() {\n parentView.destroy();\n child.destroy();\n });\n }\n});\n\ntest(\"returns receiver\", function() {\n equal(parentView.removeChild(child), parentView, 'receiver');\n});\n\ntest(\"removes child from parent.childViews array\", function() {\n ok(indexOf(get(parentView, 'childViews'), child)>=0, 'precond - has child in childViews array before remove');\n parentView.removeChild(child);\n ok(indexOf(get(parentView, 'childViews'), child)<0, 'removed child');\n});\n\ntest(\"sets parentView property to null\", function() {\n ok(get(child, 'parentView'), 'precond - has parentView');\n parentView.removeChild(child);\n ok(!get(child, 'parentView'), 'parentView is now null');\n});\n\n// .......................................................\n// removeAllChildren()\n//\nvar view, childViews;\nmodule(\"Ember.View#removeAllChildren\", {\n setup: function() {\n view = Ember.ContainerView.create({\n childViews: [Ember.View, Ember.View, Ember.View]\n });\n childViews = view.get('childViews');\n },\n teardown: function() {\n Ember.run(function() {\n childViews.forEach(function(v) { v.destroy(); });\n view.destroy();\n });\n }\n});\n\ntest(\"removes all child views\", function() {\n equal(get(view, 'childViews.length'), 3, 'precond - has child views');\n\n view.removeAllChildren();\n equal(get(view, 'childViews.length'), 0, 'removed all children');\n});\n\ntest(\"returns receiver\", function() {\n equal(view.removeAllChildren(), view, 'receiver');\n});\n\n// .......................................................\n// removeFromParent()\n//\nmodule(\"Ember.View#removeFromParent\", {\n teardown: function() {\n Ember.run(function() {\n if (parentView) { parentView.destroy(); }\n if (child) { child.destroy(); }\n if (view) { view.destroy(); }\n });\n }\n});\n\ntest(\"removes view from parent view\", function() {\n parentView = Ember.ContainerView.create({ childViews: [Ember.View] });\n child = get(parentView, 'childViews').objectAt(0);\n ok(get(child, 'parentView'), 'precond - has parentView');\n\n Ember.run(function() {\n parentView.createElement();\n });\n\n ok(parentView.$('div').length, \"precond - has a child DOM element\");\n\n Ember.run(function() {\n child.removeFromParent();\n });\n\n ok(!get(child, 'parentView'), 'no longer has parentView');\n ok(indexOf(get(parentView, 'childViews'), child)<0, 'no longer in parent childViews');\n equal(parentView.$('div').length, 0, \"removes DOM element from parent\");\n});\n\ntest(\"returns receiver\", function() {\n parentView = Ember.ContainerView.create({ childViews: [Ember.View] });\n child = get(parentView, 'childViews').objectAt(0);\n var removed = Ember.run(function() {\n return child.removeFromParent();\n });\n\n equal(removed, child, 'receiver');\n});\n\ntest(\"does nothing if not in parentView\", function() {\n var callCount = 0;\n child = Ember.View.create();\n\n // monkey patch for testing...\n ok(!get(child, 'parentView'), 'precond - has no parent');\n\n child.removeFromParent();\n\n Ember.run(function() {\n child.destroy();\n });\n});\n\n\ntest(\"the DOM element is gone after doing append and remove in two separate runloops\", function() {\n view = Ember.View.create();\n Ember.run(function() {\n view.append();\n });\n Ember.run(function() {\n view.remove();\n });\n\n var viewElem = Ember.$('#'+get(view, 'elementId'));\n ok(viewElem.length === 0, \"view's element doesn't exist in DOM\");\n});\n\ntest(\"the DOM element is gone after doing append and remove in a single runloop\", function() {\n view = Ember.View.create();\n Ember.run(function() {\n view.append();\n view.remove();\n });\n\n var viewElem = Ember.$('#'+get(view, 'elementId'));\n ok(viewElem.length === 0, \"view's element doesn't exist in DOM\");\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/remove_test");minispade.register('ember-views/~tests/views/view/render_test', "(function() {/*global module test equals context ok same */\n\nvar set = Ember.set, get = Ember.get, view;\n\n// .......................................................\n// render()\n//\nmodule(\"Ember.View#render\", {\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n }\n});\n\ntest(\"default implementation does not render child views\", function() {\n\n var rendered = 0, updated = 0, parentRendered = 0, parentUpdated = 0 ;\n view = Ember.ContainerView.createWithMixins({\n childViews: [\"child\"],\n\n render: function(buffer) {\n parentRendered++;\n this._super(buffer);\n },\n\n child: Ember.View.createWithMixins({\n render: function(buffer) {\n rendered++;\n this._super(buffer);\n }\n })\n });\n\n Ember.run(function() {\n view.createElement();\n });\n equal(rendered, 1, 'rendered the child once');\n equal(parentRendered, 1);\n equal(view.$('div').length, 1);\n\n});\n\ntest(\"should invoke renderChildViews if layer is destroyed then re-rendered\", function() {\n\n var rendered = 0, parentRendered = 0, parentUpdated = 0 ;\n view = Ember.ContainerView.createWithMixins({\n childViews: [\"child\"],\n\n render: function(buffer) {\n parentRendered++;\n this._super(buffer);\n },\n\n child: Ember.View.createWithMixins({\n render: function(buffer) {\n rendered++;\n this._super(buffer);\n }\n })\n });\n\n Ember.run(function() {\n view.append();\n });\n\n equal(rendered, 1, 'rendered the child once');\n equal(parentRendered, 1);\n equal(view.$('div').length, 1);\n\n Ember.run(function() {\n view.rerender();\n });\n\n equal(rendered, 2, 'rendered the child twice');\n equal(parentRendered, 2);\n equal(view.$('div').length, 1);\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\ntest(\"should render child views with a different tagName\", function() {\n var rendered = 0, parentRendered = 0, parentUpdated = 0 ;\n\n view = Ember.ContainerView.create({\n childViews: [\"child\"],\n\n child: Ember.View.create({\n tagName: 'aside'\n })\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.$('aside').length, 1);\n});\n\ntest(\"should add ember-view to views\", function() {\n view = Ember.View.create();\n\n Ember.run(function() {\n view.createElement();\n });\n\n ok(view.$().hasClass('ember-view'), \"the view has ember-view\");\n});\n\ntest(\"should allow hX tags as tagName\", function() {\n\n view = Ember.ContainerView.create({\n childViews: [\"child\"],\n\n child: Ember.View.create({\n tagName: 'h3'\n })\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n ok(view.$('h3').length, \"does not render the h3 tag correctly\");\n});\n\ntest(\"should not add role attribute unless one is specified\", function() {\n view = Ember.View.create();\n\n Ember.run(function() {\n view.createElement();\n });\n\n ok(view.$().attr('role') === undefined, \"does not have a role attribute\");\n});\n\ntest(\"should re-render if the context is changed\", function() {\n view = Ember.View.create({\n elementId: 'template-context-test',\n context: { foo: \"bar\" },\n render: function(buffer) {\n var value = get(get(this, 'context'), 'foo');\n buffer.push(value);\n }\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n equal(Ember.$('#qunit-fixture #template-context-test').text(), \"bar\", \"precond - renders the view with the initial value\");\n\n Ember.run(function() {\n view.set('context', {\n foo: \"bang baz\"\n });\n });\n\n equal(Ember.$('#qunit-fixture #template-context-test').text(), \"bang baz\", \"re-renders the view with the updated context\");\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/render_test");minispade.register('ember-views/~tests/views/view/replace_in_test', "(function() {var set = Ember.set, get = Ember.get;\n\nvar View, view, willDestroyCalled, childView;\n\nmodule(\"Ember.View - replaceIn()\", {\n setup: function() {\n View = Ember.View.extend({});\n },\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n }\n});\n\ntest(\"should be added to the specified element when calling replaceIn()\", function() {\n Ember.$(\"#qunit-fixture\").html('
    ');\n\n view = View.create();\n\n ok(!get(view, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.replaceIn('#menu');\n });\n\n var viewElem = Ember.$('#menu').children();\n ok(viewElem.length > 0, \"creates and replaces the view's element\");\n});\n\ntest(\"raises an assert when a target does not exist in the DOM\", function() {\n view = View.create();\n\n expectAssertion(function() {\n Ember.run(function() {\n view.replaceIn('made-up-target');\n });\n });\n});\n\n\ntest(\"should remove previous elements when calling replaceIn()\", function() {\n Ember.$(\"#qunit-fixture\").html('

    Foo

    ');\n var viewElem = Ember.$('#menu').children();\n\n view = View.create();\n\n ok(viewElem.length === 1, \"should have one element\");\n\n Ember.run(function() {\n view.replaceIn('#menu');\n });\n\n ok(viewElem.length === 1, \"should have one element\");\n\n});\n\ntest(\"should move the view to the inDOM state after replacing\", function() {\n Ember.$(\"#qunit-fixture\").html('
    ');\n view = View.create();\n\n Ember.run(function() {\n view.replaceIn('#menu');\n });\n\n equal(view.currentState, Ember.View.states.inDOM, \"the view is in the inDOM state\");\n});\n\nmodule(\"Ember.View - replaceIn() in a view hierarchy\", {\n setup: function() {\n View = Ember.ContainerView.extend({\n childViews: ['child'],\n child: Ember.View.extend({\n elementId: 'child'\n })\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n view.destroy();\n });\n }\n});\n\ntest(\"should be added to the specified element when calling replaceIn()\", function() {\n Ember.$(\"#qunit-fixture\").html('
    ');\n\n view = View.create();\n\n ok(!get(view, 'element'), \"precond - should not have an element\");\n\n Ember.run(function() {\n view.replaceIn('#menu');\n });\n\n var viewElem = Ember.$('#menu #child');\n ok(viewElem.length > 0, \"creates and replaces the view's element\");\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/replace_in_test");minispade.register('ember-views/~tests/views/view/template_test', "(function() {var set = Ember.set, get = Ember.get, container, view;\n\nmodule(\"Ember.View - Template Functionality\", {\n setup: function() {\n container = new Ember.Container();\n container.optionsForType('template', { instantiate: false });\n },\n teardown: function() {\n Ember.run(function() {\n if (view) { view.destroy(); }\n });\n }\n});\n\ntest(\"should call the function of the associated template\", function() {\n container.register('template:testTemplate', function() {\n return \"

    template was called

    \";\n });\n\n view = Ember.View.create({\n container: container,\n templateName: 'testTemplate'\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n ok(view.$('#twas-called').length, \"the named template was called\");\n});\n\ntest(\"should call the function of the associated template with itself as the context\", function() {\n container.register('template:testTemplate', function(dataSource) {\n return \"

    template was called for \" + get(dataSource, 'personName') + \"

    \";\n });\n\n view = Ember.View.create({\n container: container,\n templateName: 'testTemplate',\n\n context: {\n personName: \"Tom DAAAALE\"\n }\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(\"template was called for Tom DAAAALE\", view.$('#twas-called').text(), \"the named template was called with the view as the data source\");\n});\n\ntest(\"should fall back to defaultTemplate if neither template nor templateName are provided\", function() {\n var View;\n\n View = Ember.View.extend({\n defaultTemplate: function(dataSource) { return \"

    template was called for \" + get(dataSource, 'personName') + \"

    \"; }\n });\n\n view = View.create({\n context: {\n personName: \"Tom DAAAALE\"\n }\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(\"template was called for Tom DAAAALE\", view.$('#twas-called').text(), \"the named template was called with the view as the data source\");\n});\n\ntest(\"should not use defaultTemplate if template is provided\", function() {\n var View;\n\n View = Ember.View.extend({\n template: function() { return \"foo\"; },\n defaultTemplate: function(dataSource) { return \"

    template was called for \" + get(dataSource, 'personName') + \"

    \"; }\n });\n\n view = View.create();\n Ember.run(function() {\n view.createElement();\n });\n\n equal(\"foo\", view.$().text(), \"default template was not printed\");\n});\n\ntest(\"should not use defaultTemplate if template is provided\", function() {\n var View;\n\n container.register('template:foobar', function() { return 'foo'; });\n\n View = Ember.View.extend({\n container: container,\n templateName: 'foobar',\n defaultTemplate: function(dataSource) { return \"

    template was called for \" + get(dataSource, 'personName') + \"

    \"; }\n });\n\n view = View.create();\n Ember.run(function() {\n view.createElement();\n });\n\n equal(\"foo\", view.$().text(), \"default template was not printed\");\n});\n\ntest(\"should render an empty element if no template is specified\", function() {\n view = Ember.View.create();\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.$().html(), '', \"view div should be empty\");\n});\n\ntest(\"should provide a controller to the template if a controller is specified on the view\", function() {\n expect(7);\n\n var Controller1 = Ember.Object.extend({\n toString: function() { return \"Controller1\"; }\n });\n\n var Controller2 = Ember.Object.extend({\n toString: function() { return \"Controller2\"; }\n });\n\n var controller1 = Controller1.create(),\n controller2 = Controller2.create(),\n optionsDataKeywordsControllerForView,\n optionsDataKeywordsControllerForChildView,\n contextForView,\n contextForControllerlessView;\n\n view = Ember.View.create({\n controller: controller1,\n\n template: function(buffer, options) {\n optionsDataKeywordsControllerForView = options.data.keywords.controller;\n }\n });\n\n Ember.run(function() {\n view.appendTo('#qunit-fixture');\n });\n\n strictEqual(optionsDataKeywordsControllerForView, controller1, \"passes the controller in the data\");\n\n Ember.run(function() {\n view.destroy();\n });\n\n var parentView = Ember.View.create({\n controller: controller1,\n\n template: function(buffer, options) {\n options.data.view.appendChild(Ember.View.create({\n controller: controller2,\n templateData: options.data,\n template: function(context, options) {\n contextForView = context;\n optionsDataKeywordsControllerForChildView = options.data.keywords.controller;\n }\n }));\n optionsDataKeywordsControllerForView = options.data.keywords.controller;\n }\n });\n\n Ember.run(function() {\n parentView.appendTo('#qunit-fixture');\n });\n\n strictEqual(optionsDataKeywordsControllerForView, controller1, \"passes the controller in the data\");\n strictEqual(optionsDataKeywordsControllerForChildView, controller2, \"passes the child view's controller in the data\");\n\n Ember.run(function() {\n parentView.destroy();\n });\n\n var parentViewWithControllerlessChild = Ember.View.create({\n controller: controller1,\n\n template: function(buffer, options) {\n options.data.view.appendChild(Ember.View.create({\n templateData: options.data,\n template: function(context, options) {\n contextForControllerlessView = context;\n optionsDataKeywordsControllerForChildView = options.data.keywords.controller;\n }\n }));\n optionsDataKeywordsControllerForView = options.data.keywords.controller;\n }\n });\n\n Ember.run(function() {\n parentViewWithControllerlessChild.appendTo('#qunit-fixture');\n });\n\n strictEqual(optionsDataKeywordsControllerForView, controller1, \"passes the original controller in the data\");\n strictEqual(optionsDataKeywordsControllerForChildView, controller1, \"passes the controller in the data to child views\");\n strictEqual(contextForView, controller2, \"passes the controller in as the main context of the parent view\");\n strictEqual(contextForControllerlessView, controller1, \"passes the controller in as the main context of the child view\");\n\n Ember.run(function() {\n parentView.destroy();\n parentViewWithControllerlessChild.destroy();\n });\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/template_test");minispade.register('ember-views/~tests/views/view/view_lifecycle_test', "(function() {/*global ViewTest:true*/\n\nvar originalLookup = Ember.lookup, lookup, view;\n\nmodule(\"views/view/view_lifecycle_test - pre-render\", {\n setup: function() {\n Ember.lookup = lookup = {};\n },\n\n teardown: function() {\n if (view) {\n Ember.run(function() {\n view.destroy();\n });\n }\n Ember.lookup = originalLookup;\n }\n});\n\nfunction tmpl(str) {\n return function(context, options) {\n options.data.buffer.push(str);\n };\n}\n\ntest(\"should create and append a DOM element after bindings have synced\", function() {\n var ViewTest;\n\n lookup.ViewTest = ViewTest = {};\n\n Ember.run(function() {\n ViewTest.fakeController = Ember.Object.create({\n fakeThing: 'controllerPropertyValue'\n });\n\n view = Ember.View.createWithMixins({\n fooBinding: 'ViewTest.fakeController.fakeThing',\n\n render: function(buffer) {\n buffer.push(this.get('foo'));\n }\n });\n\n ok(!view.get('element'), \"precond - does not have an element before appending\");\n\n view.append();\n });\n\n equal(view.$().text(), 'controllerPropertyValue', \"renders and appends after bindings have synced\");\n});\n\ntest(\"should throw an exception if trying to append a child before rendering has begun\", function() {\n Ember.run(function() {\n view = Ember.View.create();\n });\n\n raises(function() {\n view.appendChild(Ember.View, {});\n }, null, \"throws an error when calling appendChild()\");\n});\n\ntest(\"should not affect rendering if rerender is called before initial render happens\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: tmpl(\"Rerender me!\")\n });\n\n view.rerender();\n view.append();\n });\n\n equal(view.$().text(), \"Rerender me!\", \"renders correctly if rerender is called first\");\n});\n\ntest(\"should not affect rendering if destroyElement is called before initial render happens\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: tmpl(\"Don't destroy me!\")\n });\n\n view.destroyElement();\n view.append();\n });\n\n equal(view.$().text(), \"Don't destroy me!\", \"renders correctly if destroyElement is called first\");\n});\n\nmodule(\"views/view/view_lifecycle_test - in render\", {\n setup: function() {\n\n },\n\n teardown: function() {\n if (view) {\n Ember.run(function() {\n view.destroy();\n });\n }\n }\n});\n\ntest(\"appendChild should work inside a template\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: function(context, options) {\n var buffer = options.data.buffer;\n\n buffer.push(\"

    Hi!

    \");\n\n options.data.view.appendChild(Ember.View, {\n template: tmpl(\"Inception reached\")\n });\n\n buffer.push(\"\");\n }\n });\n\n view.appendTo(\"#qunit-fixture\");\n });\n\n ok(view.$('h1').length === 1 && view.$('div').length === 2,\n \"The appended child is visible\");\n});\n\ntest(\"rerender should throw inside a template\", function() {\n raises(function() {\n Ember.run(function() {\n var renderCount = 0;\n view = Ember.View.create({\n template: function(context, options) {\n var view = options.data.view;\n\n var child1 = view.appendChild(Ember.View, {\n template: function(context, options) {\n renderCount++;\n options.data.buffer.push(String(renderCount));\n }\n });\n\n var child2 = view.appendChild(Ember.View, {\n template: function(context, options) {\n options.data.buffer.push(\"Inside child2\");\n child1.rerender();\n }\n });\n }\n });\n\n view.appendTo(\"#qunit-fixture\");\n });\n }, /Something you did caused a view to re-render after it rendered but before it was inserted into the DOM./);\n});\n\nmodule(\"views/view/view_lifecycle_test - hasElement\", {\n teardown: function() {\n if (view) {\n Ember.run(function() {\n view.destroy();\n });\n }\n }\n});\n\ntest(\"createElement puts the view into the hasElement state\", function() {\n view = Ember.View.create({\n render: function(buffer) { buffer.push('hello'); }\n });\n\n Ember.run(function() {\n view.createElement();\n });\n\n equal(view.currentState, Ember.View.states.hasElement, \"the view is in the hasElement state\");\n});\n\ntest(\"trigger rerender on a view in the hasElement state doesn't change its state to inDOM\", function() {\n view = Ember.View.create({\n render: function(buffer) { buffer.push('hello'); }\n });\n\n Ember.run(function() {\n view.createElement();\n view.rerender();\n });\n\n equal(view.currentState, Ember.View.states.hasElement, \"the view is still in the hasElement state\");\n});\n\n\nmodule(\"views/view/view_lifecycle_test - in DOM\", {\n teardown: function() {\n if (view) {\n Ember.run(function() {\n view.destroy();\n });\n }\n }\n});\n\ntest(\"should throw an exception when calling appendChild when DOM element exists\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: tmpl(\"Wait for the kick\")\n });\n\n view.append();\n });\n\n raises(function() {\n view.appendChild(Ember.View, {\n template: tmpl(\"Ah ah ah! You didn't say the magic word!\")\n });\n }, null, \"throws an exception when calling appendChild after element is created\");\n});\n\ntest(\"should replace DOM representation if rerender() is called after element is created\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: function(context, options) {\n var buffer = options.data.buffer;\n var value = context.get('shape');\n\n buffer.push(\"Do not taunt happy fun \"+value);\n },\n\n context: Ember.Object.create({\n shape: 'sphere'\n })\n });\n\n view.append();\n });\n\n equal(view.$().text(), \"Do not taunt happy fun sphere\", \"precond - creates DOM element\");\n\n view.set('context.shape', 'ball');\n Ember.run(function() {\n view.rerender();\n });\n\n equal(view.$().text(), \"Do not taunt happy fun ball\", \"rerenders DOM element when rerender() is called\");\n});\n\ntest(\"should destroy DOM representation when destroyElement is called\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: tmpl(\"Don't fear the reaper\")\n });\n\n view.append();\n });\n\n ok(view.get('element'), \"precond - generates a DOM element\");\n\n Ember.run(function() {\n view.destroyElement();\n });\n\n ok(!view.get('element'), \"destroys view when destroyElement() is called\");\n});\n\ntest(\"should destroy DOM representation when destroy is called\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: tmpl(\"
    Don't fear the reaper
    \")\n });\n\n view.append();\n });\n\n ok(view.get('element'), \"precond - generates a DOM element\");\n\n Ember.run(function() {\n view.destroy();\n });\n\n ok(Ember.$('#warning').length === 0, \"destroys element when destroy() is called\");\n});\n\ntest(\"should throw an exception if trying to append an element that is already in DOM\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: tmpl('Broseidon, King of the Brocean')\n });\n\n view.append();\n });\n\n ok(view.get('element'), \"precond - creates DOM element\");\n\n raises(function() {\n Ember.run(function() {\n view.append();\n });\n }, null, \"raises an exception on second append\");\n});\n\nmodule(\"views/view/view_lifecycle_test - destroyed\");\n\ntest(\"should throw an exception when calling appendChild after view is destroyed\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: tmpl(\"Wait for the kick\")\n });\n\n view.append();\n });\n\n Ember.run(function() {\n view.destroy();\n });\n\n raises(function() {\n view.appendChild(Ember.View, {\n template: tmpl(\"Ah ah ah! You didn't say the magic word!\")\n });\n }, null, \"throws an exception when calling appendChild\");\n});\n\ntest(\"should throw an exception when rerender is called after view is destroyed\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: tmpl('foo')\n });\n\n view.append();\n });\n\n Ember.run(function() {\n view.destroy();\n });\n\n raises(function() {\n view.rerender();\n }, null, \"throws an exception when calling rerender\");\n});\n\ntest(\"should throw an exception when destroyElement is called after view is destroyed\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: tmpl('foo')\n });\n\n view.append();\n });\n\n Ember.run(function() {\n view.destroy();\n });\n\n raises(function() {\n view.destroyElement();\n }, null, \"throws an exception when calling destroyElement\");\n});\n\ntest(\"trigger rerender on a view in the inDOM state keeps its state as inDOM\", function() {\n Ember.run(function() {\n view = Ember.View.create({\n template: tmpl('foo')\n });\n\n view.append();\n });\n\n Ember.run(function() {\n view.rerender();\n });\n\n equal(view.currentState, Ember.View.states.inDOM, \"the view is still in the inDOM state\");\n\n Ember.run(function() {\n view.destroy();\n });\n});\n\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/view_lifecycle_test");minispade.register('ember-views/~tests/views/view/virtual_views_test', "(function() {var get = Ember.get, set = Ember.set, rootView, childView;\n\nmodule(\"virtual views\", {\n teardown: function() {\n Ember.run(function() {\n rootView.destroy();\n childView.destroy();\n });\n }\n});\n\ntest(\"a virtual view does not appear as a view's parentView\", function() {\n rootView = Ember.View.create({\n elementId: 'root-view',\n\n render: function(buffer) {\n buffer.push(\"

    Hi

    \");\n this.appendChild(virtualView);\n }\n });\n\n var virtualView = Ember.View.create({\n isVirtual: true,\n tagName: '',\n\n render: function(buffer) {\n buffer.push(\"

    Virtual

    \");\n this.appendChild(childView);\n }\n });\n\n childView = Ember.View.create({\n render: function(buffer) {\n buffer.push(\"

    Bye!

    \");\n }\n });\n\n Ember.run(function() {\n Ember.$(\"#qunit-fixture\").empty();\n rootView.appendTo(\"#qunit-fixture\");\n });\n\n equal(Ember.$(\"#root-view > h2\").length, 1, \"nodes with '' tagName do not create wrappers\");\n equal(get(childView, 'parentView'), rootView);\n\n var children = get(rootView, 'childViews');\n\n equal(get(children, 'length'), 1, \"there is one child element\");\n equal(children.objectAt(0), childView, \"the child element skips through the virtual view\");\n});\n\ntest(\"when a virtual view's child views change, the parent's childViews should reflect\", function() {\n rootView = Ember.View.create({\n elementId: 'root-view',\n\n render: function(buffer) {\n buffer.push(\"

    Hi

    \");\n this.appendChild(virtualView);\n }\n });\n\n var virtualView = Ember.View.create({\n isVirtual: true,\n tagName: '',\n\n render: function(buffer) {\n buffer.push(\"

    Virtual

    \");\n this.appendChild(childView);\n }\n });\n\n childView = Ember.View.create({\n render: function(buffer) {\n buffer.push(\"

    Bye!

    \");\n }\n });\n\n Ember.run(function() {\n Ember.$(\"#qunit-fixture\").empty();\n rootView.appendTo(\"#qunit-fixture\");\n });\n\n equal(virtualView.get('childViews.length'), 1, \"has childView - precond\");\n equal(rootView.get('childViews.length'), 1, \"has childView - precond\");\n\n Ember.run(function() {\n childView.removeFromParent();\n });\n\n equal(virtualView.get('childViews.length'), 0, \"has no childView\");\n equal(rootView.get('childViews.length'), 0, \"has no childView\");\n});\n\n})();\n//@ sourceURL=ember-views/~tests/views/view/virtual_views_test");minispade.register('ember/~tests/application_lifecycle', "(function() {var App, container, router;\n\nmodule(\"Application Lifecycle\", {\n setup: function() {\n Ember.run(function() {\n App = Ember.Application.create({\n rootElement: '#qunit-fixture'\n });\n\n App.Router.extend({\n location: 'none'\n });\n\n App.deferReadiness();\n\n container = App.__container__;\n });\n },\n\n teardown: function() {\n router = null;\n Ember.run(App, 'destroy');\n }\n});\n\nfunction handleURL(path) {\n router = container.lookup('router:main');\n return Ember.run(function() {\n return router.handleURL(path).then(function(value) {\n ok(true, 'url: `' + path + '` was handled');\n return value;\n }, function(reason) {\n ok(false, reason);\n throw reason;\n });\n });\n}\n\n\ntest(\"Resetting the application allows controller properties to be set when a route deactivates\", function() {\n App.Router.map(function() {\n this.route('home', { path: '/' });\n });\n\n App.HomeRoute = Ember.Route.extend({\n setupController: function() {\n this.controllerFor('home').set('selectedMenuItem', 'home');\n },\n deactivate: function() {\n this.controllerFor('home').set('selectedMenuItem', null);\n }\n });\n App.ApplicationRoute = Ember.Route.extend({\n setupController: function() {\n this.controllerFor('application').set('selectedMenuItem', 'home');\n },\n deactivate: function() {\n this.controllerFor('application').set('selectedMenuItem', null);\n }\n });\n\n var router = container.lookup('router:main');\n\n Ember.run(App, 'advanceReadiness');\n\n handleURL('/');\n\n equal(Ember.controllerFor(container, 'home').get('selectedMenuItem'), 'home');\n equal(Ember.controllerFor(container, 'application').get('selectedMenuItem'), 'home');\n\n App.reset();\n\n equal(Ember.controllerFor(container, 'home').get('selectedMenuItem'), null);\n equal(Ember.controllerFor(container, 'application').get('selectedMenuItem'), null);\n});\n\n})();\n//@ sourceURL=ember/~tests/application_lifecycle");minispade.register('ember/~tests/component_registration_test', "(function() {var App, container;\nvar compile = Ember.Handlebars.compile;\n\nmodule(\"Application Lifecycle - Component Registration\", {\n setup: function() {\n Ember.TEMPLATES[\"components/expand-it\"] = compile(\"

    hello {{yield}}

    \");\n Ember.TEMPLATES.application = compile(\"Hello world {{#expand-it}}world{{/expand-it}}\");\n },\n\n teardown: function() {\n Ember.run(function() {\n App.destroy();\n App = null;\n Ember.TEMPLATES = {};\n });\n }\n});\n\nfunction boot(callback) {\n Ember.run(function() {\n App = Ember.Application.create({\n name: 'App',\n rootElement: '#qunit-fixture'\n });\n\n App.deferReadiness();\n\n App.Router = Ember.Router.extend({\n location: 'none'\n });\n\n container = App.__container__;\n\n if (callback) { callback(); }\n });\n\n var router = container.lookup('router:main');\n\n Ember.run(App, 'advanceReadiness');\n Ember.run(function() {\n router.handleURL('/');\n });\n}\n\nif (!Ember.FEATURES.isEnabled('container-renderables')) {\n test(\"A helper is registered for templates under the components/ directory\", function() {\n boot();\n ok(Ember.Handlebars.helpers['expand-it'], \"The helper is registered\");\n });\n}\n\ntest(\"The helper becomes the body of the component\", function() {\n boot();\n equal(Ember.$('div.ember-view > div.ember-view', '#qunit-fixture').text(), \"hello world\", \"The component is composed correctly\");\n});\n\ntest(\"If a component is registered, it is used\", function() {\n boot(function() {\n container.register('component:expand-it', Ember.Component.extend({\n classNames: 'testing123'\n }));\n });\n\n equal(Ember.$('div.testing123', '#qunit-fixture').text(), \"hello world\", \"The component is composed correctly\");\n});\n\nif (Ember.FEATURES.isEnabled('container-renderables')) {\n\n test(\"Late-registered components can be rendered with custom `template` property\", function() {\n\n Ember.TEMPLATES.application = compile(\"
    there goes {{my-hero}}
    \");\n\n boot(function() {\n container.register('component:my-hero', Ember.Component.extend({\n classNames: 'testing123',\n template: function() { return \"watch him as he GOES\"; }\n }));\n });\n\n equal(Ember.$('#wrapper').text(), \"there goes watch him as he GOES\", \"The component is composed correctly\");\n ok(!Ember.Handlebars.helpers['my-hero'], \"Component wasn't saved to global Handlebars.helpers hash\");\n });\n\n test(\"Late-registered components can be rendered with template registered on the container\", function() {\n\n Ember.TEMPLATES.application = compile(\"
    hello world {{sally-rutherford}} {{#sally-rutherford}}!!!{{/sally-rutherford}}
    \");\n\n boot(function() {\n container.register('template:components/sally-rutherford', compile(\"funkytowny{{yield}}\"));\n container.register('component:sally-rutherford', Ember.Component);\n });\n\n equal(Ember.$('#wrapper').text(), \"hello world funkytowny funkytowny!!!\", \"The component is composed correctly\");\n ok(!Ember.Handlebars.helpers['sally-rutherford'], \"Component wasn't saved to global Handlebars.helpers hash\");\n });\n\n test(\"Late-registered components can be rendered with ONLY the template registered on the container\", function() {\n\n Ember.TEMPLATES.application = compile(\"
    hello world {{borf-snorlax}} {{#borf-snorlax}}!!!{{/borf-snorlax}}
    \");\n\n boot(function() {\n container.register('template:components/borf-snorlax', compile(\"goodfreakingTIMES{{yield}}\"));\n });\n\n equal(Ember.$('#wrapper').text(), \"hello world goodfreakingTIMES goodfreakingTIMES!!!\", \"The component is composed correctly\");\n ok(!Ember.Handlebars.helpers['borf-snorlax'], \"Component wasn't saved to global Handlebars.helpers hash\");\n });\n\n test(\"Component-like invocations are treated as bound paths if neither template nor component are registered on the container\", function() {\n\n Ember.TEMPLATES.application = compile(\"
    {{user-name}} hello {{api-key}} world
    \");\n\n boot(function() {\n container.register('controller:application', Ember.Controller.extend({\n 'user-name': 'machty'\n }));\n });\n\n equal(Ember.$('#wrapper').text(), \"machty hello world\", \"The component is composed correctly\");\n });\n\n test(\"Component lookups should take place on components' subcontainers\", function() {\n\n expect(1);\n\n Ember.TEMPLATES.application = compile(\"
    {{#sally-rutherford}}{{mach-ty}}{{/sally-rutherford}}
    \");\n\n boot(function() {\n container.register('component:sally-rutherford', Ember.Component.extend({\n init: function() {\n this._super();\n this.container = new Ember.Container(this.container);\n this.container.register('component:mach-ty', Ember.Component.extend({\n didInsertElement: function() {\n ok(true, \"mach-ty was rendered\");\n }\n }));\n }\n }));\n });\n });\n}\n\n})();\n//@ sourceURL=ember/~tests/component_registration_test");minispade.register('ember/~tests/helpers/helper_registration_test', "(function() {var App, container;\nvar compile = Ember.Handlebars.compile;\n\nfunction reverseHelper(value) {\n return arguments.length > 1 ? value.split('').reverse().join('') : \"--\";\n}\n\nif (Ember.FEATURES.isEnabled('container-renderables')) {\n\n module(\"Application Lifecycle - Helper Registration\", {\n teardown: function() {\n Ember.run(function() {\n App.destroy();\n App = null;\n Ember.TEMPLATES = {};\n });\n }\n });\n\n var boot = function(callback) {\n Ember.run(function() {\n App = Ember.Application.create({\n name: 'App',\n rootElement: '#qunit-fixture'\n });\n\n App.deferReadiness();\n\n App.Router = Ember.Router.extend({\n location: 'none'\n });\n\n container = App.__container__;\n\n if (callback) { callback(); }\n });\n\n var router = container.lookup('router:main');\n\n Ember.run(App, 'advanceReadiness');\n Ember.run(function() {\n router.handleURL('/');\n });\n };\n\n test(\"Unbound dashed helpers registered on the container can be late-invoked\", function() {\n\n Ember.TEMPLATES.application = compile(\"
    {{x-borf}} {{x-borf YES}}
    \");\n\n boot(function() {\n container.register('helper:x-borf', function(val) {\n return arguments.length > 1 ? val : \"BORF\";\n });\n });\n\n equal(Ember.$('#wrapper').text(), \"BORF YES\", \"The helper was invoked from the container\");\n ok(!Ember.Handlebars.helpers['x-borf'], \"Container-registered helper doesn't wind up on global helpers hash\");\n });\n\n test(\"Bound helpers registered on the container can be late-invoked\", function() {\n\n Ember.TEMPLATES.application = compile(\"
    {{x-reverse}} {{x-reverse foo}}
    \");\n\n boot(function() {\n container.register('controller:application', Ember.Controller.extend({\n foo: \"alex\"\n }));\n container.register('helper:x-reverse', Ember.Handlebars.makeBoundHelper(reverseHelper));\n });\n\n equal(Ember.$('#wrapper').text(), \"-- xela\", \"The bound helper was invoked from the container\");\n ok(!Ember.Handlebars.helpers['x-reverse'], \"Container-registered helper doesn't wind up on global helpers hash\");\n });\n\n test(\"Undashed helpers registered on the container can not (presently) be invoked\", function() {\n\n var realHelperMissing = Ember.Handlebars.helpers.helperMissing;\n Ember.Handlebars.helpers.helperMissing = function() {\n return \"NOHALPER\";\n };\n\n // Note: the reason we're not allowing undashed helpers is to avoid\n // a possible perf hit in hot code paths, i.e. _triageMustache.\n // We only presently perform container lookups if prop.indexOf('-') >= 0\n\n Ember.TEMPLATES.application = compile(\"
    {{omg}}|{{omg 'GRRR'}}|{{yorp}}|{{yorp 'ahh'}}
    \");\n\n boot(function() {\n container.register('helper:omg', function() {\n return \"OMG\";\n });\n container.register('helper:yorp', Ember.Handlebars.makeBoundHelper(function() {\n return \"YORP\";\n }));\n });\n\n equal(Ember.$('#wrapper').text(), \"|NOHALPER||NOHALPER\", \"The undashed helper was invoked from the container\");\n\n Ember.Handlebars.helpers.helperMissing = realHelperMissing;\n });\n}\n\n})();\n//@ sourceURL=ember/~tests/helpers/helper_registration_test");minispade.register('ember/~tests/helpers/link_to_test', "(function() {var Router, App, AppView, templates, router, eventDispatcher, container;\nvar get = Ember.get, set = Ember.set, map = Ember.ArrayPolyfills.map;\n\nfunction bootApplication() {\n router = container.lookup('router:main');\n Ember.run(App, 'advanceReadiness');\n}\n\n// IE includes the host name\nfunction normalizeUrl(url) {\n return url.replace(/https?:\\/\\/[^\\/]+/,'');\n}\n\nfunction compile(template) {\n return Ember.Handlebars.compile(template);\n}\n\nfunction shouldNotBeActive(selector) {\n checkActive(selector, false);\n}\n\nfunction shouldBeActive(selector) {\n checkActive(selector, true);\n}\n\nfunction checkActive(selector, active) {\n var classList = Ember.$(selector, '#qunit-fixture')[0].classList;\n equal(classList.contains('active'), active, selector + \" active should be \" + active.toString());\n\n}\n\nmodule(\"The {{link-to}} helper\", {\n setup: function() {\n Ember.run(function() {\n App = Ember.Application.create({\n name: \"App\",\n rootElement: '#qunit-fixture'\n });\n\n App.deferReadiness();\n\n App.Router.reopen({\n location: 'none'\n });\n\n Router = App.Router;\n\n Ember.TEMPLATES.app = Ember.Handlebars.compile(\"{{outlet}}\");\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"

    Home

    {{#link-to 'about' id='about-link'}}About{{/link-to}}{{#link-to 'index' id='self-link'}}Self{{/link-to}}\");\n Ember.TEMPLATES.about = Ember.Handlebars.compile(\"

    About

    {{#link-to 'index' id='home-link'}}Home{{/link-to}}{{#link-to 'about' id='self-link'}}Self{{/link-to}}\");\n Ember.TEMPLATES.item = Ember.Handlebars.compile(\"

    Item

    {{name}}

    {{#link-to 'index' id='home-link'}}Home{{/link-to}}\");\n\n AppView = Ember.View.extend({\n templateName: 'app'\n });\n\n container = App.__container__;\n\n container.register('view:app', AppView);\n container.register('router:main', Router);\n });\n },\n\n teardown: function() {\n Ember.run(function() { App.destroy(); });\n Ember.TEMPLATES = {};\n }\n});\n\ntest(\"The {{link-to}} helper moves into the named route\", function() {\n Router.map(function(match) {\n this.route(\"about\");\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n equal(Ember.$('h3:contains(Home)', '#qunit-fixture').length, 1, \"The home template was rendered\");\n equal(Ember.$('#self-link.active', '#qunit-fixture').length, 1, \"The self-link was rendered with active class\");\n equal(Ember.$('#about-link:not(.active)', '#qunit-fixture').length, 1, \"The other link was rendered without active class\");\n\n Ember.run(function() {\n Ember.$('#about-link', '#qunit-fixture').click();\n });\n\n equal(Ember.$('h3:contains(About)', '#qunit-fixture').length, 1, \"The about template was rendered\");\n equal(Ember.$('#self-link.active', '#qunit-fixture').length, 1, \"The self-link was rendered with active class\");\n equal(Ember.$('#home-link:not(.active)', '#qunit-fixture').length, 1, \"The other link was rendered without active class\");\n});\n\ntest(\"The {{link-to}} helper supports URL replacement\", function() {\n var setCount = 0,\n replaceCount = 0;\n\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"

    Home

    {{#link-to 'about' id='about-link' replace=true}}About{{/link-to}}\");\n\n Router.reopen({\n location: Ember.NoneLocation.createWithMixins({\n setURL: function(path) {\n setCount++;\n set(this, 'path', path);\n },\n\n replaceURL: function(path) {\n replaceCount++;\n set(this, 'path', path);\n }\n })\n });\n\n Router.map(function() {\n this.route(\"about\");\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n equal(setCount, 0, 'precond: setURL has not been called');\n equal(replaceCount, 0, 'precond: replaceURL has not been called');\n\n Ember.run(function() {\n Ember.$('#about-link', '#qunit-fixture').click();\n });\n\n equal(setCount, 0, 'setURL should not be called');\n equal(replaceCount, 1, 'replaceURL should be called once');\n});\n\ntest(\"the {{link-to}} helper doesn't add an href when the tagName isn't 'a'\", function() {\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"{{#link-to 'about' id='about-link' tagName='div'}}About{{/link-to}}\");\n\n Router.map(function() {\n this.route(\"about\");\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n equal(Ember.$('#about-link').attr('href'), undefined, \"there is no href attribute\");\n});\n\n\ntest(\"the {{link-to}} applies a 'disabled' class when disabled\", function () {\n Ember.TEMPLATES.index = Ember.Handlebars.compile('{{#link-to \"about\" id=\"about-link\" disabledWhen=\"shouldDisable\"}}About{{/link-to}}');\n App.IndexController = Ember.Controller.extend({\n shouldDisable: true\n });\n\n Router.map(function() {\n this.route(\"about\");\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n equal(Ember.$('#about-link.disabled', '#qunit-fixture').length, 1, \"The link is disabled when its disabledWhen is true\");\n});\n\ntest(\"the {{link-to}} doesn't apply a 'disabled' class if disabledWhen is not provided\", function () {\n Ember.TEMPLATES.index = Ember.Handlebars.compile('{{#link-to \"about\" id=\"about-link\"}}About{{/link-to}}');\n\n Router.map(function() {\n this.route(\"about\");\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n ok(!Ember.$('#about-link', '#qunit-fixture').hasClass(\"disabled\"), \"The link is not disabled if disabledWhen not provided\");\n});\n\ntest(\"the {{link-to}} helper supports a custom disabledClass\", function () {\n Ember.TEMPLATES.index = Ember.Handlebars.compile('{{#link-to \"about\" id=\"about-link\" disabledWhen=\"shouldDisable\" disabledClass=\"do-not-want\"}}About{{/link-to}}');\n App.IndexController = Ember.Controller.extend({\n shouldDisable: true\n });\n\n Router.map(function() {\n this.route(\"about\");\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n equal(Ember.$('#about-link.do-not-want', '#qunit-fixture').length, 1, \"The link can apply a custom disabled class\");\n\n});\n\ntest(\"the {{link-to}} helper does not respond to clicks when disabled\", function () {\n Ember.TEMPLATES.index = Ember.Handlebars.compile('{{#link-to \"about\" id=\"about-link\" disabledWhen=\"shouldDisable\"}}About{{/link-to}}');\n App.IndexController = Ember.Controller.extend({\n shouldDisable: true\n });\n\n Router.map(function() {\n this.route(\"about\");\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n Ember.run(function() {\n Ember.$('#about-link', '#qunit-fixture').click();\n });\n\n equal(Ember.$('h3:contains(About)', '#qunit-fixture').length, 0, \"Transitioning did not occur\");\n});\n\ntest(\"The {{link-to}} helper supports a custom activeClass\", function() {\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"

    Home

    {{#link-to 'about' id='about-link'}}About{{/link-to}}{{#link-to 'index' id='self-link' activeClass='zomg-active'}}Self{{/link-to}}\");\n\n Router.map(function() {\n this.route(\"about\");\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n equal(Ember.$('h3:contains(Home)', '#qunit-fixture').length, 1, \"The home template was rendered\");\n equal(Ember.$('#self-link.zomg-active', '#qunit-fixture').length, 1, \"The self-link was rendered with active class\");\n equal(Ember.$('#about-link:not(.active)', '#qunit-fixture').length, 1, \"The other link was rendered without active class\");\n});\n\ntest(\"The {{link-to}} helper supports leaving off .index for nested routes\", function() {\n Router.map(function() {\n this.resource(\"about\", function() {\n this.route(\"item\");\n });\n });\n\n Ember.TEMPLATES.about = compile(\"

    About

    {{outlet}}\");\n Ember.TEMPLATES['about/index'] = compile(\"
    Index
    \");\n Ember.TEMPLATES['about/item'] = compile(\"
    {{#link-to 'about'}}About{{/link-to}}
    \");\n\n bootApplication();\n\n Ember.run(router, 'handleURL', '/about/item');\n\n equal(normalizeUrl(Ember.$('#item a', '#qunit-fixture').attr('href')), '/about');\n});\n\ntest(\"The {{link-to}} helper supports custom, nested, currentWhen\", function() {\n Router.map(function(match) {\n this.resource(\"index\", { path: \"/\" }, function() {\n this.route(\"about\");\n });\n\n this.route(\"item\");\n });\n\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"

    Home

    {{outlet}}\");\n Ember.TEMPLATES['index/about'] = Ember.Handlebars.compile(\"{{#link-to 'item' id='other-link' currentWhen='index'}}ITEM{{/link-to}}\");\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/about\");\n });\n\n equal(Ember.$('#other-link.active', '#qunit-fixture').length, 1, \"The link is active since currentWhen is a parent route\");\n});\n\ntest(\"The {{link-to}} helper defaults to bubbling\", function() {\n Ember.TEMPLATES.about = Ember.Handlebars.compile(\"
    {{#link-to 'about.contact' id='about-contact'}}About{{/link-to}}
    {{outlet}}\");\n Ember.TEMPLATES['about/contact'] = Ember.Handlebars.compile(\"

    Contact

    \");\n\n Router.map(function() {\n this.resource(\"about\", function() {\n this.route(\"contact\");\n });\n });\n\n var hidden = 0;\n\n App.AboutRoute = Ember.Route.extend({\n actions: {\n hide: function() {\n hidden++;\n }\n }\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/about\");\n });\n\n Ember.run(function() {\n Ember.$('#about-contact', '#qunit-fixture').click();\n });\n\n equal(Ember.$(\"#contact\", \"#qunit-fixture\").text(), \"Contact\", \"precond - the link worked\");\n\n equal(hidden, 1, \"The link bubbles\");\n});\n\ntest(\"The {{link-to}} helper supports bubbles=false\", function() {\n Ember.TEMPLATES.about = Ember.Handlebars.compile(\"
    {{#link-to 'about.contact' id='about-contact' bubbles=false}}About{{/link-to}}
    {{outlet}}\");\n Ember.TEMPLATES['about/contact'] = Ember.Handlebars.compile(\"

    Contact

    \");\n\n Router.map(function() {\n this.resource(\"about\", function() {\n this.route(\"contact\");\n });\n });\n\n var hidden = 0;\n\n App.AboutRoute = Ember.Route.extend({\n actions: {\n hide: function() {\n hidden++;\n }\n }\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/about\");\n });\n\n Ember.run(function() {\n Ember.$('#about-contact', '#qunit-fixture').click();\n });\n\n equal(Ember.$(\"#contact\", \"#qunit-fixture\").text(), \"Contact\", \"precond - the link worked\");\n\n equal(hidden, 0, \"The link didn't bubble\");\n});\n\ntest(\"The {{link-to}} helper moves into the named route with context\", function() {\n Router.map(function(match) {\n this.route(\"about\");\n this.resource(\"item\", { path: \"/item/:id\" });\n });\n\n Ember.TEMPLATES.about = Ember.Handlebars.compile(\"

    List

      {{#each controller}}
    • {{#link-to 'item' this}}{{name}}{{/link-to}}
    • {{/each}}
    {{#link-to 'index' id='home-link'}}Home{{/link-to}}\");\n\n var people = {\n yehuda: \"Yehuda Katz\",\n tom: \"Tom Dale\",\n erik: \"Erik Brynroflsson\"\n };\n\n App.AboutRoute = Ember.Route.extend({\n model: function() {\n return Ember.A([\n { id: \"yehuda\", name: \"Yehuda Katz\" },\n { id: \"tom\", name: \"Tom Dale\" },\n { id: \"erik\", name: \"Erik Brynroflsson\" }\n ]);\n }\n });\n\n App.ItemRoute = Ember.Route.extend({\n serialize: function(object) {\n return { id: object.id };\n }\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/about\");\n });\n\n equal(Ember.$('h3:contains(List)', '#qunit-fixture').length, 1, \"The home template was rendered\");\n equal(normalizeUrl(Ember.$('#home-link').attr('href')), '/', \"The home link points back at /\");\n\n Ember.run(function() {\n Ember.$('li a:contains(Yehuda)', '#qunit-fixture').click();\n });\n\n equal(Ember.$('h3:contains(Item)', '#qunit-fixture').length, 1, \"The item template was rendered\");\n equal(Ember.$('p', '#qunit-fixture').text(), \"Yehuda Katz\", \"The name is correct\");\n\n Ember.run(function() { Ember.$('#home-link').click(); });\n Ember.run(function() { Ember.$('#about-link').click(); });\n\n equal(normalizeUrl(Ember.$('li a:contains(Yehuda)').attr('href')), \"/item/yehuda\");\n equal(normalizeUrl(Ember.$('li a:contains(Tom)').attr('href')), \"/item/tom\");\n equal(normalizeUrl(Ember.$('li a:contains(Erik)').attr('href')), \"/item/erik\");\n\n Ember.run(function() {\n Ember.$('li a:contains(Erik)', '#qunit-fixture').click();\n });\n\n equal(Ember.$('h3:contains(Item)', '#qunit-fixture').length, 1, \"The item template was rendered\");\n equal(Ember.$('p', '#qunit-fixture').text(), \"Erik Brynroflsson\", \"The name is correct\");\n});\n\ntest(\"The {{link-to}} helper binds some anchor html tag common attributes\", function() {\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"

    Home

    {{#link-to 'index' id='self-link' title='title-attr' rel='rel-attr'}}Self{{/link-to}}\");\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n var link = Ember.$('#self-link', '#qunit-fixture');\n equal(link.attr('title'), 'title-attr', \"The self-link contains title attribute\");\n equal(link.attr('rel'), 'rel-attr', \"The self-link contains rel attribute\");\n});\n\ntest(\"The {{link-to}} helper accepts string/numeric arguments\", function() {\n Router.map(function() {\n this.route('filter', { path: '/filters/:filter' });\n this.route('post', { path: '/post/:post_id' });\n this.route('repo', { path: '/repo/:owner/:name' });\n });\n\n App.FilterController = Ember.Controller.extend({\n filter: \"unpopular\",\n repo: Ember.Object.create({owner: 'ember', name: 'ember.js'}),\n post_id: 123\n });\n Ember.TEMPLATES.filter = compile('

    {{filter}}

    {{#link-to \"filter\" \"unpopular\" id=\"link\"}}Unpopular{{/link-to}}{{#link-to \"filter\" filter id=\"path-link\"}}Unpopular{{/link-to}}{{#link-to \"post\" post_id id=\"post-path-link\"}}Post{{/link-to}}{{#link-to \"post\" 123 id=\"post-number-link\"}}Post{{/link-to}}{{#link-to \"repo\" repo id=\"repo-object-link\"}}Repo{{/link-to}}');\n\n Ember.TEMPLATES.index = compile(' ');\n\n bootApplication();\n\n Ember.run(function() { router.handleURL(\"/filters/popular\"); });\n\n equal(normalizeUrl(Ember.$('#link', '#qunit-fixture').attr('href')), \"/filters/unpopular\");\n equal(normalizeUrl(Ember.$('#path-link', '#qunit-fixture').attr('href')), \"/filters/unpopular\");\n equal(normalizeUrl(Ember.$('#post-path-link', '#qunit-fixture').attr('href')), \"/post/123\");\n equal(normalizeUrl(Ember.$('#post-number-link', '#qunit-fixture').attr('href')), \"/post/123\");\n equal(normalizeUrl(Ember.$('#repo-object-link', '#qunit-fixture').attr('href')), \"/repo/ember/ember.js\");\n});\n\ntest(\"The {{link-to}} helper unwraps controllers\", function() {\n // The serialize hook is called thrice: once to generate the href for the\n // link, once to generate the URL when the link is clicked, and again\n // when the URL changes to check if query params have been updated\n expect(3);\n\n Router.map(function() {\n this.route('filter', { path: '/filters/:filter' });\n });\n\n var indexObject = { filter: 'popular' };\n\n App.FilterRoute = Ember.Route.extend({\n model: function(params) {\n return indexObject;\n },\n\n serialize: function(passedObject) {\n equal(passedObject, indexObject, \"The unwrapped object is passed\");\n return { filter: 'popular' };\n }\n });\n\n App.IndexRoute = Ember.Route.extend({\n model: function() {\n return indexObject;\n }\n });\n\n Ember.TEMPLATES.filter = compile('

    {{filter}}

    ');\n Ember.TEMPLATES.index = compile('{{#link-to \"filter\" this id=\"link\"}}Filter{{/link-to}}');\n\n bootApplication();\n\n Ember.run(function() { router.handleURL(\"/\"); });\n\n Ember.$('#link', '#qunit-fixture').trigger('click');\n});\n\ntest(\"The {{link-to}} helper doesn't change view context\", function() {\n App.IndexView = Ember.View.extend({\n elementId: 'index',\n name: 'test'\n });\n\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"{{view.name}}-{{#link-to 'index' id='self-link'}}Link: {{view.name}}{{/link-to}}\");\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n equal(Ember.$('#index', '#qunit-fixture').text(), 'test-Link: test', \"accesses correct view\");\n});\n\ntest(\"Quoteless route param performs property lookup\", function() {\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"{{#link-to 'index' id='string-link'}}string{{/link-to}}{{#link-to foo id='path-link'}}path{{/link-to}}{{#link-to view.foo id='view-link'}}{{view.foo}}{{/link-to}}\");\n\n function assertEquality(href) {\n equal(normalizeUrl(Ember.$('#string-link', '#qunit-fixture').attr('href')), '/');\n equal(normalizeUrl(Ember.$('#path-link', '#qunit-fixture').attr('href')), href);\n equal(normalizeUrl(Ember.$('#view-link', '#qunit-fixture').attr('href')), href);\n }\n\n App.IndexView = Ember.View.extend({\n foo: 'index',\n elementId: 'index-view'\n });\n\n App.IndexController = Ember.Controller.extend({\n foo: 'index'\n });\n\n App.Router.map(function() {\n this.route('about');\n });\n\n bootApplication();\n\n Ember.run(router, 'handleURL', '/');\n\n assertEquality('/');\n\n var controller = container.lookup('controller:index'),\n view = Ember.View.views['index-view'];\n Ember.run(function() {\n controller.set('foo', 'about');\n view.set('foo', 'about');\n });\n\n assertEquality('/about');\n});\n\ntest(\"link-to with null/undefined dynamic parameters are put in a loading state\", function() {\n\n expect(19);\n\n var oldWarn = Ember.Logger.warn, warnCalled = false;\n Ember.Logger.warn = function() { warnCalled = true; };\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"{{#link-to destinationRoute routeContext loadingClass='i-am-loading' id='context-link'}}string{{/link-to}}{{#link-to secondRoute loadingClass='i-am-loading' id='static-link'}}string{{/link-to}}\");\n\n var thing = Ember.Object.create({ id: 123 });\n\n App.IndexController = Ember.Controller.extend({\n destinationRoute: null,\n routeContext: null\n });\n\n App.AboutRoute = Ember.Route.extend({\n activate: function() {\n ok(true, \"About was entered\");\n }\n });\n\n App.Router.map(function() {\n this.route('thing', { path: '/thing/:thing_id' });\n this.route('about');\n });\n\n bootApplication();\n\n Ember.run(router, 'handleURL', '/');\n\n function assertLinkStatus($link, url) {\n if (url) {\n equal(normalizeUrl($link.attr('href')), url, \"loaded link-to has expected href\");\n ok(!$link.hasClass('i-am-loading'), \"loaded linkView has no loadingClass\");\n } else {\n equal(normalizeUrl($link.attr('href')), '#', \"unloaded link-to has href='#'\");\n ok($link.hasClass('i-am-loading'), \"loading linkView has loadingClass\");\n }\n }\n\n var $contextLink = Ember.$('#context-link', '#qunit-fixture'),\n $staticLink = Ember.$('#static-link', '#qunit-fixture'),\n controller = container.lookup('controller:index');\n\n assertLinkStatus($contextLink);\n assertLinkStatus($staticLink);\n\n Ember.run(function() {\n warnCalled = false;\n $contextLink.click();\n ok(warnCalled, \"Logger.warn was called from clicking loading link\");\n });\n\n // Set the destinationRoute (context is still null).\n Ember.run(controller, 'set', 'destinationRoute', 'thing');\n assertLinkStatus($contextLink);\n\n // Set the routeContext to an id\n Ember.run(controller, 'set', 'routeContext', '456');\n assertLinkStatus($contextLink, '/thing/456');\n\n // Test that 0 isn't interpreted as falsy.\n Ember.run(controller, 'set', 'routeContext', 0);\n assertLinkStatus($contextLink, '/thing/0');\n\n // Set the routeContext to an object\n Ember.run(controller, 'set', 'routeContext', thing);\n assertLinkStatus($contextLink, '/thing/123');\n\n // Set the destinationRoute back to null.\n Ember.run(controller, 'set', 'destinationRoute', null);\n assertLinkStatus($contextLink);\n\n Ember.run(function() {\n warnCalled = false;\n $staticLink.click();\n ok(warnCalled, \"Logger.warn was called from clicking loading link\");\n });\n\n Ember.run(controller, 'set', 'secondRoute', 'about');\n assertLinkStatus($staticLink, '/about');\n\n // Click the now-active link\n Ember.run($staticLink, 'click');\n\n Ember.Logger.warn = oldWarn;\n});\n\ntest(\"The {{link-to}} helper refreshes href element when one of params changes\", function() {\n Router.map(function() {\n this.route('post', { path: '/posts/:post_id' });\n });\n\n var post = Ember.Object.create({id: '1'}),\n secondPost = Ember.Object.create({id: '2'});\n\n Ember.TEMPLATES.index = compile('{{#link-to \"post\" post id=\"post\"}}post{{/link-to}}');\n\n App.IndexController = Ember.Controller.extend();\n var indexController = container.lookup('controller:index');\n\n Ember.run(function() { indexController.set('post', post); });\n\n bootApplication();\n\n Ember.run(function() { router.handleURL(\"/\"); });\n\n equal(normalizeUrl(Ember.$('#post', '#qunit-fixture').attr('href')), '/posts/1', 'precond - Link has rendered href attr properly');\n\n Ember.run(function() { indexController.set('post', secondPost); });\n\n equal(Ember.$('#post', '#qunit-fixture').attr('href'), '/posts/2', 'href attr was updated after one of the params had been changed');\n\n Ember.run(function() { indexController.set('post', null); });\n\n equal(Ember.$('#post', '#qunit-fixture').attr('href'), '#', 'href attr becomes # when one of the arguments in nullified');\n});\n\nif (Ember.FEATURES.isEnabled(\"query-params\")) {\n test(\"The {{linkTo}} helper supports query params\", function() {\n expect(66);\n\n Router.map(function() {\n this.route(\"about\", {queryParams: ['section']});\n this.resource(\"items\", { queryParams: ['sort', 'direction'] });\n });\n\n Ember.TEMPLATES.about = Ember.Handlebars.compile(\"

    About

    {{#linkTo 'about' id='about-link'}}About{{/linkTo}} {{#linkTo 'about' section='intro' id='about-link-with-qp'}}Intro{{/linkTo}}{{#linkTo 'about' section=false id='about-clear-qp'}}Intro{{/linkTo}}{{#if isIntro}}

    Here is the intro

    {{/if}}\");\n Ember.TEMPLATES.items = Ember.Handlebars.compile(\"

    Items

    {{#linkTo 'about' id='about-link'}}About{{/linkTo}} {{#linkTo 'items' id='items-link' direction=otherDirection}}Sort{{/linkTo}} {{#linkTo 'items' id='items-sort-link' sort='name'}}Sort Ascending{{/linkTo}} {{#linkTo 'items' id='items-clear-link' queryParams=false}}Clear Query Params{{/linkTo}}\");\n\n App.AboutRoute = Ember.Route.extend({\n setupController: function(controller, context, queryParams) {\n controller.set('isIntro', queryParams.section === 'intro');\n }\n });\n\n App.ItemsRoute = Ember.Route.extend({\n setupController: function (controller, context, queryParams) {\n controller.set('currentDirection', queryParams.direction || 'asc');\n }\n });\n\n var shouldNotHappen = function(error) {\n console.error(error.stack);\n ok(false, \"this .then handler should not be called: \" + error.message);\n };\n\n App.ItemsController = Ember.Controller.extend({\n currentDirection: 'asc',\n otherDirection: Ember.computed(function () {\n if (get(this, 'currentDirection') === 'asc') {\n return 'desc';\n } else {\n return 'asc';\n }\n }).property('currentDirection')\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/about\");\n });\n\n equal(Ember.$('h1:contains(About)', '#qunit-fixture').length, 1, \"The about template was rendered\");\n equal(normalizeUrl(Ember.$('#about-link').attr('href')), '/about', \"The about link points back at /about\");\n shouldBeActive('#about-link');\n equal(normalizeUrl(Ember.$('#about-link-with-qp').attr('href')), '/about?section=intro', \"The helper accepts query params\");\n shouldNotBeActive('#about-link-with-qp');\n equal(normalizeUrl(Ember.$('#about-clear-qp').attr('href')), '/about', \"Falsy query params work\");\n shouldBeActive('#about-clear-qp');\n\n\n Ember.run(function() {\n Ember.$('#about-link-with-qp', '#qunit-fixture').click();\n });\n\n equal(router.get('url'), \"/about?section=intro\", \"Clicking linkTo updates the url\");\n equal(Ember.$('p', '#qunit-fixture').text(), \"Here is the intro\", \"Query param is applied to controller\");\n equal(normalizeUrl(Ember.$('#about-link').attr('href')), '/about?section=intro', \"The params have stuck\");\n shouldBeActive('#about-link');\n equal(normalizeUrl(Ember.$('#about-link-with-qp').attr('href')), '/about?section=intro', \"The helper accepts query params\");\n shouldBeActive('#about-link-with-qp');\n equal(normalizeUrl(Ember.$('#about-clear-qp').attr('href')), '/about', \"Falsy query params clear querystring\");\n shouldNotBeActive('#about-clear-qp');\n\n\n Ember.run(function() {\n router.transitionTo(\"/about\");\n });\n\n equal(router.get('url'), \"/about\", \"handleURL clears query params\");\n\n Ember.run(function() {\n router.transitionTo(\"/items\");\n });\n\n var controller = container.lookup('controller:items');\n\n equal(controller.get('currentDirection'), 'asc', \"Current direction is asc\");\n equal(controller.get('otherDirection'), 'desc', \"Other direction is desc\");\n\n equal(Ember.$('h1:contains(Items)', '#qunit-fixture').length, 1, \"The items template was rendered\");\n equal(normalizeUrl(Ember.$('#about-link').attr('href')), '/about', \"The params have not stuck\");\n shouldNotBeActive('#about-link');\n equal(normalizeUrl(Ember.$('#items-link').attr('href')), '/items?direction=desc', \"Params can come from bindings\");\n shouldNotBeActive('#items-link');\n equal(normalizeUrl(Ember.$('#items-clear-link').attr('href')), '/items', \"Can clear query params\");\n shouldBeActive('#items-clear-link');\n\n Ember.run(function() {\n Ember.$('#items-link', '#qunit-fixture').click();\n });\n\n equal(router.get('url'), \"/items?direction=desc\", \"Clicking linkTo should direct to the correct url\");\n equal(controller.get('currentDirection'), 'desc', \"Current direction is desc\");\n equal(controller.get('otherDirection'), 'asc', \"Other direction is asc\");\n\n equal(normalizeUrl(Ember.$('#items-sort-link').attr('href')), '/items?direction=desc&sort=name', \"linkTo href correctly merges query parmas\");\n shouldNotBeActive('#items-sort-link');\n\n equal(normalizeUrl(Ember.$('#items-clear-link').attr('href')), '/items', \"Can clear query params\");\n shouldNotBeActive('#items-clear-link');\n\n Ember.run(function() {\n Ember.$('#items-sort-link', '#qunit-fixture').click();\n });\n\n\n equal(router.get('url'), \"/items?sort=name&direction=desc\", \"The params should be merged correctly\");\n equal(controller.get('currentDirection'), 'desc', \"Current direction is desc\");\n equal(controller.get('otherDirection'), 'asc', \"Other direction is asc\");\n\n equal(normalizeUrl(Ember.$('#items-sort-link').attr('href')), \"/items?sort=name&direction=desc\", \"linkTo href correctly merges query parmas\");\n shouldBeActive('#items-sort-link');\n\n equal(normalizeUrl(Ember.$('#items-link').attr('href')), \"/items?sort=name&direction=asc\", \"Params can come from bindings\");\n shouldNotBeActive('#items-link');\n\n equal(normalizeUrl(Ember.$('#items-clear-link').attr('href')), '/items', \"Can clear query params\");\n shouldNotBeActive('#items-clear-link');\n\n Ember.run(function() {\n controller.set('currentDirection', 'asc');\n });\n\n equal(controller.get('currentDirection'), 'asc', \"Current direction is asc\");\n equal(controller.get('otherDirection'), 'desc', \"Other direction is desc\");\n\n equal(normalizeUrl(Ember.$('#items-link').attr('href')), \"/items?sort=name&direction=desc\", \"Params are updated when bindings change\");\n shouldBeActive('#items-link');\n equal(normalizeUrl(Ember.$('#items-sort-link').attr('href')), '/items?sort=name&direction=desc', \"linkTo href correctly merges query params when other params change\");\n shouldBeActive('#items-sort-link');\n\n Ember.run(function() {\n Ember.$('#items-sort-link', '#qunit-fixture').click();\n });\n\n equal(router.get('url'), '/items?sort=name&direction=desc', \"Clicking the active link should preserve the url\");\n shouldBeActive('#items-sort-link');\n\n\n var promise, next;\n\n stop();\n\n Ember.run(function () {\n promise = router.transitionTo({queryParams: {sort: false}});\n });\n\n next = function () {\n equal(router.get('url'), '/items?direction=desc', \"Transitioning updates the url\");\n\n equal(controller.get('currentDirection'), 'desc', \"Current direction is asc\");\n equal(controller.get('otherDirection'), 'asc', \"Other direction is desc\");\n\n equal(normalizeUrl(Ember.$('#items-link').attr('href')), \"/items?direction=asc\", \"Params are updated when transitioning\");\n shouldNotBeActive('#items-link');\n\n equal(normalizeUrl(Ember.$('#items-sort-link').attr('href')), \"/items?direction=desc&sort=name\", \"Params are updated when transitioning\");\n shouldNotBeActive('#items-sort-link');\n\n return router.transitionTo({queryParams: {sort: 'name'}});\n };\n\n Ember.run(function () {\n promise.then(next, shouldNotHappen);\n });\n\n next = function () {\n equal(router.get('url'), '/items?sort=name&direction=desc', \"Transitioning updates the url\");\n\n equal(controller.get('currentDirection'), 'desc', \"Current direction is asc\");\n equal(controller.get('otherDirection'), 'asc', \"Other direction is desc\");\n\n equal(normalizeUrl(Ember.$('#items-link').attr('href')), \"/items?sort=name&direction=asc\", \"Params are updated when transitioning\");\n shouldNotBeActive('#items-link');\n\n equal(normalizeUrl(Ember.$('#items-sort-link').attr('href')), \"/items?sort=name&direction=desc\", \"Params are updated when transitioning\");\n shouldBeActive('#items-sort-link');\n\n\n Ember.$('#items-clear-link', '#qunit-fixture').click();\n\n equal(router.get('url'), '/items', \"Link clears the query params\");\n equal(normalizeUrl(Ember.$('#items-clear-link').attr('href')), '/items', \"Can clear query params\");\n shouldBeActive('#items-clear-link');\n\n\n start();\n };\n\n Ember.run(function () {\n promise.then(next, shouldNotHappen);\n });\n });\n\n\n\n test(\"The {{linkTo}} can work without a route name if query params are supplied\", function() {\n expect(4);\n\n Router.map(function() {\n this.route(\"items\", { queryParams: ['page'] });\n this.route('about');\n });\n\n Ember.TEMPLATES.items = Ember.Handlebars.compile(\"

    Items

    {{#linkTo page=2 id='next-page'}}Next Page{{/linkTo}}\");\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/items\");\n });\n\n equal(normalizeUrl(Ember.$('#next-page').attr('href')), '/items?page=2', \"The link-to works without a routename\");\n shouldNotBeActive('#next-page');\n\n Ember.run(function() {\n Ember.$('#next-page', '#qunit-fixture').click();\n });\n\n equal(router.get('url'), \"/items?page=2\", \"Clicking the link updates the url\");\n shouldBeActive('#next-page');\n });\n}\n\ntest(\"The {{link-to}} helper's bound parameter functionality works as expected in conjunction with an ObjectProxy/Controller\", function() {\n Router.map(function() {\n this.route('post', { path: '/posts/:post_id' });\n });\n\n var post = Ember.Object.create({id: '1'}),\n secondPost = Ember.Object.create({id: '2'});\n\n Ember.TEMPLATES = {\n index: compile(' '),\n post: compile('{{#link-to \"post\" this id=\"self-link\"}}selflink{{/link-to}}')\n };\n\n App.PostController = Ember.ObjectController.extend();\n var postController = container.lookup('controller:post');\n\n bootApplication();\n\n Ember.run(router, 'transitionTo', 'post', post);\n\n var $link = Ember.$('#self-link', '#qunit-fixture');\n equal(normalizeUrl($link.attr('href')), '/posts/1', 'self link renders post 1');\n\n Ember.run(postController, 'set', 'content', secondPost);\n var linkView = Ember.View.views['self-link'];\n\n equal(normalizeUrl($link.attr('href')), '/posts/2', 'self link updated to post 2');\n});\n\ntest(\"{{linkTo}} is aliased\", function() {\n equal(Ember.Handlebars.helpers.linkTo, Ember.Handlebars.helpers['link-to']);\n});\n\ntest(\"The {{link-to}} helper is active when a resource is active\", function() {\n Router.map(function() {\n this.resource(\"about\", function() {\n this.route(\"item\");\n });\n });\n\n Ember.TEMPLATES.about = compile(\"
    {{#link-to 'about' id='about-link'}}About{{/link-to}} {{#link-to 'about.item' id='item-link'}}Item{{/link-to}} {{outlet}}
    \");\n Ember.TEMPLATES['about/item'] = compile(\" \");\n Ember.TEMPLATES['about/index'] = compile(\" \");\n\n bootApplication();\n\n Ember.run(router, 'handleURL', '/about');\n\n equal(Ember.$('#about-link.active', '#qunit-fixture').length, 1, \"The about resource link is active\");\n equal(Ember.$('#item-link.active', '#qunit-fixture').length, 0, \"The item route link is inactive\");\n\n Ember.run(router, 'handleURL', '/about/item');\n\n equal(Ember.$('#about-link.active', '#qunit-fixture').length, 1, \"The about resource link is active\");\n equal(Ember.$('#item-link.active', '#qunit-fixture').length, 1, \"The item route link is active\");\n\n});\n\ntest(\"The {{link-to}} helper works in an #each'd array of string route names\", function() {\n Router.map(function() {\n this.route('foo');\n this.route('bar');\n this.route('rar');\n });\n\n App.IndexController = Ember.Controller.extend({\n routeNames: Ember.A(['foo', 'bar', 'rar']),\n route1: 'bar',\n route2: 'foo'\n });\n\n Ember.TEMPLATES = {\n index: compile('{{#each routeName in routeNames}}{{#link-to routeName}}{{routeName}}{{/link-to}}{{/each}}{{#each routeNames}}{{#link-to this}}{{this}}{{/link-to}}{{/each}}{{#link-to route1}}a{{/link-to}}{{#link-to route2}}b{{/link-to}}')\n };\n\n bootApplication();\n\n function linksEqual($links, expected) {\n equal($links.length, expected.length, \"Has correct number of links\");\n\n var idx;\n for (idx = 0; idx < $links.length; idx++) {\n var href = Ember.$($links[idx]).attr('href');\n // Old IE includes the whole hostname as well\n equal(href.slice(-expected[idx].length), expected[idx], \"Expected link to be '\"+expected[idx]+\"', but was '\"+href+\"'\");\n }\n }\n\n linksEqual(Ember.$('a', '#qunit-fixture'), [\"/foo\", \"/bar\", \"/rar\", \"/foo\", \"/bar\", \"/rar\", \"/bar\", \"/foo\"]);\n\n var indexController = container.lookup('controller:index');\n Ember.run(indexController, 'set', 'route1', 'rar');\n\n linksEqual(Ember.$('a', '#qunit-fixture'), [\"/foo\", \"/bar\", \"/rar\", \"/foo\", \"/bar\", \"/rar\", \"/rar\", \"/foo\"]);\n\n Ember.run(indexController.routeNames, 'shiftObject');\n\n linksEqual(Ember.$('a', '#qunit-fixture'), [\"/bar\", \"/rar\", \"/bar\", \"/rar\", \"/rar\", \"/foo\"]);\n});\n\nif (Ember.FEATURES.isEnabled('link-to-non-block')) {\n test(\"The non-block form {{link-to}} helper moves into the named route\", function() {\n expect(3);\n Router.map(function(match) {\n this.route(\"contact\");\n });\n\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"

    Home

    {{link-to 'Contact us' 'contact' id='contact-link'}}{{#link-to 'index' id='self-link'}}Self{{/link-to}}\");\n Ember.TEMPLATES.contact = Ember.Handlebars.compile(\"

    Contact

    {{link-to 'Home' 'index' id='home-link'}}{{link-to 'Self' 'contact' id='self-link'}}\");\n\n bootApplication();\n\n Ember.run(function() {\n Ember.$('#contact-link', '#qunit-fixture').click();\n });\n\n equal(Ember.$('h3:contains(Contact)', '#qunit-fixture').length, 1, \"The contact template was rendered\");\n equal(Ember.$('#self-link.active', '#qunit-fixture').length, 1, \"The self-link was rendered with active class\");\n equal(Ember.$('#home-link:not(.active)', '#qunit-fixture').length, 1, \"The other link was rendered without active class\");\n });\n\n test(\"The non-block form {{link-to}} helper updates the link text when it is a binding\", function() {\n expect(7);\n Router.map(function(match) {\n this.route(\"contact\");\n });\n\n App.IndexController = Ember.Controller.extend({\n contactName: 'Jane'\n });\n\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"

    Home

    {{link-to contactName 'contact' id='contact-link'}}{{#link-to 'index' id='self-link'}}Self{{/link-to}}\");\n Ember.TEMPLATES.contact = Ember.Handlebars.compile(\"

    Contact

    {{link-to 'Home' 'index' id='home-link'}}{{link-to 'Self' 'contact' id='self-link'}}\");\n\n bootApplication();\n\n Ember.run(function() {\n router.handleURL(\"/\");\n });\n\n equal(Ember.$('#contact-link:contains(Jane)', '#qunit-fixture').length, 1, \"The link title is correctly resolved\");\n\n var controller = container.lookup('controller:index');\n Ember.run(function() {\n controller.set('contactName', 'Joe');\n });\n equal(Ember.$('#contact-link:contains(Joe)', '#qunit-fixture').length, 1, \"The link title is correctly updated when the bound property changes\");\n\n Ember.run(function() {\n Ember.$('#contact-link', '#qunit-fixture').click();\n });\n\n equal(Ember.$('h3:contains(Contact)', '#qunit-fixture').length, 1, \"The contact template was rendered\");\n equal(Ember.$('#self-link.active', '#qunit-fixture').length, 1, \"The self-link was rendered with active class\");\n equal(Ember.$('#home-link:not(.active)', '#qunit-fixture').length, 1, \"The other link was rendered without active class\");\n\n Ember.run(function() {\n Ember.$('#home-link', '#qunit-fixture').click();\n });\n\n equal(Ember.$('h3:contains(Home)', '#qunit-fixture').length, 1, \"The index template was rendered\");\n equal(Ember.$('#contact-link:contains(Joe)', '#qunit-fixture').length, 1, \"The link title is correctly updated when the route changes\");\n });\n\n test(\"The non-block form {{link-to}} helper moves into the named route with context\", function() {\n expect(5);\n Router.map(function(match) {\n this.route(\"item\", { path: \"/item/:id\" });\n });\n\n App.IndexRoute = Ember.Route.extend({\n model: function() {\n return Ember.A([\n { id: \"yehuda\", name: \"Yehuda Katz\" },\n { id: \"tom\", name: \"Tom Dale\" },\n { id: \"erik\", name: \"Erik Brynroflsson\" }\n ]);\n }\n });\n\n App.ItemRoute = Ember.Route.extend({\n serialize: function(object) {\n return { id: object.id };\n }\n });\n\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"

    Home

      {{#each controller}}
    • {{link-to name 'item' this}}
    • {{/each}}
    \");\n Ember.TEMPLATES.item = Ember.Handlebars.compile(\"

    Item

    {{name}}

    {{#link-to 'index' id='home-link'}}Home{{/link-to}}\");\n\n bootApplication();\n\n Ember.run(function() {\n Ember.$('li a:contains(Yehuda)', '#qunit-fixture').click();\n });\n\n equal(Ember.$('h3:contains(Item)', '#qunit-fixture').length, 1, \"The item template was rendered\");\n equal(Ember.$('p', '#qunit-fixture').text(), \"Yehuda Katz\", \"The name is correct\");\n\n Ember.run(function() { Ember.$('#home-link').click(); });\n\n equal(normalizeUrl(Ember.$('li a:contains(Yehuda)').attr('href')), \"/item/yehuda\");\n equal(normalizeUrl(Ember.$('li a:contains(Tom)').attr('href')), \"/item/tom\");\n equal(normalizeUrl(Ember.$('li a:contains(Erik)').attr('href')), \"/item/erik\");\n\n });\n\n test(\"The non-block form {{link-to}} performs property lookup\", function() {\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"{{link-to 'string' 'index' id='string-link'}}{{link-to path foo id='path-link'}}{{link-to view.foo view.foo id='view-link'}}\");\n\n function assertEquality(href) {\n equal(normalizeUrl(Ember.$('#string-link', '#qunit-fixture').attr('href')), '/');\n equal(normalizeUrl(Ember.$('#path-link', '#qunit-fixture').attr('href')), href);\n equal(normalizeUrl(Ember.$('#view-link', '#qunit-fixture').attr('href')), href);\n }\n\n App.IndexView = Ember.View.extend({\n foo: 'index',\n elementId: 'index-view'\n });\n\n App.IndexController = Ember.Controller.extend({\n foo: 'index'\n });\n\n App.Router.map(function() {\n this.route('about');\n });\n\n bootApplication();\n\n Ember.run(router, 'handleURL', '/');\n\n assertEquality('/');\n\n var controller = container.lookup('controller:index'),\n view = Ember.View.views['index-view'];\n Ember.run(function() {\n controller.set('foo', 'about');\n view.set('foo', 'about');\n });\n\n assertEquality('/about');\n });\n}\n\ntest(\"The non-block form {{link-to}} protects against XSS\", function() {\n Ember.TEMPLATES.application = Ember.Handlebars.compile(\"{{link-to display 'index' id='link'}}\");\n\n App.ApplicationController = Ember.Controller.extend({\n display: 'blahzorz'\n });\n\n bootApplication();\n\n Ember.run(router, 'handleURL', '/');\n\n var controller = container.lookup('controller:application');\n\n equal(Ember.$('#link', '#qunit-fixture').text(), 'blahzorz');\n Ember.run(function() {\n controller.set('display', 'BLAMMO');\n });\n\n equal(Ember.$('#link', '#qunit-fixture').text(), 'BLAMMO');\n equal(Ember.$('b', '#qunit-fixture').length, 0);\n});\n\n})();\n//@ sourceURL=ember/~tests/helpers/link_to_test");minispade.register('ember/~tests/homepage_example_test', "(function() {var App, $fixture;\n\nfunction setupExample() {\n // setup templates\n Ember.TEMPLATES.application = Ember.Handlebars.compile(\"{{outlet}}\");\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"

    People

      {{#each model}}
    • Hello, {{fullName}}!
    • {{/each}}
    \");\n\n\n App.Person = Ember.Object.extend({\n firstName: null,\n lastName: null,\n\n fullName: Ember.computed('firstName', 'lastName', function() {\n return this.get('firstName') + \" \" + this.get('lastName');\n })\n });\n\n App.IndexRoute = Ember.Route.extend({\n model: function() {\n var people = Ember.A([\n App.Person.create({\n firstName: \"Tom\",\n lastName: \"Dale\"\n }),\n App.Person.create({\n firstName: \"Yehuda\",\n lastName: \"Katz\"\n })\n ]);\n return people;\n }\n });\n}\n\nmodule(\"Homepage Example\", {\n setup: function() {\n Ember.run(function() {\n App = Ember.Application.create({\n name: \"App\",\n rootElement: '#qunit-fixture'\n });\n App.deferReadiness();\n\n App.Router.reopen({\n location: 'none'\n });\n\n App.LoadingRoute = Ember.Route.extend();\n });\n\n $fixture = Ember.$('#qunit-fixture');\n\n\n setupExample();\n\n },\n\n teardown: function() {\n Ember.run(function() {\n App.destroy();\n App = null;\n\n Ember.TEMPLATES = {};\n });\n }\n});\n\n\ntest(\"The example renders correctly\", function() {\n Ember.run(App, 'advanceReadiness');\n\n equal($fixture.find('h1:contains(People)').length, 1);\n equal($fixture.find('li').length, 2);\n equal($fixture.find('li:nth-of-type(1)').text(), 'Hello, Tom Dale!');\n equal($fixture.find('li:nth-of-type(2)').text(), 'Hello, Yehuda Katz!');\n});\n\n})();\n//@ sourceURL=ember/~tests/homepage_example_test");minispade.register('ember/~tests/routing/basic_test', "(function() {var Router, App, AppView, templates, router, container;\nvar get = Ember.get,\n set = Ember.set,\n compile = Ember.Handlebars.compile,\n forEach = Ember.EnumerableUtils.forEach;\n\nfunction bootApplication() {\n router = container.lookup('router:main');\n Ember.run(App, 'advanceReadiness');\n}\n\nfunction handleURL(path) {\n return Ember.run(function() {\n return router.handleURL(path).then(function(value) {\n ok(true, 'url: `' + path + '` was handled');\n return value;\n }, function(reason) {\n ok(false, 'failed to visit:`' + path + '` reason: `' + QUnit.jsDump.parse(reason));\n throw reason;\n });\n });\n}\n\nfunction handleURLAborts(path) {\n Ember.run(function() {\n router.handleURL(path).then(function(value) {\n ok(false, 'url: `' + path + '` was NOT to be handled');\n }, function(reason) {\n ok(reason && reason.message === \"TransitionAborted\", 'url: `' + path + '` was to be aborted');\n });\n });\n}\n\nfunction handleURLRejectsWith(path, expectedReason) {\n Ember.run(function() {\n router.handleURL(path).then(function(value) {\n ok(false, 'expected handleURLing: `' + path + '` to fail');\n }, function(reason) {\n equal(expectedReason, reason);\n });\n });\n}\n\nmodule(\"Basic Routing\", {\n setup: function() {\n Ember.run(function() {\n App = Ember.Application.create({\n name: \"App\",\n rootElement: '#qunit-fixture'\n });\n\n App.deferReadiness();\n\n App.Router.reopen({\n location: 'none'\n });\n\n Router = App.Router;\n\n App.LoadingRoute = Ember.Route.extend({\n });\n\n container = App.__container__;\n\n Ember.TEMPLATES.application = compile(\"{{outlet}}\");\n Ember.TEMPLATES.home = compile(\"

    Hours

    \");\n Ember.TEMPLATES.homepage = compile(\"

    Megatroll

    {{home}}

    \");\n Ember.TEMPLATES.camelot = compile('

    Is a silly place

    ');\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n App.destroy();\n App = null;\n\n Ember.TEMPLATES = {};\n });\n Ember.TESTING_DEPRECATION = false;\n }\n});\n\ntest(\"warn on URLs not included in the route set\", function () {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n\n bootApplication();\n\n // it's tricky to use expectAssertion(fn) in a callback.\n var oldAssert = Ember.assert;\n Ember.assert = function(message, test){\n ok(true, test);\n equal(\"The URL '/what-is-this-i-dont-even' did not match any routes in your application\", message);\n };\n\n Ember.run(function(){\n router.handleURL(\"/what-is-this-i-dont-even\");\n });\n\n Ember.assert = oldAssert;\n\n});\n\ntest(\"The Homepage\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeRoute = Ember.Route.extend({\n });\n\n var currentPath;\n\n App.ApplicationController = Ember.Controller.extend({\n currentPathDidChange: Ember.observer('currentPath', function() {\n currentPath = get(this, 'currentPath');\n })\n });\n\n bootApplication();\n\n equal(currentPath, 'home');\n equal(Ember.$('h3:contains(Hours)', '#qunit-fixture').length, 1, \"The home template was rendered\");\n});\n\ntest(\"The Home page and the Camelot page with multiple Router.map calls\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n Router.map(function() {\n this.route(\"camelot\", {path: \"/camelot\"});\n });\n\n App.HomeRoute = Ember.Route.extend({\n });\n\n App.CamelotRoute = Ember.Route.extend({\n });\n\n var currentPath;\n\n App.ApplicationController = Ember.Controller.extend({\n currentPathDidChange: Ember.observer('currentPath', function() {\n currentPath = get(this, 'currentPath');\n })\n });\n\n App.CamelotController = Ember.Controller.extend({\n currentPathDidChange: Ember.observer('currentPath', function() {\n currentPath = get(this, 'currentPath');\n })\n });\n\n bootApplication();\n\n handleURL(\"/camelot\");\n\n equal(currentPath, 'camelot');\n equal(Ember.$('h3:contains(silly)', '#qunit-fixture').length, 1, \"The camelot template was rendered\");\n\n handleURL(\"/\");\n\n equal(currentPath, 'home');\n equal(Ember.$('h3:contains(Hours)', '#qunit-fixture').length, 1, \"The home template was rendered\");\n});\n\ntest(\"The Homepage register as activeView\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.route(\"homepage\");\n });\n\n App.HomeRoute = Ember.Route.extend({\n });\n\n App.HomepageRoute = Ember.Route.extend({\n });\n\n bootApplication();\n\n ok(router._lookupActiveView('home'), '`home` active view is connected');\n\n handleURL('/homepage');\n\n ok(router._lookupActiveView('homepage'), '`homepage` active view is connected');\n equal(router._lookupActiveView('home'), undefined, '`home` active view is disconnected');\n});\n\ntest(\"The Homepage with explicit template name in renderTemplate\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeRoute = Ember.Route.extend({\n renderTemplate: function() {\n this.render('homepage');\n }\n });\n\n bootApplication();\n\n equal(Ember.$('h3:contains(Megatroll)', '#qunit-fixture').length, 1, \"The homepage template was rendered\");\n});\n\ntest(\"An alternate template will pull in an alternate controller\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeRoute = Ember.Route.extend({\n renderTemplate: function() {\n this.render('homepage');\n }\n });\n\n App.HomepageController = Ember.Controller.extend({\n home: \"Comes from homepage\"\n });\n\n bootApplication();\n\n equal(Ember.$('h3:contains(Megatroll) + p:contains(Comes from homepage)', '#qunit-fixture').length, 1, \"The homepage template was rendered\");\n});\n\ntest(\"The template will pull in an alternate controller via key/value\", function() {\n Router.map(function() {\n this.route(\"homepage\", { path: \"/\" });\n });\n\n App.HomepageRoute = Ember.Route.extend({\n renderTemplate: function() {\n this.render({controller: 'home'});\n }\n });\n\n App.HomeController = Ember.Controller.extend({\n home: \"Comes from home.\"\n });\n\n bootApplication();\n\n equal(Ember.$('h3:contains(Megatroll) + p:contains(Comes from home.)', '#qunit-fixture').length, 1, \"The homepage template was rendered from data from the HomeController\");\n});\n\ntest(\"The Homepage with explicit template name in renderTemplate and controller\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeController = Ember.Controller.extend({\n home: \"YES I AM HOME\"\n });\n\n App.HomeRoute = Ember.Route.extend({\n renderTemplate: function() {\n this.render('homepage');\n }\n });\n\n bootApplication();\n\n equal(Ember.$('h3:contains(Megatroll) + p:contains(YES I AM HOME)', '#qunit-fixture').length, 1, \"The homepage template was rendered\");\n});\n\ntest(\"Renders correct view with slash notation\", function() {\n Ember.TEMPLATES['home/page'] = compile(\"

    {{view.name}}

    \");\n\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeRoute = Ember.Route.extend({\n renderTemplate: function() {\n this.render('home/page');\n }\n });\n\n App.HomePageView = Ember.View.extend({\n name: \"Home/Page\"\n });\n\n bootApplication();\n\n equal(Ember.$('p:contains(Home/Page)', '#qunit-fixture').length, 1, \"The homepage template was rendered\");\n});\n\ntest(\"Renders the view given in the view option\", function() {\n Ember.TEMPLATES['home'] = compile(\"

    {{view.name}}

    \");\n\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeRoute = Ember.Route.extend({\n renderTemplate: function() {\n this.render({view: 'homePage'});\n }\n });\n\n App.HomePageView = Ember.View.extend({\n name: \"Home/Page\"\n });\n\n bootApplication();\n\n equal(Ember.$('p:contains(Home/Page)', '#qunit-fixture').length, 1, \"The homepage view was rendered\");\n});\n\ntest('render does not replace templateName if user provided', function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n Ember.TEMPLATES.the_real_home_template = Ember.Handlebars.compile(\n \"

    THIS IS THE REAL HOME

    \"\n );\n\n App.HomeView = Ember.View.extend({\n templateName: 'the_real_home_template'\n });\n App.HomeController = Ember.Controller.extend();\n App.HomeRoute = Ember.Route.extend();\n\n bootApplication();\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"THIS IS THE REAL HOME\", \"The homepage template was rendered\");\n});\n\ntest('render does not replace template if user provided', function () {\n Router.map(function () {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeView = Ember.View.extend({\n template: Ember.Handlebars.compile(\"

    THIS IS THE REAL HOME

    \")\n });\n App.HomeController = Ember.Controller.extend();\n App.HomeRoute = Ember.Route.extend();\n\n bootApplication();\n\n Ember.run(function () {\n router.handleURL(\"/\");\n });\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"THIS IS THE REAL HOME\", \"The homepage template was rendered\");\n});\n\ntest('render uses templateName from route', function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n Ember.TEMPLATES.the_real_home_template = Ember.Handlebars.compile(\n \"

    THIS IS THE REAL HOME

    \"\n );\n\n App.HomeController = Ember.Controller.extend();\n App.HomeRoute = Ember.Route.extend({\n templateName: 'the_real_home_template'\n });\n\n bootApplication();\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"THIS IS THE REAL HOME\", \"The homepage template was rendered\");\n});\n\ntest('defining templateName allows other templates to be rendered', function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n Ember.TEMPLATES.alert = Ember.Handlebars.compile(\n \"
    Invader!
    \"\n );\n Ember.TEMPLATES.the_real_home_template = Ember.Handlebars.compile(\n \"

    THIS IS THE REAL HOME

    {{outlet alert}}\"\n );\n\n App.HomeController = Ember.Controller.extend();\n App.HomeRoute = Ember.Route.extend({\n templateName: 'the_real_home_template',\n actions: {\n showAlert: function(){\n this.render('alert', {\n into: 'home',\n outlet: 'alert'\n });\n }\n }\n });\n\n bootApplication();\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"THIS IS THE REAL HOME\", \"The homepage template was rendered\");\n\n Ember.run(function(){\n router.send('showAlert');\n });\n\n equal(Ember.$('.alert-box', '#qunit-fixture').text(), \"Invader!\", \"Template for alert was render into outlet\");\n\n});\n\ntest(\"The Homepage with a `setupController` hook\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeRoute = Ember.Route.extend({\n setupController: function(controller) {\n set(controller, 'hours', Ember.A([\n \"Monday through Friday: 9am to 5pm\",\n \"Saturday: Noon to Midnight\",\n \"Sunday: Noon to 6pm\"\n ]));\n }\n });\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"
      {{#each entry in hours}}
    • {{entry}}
    • {{/each}}
    \"\n );\n\n bootApplication();\n\n equal(Ember.$('ul li', '#qunit-fixture').eq(2).text(), \"Sunday: Noon to 6pm\", \"The template was rendered with the hours context\");\n});\n\ntest(\"The route controller is still set when overriding the setupController hook\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeRoute = Ember.Route.extend({\n setupController: function(controller) {\n // no-op\n // importantly, we are not calling this._super here\n }\n });\n\n container.register('controller:home', Ember.Controller.extend());\n\n bootApplication();\n\n deepEqual(container.lookup('route:home').controller, container.lookup('controller:home'), \"route controller is the home controller\");\n});\n\ntest(\"The route controller can be specified via controllerName\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"

    {{myValue}}

    \"\n );\n\n App.HomeRoute = Ember.Route.extend({\n controllerName: 'myController'\n });\n\n container.register('controller:myController', Ember.Controller.extend({\n myValue: \"foo\"\n }));\n\n bootApplication();\n\n deepEqual(container.lookup('route:home').controller, container.lookup('controller:myController'), \"route controller is set by controllerName\");\n equal(Ember.$('p', '#qunit-fixture').text(), \"foo\", \"The homepage template was rendered with data from the custom controller\");\n});\n\ntest(\"The route controller specified via controllerName is used in render\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n Ember.TEMPLATES.alternative_home = Ember.Handlebars.compile(\n \"

    alternative home: {{myValue}}

    \"\n );\n\n App.HomeRoute = Ember.Route.extend({\n controllerName: 'myController',\n renderTemplate: function() {\n this.render(\"alternative_home\");\n }\n });\n\n container.register('controller:myController', Ember.Controller.extend({\n myValue: \"foo\"\n }));\n\n bootApplication();\n\n deepEqual(container.lookup('route:home').controller, container.lookup('controller:myController'), \"route controller is set by controllerName\");\n equal(Ember.$('p', '#qunit-fixture').text(), \"alternative home: foo\", \"The homepage template was rendered with data from the custom controller\");\n});\n\ntest(\"The Homepage with a `setupController` hook modifying other controllers\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeRoute = Ember.Route.extend({\n setupController: function(controller) {\n set(this.controllerFor('home'), 'hours', Ember.A([\n \"Monday through Friday: 9am to 5pm\",\n \"Saturday: Noon to Midnight\",\n \"Sunday: Noon to 6pm\"\n ]));\n }\n });\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"
      {{#each entry in hours}}
    • {{entry}}
    • {{/each}}
    \"\n );\n\n bootApplication();\n\n equal(Ember.$('ul li', '#qunit-fixture').eq(2).text(), \"Sunday: Noon to 6pm\", \"The template was rendered with the hours context\");\n});\n\ntest(\"The Homepage with a computed context that does not get overridden\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeController = Ember.ArrayController.extend({\n content: Ember.computed(function() {\n return Ember.A([\n \"Monday through Friday: 9am to 5pm\",\n \"Saturday: Noon to Midnight\",\n \"Sunday: Noon to 6pm\"\n ]);\n })\n });\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"
      {{#each}}
    • {{this}}
    • {{/each}}
    \"\n );\n\n bootApplication();\n\n equal(Ember.$('ul li', '#qunit-fixture').eq(2).text(), \"Sunday: Noon to 6pm\", \"The template was rendered with the context intact\");\n});\n\ntest(\"The Homepage getting its controller context via model\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n App.HomeRoute = Ember.Route.extend({\n model: function() {\n return Ember.A([\n \"Monday through Friday: 9am to 5pm\",\n \"Saturday: Noon to Midnight\",\n \"Sunday: Noon to 6pm\"\n ]);\n },\n\n setupController: function(controller, model) {\n equal(this.controllerFor('home'), controller);\n\n set(this.controllerFor('home'), 'hours', model);\n }\n });\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"
      {{#each entry in hours}}
    • {{entry}}
    • {{/each}}
    \"\n );\n\n bootApplication();\n\n equal(Ember.$('ul li', '#qunit-fixture').eq(2).text(), \"Sunday: Noon to 6pm\", \"The template was rendered with the hours context\");\n});\n\ntest(\"The Specials Page getting its controller context by deserializing the params hash\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.resource(\"special\", { path: \"/specials/:menu_item_id\" });\n });\n\n App.SpecialRoute = Ember.Route.extend({\n model: function(params) {\n return Ember.Object.create({\n menuItemId: params.menu_item_id\n });\n },\n\n setupController: function(controller, model) {\n set(controller, 'content', model);\n }\n });\n\n Ember.TEMPLATES.special = Ember.Handlebars.compile(\n \"

    {{content.menuItemId}}

    \"\n );\n\n bootApplication();\n\n container.register('controller:special', Ember.Controller.extend());\n\n handleURL(\"/specials/1\");\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"1\", \"The model was used to render the template\");\n});\n\ntest(\"The Specials Page defaults to looking models up via `find`\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.resource(\"special\", { path: \"/specials/:menu_item_id\" });\n });\n\n App.MenuItem = Ember.Object.extend();\n App.MenuItem.reopenClass({\n find: function(id) {\n return App.MenuItem.create({\n id: id\n });\n }\n });\n\n App.SpecialRoute = Ember.Route.extend({\n setupController: function(controller, model) {\n set(controller, 'content', model);\n }\n });\n\n Ember.TEMPLATES.special = Ember.Handlebars.compile(\n \"

    {{content.id}}

    \"\n );\n\n bootApplication();\n\n container.register('controller:special', Ember.Controller.extend());\n\n handleURL(\"/specials/1\");\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"1\", \"The model was used to render the template\");\n});\n\ntest(\"The Special Page returning a promise puts the app into a loading state until the promise is resolved\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.resource(\"special\", { path: \"/specials/:menu_item_id\" });\n });\n\n var menuItem;\n\n App.MenuItem = Ember.Object.extend(Ember.DeferredMixin);\n App.MenuItem.reopenClass({\n find: function(id) {\n menuItem = App.MenuItem.create({\n id: id\n });\n\n return menuItem;\n }\n });\n\n App.LoadingRoute = Ember.Route.extend({\n\n });\n\n App.SpecialRoute = Ember.Route.extend({\n setupController: function(controller, model) {\n set(controller, 'content', model);\n }\n });\n\n Ember.TEMPLATES.special = Ember.Handlebars.compile(\n \"

    {{content.id}}

    \"\n );\n\n Ember.TEMPLATES.loading = Ember.Handlebars.compile(\n \"

    LOADING!

    \"\n );\n\n bootApplication();\n\n container.register('controller:special', Ember.Controller.extend());\n\n handleURL(\"/specials/1\");\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"LOADING!\", \"The app is in the loading state\");\n\n Ember.run(function() {\n menuItem.resolve(menuItem);\n });\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"1\", \"The app is now in the specials state\");\n});\n\ntest(\"The loading state doesn't get entered for promises that resolve on the same run loop\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.resource(\"special\", { path: \"/specials/:menu_item_id\" });\n });\n\n App.MenuItem = Ember.Object.extend();\n App.MenuItem.reopenClass({\n find: function(id) {\n return { id: id };\n }\n });\n\n App.LoadingRoute = Ember.Route.extend({\n enter: function() {\n ok(false, \"LoadingRoute shouldn't have been entered.\");\n }\n });\n\n App.SpecialRoute = Ember.Route.extend({\n setupController: function(controller, model) {\n set(controller, 'content', model);\n }\n });\n\n Ember.TEMPLATES.special = Ember.Handlebars.compile(\n \"

    {{content.id}}

    \"\n );\n\n Ember.TEMPLATES.loading = Ember.Handlebars.compile(\n \"

    LOADING!

    \"\n );\n\n bootApplication();\n\n container.register('controller:special', Ember.Controller.extend());\n\n handleURL(\"/specials/1\");\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"1\", \"The app is now in the specials state\");\n});\n\nasyncTest(\"The Special page returning an error fires the error hook on SpecialRoute\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.resource(\"special\", { path: \"/specials/:menu_item_id\" });\n });\n\n var menuItem;\n\n App.MenuItem = Ember.Object.extend(Ember.DeferredMixin);\n App.MenuItem.reopenClass({\n find: function(id) {\n menuItem = App.MenuItem.create({ id: id });\n Ember.run.later(function() { menuItem.resolve(menuItem); }, 1);\n return menuItem;\n }\n });\n\n App.SpecialRoute = Ember.Route.extend({\n setup: function() {\n throw 'Setup error';\n },\n actions: {\n error: function(reason) {\n equal(reason, 'Setup error');\n start();\n }\n }\n });\n\n bootApplication();\n\n handleURLRejectsWith('/specials/1', 'Setup error');\n});\n\nasyncTest(\"The Special page returning an error invokes SpecialRoute's error handler\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.resource(\"special\", { path: \"/specials/:menu_item_id\" });\n });\n\n var menuItem;\n\n App.MenuItem = Ember.Object.extend(Ember.DeferredMixin);\n App.MenuItem.reopenClass({\n find: function(id) {\n menuItem = App.MenuItem.create({ id: id });\n Ember.run.later(function() {\n menuItem.resolve(menuItem);\n }, 1);\n return menuItem;\n }\n });\n\n App.SpecialRoute = Ember.Route.extend({\n setup: function() {\n throw 'Setup error';\n },\n actions: {\n error: function(reason) {\n equal(reason, 'Setup error', 'SpecialRoute#error received the error thrown from setup');\n start();\n }\n }\n });\n\n bootApplication();\n\n handleURLRejectsWith('/specials/1', 'Setup error');\n});\n\nfunction testOverridableErrorHandler(handlersName) {\n\n expect(2);\n\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.resource(\"special\", { path: \"/specials/:menu_item_id\" });\n });\n\n var menuItem;\n\n App.MenuItem = Ember.Object.extend(Ember.DeferredMixin);\n App.MenuItem.reopenClass({\n find: function(id) {\n menuItem = App.MenuItem.create({ id: id });\n Ember.run.later(function() {\n menuItem.resolve(menuItem);\n }, 1);\n return menuItem;\n }\n });\n\n var attrs = {};\n attrs[handlersName] = {\n error: function(reason) {\n equal(reason, 'Setup error', \"error was correctly passed to custom ApplicationRoute handler\");\n start();\n }\n };\n\n App.ApplicationRoute = Ember.Route.extend(attrs);\n\n App.SpecialRoute = Ember.Route.extend({\n setup: function() {\n throw 'Setup error';\n }\n });\n\n bootApplication();\n\n handleURLRejectsWith(\"/specials/1\", \"Setup error\");\n}\n\nasyncTest(\"ApplicationRoute's default error handler can be overridden\", function() {\n testOverridableErrorHandler('actions');\n});\n\nasyncTest(\"ApplicationRoute's default error handler can be overridden (with DEPRECATED `events`)\", function() {\n Ember.TESTING_DEPRECATION = true;\n testOverridableErrorHandler('events');\n});\n\nasyncTest(\"Moving from one page to another triggers the correct callbacks\", function() {\n expect(3);\n\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.resource(\"special\", { path: \"/specials/:menu_item_id\" });\n });\n\n App.MenuItem = Ember.Object.extend(Ember.DeferredMixin);\n\n App.SpecialRoute = Ember.Route.extend({\n setupController: function(controller, model) {\n set(controller, 'content', model);\n }\n });\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"

    Home

    \"\n );\n\n Ember.TEMPLATES.special = Ember.Handlebars.compile(\n \"

    {{content.id}}

    \"\n );\n\n bootApplication();\n\n container.register('controller:special', Ember.Controller.extend());\n\n var transition = handleURL('/');\n\n Ember.run(function() {\n transition.then(function() {\n equal(Ember.$('h3', '#qunit-fixture').text(), \"Home\", \"The app is now in the initial state\");\n\n var promiseContext = App.MenuItem.create({ id: 1 });\n Ember.run.later(function() {\n promiseContext.resolve(promiseContext);\n }, 1);\n\n return router.transitionTo('special', promiseContext);\n }).then(function(result) {\n deepEqual(router.location.path, '/specials/1');\n start();\n });\n });\n});\n\nasyncTest(\"Nested callbacks are not exited when moving to siblings\", function() {\n Router.map(function() {\n this.resource(\"root\", { path: \"/\" }, function() {\n this.resource(\"special\", { path: \"/specials/:menu_item_id\" });\n });\n });\n\n var currentPath;\n\n App.ApplicationController = Ember.Controller.extend({\n currentPathDidChange: Ember.observer('currentPath', function() {\n currentPath = get(this, 'currentPath');\n })\n });\n\n var menuItem;\n\n App.MenuItem = Ember.Object.extend(Ember.DeferredMixin);\n App.MenuItem.reopenClass({\n find: function(id) {\n menuItem = App.MenuItem.create({ id: id });\n return menuItem;\n }\n });\n\n App.LoadingRoute = Ember.Route.extend({\n\n });\n\n App.RootRoute = Ember.Route.extend({\n model: function() {\n rootModel++;\n return this._super.apply(this, arguments);\n },\n\n serialize: function() {\n rootSerialize++;\n return this._super.apply(this, arguments);\n },\n\n setupController: function() {\n rootSetup++;\n },\n\n renderTemplate: function() {\n rootRender++;\n }\n });\n\n App.HomeRoute = Ember.Route.extend({\n\n });\n\n App.SpecialRoute = Ember.Route.extend({\n setupController: function(controller, model) {\n set(controller, 'content', model);\n }\n });\n\n Ember.TEMPLATES['root/index'] = Ember.Handlebars.compile(\n \"

    Home

    \"\n );\n\n Ember.TEMPLATES.special = Ember.Handlebars.compile(\n \"

    {{content.id}}

    \"\n );\n\n Ember.TEMPLATES.loading = Ember.Handlebars.compile(\n \"

    LOADING!

    \"\n );\n\n var rootSetup = 0, rootRender = 0, rootModel = 0, rootSerialize = 0;\n\n bootApplication();\n\n container.register('controller:special', Ember.Controller.extend());\n\n equal(Ember.$('h3', '#qunit-fixture').text(), \"Home\", \"The app is now in the initial state\");\n equal(rootSetup, 1, \"The root setup was triggered\");\n equal(rootRender, 1, \"The root render was triggered\");\n equal(rootSerialize, 0, \"The root serialize was not called\");\n equal(rootModel, 1, \"The root model was called\");\n\n router = container.lookup('router:main');\n\n Ember.run(function() {\n var menuItem = App.MenuItem.create({ id: 1 });\n Ember.run.later(function() { menuItem.resolve(menuItem); }, 1);\n\n router.transitionTo('special', menuItem).then(function(result) {\n equal(rootSetup, 1, \"The root setup was not triggered again\");\n equal(rootRender, 1, \"The root render was not triggered again\");\n equal(rootSerialize, 0, \"The root serialize was not called\");\n\n // TODO: Should this be changed?\n equal(rootModel, 1, \"The root model was called again\");\n\n deepEqual(router.location.path, '/specials/1');\n equal(currentPath, 'root.special');\n\n start();\n });\n });\n});\n\nasyncTest(\"Events are triggered on the controller if a matching action name is implemented\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n var model = { name: \"Tom Dale\" };\n var stateIsNotCalled = true;\n\n App.HomeRoute = Ember.Route.extend({\n model: function() {\n return model;\n },\n\n actions: {\n showStuff: function(obj) {\n stateIsNotCalled = false;\n }\n }\n });\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"{{name}}\"\n );\n\n var controller = Ember.Controller.extend({\n actions: {\n showStuff: function(context) {\n ok (stateIsNotCalled, \"an event on the state is not triggered\");\n deepEqual(context, { name: \"Tom Dale\" }, \"an event with context is passed\");\n start();\n }\n }\n });\n\n container.register('controller:home', controller);\n\n bootApplication();\n\n var actionId = Ember.$(\"#qunit-fixture a\").data(\"ember-action\");\n var action = Ember.Handlebars.ActionHelper.registeredActions[actionId];\n var event = new Ember.$.Event(\"click\");\n action.handler(event);\n});\n\nasyncTest(\"Events are triggered on the current state when defined in `actions` object\", function() {\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n var model = { name: \"Tom Dale\" };\n\n App.HomeRoute = Ember.Route.extend({\n model: function() {\n return model;\n },\n\n actions: {\n showStuff: function(obj) {\n ok(this instanceof App.HomeRoute, \"the handler is an App.HomeRoute\");\n // Using Ember.copy removes any private Ember vars which older IE would be confused by\n deepEqual(Ember.copy(obj, true), { name: \"Tom Dale\" }, \"the context is correct\");\n start();\n }\n }\n });\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"{{name}}\"\n );\n\n bootApplication();\n\n var actionId = Ember.$(\"#qunit-fixture a\").data(\"ember-action\");\n var action = Ember.Handlebars.ActionHelper.registeredActions[actionId];\n var event = new Ember.$.Event(\"click\");\n action.handler(event);\n});\n\nasyncTest(\"Events defined in `actions` object are triggered on the current state when routes are nested\", function() {\n Router.map(function() {\n this.resource(\"root\", { path: \"/\" }, function() {\n this.route(\"index\", { path: \"/\" });\n });\n });\n\n var model = { name: \"Tom Dale\" };\n\n App.RootRoute = Ember.Route.extend({\n actions: {\n showStuff: function(obj) {\n ok(this instanceof App.RootRoute, \"the handler is an App.HomeRoute\");\n // Using Ember.copy removes any private Ember vars which older IE would be confused by\n deepEqual(Ember.copy(obj, true), { name: \"Tom Dale\" }, \"the context is correct\");\n start();\n }\n }\n });\n\n App.RootIndexRoute = Ember.Route.extend({\n model: function() {\n return model;\n }\n });\n\n Ember.TEMPLATES['root/index'] = Ember.Handlebars.compile(\n \"{{name}}\"\n );\n\n bootApplication();\n\n var actionId = Ember.$(\"#qunit-fixture a\").data(\"ember-action\");\n var action = Ember.Handlebars.ActionHelper.registeredActions[actionId];\n var event = new Ember.$.Event(\"click\");\n action.handler(event);\n});\n\nasyncTest(\"Events are triggered on the current state when defined in `events` object (DEPRECATED)\", function() {\n Ember.TESTING_DEPRECATION = true;\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n var model = { name: \"Tom Dale\" };\n\n App.HomeRoute = Ember.Route.extend({\n model: function() {\n return model;\n },\n\n events: {\n showStuff: function(obj) {\n ok(this instanceof App.HomeRoute, \"the handler is an App.HomeRoute\");\n // Using Ember.copy removes any private Ember vars which older IE would be confused by\n deepEqual(Ember.copy(obj, true), { name: \"Tom Dale\" }, \"the context is correct\");\n start();\n }\n }\n });\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"{{name}}\"\n );\n\n bootApplication();\n\n var actionId = Ember.$(\"#qunit-fixture a\").data(\"ember-action\");\n var action = Ember.Handlebars.ActionHelper.registeredActions[actionId];\n var event = new Ember.$.Event(\"click\");\n action.handler(event);\n});\n\nasyncTest(\"Events defined in `events` object are triggered on the current state when routes are nested (DEPRECATED)\", function() {\n Ember.TESTING_DEPRECATION = true;\n Router.map(function() {\n this.resource(\"root\", { path: \"/\" }, function() {\n this.route(\"index\", { path: \"/\" });\n });\n });\n\n var model = { name: \"Tom Dale\" };\n\n App.RootRoute = Ember.Route.extend({\n events: {\n showStuff: function(obj) {\n ok(this instanceof App.RootRoute, \"the handler is an App.HomeRoute\");\n // Using Ember.copy removes any private Ember vars which older IE would be confused by\n deepEqual(Ember.copy(obj, true), { name: \"Tom Dale\" }, \"the context is correct\");\n start();\n }\n }\n });\n\n App.RootIndexRoute = Ember.Route.extend({\n model: function() {\n return model;\n }\n });\n\n Ember.TEMPLATES['root/index'] = Ember.Handlebars.compile(\n \"{{name}}\"\n );\n\n bootApplication();\n\n var actionId = Ember.$(\"#qunit-fixture a\").data(\"ember-action\");\n var action = Ember.Handlebars.ActionHelper.registeredActions[actionId];\n var event = new Ember.$.Event(\"click\");\n action.handler(event);\n});\n\ntest(\"Events can be handled by inherited event handlers\", function() {\n\n expect(4);\n\n App.SuperRoute = Ember.Route.extend({\n actions: {\n foo: function() {\n ok(true, 'foo');\n },\n bar: function(msg) {\n equal(msg, \"HELLO\");\n }\n }\n });\n\n App.RouteMixin = Ember.Mixin.create({\n actions: {\n bar: function(msg) {\n equal(msg, \"HELLO\");\n this._super(msg);\n }\n }\n });\n\n App.IndexRoute = App.SuperRoute.extend(App.RouteMixin, {\n actions: {\n baz: function() {\n ok(true, 'baz');\n }\n }\n });\n\n bootApplication();\n\n router.send(\"foo\");\n router.send(\"bar\", \"HELLO\");\n router.send(\"baz\");\n});\n\nasyncTest(\"Events are triggered on the controller if a matching action name is implemented as a method (DEPRECATED)\", function() {\n Ember.TESTING_DEPRECATION = true;\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n });\n\n var model = { name: \"Tom Dale\" };\n var stateIsNotCalled = true;\n\n App.HomeRoute = Ember.Route.extend({\n model: function() {\n return model;\n },\n\n events: {\n showStuff: function(obj) {\n stateIsNotCalled = false;\n }\n }\n });\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"{{name}}\"\n );\n\n var controller = Ember.Controller.extend({\n showStuff: function(context) {\n ok (stateIsNotCalled, \"an event on the state is not triggered\");\n deepEqual(context, { name: \"Tom Dale\" }, \"an event with context is passed\");\n start();\n }\n });\n\n container.register('controller:home', controller);\n\n bootApplication();\n\n var actionId = Ember.$(\"#qunit-fixture a\").data(\"ember-action\");\n var action = Ember.Handlebars.ActionHelper.registeredActions[actionId];\n var event = new Ember.$.Event(\"click\");\n action.handler(event);\n});\n\n\nasyncTest(\"actions can be triggered with multiple arguments\", function() {\n Router.map(function() {\n this.resource(\"root\", { path: \"/\" }, function() {\n this.route(\"index\", { path: \"/\" });\n });\n });\n\n var model1 = { name: \"Tilde\" },\n model2 = { name: \"Tom Dale\" };\n\n App.RootRoute = Ember.Route.extend({\n actions: {\n showStuff: function(obj1, obj2) {\n ok(this instanceof App.RootRoute, \"the handler is an App.HomeRoute\");\n // Using Ember.copy removes any private Ember vars which older IE would be confused by\n deepEqual(Ember.copy(obj1, true), { name: \"Tilde\" }, \"the first context is correct\");\n deepEqual(Ember.copy(obj2, true), { name: \"Tom Dale\" }, \"the second context is correct\");\n start();\n }\n }\n });\n\n App.RootIndexController = Ember.Controller.extend({\n model1: model1,\n model2: model2\n });\n\n Ember.TEMPLATES['root/index'] = Ember.Handlebars.compile(\n \"{{model1.name}}\"\n );\n\n bootApplication();\n\n var actionId = Ember.$(\"#qunit-fixture a\").data(\"ember-action\");\n var action = Ember.Handlebars.ActionHelper.registeredActions[actionId];\n var event = new Ember.$.Event(\"click\");\n action.handler(event);\n});\n\ntest(\"transitioning multiple times in a single run loop only sets the URL once\", function() {\n Router.map(function() {\n this.route(\"root\", { path: \"/\" });\n this.route(\"foo\");\n this.route(\"bar\");\n });\n\n bootApplication();\n\n var urlSetCount = 0;\n\n router.get('location').setURL = function(path) {\n urlSetCount++;\n set(this, 'path', path);\n };\n\n equal(urlSetCount, 0);\n\n Ember.run(function() {\n router.transitionTo(\"foo\");\n router.transitionTo(\"bar\");\n });\n\n equal(urlSetCount, 1);\n equal(router.get('location').getURL(), \"/bar\");\n});\n\ntest('navigating away triggers a url property change', function() {\n\n expect(3);\n\n Router.map(function() {\n this.route('root', { path: '/' });\n this.route('foo', { path: '/foo' });\n this.route('bar', { path: '/bar' });\n });\n\n bootApplication();\n\n Ember.run(function() {\n Ember.addObserver(router, 'url', function() {\n ok(true, \"url change event was fired\");\n });\n });\n\n forEach(['foo', 'bar', '/foo'], function(destination) {\n Ember.run(router, 'transitionTo', destination);\n });\n});\n\ntest(\"using replaceWith calls location.replaceURL if available\", function() {\n var setCount = 0,\n replaceCount = 0;\n\n Router.reopen({\n location: Ember.NoneLocation.createWithMixins({\n setURL: function(path) {\n setCount++;\n set(this, 'path', path);\n },\n\n replaceURL: function(path) {\n replaceCount++;\n set(this, 'path', path);\n }\n })\n });\n\n Router.map(function() {\n this.route(\"root\", { path: \"/\" });\n this.route(\"foo\");\n });\n\n bootApplication();\n\n equal(setCount, 0);\n equal(replaceCount, 0);\n\n Ember.run(function() {\n router.replaceWith(\"foo\");\n });\n\n equal(setCount, 0, 'should not call setURL');\n equal(replaceCount, 1, 'should call replaceURL once');\n equal(router.get('location').getURL(), \"/foo\");\n});\n\ntest(\"using replaceWith calls setURL if location.replaceURL is not defined\", function() {\n var setCount = 0;\n\n Router.reopen({\n location: Ember.NoneLocation.createWithMixins({\n setURL: function(path) {\n setCount++;\n set(this, 'path', path);\n }\n })\n });\n\n Router.map(function() {\n this.route(\"root\", { path: \"/\" });\n this.route(\"foo\");\n });\n\n bootApplication();\n\n equal(setCount, 0);\n\n Ember.run(function() {\n router.replaceWith(\"foo\");\n });\n\n equal(setCount, 1, 'should call setURL once');\n equal(router.get('location').getURL(), \"/foo\");\n});\n\ntest(\"It is possible to get the model from a parent route\", function() {\n expect(9);\n\n Router.map(function() {\n this.resource(\"the_post\", { path: \"/posts/:post_id\" }, function() {\n this.resource(\"comments\");\n });\n });\n\n var post1 = {}, post2 = {}, post3 = {}, currentPost;\n\n var posts = {\n 1: post1,\n 2: post2,\n 3: post3\n };\n\n App.ThePostRoute = Ember.Route.extend({\n model: function(params) {\n return posts[params.post_id];\n }\n });\n\n App.CommentsRoute = Ember.Route.extend({\n model: function() {\n // Allow both underscore / camelCase format.\n equal(this.modelFor('thePost'), currentPost);\n equal(this.modelFor('the_post'), currentPost);\n }\n });\n\n bootApplication();\n\n currentPost = post1;\n handleURL(\"/posts/1/comments\");\n\n currentPost = post2;\n handleURL(\"/posts/2/comments\");\n\n currentPost = post3;\n handleURL(\"/posts/3/comments\");\n});\n\ntest(\"A redirection hook is provided\", function() {\n Router.map(function() {\n this.route(\"choose\", { path: \"/\" });\n this.route(\"home\");\n });\n\n var chooseFollowed = 0, destination;\n\n App.ChooseRoute = Ember.Route.extend({\n redirect: function() {\n if (destination) {\n this.transitionTo(destination);\n }\n },\n\n setupController: function() {\n chooseFollowed++;\n }\n });\n\n destination = 'home';\n\n bootApplication();\n\n equal(chooseFollowed, 0, \"The choose route wasn't entered since a transition occurred\");\n equal(Ember.$(\"h3:contains(Hours)\", \"#qunit-fixture\").length, 1, \"The home template was rendered\");\n equal(router.container.lookup('controller:application').get('currentPath'), 'home');\n});\n\ntest(\"Redirecting from the middle of a route aborts the remainder of the routes\", function() {\n expect(3);\n\n Router.map(function() {\n this.route(\"home\");\n this.resource(\"foo\", function() {\n this.resource(\"bar\", function() {\n this.route(\"baz\");\n });\n });\n });\n\n App.BarRoute = Ember.Route.extend({\n redirect: function() {\n this.transitionTo(\"home\");\n },\n setupController: function() {\n ok(false, \"Should transition before setupController\");\n }\n });\n\n App.BarBazRoute = Ember.Route.extend({\n enter: function() {\n ok(false, \"Should abort transition getting to next route\");\n }\n });\n\n bootApplication();\n\n handleURLAborts(\"/foo/bar/baz\");\n\n equal(router.container.lookup('controller:application').get('currentPath'), 'home');\n equal(router.get('location').getURL(), \"/home\");\n});\n\ntest(\"Redirecting to the current target in the middle of a route does not abort initial routing\", function() {\n expect(5);\n\n Router.map(function() {\n this.route(\"home\");\n this.resource(\"foo\", function() {\n this.resource(\"bar\", function() {\n this.route(\"baz\");\n });\n });\n });\n\n var successCount = 0;\n App.BarRoute = Ember.Route.extend({\n redirect: function() {\n this.transitionTo(\"bar.baz\").then(function() {\n successCount++;\n });\n },\n\n setupController: function() {\n ok(true, \"Should still invoke bar's setupController\");\n }\n });\n\n App.BarBazRoute = Ember.Route.extend({\n setupController: function() {\n ok(true, \"Should still invoke bar.baz's setupController\");\n }\n });\n\n bootApplication();\n\n handleURL(\"/foo/bar/baz\");\n\n equal(router.container.lookup('controller:application').get('currentPath'), 'foo.bar.baz');\n equal(successCount, 1, 'transitionTo success handler was called once');\n\n});\n\ntest(\"Redirecting to the current target with a different context aborts the remainder of the routes\", function() {\n expect(4);\n\n Router.map(function() {\n this.route(\"home\");\n this.resource(\"foo\", function() {\n this.resource(\"bar\", { path: \"bar/:id\" }, function() {\n this.route(\"baz\");\n });\n });\n });\n\n var model = { id: 2 };\n\n var count = 0;\n\n App.BarRoute = Ember.Route.extend({\n afterModel: function(context) {\n if (count++ > 10) {\n ok(false, 'infinite loop');\n } else {\n this.transitionTo(\"bar.baz\", model);\n }\n },\n\n serialize: function(params) {\n return params;\n }\n });\n\n App.BarBazRoute = Ember.Route.extend({\n setupController: function() {\n ok(true, \"Should still invoke setupController\");\n }\n });\n\n bootApplication();\n\n handleURLAborts(\"/foo/bar/1/baz\");\n\n equal(router.container.lookup('controller:application').get('currentPath'), 'foo.bar.baz');\n equal(router.get('location').getURL(), \"/foo/bar/2/baz\");\n});\n\ntest(\"Transitioning from a parent event does not prevent currentPath from being set\", function() {\n Router.map(function() {\n this.resource(\"foo\", function() {\n this.resource(\"bar\", function() {\n this.route(\"baz\");\n });\n this.route(\"qux\");\n });\n });\n\n App.FooRoute = Ember.Route.extend({\n actions: {\n goToQux: function() {\n this.transitionTo('foo.qux');\n }\n }\n });\n\n bootApplication();\n\n var applicationController = router.container.lookup('controller:application');\n\n handleURL(\"/foo/bar/baz\");\n\n equal(applicationController.get('currentPath'), 'foo.bar.baz');\n\n Ember.run(function() {\n router.send(\"goToQux\");\n });\n\n equal(applicationController.get('currentPath'), 'foo.qux');\n equal(router.get('location').getURL(), \"/foo/qux\");\n});\n\ntest(\"Generated names can be customized when providing routes with dot notation\", function() {\n expect(4);\n\n Ember.TEMPLATES.index = compile(\"
    Index
    \");\n Ember.TEMPLATES.application = compile(\"

    Home

    {{outlet}}
    \");\n Ember.TEMPLATES.foo = compile(\"
    {{outlet}}
    \");\n Ember.TEMPLATES.bar = compile(\"
    {{outlet}}
    \");\n Ember.TEMPLATES['bar/baz'] = compile(\"

    {{name}}Bottom!

    \");\n\n Router.map(function() {\n this.resource(\"foo\", { path: \"/top\" }, function() {\n this.resource(\"bar\", { path: \"/middle\" }, function() {\n this.route(\"baz\", { path: \"/bottom\" });\n });\n });\n });\n\n App.FooRoute = Ember.Route.extend({\n renderTemplate: function() {\n ok(true, \"FooBarRoute was called\");\n return this._super.apply(this, arguments);\n }\n });\n\n App.BarBazRoute = Ember.Route.extend({\n renderTemplate: function() {\n ok(true, \"BarBazRoute was called\");\n return this._super.apply(this, arguments);\n }\n });\n\n App.BarController = Ember.Controller.extend({\n name: \"Bar\"\n });\n\n App.BarBazController = Ember.Controller.extend({\n name: \"BarBaz\"\n });\n\n bootApplication();\n\n handleURL(\"/top/middle/bottom\");\n\n equal(Ember.$('.main .middle .bottom p', '#qunit-fixture').text(), \"BarBazBottom!\", \"The templates were rendered into their appropriate parents\");\n});\n\ntest(\"Child routes render into their parent route's template by default\", function() {\n Ember.TEMPLATES.index = compile(\"
    Index
    \");\n Ember.TEMPLATES.application = compile(\"

    Home

    {{outlet}}
    \");\n Ember.TEMPLATES.top = compile(\"
    {{outlet}}
    \");\n Ember.TEMPLATES.middle = compile(\"
    {{outlet}}
    \");\n Ember.TEMPLATES['middle/bottom'] = compile(\"

    Bottom!

    \");\n\n Router.map(function() {\n this.resource(\"top\", function() {\n this.resource(\"middle\", function() {\n this.route(\"bottom\");\n });\n });\n });\n\n bootApplication();\n\n handleURL(\"/top/middle/bottom\");\n\n equal(Ember.$('.main .middle .bottom p', '#qunit-fixture').text(), \"Bottom!\", \"The templates were rendered into their appropriate parents\");\n});\n\ntest(\"Child routes render into specified template\", function() {\n Ember.TEMPLATES.index = compile(\"
    Index
    \");\n Ember.TEMPLATES.application = compile(\"

    Home

    {{outlet}}
    \");\n Ember.TEMPLATES.top = compile(\"
    {{outlet}}
    \");\n Ember.TEMPLATES.middle = compile(\"
    {{outlet}}
    \");\n Ember.TEMPLATES['middle/bottom'] = compile(\"

    Bottom!

    \");\n\n Router.map(function() {\n this.resource(\"top\", function() {\n this.resource(\"middle\", function() {\n this.route(\"bottom\");\n });\n });\n });\n\n App.MiddleBottomRoute = Ember.Route.extend({\n renderTemplate: function() {\n this.render('middle/bottom', { into: 'top' });\n }\n });\n\n bootApplication();\n\n handleURL(\"/top/middle/bottom\");\n\n equal(Ember.$('.main .middle .bottom p', '#qunit-fixture').length, 0, \"should not render into the middle template\");\n equal(Ember.$('.main .middle > p', '#qunit-fixture').text(), \"Bottom!\", \"The template was rendered into the top template\");\n});\n\ntest(\"Rendering into specified template with slash notation\", function() {\n Ember.TEMPLATES['person/profile'] = compile(\"profile {{outlet}}\");\n Ember.TEMPLATES['person/details'] = compile(\"details!\");\n\n Router.map(function() {\n this.resource(\"home\", { path: '/' });\n });\n\n App.HomeRoute = Ember.Route.extend({\n renderTemplate: function() {\n this.render('person/profile');\n this.render('person/details', { into: 'person/profile' });\n }\n });\n\n bootApplication();\n\n equal(Ember.$('#qunit-fixture:contains(profile details!)').length, 1, \"The templates were rendered\");\n});\n\n\ntest(\"Parent route context change\", function() {\n var editCount = 0,\n editedPostIds = Ember.A();\n\n Ember.TEMPLATES.application = compile(\"{{outlet}}\");\n Ember.TEMPLATES.posts = compile(\"{{outlet}}\");\n Ember.TEMPLATES.post = compile(\"{{outlet}}\");\n Ember.TEMPLATES['post/index'] = compile(\"showing\");\n Ember.TEMPLATES['post/edit'] = compile(\"editing\");\n\n Router.map(function() {\n this.resource(\"posts\", function() {\n this.resource(\"post\", { path: \"/:postId\" }, function() {\n this.route(\"edit\");\n });\n });\n });\n\n App.PostsRoute = Ember.Route.extend({\n actions: {\n showPost: function(context) {\n this.transitionTo('post', context);\n }\n }\n });\n\n App.PostRoute = Ember.Route.extend({\n model: function(params) {\n return {id: params.postId};\n },\n\n actions: {\n editPost: function(context) {\n this.transitionTo('post.edit');\n }\n }\n });\n\n App.PostEditRoute = Ember.Route.extend({\n model: function(params) {\n var postId = this.modelFor(\"post\").id;\n editedPostIds.push(postId);\n return null;\n },\n setup: function() {\n this._super.apply(this, arguments);\n editCount++;\n }\n });\n\n bootApplication();\n\n handleURL(\"/posts/1\");\n\n Ember.run(function() {\n router.send('editPost');\n });\n\n Ember.run(function() {\n router.send('showPost', {id: '2'});\n });\n\n Ember.run(function() {\n router.send('editPost');\n });\n\n equal(editCount, 2, 'set up the edit route twice without failure');\n deepEqual(editedPostIds, ['1', '2'], 'modelFor posts.post returns the right context');\n});\n\ntest(\"Router accounts for rootURL on page load when using history location\", function() {\n var rootURL = window.location.pathname + '/app',\n postsTemplateRendered = false,\n setHistory,\n HistoryTestLocation;\n\n setHistory = function(obj, path) {\n obj.set('history', { state: { path: path } });\n };\n\n // Create new implementation that extends HistoryLocation\n // and set current location to rootURL + '/posts'\n HistoryTestLocation = Ember.HistoryLocation.extend({\n initState: function() {\n var path = rootURL + '/posts';\n\n setHistory(this, path);\n this.set('location', {\n pathname: path\n });\n },\n\n replaceState: function(path) {\n setHistory(this, path);\n },\n\n pushState: function(path) {\n setHistory(this, path);\n }\n });\n\n Ember.Location.registerImplementation('historyTest', HistoryTestLocation);\n\n Router.reopen({\n location: 'historyTest',\n rootURL: rootURL\n });\n\n Router.map(function() {\n this.resource(\"posts\", { path: '/posts' });\n });\n\n App.PostsRoute = Ember.Route.extend({\n model: function() {},\n renderTemplate: function() {\n postsTemplateRendered = true;\n }\n });\n\n bootApplication();\n\n ok(postsTemplateRendered, \"Posts route successfully stripped from rootURL\");\n\n // clean after test\n delete Ember.Location.implementations['historyTest'];\n});\n\ntest(\"HistoryLocation has the correct rootURL on initState and webkit doesn't fire popstate on page load\", function() {\n expect(2);\n var rootURL = window.location.pathname,\n history,\n HistoryTestLocation;\n\n history = { replaceState: function() {} };\n\n HistoryTestLocation = Ember.HistoryLocation.extend({\n history: history,\n initState: function() {\n equal(this.get('rootURL'), rootURL);\n this._super();\n // these two should be equal to be able\n // to successfully detect webkit initial popstate\n equal(this._previousURL, this.getURL());\n }\n });\n\n Ember.Location.registerImplementation('historyTest', HistoryTestLocation);\n\n Router.reopen({\n location: 'historyTest',\n rootURL: rootURL\n });\n\n bootApplication();\n\n // clean after test\n delete Ember.Location.implementations['historyTest'];\n});\n\n\ntest(\"Only use route rendered into main outlet for default into property on child\", function() {\n Ember.TEMPLATES.application = compile(\"{{outlet menu}}{{outlet}}\");\n Ember.TEMPLATES.posts = compile(\"{{outlet}}\");\n Ember.TEMPLATES['posts/index'] = compile(\"postsIndex\");\n Ember.TEMPLATES['posts/menu'] = compile(\"postsMenu\");\n\n Router.map(function() {\n this.resource(\"posts\", function() {});\n });\n\n App.PostsMenuView = Ember.View.extend({\n tagName: 'div',\n templateName: 'posts/menu',\n classNames: ['posts-menu']\n });\n\n App.PostsIndexView = Ember.View.extend({\n tagName: 'p',\n classNames: ['posts-index']\n });\n\n App.PostsRoute = Ember.Route.extend({\n renderTemplate: function() {\n this.render();\n this.render('postsMenu', {\n into: 'application',\n outlet: 'menu'\n });\n }\n });\n\n bootApplication();\n\n handleURL(\"/posts\");\n\n equal(Ember.$('div.posts-menu:contains(postsMenu)', '#qunit-fixture').length, 1, \"The posts/menu template was rendered\");\n equal(Ember.$('p.posts-index:contains(postsIndex)', '#qunit-fixture').length, 1, \"The posts/index template was rendered\");\n});\n\ntest(\"Generating a URL should not affect currentModel\", function() {\n Router.map(function() {\n this.route(\"post\", { path: \"/posts/:post_id\" });\n });\n\n var posts = {\n 1: { id: 1 },\n 2: { id: 2 }\n };\n\n App.PostRoute = Ember.Route.extend({\n model: function(params) {\n return posts[params.post_id];\n }\n });\n\n bootApplication();\n\n handleURL(\"/posts/1\");\n\n var route = container.lookup('route:post');\n equal(route.modelFor('post'), posts[1]);\n\n var url = router.generate('post', posts[2]);\n equal(url, \"/posts/2\");\n\n equal(route.modelFor('post'), posts[1]);\n});\n\n\ntest(\"Generated route should be an instance of App.Route if provided\", function() {\n var generatedRoute;\n\n Router.map(function() {\n this.route('posts');\n });\n\n App.Route = Ember.Route.extend();\n\n bootApplication();\n\n handleURL(\"/posts\");\n\n generatedRoute = container.lookup('route:posts');\n\n ok(generatedRoute instanceof App.Route, 'should extend the correct route');\n\n});\n\ntest(\"Nested index route is not overriden by parent's implicit index route\", function() {\n Router.map(function() {\n this.resource('posts', function() {\n this.route('index', { path: ':category' } );\n });\n });\n\n App.Route = Ember.Route.extend({\n serialize: function(model) {\n return { category: model.category };\n }\n });\n\n bootApplication();\n\n Ember.run(function() {\n router.transitionTo('posts', { category: 'emberjs' });\n });\n\n deepEqual(router.location.path, '/posts/emberjs');\n});\n\ntest(\"Application template does not duplicate when re-rendered\", function() {\n Ember.TEMPLATES.application = compile(\"

    I Render Once

    {{outlet}}\");\n\n Router.map(function() {\n this.route('posts');\n });\n\n App.ApplicationRoute = Ember.Route.extend({\n model: function() {\n return Ember.A();\n }\n });\n\n bootApplication();\n\n // should cause application template to re-render\n handleURL('/posts');\n\n equal(Ember.$('h3:contains(I Render Once)').size(), 1);\n});\n\ntest(\"Child routes should render inside the application template if the application template causes a redirect\", function() {\n Ember.TEMPLATES.application = compile(\"

    App

    {{outlet}}\");\n Ember.TEMPLATES.posts = compile(\"posts\");\n\n Router.map(function() {\n this.route('posts');\n this.route('photos');\n });\n\n App.ApplicationRoute = Ember.Route.extend({\n afterModel: function() {\n this.transitionTo('posts');\n }\n });\n\n bootApplication();\n\n equal(Ember.$('#qunit-fixture > div').text(), \"App posts\");\n});\n\ntest(\"The template is not re-rendered when the route's context changes\", function() {\n Router.map(function() {\n this.route(\"page\", { path: \"/page/:name\" });\n });\n\n App.PageRoute = Ember.Route.extend({\n model: function(params) {\n return Ember.Object.create({name: params.name});\n }\n });\n\n var insertionCount = 0;\n App.PageView = Ember.View.extend({\n didInsertElement: function() {\n insertionCount += 1;\n }\n });\n\n Ember.TEMPLATES.page = Ember.Handlebars.compile(\n \"

    {{name}}

    \"\n );\n\n bootApplication();\n\n handleURL(\"/page/first\");\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"first\");\n equal(insertionCount, 1);\n\n handleURL(\"/page/second\");\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"second\");\n equal(insertionCount, 1, \"view should have inserted only once\");\n\n Ember.run(function() {\n router.transitionTo('page', Ember.Object.create({name: 'third'}));\n });\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"third\");\n equal(insertionCount, 1, \"view should still have inserted only once\");\n});\n\n\ntest(\"The template is not re-rendered when two routes present the exact same template, view, & controller\", function() {\n Router.map(function() {\n this.route(\"first\");\n this.route(\"second\");\n this.route(\"third\");\n this.route(\"fourth\");\n });\n\n App.SharedRoute = Ember.Route.extend({\n viewName: 'shared',\n setupController: function(controller) {\n this.controllerFor('shared').set('message', \"This is the \" + this.routeName + \" message\");\n },\n\n renderTemplate: function(controller, context) {\n this.render({ controller: 'shared' });\n }\n });\n\n App.FirstRoute = App.SharedRoute.extend();\n App.SecondRoute = App.SharedRoute.extend();\n App.ThirdRoute = App.SharedRoute.extend();\n App.FourthRoute = App.SharedRoute.extend({\n viewName: 'fourth'\n });\n\n App.SharedController = Ember.Controller.extend();\n\n var insertionCount = 0;\n App.SharedView = Ember.View.extend({\n templateName: 'shared',\n didInsertElement: function() {\n insertionCount += 1;\n }\n });\n\n // Extending, in essence, creates a different view\n App.FourthView = App.SharedView.extend();\n\n Ember.TEMPLATES.shared = Ember.Handlebars.compile(\n \"

    {{message}}

    \"\n );\n\n bootApplication();\n\n handleURL(\"/first\");\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"This is the first message\");\n equal(insertionCount, 1, 'expected one assertion');\n\n // Transition by URL\n handleURL(\"/second\");\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"This is the second message\");\n equal(insertionCount, 1, \"view should have inserted only once\");\n\n // Then transition directly by route name\n Ember.run(function() {\n router.transitionTo('third').then(function(value){\n ok(true, 'expected transition');\n }, function(reason) {\n ok(false, 'unexpected transition failure: ', QUnit.jsDump.parse(reason));\n });\n });\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"This is the third message\");\n equal(insertionCount, 1, \"view should still have inserted only once\");\n\n // Lastly transition to a different view, with the same controller and template\n handleURL(\"/fourth\");\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"This is the fourth message\");\n equal(insertionCount, 2, \"view should have inserted a second time\");\n});\n\ntest(\"ApplicationRoute with model does not proxy the currentPath\", function() {\n var model = {};\n var currentPath;\n\n App.ApplicationRoute = Ember.Route.extend({\n model: function () { return model; }\n });\n\n App.ApplicationController = Ember.ObjectController.extend({\n currentPathDidChange: Ember.observer('currentPath', function() {\n currentPath = get(this, 'currentPath');\n })\n });\n\n bootApplication();\n\n equal(currentPath, 'index', 'currentPath is index');\n equal('currentPath' in model, false, 'should have defined currentPath on controller');\n});\n\ntest(\"Promises encountered on app load put app into loading state until resolved\", function() {\n\n expect(2);\n\n var deferred = Ember.RSVP.defer();\n\n App.IndexRoute = Ember.Route.extend({\n model: function() {\n return deferred.promise;\n }\n });\n\n Ember.TEMPLATES.index = Ember.Handlebars.compile(\"

    INDEX

    \");\n Ember.TEMPLATES.loading = Ember.Handlebars.compile(\"

    LOADING

    \");\n\n bootApplication();\n\n equal(Ember.$('p', '#qunit-fixture').text(), \"LOADING\", \"The loading state is displaying.\");\n Ember.run(deferred.resolve);\n equal(Ember.$('p', '#qunit-fixture').text(), \"INDEX\", \"The index route is display.\");\n});\n\ntest(\"Route should tear down multiple outlets\", function() {\n Ember.TEMPLATES.application = compile(\"{{outlet menu}}{{outlet}}{{outlet footer}}\");\n Ember.TEMPLATES.posts = compile(\"{{outlet}}\");\n Ember.TEMPLATES.users = compile(\"users\");\n Ember.TEMPLATES['posts/index'] = compile(\"postsIndex\");\n Ember.TEMPLATES['posts/menu'] = compile(\"postsMenu\");\n Ember.TEMPLATES['posts/footer'] = compile(\"postsFooter\");\n\n Router.map(function() {\n this.resource(\"posts\", function() {});\n this.resource(\"users\", function() {});\n });\n\n App.PostsMenuView = Ember.View.extend({\n tagName: 'div',\n templateName: 'posts/menu',\n classNames: ['posts-menu']\n });\n\n App.PostsIndexView = Ember.View.extend({\n tagName: 'p',\n classNames: ['posts-index']\n });\n\n App.PostsFooterView = Ember.View.extend({\n tagName: 'div',\n templateName: 'posts/footer',\n classNames: ['posts-footer']\n });\n\n App.PostsRoute = Ember.Route.extend({\n renderTemplate: function() {\n this.render('postsMenu', {\n into: 'application',\n outlet: 'menu'\n });\n\n this.render();\n\n this.render('postsFooter', {\n into: 'application',\n outlet: 'footer'\n });\n }\n });\n\n bootApplication();\n\n handleURL('/posts');\n\n equal(Ember.$('div.posts-menu:contains(postsMenu)', '#qunit-fixture').length, 1, \"The posts/menu template was rendered\");\n equal(Ember.$('p.posts-index:contains(postsIndex)', '#qunit-fixture').length, 1, \"The posts/index template was rendered\");\n equal(Ember.$('div.posts-footer:contains(postsFooter)', '#qunit-fixture').length, 1, \"The posts/footer template was rendered\");\n\n handleURL('/users');\n\n equal(Ember.$('div.posts-menu:contains(postsMenu)', '#qunit-fixture').length, 0, \"The posts/menu template was removed\");\n equal(Ember.$('p.posts-index:contains(postsIndex)', '#qunit-fixture').length, 0, \"The posts/index template was removed\");\n equal(Ember.$('div.posts-footer:contains(postsFooter)', '#qunit-fixture').length, 0, \"The posts/footer template was removed\");\n\n});\n\n\ntest(\"Route supports clearing outlet explicitly\", function() {\n Ember.TEMPLATES.application = compile(\"{{outlet}}{{outlet modal}}\");\n Ember.TEMPLATES.posts = compile(\"{{outlet}}\");\n Ember.TEMPLATES.users = compile(\"users\");\n Ember.TEMPLATES['posts/index'] = compile(\"postsIndex {{outlet}}\");\n Ember.TEMPLATES['posts/modal'] = compile(\"postsModal\");\n Ember.TEMPLATES['posts/extra'] = compile(\"postsExtra\");\n\n Router.map(function() {\n this.resource(\"posts\", function() {});\n this.resource(\"users\", function() {});\n });\n\n App.PostsIndexView = Ember.View.extend({\n classNames: ['posts-index']\n });\n\n App.PostsModalView = Ember.View.extend({\n templateName: 'posts/modal',\n classNames: ['posts-modal']\n });\n\n App.PostsExtraView = Ember.View.extend({\n templateName: 'posts/extra',\n classNames: ['posts-extra']\n });\n\n App.PostsRoute = Ember.Route.extend({\n actions: {\n showModal: function() {\n this.render('postsModal', {\n into: 'application',\n outlet: 'modal'\n });\n },\n hideModal: function() {\n this.disconnectOutlet({outlet: 'modal', parentView: 'application'});\n }\n }\n });\n\n App.PostsIndexRoute = Ember.Route.extend({\n actions: {\n showExtra: function() {\n this.render('postsExtra', {\n into: 'posts/index'\n });\n },\n hideExtra: function() {\n this.disconnectOutlet({parentView: 'posts/index'});\n }\n }\n });\n\n bootApplication();\n\n handleURL('/posts');\n\n equal(Ember.$('div.posts-index:contains(postsIndex)', '#qunit-fixture').length, 1, \"The posts/index template was rendered\");\n Ember.run(function() {\n router.send('showModal');\n });\n equal(Ember.$('div.posts-modal:contains(postsModal)', '#qunit-fixture').length, 1, \"The posts/modal template was rendered\");\n Ember.run(function() {\n router.send('showExtra');\n });\n equal(Ember.$('div.posts-extra:contains(postsExtra)', '#qunit-fixture').length, 1, \"The posts/extra template was rendered\");\n Ember.run(function() {\n router.send('hideModal');\n });\n equal(Ember.$('div.posts-modal:contains(postsModal)', '#qunit-fixture').length, 0, \"The posts/modal template was removed\");\n Ember.run(function() {\n router.send('hideExtra');\n });\n equal(Ember.$('div.posts-extra:contains(postsExtra)', '#qunit-fixture').length, 0, \"The posts/extra template was removed\");\n\n handleURL('/users');\n\n equal(Ember.$('div.posts-index:contains(postsIndex)', '#qunit-fixture').length, 0, \"The posts/index template was removed\");\n equal(Ember.$('div.posts-modal:contains(postsModal)', '#qunit-fixture').length, 0, \"The posts/modal template was removed\");\n equal(Ember.$('div.posts-extra:contains(postsExtra)', '#qunit-fixture').length, 0, \"The posts/extra template was removed\");\n});\n\nif (!Ember.FEATURES.isEnabled(\"ember-routing-loading-error-substates\")) {\n test(\"Aborting/redirecting the transition in `willTransition` prevents LoadingRoute from being entered\", function() {\n\n expect(8);\n\n Router.map(function() {\n this.route(\"nork\");\n this.route(\"about\");\n });\n\n var redirect = false;\n\n App.IndexRoute = Ember.Route.extend({\n actions: {\n willTransition: function(transition) {\n ok(true, \"willTransition was called\");\n if (redirect) {\n // router.js won't refire `willTransition` for this redirect\n this.transitionTo('about');\n } else {\n transition.abort();\n }\n }\n }\n });\n\n var deferred = null;\n\n App.LoadingRoute = Ember.Route.extend({\n activate: function() {\n ok(deferred, \"LoadingRoute should be entered at this time\");\n },\n deactivate: function() {\n ok(true, \"LoadingRoute was exited\");\n }\n });\n\n App.NorkRoute = Ember.Route.extend({\n activate: function() {\n ok(true, \"NorkRoute was entered\");\n }\n });\n\n App.AboutRoute = Ember.Route.extend({\n activate: function() {\n ok(true, \"AboutRoute was entered\");\n },\n model: function() {\n if (deferred) { return deferred.promise; }\n }\n });\n\n bootApplication();\n\n // Attempted transitions out of index should abort.\n Ember.run(router, 'transitionTo', 'nork');\n Ember.run(router, 'handleURL', '/nork');\n\n // Attempted transitions out of index should redirect to about\n redirect = true;\n Ember.run(router, 'transitionTo', 'nork');\n Ember.run(router, 'transitionTo', 'index');\n\n // Redirected transitions out of index to a route with a\n // promise model should pause the transition and\n // activate LoadingRoute\n deferred = Ember.RSVP.defer();\n Ember.run(router, 'transitionTo', 'nork');\n Ember.run(deferred.resolve);\n });\n}\n\nif (Ember.FEATURES.isEnabled(\"ember-routing-didTransition-hook\")) {\n test(\"`didTransition` event fires on the router\", function() {\n expect(3);\n\n Router.map(function(){\n this.route(\"nork\");\n });\n\n router = container.lookup('router:main');\n\n router.one('didTransition', function(){\n ok(true, 'didTransition fired on initial routing');\n });\n\n bootApplication();\n\n router.one('didTransition', function(){\n ok(true, 'didTransition fired on the router');\n equal(router.get('url'), \"/nork\", 'The url property is updated by the time didTransition fires');\n });\n\n Ember.run(router, 'transitionTo', 'nork');\n });\n test(\"`didTransition` can be reopened\", function() {\n expect(1);\n\n Router.map(function(){\n this.route(\"nork\");\n });\n\n Router.reopen({\n didTransition: function(){\n this._super.apply(this, arguments);\n ok(true, 'reopened didTransition was called');\n }\n });\n\n bootApplication();\n });\n}\n\ntest(\"Actions can be handled by inherited action handlers\", function() {\n\n expect(4);\n\n App.SuperRoute = Ember.Route.extend({\n actions: {\n foo: function() {\n ok(true, 'foo');\n },\n bar: function(msg) {\n equal(msg, \"HELLO\");\n }\n }\n });\n\n App.RouteMixin = Ember.Mixin.create({\n actions: {\n bar: function(msg) {\n equal(msg, \"HELLO\");\n this._super(msg);\n }\n }\n });\n\n App.IndexRoute = App.SuperRoute.extend(App.RouteMixin, {\n actions: {\n baz: function() {\n ok(true, 'baz');\n }\n }\n });\n\n bootApplication();\n\n router.send(\"foo\");\n router.send(\"bar\", \"HELLO\");\n router.send(\"baz\");\n});\n\ntest(\"currentRouteName is a property installed on ApplicationController that can be used in transitionTo\", function() {\n\n expect(24);\n\n Router.map(function() {\n this.resource(\"be\", function() {\n this.resource(\"excellent\", function() {\n this.resource(\"to\", function() {\n this.resource(\"each\", function() {\n this.route(\"other\");\n });\n });\n });\n });\n });\n\n bootApplication();\n\n var appController = router.container.lookup('controller:application');\n\n function transitionAndCheck(path, expectedPath, expectedRouteName) {\n if (path) { Ember.run(router, 'transitionTo', path); }\n equal(appController.get('currentPath'), expectedPath);\n equal(appController.get('currentRouteName'), expectedRouteName);\n }\n\n transitionAndCheck(null, 'index', 'index');\n transitionAndCheck('/be', 'be.index', 'be.index');\n transitionAndCheck('/be/excellent', 'be.excellent.index', 'excellent.index');\n transitionAndCheck('/be/excellent/to', 'be.excellent.to.index', 'to.index');\n transitionAndCheck('/be/excellent/to/each', 'be.excellent.to.each.index', 'each.index');\n transitionAndCheck('/be/excellent/to/each/other', 'be.excellent.to.each.other', 'each.other');\n\n transitionAndCheck('index', 'index', 'index');\n transitionAndCheck('be', 'be.index', 'be.index');\n transitionAndCheck('excellent', 'be.excellent.index', 'excellent.index');\n transitionAndCheck('to.index', 'be.excellent.to.index', 'to.index');\n transitionAndCheck('each', 'be.excellent.to.each.index', 'each.index');\n transitionAndCheck('each.other', 'be.excellent.to.each.other', 'each.other');\n});\n\ntest(\"Route model hook finds the same model as a manual find\", function() {\n var Post;\n App.Post = Ember.Object.extend();\n App.Post.reopenClass({\n find: function() {\n Post = this;\n return {};\n }\n });\n\n Router.map(function() {\n this.route('post', { path: '/post/:post_id' });\n });\n\n bootApplication();\n\n handleURL('/post/1');\n\n equal(App.Post, Post);\n});\n\n})();\n//@ sourceURL=ember/~tests/routing/basic_test");minispade.register('ember/~tests/routing/query_params_test', "(function() {var Router, App, AppView, templates, router, container, originalTemplates;\nvar get = Ember.get, set = Ember.set;\n\nfunction bootApplication(url) {\n router = container.lookup('router:main');\n if(url) { router.location.setURL(url); }\n Ember.run(App, 'advanceReadiness');\n}\n\nfunction compile(string) {\n return Ember.Handlebars.compile(string);\n}\n\nfunction handleURL(path) {\n return Ember.run(function() {\n return router.handleURL(path).then(function(value) {\n ok(true, 'url: `' + path + '` was handled');\n return value;\n }, function(reason) {\n ok(false, 'failed to visit:`' + path + '` reason: `' + QUnit.jsDump.parse(reason));\n throw reason;\n });\n });\n}\n\nfunction handleURLAborts(path) {\n Ember.run(function() {\n router.handleURL(path).then(function(value) {\n ok(false, 'url: `' + path + '` was NOT to be handled');\n }, function(reason) {\n ok(reason && reason.message === \"TransitionAborted\", 'url: `' + path + '` was to be aborted');\n });\n });\n}\n\nfunction shouldNotHappen(error) {\n console.error(error.stack);\n ok(false, \"this .then handler should not be called: \" + error.message);\n}\n\nfunction handleURLRejectsWith(path, expectedReason) {\n Ember.run(function() {\n router.handleURL(path).then(function(value) {\n ok(false, 'expected handleURLing: `' + path + '` to fail');\n }, function(reason) {\n equal(expectedReason, reason);\n });\n });\n}\nif (Ember.FEATURES.isEnabled(\"query-params\")) {\n module(\"Routing with Query Params\", {\n setup: function() {\n Ember.run(function() {\n App = Ember.Application.create({\n name: \"App\",\n rootElement: '#qunit-fixture'\n });\n\n App.deferReadiness();\n\n App.Router.reopen({\n location: 'none'\n });\n\n Router = App.Router;\n\n App.LoadingRoute = Ember.Route.extend({\n });\n\n container = App.__container__;\n\n originalTemplates = Ember.$.extend({}, Ember.TEMPLATES);\n Ember.TEMPLATES.application = compile(\"{{outlet}}\");\n Ember.TEMPLATES.home = compile(\"

    Hours

    \");\n Ember.TEMPLATES.homepage = compile(\"

    Megatroll

    {{home}}

    \");\n Ember.TEMPLATES.camelot = compile('

    Is a silly place

    ');\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n App.destroy();\n App = null;\n\n Ember.TEMPLATES = originalTemplates;\n });\n }\n });\n\n test(\"The Homepage with Query Params\", function() {\n expect(5);\n\n Router.map(function() {\n this.route(\"index\", { path: \"/\", queryParams: ['foo', 'baz'] });\n });\n\n App.IndexRoute = Ember.Route.extend({\n beforeModel: function(queryParams, transition) {\n deepEqual(queryParams, {foo: 'bar', baz: true}, \"beforeModel hook is called with query params\");\n },\n\n model: function(params, queryParams, transition) {\n deepEqual(queryParams, {foo: 'bar', baz: true}, \"Model hook is called with query params\");\n },\n\n afterModel: function(resolvedModel, queryParams, transition) {\n deepEqual(queryParams, {foo: 'bar', baz: true}, \"afterModel hook is called with query params\");\n },\n\n setupController: function (controller, context, queryParams) {\n deepEqual(queryParams, {foo: 'bar', baz: true}, \"setupController hook is called with query params\");\n },\n\n renderTemplate: function (controller, context, queryParams) {\n deepEqual(queryParams, {foo: 'bar', baz: true}, \"renderTemplates hook is called with query params\");\n }\n\n });\n\n\n bootApplication(\"/?foo=bar&baz\");\n });\n\n\n asyncTest(\"Transitioning query params works on the same route\", function() {\n expect(25);\n\n var expectedQueryParams;\n\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.resource(\"special\", { path: \"/specials/:menu_item_id\", queryParams: ['view'] });\n });\n\n App.SpecialRoute = Ember.Route.extend({\n beforeModel: function (queryParams, transition) {\n deepEqual(queryParams, expectedQueryParams, \"The query params are correct in the beforeModel hook\");\n },\n\n model: function(params, queryParams, transition) {\n deepEqual(queryParams, expectedQueryParams, \"The query params are correct in the model hook\");\n return {id: params.menu_item_id};\n },\n\n afterModel: function (resolvedModel, queryParams, transition) {\n deepEqual(queryParams, expectedQueryParams, \"The query params are correct in the beforeModel hook\");\n },\n\n setupController: function (controller, context, queryParams) {\n deepEqual(queryParams, expectedQueryParams, \"The query params are correct in the setupController hook\");\n },\n\n renderTemplate: function (controller, context, queryParams) {\n deepEqual(queryParams, expectedQueryParams, \"The query params are correct in the renderTemplates hook\");\n },\n\n serialize: function (obj) {\n return {menu_item_id: obj.id};\n }\n });\n\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"

    Home

    \"\n );\n\n\n Ember.TEMPLATES.special = Ember.Handlebars.compile(\n \"

    {{content.id}}

    \"\n );\n\n bootApplication();\n\n var transition = handleURL('/');\n\n Ember.run(function() {\n transition.then(function() {\n equal(Ember.$('h3', '#qunit-fixture').text(), \"Home\", \"The app is now in the initial state\");\n\n expectedQueryParams = {};\n return router.transitionTo('special', {id: 1});\n }, shouldNotHappen).then(function(result) {\n deepEqual(router.location.path, '/specials/1', \"Correct URL after transitioning\");\n\n expectedQueryParams = {view: 'details'};\n return router.transitionTo('special', {queryParams: {view: 'details'}});\n }, shouldNotHappen).then(function (result) {\n deepEqual(router.location.path, '/specials/1?view=details', \"Correct URL after transitioning with route name and query params\");\n\n expectedQueryParams = {view: 'other'};\n return router.transitionTo({queryParams: {view: 'other'}});\n }, shouldNotHappen).then(function (result) {\n deepEqual(router.location.path, '/specials/1?view=other', \"Correct URL after transitioning with query params only\");\n\n expectedQueryParams = {view: 'three'};\n return router.transitionTo(\"/specials/1?view=three\");\n }, shouldNotHappen).then(function (result) {\n deepEqual(router.location.path, '/specials/1?view=three', \"Correct URL after transitioning with url\");\n\n start();\n }, shouldNotHappen);\n });\n });\n\n\n asyncTest(\"Transitioning query params works on a different route\", function() {\n expect(46);\n\n var expectedQueryParams, expectedOtherQueryParams;\n\n Router.map(function() {\n this.route(\"home\", { path: \"/\" });\n this.resource(\"special\", { path: \"/specials/:menu_item_id\", queryParams: ['view'] });\n this.resource(\"other\", { path: \"/others/:menu_item_id\", queryParams: ['view', 'lang'] });\n });\n\n App.SpecialRoute = Ember.Route.extend({\n beforeModel: function (queryParams, transition) {\n deepEqual(queryParams, expectedQueryParams, \"The query params are correct in the beforeModel hook\");\n },\n\n model: function(params, queryParams, transition) {\n deepEqual(queryParams, expectedQueryParams, \"The query params are correct in the model hook\");\n return {id: params.menu_item_id};\n },\n\n afterModel: function (resolvedModel, queryParams, transition) {\n deepEqual(queryParams, expectedQueryParams, \"The query params are correct in the beforeModel hook\");\n },\n\n setupController: function (controller, context, queryParams) {\n deepEqual(queryParams, expectedQueryParams, \"The query params are correct in the setupController hook\");\n },\n\n renderTemplate: function (controller, context, queryParams) {\n deepEqual(queryParams, expectedQueryParams, \"The query params are correct in the renderTemplates hook\");\n },\n\n serialize: function (obj) {\n return {menu_item_id: obj.id};\n }\n });\n\n App.OtherRoute = Ember.Route.extend({\n beforeModel: function (queryParams, transition) {\n deepEqual(queryParams, expectedOtherQueryParams, \"The query params are correct in the beforeModel hook\");\n },\n\n model: function(params, queryParams, transition) {\n deepEqual(queryParams, expectedOtherQueryParams, \"The query params are correct in the model hook\");\n return {id: params.menu_item_id};\n },\n\n afterModel: function (resolvedModel, queryParams, transition) {\n deepEqual(queryParams, expectedOtherQueryParams, \"The query params are correct in the beforeModel hook\");\n },\n\n setupController: function (controller, context, queryParams) {\n deepEqual(queryParams, expectedOtherQueryParams, \"The query params are correct in the setupController hook\");\n },\n\n renderTemplate: function (controller, context, queryParams) {\n deepEqual(queryParams, expectedOtherQueryParams, \"The query params are correct in the renderTemplates hook\");\n },\n\n serialize: function (obj) {\n return {menu_item_id: obj.id};\n }\n });\n\n\n\n Ember.TEMPLATES.home = Ember.Handlebars.compile(\n \"

    Home

    \"\n );\n\n\n Ember.TEMPLATES.special = Ember.Handlebars.compile(\n \"

    {{content.id}}

    \"\n );\n\n bootApplication();\n\n var transition = handleURL('/');\n\n Ember.run(function() {\n transition.then(function() {\n equal(Ember.$('h3', '#qunit-fixture').text(), \"Home\", \"The app is now in the initial state\");\n\n expectedQueryParams = {};\n\n return router.transitionTo('special', {id: 1});\n }, shouldNotHappen).then(function(result) {\n deepEqual(router.location.path, '/specials/1', \"Correct URL after transitioning\");\n\n expectedQueryParams = {view: 'details'};\n return router.transitionTo('special', {queryParams: {view: 'details'}});\n }, shouldNotHappen).then(function (result) {\n deepEqual(router.location.path, '/specials/1?view=details', \"Correct URL after transitioning with route name and query params\");\n\n expectedOtherQueryParams = {view: 'details'};\n\n return router.transitionTo('other', {id: 2});\n }, shouldNotHappen).then(function (result) {\n deepEqual(router.location.path, '/others/2?view=details', \"Correct URL after transitioning to other route\");\n\n expectedOtherQueryParams = {view: 'details', lang: 'en'};\n return router.transitionTo({queryParams: {lang: 'en'}});\n }, shouldNotHappen).then(function (result) {\n deepEqual(router.location.path, '/others/2?view=details&lang=en', \"Correct URL after transitioning to other route\");\n\n expectedQueryParams = {view: 'details'};\n\n return router.transitionTo(\"special\", {id: 2});\n }, shouldNotHappen).then(function (result) {\n deepEqual(router.location.path, '/specials/2?view=details', \"Correct URL after back to special route\");\n\n expectedQueryParams = {};\n\n return router.transitionTo({queryParams: false});\n }, shouldNotHappen).then(function (result) {\n deepEqual(router.location.path, '/specials/2', \"queryParams: false clears queryParams\");\n\n expectedQueryParams = {view: 'details'};\n\n return router.transitionTo(\"special\", {id: 2}, {queryParams: {view: 'details'}});\n }, shouldNotHappen).then(function (result) {\n deepEqual(router.location.path, '/specials/2?view=details', \"Correct URL after back to special route\");\n\n expectedQueryParams = {};\n\n return router.transitionTo(\"/specials/2\");\n }, shouldNotHappen).then(function (result) {\n deepEqual(router.location.path, '/specials/2', \"url transition clears queryParams\");\n\n start();\n }, shouldNotHappen);\n });\n });\n\n\n\n test(\"Redirecting to the current target with a different query param aborts the remainder of the routes\", function() {\n expect(4);\n\n Router.map(function() {\n this.route(\"home\");\n this.resource(\"foo\", function() {\n this.resource(\"bar\", { path: \"bar/:id\" }, function() {\n this.route(\"baz\", { queryParams: ['foo']});\n });\n });\n });\n\n var model = { id: 2 };\n\n var count = 0;\n\n App.BarRoute = Ember.Route.extend({\n afterModel: function(context) {\n if (count++ > 10) {\n ok(false, 'infinite loop');\n } else {\n this.transitionTo(\"bar.baz\", {queryParams: {foo: 'bar'}});\n }\n },\n\n serialize: function(params) {\n return params;\n }\n });\n\n App.BarBazRoute = Ember.Route.extend({\n setupController: function() {\n ok(true, \"Should still invoke setupController\");\n }\n });\n\n bootApplication();\n\n handleURLAborts(\"/foo/bar/2/baz\");\n\n equal(router.container.lookup('controller:application').get('currentPath'), 'foo.bar.baz');\n equal(router.get('location').getURL(), \"/foo/bar/2/baz?foo=bar\");\n });\n\n test(\"Parent route query params change\", function() {\n expect(4);\n\n var editCount = 0,\n expectedQueryParams = {};\n\n Ember.TEMPLATES.application = compile(\"{{outlet}}\");\n Ember.TEMPLATES.posts = compile(\"{{outlet}}\");\n Ember.TEMPLATES.post = compile(\"{{outlet}}\");\n Ember.TEMPLATES['post/index'] = compile(\"showing\");\n Ember.TEMPLATES['post/edit'] = compile(\"editing\");\n\n Router.map(function() {\n this.resource(\"posts\", {queryParams: ['sort']}, function() {\n this.resource(\"post\", { path: \"/:postId\" }, function() {\n this.route(\"edit\");\n });\n });\n });\n\n App.PostsRoute = Ember.Route.extend({\n actions: {\n sort: function(dir) {\n this.transitionTo({queryParams: {sort: dir}});\n }\n },\n\n setupController: function(controller, context, queryParams) {\n deepEqual(queryParams, expectedQueryParams, \"Posts route has correct query params\");\n }\n });\n\n App.PostRoute = Ember.Route.extend({\n actions: {\n editPost: function(context) {\n this.transitionTo('post.edit');\n }\n }\n });\n\n App.PostEditRoute = Ember.Route.extend({\n setup: function() {\n editCount++;\n }\n });\n\n bootApplication();\n\n handleURL(\"/posts/1\");\n\n Ember.run(function() {\n router.send('editPost');\n });\n\n expectedQueryParams = {sort: 'desc'};\n\n Ember.run(function() {\n router.send('sort', 'desc');\n });\n\n equal(editCount, 2, 'set up the edit route twice without failure');\n });\n\n test(\"History location can handle queryparams\", function() {\n var location = {\n pathname: \"/foo\",\n search: \"?bar=baz\"\n };\n\n var history = {\n pushState: Ember.K,\n replaceState: Ember.K\n };\n\n var historyLocation = Ember.HistoryLocation.create({location: location, history: history});\n\n equal(historyLocation.getURL(), \"/foo?bar=baz\", \"The query params are present\");\n });\n\n test(\"Hash location can handle urlencoded queryparams (issue #3390)\", function() {\n // Firefox automatically de-url-encodes the hash, however we need it to\n // be URL encoded so that encoded data can be used in query params\n\n var location = {\n href: \"http://example.com#/testing?url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DkfVsfOSbJY0\",\n hash: \"#/testing?url=http://www.youtube.com/watch?v=kfVsfOSbJY0\"\n };\n\n var hashLocation = Ember.HashLocation.create({location: location});\n\n equal(hashLocation.getURL(), \"/testing?url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DkfVsfOSbJY0\", \"The query params are still URL encoded\");\n });\n\n}\n\n})();\n//@ sourceURL=ember/~tests/routing/query_params_test");minispade.register('ember/~tests/routing/substates_test', "(function() {var Router, App, AppView, templates, router, container, counter;\nvar get = Ember.get, set = Ember.set, compile = Ember.Handlebars.compile;\n\nfunction step(expectedValue, description) {\n equal(counter, expectedValue, \"Step \" + expectedValue + \": \" + description);\n counter++;\n}\n\nfunction bootApplication(startingURL) {\n\n for (var name in templates) {\n Ember.TEMPLATES[name] = compile(templates[name]);\n }\n\n if (startingURL) {\n Ember.NoneLocation.reopen({\n path: startingURL\n });\n }\n\n startingURL = startingURL || '';\n router = container.lookup('router:main');\n Ember.run(App, 'advanceReadiness');\n}\n\nfunction handleURL(path) {\n return Ember.run(function() {\n return router.handleURL(path).then(function(value) {\n ok(true, 'url: `' + path + '` was handled');\n return value;\n }, function(reason) {\n ok(false, 'failed to visit:`' + path + '` reason: `' + QUnit.jsDump.parse(reason));\n throw reason;\n });\n });\n}\n\nif (Ember.FEATURES.isEnabled(\"ember-routing-loading-error-substates\")) {\n\n module(\"Loading/Error Substates\", {\n setup: function() {\n counter = 1;\n\n Ember.run(function() {\n App = Ember.Application.create({\n name: \"App\",\n rootElement: '#qunit-fixture'\n });\n\n App.deferReadiness();\n\n App.Router.reopen({\n location: 'none'\n });\n\n Router = App.Router;\n\n container = App.__container__;\n\n templates = {\n application: '
    {{outlet}}
    ',\n index: 'INDEX',\n loading: 'LOADING',\n bro: 'BRO',\n sis: 'SIS'\n };\n });\n },\n\n teardown: function() {\n Ember.run(function() {\n App.destroy();\n App = null;\n\n Ember.TEMPLATES = {};\n });\n\n Ember.NoneLocation.reopen({\n path: ''\n });\n }\n });\n\n test(\"Slow promise from a child route of application enters nested loading state\", function() {\n\n var broModel = {}, broDeferred = Ember.RSVP.defer();\n\n Router.map(function() {\n this.route('bro');\n });\n\n App.ApplicationRoute = Ember.Route.extend({\n setupController: function() {\n step(2, \"ApplicationRoute#setup\");\n }\n });\n\n App.BroRoute = Ember.Route.extend({\n model: function() {\n step(1, \"BroRoute#model\");\n return broDeferred.promise;\n }\n });\n\n bootApplication('/bro');\n\n equal(Ember.$('#app', '#qunit-fixture').text(), \"LOADING\", \"The Loading template is nested in application template's outlet\");\n\n Ember.run(broDeferred, 'resolve', broModel);\n\n equal(Ember.$('#app', '#qunit-fixture').text(), \"BRO\", \"bro template has loaded and replaced loading template\");\n });\n\n test(\"Slow promises waterfall on startup\", function() {\n\n expect(7);\n\n var grandmaDeferred = Ember.RSVP.defer(),\n sallyDeferred = Ember.RSVP.defer();\n\n Router.map(function() {\n this.resource('grandma', function() {\n this.resource('mom', function() {\n this.route('sally');\n });\n });\n });\n\n templates.grandma = \"GRANDMA {{outlet}}\";\n templates.mom = \"MOM {{outlet}}\";\n templates['mom/loading'] = \"MOMLOADING\";\n templates['mom/sally'] = \"SALLY\";\n\n App.GrandmaRoute = Ember.Route.extend({\n model: function() {\n step(1, \"GrandmaRoute#model\");\n return grandmaDeferred.promise;\n }\n });\n\n App.MomRoute = Ember.Route.extend({\n model: function() {\n step(2, \"Mom#model\");\n return {};\n }\n });\n\n App.MomSallyRoute = Ember.Route.extend({\n model: function() {\n step(3, \"SallyRoute#model\");\n return sallyDeferred.promise;\n },\n setupController: function() {\n step(4, \"SallyRoute#setupController\");\n }\n });\n\n bootApplication('/grandma/mom/sally');\n\n equal(Ember.$('#app', '#qunit-fixture').text(), \"LOADING\", \"The Loading template is nested in application template's outlet\");\n\n Ember.run(grandmaDeferred, 'resolve', {});\n equal(Ember.$('#app', '#qunit-fixture').text(), \"GRANDMA MOM MOMLOADING\", \"Mom's child loading route is displayed due to sally's slow promise\");\n\n Ember.run(sallyDeferred, 'resolve', {});\n equal(Ember.$('#app', '#qunit-fixture').text(), \"GRANDMA MOM SALLY\", \"Sally template displayed\");\n });\n\n test(\"ApplicationRoute#currentPath reflects loading state path\", function() {\n\n expect(4);\n\n var momDeferred = Ember.RSVP.defer();\n\n Router.map(function() {\n this.resource('grandma', function() {\n this.route('mom');\n });\n });\n\n templates.grandma = \"GRANDMA {{outlet}}\";\n templates['grandma/loading'] = \"GRANDMALOADING\";\n templates['grandma/mom'] = \"MOM\";\n\n App.GrandmaMomRoute = Ember.Route.extend({\n model: function() {\n return momDeferred.promise;\n }\n });\n\n bootApplication('/grandma/mom');\n\n equal(Ember.$('#app', '#qunit-fixture').text(), \"GRANDMA GRANDMALOADING\");\n\n var appController = container.lookup('controller:application');\n equal(appController.get('currentPath'), \"grandma.loading\", \"currentPath reflects loading state\");\n\n Ember.run(momDeferred, 'resolve', {});\n equal(Ember.$('#app', '#qunit-fixture').text(), \"GRANDMA MOM\");\n equal(appController.get('currentPath'), \"grandma.mom\", \"currentPath reflects final state\");\n });\n\n test(\"Slow promises returned from ApplicationRoute#model don't enter LoadingRoute\", function() {\n\n expect(2);\n\n var appDeferred = Ember.RSVP.defer();\n\n App.ApplicationRoute = Ember.Route.extend({\n model: function() {\n return appDeferred.promise;\n }\n });\n\n App.LoadingRoute = Ember.Route.extend({\n setupController: function() {\n ok(false, \"shouldn't get here\");\n }\n });\n\n bootApplication();\n\n equal(Ember.$('#app', '#qunit-fixture').text(), \"\", \"nothing has been rendered yet\");\n\n Ember.run(appDeferred, 'resolve', {});\n equal(Ember.$('#app', '#qunit-fixture').text(), \"INDEX\");\n });\n\n test(\"Don't enter loading route unless either route or template defined\", function() {\n\n delete templates.loading;\n\n expect(2);\n\n var indexDeferred = Ember.RSVP.defer();\n\n App.ApplicationController = Ember.Controller.extend();\n\n App.IndexRoute = Ember.Route.extend({\n model: function() {\n return indexDeferred.promise;\n }\n });\n\n bootApplication();\n\n var appController = container.lookup('controller:application');\n ok(appController.get('currentPath') !== \"loading\", \"loading state not entered\");\n\n Ember.run(indexDeferred, 'resolve', {});\n equal(Ember.$('#app', '#qunit-fixture').text(), \"INDEX\");\n });\n\n test(\"Enter loading route if only LoadingRoute defined\", function() {\n\n delete templates.loading;\n\n expect(4);\n\n var indexDeferred = Ember.RSVP.defer();\n\n App.IndexRoute = Ember.Route.extend({\n model: function() {\n step(1, \"IndexRoute#model\");\n return indexDeferred.promise;\n }\n });\n\n App.LoadingRoute = Ember.Route.extend({\n setupController: function() {\n step(2, \"LoadingRoute#setupController\");\n }\n });\n\n bootApplication();\n\n var appController = container.lookup('controller:application');\n equal(appController.get('currentPath'), \"loading\", \"loading state entered\");\n\n Ember.run(indexDeferred, 'resolve', {});\n equal(Ember.$('#app', '#qunit-fixture').text(), \"INDEX\");\n });\n\n test(\"Enter child loading state of pivot route\", function() {\n\n expect(4);\n\n var deferred = Ember.RSVP.defer();\n\n Router.map(function() {\n this.resource('grandma', function() {\n this.resource('mom', function() {\n this.route('sally');\n });\n this.route('smells');\n });\n });\n\n templates['grandma/loading'] = \"GMONEYLOADING\";\n\n App.ApplicationController = Ember.Controller.extend();\n\n App.MomSallyRoute = Ember.Route.extend({\n setupController: function() {\n step(1, \"SallyRoute#setupController\");\n }\n });\n\n App.GrandmaSmellsRoute = Ember.Route.extend({\n model: function() {\n return deferred.promise;\n }\n });\n\n bootApplication('/grandma/mom/sally');\n\n var appController = container.lookup('controller:application');\n equal(appController.get('currentPath'), \"grandma.mom.sally\", \"Initial route fully loaded\");\n\n Ember.run(router, 'transitionTo', 'grandma.smells');\n equal(appController.get('currentPath'), \"grandma.loading\", \"in pivot route's child loading state\");\n\n Ember.run(deferred, 'resolve', {});\n\n equal(appController.get('currentPath'), \"grandma.smells\", \"Finished transition\");\n });\n\n test(\"Loading actions bubble to root, but don't enter substates above pivot\", function() {\n\n expect(6);\n\n delete templates.loading;\n\n var sallyDeferred = Ember.RSVP.defer(),\n smellsDeferred = Ember.RSVP.defer();\n\n var shouldBubbleToApplication = true;\n\n Router.map(function() {\n this.resource('grandma', function() {\n this.resource('mom', function() {\n this.route('sally');\n });\n this.route('smells');\n });\n });\n\n App.ApplicationController = Ember.Controller.extend();\n\n App.ApplicationRoute = Ember.Route.extend({\n actions: {\n loading: function(transition, route) {\n ok(true, \"loading action received on ApplicationRoute\");\n }\n }\n });\n\n App.MomSallyRoute = Ember.Route.extend({\n model: function() {\n return sallyDeferred.promise;\n }\n });\n\n App.GrandmaSmellsRoute = Ember.Route.extend({\n model: function() {\n return smellsDeferred.promise;\n }\n });\n\n bootApplication('/grandma/mom/sally');\n\n var appController = container.lookup('controller:application');\n ok(!appController.get('currentPath'), \"Initial route fully loaded\");\n Ember.run(sallyDeferred, 'resolve', {});\n\n equal(appController.get('currentPath'), \"grandma.mom.sally\", \"transition completed\");\n\n Ember.run(router, 'transitionTo', 'grandma.smells');\n equal(appController.get('currentPath'), \"grandma.mom.sally\", \"still in initial state because the only loading state is above the pivot route\");\n\n Ember.run(smellsDeferred, 'resolve', {});\n\n equal(appController.get('currentPath'), \"grandma.smells\", \"Finished transition\");\n });\n\n test(\"Default error event moves into nested route\", function() {\n\n expect(5);\n\n templates['grandma'] = \"GRANDMA {{outlet}}\";\n templates['grandma/error'] = \"ERROR: {{msg}}\";\n\n Router.map(function() {\n this.resource('grandma', function() {\n this.resource('mom', function() {\n this.route('sally');\n });\n });\n });\n\n App.ApplicationController = Ember.Controller.extend();\n\n App.MomSallyRoute = Ember.Route.extend({\n model: function() {\n step(1, \"MomSallyRoute#model\");\n\n return Ember.RSVP.reject({\n msg: \"did it broke?\"\n });\n },\n actions: {\n error: function() {\n step(2, \"MomSallyRoute#actions.error\");\n return true;\n }\n }\n });\n\n bootApplication('/grandma/mom/sally');\n\n step(3, \"App finished booting\");\n\n equal(Ember.$('#app', '#qunit-fixture').text(), \"GRANDMA ERROR: did it broke?\", \"error bubbles\");\n\n var appController = container.lookup('controller:application');\n equal(appController.get('currentPath'), 'grandma.error', \"Initial route fully loaded\");\n });\n\n}\n\n})();\n//@ sourceURL=ember/~tests/routing/substates_test");minispade.register('ember/~tests/states_removal_test', "(function() {module(\"ember-states removal\");\n\ntest(\"errors occur when attempting to use Ember.StateManager or Ember.State\", function() {\n raises(function() {\n Ember.StateManager.extend();\n }, /has been moved into a plugin/);\n\n raises(function() {\n Ember.State.extend();\n }, /has been moved into a plugin/);\n\n raises(function() {\n Ember.StateManager.create();\n }, /has been moved into a plugin/);\n\n raises(function() {\n Ember.State.create();\n }, /has been moved into a plugin/);\n});\n})();\n//@ sourceURL=ember/~tests/states_removal_test");