mockjax 0.0.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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mockjax.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Eric J. Holmes
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,56 @@
1
+ # Mockjax
2
+
3
+ Mockjax gem for rails and rack applications. Define javascript mocks in your
4
+ request specs
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'mockjax'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install mockjax
19
+
20
+ ## Usage
21
+ Assuming you're using capybara...
22
+
23
+ ### Rack
24
+
25
+ ```ruby
26
+ # spec/spec_helper.rb
27
+ Mockjax.path_to_js = '/path/to/jquery.mockjax.js'
28
+
29
+ Capybara.app = Rack::Build.new {
30
+ use Rack::Mockjax
31
+ run MyApp
32
+ }
33
+ ```
34
+
35
+ #### Rails 3
36
+
37
+ ```ruby
38
+ # config/initializers/test.rb
39
+ config.middleware.use Rack::Mockjax
40
+ ```
41
+
42
+ Then define your stubs like you would with any other stubbing library:
43
+
44
+ ```ruby
45
+ before do
46
+ mockjax url: '/test', responseText: { message: 'hello world' }
47
+ end
48
+ ```
49
+
50
+ ## Contributing
51
+
52
+ 1. Fork it
53
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
54
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
55
+ 4. Push to the branch (`git push origin my-new-feature`)
56
+ 5. Create new Pull Request
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,521 @@
1
+ /*!
2
+ * MockJax - jQuery Plugin to Mock Ajax requests
3
+ *
4
+ * Version: 1.5.0pre
5
+ * Released:
6
+ * Home: http://github.com/appendto/jquery-mockjax
7
+ * Author: Jonathan Sharp (http://jdsharp.com)
8
+ * License: MIT,GPL
9
+ *
10
+ * Copyright (c) 2011 appendTo LLC.
11
+ * Dual licensed under the MIT or GPL licenses.
12
+ * http://appendto.com/open-source-licenses
13
+ */
14
+ (function($) {
15
+ var _ajax = $.ajax,
16
+ mockHandlers = [],
17
+ CALLBACK_REGEX = /=\?(&|$)/,
18
+ jsc = (new Date()).getTime();
19
+
20
+
21
+ // Parse the given XML string.
22
+ function parseXML(xml) {
23
+ if ( window['DOMParser'] == undefined && window.ActiveXObject ) {
24
+ DOMParser = function() { };
25
+ DOMParser.prototype.parseFromString = function( xmlString ) {
26
+ var doc = new ActiveXObject('Microsoft.XMLDOM');
27
+ doc.async = 'false';
28
+ doc.loadXML( xmlString );
29
+ return doc;
30
+ };
31
+ }
32
+
33
+ try {
34
+ var xmlDoc = ( new DOMParser() ).parseFromString( xml, 'text/xml' );
35
+ if ( $.isXMLDoc( xmlDoc ) ) {
36
+ var err = $('parsererror', xmlDoc);
37
+ if ( err.length == 1 ) {
38
+ throw('Error: ' + $(xmlDoc).text() );
39
+ }
40
+ } else {
41
+ throw('Unable to parse XML');
42
+ }
43
+ } catch( e ) {
44
+ var msg = ( e.name == undefined ? e : e.name + ': ' + e.message );
45
+ $(document).trigger('xmlParseError', [ msg ]);
46
+ return undefined;
47
+ }
48
+ return xmlDoc;
49
+ }
50
+
51
+ // Trigger a jQuery event
52
+ function trigger(s, type, args) {
53
+ (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
54
+ }
55
+
56
+ // Check if the data field on the mock handler and the request match. This
57
+ // can be used to restrict a mock handler to being used only when a certain
58
+ // set of data is passed to it.
59
+ function isMockDataEqual( mock, live ) {
60
+ var identical = false;
61
+ // Test for situations where the data is a querystring (not an object)
62
+ if (typeof live === 'string') {
63
+ // Querystring may be a regex
64
+ return $.isFunction( mock.test ) ? mock.test(live) : mock == live;
65
+ }
66
+ $.each(mock, function(k, v) {
67
+ if ( live[k] === undefined ) {
68
+ identical = false;
69
+ return identical;
70
+ } else {
71
+ identical = true;
72
+ if ( typeof live[k] == 'object' ) {
73
+ return isMockDataEqual(mock[k], live[k]);
74
+ } else {
75
+ if ( $.isFunction( mock[k].test ) ) {
76
+ identical = mock[k].test(live[k]);
77
+ } else {
78
+ identical = ( mock[k] == live[k] );
79
+ }
80
+ return identical;
81
+ }
82
+ }
83
+ });
84
+
85
+ return identical;
86
+ }
87
+
88
+ // Check the given handler should mock the given request
89
+ function getMockForRequest( handler, requestSettings ) {
90
+ // If the mock was registered with a function, let the function decide if we
91
+ // want to mock this request
92
+ if ( $.isFunction(handler) ) {
93
+ return handler( requestSettings );
94
+ }
95
+
96
+ // Inspect the URL of the request and check if the mock handler's url
97
+ // matches the url for this ajax request
98
+ if ( $.isFunction(handler.url.test) ) {
99
+ // The user provided a regex for the url, test it
100
+ if ( !handler.url.test( requestSettings.url ) ) {
101
+ return null;
102
+ }
103
+ } else {
104
+ // Look for a simple wildcard '*' or a direct URL match
105
+ var star = handler.url.indexOf('*');
106
+ if (handler.url !== requestSettings.url && star === -1 ||
107
+ !new RegExp(handler.url.replace(/[-[\]{}()+?.,\\^$|#\s]/g, "\\$&").replace('*', '.+')).test(requestSettings.url)) {
108
+ return null;
109
+ }
110
+ }
111
+
112
+ // Inspect the data submitted in the request (either POST body or GET query string)
113
+ if ( handler.data && requestSettings.data ) {
114
+ if ( !isMockDataEqual(handler.data, requestSettings.data) ) {
115
+ // They're not identical, do not mock this request
116
+ return null;
117
+ }
118
+ }
119
+ // Inspect the request type
120
+ if ( handler && handler.type &&
121
+ handler.type.toLowerCase() != requestSettings.type.toLowerCase() ) {
122
+ // The request type doesn't match (GET vs. POST)
123
+ return null;
124
+ }
125
+
126
+ return handler;
127
+ }
128
+
129
+ // If logging is enabled, log the mock to the console
130
+ function logMock( mockHandler, requestSettings ) {
131
+ var c = $.extend({}, $.mockjaxSettings, mockHandler);
132
+ if ( c.log && $.isFunction(c.log) ) {
133
+ c.log('MOCK ' + requestSettings.type.toUpperCase() + ': ' + requestSettings.url, $.extend({}, requestSettings));
134
+ }
135
+ }
136
+
137
+ // Process the xhr objects send operation
138
+ function _xhrSend(mockHandler, requestSettings, origSettings) {
139
+
140
+ // This is a substitute for < 1.4 which lacks $.proxy
141
+ var process = (function(that) {
142
+ return function() {
143
+ return (function() {
144
+ // The request has returned
145
+ this.status = mockHandler.status;
146
+ this.statusText = mockHandler.statusText;
147
+ this.readyState = 4;
148
+
149
+ // We have an executable function, call it to give
150
+ // the mock handler a chance to update it's data
151
+ if ( $.isFunction(mockHandler.response) ) {
152
+ mockHandler.response(origSettings);
153
+ }
154
+ // Copy over our mock to our xhr object before passing control back to
155
+ // jQuery's onreadystatechange callback
156
+ if ( requestSettings.dataType == 'json' && ( typeof mockHandler.responseText == 'object' ) ) {
157
+ this.responseText = JSON.stringify(mockHandler.responseText);
158
+ } else if ( requestSettings.dataType == 'xml' ) {
159
+ if ( typeof mockHandler.responseXML == 'string' ) {
160
+ this.responseXML = parseXML(mockHandler.responseXML);
161
+ } else {
162
+ this.responseXML = mockHandler.responseXML;
163
+ }
164
+ } else {
165
+ this.responseText = mockHandler.responseText;
166
+ }
167
+ if( typeof mockHandler.status == 'number' || typeof mockHandler.status == 'string' ) {
168
+ this.status = mockHandler.status;
169
+ }
170
+ if( typeof mockHandler.statusText === "string") {
171
+ this.statusText = mockHandler.statusText;
172
+ }
173
+ // jQuery < 1.4 doesn't have onreadystate change for xhr
174
+ if ( $.isFunction(this.onreadystatechange) ) {
175
+ if( mockHandler.isTimeout) {
176
+ this.status = -1;
177
+ }
178
+ this.onreadystatechange( mockHandler.isTimeout ? 'timeout' : undefined );
179
+ } else if ( mockHandler.isTimeout ) {
180
+ // Fix for 1.3.2 timeout to keep success from firing.
181
+ this.status = -1;
182
+ }
183
+ }).apply(that);
184
+ };
185
+ })(this);
186
+
187
+ if ( mockHandler.proxy ) {
188
+ // We're proxying this request and loading in an external file instead
189
+ _ajax({
190
+ global: false,
191
+ url: mockHandler.proxy,
192
+ type: mockHandler.proxyType,
193
+ data: mockHandler.data,
194
+ dataType: requestSettings.dataType === "script" ? "text/plain" : requestSettings.dataType,
195
+ complete: function(xhr, txt) {
196
+ mockHandler.responseXML = xhr.responseXML;
197
+ mockHandler.responseText = xhr.responseText;
198
+ mockHandler.status = xhr.status;
199
+ mockHandler.statusText = xhr.statusText;
200
+ this.responseTimer = setTimeout(process, mockHandler.responseTime || 0);
201
+ }
202
+ });
203
+ } else {
204
+ // type == 'POST' || 'GET' || 'DELETE'
205
+ if ( requestSettings.async === false ) {
206
+ // TODO: Blocking delay
207
+ process();
208
+ } else {
209
+ this.responseTimer = setTimeout(process, mockHandler.responseTime || 50);
210
+ }
211
+ }
212
+ }
213
+
214
+ // Construct a mocked XHR Object
215
+ function xhr(mockHandler, requestSettings, origSettings, origHandler) {
216
+ // Extend with our default mockjax settings
217
+ mockHandler = $.extend({}, $.mockjaxSettings, mockHandler);
218
+
219
+ if (typeof mockHandler.headers === 'undefined') {
220
+ mockHandler.headers = {};
221
+ }
222
+ if ( mockHandler.contentType ) {
223
+ mockHandler.headers['content-type'] = mockHandler.contentType;
224
+ }
225
+
226
+ return {
227
+ status: mockHandler.status,
228
+ statusText: mockHandler.statusText,
229
+ readyState: 1,
230
+ open: function() { },
231
+ send: function() {
232
+ origHandler.fired = true;
233
+ _xhrSend.call(this, mockHandler, requestSettings, origSettings);
234
+ },
235
+ abort: function() {
236
+ clearTimeout(this.responseTimer);
237
+ },
238
+ setRequestHeader: function(header, value) {
239
+ mockHandler.headers[header] = value;
240
+ },
241
+ getResponseHeader: function(header) {
242
+ // 'Last-modified', 'Etag', 'content-type' are all checked by jQuery
243
+ if ( mockHandler.headers && mockHandler.headers[header] ) {
244
+ // Return arbitrary headers
245
+ return mockHandler.headers[header];
246
+ } else if ( header.toLowerCase() == 'last-modified' ) {
247
+ return mockHandler.lastModified || (new Date()).toString();
248
+ } else if ( header.toLowerCase() == 'etag' ) {
249
+ return mockHandler.etag || '';
250
+ } else if ( header.toLowerCase() == 'content-type' ) {
251
+ return mockHandler.contentType || 'text/plain';
252
+ }
253
+ },
254
+ getAllResponseHeaders: function() {
255
+ var headers = '';
256
+ $.each(mockHandler.headers, function(k, v) {
257
+ headers += k + ': ' + v + "\n";
258
+ });
259
+ return headers;
260
+ }
261
+ };
262
+ }
263
+
264
+ // Process a JSONP mock request.
265
+ function processJsonpMock( requestSettings, mockHandler, origSettings ) {
266
+ // Handle JSONP Parameter Callbacks, we need to replicate some of the jQuery core here
267
+ // because there isn't an easy hook for the cross domain script tag of jsonp
268
+
269
+ processJsonpUrl( requestSettings );
270
+
271
+ requestSettings.dataType = "json";
272
+ if(requestSettings.data && CALLBACK_REGEX.test(requestSettings.data) || CALLBACK_REGEX.test(requestSettings.url)) {
273
+ createJsonpCallback(requestSettings, mockHandler);
274
+
275
+ // We need to make sure
276
+ // that a JSONP style response is executed properly
277
+
278
+ var rurl = /^(\w+:)?\/\/([^\/?#]+)/,
279
+ parts = rurl.exec( requestSettings.url ),
280
+ remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
281
+
282
+ requestSettings.dataType = "script";
283
+ if(requestSettings.type.toUpperCase() === "GET" && remote ) {
284
+ var newMockReturn = processJsonpRequest( requestSettings, mockHandler, origSettings );
285
+
286
+ // Check if we are supposed to return a Deferred back to the mock call, or just
287
+ // signal success
288
+ if(newMockReturn) {
289
+ return newMockReturn;
290
+ } else {
291
+ return true;
292
+ }
293
+ }
294
+ }
295
+ return null;
296
+ }
297
+
298
+ // Append the required callback parameter to the end of the request URL, for a JSONP request
299
+ function processJsonpUrl( requestSettings ) {
300
+ if ( requestSettings.type.toUpperCase() === "GET" ) {
301
+ if ( !CALLBACK_REGEX.test( requestSettings.url ) ) {
302
+ requestSettings.url += (/\?/.test( requestSettings.url ) ? "&" : "?") +
303
+ (requestSettings.jsonp || "callback") + "=?";
304
+ }
305
+ } else if ( !requestSettings.data || !CALLBACK_REGEX.test(requestSettings.data) ) {
306
+ requestSettings.data = (requestSettings.data ? requestSettings.data + "&" : "") + (requestSettings.jsonp || "callback") + "=?";
307
+ }
308
+ }
309
+
310
+ // Process a JSONP request by evaluating the mocked response text
311
+ function processJsonpRequest( requestSettings, mockHandler, origSettings ) {
312
+ // Synthesize the mock request for adding a script tag
313
+ var callbackContext = origSettings && origSettings.context || requestSettings,
314
+ newMock = null;
315
+
316
+
317
+ // If the response handler on the moock is a function, call it
318
+ if ( mockHandler.response && $.isFunction(mockHandler.response) ) {
319
+ mockHandler.response(origSettings);
320
+ } else {
321
+
322
+ // Evaluate the responseText javascript in a global context
323
+ if( typeof mockHandler.responseText === 'object' ) {
324
+ $.globalEval( '(' + JSON.stringify( mockHandler.responseText ) + ')');
325
+ } else {
326
+ $.globalEval( '(' + mockHandler.responseText + ')');
327
+ }
328
+ }
329
+
330
+ // Successful response
331
+ jsonpSuccess( requestSettings, mockHandler );
332
+ jsonpComplete( requestSettings, mockHandler );
333
+
334
+ // If we are running under jQuery 1.5+, return a deferred object
335
+ if(jQuery.Deferred){
336
+ newMock = new jQuery.Deferred();
337
+ if(typeof mockHandler.responseText == "object"){
338
+ newMock.resolve( mockHandler.responseText );
339
+ }
340
+ else{
341
+ newMock.resolve( jQuery.parseJSON( mockHandler.responseText ) );
342
+ }
343
+ }
344
+ return newMock;
345
+ }
346
+
347
+
348
+ // Create the required JSONP callback function for the request
349
+ function createJsonpCallback( requestSettings, mockHandler ) {
350
+ jsonp = requestSettings.jsonpCallback || ("jsonp" + jsc++);
351
+
352
+ // Replace the =? sequence both in the query string and the data
353
+ if ( requestSettings.data ) {
354
+ requestSettings.data = (requestSettings.data + "").replace(CALLBACK_REGEX, "=" + jsonp + "$1");
355
+ }
356
+
357
+ requestSettings.url = requestSettings.url.replace(CALLBACK_REGEX, "=" + jsonp + "$1");
358
+
359
+
360
+ // Handle JSONP-style loading
361
+ window[ jsonp ] = window[ jsonp ] || function( tmp ) {
362
+ data = tmp;
363
+ jsonpSuccess( requestSettings, mockHandler );
364
+ jsonpComplete( requestSettings, mockHandler );
365
+ // Garbage collect
366
+ window[ jsonp ] = undefined;
367
+
368
+ try {
369
+ delete window[ jsonp ];
370
+ } catch(e) {}
371
+
372
+ if ( head ) {
373
+ head.removeChild( script );
374
+ }
375
+ };
376
+ }
377
+
378
+ // The JSONP request was successful
379
+ function jsonpSuccess(requestSettings, mockHandler) {
380
+ // If a local callback was specified, fire it and pass it the data
381
+ if ( requestSettings.success ) {
382
+ requestSettings.success.call( callbackContext, ( mockHandler.response ? mockHandler.response.toString() : mockHandler.responseText || ''), status, {} );
383
+ }
384
+
385
+ // Fire the global callback
386
+ if ( requestSettings.global ) {
387
+ trigger(requestSettings, "ajaxSuccess", [{}, requestSettings] );
388
+ }
389
+ }
390
+
391
+ // The JSONP request was completed
392
+ function jsonpComplete(requestSettings, mockHandler) {
393
+ // Process result
394
+ if ( requestSettings.complete ) {
395
+ requestSettings.complete.call( callbackContext, {} , status );
396
+ }
397
+
398
+ // The request was completed
399
+ if ( requestSettings.global ) {
400
+ trigger( "ajaxComplete", [{}, requestSettings] );
401
+ }
402
+
403
+ // Handle the global AJAX counter
404
+ if ( requestSettings.global && ! --jQuery.active ) {
405
+ jQuery.event.trigger( "ajaxStop" );
406
+ }
407
+ }
408
+
409
+
410
+ // The core $.ajax replacement.
411
+ function handleAjax( url, origSettings ) {
412
+ var mockRequest, requestSettings, mockHandler;
413
+
414
+ // If url is an object, simulate pre-1.5 signature
415
+ if ( typeof url === "object" ) {
416
+ origSettings = url;
417
+ url = undefined;
418
+ } else {
419
+ // work around to support 1.5 signature
420
+ origSettings.url = url;
421
+ }
422
+
423
+ // Extend the original settings for the request
424
+ requestSettings = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
425
+
426
+ // Iterate over our mock handlers (in registration order) until we find
427
+ // one that is willing to intercept the request
428
+ for(var k = 0; k < mockHandlers.length; k++) {
429
+ if ( !mockHandlers[k] ) {
430
+ continue;
431
+ }
432
+
433
+ mockHandler = getMockForRequest( mockHandlers[k], requestSettings );
434
+ if(!mockHandler) {
435
+ // No valid mock found for this request
436
+ continue;
437
+ }
438
+
439
+ // Handle console logging
440
+ logMock( mockHandler, requestSettings );
441
+
442
+
443
+ if ( requestSettings.dataType === "jsonp" ) {
444
+ if ((mockRequest = processJsonpMock( requestSettings, mockHandler, origSettings ))) {
445
+ // This mock will handle the JSONP request
446
+ return mockRequest;
447
+ }
448
+ }
449
+
450
+
451
+ // Removed to fix #54 - keep the mocking data object intact
452
+ //mockHandler.data = requestSettings.data;
453
+
454
+ mockHandler.cache = requestSettings.cache;
455
+ mockHandler.timeout = requestSettings.timeout;
456
+ mockHandler.global = requestSettings.global;
457
+
458
+ (function(mockHandler, requestSettings, origSettings, origHandler) {
459
+ mockRequest = _ajax.call($, $.extend(true, {}, origSettings, {
460
+ // Mock the XHR object
461
+ xhr: function() { return xhr( mockHandler, requestSettings, origSettings, origHandler ) }
462
+ }));
463
+ })(mockHandler, requestSettings, origSettings, mockHandlers[k]);
464
+
465
+ return mockRequest;
466
+ }
467
+
468
+ // We don't have a mock request, trigger a normal request
469
+ return _ajax.apply($, [origSettings]);
470
+ }
471
+
472
+
473
+ // Public
474
+
475
+ $.extend({
476
+ ajax: handleAjax
477
+ });
478
+
479
+ $.mockjaxSettings = {
480
+ //url: null,
481
+ //type: 'GET',
482
+ log: function(msg) {
483
+ window['console'] && window.console.log && window.console.log(msg);
484
+ },
485
+ status: 200,
486
+ statusText: "OK",
487
+ responseTime: 500,
488
+ isTimeout: false,
489
+ contentType: 'text/plain',
490
+ response: '',
491
+ responseText: '',
492
+ responseXML: '',
493
+ proxy: '',
494
+ proxyType: 'GET',
495
+
496
+ lastModified: null,
497
+ etag: '',
498
+ headers: {
499
+ etag: 'IJF@H#@923uf8023hFO@I#H#',
500
+ 'content-type' : 'text/plain'
501
+ }
502
+ };
503
+
504
+ $.mockjax = function(settings) {
505
+ var i = mockHandlers.length;
506
+ mockHandlers[i] = settings;
507
+ return i;
508
+ };
509
+ $.mockjaxClear = function(i) {
510
+ if ( arguments.length == 1 ) {
511
+ mockHandlers[i] = null;
512
+ } else {
513
+ mockHandlers = [];
514
+ }
515
+ };
516
+ $.mockjax.handler = function(i) {
517
+ if ( arguments.length == 1 ) {
518
+ return mockHandlers[i];
519
+ }
520
+ };
521
+ })(jQuery);
@@ -0,0 +1,46 @@
1
+ require 'rack'
2
+ require 'rspec'
3
+
4
+ require 'mockjax/version'
5
+ require 'mockjax/rails'
6
+ require 'mockjax/rack'
7
+
8
+ module Mockjax
9
+ class << self
10
+ def mock(options)
11
+ @mocks ||= []
12
+ @mocks << options
13
+ end
14
+
15
+ def mocks
16
+ @mocks || []
17
+ end
18
+
19
+ def cleanup
20
+ @mocks = []
21
+ end
22
+
23
+ def path_to_js=(path)
24
+ @path_to_js = path
25
+ end
26
+
27
+ def path_to_js
28
+ @path_to_js || '/assets/jquery.mockjax.js'
29
+ end
30
+ end
31
+
32
+ # RSpec helper
33
+ module Helpers
34
+ def mockjax(*args)
35
+ Mockjax.mock(*args)
36
+ end
37
+ end
38
+ end
39
+
40
+ RSpec.configure do |config|
41
+ config.include Mockjax::Helpers
42
+
43
+ config.after(:each) do
44
+ Mockjax.cleanup
45
+ end
46
+ end
@@ -0,0 +1,23 @@
1
+ require 'rack'
2
+
3
+ class Rack::Mockjax
4
+ def initialize(app, options={})
5
+ @app = app
6
+ @options = options
7
+ end
8
+
9
+ def call(env)
10
+ @status, @headers, @body = @app.call(env)
11
+ @body = @body.to_a.join
12
+ insert!
13
+ [@status, @headers, [@body]]
14
+ end
15
+
16
+ def insert!
17
+ mocks = ''.tap do |m|
18
+ Mockjax.mocks.each { |mock| m << "$.mockjax(#{mock.to_json});\n" }
19
+ end
20
+ @body.gsub!(/(<\/head>)/, "<script src='#{Mockjax.path_to_js}' type='text/javascript'></script>\n<script>#{mocks}</script>\\1")
21
+ @headers['Content-Length'] = Rack::Utils.bytesize(@body).to_s
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ module Mockjax
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end if defined?(::Rails)
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module Mockjax
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mockjax/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Eric J. Holmes"]
6
+ gem.email = ["eric@ejholmes.net"]
7
+ gem.description = %q{Ruby gem for using jquery mockjax within rspec examples}
8
+ gem.summary = %q{Ruby gem for using jquery mockjax within rspec examples}
9
+ gem.homepage = "https://github.com/ejholmes/mockjax"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "mockjax"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Mockjax::VERSION
17
+
18
+ gem.add_dependency 'rack'
19
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mockjax
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric J. Holmes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: &70176437967960 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70176437967960
25
+ description: Ruby gem for using jquery mockjax within rspec examples
26
+ email:
27
+ - eric@ejholmes.net
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - LICENSE
35
+ - README.md
36
+ - Rakefile
37
+ - app/assets/javascripts/jquery.mockjax.js
38
+ - lib/mockjax.rb
39
+ - lib/mockjax/rack.rb
40
+ - lib/mockjax/rails.rb
41
+ - lib/mockjax/version.rb
42
+ - mockjax.gemspec
43
+ homepage: https://github.com/ejholmes/mockjax
44
+ licenses: []
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.11
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Ruby gem for using jquery mockjax within rspec examples
67
+ test_files: []
68
+ has_rdoc: