ember-source 1.10.1 → 1.11.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.
- 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
|
|