roar-rails 0.0.11 → 0.0.12

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/.gitignore CHANGED
@@ -3,7 +3,7 @@
3
3
  *.swo
4
4
  bin
5
5
  .bundle
6
- Gemfile.lock
6
+ Gemfile*.lock
7
7
  pkg/*
8
8
  test/dummy/log/*
9
9
  .rvmrc
data/CHANGES.markdown CHANGED
@@ -1,3 +1,7 @@
1
+ h2. 0.0.12
2
+
3
+ * Bumping representable to 1.4 which allows us using both extend and decorating representers.
4
+
1
5
  h2. 0.0.11
2
6
 
3
7
  * Back to `request.body.read` in `#consume!` (again). If anyone is having problems with empty incoming strings this is a Rails issue - update ;-)
data/README.markdown CHANGED
@@ -100,7 +100,7 @@ class SingersController < ApplicationController
100
100
  def create
101
101
  singer = Singer.new
102
102
  consume!(singer)
103
-
103
+
104
104
  respond_with singer
105
105
  end
106
106
  end
@@ -122,6 +122,18 @@ Note that it respects settings from `#represents`. It uses the same mechanics kn
122
122
  consume!(singer, :represent_with => MusicianRepresenter)
123
123
  ```
124
124
 
125
+ ## Using Decorators
126
+
127
+ If you prefer roar's decorator approach over extend, just go for it. roar-rails will figure out automatically which represent strategy to use.
128
+
129
+ ```ruby
130
+ class SingerRepresenter < Roar::Decorator
131
+ include Roar::Representer::JSON
132
+
133
+ property :name
134
+ end
135
+ ```
136
+
125
137
  ## URL Helpers
126
138
 
127
139
  Any URL helpers from the Rails app are automatically available in representers.
@@ -1,6 +1,6 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in roar-rails.gemspec
4
- gemspec path: '../'
4
+ gemspec :path => '../'
5
5
 
6
6
  gem 'railties', '~> 3.0.11'
@@ -1,6 +1,6 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in roar-rails.gemspec
4
- gemspec path: '../'
4
+ gemspec :path => '../'
5
5
 
6
6
  gem 'railties', '~> 3.2.0'
@@ -37,10 +37,16 @@ module Roar::Rails
37
37
 
38
38
 
39
39
  def consume!(model, options={})
40
- format = formats.first # FIXME: i expected request.content_mime_type to do the job. copied from responder.rb. this will return the wrong format when the controller responds to :json and :xml and the Content-type is :xml (?)
40
+ format = formats.first # FIXME: i expected request.content_mime_type to do the job. copied from responder.rb. this will return the wrong format when the controller responds to :json and :xml and the Content-type is :xml (?)
41
+ model = prepare_model_for(format, model, options)
42
+
43
+ model.send(compute_parsing_method(format), incoming_string) # e.g. from_json("...")
44
+ model
45
+ end
46
+
47
+ def prepare_model_for(format, model, options)
41
48
  representer = representer_for(format, model, options)
42
49
  extend_with!(model, representer)
43
- model.send(compute_parsing_method(format), incoming_string) # e.g. from_json("...")
44
50
  model
45
51
  end
46
52
 
@@ -4,7 +4,7 @@ module Roar::Rails
4
4
  def prepare_model!(model)
5
5
  # rails <= 3.1 compatibility. #display gets called for empty responses
6
6
  # >= 3.2 fixes by calling #head, not #display for all empty bodies (PUT, DELETE)
7
- return if respond_to?("empty_#{format}_resource") && model == empty_resource
7
+ return model if respond_to?("empty_#{format}_resource") && model == empty_resource
8
8
  super
9
9
  end
10
10
  end
@@ -2,31 +2,30 @@ module Roar::Rails
2
2
  module ModelMethods
3
3
  private
4
4
  # DISCUSS: move this into a generic namespace as we could need that in Sinatra as well.
5
- def extend_with!(model, representer)
6
- model.extend(representer)
5
+ def extend_with!(model, representer) # TODO: rename to #prepare_model.
6
+ representer.prepare(model)
7
7
  end
8
-
8
+
9
9
  def prepare_model!(model)
10
- representer = controller.representer_for(format, model, options)
11
- extend_with!(model, representer)
10
+ controller.prepare_model_for(format, model, options)
12
11
  end
13
12
  end
14
-
13
+
15
14
  module Responder
16
15
  include ModelMethods
17
-
16
+
18
17
  # DISCUSS: why THE FUCK is options not passed as a method argument but kept as an internal instance variable in the responder? this is something i will never understand about Rails.
19
18
  def display(model, *args)
20
19
  if representer = options.delete(:represent_items_with)
21
20
  render_items_with(model, representer) # convenience API, not recommended since it's missing hypermedia.
22
21
  return super
23
22
  end
24
-
25
- prepare_model!(model)
26
-
23
+
24
+ model = prepare_model!(model)
25
+
27
26
  super
28
27
  end
29
-
28
+
30
29
  private
31
30
  def render_items_with(collection, representer)
32
31
  collection.map! do |m| # DISCUSS: i don't like changing the method argument here.
@@ -34,7 +33,7 @@ module Roar::Rails
34
33
  m.to_hash # FIXME: huh? and what about XML?
35
34
  end
36
35
  end
37
-
36
+
38
37
  include VersionStrategy
39
38
  end
40
39
  end
@@ -1,5 +1,5 @@
1
1
  module Roar
2
2
  module Rails
3
- VERSION = "0.0.11"
3
+ VERSION = "0.0.12"
4
4
  end
5
5
  end
data/roar-rails.gemspec CHANGED
@@ -17,13 +17,14 @@ Gem::Specification.new do |s|
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
-
20
+
21
21
  s.add_runtime_dependency "roar", "~> 0.10"
22
+ s.add_runtime_dependency "representable", "~> 1.4"
22
23
  s.add_runtime_dependency "test_xml"
23
24
  s.add_runtime_dependency "actionpack", "~> 3.0"
24
25
  s.add_runtime_dependency "railties", "~> 3.0"
25
26
  s.add_runtime_dependency "hooks"
26
-
27
+
27
28
  s.add_development_dependency "minitest", ">= 2.8.1"
28
29
  s.add_development_dependency "tzinfo" # FIXME: why the hell do we need this for 3.1?
29
30
  end
@@ -4,7 +4,7 @@ Singer = Struct.new(:name)
4
4
 
5
5
  module SingersRepresenter
6
6
  include Roar::Representer::JSON
7
-
7
+
8
8
  collection :singers, :extend => SingerRepresenter
9
9
  def singers
10
10
  each
@@ -19,13 +19,13 @@ end
19
19
  class RepresentsTest < MiniTest::Spec
20
20
  class SingersController
21
21
  end
22
-
22
+
23
23
  before do
24
24
  @controller = Class.new do
25
25
  include Roar::Rails::ControllerAdditions
26
26
  end.new
27
27
  end
28
-
28
+
29
29
  describe "representer_for" do
30
30
  describe "nothing configured" do
31
31
  before do
@@ -34,16 +34,16 @@ class RepresentsTest < MiniTest::Spec
34
34
  self
35
35
  end.new
36
36
  end
37
-
37
+
38
38
  it "uses model class" do
39
39
  assert_equal SingerRepresenter, @controller.representer_for(:json, Singer.new)
40
40
  end
41
-
41
+
42
42
  it "uses plural controller name when collection" do
43
43
  assert_equal SingersRepresenter, @controller.representer_for(:json, [])
44
44
  end
45
45
  end
46
-
46
+
47
47
  describe "represents :json, Singer" do
48
48
  before do
49
49
  @controller = class ::WhateverController < ActionController::Base
@@ -52,17 +52,17 @@ class RepresentsTest < MiniTest::Spec
52
52
  self
53
53
  end.new
54
54
  end
55
-
55
+
56
56
  it "uses defined class for item" do
57
57
  assert_equal ObjectRepresenter, @controller.representer_for(:json, Singer.new)
58
58
  end
59
-
59
+
60
60
  it "uses plural name when collection" do
61
61
  assert_equal ObjectsRepresenter, @controller.representer_for(:json, [])
62
62
  end
63
63
  end
64
-
65
-
64
+
65
+
66
66
  describe "represents :json, :entity => SingerRepresenter" do
67
67
  before do
68
68
  @controller = class ::FooController < ActionController::Base
@@ -71,16 +71,16 @@ class RepresentsTest < MiniTest::Spec
71
71
  self
72
72
  end.new
73
73
  end
74
-
74
+
75
75
  it "returns :entity representer name" do
76
76
  assert_equal "ObjectRepresenter", @controller.representer_for(:json, Singer.new)
77
77
  end
78
-
78
+
79
79
  it "doesn't infer collection representer" do
80
80
  assert_equal nil, @controller.representer_for(:json, [])
81
81
  end
82
82
  end
83
-
83
+
84
84
  describe "represents :json, :entity => SingerRepresenter, :collection => SingersRepresenter" do
85
85
  before do
86
86
  @controller = class ::BooController < ActionController::Base
@@ -89,11 +89,11 @@ class RepresentsTest < MiniTest::Spec
89
89
  self
90
90
  end.new
91
91
  end
92
-
92
+
93
93
  it "uses defined class for item" do
94
94
  assert_equal "ObjectRepresenter", @controller.representer_for(:json, Singer.new)
95
95
  end
96
-
96
+
97
97
  it "uses defined class when collection" do
98
98
  assert_equal "SingersRepresenter", @controller.representer_for(:json, [])
99
99
  end
@@ -104,11 +104,11 @@ end
104
104
 
105
105
  class ResponderTest < ActionController::TestCase
106
106
  include Roar::Rails::TestCase
107
-
107
+
108
108
  class BaseController < ActionController::Base
109
109
  include Roar::Rails::ControllerAdditions
110
110
  respond_to :json
111
-
111
+
112
112
  def execute
113
113
  instance_exec &@block
114
114
  end
@@ -138,16 +138,16 @@ class ResponderTest < ActionController::TestCase
138
138
  singer = Singer.new("Bumi")
139
139
  respond_with singer
140
140
  end
141
-
141
+
142
142
  assert_equal singer.to_json, @response.body
143
143
  end
144
-
144
+
145
145
  test "responder finds SingersRepresenter for collections by convention" do
146
146
  get do
147
147
  singers = [Singer.new("Bumi"), Singer.new("Bjork"), Singer.new("Sinead")]
148
148
  respond_with singers
149
149
  end
150
-
150
+
151
151
  assert_equal({:singers => singers.collect {|s| s.extend(SingerRepresenter).to_hash }}.to_json, @response.body)
152
152
  end
153
153
 
@@ -165,68 +165,90 @@ class ResponderTest < ActionController::TestCase
165
165
  class SingersController < BaseController
166
166
  represents :json, Object
167
167
  end
168
-
168
+
169
169
  tests SingersController
170
-
170
+
171
171
  test "responder uses passed representer" do
172
172
  get do
173
173
  singer = Singer.new("Bumi")
174
174
  respond_with singer, :represent_with => SingerRepresenter
175
175
  end
176
-
176
+
177
177
  assert_equal singer.to_json, @response.body
178
178
  end
179
-
179
+
180
180
  test "responder uses passed representer for collection" do
181
181
  get do
182
182
  singers = [Singer.new("Bumi"), Singer.new("Bjork"), Singer.new("Sinead")]
183
183
  respond_with singers, :represent_with => SingersRepresenter
184
184
  end
185
-
185
+
186
186
  assert_equal({:singers => singers.collect {|s| s.extend(SingerRepresenter).to_hash }}.to_json, @response.body)
187
187
  end
188
-
188
+
189
189
  test "responder uses passed representer for collection items when :represent_items_with set" do
190
190
  get do
191
191
  singers = [Singer.new("Bumi"), Singer.new("Bjork"), Singer.new("Sinead")]
192
192
  respond_with singers, :represent_items_with => SingerRepresenter
193
193
  end
194
-
194
+
195
195
  assert_equal(singers.collect {|s| s.extend(SingerRepresenter).to_hash }.to_json, @response.body)
196
196
  end
197
197
  end
198
-
198
+
199
199
  class ConfiguredControllerTest < ResponderTest
200
200
  class MusicianController < BaseController
201
201
  represents :json, :entity => SingerRepresenter, :collection => SingersRepresenter
202
202
  end
203
-
203
+
204
204
  tests MusicianController
205
-
205
+
206
206
  test "responder uses configured representer" do
207
207
  get do
208
208
  singer = Singer.new("Bumi")
209
209
  respond_with singer
210
210
  end
211
-
211
+
212
212
  assert_equal singer.to_json, @response.body
213
213
  end
214
-
214
+
215
215
  test "responder uses configured representer for collection" do
216
216
  get do
217
217
  singers = [Singer.new("Bumi"), Singer.new("Bjork"), Singer.new("Sinead")]
218
218
  respond_with singers
219
219
  end
220
-
220
+
221
221
  assert_equal({:singers => singers.collect {|s| s.extend(SingerRepresenter).to_hash }}.to_json, @response.body)
222
222
  end
223
223
  end
224
-
224
+
225
+ class ControllerWithDecoratorTest < ResponderTest
226
+ class SingerRepresentation < Representable::Decorator
227
+ include Roar::Representer::JSON
228
+ include ::SingerRepresenter
229
+ end
230
+ class MusicianController < BaseController
231
+ represents :json, :entity => SingerRepresentation
232
+ end
233
+
234
+ tests MusicianController
235
+
236
+ test "responder uses configured decorating representer" do
237
+ get do
238
+ singer = Singer.new("Bumi")
239
+ respond_with singer
240
+ end
241
+
242
+ assert_equal "{\"name\":\"Bumi\"}", @response.body
243
+ end
244
+ end
245
+
246
+
225
247
  def get(&block)
226
248
  @controller.instance_eval do
227
249
  @block = block
228
250
  end
229
-
251
+
230
252
  super :execute, :format => 'json'
231
253
  end
232
254
 
@@ -236,7 +258,7 @@ class ResponderTest < ActionController::TestCase
236
258
  end
237
259
  super :execute, :format => 'json'
238
260
  end
239
-
261
+
240
262
  def singer(name="Bumi")
241
263
  singer = Musician.new(name)
242
264
  singer.extend SingerRepresenter
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roar-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.12
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-06 00:00:00.000000000 Z
12
+ date: 2013-04-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: roar
@@ -27,6 +27,22 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0.10'
30
+ - !ruby/object:Gem::Dependency
31
+ name: representable
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.4'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.4'
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: test_xml
32
48
  requirement: !ruby/object:Gem::Requirement