mockjax 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: