roar 0.11.9 → 0.11.10

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.
@@ -1,3 +1,7 @@
1
+ ## 0.11.10
2
+ * Fix a syntax error for Ruby 1.8.
3
+ * Store link definitions in `representable_attrs(:links)` now and no longer in the `LinksDefinition` instance itself. removing `#links_definition` in favor of `#link_configs`.
4
+
1
5
  ## 0.11.9
2
6
 
3
7
  * When using `Feature::Client` hyperlinks are no longer rendered in POST and PUT since we pass `links: false`.
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in roar.gemspec
4
4
  gemspec
5
5
 
6
- gem "representable", ">= 1.3.1"
6
+ gem "representable", ">= 1.3.2"
7
7
 
8
8
 
9
9
  group :test do
@@ -1,3 +1,4 @@
1
1
  * Add proxies, so nested models can be lazy-loaded.
2
2
  * move #prepare_links! call to #_links or something so it doesn't need to be called in #serialize.
3
- * alias Roar::Representer to Representer
3
+ * alias Roar::Representer to Representer
4
+ * remove #before_serialize and just overwrite #serialize
@@ -37,6 +37,7 @@ module Roar
37
37
  module Hypermedia
38
38
  def self.included(base)
39
39
  base.extend ClassMethods
40
+ base.extend InheritableArray
40
41
  end
41
42
 
42
43
  def before_serialize(options={})
@@ -60,15 +61,19 @@ module Roar
60
61
  ary.each { |lnk| links.add(lnk) }
61
62
  end
62
63
 
63
- private
64
- def links_definition
65
- representable_attrs.find { |d| d.is_a?(LinksDefinition) } or [] # FIXME: this is a bug as soon as #links_definition is used somewhere else beside #prepare_links.
64
+ module LinkConfigsMethod
65
+ def link_configs
66
+ representable_attrs.inheritable_array(:links)
67
+ end
66
68
  end
67
69
 
70
+ include LinkConfigsMethod
71
+
72
+ private
68
73
  # Setup hypermedia links by invoking their blocks. Usually called by #serialize.
69
74
  def prepare_links!(*args)
70
75
  # TODO: move this method to _links or something so it doesn't need to be called in #serialize.
71
- compile_links_for(links_definition, *args).each do |lnk|
76
+ compile_links_for(link_configs, *args).each do |lnk|
72
77
  links.add(lnk) # TODO: move to LinkCollection.new.
73
78
  end
74
79
  end
@@ -117,42 +122,20 @@ module Roar
117
122
  # Note that you're free to put decider logic into #link blocks, too.
118
123
  def link(options, &block)
119
124
  options = {:rel => options} if options.is_a?(Symbol)
120
- links_definition << [options, block]
125
+ create_links_definition # this assures the links are rendered at the right position.
126
+ link_configs << [options, block]
121
127
  end
122
128
 
129
+ include LinkConfigsMethod
130
+
123
131
  private
124
132
  def create_links_definition
125
- representable_attrs << links = LinksDefinition.new(*links_definition_options)
126
- links
127
- end
128
-
129
- def links_definition
130
- representable_attrs.find { |d| d.is_a?(LinksDefinition) } or create_links_definition
133
+ return if representable_attrs.find { |d| d.is_a?(LinksDefinition) }
134
+ representable_attrs << LinksDefinition.new(*links_definition_options)
131
135
  end
132
136
  end
133
137
 
134
-
135
138
  class LinksDefinition < Representable::Definition
136
- include Enumerable
137
-
138
- attr_accessor :rel2block
139
- def initialize(*)
140
- super
141
- @rel2block = []
142
- end
143
-
144
- def <<(args)
145
- rel2block << args
146
- end
147
-
148
- def each(*args, &block)
149
- rel2block.each(*args, &block)
150
- end
151
-
152
- # DISCUSS: where do we need this?
153
- def clone
154
- super.tap { |d| d.rel2block = rel2block.clone }
155
- end
156
139
  end
157
140
 
158
141
 
@@ -171,6 +154,31 @@ module Roar
171
154
  marshal_load(hash.inject({}) { |h, (k,v)| h[k.to_sym] = v; h })
172
155
  end
173
156
  end
157
+
158
+ # TODO: move to separate module
159
+ # DISCUSS: experimental. this will soon be moved to a separate gem
160
+ module InheritableArray
161
+ def representable_attrs
162
+ super.extend(ConfigExtensions)
163
+ end
164
+
165
+ module ConfigExtensions
166
+ def inheritable_array(name)
167
+ inheritable_arrays[name] ||= []
168
+ end
169
+ def inheritable_arrays
170
+ @inheritable_arrays ||= {}
171
+ end
172
+
173
+ def inherit(parent)
174
+ super
175
+
176
+ parent.inheritable_arrays.keys.each do |k|
177
+ inheritable_array(k).push *parent.inheritable_array(k).clone
178
+ end
179
+ end
180
+ end
181
+ end
174
182
  end
175
183
  end
176
184
  end
@@ -23,7 +23,7 @@ module Roar::Representer::JSON
23
23
 
24
24
  collection :queries, :extend => Roar::Representer::JSON::HyperlinkRepresenter
25
25
  def queries
26
- compile_links_for(representable_attrs.collection_representers[:queries].representable_attrs.first)
26
+ compile_links_for(representable_attrs.collection_representers[:queries].link_configs)
27
27
  end
28
28
  def queries=(v)
29
29
  end
@@ -43,7 +43,7 @@ module Roar::Representer::JSON
43
43
 
44
44
  property :__href, :as => :href
45
45
  def __href
46
- compile_links_for(representable_attrs.collection_representers[:href].representable_attrs.first).first.href
46
+ compile_links_for(representable_attrs.collection_representers[:href].link_configs).first.href
47
47
  end
48
48
 
49
49
 
@@ -119,7 +119,7 @@ module Roar::Representer::JSON
119
119
  # TODO: share with main module!
120
120
  property :__href, :as => :href
121
121
  def __href
122
- compile_links_for(representable_attrs.collection_representers[:href].representable_attrs.first).first.href
122
+ compile_links_for(representable_attrs.collection_representers[:href].link_configs).first.href
123
123
  end
124
124
  def __href=(v)
125
125
  @__href = Roar::Representer::Feature::Hypermedia::Hyperlink.new(:href => v)
@@ -81,28 +81,28 @@ module Roar::Representer
81
81
  module Links
82
82
  def self.included(base)
83
83
  base.class_eval do
84
+ extend Links::ClassMethods # ::links_definition_options
84
85
  include Roar::Representer::Feature::Hypermedia
85
- include InstanceMethods
86
- extend Links::ClassMethods
86
+ include InstanceMethods
87
87
  end
88
88
  end
89
-
89
+
90
90
  module InstanceMethods
91
91
  private
92
92
  def prepare_link_for(href, options)
93
93
  return super(href, options) unless options[:array] # TODO: remove :array and use special instan
94
-
94
+
95
95
  list = href.collect { |opts| Feature::Hypermedia::Hyperlink.new(opts.merge!(:rel => options[:rel])) }
96
96
  LinkArray.new(list)
97
97
  end
98
-
98
+
99
99
  # TODO: move to LinksDefinition.
100
100
  def link_array_rels
101
- links_definition.collect { |cfg| cfg.first[:array] ? cfg.first[:rel] : nil }.compact
101
+ link_configs.collect { |cfg| cfg.first[:array] ? cfg.first[:rel] : nil }.compact
102
102
  end
103
103
  end
104
-
105
-
104
+
105
+
106
106
  require 'representable/json/hash'
107
107
  module LinkCollectionRepresenter
108
108
  include Representable::JSON::Hash
@@ -115,11 +115,11 @@ module Roar::Representer
115
115
  hsh.each { |k,v| v.delete(:rel) }
116
116
  end
117
117
  end
118
-
118
+
119
119
 
120
120
  def from_hash(hash, options={})
121
121
  hash.each { |k,v| hash[k] = LinkArray.new(v) if is_array?(k) }
122
-
122
+
123
123
  hsh = super(hash) # this is where :class and :extend do the work.
124
124
 
125
125
  hsh.each { |k, v| v.rel = k }
@@ -154,16 +154,18 @@ module Roar::Representer
154
154
  module ClassMethods
155
155
  def links_definition_options
156
156
  [:links,
157
- :from => :links,
158
- :extend => HAL::Links::LinkCollectionRepresenter,
159
- :instance => lambda { |hsh| LinkCollection.new(link_array_rels) } # defined in InstanceMethods as this is executed in represented context.
157
+ {
158
+ :from => :links,
159
+ :extend => HAL::Links::LinkCollectionRepresenter,
160
+ :instance => lambda { |hsh| LinkCollection.new(link_array_rels) } # defined in InstanceMethods as this is executed in represented context.
161
+ }
160
162
  ]
161
163
  end
162
164
 
163
165
  # Use this to define link arrays. It accepts the shared rel attribute and an array of options per link object.
164
166
  #
165
167
  # links :self do
166
- # [{:lang => "en", :href => "http://en.hit"},
168
+ # [{:lang => "en", :href => "http://en.hit"},
167
169
  # {:lang => "de", :href => "http://de.hit"}]
168
170
  # end
169
171
  def links(options, &block)
@@ -1,3 +1,3 @@
1
1
  module Roar
2
- VERSION = "0.11.9"
2
+ VERSION = "0.11.10"
3
3
  end
@@ -18,7 +18,7 @@ class HalLinkTest < MiniTest::Spec
18
18
 
19
19
  describe "#to_json" do
20
20
  it "uses 'links' key" do
21
- assert_equal subject.to_json, "{\"links\":{\"self\":{\"href\":\"//songs\"}}}"
21
+ subject.to_json.must_equal "{\"links\":{\"self\":{\"href\":\"//songs\"}}}"
22
22
  end
23
23
  end
24
24
 
@@ -134,39 +134,3 @@ class LinkCollectionTest < MiniTest::Spec
134
134
  end
135
135
  end
136
136
  end
137
-
138
- class HyperlinkInheritanceTest < MiniTest::Spec
139
- describe "when the base representer has a link" do
140
- before do
141
- module BaseRepresenter
142
- include Roar::Representer::JSON
143
- include Roar::Representer::Feature::Hypermedia
144
-
145
- link(:base) { "http://base" }
146
- end
147
-
148
- module Foo
149
- include Roar::Representer::JSON
150
- include Roar::Representer::Feature::Hypermedia
151
- include BaseRepresenter
152
-
153
- link(:foo) { "http://foo" }
154
- end
155
-
156
- module Bar
157
- include Roar::Representer::JSON
158
- include Roar::Representer::Feature::Hypermedia
159
- include BaseRepresenter
160
-
161
- link(:bar) { "http://bar" }
162
- end
163
- end
164
-
165
- it "should inherit parent links" do
166
- foo = Object.new.extend(Foo)
167
-
168
- assert_equal "{\"links\":[{\"rel\":\"base\",\"href\":\"http://base\"},{\"rel\":\"foo\",\"href\":\"http://foo\"}]}", foo.to_json
169
- end
170
-
171
- end
172
- end
@@ -1,6 +1,44 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class HypermediaTest < MiniTest::Spec
4
+ describe "inheritance" do
5
+ before do
6
+ module BaseRepresenter
7
+ include Roar::Representer::JSON
8
+ include Roar::Representer::Feature::Hypermedia
9
+
10
+ link(:base) { "http://base" }
11
+ end
12
+
13
+ module Bar
14
+ include Roar::Representer::JSON
15
+ include Roar::Representer::Feature::Hypermedia
16
+
17
+ link(:bar) { "http://bar" }
18
+ end
19
+
20
+ module Foo
21
+ include Roar::Representer::JSON
22
+ include Roar::Representer::Feature::Hypermedia
23
+ include BaseRepresenter
24
+ include Bar
25
+
26
+ link(:foo) { "http://foo" }
27
+ end
28
+ end
29
+
30
+ it "inherits parent links" do
31
+ foo = Object.new.extend(Foo)
32
+
33
+ assert_equal "{\"links\":[{\"rel\":\"base\",\"href\":\"http://base\"},{\"rel\":\"bar\",\"href\":\"http://bar\"},{\"rel\":\"foo\",\"href\":\"http://foo\"}]}", foo.to_json
34
+ end
35
+
36
+ it "inherits links from all mixed-in representers" do
37
+ skip
38
+ Object.new.extend(BaseRepresenter).extend(Bar).to_json.must_equal "{\"links\":[{\"rel\":\"base\",\"href\":\"http://base\"},{\"rel\":\"bar\",\"href\":\"http://bar\"}]}"
39
+ end
40
+ end
41
+
4
42
  describe "#links_array" do
5
43
  subject { Object.new.extend(rpr) }
6
44
 
@@ -89,35 +127,6 @@ class HypermediaTest < MiniTest::Spec
89
127
  end
90
128
  end
91
129
 
92
- class LinksDefinitionTest < MiniTest::Spec
93
- describe "LinksDefinition" do
94
- subject { Roar::Representer::Feature::Hypermedia::LinksDefinition.new(:links) }
95
-
96
- it "responds to #<<" do
97
- subject << "arbitrary bullshit"
98
- subject.to_a.must_equal ["arbitrary bullshit"]
99
- end
100
-
101
- it "responds to #each" do
102
- subject.to_a.must_equal []
103
- end
104
-
105
- it "accepts options in constructor" do
106
- assert_equal [], subject.rel2block
107
- end
108
-
109
- it "accepts configuration" do
110
- subject.rel2block << {:rel => :self}
111
- assert_equal [{:rel=>:self}], subject.rel2block
112
- end
113
-
114
- it "responds to #clone" do
115
- subject.rel2block << {:rel => :self}
116
- assert subject.clone.rel2block.object_id != subject.rel2block.object_id
117
- end
118
- end
119
- end
120
-
121
130
  class HyperlinkTest < MiniTest::Spec
122
131
  describe "Hyperlink" do
123
132
  subject { link(:rel => "self", "href" => "http://self", "data-whatever" => "Hey, @myabc") }
@@ -144,4 +153,61 @@ class HyperlinkTest < MiniTest::Spec
144
153
  assert_equal ["rel:self", "href:http://self", "data-whatever:Hey, @myabc"], subject.collect { |k,v| "#{k}:#{v}" }
145
154
  end
146
155
  end
156
+
157
+ describe "Config inheritance" do
158
+ # TODO: this section will soon be moved to uber.
159
+ describe "inheritance when including" do
160
+ # TODO: test all the below issues AND if cloning works.
161
+ module TestMethods
162
+ def representer_for(modules=[Roar::Representer::Feature::Hypermedia, Representable], &block)
163
+ Module.new do
164
+ extend TestMethods
165
+ include *modules
166
+ module_exec(&block)
167
+ end
168
+ end
169
+ end
170
+ include TestMethods
171
+
172
+ it "inherits to uninitialized child" do
173
+ representer_for do # child
174
+ include(representer_for do # parent
175
+ representable_attrs.inheritable_array(:links) << "bar"
176
+ end)
177
+ end.representable_attrs.inheritable_array(:links).must_equal(["bar"])
178
+ end
179
+
180
+ it "works with uninitialized parent" do
181
+ representer_for do # child
182
+ representable_attrs.inheritable_array(:links) << "bar"
183
+
184
+ include(representer_for do # parent
185
+ end)
186
+ end.representable_attrs.inheritable_array(:links).must_equal(["bar"])
187
+ end
188
+
189
+ it "inherits when both are initialized" do
190
+ representer_for do # child
191
+ representable_attrs.inheritable_array(:links) << "bar"
192
+
193
+ include(representer_for do # parent
194
+ representable_attrs.inheritable_array(:links) << "stadium"
195
+ end)
196
+ end.representable_attrs.inheritable_array(:links).must_equal(["bar", "stadium"])
197
+ end
198
+
199
+ it "clones parent inheritables" do # FIXME: actually we don't clone here!
200
+ representer_for do # child
201
+ representable_attrs.inheritable_array(:links) << "bar"
202
+
203
+ include(parent = representer_for do # parent
204
+ representable_attrs.inheritable_array(:links) << "stadium"
205
+ end)
206
+
207
+ parent.representable_attrs.inheritable_array(:links) << "park" # modify parent array.
208
+
209
+ end.representable_attrs.inheritable_array(:links).must_equal(["bar", "stadium"])
210
+ end
211
+ end
212
+ end
147
213
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.9
4
+ version: 0.11.10
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-02-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: representable