grape-rabl 0.4.3 → 0.6.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.
data/UPGRADING.md ADDED
@@ -0,0 +1,36 @@
1
+ # Upgrading Grape::Rabl
2
+
3
+ ## Upgrading to the next release
4
+
5
+ Ruby 2.7 or newer is required. Grape 1.x through 4.x are covered by CI, with Grape 3.x and 4.x tested on Ruby 3.3 and newer. Applications on Grape 1.x must use Rack 2.x.
6
+
7
+ ## Upgrading to >= 0.5
8
+
9
+ ### Fallback rendering when no RABL template is defined
10
+
11
+ Prior to v0.5.0, Grape::Rabl would always render content as JSON when no Rabl template was specified for a request. Beginning in v0.5.0 Grape::Rabl will now fallback to using the default response format [as determined by Grape](https://github.com/ruby-grape/grape#api-formats)
12
+
13
+ ```ruby
14
+ class SampleApi < Grape::API
15
+ format :xml
16
+ formatter :xml, Grape::Formatter::Rabl
17
+
18
+ get 'list' do
19
+ %w[thing]
20
+ end
21
+ end
22
+ ```
23
+
24
+ #### Former behavior
25
+
26
+ ```ruby
27
+ response.body # => ["thing"]
28
+ ```
29
+
30
+ #### Current behavior
31
+
32
+ ```ruby
33
+ response.body # => <?xml version="1.0" encoding="UTF-8"?>\n<strings type="array">\n <string>thing</string>\n</strings>
34
+ ```
35
+
36
+ See [#34](https://github.com/ruby-grape/grape-rabl/pull/34) for more information.
data/grape-rabl.gemspec CHANGED
@@ -1,8 +1,9 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/grape-rabl/version', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('lib/grape-rabl/version', __dir__)
3
4
 
4
5
  Gem::Specification.new do |gem|
5
- gem.authors = ["Piotr Niełacny"]
6
+ gem.authors = ['Piotr Niełacny']
6
7
  gem.email = ['piotr.nielacny@gmail.com']
7
8
  gem.description = 'Use rabl in grape'
8
9
  gem.summary = 'Use rabl in grape'
@@ -10,14 +11,14 @@ Gem::Specification.new do |gem|
10
11
 
11
12
  gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
12
13
  gem.files = `git ls-files`.split("\n")
13
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
14
  gem.name = 'grape-rabl'
15
15
  gem.require_paths = ['lib']
16
16
  gem.version = Grape::Rabl::VERSION
17
- gem.required_ruby_version = '>= 2.2.0'
17
+ gem.required_ruby_version = '>= 2.7.0'
18
18
 
19
19
  gem.add_dependency 'grape'
20
+ gem.add_dependency 'i18n'
20
21
  gem.add_dependency 'rabl'
21
22
  gem.add_dependency 'tilt'
22
- gem.add_dependency 'i18n'
23
+ gem.metadata['rubygems_mfa_required'] = 'true'
23
24
  end
data/lib/grape/rabl.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'grape-rabl'
2
4
 
3
5
  module Grape
@@ -1,10 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Grape
2
4
  module Rabl
3
5
  class Configuration
4
- attr_accessor :cache_template_loading
6
+ attr_accessor :cache_template_loading, :tilt_root
5
7
 
6
8
  def initialize
7
9
  @cache_template_loading = false
10
+ @tilt_root = nil
8
11
  end
9
12
  end
10
13
  end
@@ -1,11 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
 
3
5
  module Grape
4
6
  module Rabl
5
7
  class Formatter
8
+ @tilt_cache = {}
9
+ @tilt_cache_mutex = Mutex.new
10
+
6
11
  class << self
7
- def tilt_cache
8
- @tilt_cache ||= ::Tilt::Cache.new
12
+ attr_reader :tilt_cache
13
+
14
+ def fetch_cached_template(key)
15
+ @tilt_cache_mutex.synchronize do
16
+ tilt_cache.fetch(key) { tilt_cache[key] = yield }
17
+ end
9
18
  end
10
19
  end
11
20
 
@@ -29,17 +38,23 @@ module Grape
29
38
  end
30
39
  end
31
40
  else
32
- Grape::Formatter::Json.call object, env
41
+ fallback_formatter.call object, env
33
42
  end
34
43
  end
35
44
 
36
45
  private
37
46
 
47
+ # Find a formatter to fallback to. `env[Grape::Env::API_FORMAT]` will always be a
48
+ # valid formatter, otherwise a HTTP 406 error would have already have been thrown
49
+ def fallback_formatter
50
+ Grape::Formatter.formatter_for(env[Grape::Env::API_FORMAT], formatters: {})
51
+ end
52
+
38
53
  def view_path(template)
39
54
  if template.split('.')[-1] == 'rabl'
40
55
  File.join(env['api.tilt.root'], template)
41
56
  else
42
- File.join(env['api.tilt.root'], (template + '.rabl'))
57
+ File.join(env['api.tilt.root'], "#{template}.rabl")
43
58
  end
44
59
  end
45
60
 
@@ -49,6 +64,7 @@ module Grape
49
64
 
50
65
  def rabl
51
66
  raise 'missing rabl template' unless rabl_template
67
+
52
68
  set_view_root unless env['api.tilt.root']
53
69
  yield rabl_template
54
70
  end
@@ -62,12 +78,18 @@ module Grape
62
78
  end
63
79
 
64
80
  def set_view_root
65
- raise "Use Rack::Config to set 'api.tilt.root' in config.ru"
81
+ root = Grape::Rabl.configuration.tilt_root
82
+ env['api.tilt.root'] = root.is_a?(Proc) ? endpoint.instance_exec(&root) : root
83
+ return if env['api.tilt.root']
84
+
85
+ raise "Use Rack::Config to set 'api.tilt.root' in config.ru or configure 'tilt_root'"
66
86
  end
67
87
 
68
88
  def tilt_template(template)
69
89
  if Grape::Rabl.configuration.cache_template_loading
70
- Grape::Rabl::Formatter.tilt_cache.fetch(tilt_cache_key(template)) { ::Tilt.new(view_path(template), tilt_options) }
90
+ Grape::Rabl::Formatter.fetch_cached_template(tilt_cache_key(template)) do
91
+ ::Tilt.new(view_path(template), tilt_options)
92
+ end
71
93
  else
72
94
  ::Tilt.new(view_path(template), tilt_options)
73
95
  end
@@ -80,7 +102,9 @@ module Grape
80
102
  def layout_template
81
103
  layout_path = view_path(env['api.tilt.layout'] || 'layouts/application')
82
104
  if Grape::Rabl.configuration.cache_template_loading
83
- Grape::Rabl::Formatter.tilt_cache.fetch(tilt_cache_key(layout_path)) { ::Tilt.new(layout_path, tilt_options) if File.exist?(layout_path) }
105
+ Grape::Rabl::Formatter.fetch_cached_template(tilt_cache_key(layout_path)) do
106
+ ::Tilt.new(layout_path, tilt_options) if File.exist?(layout_path)
107
+ end
84
108
  else
85
109
  ::Tilt.new(layout_path, tilt_options) if File.exist?(layout_path)
86
110
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Grape
2
4
  module Rabl
3
5
  module Render
@@ -9,4 +11,4 @@ module Grape
9
11
  end
10
12
  end
11
13
 
12
- Grape::Endpoint.send(:include, Grape::Rabl::Render)
14
+ Grape::Endpoint.include Grape::Rabl::Render
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tilt'
2
4
 
3
5
  Rabl.register!
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Grape
2
4
  module Rabl
3
- VERSION = '0.4.3'.freeze
5
+ VERSION = '0.6.0'
4
6
  end
5
7
  end
data/lib/grape-rabl.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rabl'
2
4
  require 'grape'
3
5
  require 'grape/rabl'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'Grape::Rabl configuration' do
@@ -0,0 +1,218 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Grape::Rabl::Formatter do
6
+ before do
7
+ hide_const('Tilt::Cache')
8
+ described_class.tilt_cache.clear
9
+ end
10
+
11
+ after do
12
+ described_class.tilt_cache.clear
13
+ end
14
+
15
+ it 'reuses a cached template without Tilt::Cache' do
16
+ template = described_class.fetch_cached_template(:template) { Object.new }
17
+
18
+ expect(described_class.fetch_cached_template(:template) { raise 'recompiled' })
19
+ .to equal(template)
20
+ end
21
+
22
+ it 'memoizes missing layouts' do
23
+ expect(described_class.fetch_cached_template(:missing) { nil }).to be_nil
24
+ expect(described_class.fetch_cached_template(:missing) { raise 'looked up again' })
25
+ .to be_nil
26
+ end
27
+
28
+ it 'creates one cached template for concurrent requests' do
29
+ threads = 4.times.map do
30
+ Thread.new do
31
+ described_class.fetch_cached_template(:concurrent) do
32
+ sleep 0.01
33
+ Object.new
34
+ end
35
+ end
36
+ end
37
+
38
+ expect(threads.map(&:value).map(&:object_id).uniq.size).to eq(1)
39
+ end
40
+ end
41
+
42
+ describe 'configured template roots' do
43
+ let(:app) { Class.new(Grape::API) }
44
+ let(:request_root) { nil }
45
+ let(:root) do
46
+ lambda {
47
+ File.join(__dir__, 'views', env['api.version'] == 'v2' ? 'layout_test' : '')
48
+ }
49
+ end
50
+
51
+ before do
52
+ Grape::Rabl.configuration.tilt_root = root
53
+ Grape::Rabl::Formatter.tilt_cache.clear
54
+ app.version %w[v1 v2], using: :path
55
+ app.format :json
56
+ app.formatter :json, Grape::Formatter::Rabl
57
+ override = request_root
58
+ app.before { env['api.tilt.root'] = override } if override
59
+ app.get('/user', rabl: 'user', rabl_locals: { details: 'base template' }) do
60
+ @user = Struct.new(:name).new('Jane')
61
+ @project = Struct.new(:name).new('First')
62
+ @status = 200
63
+ end
64
+ end
65
+
66
+ after do
67
+ Grape::Rabl.reset_configuration!
68
+ Grape::Rabl::Formatter.tilt_cache.clear
69
+ end
70
+
71
+ [false, true].each do |cache|
72
+ context "with template caching #{cache ? 'enabled' : 'disabled'}" do
73
+ before do
74
+ Grape::Rabl.configuration.cache_template_loading = cache
75
+ end
76
+
77
+ it 'resolves templates and layouts per request without leaking roots' do
78
+ user = { 'user' => { 'name' => 'Jane', 'project' => { 'name' => 'First' } } }
79
+ base_user = { 'user' => user.fetch('user').merge('details' => 'base template') }
80
+
81
+ get '/v1/user'
82
+ expect(JSON.parse(last_response.body)).to eq(base_user)
83
+
84
+ get '/v2/user'
85
+ expect(JSON.parse(last_response.body)).to eq('status' => 200, 'result' => user)
86
+
87
+ get '/v1/user'
88
+ expect(JSON.parse(last_response.body)).to eq(base_user)
89
+ expect(Grape::Rabl.configuration.tilt_root).to equal(root)
90
+ end
91
+ end
92
+ end
93
+
94
+ context 'a static configured root' do
95
+ let(:root) { File.join(__dir__, 'views') }
96
+
97
+ it 'does not automatically append the API version' do
98
+ get '/v2/user'
99
+ expect(JSON.parse(last_response.body)).to have_key('user')
100
+ expect(last_request.env['api.tilt.root']).to eq(root)
101
+ end
102
+ end
103
+
104
+ context 'an explicit request root' do
105
+ let(:root) { -> { raise 'configured root should not run' } }
106
+ let(:request_root) { File.join(__dir__, 'views') }
107
+
108
+ it 'takes precedence over the configured root' do
109
+ get '/v1/user'
110
+ expect(JSON.parse(last_response.body)).to have_key('user')
111
+ end
112
+ end
113
+
114
+ context 'a missing resolved root' do
115
+ let(:root) { -> {} }
116
+
117
+ it 'raises the configuration error' do
118
+ expect { get '/v1/user' }.to raise_error(RuntimeError, /configure 'tilt_root'/)
119
+ end
120
+ end
121
+
122
+ context 'a failing root resolver' do
123
+ let(:root) { -> { raise 'root lookup failed' } }
124
+
125
+ it 'propagates the error' do
126
+ expect { get '/v1/user' }.to raise_error(RuntimeError, 'root lookup failed')
127
+ end
128
+
129
+ it 'does not run when falling back to the default formatter' do
130
+ app.get('/health') { { healthy: true } }
131
+ get '/v1/health'
132
+ expect(JSON.parse(last_response.body)).to eq('healthy' => true)
133
+ end
134
+ end
135
+ end
136
+
137
+ describe 'Grape::Rabl formatter' do
138
+ subject do
139
+ Class.new(Grape::API)
140
+ end
141
+
142
+ let(:xml_render) do
143
+ %(<?xml version="1.0" encoding="UTF-8"?>
144
+ <hash>
145
+ <errors type="array">
146
+ <error>bad</error>
147
+ <error>things</error>
148
+ <error>happened</error>
149
+ </errors>
150
+ </hash>
151
+ )
152
+ end
153
+
154
+ def app
155
+ subject
156
+ end
157
+
158
+ context 'rendering' do
159
+ context 'when no rabl template is specified' do
160
+ before do
161
+ # Grape::API defaults to the following declarations:
162
+ # content_type :xml, 'application/xml'
163
+ # content_type :json, 'application/json'
164
+ # content_type :binary, 'application/octet-stream'
165
+ # content_type :txt, 'text/plain'
166
+ # default_format :txt
167
+ subject.formatter :xml, Grape::Formatter::Rabl
168
+ subject.formatter :txt, Grape::Formatter::Rabl
169
+ subject.get('/oops') { { errors: %w[bad things happened] } }
170
+ expect_any_instance_of(Grape::Rabl::Formatter).to receive(:render).and_call_original
171
+ end
172
+
173
+ it 'falls back to :txt given no other format information' do
174
+ get '/oops'
175
+ expect(last_response.body).to eq({ errors: %w[bad things happened] }.to_s)
176
+ expect(last_response.headers['Content-Type']).to eq('text/plain')
177
+ end
178
+
179
+ it 'falls back to the file extension if it is a valid format' do
180
+ get '/oops.xml'
181
+ expect(last_response.body).to eq(xml_render)
182
+ expect(last_response.headers['Content-Type']).to eq('application/xml')
183
+ end
184
+
185
+ it 'falls back to the value of the `format` parameter in the query string if it is provided' do
186
+ get '/oops?format=xml'
187
+ expect(last_response.body).to eq(xml_render)
188
+ expect(last_response.headers['Content-Type']).to eq('application/xml')
189
+ end
190
+
191
+ it 'falls back to the format set by the `format` option if it is a valid format' do
192
+ # `format` option must be declared before endpoint
193
+ subject.format :xml
194
+ subject.get('/oops/2') { { errors: %w[bad things happened] } }
195
+
196
+ get '/oops/2'
197
+ expect(last_response.body).to eq(xml_render)
198
+ expect(last_response.headers['Content-Type']).to eq('application/xml')
199
+ end
200
+
201
+ it 'falls back to the `Accept` header if it is a valid format' do
202
+ get '/oops', {}, 'HTTP_ACCEPT' => 'application/xml'
203
+ expect(last_response.body).to eq(xml_render)
204
+ expect(last_response.headers['Content-Type']).to eq('application/xml')
205
+ end
206
+
207
+ it 'falls back to the default_format option if it is a valid format' do
208
+ # `default_format` option must be declared before endpoint
209
+ subject.default_format :xml
210
+ subject.get('/oops/2') { { errors: %w[bad things happened] } }
211
+
212
+ get '/oops/2'
213
+ expect(last_response.body).to eq(xml_render)
214
+ expect(last_response.headers['Content-Type']).to eq('application/xml')
215
+ end
216
+ end
217
+ end
218
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'Grape::Rabl layout' do
@@ -22,8 +24,8 @@ describe 'Grape::Rabl layout' do
22
24
  context 'default' do
23
25
  it 'proper render with default layout' do
24
26
  subject.get('/about', rabl: 'user') do
25
- @user = OpenStruct.new(name: 'LTe')
26
- @project = OpenStruct.new(name: 'First')
27
+ @user = Struct.new(:name).new('LTe')
28
+ @project = Struct.new(:name).new('First')
27
29
  @status = 200
28
30
  end
29
31
 
@@ -41,8 +43,8 @@ describe 'Grape::Rabl layout' do
41
43
 
42
44
  it 'proper render with specified layout' do
43
45
  subject.get('/about', rabl: 'user') do
44
- @user = OpenStruct.new(name: 'LTe')
45
- @project = OpenStruct.new(name: 'First')
46
+ @user = Struct.new(:name).new('LTe')
47
+ @project = Struct.new(:name).new('First')
46
48
  @status = 200
47
49
  end
48
50
 
@@ -61,8 +63,8 @@ describe 'Grape::Rabl layout' do
61
63
  FileUtils.cp_r("#{File.dirname(__FILE__)}/views/layout_test/.", @views_dir)
62
64
  subject.before { env['api.tilt.root'] = "#{File.expand_path('..', File.dirname(__FILE__))}/tmp" }
63
65
  subject.get('/home', rabl: 'user') do
64
- @user = OpenStruct.new(name: 'LTe', email: 'email@example.com')
65
- @project = OpenStruct.new(name: 'First')
66
+ @user = Struct.new(:name, :email).new('LTe', 'email@example.com')
67
+ @project = Struct.new(:name).new('First')
66
68
  @status = 200
67
69
  end
68
70
  end
@@ -79,7 +81,7 @@ describe 'Grape::Rabl layout' do
79
81
  get '/home'
80
82
  expect(last_response.status).to eq(200)
81
83
  old_response = last_response.body
82
- open(@layout, 'a') { |f| f << 'node(:test) { "test" }' }
84
+ File.open(@layout, 'a') { |f| f << 'node(:test) { "test" }' }
83
85
  get '/home'
84
86
  expect(last_response.status).to eq(200)
85
87
  new_response = last_response.body
@@ -90,7 +92,7 @@ describe 'Grape::Rabl layout' do
90
92
  get '/home'
91
93
  expect(last_response.status).to eq(200)
92
94
  old_response = last_response.body
93
- open(@layout, 'a') { |f| f << 'node(:test) { "test" }' }
95
+ File.open(@layout, 'a') { |f| f << 'node(:test) { "test" }' }
94
96
  get '/home'
95
97
  expect(last_response.status).to eq(200)
96
98
  new_response = last_response.body
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'Grape::Rabl partials' do
@@ -19,9 +21,9 @@ describe 'Grape::Rabl partials' do
19
21
 
20
22
  it 'proper render partials' do
21
23
  subject.get('/home', rabl: 'project') do
22
- @author = OpenStruct.new(author: 'LTe')
23
- @type = OpenStruct.new(type: 'paper')
24
- @project = OpenStruct.new(name: 'First', type: @type, author: @author)
24
+ @author = Struct.new(:author).new('LTe')
25
+ @type = Struct.new(:type).new('paper')
26
+ @project = Struct.new(:name, :type, :author).new('First', @type, @author)
25
27
  end
26
28
 
27
29
  get('/home')
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Rabl do
@@ -23,12 +25,8 @@ describe Grape::Rabl do
23
25
  end
24
26
 
25
27
  it 'should raise error about root directory' do
26
- begin
27
- subject.get('/home', rabl: true) {}
28
- get '/home'
29
- rescue Exception => e
30
- expect(e.message).to include "Use Rack::Config to set 'api.tilt.root' in config.ru"
31
- end
28
+ subject.get('/home', rabl: true) { nil }
29
+ expect { get '/home' }.to raise_error(RuntimeError, /Use Rack::Config to set 'api.tilt.root' in config.ru/)
32
30
  end
33
31
 
34
32
  context 'titl root is setup' do
@@ -40,7 +38,7 @@ describe Grape::Rabl do
40
38
 
41
39
  describe 'helpers' do
42
40
  it 'should execute helper' do
43
- subject.get('/home', rabl: 'helper') { @user = OpenStruct.new }
41
+ subject.get('/home', rabl: 'helper') { @user = Object.new }
44
42
  get '/home'
45
43
  expect(parsed_response).to eq(JSON.parse('{"user":{"helper":"my_helper"}}'))
46
44
  end
@@ -49,27 +47,27 @@ describe Grape::Rabl do
49
47
  describe '#render' do
50
48
  before do
51
49
  subject.get('/home', rabl: 'user') do
52
- @user = OpenStruct.new(name: 'LTe')
50
+ @user = Struct.new(:name).new('LTe')
53
51
  render rabl: 'admin'
54
52
  end
55
53
 
56
54
  subject.get('/admin/:id', rabl: 'user') do
57
- @user = OpenStruct.new(name: 'LTe')
55
+ @user = Struct.new(:name).new('LTe')
58
56
 
59
57
  render rabl: 'admin' if params[:id] == '1'
60
58
  end
61
59
 
62
60
  subject.get('/home-detail', rabl: 'user') do
63
- @user = OpenStruct.new(name: 'LTe')
61
+ @user = Struct.new(:name).new('LTe')
64
62
  render rabl: 'admin', locals: { details: 'amazing detail' }
65
63
  end
66
64
 
67
65
  subject.get('/about', rabl: 'user') do
68
- @user = OpenStruct.new(name: 'LTe')
66
+ @user = Struct.new(:name).new('LTe')
69
67
  end
70
68
 
71
69
  subject.get('/about-detail', rabl: 'user') do
72
- @user = OpenStruct.new(name: 'LTe')
70
+ @user = Struct.new(:name).new('LTe')
73
71
  render locals: { details: 'just a user' }
74
72
  end
75
73
  end
@@ -112,13 +110,13 @@ describe Grape::Rabl do
112
110
  end
113
111
 
114
112
  it 'should respond with proper content-type' do
115
- subject.get('/home', rabl: 'user') {}
113
+ subject.get('/home', rabl: 'user') { nil }
116
114
  get('/home')
117
115
  expect(last_response.headers['Content-Type']).to eq('application/json')
118
116
  end
119
117
 
120
118
  it 'should not raise error about root directory' do
121
- subject.get('/home', rabl: 'user') {}
119
+ subject.get('/home', rabl: 'user') { nil }
122
120
  get '/home'
123
121
  expect(last_response.status).to eq 200
124
122
  expect(last_response.body).not_to include "Use Rack::Config to set 'api.tilt.root' in config.ru"
@@ -127,8 +125,8 @@ describe Grape::Rabl do
127
125
  ['user', 'user.rabl'].each do |rabl_option|
128
126
  it "should render rabl template (#{rabl_option})" do
129
127
  subject.get('/home', rabl: rabl_option) do
130
- @user = OpenStruct.new(name: 'LTe', email: 'email@example.com')
131
- @project = OpenStruct.new(name: 'First')
128
+ @user = Struct.new(:name, :email).new('LTe', 'email@example.com')
129
+ @project = Struct.new(:name).new('First')
132
130
  end
133
131
 
134
132
  get '/home'
@@ -143,8 +141,8 @@ describe Grape::Rabl do
143
141
  FileUtils.cp("#{File.dirname(__FILE__)}/views/user.rabl", @template)
144
142
  subject.before { env['api.tilt.root'] = "#{File.expand_path('..', File.dirname(__FILE__))}/tmp" }
145
143
  subject.get('/home', rabl: 'user') do
146
- @user = OpenStruct.new(name: 'LTe', email: 'email@example.com')
147
- @project = OpenStruct.new(name: 'First')
144
+ @user = Struct.new(:name, :email).new('LTe', 'email@example.com')
145
+ @project = Struct.new(:name).new('First')
148
146
  end
149
147
  end
150
148
 
@@ -160,7 +158,7 @@ describe Grape::Rabl do
160
158
  get '/home'
161
159
  expect(last_response.status).to eq(200)
162
160
  old_response = last_response.body
163
- open(@template, 'a') { |f| f << 'node(:test) { "test" }' }
161
+ File.open(@template, 'a') { |f| f << 'node(:test) { "test" }' }
164
162
  get '/home'
165
163
  expect(last_response.status).to eq(200)
166
164
  new_response = last_response.body
@@ -178,7 +176,7 @@ describe Grape::Rabl do
178
176
  expect(last_response.status).to eq(200)
179
177
  xml_response = last_response.body
180
178
  expect(json_response).not_to eq(xml_response)
181
- open(@template, 'a') { |f| f << 'node(:test) { "test" }' }
179
+ File.open(@template, 'a') { |f| f << 'node(:test) { "test" }' }
182
180
  get '/home.xml'
183
181
  expect(last_response.status).to eq(200)
184
182
  expect(last_response.body).to eq(xml_response)
@@ -191,7 +189,7 @@ describe Grape::Rabl do
191
189
  get '/home'
192
190
  expect(last_response.status).to eq(200)
193
191
  old_response = last_response.body
194
- open(@template, 'a') { |f| f << 'node(:test) { "test" }' }
192
+ File.open(@template, 'a') { |f| f << 'node(:test) { "test" }' }
195
193
  get '/home'
196
194
  expect(last_response.status).to eq(200)
197
195
  new_response = last_response.body
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Grape::Rabl do
@@ -23,7 +25,7 @@ describe Grape::Rabl do
23
25
  end
24
26
 
25
27
  it 'should respond with proper content-type' do
26
- subject.get('/home', rabl: 'user') {}
28
+ subject.get('/home', rabl: 'user') { nil }
27
29
  get('/home')
28
30
  expect(last_response.headers['Content-Type']).to eq('application/xml')
29
31
  end
@@ -31,8 +33,8 @@ describe Grape::Rabl do
31
33
  ['user', 'user.rabl'].each do |rabl_option|
32
34
  it "should render rabl template (#{rabl_option})" do
33
35
  subject.get('/home', rabl: rabl_option) do
34
- @user = OpenStruct.new(name: 'LTe', email: 'email@example.com')
35
- @project = OpenStruct.new(name: 'First')
36
+ @user = Struct.new(:name, :email).new('LTe', 'email@example.com')
37
+ @project = Struct.new(:name).new('First')
36
38
  end
37
39
 
38
40
  get '/home'