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