requester 0.1.0

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5f3cc16c0a4d1f66db6398c2a4b19346a141c1ad
4
+ data.tar.gz: 5c36b763a9c82f1d59905c868301c652a84badd5
5
+ SHA512:
6
+ metadata.gz: b422f66f43c02bdf78f8b2bfb95f44cf043b094265541ce449432497c22888e17c3aaa1e186a7fda2f509396bd2bed86af046d53f4a72ea7ef30a702168f4062
7
+ data.tar.gz: 54d90e4eb0a7845ed5598b464bf4f51698cff53a9c14d5f50ede06bc93ee2b1c9985c332a9b7a50b2d8666cf134640d832ddeea3a1f225579e71b1bba0f3c671
@@ -0,0 +1,400 @@
1
+ # Requester
2
+
3
+ ## What is Requester?
4
+
5
+ Requester coordinates json api requests and responses between the server test
6
+ suite and the client test suite in Rails-based web applications.
7
+
8
+ ## How does it work?
9
+
10
+ Requester captures the api requests and responses generated by a Rails test
11
+ suite and writes them to a shared file. The client-side test suite (mocha,
12
+ ember-test, etc) uses that file as the source for mocking out those
13
+ same requests.
14
+
15
+ Requester can be used with Rails API and any front end framework.
16
+
17
+ ## Why would you want this?
18
+
19
+ Many web applications with extensive front-end rendering test the front-end
20
+ independently from the relied upon server-side api. In these siutations, changes to the
21
+ server-side api may go unnoticed by the front-end test suite leading to
22
+ an a green test suite but a broken app. Additionally, when an api change is
23
+ communicated to the front-end team, effort is needed to ensure that the
24
+ test suite api is mocked correctly. Requester aims to save that effort
25
+ and provide more transparency to api changes.
26
+
27
+ ## Usage
28
+
29
+ Pretend we have a Rails app with a `DecksController` with
30
+ this set of tests:
31
+
32
+ ```ruby
33
+ RSpec.describe DecksController, type: :request do
34
+ prepend Requester::Requests
35
+
36
+ before do
37
+ %w[diamonds hearts spades clubs].each do |suit|
38
+ Deck.create suit: suit, cards: "A 2 3 4 5 6 7 8 9 10 J Q K"
39
+ end
40
+ end
41
+
42
+ describe "GET /decks" do
43
+ it "works! (now write some real specs)" do
44
+ get decks_path
45
+ expect(response).to have_http_status(200)
46
+ end
47
+
48
+ it 'searches' do
49
+ get decks_path, { search: 'clubs' }, log_as: 'with search'
50
+ expect(response).to have_http_status(200)
51
+ end
52
+ end
53
+
54
+ describe 'show' do
55
+ it "works! (now write some real specs)" do
56
+ get deck_path(1), headers
57
+ expect(response).to have_http_status(200)
58
+ end
59
+ end
60
+
61
+ describe "PUT /decks" do
62
+ it "works! (now write some real specs)" do
63
+ headers = { 'ACCEPT' => 'application/json' }
64
+ xhr :put, deck_path(1), { deck: {cards: '10 J Q K'} }, headers
65
+ expect(response).to have_http_status(200)
66
+ end
67
+ end
68
+
69
+ describe "POST /decks" do
70
+ it "works! (now write some real specs)" do
71
+ headers = { 'ACCEPT' => 'application/json' }
72
+ post decks_path, { deck: { cards: "1 2 3", suit: 'horseshoes'} }, headers
73
+ expect(response).to have_http_status(201)
74
+ end
75
+ end
76
+ end
77
+ ```
78
+
79
+ Requester will generate JSON where the top level keys are controllers, followed by
80
+ actions, then the response/request generated by testing that endpoint:
81
+
82
+ ```javascript
83
+ //2017-07-11 13:34:11 UTC
84
+
85
+ export default {
86
+ "decks": {
87
+ "index": {
88
+ "response": {
89
+ "status": 200,
90
+ "body": {
91
+ "data": [
92
+ {
93
+ "id": "1",
94
+ "type": "decks",
95
+ "attributes": {
96
+ "cards": "A 2 3 4 5 6 7 8 9 10 J Q K",
97
+ "suit": "diamonds"
98
+ }
99
+ },
100
+ {
101
+ "id": "2",
102
+ "type": "decks",
103
+ "attributes": {
104
+ "cards": "A 2 3 4 5 6 7 8 9 10 J Q K",
105
+ "suit": "hearts"
106
+ }
107
+ },
108
+ {
109
+ "id": "3",
110
+ "type": "decks",
111
+ "attributes": {
112
+ "cards": "A 2 3 4 5 6 7 8 9 10 J Q K",
113
+ "suit": "spades"
114
+ }
115
+ },
116
+ {
117
+ "id": "4",
118
+ "type": "decks",
119
+ "attributes": {
120
+ "cards": "A 2 3 4 5 6 7 8 9 10 J Q K",
121
+ "suit": "clubs"
122
+ }
123
+ }
124
+ ]
125
+ },
126
+ "message": "OK"
127
+ },
128
+ "request": {
129
+ "path": "/decks",
130
+ "method": "GET"
131
+ },
132
+ "with search": {
133
+ "response": {
134
+ "status": 200,
135
+ "body": {
136
+ "decks": {
137
+ "id": 4,
138
+ "suit": "clubs",
139
+ "cards": "A 2 3 4 5 6 7 8 9 10 J Q K"
140
+ }
141
+ },
142
+ "message": "OK"
143
+ },
144
+ "request": {
145
+ "path": "/decks?search=clubs",
146
+ "method": "GET",
147
+ "query_string": "search=clubs"
148
+ }
149
+ }
150
+ },
151
+ "show": {
152
+ "response": {
153
+ "status": 200,
154
+ "body": {
155
+ "data": {
156
+ "id": "1",
157
+ "type": "decks",
158
+ "attributes": {
159
+ "cards": "A 2 3 4 5 6 7 8 9 10 J Q K",
160
+ "suit": "diamonds"
161
+ }
162
+ }
163
+ },
164
+ "message": "OK"
165
+ },
166
+ "request": {
167
+ "path": "/decks/1",
168
+ "method": "GET"
169
+ }
170
+ },
171
+ "update": {
172
+ "response": {
173
+ "status": 200,
174
+ "body": {
175
+ "data": {
176
+ "id": "1",
177
+ "type": "decks",
178
+ "attributes": {
179
+ "cards": "10 J Q K",
180
+ "suit": "diamonds"
181
+ }
182
+ }
183
+ },
184
+ "message": "OK"
185
+ },
186
+ "request": {
187
+ "path": "/decks/1",
188
+ "method": "PUT",
189
+ "request_parameters": {
190
+ "deck": {
191
+ "cards": "10 J Q K"
192
+ }
193
+ },
194
+ "media_type": "application/x-www-form-urlencoded"
195
+ }
196
+ },
197
+ "create": {
198
+ "response": {
199
+ "status": 201,
200
+ "body": {
201
+ "data": {
202
+ "id": "5",
203
+ "type": "decks",
204
+ "attributes": {
205
+ "cards": "1 2 3",
206
+ "suit": "horseshoes"
207
+ }
208
+ }
209
+ },
210
+ "message": "Created"
211
+ },
212
+ "request": {
213
+ "path": "/decks",
214
+ "method": "POST",
215
+ "request_parameters": {
216
+ "deck": {
217
+ "cards": "1 2 3",
218
+ "suit": "horseshoes"
219
+ }
220
+ },
221
+ "media_type": "application/x-www-form-urlencoded"
222
+ }
223
+ }
224
+ }
225
+ }
226
+ ```
227
+
228
+ Now in your front end app, using whatever fake API, you can use this data
229
+ to return responses you know work (assuming you ran requester with a green suite).
230
+ You also have access to the requests.
231
+
232
+ ```javascript
233
+ // meanwhile, in some fake server config in some JS framework...
234
+ import responses from 'dummy-ui/tests/responses';
235
+
236
+ myFakeApi.get('/decks', () => {
237
+ return data.decks.index.response.body;
238
+ })
239
+ ```
240
+
241
+ ## Usage
242
+
243
+ There is no magic involved in Requester. It simply prepends itself in your tests so it can log the request/response. Requester expects your tests to use a reasonable set of method calls to initiate a request (xhr, get, put, patch, post, delete, head).
244
+ Requester won't actually do anything when you run your test suite normally.
245
+ When you want to capture data, run `rake requester`.
246
+
247
+ ## Setup
248
+
249
+ Install requester in your development and test groups
250
+
251
+ ```ruby
252
+ gem 'requester'
253
+ ```
254
+
255
+ The minimum required configuration is to tell Requester where you want the JSON
256
+ dump to be stored for your front end, and dump the Requester logs when the suite ends.
257
+
258
+ ```ruby
259
+ # rails_helper.rb
260
+
261
+ Requester::Config.initialize do |config|
262
+ config.front_end_path = '/Users/you/code/my_ui/tests'
263
+ end
264
+
265
+ RSpec.configure do |config|
266
+ config.after :suite do
267
+ Requester::Logger.dump
268
+ end
269
+ end
270
+ ```
271
+
272
+ #### Config options
273
+
274
+ * `file_name`: By default this is set to `'responses.js'`. If you want
275
+ to use something different, set it here.
276
+ * `additional_request_attributes`: By default the the following methods are called/logged on the request object:
277
+ - `path`, `method`, `request_parameters`, `query_string`, `media_type`.
278
+ You can add additional methods to be logged here.
279
+ * `additional_response_attributes`: By default the the following methods are called/logged on the request object:
280
+ - `status`, `body`, `message`
281
+ You can add additional methods to be logged here.
282
+
283
+ ```ruby
284
+ # rails_helper.rb
285
+
286
+ Request::Config.initialize do |config|
287
+ config.file_name = 'rails_responses.js'
288
+ config.additional_request_attributes = [:ssl?]
289
+ config.additional_response_attributes = [:headers, :cookies]
290
+ end
291
+ ```
292
+
293
+ See below for other config options.
294
+
295
+ You can set up your tests in a few ways:
296
+
297
+ #### 1. Capture request/response for every test in the file
298
+
299
+ Prepend `Requester::Requests` and every test in this group
300
+ will have a log entry.
301
+
302
+ ```ruby
303
+ RSpec.describe DecksController, type: :request do
304
+ prepend Requester::Requests
305
+
306
+ describe "GET /decks" do
307
+ it "works! (now write some real specs)" do
308
+ get decks_path
309
+ expect(response).to have_http_status(200)
310
+ end
311
+
312
+ it 'searches' do
313
+ get decks_path, { search: 'clubs' }, log_as: 'with search'
314
+ expect(response).to have_http_status(200)
315
+ end
316
+ end
317
+
318
+ describe 'show' do
319
+ it "works! (now write some real specs)" do
320
+ get deck_path(1), headers
321
+ expect(response).to have_http_status(200)
322
+ end
323
+ end
324
+ ```
325
+
326
+ #### 2. Capture request/response for a describe/context block
327
+
328
+ Prepend `Requester::Requests` and only the tests in this group
329
+ will have a log entry.
330
+
331
+ ```ruby
332
+ RSpec.describe DecksController, type: :request do
333
+
334
+ describe "GET /decks" do
335
+ prepend Requester::Requests
336
+
337
+ it "works! (now write some real specs)" do
338
+ get decks_path
339
+ expect(response).to have_http_status(200)
340
+ end
341
+
342
+ it 'searches' do
343
+ get decks_path, { search: 'clubs' }, log_as: 'with search'
344
+ expect(response).to have_http_status(200)
345
+ end
346
+ end
347
+
348
+ describe 'show' do
349
+ it "works! (now write some real specs)" do
350
+ get deck_path(1), headers
351
+ expect(response).to have_http_status(200)
352
+ end
353
+ end
354
+ ```
355
+
356
+ #### 3. Capture request/response for individual tests
357
+
358
+ ```ruby
359
+ describe "GET /decks" do
360
+ it "works! (now write some real specs)" do
361
+ get decks_path
362
+
363
+ Requester.log_data(
364
+ request: request,
365
+ response: response,
366
+ controller: controller
367
+ )
368
+ expect(response).to have_http_status(200)
369
+ end
370
+
371
+ it 'searches' do
372
+ get decks_path, { search: 'clubs' }, log_as: 'with search'
373
+ expect(response).to have_http_status(200)
374
+ end
375
+ end
376
+ ```
377
+
378
+ You will likely have tests hitting the same endpoint testing different things.
379
+ For example, a test for an index action, and index with optional search params.
380
+ Specify a `log_as` option when you have multiple tests hitting the same endpoint.
381
+ Requester won't override an endpoint entry once it exists.
382
+
383
+ ```ruby
384
+ describe "GET /decks" do
385
+ it "works! (now write some real specs)" do
386
+ get decks_path
387
+ expect(response).to have_http_status(200)
388
+ end
389
+
390
+ it 'searches' do
391
+ get decks_path, { search: 'clubs' }, log_as: 'with search'
392
+ expect(response).to have_http_status(200)
393
+ end
394
+ end
395
+ ```
396
+
397
+ ## Contributing
398
+
399
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Jason Cummings/requester.
400
+ I am not looking to increase the scope of this gem, but I'll consider any ideas.
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "requester"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,10 @@
1
+ require 'requester/version'
2
+ require 'requester/config'
3
+ require 'requester/logger'
4
+ require 'requester/requests'
5
+ require 'requester/railtie' if defined?(Rails)
6
+
7
+ module Requester
8
+ include Requester::Requests
9
+ extend Requester::Requests
10
+ end
@@ -0,0 +1,58 @@
1
+ module Requester
2
+ class Config
3
+ class RequesterConfigError < StandardError; end
4
+
5
+ class << self
6
+ attr_accessor :file_name
7
+ attr_reader :front_end_path, :additional_response_attributes, :additional_request_attributes
8
+
9
+ def initialize(&block)
10
+ @file_name = 'responses.js'
11
+ @additional_request_attributes = []
12
+ @additional_response_attributes = []
13
+
14
+ class_exec(self, &block)
15
+ end
16
+
17
+ def front_end_path=(path)
18
+ @front_end_path = path
19
+
20
+ unless valid_path_to_front_end_app?
21
+ raise RequesterConfigError, config_error
22
+ end
23
+ end
24
+
25
+ def additional_request_attributes=(*args)
26
+ @additional_request_attributes = args.flatten
27
+ end
28
+
29
+ def additional_response_attributes=(*args)
30
+ @additional_response_attributes = args.flatten
31
+ end
32
+
33
+ def back_end_path
34
+ dir = defined?(RSpec) ? 'spec' : 'test'
35
+ File.join(Rails.root, dir)
36
+ end
37
+
38
+ def export_type
39
+ :es6
40
+ end
41
+
42
+ private
43
+
44
+ def valid_path_to_front_end_app?
45
+ front_end_path && File.exist?(front_end_path)
46
+ end
47
+
48
+ def config_error
49
+ <<-UIERROR
50
+ \n *********************************************************
51
+ \n Requester needs to know the path to your front end app
52
+ \n *********************************************************
53
+ \n
54
+ UIERROR
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,82 @@
1
+ require_relative 'request'
2
+ require_relative 'response'
3
+
4
+ module Requester
5
+ class Logger
6
+ class << self
7
+ def log
8
+ @log ||= {}
9
+ end
10
+
11
+ def log_response(response, controller, **options)
12
+ write('response', controller, options) do
13
+ Requester::Response.generate(response)
14
+ end
15
+ end
16
+
17
+ def log_request(request, controller, **options)
18
+ write('request', controller, options) do
19
+ Requester::Request.generate(request)
20
+ end
21
+ end
22
+
23
+ def dump
24
+ return unless ENV['REQUESTER']
25
+
26
+ api_dump = File.new(back_end_file, 'w+')
27
+ ui_dump = File.new(front_end_file, 'w+')
28
+ json = JSON.pretty_generate(log)
29
+
30
+ # would like to support other types as well
31
+ case Requester::Config.export_type
32
+ when :es6
33
+ ui_dump.write(es6_export + json)
34
+ api_dump.write(es6_export + json)
35
+ end
36
+
37
+ puts <<-DUMP
38
+ \n**************************
39
+ \n Interceptor logs dumped at:
40
+ \n #{File.expand_path(front_end_file)}
41
+ \n #{File.expand_path(back_end_file)}
42
+ \n**************************
43
+ DUMP
44
+ ensure
45
+ api_dump.close if api_dump
46
+ ui_dump.close if ui_dump
47
+ end
48
+
49
+ private
50
+
51
+ def write(request_or_response, controller, **options, &block)
52
+ c_name = controller.controller_name
53
+ a_name = controller.action_name
54
+ log_as = options[:log_as]
55
+
56
+ log[c_name] ||= {}
57
+ log[c_name][a_name] ||= {}
58
+
59
+ json = block.call
60
+
61
+ if log_as
62
+ log[c_name][a_name][log_as] ||= {}
63
+ log[c_name][a_name][log_as][request_or_response] ||= json
64
+ else
65
+ log[c_name][a_name][request_or_response] ||= json
66
+ end
67
+ end
68
+
69
+ def es6_export
70
+ "//#{Time.zone.now}\n\nexport default "
71
+ end
72
+
73
+ def front_end_file
74
+ File.join(Requester::Config.front_end_path, Requester::Config.file_name)
75
+ end
76
+
77
+ def back_end_file
78
+ File.join(Requester::Config.back_end_path, Requester::Config.file_name)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,8 @@
1
+ module Requester
2
+ class Railtie < Rails::Railtie
3
+ railtie_name :requester
4
+ rake_tasks do
5
+ load 'tasks/requester.rake'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'config'
2
+
3
+ module Requester
4
+ class Request
5
+ def self.generate(request)
6
+ new(request).json
7
+ end
8
+
9
+ def initialize(request)
10
+ @request = request
11
+ @config = Requester::Config
12
+ @json = {
13
+ path: request.fullpath,
14
+ method: request.method
15
+ }
16
+ end
17
+
18
+ def json
19
+ @json.tap do |json|
20
+ json[:request_parameters] = @request.request_parameters if @request.request_parameters
21
+ json[:query_string] = @request.query_string if @request.query_string
22
+ json[:media_type] = @request.media_type if @request.media_type
23
+
24
+ Requester::Config.additional_request_attributes.each do |attr|
25
+ json[attr] = @request.public_send(attr)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'config'
2
+
3
+ module Requester
4
+ module Requests
5
+ REQUEST_TYPES = [
6
+ :xhr, :get, :put, :patch, :post, :delete, :head
7
+ ]
8
+
9
+ REQUEST_TYPES.each do |method|
10
+ define_method(method) do |*args, **options|
11
+ super(*args, **options)
12
+ log_data(options) if ENV['REQUESTER']
13
+ end
14
+ end
15
+
16
+ def log_data(**options)
17
+ Logger.log_response(response, controller, options)
18
+ Logger.log_request(request, controller, options)
19
+ end
20
+
21
+ def self.log_data(request:, response:, controller:, **options)
22
+ return unless ENV['REQUESTER']
23
+ Logger.log_response(response, controller, options)
24
+ Logger.log_request(request, controller, options)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ require 'json'
2
+
3
+ module Requester
4
+ class Response
5
+
6
+ def self.generate(response)
7
+ new(response).json
8
+ end
9
+
10
+ def initialize(response)
11
+ @response = response
12
+ @json = {
13
+ status: response.status,
14
+ body: JSON.parse(response.body),
15
+ message: response.message
16
+ }
17
+ end
18
+
19
+ def json
20
+ @json.tap do |json|
21
+ Requester::Config.additional_response_attributes.each do |attr|
22
+ json[attr] = @response.public_send(attr)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module Requester
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,20 @@
1
+ desc 'Runs your specs and generates a JSON file based on the selected specs'
2
+
3
+ task :requester do
4
+ ENV['REQUESTER'] = 'true'
5
+
6
+ command = defined?(RSpec) ? 'rspec' : 'rails test'
7
+
8
+ command += " #{ARGV[1..-1].join(' ')}"
9
+
10
+ puts(<<-COMMAND)
11
+ \n *********************************************************
12
+ \n Running requester using command: #{command.rstrip}
13
+ \n *********************************************************
14
+ \n
15
+ COMMAND
16
+
17
+ system(command)
18
+
19
+ ENV['REQUESTER'] = nil
20
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: requester
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jason Cummings
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-07-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: railties
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '4.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '4.0'
69
+ description:
70
+ email: []
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - README.md
76
+ - bin/console
77
+ - bin/setup
78
+ - lib/requester.rb
79
+ - lib/requester/config.rb
80
+ - lib/requester/logger.rb
81
+ - lib/requester/railtie.rb
82
+ - lib/requester/request.rb
83
+ - lib/requester/requests.rb
84
+ - lib/requester/response.rb
85
+ - lib/requester/version.rb
86
+ - lib/tasks/requester.rake
87
+ homepage: https://github.com/jsncmgs1/requester
88
+ licenses: []
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.4.8
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Requester coordinates json api requests and responses between the server
110
+ test suite and the client test suite in Rails-based web applications.
111
+ test_files: []
112
+ has_rdoc: