desponders 0.2.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e54fe6506dfbcfbd55b07f20c47647da2cc553bf
4
+ data.tar.gz: b0d9692bcbcceb0798ee20943ef4ed75849fa47d
5
+ SHA512:
6
+ metadata.gz: 53ff2a38c22f6b6a441eda7df9e8870febd397e978afd8736e216a15311036c11ab27d0277746767981bce161b6f636f6932a3c5d7d1eae6056c1449bd29357c
7
+ data.tar.gz: 4f80b5479461aa336fe2946ae7356413ea68a9c5893c1fd86b8d8c2e10acf1c2e0d231f7d94b0636a3fa588f7f57483b3b869e3bb256e6a3e98e5d361ebefc5b
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ bin/
12
+ vendor/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format progress
3
+ -I spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ script: bundle exec rspec spec
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # 0.2.0
2
+
3
+ - Initial release ported from internal responders. Initial set of responders
4
+ includes:
5
+
6
+ - Error
7
+ - HttpCaching
8
+ - Paginated
9
+ - Rest
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in desponders.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Dscout, Inc
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.
data/README.md ADDED
@@ -0,0 +1,59 @@
1
+ [![Build Status](https://travis-ci.org/dscout/desponders.png?branch=master)](https://travis-ci.org/dscout/desponders)
2
+
3
+ # Desponders
4
+
5
+ A stack of light-weight responders tailored to JSON APIs.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'desponders', '0.2.0'
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ Use the provided `ApiResponder`, which includes all of the responder modules in
18
+ a sane order:
19
+
20
+ * Desponders::ErrorResponder
21
+ * Desponders::RESTResponder
22
+ * Desponders::PaginatedResponder
23
+ * Desponders::HTTPCacheResponder
24
+
25
+ Alternatively, create a `ActionController::Responder` subclass and include the
26
+ responders that you would like to use:
27
+
28
+ ```ruby
29
+ class CustomResponder < ActionController::Responder
30
+ include Desponders::RESTResponder
31
+ include Desponders::HTTPCacheResponder
32
+ end
33
+ ```
34
+
35
+ Include the responder in any controllers serving API requests:
36
+
37
+ ```ruby
38
+ class ApplicationController < ActionController::Base
39
+ # Included
40
+ self.responder = Desponder::Responder
41
+
42
+ # Custom
43
+ self.responder = CustomResponder
44
+ end
45
+ ```
46
+
47
+ ## Thanks
48
+
49
+ The implementation of Desponders is based on the fanstastic work of Jose Valim
50
+ and his contributions to Responders within Rails, as well as Plataformatec's
51
+ Responders gem.
52
+
53
+ ## Contributing
54
+
55
+ 1. Fork it
56
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
57
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
58
+ 4. Push to the branch (`git push origin my-new-feature`)
59
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'desponders/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'desponders'
8
+ spec.version = Desponders::VERSION
9
+ spec.authors = ['Parker Selbert']
10
+ spec.email = ['parker@sorentwo.com']
11
+ spec.homepage = 'https://github.com/dscout/desponders'
12
+ spec.license = 'MIT'
13
+ spec.description = 'A stack of light-weight responders tailored to JSON APIs'
14
+ spec.summary = 'A stack of light-weight responders tailored to JSON APIs'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.test_files = spec.files.grep(%r{^(spec)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_dependency 'railties', '>= 3.2', '< 5'
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.3'
23
+ spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'rspec', '~> 2.14.0'
25
+ end
@@ -0,0 +1,23 @@
1
+ module Desponders
2
+ module ErrorResponder
3
+ # If it isn't a get request and the response model has errors it
4
+ # automatically renders json with errors
5
+ def to_format
6
+ if has_errors?
7
+ controller.render json: {
8
+ message: lookup_message, errors: resource.errors
9
+ }, status: :unprocessable_entity
10
+ else
11
+ super
12
+ end
13
+ end
14
+
15
+ def lookup_message
16
+ action = controller.action_name
17
+ lookup = ['errors', action].join('.').to_sym
18
+ options = { resource_name: resource.class.model_name.human }
19
+
20
+ I18n.t(lookup, options)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ module Desponders
2
+ module HttpCacheResponder
3
+ def to_format
4
+ return if do_http_cache? && do_http_cache!
5
+
6
+ super
7
+ end
8
+
9
+ private
10
+
11
+ def do_http_cache?
12
+ get? && ActionController::Base.perform_caching &&
13
+ resource.respond_to?(:updated_at)
14
+ end
15
+
16
+ def do_http_cache!
17
+ controller.fresh_when(etag: resource,
18
+ last_modified: resource.updated_at,
19
+ public: false)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ en:
2
+ errors:
3
+ create: "%{resource_name} could not be created"
4
+ update: "%{resource_name} could not be updated"
5
+ destroy: "%{resource_name} could not be destroyed"
6
+
@@ -0,0 +1,69 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+
3
+ module Desponders
4
+ module PaginatedResponder
5
+ def to_format
6
+ if get? && resource.respond_to?(:paginate)
7
+ self.resource_size = resource.size
8
+ self.resource = resource.paginate(page: page, per_page: per_page)
9
+
10
+ response.headers['Link'] = link_headers
11
+ end
12
+
13
+ super
14
+ end
15
+
16
+ private
17
+
18
+ attr_accessor :resource, :resource_size
19
+
20
+ delegate :response, :request, to: :controller
21
+
22
+ def default_page
23
+ 1
24
+ end
25
+
26
+ def default_per_page
27
+ 30
28
+ end
29
+
30
+ def page
31
+ (request.params[:page] || default_page).to_i
32
+ end
33
+
34
+ def per_page
35
+ (request.params[:per_page] || default_per_page).to_i
36
+ end
37
+
38
+ def first_page
39
+ 1
40
+ end
41
+
42
+ def prev_page
43
+ [first_page, page - 1].max
44
+ end
45
+
46
+ def next_page
47
+ [last_page, page + 1].min
48
+ end
49
+
50
+ def last_page
51
+ calculated = (resource_size.to_f / per_page).ceil
52
+
53
+ calculated.zero? ? 1 : calculated
54
+ end
55
+
56
+ def link_headers
57
+ base, rest = request.url.split('?')
58
+
59
+ [construct_link_rel(base, first_page, per_page, 'first'),
60
+ construct_link_rel(base, prev_page, per_page, 'prev'),
61
+ construct_link_rel(base, next_page, per_page, 'next'),
62
+ construct_link_rel(base, last_page, per_page, 'last')].join(',')
63
+ end
64
+
65
+ def construct_link_rel(base, page, per_page, rel)
66
+ %(#{base}?page=#{page}&per_page=#{per_page}; rel="#{rel}")
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,18 @@
1
+ module Desponders
2
+ module RestResponder
3
+ def to_format
4
+ case
5
+ when get?
6
+ display(resource, status: :ok)
7
+ when has_errors?
8
+ super
9
+ when post?
10
+ display(resource, status: :created)
11
+ when put?
12
+ display(resource, status: :ok)
13
+ when delete?
14
+ display({}, status: :no_content)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module Desponders
2
+ VERSION = '0.2.0'
3
+ end
data/lib/desponders.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'action_controller/base'
2
+
3
+ module Desponders
4
+ autoload :ErrorResponder, 'desponders/error_responder'
5
+ autoload :HttpCacheResponder, 'desponders/http_cache_responder'
6
+ autoload :PaginatedResponder, 'desponders/paginated_responder'
7
+ autoload :RestResponder, 'desponders/rest_responder'
8
+
9
+ class Railtie < ::Rails::Railtie
10
+ require 'active_support/i18n'
11
+ I18n.load_path << File.expand_path('../desponders/locales/en.yml', __FILE__)
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ I18n.load_path += [File.expand_path('lib/desponders/locales/en.yml')]
4
+
5
+ describe Desponders::ErrorResponder do
6
+ class MockErrorResponder < Struct.new(:to_format)
7
+ include Desponders::ErrorResponder
8
+
9
+ attr_accessor :controller, :resource
10
+
11
+ def initialize(controller, resource)
12
+ @controller = controller
13
+ @resource = resource
14
+ end
15
+ end
16
+
17
+ let(:controller) { double(:controller, action_name: 'create') }
18
+ let(:resource) { double(:resource, errors: []) }
19
+
20
+ subject(:responder) { MockErrorResponder.new(controller, resource) }
21
+
22
+ before do
23
+ resource.class.stub_chain(:model_name, :human).and_return('Mock')
24
+ end
25
+
26
+ it 'renders error messages when a non-get request has errors ' do
27
+ responder.stub(has_errors?: true)
28
+
29
+ expect(controller).to receive(:render).with(json: {
30
+ message: 'Mock could not be created',
31
+ errors: []
32
+ }, status: :unprocessable_entity)
33
+
34
+ responder.to_format
35
+ end
36
+
37
+ it 'does not render without errors' do
38
+ responder.stub(has_errors?: false)
39
+
40
+ expect(controller).to_not receive(:render)
41
+
42
+ responder.to_format
43
+ end
44
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe Desponders::HttpCacheResponder do
4
+ class MockHttpCacheResponderBase
5
+ def to_format
6
+ '{}'
7
+ end
8
+ end
9
+
10
+ class MockHttpCacheResponder < MockHttpCacheResponderBase
11
+ include Desponders::HttpCacheResponder
12
+
13
+ attr_accessor :controller
14
+
15
+ def initialize(controller)
16
+ @controller = controller
17
+ end
18
+ end
19
+
20
+ let(:controller) { double(:controller, fresh_when: true) }
21
+ let(:resource) { double(:resource, updated_at: nil) }
22
+ let(:collection) { double(:collection) }
23
+
24
+ subject(:responder) { MockHttpCacheResponder.new(controller) }
25
+
26
+ it 'returns nothing with a single resource on get' do
27
+ responder.stub(get?: true, fresh_when: true, resource: resource)
28
+
29
+ expect(responder.to_format).to be_nil
30
+ end
31
+
32
+ it 'passes through with multiple resources on get' do
33
+ responder.stub(get?: true, resource: collection)
34
+
35
+ expect(responder.to_format).to be_present
36
+ end
37
+
38
+ it 'passes through without a fresh resource' do
39
+ controller.stub(fresh_when: false)
40
+ responder.stub(get?: true, resource: resource)
41
+
42
+ expect(responder.to_format).to be_present
43
+ end
44
+
45
+ it 'passes through without a get request' do
46
+ responder.stub(get?: false, resource: resource)
47
+
48
+ expect(responder.to_format).to be_present
49
+ end
50
+
51
+ it 'does not cache if perform_caching is false' do
52
+ responder.stub(get?: true, resource: resource)
53
+
54
+ ActionController::Base.stub(perform_caching: false)
55
+
56
+ expect(responder.to_format).to be_present
57
+ end
58
+ end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ describe Desponders::PaginatedResponder do
4
+ class MockPaginatedResponderBase
5
+ def to_format
6
+ end
7
+ end
8
+
9
+ class MockPaginatedResponder < MockPaginatedResponderBase
10
+ include Desponders::PaginatedResponder
11
+
12
+ attr_accessor :controller, :resource
13
+
14
+ def initialize(controller, resource)
15
+ @controller = controller
16
+ @resource = resource
17
+ end
18
+
19
+ def get?; true; end
20
+ end
21
+
22
+ let(:controller) { double(:controller, request: request, response: response) }
23
+ let(:paginated) { double(:paginated) }
24
+ let(:request) { double(:request, params: {}, url: 'https://example.com/missions') }
25
+ let(:response) { double(:response, headers: {}) }
26
+ let(:resource) { double(:resource, paginate: paginated, size: 100) }
27
+
28
+ subject(:responder) { MockPaginatedResponder.new(controller, resource) }
29
+
30
+ def link_header
31
+ controller.response.headers['Link']
32
+ end
33
+
34
+ context 'with a paginatable resource on a get request' do
35
+ it 'replaces the current resource with a paginated scope' do
36
+ responder.to_format
37
+ responder.resource.should eq(paginated)
38
+ end
39
+
40
+ it 'defaults pagination to the first page' do
41
+ resource.should_receive(:paginate).with(hash_including(page: 1))
42
+ responder.to_format
43
+ end
44
+
45
+ it 'uses provided page and per_page params' do
46
+ resource.should_receive(:paginate).with(page: 2, per_page: 25)
47
+
48
+ request.params[:page] = 2
49
+ request.params[:per_page] = 25
50
+
51
+ responder.to_format
52
+ end
53
+
54
+ it 'injects resource urls into a LINK header' do
55
+ request.params[:page] = 2
56
+
57
+ responder.to_format
58
+
59
+ link_header.tap do |header|
60
+ header.should include('https://example.com/missions?page=1&per_page=30; rel="first"')
61
+ header.should include('https://example.com/missions?page=1&per_page=30; rel="prev"')
62
+ header.should include('https://example.com/missions?page=3&per_page=30; rel="next"')
63
+ header.should include('https://example.com/missions?page=4&per_page=30; rel="last"')
64
+ end
65
+ end
66
+
67
+ it 'ignores params in the request url when constructing headers' do
68
+ request.stub(url: 'https://example.com/missions?thing=1&other=2')
69
+
70
+ responder.to_format
71
+
72
+ link_header.should_not include('?thing=1&other=2')
73
+ end
74
+
75
+ it 'calculates the next page based on resource size and the per_page value' do
76
+ resource.stub(size: 500)
77
+
78
+ request.params[:page] = 3
79
+ request.params[:per_page] = 50
80
+
81
+ responder.to_format
82
+
83
+ link_header.tap do |header|
84
+ header.should include('page=2&per_page=50; rel="prev"')
85
+ header.should include('page=4&per_page=50; rel="next"')
86
+ end
87
+ end
88
+
89
+ it 'prevents the next and last pages from being 0' do
90
+ resource.stub(size: 0)
91
+
92
+ responder.to_format
93
+
94
+ link_header.should include('page=1&per_page=30; rel="next"')
95
+ link_header.should include('page=1&per_page=30; rel="last"')
96
+ end
97
+
98
+ it 'calculates the last page based on resource size and the per_page value' do
99
+ resource.stub(size: 500)
100
+
101
+ request.params[:per_page] = 50
102
+
103
+ responder.to_format
104
+
105
+ link_header.should include('page=10&per_page=50; rel="last"')
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Desponders::RestResponder do
4
+ class MockRestResponderBase
5
+ def to_format
6
+ '{}'
7
+ end
8
+ end
9
+
10
+ class MockRestResponder < MockRestResponderBase
11
+ include Desponders::RestResponder
12
+
13
+ attr_accessor :resource
14
+
15
+ def initialize(resource)
16
+ @resource = resource
17
+ end
18
+
19
+ def display
20
+ end
21
+
22
+ def get?; false; end
23
+ def post?; false; end
24
+ def put?; false; end
25
+ def delete?; false; end
26
+ def has_errors?; false; end
27
+ end
28
+
29
+ let(:resource) { double(:resource) }
30
+
31
+ subject(:responder) { MockRestResponder.new(resource) }
32
+
33
+ it 'renders the resource with 200 status with a get request' do
34
+ responder.stub(get?: true)
35
+
36
+ expect(responder).to receive(:display).with(resource, status: :ok)
37
+
38
+ responder.to_format
39
+ end
40
+
41
+ it 'renders the resource with 201 created with a create request' do
42
+ responder.stub(post?: true)
43
+
44
+ expect(responder).to receive(:display).with(resource, status: :created)
45
+
46
+ responder.to_format
47
+ end
48
+
49
+ it 'renders the resource with a put request' do
50
+ responder.stub(put?: true)
51
+
52
+ expect(responder).to receive(:display).with(resource, status: :ok)
53
+
54
+ responder.to_format
55
+ end
56
+
57
+ it 'renders no content with a delete request' do
58
+ responder.stub(delete?: true)
59
+
60
+ expect(responder).to receive(:display).with({}, status: :no_content)
61
+
62
+ responder.to_format
63
+ end
64
+
65
+ it 'falls through to super with errors' do
66
+ responder.stub(has_errors?: true)
67
+
68
+ expect(responder.to_format).to eq('{}')
69
+ end
70
+ end
@@ -0,0 +1,19 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+
4
+ require 'active_support'
5
+ require 'action_controller'
6
+ require 'rails/railtie'
7
+ require 'i18n'
8
+
9
+ ENV['RAILS_ENV'] = 'test'
10
+
11
+ require 'desponders'
12
+
13
+ RSpec.configure do |config|
14
+ config.treat_symbols_as_metadata_keys_with_true_values = true
15
+ config.run_all_when_everything_filtered = true
16
+ config.filter_run :focus
17
+
18
+ config.order = 'random'
19
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: desponders
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Parker Selbert
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ - - <
21
+ - !ruby/object:Gem::Version
22
+ version: '5'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '3.2'
30
+ - - <
31
+ - !ruby/object:Gem::Version
32
+ version: '5'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ version: '1.3'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: '1.3'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: 2.14.0
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ~>
73
+ - !ruby/object:Gem::Version
74
+ version: 2.14.0
75
+ description: A stack of light-weight responders tailored to JSON APIs
76
+ email:
77
+ - parker@sorentwo.com
78
+ executables: []
79
+ extensions: []
80
+ extra_rdoc_files: []
81
+ files:
82
+ - .gitignore
83
+ - .rspec
84
+ - .travis.yml
85
+ - CHANGELOG.md
86
+ - Gemfile
87
+ - LICENSE.txt
88
+ - README.md
89
+ - Rakefile
90
+ - desponders.gemspec
91
+ - lib/desponders.rb
92
+ - lib/desponders/error_responder.rb
93
+ - lib/desponders/http_cache_responder.rb
94
+ - lib/desponders/locales/en.yml
95
+ - lib/desponders/paginated_responder.rb
96
+ - lib/desponders/rest_responder.rb
97
+ - lib/desponders/version.rb
98
+ - spec/desponders/error_responder_spec.rb
99
+ - spec/desponders/http_cache_responder_spec.rb
100
+ - spec/desponders/paginated_responder_spec.rb
101
+ - spec/desponders/rest_responder_spec.rb
102
+ - spec/spec_helper.rb
103
+ homepage: https://github.com/dscout/desponders
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.0.0
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: A stack of light-weight responders tailored to JSON APIs
127
+ test_files:
128
+ - spec/desponders/error_responder_spec.rb
129
+ - spec/desponders/http_cache_responder_spec.rb
130
+ - spec/desponders/paginated_responder_spec.rb
131
+ - spec/desponders/rest_responder_spec.rb
132
+ - spec/spec_helper.rb