ember-source 1.9.0.alpha.2 → 1.9.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ember-source might be problematic. Click here for more details.

@@ -2,6 +2,11 @@
2
2
  var Ember = { assert: function() {}, FEATURES: { isEnabled: function() {} } };
3
3
  /* global Handlebars:true */
4
4
 
5
+ // Remove "use strict"; from transpiled module (in browser builds only) until
6
+ // https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed
7
+ //
8
+ // REMOVE_USE_STRICT: true
9
+
5
10
  /**
6
11
  @module ember
7
12
  @submodule ember-handlebars-compiler
@@ -0,0 +1,1529 @@
1
+ /*!
2
+ * @overview Ember - JavaScript Application Framework
3
+ * @copyright Copyright 2011-2014 Tilde Inc. and contributors
4
+ * Portions Copyright 2006-2011 Strobe Inc.
5
+ * Portions Copyright 2008-2011 Apple Inc. All rights reserved.
6
+ * @license Licensed under MIT license
7
+ * See https://raw.github.com/emberjs/ember.js/master/LICENSE
8
+ * @version 1.9.0-beta.1
9
+ */
10
+
11
+ (function() {
12
+ var enifed, requireModule, eriuqer, requirejs, Ember;
13
+
14
+ (function() {
15
+ Ember = this.Ember = this.Ember || {};
16
+ if (typeof Ember === 'undefined') { Ember = {}; };
17
+
18
+ if (typeof Ember.__loader === 'undefined') {
19
+ var registry = {}, seen = {};
20
+
21
+ enifed = function(name, deps, callback) {
22
+ registry[name] = { deps: deps, callback: callback };
23
+ };
24
+
25
+ requirejs = eriuqer = requireModule = function(name) {
26
+ if (seen.hasOwnProperty(name)) { return seen[name]; }
27
+ seen[name] = {};
28
+
29
+ if (!registry[name]) {
30
+ throw new Error("Could not find module " + name);
31
+ }
32
+
33
+ var mod = registry[name];
34
+ var deps = mod.deps;
35
+ var callback = mod.callback;
36
+ var reified = [];
37
+ var exports;
38
+
39
+ for (var i=0, l=deps.length; i<l; i++) {
40
+ if (deps[i] === 'exports') {
41
+ reified.push(exports = {});
42
+ } else {
43
+ reified.push(requireModule(resolve(deps[i])));
44
+ }
45
+ }
46
+
47
+ var value = callback.apply(this, reified);
48
+ return seen[name] = exports || value;
49
+
50
+ function resolve(child) {
51
+ if (child.charAt(0) !== '.') { return child; }
52
+ var parts = child.split("/");
53
+ var parentBase = name.split("/").slice(0, -1);
54
+
55
+ for (var i=0, l=parts.length; i<l; i++) {
56
+ var part = parts[i];
57
+
58
+ if (part === '..') { parentBase.pop(); }
59
+ else if (part === '.') { continue; }
60
+ else { parentBase.push(part); }
61
+ }
62
+
63
+ return parentBase.join("/");
64
+ }
65
+ };
66
+ requirejs._eak_seen = registry;
67
+
68
+ Ember.__loader = {define: enifed, require: eriuqer, registry: registry};
69
+ } else {
70
+ enifed = Ember.__loader.define;
71
+ requirejs = eriuqer = requireModule = Ember.__loader.require;
72
+ }
73
+ })();
74
+
75
+ enifed("ember-debug",
76
+ ["ember-metal/core","ember-metal/error","ember-metal/logger","exports"],
77
+ function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
78
+ "use strict";
79
+ /*global __fail__*/
80
+
81
+ var Ember = __dependency1__["default"];
82
+ var EmberError = __dependency2__["default"];
83
+ var Logger = __dependency3__["default"];
84
+
85
+ /**
86
+ Ember Debug
87
+
88
+ @module ember
89
+ @submodule ember-debug
90
+ */
91
+
92
+ /**
93
+ @class Ember
94
+ */
95
+
96
+ /**
97
+ Define an assertion that will throw an exception if the condition is not
98
+ met. Ember build tools will remove any calls to `Ember.assert()` when
99
+ doing a production build. Example:
100
+
101
+ ```javascript
102
+ // Test for truthiness
103
+ Ember.assert('Must pass a valid object', obj);
104
+
105
+ // Fail unconditionally
106
+ Ember.assert('This code path should never be run');
107
+ ```
108
+
109
+ @method assert
110
+ @param {String} desc A description of the assertion. This will become
111
+ the text of the Error thrown if the assertion fails.
112
+ @param {Boolean} test Must be truthy for the assertion to pass. If
113
+ falsy, an exception will be thrown.
114
+ */
115
+ Ember.assert = function(desc, test) {
116
+ if (!test) {
117
+ throw new EmberError("Assertion Failed: " + desc);
118
+ }
119
+ };
120
+
121
+
122
+ /**
123
+ Display a warning with the provided message. Ember build tools will
124
+ remove any calls to `Ember.warn()` when doing a production build.
125
+
126
+ @method warn
127
+ @param {String} message A warning to display.
128
+ @param {Boolean} test An optional boolean. If falsy, the warning
129
+ will be displayed.
130
+ */
131
+ Ember.warn = function(message, test) {
132
+ if (!test) {
133
+ Logger.warn("WARNING: "+message);
134
+ if ('trace' in Logger) Logger.trace();
135
+ }
136
+ };
137
+
138
+ /**
139
+ Display a debug notice. Ember build tools will remove any calls to
140
+ `Ember.debug()` when doing a production build.
141
+
142
+ ```javascript
143
+ Ember.debug('I\'m a debug notice!');
144
+ ```
145
+
146
+ @method debug
147
+ @param {String} message A debug message to display.
148
+ */
149
+ Ember.debug = function(message) {
150
+ Logger.debug("DEBUG: "+message);
151
+ };
152
+
153
+ /**
154
+ Display a deprecation warning with the provided message and a stack trace
155
+ (Chrome and Firefox only). Ember build tools will remove any calls to
156
+ `Ember.deprecate()` when doing a production build.
157
+
158
+ @method deprecate
159
+ @param {String} message A description of the deprecation.
160
+ @param {Boolean} test An optional boolean. If falsy, the deprecation
161
+ will be displayed.
162
+ */
163
+ Ember.deprecate = function(message, test) {
164
+ if (test) { return; }
165
+
166
+ if (Ember.ENV.RAISE_ON_DEPRECATION) { throw new EmberError(message); }
167
+
168
+ var error;
169
+
170
+ // When using new Error, we can't do the arguments check for Chrome. Alternatives are welcome
171
+ try { __fail__.fail(); } catch (e) { error = e; }
172
+
173
+ if (Ember.LOG_STACKTRACE_ON_DEPRECATION && error.stack) {
174
+ var stack;
175
+ var stackStr = '';
176
+
177
+ if (error['arguments']) {
178
+ // Chrome
179
+ stack = error.stack.replace(/^\s+at\s+/gm, '').
180
+ replace(/^([^\(]+?)([\n$])/gm, '{anonymous}($1)$2').
181
+ replace(/^Object.<anonymous>\s*\(([^\)]+)\)/gm, '{anonymous}($1)').split('\n');
182
+ stack.shift();
183
+ } else {
184
+ // Firefox
185
+ stack = error.stack.replace(/(?:\n@:0)?\s+$/m, '').
186
+ replace(/^\(/gm, '{anonymous}(').split('\n');
187
+ }
188
+
189
+ stackStr = "\n " + stack.slice(2).join("\n ");
190
+ message = message + stackStr;
191
+ }
192
+
193
+ Logger.warn("DEPRECATION: "+message);
194
+ };
195
+
196
+
197
+
198
+ /**
199
+ Alias an old, deprecated method with its new counterpart.
200
+
201
+ Display a deprecation warning with the provided message and a stack trace
202
+ (Chrome and Firefox only) when the assigned method is called.
203
+
204
+ Ember build tools will not remove calls to `Ember.deprecateFunc()`, though
205
+ no warnings will be shown in production.
206
+
207
+ ```javascript
208
+ Ember.oldMethod = Ember.deprecateFunc('Please use the new, updated method', Ember.newMethod);
209
+ ```
210
+
211
+ @method deprecateFunc
212
+ @param {String} message A description of the deprecation.
213
+ @param {Function} func The new function called to replace its deprecated counterpart.
214
+ @return {Function} a new function that wrapped the original function with a deprecation warning
215
+ */
216
+ Ember.deprecateFunc = function(message, func) {
217
+ return function() {
218
+ Ember.deprecate(message);
219
+ return func.apply(this, arguments);
220
+ };
221
+ };
222
+
223
+
224
+ /**
225
+ Run a function meant for debugging. Ember build tools will remove any calls to
226
+ `Ember.runInDebug()` when doing a production build.
227
+
228
+ ```javascript
229
+ Ember.runInDebug(function() {
230
+ Ember.Handlebars.EachView.reopen({
231
+ didInsertElement: function() {
232
+ console.log('I\'m happy');
233
+ }
234
+ });
235
+ });
236
+ ```
237
+
238
+ @method runInDebug
239
+ @param {Function} func The function to be executed.
240
+ @since 1.5.0
241
+ */
242
+ Ember.runInDebug = function(func) {
243
+ func();
244
+ };
245
+
246
+ /**
247
+ Will call `Ember.warn()` if ENABLE_ALL_FEATURES, ENABLE_OPTIONAL_FEATURES, or
248
+ any specific FEATURES flag is truthy.
249
+
250
+ This method is called automatically in debug canary builds.
251
+
252
+ @private
253
+ @method _warnIfUsingStrippedFeatureFlags
254
+ @return {void}
255
+ */
256
+ function _warnIfUsingStrippedFeatureFlags(FEATURES, featuresWereStripped) {
257
+ if (featuresWereStripped) {
258
+ Ember.warn('Ember.ENV.ENABLE_ALL_FEATURES is only available in canary builds.', !Ember.ENV.ENABLE_ALL_FEATURES);
259
+ Ember.warn('Ember.ENV.ENABLE_OPTIONAL_FEATURES is only available in canary builds.', !Ember.ENV.ENABLE_OPTIONAL_FEATURES);
260
+
261
+ for (var key in FEATURES) {
262
+ if (FEATURES.hasOwnProperty(key) && key !== 'isEnabled') {
263
+ Ember.warn('FEATURE["' + key + '"] is set as enabled, but FEATURE flags are only available in canary builds.', !FEATURES[key]);
264
+ }
265
+ }
266
+ }
267
+ }
268
+
269
+ __exports__._warnIfUsingStrippedFeatureFlags = _warnIfUsingStrippedFeatureFlags;if (!Ember.testing) {
270
+ // Complain if they're using FEATURE flags in builds other than canary
271
+ Ember.FEATURES['features-stripped-test'] = true;
272
+ var featuresWereStripped = true;
273
+
274
+
275
+ delete Ember.FEATURES['features-stripped-test'];
276
+ _warnIfUsingStrippedFeatureFlags(Ember.ENV.FEATURES, featuresWereStripped);
277
+
278
+ // Inform the developer about the Ember Inspector if not installed.
279
+ var isFirefox = typeof InstallTrigger !== 'undefined';
280
+ var isChrome = !!window.chrome && !window.opera;
281
+
282
+ if (typeof window !== 'undefined' && (isFirefox || isChrome) && window.addEventListener) {
283
+ window.addEventListener("load", function() {
284
+ if (document.documentElement && document.documentElement.dataset && !document.documentElement.dataset.emberExtension) {
285
+ var downloadURL;
286
+
287
+ if(isChrome) {
288
+ downloadURL = 'https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi';
289
+ } else if(isFirefox) {
290
+ downloadURL = 'https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/';
291
+ }
292
+
293
+ Ember.debug('For more advanced debugging, install the Ember Inspector from ' + downloadURL);
294
+ }
295
+ }, false);
296
+ }
297
+ }
298
+ });
299
+ enifed("ember-testing",
300
+ ["ember-metal/core","ember-testing/initializers","ember-testing/support","ember-testing/setup_for_testing","ember-testing/test","ember-testing/adapters/adapter","ember-testing/adapters/qunit","ember-testing/helpers"],
301
+ function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __dependency8__) {
302
+ "use strict";
303
+ var Ember = __dependency1__["default"];
304
+
305
+ // to setup initializer
306
+ // to handle various edge cases
307
+
308
+ var setupForTesting = __dependency4__["default"];
309
+ var Test = __dependency5__["default"];
310
+ var Adapter = __dependency6__["default"];
311
+ var QUnitAdapter = __dependency7__["default"];
312
+ // adds helpers to helpers object in Test
313
+
314
+ /**
315
+ Ember Testing
316
+
317
+ @module ember
318
+ @submodule ember-testing
319
+ @requires ember-application
320
+ */
321
+
322
+ Ember.Test = Test;
323
+ Ember.Test.Adapter = Adapter;
324
+ Ember.Test.QUnitAdapter = QUnitAdapter;
325
+ Ember.setupForTesting = setupForTesting;
326
+ });
327
+ enifed("ember-testing/adapters/adapter",
328
+ ["ember-metal/core","ember-runtime/system/object","exports"],
329
+ function(__dependency1__, __dependency2__, __exports__) {
330
+ "use strict";
331
+ var Ember = __dependency1__["default"];
332
+ // Ember.K
333
+ var EmberObject = __dependency2__["default"];
334
+
335
+ /**
336
+ @module ember
337
+ @submodule ember-testing
338
+ */
339
+
340
+ /**
341
+ The primary purpose of this class is to create hooks that can be implemented
342
+ by an adapter for various test frameworks.
343
+
344
+ @class Adapter
345
+ @namespace Ember.Test
346
+ */
347
+ var Adapter = EmberObject.extend({
348
+ /**
349
+ This callback will be called whenever an async operation is about to start.
350
+
351
+ Override this to call your framework's methods that handle async
352
+ operations.
353
+
354
+ @public
355
+ @method asyncStart
356
+ */
357
+ asyncStart: Ember.K,
358
+
359
+ /**
360
+ This callback will be called whenever an async operation has completed.
361
+
362
+ @public
363
+ @method asyncEnd
364
+ */
365
+ asyncEnd: Ember.K,
366
+
367
+ /**
368
+ Override this method with your testing framework's false assertion.
369
+ This function is called whenever an exception occurs causing the testing
370
+ promise to fail.
371
+
372
+ QUnit example:
373
+
374
+ ```javascript
375
+ exception: function(error) {
376
+ ok(false, error);
377
+ };
378
+ ```
379
+
380
+ @public
381
+ @method exception
382
+ @param {String} error The exception to be raised.
383
+ */
384
+ exception: function(error) {
385
+ throw error;
386
+ }
387
+ });
388
+
389
+ __exports__["default"] = Adapter;
390
+ });
391
+ enifed("ember-testing/adapters/qunit",
392
+ ["ember-testing/adapters/adapter","ember-metal/utils","exports"],
393
+ function(__dependency1__, __dependency2__, __exports__) {
394
+ "use strict";
395
+ var Adapter = __dependency1__["default"];
396
+ var inspect = __dependency2__.inspect;
397
+
398
+ /**
399
+ This class implements the methods defined by Ember.Test.Adapter for the
400
+ QUnit testing framework.
401
+
402
+ @class QUnitAdapter
403
+ @namespace Ember.Test
404
+ @extends Ember.Test.Adapter
405
+ */
406
+ __exports__["default"] = Adapter.extend({
407
+ asyncStart: function() {
408
+ QUnit.stop();
409
+ },
410
+ asyncEnd: function() {
411
+ QUnit.start();
412
+ },
413
+ exception: function(error) {
414
+ ok(false, inspect(error));
415
+ }
416
+ });
417
+ });
418
+ enifed("ember-testing/helpers",
419
+ ["ember-metal/property_get","ember-metal/error","ember-metal/run_loop","ember-views/system/jquery","ember-testing/test"],
420
+ function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
421
+ "use strict";
422
+ var get = __dependency1__.get;
423
+ var EmberError = __dependency2__["default"];
424
+ var run = __dependency3__["default"];
425
+ var jQuery = __dependency4__["default"];
426
+ var Test = __dependency5__["default"];
427
+
428
+ /**
429
+ * @module ember
430
+ * @submodule ember-testing
431
+ */
432
+
433
+ var helper = Test.registerHelper;
434
+ var asyncHelper = Test.registerAsyncHelper;
435
+ var countAsync = 0;
436
+
437
+ function currentRouteName(app){
438
+ var appController = app.__container__.lookup('controller:application');
439
+
440
+ return get(appController, 'currentRouteName');
441
+ }
442
+
443
+ function currentPath(app){
444
+ var appController = app.__container__.lookup('controller:application');
445
+
446
+ return get(appController, 'currentPath');
447
+ }
448
+
449
+ function currentURL(app){
450
+ var router = app.__container__.lookup('router:main');
451
+
452
+ return get(router, 'location').getURL();
453
+ }
454
+
455
+ function pauseTest(){
456
+ Test.adapter.asyncStart();
457
+ return new Ember.RSVP.Promise(function(){ }, 'TestAdapter paused promise');
458
+ }
459
+
460
+ function visit(app, url) {
461
+ var router = app.__container__.lookup('router:main');
462
+ router.location.setURL(url);
463
+
464
+ if (app._readinessDeferrals > 0) {
465
+ router['initialURL'] = url;
466
+ run(app, 'advanceReadiness');
467
+ delete router['initialURL'];
468
+ } else {
469
+ run(app, app.handleURL, url);
470
+ }
471
+
472
+ return app.testHelpers.wait();
473
+ }
474
+
475
+ function click(app, selector, context) {
476
+ var $el = app.testHelpers.findWithAssert(selector, context);
477
+ run($el, 'mousedown');
478
+
479
+ if ($el.is(':input')) {
480
+ var type = $el.prop('type');
481
+ if (type !== 'checkbox' && type !== 'radio' && type !== 'hidden') {
482
+ run($el, function(){
483
+ // Firefox does not trigger the `focusin` event if the window
484
+ // does not have focus. If the document doesn't have focus just
485
+ // use trigger('focusin') instead.
486
+ if (!document.hasFocus || document.hasFocus()) {
487
+ this.focus();
488
+ } else {
489
+ this.trigger('focusin');
490
+ }
491
+ });
492
+ }
493
+ }
494
+
495
+ run($el, 'mouseup');
496
+ run($el, 'click');
497
+
498
+ return app.testHelpers.wait();
499
+ }
500
+
501
+ function triggerEvent(app, selector, contextOrType, typeOrOptions, possibleOptions){
502
+ var arity = arguments.length;
503
+ var context, type, options;
504
+
505
+ if (arity === 3) {
506
+ // context and options are optional, so this is
507
+ // app, selector, type
508
+ context = null;
509
+ type = contextOrType;
510
+ options = {};
511
+ } else if (arity === 4) {
512
+ // context and options are optional, so this is
513
+ if (typeof typeOrOptions === "object") { // either
514
+ // app, selector, type, options
515
+ context = null;
516
+ type = contextOrType;
517
+ options = typeOrOptions;
518
+ } else { // or
519
+ // app, selector, context, type
520
+ context = contextOrType;
521
+ type = typeOrOptions;
522
+ options = {};
523
+ }
524
+ } else {
525
+ context = contextOrType;
526
+ type = typeOrOptions;
527
+ options = possibleOptions;
528
+ }
529
+
530
+ var $el = app.testHelpers.findWithAssert(selector, context);
531
+
532
+ var event = jQuery.Event(type, options);
533
+
534
+ run($el, 'trigger', event);
535
+
536
+ return app.testHelpers.wait();
537
+ }
538
+
539
+ function keyEvent(app, selector, contextOrType, typeOrKeyCode, keyCode) {
540
+ var context, type;
541
+
542
+ if (typeof keyCode === 'undefined') {
543
+ context = null;
544
+ keyCode = typeOrKeyCode;
545
+ type = contextOrType;
546
+ } else {
547
+ context = contextOrType;
548
+ type = typeOrKeyCode;
549
+ }
550
+
551
+ return app.testHelpers.triggerEvent(selector, context, type, { keyCode: keyCode, which: keyCode });
552
+ }
553
+
554
+ function fillIn(app, selector, contextOrText, text) {
555
+ var $el, context;
556
+ if (typeof text === 'undefined') {
557
+ text = contextOrText;
558
+ } else {
559
+ context = contextOrText;
560
+ }
561
+ $el = app.testHelpers.findWithAssert(selector, context);
562
+ run(function() {
563
+ $el.val(text).change();
564
+ });
565
+ return app.testHelpers.wait();
566
+ }
567
+
568
+ function findWithAssert(app, selector, context) {
569
+ var $el = app.testHelpers.find(selector, context);
570
+ if ($el.length === 0) {
571
+ throw new EmberError("Element " + selector + " not found.");
572
+ }
573
+ return $el;
574
+ }
575
+
576
+ function find(app, selector, context) {
577
+ var $el;
578
+ context = context || get(app, 'rootElement');
579
+ $el = app.$(selector, context);
580
+
581
+ return $el;
582
+ }
583
+
584
+ function andThen(app, callback) {
585
+ return app.testHelpers.wait(callback(app));
586
+ }
587
+
588
+ function wait(app, value) {
589
+ return Test.promise(function(resolve) {
590
+ // If this is the first async promise, kick off the async test
591
+ if (++countAsync === 1) {
592
+ Test.adapter.asyncStart();
593
+ }
594
+
595
+ // Every 10ms, poll for the async thing to have finished
596
+ var watcher = setInterval(function() {
597
+ // 1. If the router is loading, keep polling
598
+ var routerIsLoading = !!app.__container__.lookup('router:main').router.activeTransition;
599
+ if (routerIsLoading) { return; }
600
+
601
+ // 2. If there are pending Ajax requests, keep polling
602
+ if (Test.pendingAjaxRequests) { return; }
603
+
604
+ // 3. If there are scheduled timers or we are inside of a run loop, keep polling
605
+ if (run.hasScheduledTimers() || run.currentRunLoop) { return; }
606
+ if (Test.waiters && Test.waiters.any(function(waiter) {
607
+ var context = waiter[0];
608
+ var callback = waiter[1];
609
+ return !callback.call(context);
610
+ })) { return; }
611
+ // Stop polling
612
+ clearInterval(watcher);
613
+
614
+ // If this is the last async promise, end the async test
615
+ if (--countAsync === 0) {
616
+ Test.adapter.asyncEnd();
617
+ }
618
+
619
+ // Synchronously resolve the promise
620
+ run(null, resolve, value);
621
+ }, 10);
622
+ });
623
+
624
+ }
625
+
626
+
627
+ /**
628
+ * Loads a route, sets up any controllers, and renders any templates associated
629
+ * with the route as though a real user had triggered the route change while
630
+ * using your app.
631
+ *
632
+ * Example:
633
+ *
634
+ * ```javascript
635
+ * visit('posts/index').then(function() {
636
+ * // assert something
637
+ * });
638
+ * ```
639
+ *
640
+ * @method visit
641
+ * @param {String} url the name of the route
642
+ * @return {RSVP.Promise}
643
+ */
644
+ asyncHelper('visit', visit);
645
+
646
+ /**
647
+ * Clicks an element and triggers any actions triggered by the element's `click`
648
+ * event.
649
+ *
650
+ * Example:
651
+ *
652
+ * ```javascript
653
+ * click('.some-jQuery-selector').then(function() {
654
+ * // assert something
655
+ * });
656
+ * ```
657
+ *
658
+ * @method click
659
+ * @param {String} selector jQuery selector for finding element on the DOM
660
+ * @return {RSVP.Promise}
661
+ */
662
+ asyncHelper('click', click);
663
+
664
+ /**
665
+ * Simulates a key event, e.g. `keypress`, `keydown`, `keyup` with the desired keyCode
666
+ *
667
+ * Example:
668
+ *
669
+ * ```javascript
670
+ * keyEvent('.some-jQuery-selector', 'keypress', 13).then(function() {
671
+ * // assert something
672
+ * });
673
+ * ```
674
+ *
675
+ * @method keyEvent
676
+ * @param {String} selector jQuery selector for finding element on the DOM
677
+ * @param {String} type the type of key event, e.g. `keypress`, `keydown`, `keyup`
678
+ * @param {Number} keyCode the keyCode of the simulated key event
679
+ * @return {RSVP.Promise}
680
+ * @since 1.5.0
681
+ */
682
+ asyncHelper('keyEvent', keyEvent);
683
+
684
+ /**
685
+ * Fills in an input element with some text.
686
+ *
687
+ * Example:
688
+ *
689
+ * ```javascript
690
+ * fillIn('#email', 'you@example.com').then(function() {
691
+ * // assert something
692
+ * });
693
+ * ```
694
+ *
695
+ * @method fillIn
696
+ * @param {String} selector jQuery selector finding an input element on the DOM
697
+ * to fill text with
698
+ * @param {String} text text to place inside the input element
699
+ * @return {RSVP.Promise}
700
+ */
701
+ asyncHelper('fillIn', fillIn);
702
+
703
+ /**
704
+ * Finds an element in the context of the app's container element. A simple alias
705
+ * for `app.$(selector)`.
706
+ *
707
+ * Example:
708
+ *
709
+ * ```javascript
710
+ * var $el = find('.my-selector');
711
+ * ```
712
+ *
713
+ * @method find
714
+ * @param {String} selector jQuery string selector for element lookup
715
+ * @return {Object} jQuery object representing the results of the query
716
+ */
717
+ helper('find', find);
718
+
719
+ /**
720
+ * Like `find`, but throws an error if the element selector returns no results.
721
+ *
722
+ * Example:
723
+ *
724
+ * ```javascript
725
+ * var $el = findWithAssert('.doesnt-exist'); // throws error
726
+ * ```
727
+ *
728
+ * @method findWithAssert
729
+ * @param {String} selector jQuery selector string for finding an element within
730
+ * the DOM
731
+ * @return {Object} jQuery object representing the results of the query
732
+ * @throws {Error} throws error if jQuery object returned has a length of 0
733
+ */
734
+ helper('findWithAssert', findWithAssert);
735
+
736
+ /**
737
+ Causes the run loop to process any pending events. This is used to ensure that
738
+ any async operations from other helpers (or your assertions) have been processed.
739
+
740
+ This is most often used as the return value for the helper functions (see 'click',
741
+ 'fillIn','visit',etc).
742
+
743
+ Example:
744
+
745
+ ```javascript
746
+ Ember.Test.registerAsyncHelper('loginUser', function(app, username, password) {
747
+ visit('secured/path/here')
748
+ .fillIn('#username', username)
749
+ .fillIn('#password', username)
750
+ .click('.submit')
751
+
752
+ return app.testHelpers.wait();
753
+ });
754
+
755
+ @method wait
756
+ @param {Object} value The value to be returned.
757
+ @return {RSVP.Promise}
758
+ */
759
+ asyncHelper('wait', wait);
760
+ asyncHelper('andThen', andThen);
761
+
762
+
763
+ /**
764
+ Returns the currently active route name.
765
+
766
+ Example:
767
+
768
+ ```javascript
769
+ function validateRouteName(){
770
+ equal(currentRouteName(), 'some.path', "correct route was transitioned into.");
771
+ }
772
+
773
+ visit('/some/path').then(validateRouteName)
774
+ ```
775
+
776
+ @method currentRouteName
777
+ @return {Object} The name of the currently active route.
778
+ @since 1.5.0
779
+ */
780
+ helper('currentRouteName', currentRouteName);
781
+
782
+ /**
783
+ Returns the current path.
784
+
785
+ Example:
786
+
787
+ ```javascript
788
+ function validateURL(){
789
+ equal(currentPath(), 'some.path.index', "correct path was transitioned into.");
790
+ }
791
+
792
+ click('#some-link-id').then(validateURL);
793
+ ```
794
+
795
+ @method currentPath
796
+ @return {Object} The currently active path.
797
+ @since 1.5.0
798
+ */
799
+ helper('currentPath', currentPath);
800
+
801
+ /**
802
+ Returns the current URL.
803
+
804
+ Example:
805
+
806
+ ```javascript
807
+ function validateURL(){
808
+ equal(currentURL(), '/some/path', "correct URL was transitioned into.");
809
+ }
810
+
811
+ click('#some-link-id').then(validateURL);
812
+ ```
813
+
814
+ @method currentURL
815
+ @return {Object} The currently active URL.
816
+ @since 1.5.0
817
+ */
818
+ helper('currentURL', currentURL);
819
+
820
+
821
+ /**
822
+ Pauses the current test - this is useful for debugging while testing or for test-driving.
823
+ It allows you to inspect the state of your application at any point.
824
+
825
+ Example (The test will pause before clicking the button):
826
+
827
+ ```javascript
828
+ visit('/')
829
+ return pauseTest();
830
+
831
+ click('.btn');
832
+ ```
833
+
834
+ @method pauseTest
835
+ @return {Object} A promise that will never resolve
836
+ */
837
+ helper('pauseTest', pauseTest);
838
+
839
+
840
+ /**
841
+ Triggers the given DOM event on the element identified by the provided selector.
842
+
843
+ Example:
844
+
845
+ ```javascript
846
+ triggerEvent('#some-elem-id', 'blur');
847
+ ```
848
+
849
+ This is actually used internally by the `keyEvent` helper like so:
850
+
851
+ ```javascript
852
+ triggerEvent('#some-elem-id', 'keypress', { keyCode: 13 });
853
+ ```
854
+
855
+ @method triggerEvent
856
+ @param {String} selector jQuery selector for finding element on the DOM
857
+ @param {String} [context] jQuery selector that will limit the selector
858
+ argument to find only within the context's children
859
+ @param {String} type The event type to be triggered.
860
+ @param {Object} [options] The options to be passed to jQuery.Event.
861
+ @return {RSVP.Promise}
862
+ @since 1.5.0
863
+ */
864
+ asyncHelper('triggerEvent', triggerEvent);
865
+ });
866
+ enifed("ember-testing/initializers",
867
+ ["ember-runtime/system/lazy_load"],
868
+ function(__dependency1__) {
869
+ "use strict";
870
+ var onLoad = __dependency1__.onLoad;
871
+
872
+ var name = 'deferReadiness in `testing` mode';
873
+
874
+ onLoad('Ember.Application', function(Application) {
875
+ if (!Application.initializers[name]) {
876
+ Application.initializer({
877
+ name: name,
878
+
879
+ initialize: function(container, application){
880
+ if (application.testing) {
881
+ application.deferReadiness();
882
+ }
883
+ }
884
+ });
885
+ }
886
+ });
887
+ });
888
+ enifed("ember-testing/setup_for_testing",
889
+ ["ember-metal/core","ember-testing/adapters/qunit","ember-views/system/jquery","exports"],
890
+ function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
891
+ "use strict";
892
+ var Ember = __dependency1__["default"];
893
+ // import Test from "ember-testing/test"; // ES6TODO: fix when cycles are supported
894
+ var QUnitAdapter = __dependency2__["default"];
895
+ var jQuery = __dependency3__["default"];
896
+
897
+ var Test, requests;
898
+
899
+ function incrementAjaxPendingRequests(_, xhr){
900
+ requests.push(xhr);
901
+ Test.pendingAjaxRequests = requests.length;
902
+ }
903
+
904
+ function decrementAjaxPendingRequests(_, xhr){
905
+ for (var i=0;i<requests.length;i++) {
906
+ if (xhr === requests[i]) {
907
+ requests.splice(i, 1);
908
+ }
909
+ }
910
+ Test.pendingAjaxRequests = requests.length;
911
+ }
912
+
913
+ /**
914
+ Sets Ember up for testing. This is useful to perform
915
+ basic setup steps in order to unit test.
916
+
917
+ Use `App.setupForTesting` to perform integration tests (full
918
+ application testing).
919
+
920
+ @method setupForTesting
921
+ @namespace Ember
922
+ @since 1.5.0
923
+ */
924
+ __exports__["default"] = function setupForTesting() {
925
+ if (!Test) { Test = requireModule('ember-testing/test')['default']; }
926
+
927
+ Ember.testing = true;
928
+
929
+ // if adapter is not manually set default to QUnit
930
+ if (!Test.adapter) {
931
+ Test.adapter = QUnitAdapter.create();
932
+ }
933
+
934
+ requests = [];
935
+ Test.pendingAjaxRequests = requests.length;
936
+
937
+ jQuery(document).off('ajaxSend', incrementAjaxPendingRequests);
938
+ jQuery(document).off('ajaxComplete', decrementAjaxPendingRequests);
939
+ jQuery(document).on('ajaxSend', incrementAjaxPendingRequests);
940
+ jQuery(document).on('ajaxComplete', decrementAjaxPendingRequests);
941
+ }
942
+ });
943
+ enifed("ember-testing/support",
944
+ ["ember-metal/core","ember-views/system/jquery"],
945
+ function(__dependency1__, __dependency2__) {
946
+ "use strict";
947
+ var Ember = __dependency1__["default"];
948
+ var jQuery = __dependency2__["default"];
949
+
950
+ /**
951
+ @module ember
952
+ @submodule ember-testing
953
+ */
954
+
955
+ var $ = jQuery;
956
+
957
+ /**
958
+ This method creates a checkbox and triggers the click event to fire the
959
+ passed in handler. It is used to correct for a bug in older versions
960
+ of jQuery (e.g 1.8.3).
961
+
962
+ @private
963
+ @method testCheckboxClick
964
+ */
965
+ function testCheckboxClick(handler) {
966
+ $('<input type="checkbox">')
967
+ .css({ position: 'absolute', left: '-1000px', top: '-1000px' })
968
+ .appendTo('body')
969
+ .on('click', handler)
970
+ .trigger('click')
971
+ .remove();
972
+ }
973
+
974
+ $(function() {
975
+ /*
976
+ Determine whether a checkbox checked using jQuery's "click" method will have
977
+ the correct value for its checked property.
978
+
979
+ If we determine that the current jQuery version exhibits this behavior,
980
+ patch it to work correctly as in the commit for the actual fix:
981
+ https://github.com/jquery/jquery/commit/1fb2f92.
982
+ */
983
+ testCheckboxClick(function() {
984
+ if (!this.checked && !$.event.special.click) {
985
+ $.event.special.click = {
986
+ // For checkbox, fire native event so checked state will be right
987
+ trigger: function() {
988
+ if ($.nodeName( this, "input" ) && this.type === "checkbox" && this.click) {
989
+ this.click();
990
+ return false;
991
+ }
992
+ }
993
+ };
994
+ }
995
+ });
996
+
997
+ // Try again to verify that the patch took effect or blow up.
998
+ testCheckboxClick(function() {
999
+ Ember.warn("clicked checkboxes should be checked! the jQuery patch didn't work", this.checked);
1000
+ });
1001
+ });
1002
+ });
1003
+ enifed("ember-testing/test",
1004
+ ["ember-metal/core","ember-metal/run_loop","ember-metal/platform","ember-runtime/compare","ember-runtime/ext/rsvp","ember-testing/setup_for_testing","ember-application/system/application","exports"],
1005
+ function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
1006
+ "use strict";
1007
+ var Ember = __dependency1__["default"];
1008
+ var emberRun = __dependency2__["default"];
1009
+ var create = __dependency3__.create;
1010
+ var compare = __dependency4__["default"];
1011
+ var RSVP = __dependency5__["default"];
1012
+ var setupForTesting = __dependency6__["default"];
1013
+ var EmberApplication = __dependency7__["default"];
1014
+
1015
+ /**
1016
+ @module ember
1017
+ @submodule ember-testing
1018
+ */
1019
+ var slice = [].slice;
1020
+ var helpers = {};
1021
+ var injectHelpersCallbacks = [];
1022
+
1023
+ /**
1024
+ This is a container for an assortment of testing related functionality:
1025
+
1026
+ * Choose your default test adapter (for your framework of choice).
1027
+ * Register/Unregister additional test helpers.
1028
+ * Setup callbacks to be fired when the test helpers are injected into
1029
+ your application.
1030
+
1031
+ @class Test
1032
+ @namespace Ember
1033
+ */
1034
+ var Test = {
1035
+ /**
1036
+ Hash containing all known test helpers.
1037
+
1038
+ @property _helpers
1039
+ @private
1040
+ @since 1.7.0
1041
+ */
1042
+ _helpers: helpers,
1043
+
1044
+ /**
1045
+ `registerHelper` is used to register a test helper that will be injected
1046
+ when `App.injectTestHelpers` is called.
1047
+
1048
+ The helper method will always be called with the current Application as
1049
+ the first parameter.
1050
+
1051
+ For example:
1052
+
1053
+ ```javascript
1054
+ Ember.Test.registerHelper('boot', function(app) {
1055
+ Ember.run(app, app.advanceReadiness);
1056
+ });
1057
+ ```
1058
+
1059
+ This helper can later be called without arguments because it will be
1060
+ called with `app` as the first parameter.
1061
+
1062
+ ```javascript
1063
+ App = Ember.Application.create();
1064
+ App.injectTestHelpers();
1065
+ boot();
1066
+ ```
1067
+
1068
+ @public
1069
+ @method registerHelper
1070
+ @param {String} name The name of the helper method to add.
1071
+ @param {Function} helperMethod
1072
+ @param options {Object}
1073
+ */
1074
+ registerHelper: function(name, helperMethod) {
1075
+ helpers[name] = {
1076
+ method: helperMethod,
1077
+ meta: { wait: false }
1078
+ };
1079
+ },
1080
+
1081
+ /**
1082
+ `registerAsyncHelper` is used to register an async test helper that will be injected
1083
+ when `App.injectTestHelpers` is called.
1084
+
1085
+ The helper method will always be called with the current Application as
1086
+ the first parameter.
1087
+
1088
+ For example:
1089
+
1090
+ ```javascript
1091
+ Ember.Test.registerAsyncHelper('boot', function(app) {
1092
+ Ember.run(app, app.advanceReadiness);
1093
+ });
1094
+ ```
1095
+
1096
+ The advantage of an async helper is that it will not run
1097
+ until the last async helper has completed. All async helpers
1098
+ after it will wait for it complete before running.
1099
+
1100
+
1101
+ For example:
1102
+
1103
+ ```javascript
1104
+ Ember.Test.registerAsyncHelper('deletePost', function(app, postId) {
1105
+ click('.delete-' + postId);
1106
+ });
1107
+
1108
+ // ... in your test
1109
+ visit('/post/2');
1110
+ deletePost(2);
1111
+ visit('/post/3');
1112
+ deletePost(3);
1113
+ ```
1114
+
1115
+ @public
1116
+ @method registerAsyncHelper
1117
+ @param {String} name The name of the helper method to add.
1118
+ @param {Function} helperMethod
1119
+ @since 1.2.0
1120
+ */
1121
+ registerAsyncHelper: function(name, helperMethod) {
1122
+ helpers[name] = {
1123
+ method: helperMethod,
1124
+ meta: { wait: true }
1125
+ };
1126
+ },
1127
+
1128
+ /**
1129
+ Remove a previously added helper method.
1130
+
1131
+ Example:
1132
+
1133
+ ```javascript
1134
+ Ember.Test.unregisterHelper('wait');
1135
+ ```
1136
+
1137
+ @public
1138
+ @method unregisterHelper
1139
+ @param {String} name The helper to remove.
1140
+ */
1141
+ unregisterHelper: function(name) {
1142
+ delete helpers[name];
1143
+ delete Test.Promise.prototype[name];
1144
+ },
1145
+
1146
+ /**
1147
+ Used to register callbacks to be fired whenever `App.injectTestHelpers`
1148
+ is called.
1149
+
1150
+ The callback will receive the current application as an argument.
1151
+
1152
+ Example:
1153
+
1154
+ ```javascript
1155
+ Ember.Test.onInjectHelpers(function() {
1156
+ Ember.$(document).ajaxSend(function() {
1157
+ Test.pendingAjaxRequests++;
1158
+ });
1159
+
1160
+ Ember.$(document).ajaxComplete(function() {
1161
+ Test.pendingAjaxRequests--;
1162
+ });
1163
+ });
1164
+ ```
1165
+
1166
+ @public
1167
+ @method onInjectHelpers
1168
+ @param {Function} callback The function to be called.
1169
+ */
1170
+ onInjectHelpers: function(callback) {
1171
+ injectHelpersCallbacks.push(callback);
1172
+ },
1173
+
1174
+ /**
1175
+ This returns a thenable tailored for testing. It catches failed
1176
+ `onSuccess` callbacks and invokes the `Ember.Test.adapter.exception`
1177
+ callback in the last chained then.
1178
+
1179
+ This method should be returned by async helpers such as `wait`.
1180
+
1181
+ @public
1182
+ @method promise
1183
+ @param {Function} resolver The function used to resolve the promise.
1184
+ */
1185
+ promise: function(resolver) {
1186
+ return new Test.Promise(resolver);
1187
+ },
1188
+
1189
+ /**
1190
+ Used to allow ember-testing to communicate with a specific testing
1191
+ framework.
1192
+
1193
+ You can manually set it before calling `App.setupForTesting()`.
1194
+
1195
+ Example:
1196
+
1197
+ ```javascript
1198
+ Ember.Test.adapter = MyCustomAdapter.create()
1199
+ ```
1200
+
1201
+ If you do not set it, ember-testing will default to `Ember.Test.QUnitAdapter`.
1202
+
1203
+ @public
1204
+ @property adapter
1205
+ @type {Class} The adapter to be used.
1206
+ @default Ember.Test.QUnitAdapter
1207
+ */
1208
+ adapter: null,
1209
+
1210
+ /**
1211
+ Replacement for `Ember.RSVP.resolve`
1212
+ The only difference is this uses
1213
+ an instance of `Ember.Test.Promise`
1214
+
1215
+ @public
1216
+ @method resolve
1217
+ @param {Mixed} The value to resolve
1218
+ @since 1.2.0
1219
+ */
1220
+ resolve: function(val) {
1221
+ return Test.promise(function(resolve) {
1222
+ return resolve(val);
1223
+ });
1224
+ },
1225
+
1226
+ /**
1227
+ This allows ember-testing to play nicely with other asynchronous
1228
+ events, such as an application that is waiting for a CSS3
1229
+ transition or an IndexDB transaction.
1230
+
1231
+ For example:
1232
+
1233
+ ```javascript
1234
+ Ember.Test.registerWaiter(function() {
1235
+ return myPendingTransactions() == 0;
1236
+ });
1237
+ ```
1238
+ The `context` argument allows you to optionally specify the `this`
1239
+ with which your callback will be invoked.
1240
+
1241
+ For example:
1242
+
1243
+ ```javascript
1244
+ Ember.Test.registerWaiter(MyDB, MyDB.hasPendingTransactions);
1245
+ ```
1246
+
1247
+ @public
1248
+ @method registerWaiter
1249
+ @param {Object} context (optional)
1250
+ @param {Function} callback
1251
+ @since 1.2.0
1252
+ */
1253
+ registerWaiter: function(context, callback) {
1254
+ if (arguments.length === 1) {
1255
+ callback = context;
1256
+ context = null;
1257
+ }
1258
+ if (!this.waiters) {
1259
+ this.waiters = Ember.A();
1260
+ }
1261
+ this.waiters.push([context, callback]);
1262
+ },
1263
+ /**
1264
+ `unregisterWaiter` is used to unregister a callback that was
1265
+ registered with `registerWaiter`.
1266
+
1267
+ @public
1268
+ @method unregisterWaiter
1269
+ @param {Object} context (optional)
1270
+ @param {Function} callback
1271
+ @since 1.2.0
1272
+ */
1273
+ unregisterWaiter: function(context, callback) {
1274
+ var pair;
1275
+ if (!this.waiters) { return; }
1276
+ if (arguments.length === 1) {
1277
+ callback = context;
1278
+ context = null;
1279
+ }
1280
+ pair = [context, callback];
1281
+ this.waiters = Ember.A(this.waiters.filter(function(elt) {
1282
+ return compare(elt, pair)!==0;
1283
+ }));
1284
+ }
1285
+ };
1286
+
1287
+ function helper(app, name) {
1288
+ var fn = helpers[name].method;
1289
+ var meta = helpers[name].meta;
1290
+
1291
+ return function() {
1292
+ var args = slice.call(arguments);
1293
+ var lastPromise = Test.lastPromise;
1294
+
1295
+ args.unshift(app);
1296
+
1297
+ // some helpers are not async and
1298
+ // need to return a value immediately.
1299
+ // example: `find`
1300
+ if (!meta.wait) {
1301
+ return fn.apply(app, args);
1302
+ }
1303
+
1304
+ if (!lastPromise) {
1305
+ // It's the first async helper in current context
1306
+ lastPromise = fn.apply(app, args);
1307
+ } else {
1308
+ // wait for last helper's promise to resolve
1309
+ // and then execute
1310
+ run(function() {
1311
+ lastPromise = Test.resolve(lastPromise).then(function() {
1312
+ return fn.apply(app, args);
1313
+ });
1314
+ });
1315
+ }
1316
+
1317
+ return lastPromise;
1318
+ };
1319
+ }
1320
+
1321
+ function run(fn) {
1322
+ if (!emberRun.currentRunLoop) {
1323
+ emberRun(fn);
1324
+ } else {
1325
+ fn();
1326
+ }
1327
+ }
1328
+
1329
+ EmberApplication.reopen({
1330
+ /**
1331
+ This property contains the testing helpers for the current application. These
1332
+ are created once you call `injectTestHelpers` on your `Ember.Application`
1333
+ instance. The included helpers are also available on the `window` object by
1334
+ default, but can be used from this object on the individual application also.
1335
+
1336
+ @property testHelpers
1337
+ @type {Object}
1338
+ @default {}
1339
+ */
1340
+ testHelpers: {},
1341
+
1342
+ /**
1343
+ This property will contain the original methods that were registered
1344
+ on the `helperContainer` before `injectTestHelpers` is called.
1345
+
1346
+ When `removeTestHelpers` is called, these methods are restored to the
1347
+ `helperContainer`.
1348
+
1349
+ @property originalMethods
1350
+ @type {Object}
1351
+ @default {}
1352
+ @private
1353
+ @since 1.3.0
1354
+ */
1355
+ originalMethods: {},
1356
+
1357
+
1358
+ /**
1359
+ This property indicates whether or not this application is currently in
1360
+ testing mode. This is set when `setupForTesting` is called on the current
1361
+ application.
1362
+
1363
+ @property testing
1364
+ @type {Boolean}
1365
+ @default false
1366
+ @since 1.3.0
1367
+ */
1368
+ testing: false,
1369
+
1370
+ /**
1371
+ This hook defers the readiness of the application, so that you can start
1372
+ the app when your tests are ready to run. It also sets the router's
1373
+ location to 'none', so that the window's location will not be modified
1374
+ (preventing both accidental leaking of state between tests and interference
1375
+ with your testing framework).
1376
+
1377
+ Example:
1378
+
1379
+ ```
1380
+ App.setupForTesting();
1381
+ ```
1382
+
1383
+ @method setupForTesting
1384
+ */
1385
+ setupForTesting: function() {
1386
+ setupForTesting();
1387
+
1388
+ this.testing = true;
1389
+
1390
+ this.Router.reopen({
1391
+ location: 'none'
1392
+ });
1393
+ },
1394
+
1395
+ /**
1396
+ This will be used as the container to inject the test helpers into. By
1397
+ default the helpers are injected into `window`.
1398
+
1399
+ @property helperContainer
1400
+ @type {Object} The object to be used for test helpers.
1401
+ @default window
1402
+ @since 1.2.0
1403
+ */
1404
+ helperContainer: window,
1405
+
1406
+ /**
1407
+ This injects the test helpers into the `helperContainer` object. If an object is provided
1408
+ it will be used as the helperContainer. If `helperContainer` is not set it will default
1409
+ to `window`. If a function of the same name has already been defined it will be cached
1410
+ (so that it can be reset if the helper is removed with `unregisterHelper` or
1411
+ `removeTestHelpers`).
1412
+
1413
+ Any callbacks registered with `onInjectHelpers` will be called once the
1414
+ helpers have been injected.
1415
+
1416
+ Example:
1417
+ ```
1418
+ App.injectTestHelpers();
1419
+ ```
1420
+
1421
+ @method injectTestHelpers
1422
+ */
1423
+ injectTestHelpers: function(helperContainer) {
1424
+ if (helperContainer) { this.helperContainer = helperContainer; }
1425
+
1426
+ this.testHelpers = {};
1427
+ for (var name in helpers) {
1428
+ this.originalMethods[name] = this.helperContainer[name];
1429
+ this.testHelpers[name] = this.helperContainer[name] = helper(this, name);
1430
+ protoWrap(Test.Promise.prototype, name, helper(this, name), helpers[name].meta.wait);
1431
+ }
1432
+
1433
+ for(var i = 0, l = injectHelpersCallbacks.length; i < l; i++) {
1434
+ injectHelpersCallbacks[i](this);
1435
+ }
1436
+ },
1437
+
1438
+ /**
1439
+ This removes all helpers that have been registered, and resets and functions
1440
+ that were overridden by the helpers.
1441
+
1442
+ Example:
1443
+
1444
+ ```javascript
1445
+ App.removeTestHelpers();
1446
+ ```
1447
+
1448
+ @public
1449
+ @method removeTestHelpers
1450
+ */
1451
+ removeTestHelpers: function() {
1452
+ for (var name in helpers) {
1453
+ this.helperContainer[name] = this.originalMethods[name];
1454
+ delete this.testHelpers[name];
1455
+ delete this.originalMethods[name];
1456
+ }
1457
+ }
1458
+ });
1459
+
1460
+ // This method is no longer needed
1461
+ // But still here for backwards compatibility
1462
+ // of helper chaining
1463
+ function protoWrap(proto, name, callback, isAsync) {
1464
+ proto[name] = function() {
1465
+ var args = arguments;
1466
+ if (isAsync) {
1467
+ return callback.apply(this, args);
1468
+ } else {
1469
+ return this.then(function() {
1470
+ return callback.apply(this, args);
1471
+ });
1472
+ }
1473
+ };
1474
+ }
1475
+
1476
+ Test.Promise = function() {
1477
+ RSVP.Promise.apply(this, arguments);
1478
+ Test.lastPromise = this;
1479
+ };
1480
+
1481
+ Test.Promise.prototype = create(RSVP.Promise.prototype);
1482
+ Test.Promise.prototype.constructor = Test.Promise;
1483
+
1484
+ // Patch `then` to isolate async methods
1485
+ // specifically `Ember.Test.lastPromise`
1486
+ var originalThen = RSVP.Promise.prototype.then;
1487
+ Test.Promise.prototype.then = function(onSuccess, onFailure) {
1488
+ return originalThen.call(this, function(val) {
1489
+ return isolate(onSuccess, val);
1490
+ }, onFailure);
1491
+ };
1492
+
1493
+ // This method isolates nested async methods
1494
+ // so that they don't conflict with other last promises.
1495
+ //
1496
+ // 1. Set `Ember.Test.lastPromise` to null
1497
+ // 2. Invoke method
1498
+ // 3. Return the last promise created during method
1499
+ // 4. Restore `Ember.Test.lastPromise` to original value
1500
+ function isolate(fn, val) {
1501
+ var value, lastPromise;
1502
+
1503
+ // Reset lastPromise for nested helpers
1504
+ Test.lastPromise = null;
1505
+
1506
+ value = fn(val);
1507
+
1508
+ lastPromise = Test.lastPromise;
1509
+
1510
+ // If the method returned a promise
1511
+ // return that promise. If not,
1512
+ // return the last async helper's promise
1513
+ if ((value && (value instanceof Test.Promise)) || !lastPromise) {
1514
+ return value;
1515
+ } else {
1516
+ run(function() {
1517
+ lastPromise = Test.resolve(lastPromise).then(function() {
1518
+ return value;
1519
+ });
1520
+ });
1521
+ return lastPromise;
1522
+ }
1523
+ }
1524
+
1525
+ __exports__["default"] = Test;
1526
+ });
1527
+ requireModule("ember-testing");
1528
+
1529
+ })();