capybara-jasmine 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,629 @@
1
+ /*
2
+
3
+ Jasmine-Ajax - v3.1.0: a set of helpers for testing AJAX requests under the Jasmine
4
+ BDD framework for JavaScript.
5
+
6
+ http://github.com/jasmine/jasmine-ajax
7
+
8
+ Jasmine Home page: http://jasmine.github.io/
9
+
10
+ Copyright (c) 2008-2015 Pivotal Labs
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining
13
+ a copy of this software and associated documentation files (the
14
+ "Software"), to deal in the Software without restriction, including
15
+ without limitation the rights to use, copy, modify, merge, publish,
16
+ distribute, sublicense, and/or sell copies of the Software, and to
17
+ permit persons to whom the Software is furnished to do so, subject to
18
+ the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be
21
+ included in all copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
+
31
+ */
32
+
33
+ getJasmineRequireObj().ajax = function(jRequire) {
34
+ var $ajax = {};
35
+
36
+ $ajax.RequestStub = jRequire.AjaxRequestStub();
37
+ $ajax.RequestTracker = jRequire.AjaxRequestTracker();
38
+ $ajax.StubTracker = jRequire.AjaxStubTracker();
39
+ $ajax.ParamParser = jRequire.AjaxParamParser();
40
+ $ajax.eventBus = jRequire.AjaxEventBus();
41
+ $ajax.fakeRequest = jRequire.AjaxFakeRequest($ajax.eventBus);
42
+ $ajax.MockAjax = jRequire.MockAjax($ajax);
43
+
44
+ return $ajax.MockAjax;
45
+ };
46
+
47
+ getJasmineRequireObj().AjaxEventBus = function() {
48
+ function EventBus() {
49
+ this.eventList = {};
50
+ }
51
+
52
+ function ensureEvent(eventList, name) {
53
+ eventList[name] = eventList[name] || [];
54
+ return eventList[name];
55
+ }
56
+
57
+ function findIndex(list, thing) {
58
+ if (list.indexOf) {
59
+ return list.indexOf(thing);
60
+ }
61
+
62
+ for(var i = 0; i < list.length; i++) {
63
+ if (thing === list[i]) {
64
+ return i;
65
+ }
66
+ }
67
+
68
+ return -1;
69
+ }
70
+
71
+ EventBus.prototype.addEventListener = function(event, callback) {
72
+ ensureEvent(this.eventList, event).push(callback);
73
+ };
74
+
75
+ EventBus.prototype.removeEventListener = function(event, callback) {
76
+ var index = findIndex(this.eventList[event], callback);
77
+
78
+ if (index >= 0) {
79
+ this.eventList[event].splice(index, 1);
80
+ }
81
+ };
82
+
83
+ EventBus.prototype.trigger = function(event) {
84
+ var eventListeners = this.eventList[event];
85
+
86
+ if(eventListeners){
87
+ for(var i = 0; i < eventListeners.length; i++){
88
+ eventListeners[i]();
89
+ }
90
+ }
91
+ };
92
+
93
+ return function() {
94
+ return new EventBus();
95
+ };
96
+ };
97
+ getJasmineRequireObj().AjaxFakeRequest = function(eventBusFactory) {
98
+ function extend(destination, source, propertiesToSkip) {
99
+ propertiesToSkip = propertiesToSkip || [];
100
+ for (var property in source) {
101
+ if (!arrayContains(propertiesToSkip, property)) {
102
+ destination[property] = source[property];
103
+ }
104
+ }
105
+ return destination;
106
+ }
107
+
108
+ function arrayContains(arr, item) {
109
+ for (var i = 0; i < arr.length; i++) {
110
+ if (arr[i] === item) {
111
+ return true;
112
+ }
113
+ }
114
+ return false;
115
+ }
116
+
117
+ function wrapProgressEvent(xhr, eventName) {
118
+ return function() {
119
+ if (xhr[eventName]) {
120
+ xhr[eventName]();
121
+ }
122
+ };
123
+ }
124
+
125
+ function initializeEvents(xhr) {
126
+ xhr.eventBus.addEventListener('loadstart', wrapProgressEvent(xhr, 'onloadstart'));
127
+ xhr.eventBus.addEventListener('load', wrapProgressEvent(xhr, 'onload'));
128
+ xhr.eventBus.addEventListener('loadend', wrapProgressEvent(xhr, 'onloadend'));
129
+ xhr.eventBus.addEventListener('progress', wrapProgressEvent(xhr, 'onprogress'));
130
+ xhr.eventBus.addEventListener('error', wrapProgressEvent(xhr, 'onerror'));
131
+ xhr.eventBus.addEventListener('abort', wrapProgressEvent(xhr, 'onabort'));
132
+ xhr.eventBus.addEventListener('timeout', wrapProgressEvent(xhr, 'ontimeout'));
133
+ }
134
+
135
+ function unconvertibleResponseTypeMessage(type) {
136
+ var msg = [
137
+ "Can't build XHR.response for XHR.responseType of '",
138
+ type,
139
+ "'.",
140
+ "XHR.response must be explicitly stubbed"
141
+ ];
142
+ return msg.join(' ');
143
+ }
144
+
145
+ function fakeRequest(global, requestTracker, stubTracker, paramParser) {
146
+ function FakeXMLHttpRequest() {
147
+ requestTracker.track(this);
148
+ this.eventBus = eventBusFactory();
149
+ initializeEvents(this);
150
+ this.requestHeaders = {};
151
+ this.overriddenMimeType = null;
152
+ }
153
+
154
+ function findHeader(name, headers) {
155
+ name = name.toLowerCase();
156
+ for (var header in headers) {
157
+ if (header.toLowerCase() === name) {
158
+ return headers[header];
159
+ }
160
+ }
161
+ }
162
+
163
+ function normalizeHeaders(rawHeaders, contentType) {
164
+ var headers = [];
165
+
166
+ if (rawHeaders) {
167
+ if (rawHeaders instanceof Array) {
168
+ headers = rawHeaders;
169
+ } else {
170
+ for (var headerName in rawHeaders) {
171
+ if (rawHeaders.hasOwnProperty(headerName)) {
172
+ headers.push({ name: headerName, value: rawHeaders[headerName] });
173
+ }
174
+ }
175
+ }
176
+ } else {
177
+ headers.push({ name: "Content-Type", value: contentType || "application/json" });
178
+ }
179
+
180
+ return headers;
181
+ }
182
+
183
+ function parseXml(xmlText, contentType) {
184
+ if (global.DOMParser) {
185
+ return (new global.DOMParser()).parseFromString(xmlText, 'text/xml');
186
+ } else {
187
+ var xml = new global.ActiveXObject("Microsoft.XMLDOM");
188
+ xml.async = "false";
189
+ xml.loadXML(xmlText);
190
+ return xml;
191
+ }
192
+ }
193
+
194
+ var xmlParsables = ['text/xml', 'application/xml'];
195
+
196
+ function getResponseXml(responseText, contentType) {
197
+ if (arrayContains(xmlParsables, contentType.toLowerCase())) {
198
+ return parseXml(responseText, contentType);
199
+ } else if (contentType.match(/\+xml$/)) {
200
+ return parseXml(responseText, 'text/xml');
201
+ }
202
+ return null;
203
+ }
204
+
205
+ var iePropertiesThatCannotBeCopied = ['responseBody', 'responseText', 'responseXML', 'status', 'statusText', 'responseTimeout'];
206
+ extend(FakeXMLHttpRequest.prototype, new global.XMLHttpRequest(), iePropertiesThatCannotBeCopied);
207
+ extend(FakeXMLHttpRequest.prototype, {
208
+ open: function() {
209
+ this.method = arguments[0];
210
+ this.url = arguments[1];
211
+ this.username = arguments[3];
212
+ this.password = arguments[4];
213
+ this.readyState = 1;
214
+ this.onreadystatechange();
215
+ },
216
+
217
+ setRequestHeader: function(header, value) {
218
+ if(this.requestHeaders.hasOwnProperty(header)) {
219
+ this.requestHeaders[header] = [this.requestHeaders[header], value].join(', ');
220
+ } else {
221
+ this.requestHeaders[header] = value;
222
+ }
223
+ },
224
+
225
+ overrideMimeType: function(mime) {
226
+ this.overriddenMimeType = mime;
227
+ },
228
+
229
+ abort: function() {
230
+ this.readyState = 0;
231
+ this.status = 0;
232
+ this.statusText = "abort";
233
+ this.onreadystatechange();
234
+ this.eventBus.trigger('progress');
235
+ this.eventBus.trigger('abort');
236
+ this.eventBus.trigger('loadend');
237
+ },
238
+
239
+ readyState: 0,
240
+
241
+ onloadstart: null,
242
+ onprogress: null,
243
+ onabort: null,
244
+ onerror: null,
245
+ onload: null,
246
+ ontimeout: null,
247
+ onloadend: null,
248
+
249
+ onreadystatechange: function(isTimeout) {
250
+ },
251
+
252
+ addEventListener: function() {
253
+ this.eventBus.addEventListener.apply(this.eventBus, arguments);
254
+ },
255
+
256
+ removeEventListener: function(event, callback) {
257
+ this.eventBus.removeEventListener.apply(this.eventBus, arguments);
258
+ },
259
+
260
+ status: null,
261
+
262
+ send: function(data) {
263
+ this.params = data;
264
+ this.readyState = 2;
265
+ this.eventBus.trigger('loadstart');
266
+ this.onreadystatechange();
267
+
268
+ var stub = stubTracker.findStub(this.url, data, this.method);
269
+ if (stub) {
270
+ this.respondWith(stub);
271
+ }
272
+ },
273
+
274
+ contentType: function() {
275
+ return findHeader('content-type', this.requestHeaders);
276
+ },
277
+
278
+ data: function() {
279
+ if (!this.params) {
280
+ return {};
281
+ }
282
+
283
+ return paramParser.findParser(this).parse(this.params);
284
+ },
285
+
286
+ getResponseHeader: function(name) {
287
+ name = name.toLowerCase();
288
+ var resultHeader;
289
+ for(var i = 0; i < this.responseHeaders.length; i++) {
290
+ var header = this.responseHeaders[i];
291
+ if (name === header.name.toLowerCase()) {
292
+ if (resultHeader) {
293
+ resultHeader = [resultHeader, header.value].join(', ');
294
+ } else {
295
+ resultHeader = header.value;
296
+ }
297
+ }
298
+ }
299
+ return resultHeader;
300
+ },
301
+
302
+ getAllResponseHeaders: function() {
303
+ var responseHeaders = [];
304
+ for (var i = 0; i < this.responseHeaders.length; i++) {
305
+ responseHeaders.push(this.responseHeaders[i].name + ': ' +
306
+ this.responseHeaders[i].value);
307
+ }
308
+ return responseHeaders.join('\r\n') + '\r\n';
309
+ },
310
+
311
+ responseText: null,
312
+ response: null,
313
+ responseType: null,
314
+
315
+ responseValue: function() {
316
+ switch(this.responseType) {
317
+ case null:
318
+ case "":
319
+ case "text":
320
+ return this.readyState >= 3 ? this.responseText : "";
321
+ case "json":
322
+ return JSON.parse(this.responseText);
323
+ case "arraybuffer":
324
+ throw unconvertibleResponseTypeMessage('arraybuffer');
325
+ case "blob":
326
+ throw unconvertibleResponseTypeMessage('blob');
327
+ case "document":
328
+ return this.responseXML;
329
+ }
330
+ },
331
+
332
+
333
+ respondWith: function(response) {
334
+ if (this.readyState === 4) {
335
+ throw new Error("FakeXMLHttpRequest already completed");
336
+ }
337
+ this.status = response.status;
338
+ this.statusText = response.statusText || "";
339
+ this.responseText = response.responseText || "";
340
+ this.responseType = response.responseType || "";
341
+ this.readyState = 4;
342
+ this.responseHeaders = normalizeHeaders(response.responseHeaders, response.contentType);
343
+ this.responseXML = getResponseXml(response.responseText, this.getResponseHeader('content-type') || '');
344
+ if (this.responseXML) {
345
+ this.responseType = 'document';
346
+ }
347
+
348
+ if ('response' in response) {
349
+ this.response = response.response;
350
+ } else {
351
+ this.response = this.responseValue();
352
+ }
353
+
354
+ this.onreadystatechange();
355
+ this.eventBus.trigger('progress');
356
+ this.eventBus.trigger('load');
357
+ this.eventBus.trigger('loadend');
358
+ },
359
+
360
+ responseTimeout: function() {
361
+ if (this.readyState === 4) {
362
+ throw new Error("FakeXMLHttpRequest already completed");
363
+ }
364
+ this.readyState = 4;
365
+ jasmine.clock().tick(30000);
366
+ this.onreadystatechange('timeout');
367
+ this.eventBus.trigger('progress');
368
+ this.eventBus.trigger('timeout');
369
+ this.eventBus.trigger('loadend');
370
+ },
371
+
372
+ responseError: function() {
373
+ if (this.readyState === 4) {
374
+ throw new Error("FakeXMLHttpRequest already completed");
375
+ }
376
+ this.readyState = 4;
377
+ this.onreadystatechange();
378
+ this.eventBus.trigger('progress');
379
+ this.eventBus.trigger('error');
380
+ this.eventBus.trigger('loadend');
381
+ }
382
+ });
383
+
384
+ return FakeXMLHttpRequest;
385
+ }
386
+
387
+ return fakeRequest;
388
+ };
389
+
390
+ getJasmineRequireObj().MockAjax = function($ajax) {
391
+ function MockAjax(global) {
392
+ var requestTracker = new $ajax.RequestTracker(),
393
+ stubTracker = new $ajax.StubTracker(),
394
+ paramParser = new $ajax.ParamParser(),
395
+ realAjaxFunction = global.XMLHttpRequest,
396
+ mockAjaxFunction = $ajax.fakeRequest(global, requestTracker, stubTracker, paramParser);
397
+
398
+ this.install = function() {
399
+ if (global.XMLHttpRequest === mockAjaxFunction) {
400
+ throw "MockAjax is already installed.";
401
+ }
402
+
403
+ global.XMLHttpRequest = mockAjaxFunction;
404
+ };
405
+
406
+ this.uninstall = function() {
407
+ global.XMLHttpRequest = realAjaxFunction;
408
+
409
+ this.stubs.reset();
410
+ this.requests.reset();
411
+ paramParser.reset();
412
+ };
413
+
414
+ this.stubRequest = function(url, data, method) {
415
+ var stub = new $ajax.RequestStub(url, data, method);
416
+ stubTracker.addStub(stub);
417
+ return stub;
418
+ };
419
+
420
+ this.withMock = function(closure) {
421
+ this.install();
422
+ try {
423
+ closure();
424
+ } finally {
425
+ this.uninstall();
426
+ }
427
+ };
428
+
429
+ this.addCustomParamParser = function(parser) {
430
+ paramParser.add(parser);
431
+ };
432
+
433
+ this.requests = requestTracker;
434
+ this.stubs = stubTracker;
435
+ }
436
+
437
+ return MockAjax;
438
+ };
439
+
440
+ getJasmineRequireObj().AjaxParamParser = function() {
441
+ function ParamParser() {
442
+ var defaults = [
443
+ {
444
+ test: function(xhr) {
445
+ return (/^application\/json/).test(xhr.contentType());
446
+ },
447
+ parse: function jsonParser(paramString) {
448
+ return JSON.parse(paramString);
449
+ }
450
+ },
451
+ {
452
+ test: function(xhr) {
453
+ return true;
454
+ },
455
+ parse: function naiveParser(paramString) {
456
+ var data = {};
457
+ var params = paramString.split('&');
458
+
459
+ for (var i = 0; i < params.length; ++i) {
460
+ var kv = params[i].replace(/\+/g, ' ').split('=');
461
+ var key = decodeURIComponent(kv[0]);
462
+ data[key] = data[key] || [];
463
+ data[key].push(decodeURIComponent(kv[1]));
464
+ }
465
+ return data;
466
+ }
467
+ }
468
+ ];
469
+ var paramParsers = [];
470
+
471
+ this.add = function(parser) {
472
+ paramParsers.unshift(parser);
473
+ };
474
+
475
+ this.findParser = function(xhr) {
476
+ for(var i in paramParsers) {
477
+ var parser = paramParsers[i];
478
+ if (parser.test(xhr)) {
479
+ return parser;
480
+ }
481
+ }
482
+ };
483
+
484
+ this.reset = function() {
485
+ paramParsers = [];
486
+ for(var i in defaults) {
487
+ paramParsers.push(defaults[i]);
488
+ }
489
+ };
490
+
491
+ this.reset();
492
+ }
493
+
494
+ return ParamParser;
495
+ };
496
+
497
+ getJasmineRequireObj().AjaxRequestStub = function() {
498
+ function RequestStub(url, stubData, method) {
499
+ var normalizeQuery = function(query) {
500
+ return query ? query.split('&').sort().join('&') : undefined;
501
+ };
502
+
503
+ if (url instanceof RegExp) {
504
+ this.url = url;
505
+ this.query = undefined;
506
+ } else {
507
+ var split = url.split('?');
508
+ this.url = split[0];
509
+ this.query = split.length > 1 ? normalizeQuery(split[1]) : undefined;
510
+ }
511
+
512
+ this.data = normalizeQuery(stubData);
513
+ this.method = method;
514
+
515
+ this.andReturn = function(options) {
516
+ this.status = options.status || 200;
517
+
518
+ this.contentType = options.contentType;
519
+ this.response = options.response;
520
+ this.responseText = options.responseText;
521
+ this.responseHeaders = options.responseHeaders;
522
+ };
523
+
524
+ this.matches = function(fullUrl, data, method) {
525
+ var matches = false;
526
+ fullUrl = fullUrl.toString();
527
+ if (this.url instanceof RegExp) {
528
+ matches = this.url.test(fullUrl);
529
+ } else {
530
+ var urlSplit = fullUrl.split('?'),
531
+ url = urlSplit[0],
532
+ query = urlSplit[1];
533
+ matches = this.url === url && this.query === normalizeQuery(query);
534
+ }
535
+ return matches && (!this.data || this.data === normalizeQuery(data)) && (!this.method || this.method === method);
536
+ };
537
+ }
538
+
539
+ return RequestStub;
540
+ };
541
+
542
+ getJasmineRequireObj().AjaxRequestTracker = function() {
543
+ function RequestTracker() {
544
+ var requests = [];
545
+
546
+ this.track = function(request) {
547
+ requests.push(request);
548
+ };
549
+
550
+ this.first = function() {
551
+ return requests[0];
552
+ };
553
+
554
+ this.count = function() {
555
+ return requests.length;
556
+ };
557
+
558
+ this.reset = function() {
559
+ requests = [];
560
+ };
561
+
562
+ this.mostRecent = function() {
563
+ return requests[requests.length - 1];
564
+ };
565
+
566
+ this.at = function(index) {
567
+ return requests[index];
568
+ };
569
+
570
+ this.filter = function(url_to_match) {
571
+ var matching_requests = [];
572
+
573
+ for (var i = 0; i < requests.length; i++) {
574
+ if (url_to_match instanceof RegExp &&
575
+ url_to_match.test(requests[i].url)) {
576
+ matching_requests.push(requests[i]);
577
+ } else if (url_to_match instanceof Function &&
578
+ url_to_match(requests[i])) {
579
+ matching_requests.push(requests[i]);
580
+ } else {
581
+ if (requests[i].url === url_to_match) {
582
+ matching_requests.push(requests[i]);
583
+ }
584
+ }
585
+ }
586
+
587
+ return matching_requests;
588
+ };
589
+ }
590
+
591
+ return RequestTracker;
592
+ };
593
+
594
+ getJasmineRequireObj().AjaxStubTracker = function() {
595
+ function StubTracker() {
596
+ var stubs = [];
597
+
598
+ this.addStub = function(stub) {
599
+ stubs.push(stub);
600
+ };
601
+
602
+ this.reset = function() {
603
+ stubs = [];
604
+ };
605
+
606
+ this.findStub = function(url, data, method) {
607
+ for (var i = stubs.length - 1; i >= 0; i--) {
608
+ var stub = stubs[i];
609
+ if (stub.matches(url, data, method)) {
610
+ return stub;
611
+ }
612
+ }
613
+ };
614
+ }
615
+
616
+ return StubTracker;
617
+ };
618
+
619
+ (function() {
620
+ var jRequire = getJasmineRequireObj(),
621
+ MockAjax = jRequire.ajax(jRequire);
622
+ if (typeof window === "undefined" && typeof exports === "object") {
623
+ exports.MockAjax = MockAjax;
624
+ jasmine.Ajax = new MockAjax(exports);
625
+ } else {
626
+ window.MockAjax = MockAjax;
627
+ jasmine.Ajax = new MockAjax(window);
628
+ }
629
+ }());