roar 0.12.1 → 0.12.2

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,368 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+
4
+ require 'ostruct'
5
+ require 'roar/representer/json'
6
+
7
+ def reset_representer(*module_name)
8
+ module_name.each do |mod|
9
+ mod.module_eval do
10
+ @representable_attrs = nil
11
+ end
12
+ end
13
+ end
14
+
15
+
16
+ class Song < OpenStruct
17
+ end
18
+
19
+ module SongRepresenter
20
+ include Roar::Representer::JSON
21
+
22
+ property :title
23
+ end
24
+
25
+ song = Song.new(title: "Fate").extend(SongRepresenter)
26
+ puts song.to_json
27
+
28
+ # Parsing
29
+
30
+ song = Song.new.extend(SongRepresenter)
31
+ song.from_json('{"title":"Linoleum"}')
32
+ puts song.title
33
+
34
+
35
+ # Decorator
36
+
37
+ require 'roar/decorator'
38
+
39
+ module Decorator
40
+ class SongRepresenter < Roar::Decorator
41
+ include Roar::Representer::JSON
42
+
43
+ property :title
44
+ end
45
+ end
46
+
47
+ song = Song.new(title: "Medicine Balls")
48
+ puts Decorator::SongRepresenter.new(song).to_json
49
+
50
+ # Collections
51
+
52
+ reset_representer(SongRepresenter)
53
+
54
+ module SongRepresenter
55
+ include Roar::Representer::JSON
56
+
57
+ property :title
58
+ collection :composers
59
+ end
60
+
61
+
62
+ song = Song.new(title: "Roxanne", composers: ["Sting", "Stu Copeland"])
63
+ song.extend(SongRepresenter)
64
+ puts song.to_json
65
+
66
+ # Nesting
67
+
68
+ class Album < OpenStruct
69
+ end
70
+
71
+ module AlbumRepresenter
72
+ include Roar::Representer::JSON
73
+
74
+ property :title
75
+ collection :songs, extend: SongRepresenter, class: Song
76
+ end
77
+
78
+ album = Album.new(title: "True North", songs: [Song.new(title: "The Island"), Song.new(:title => "Changing Tide")])
79
+ album.extend(AlbumRepresenter)
80
+ puts album.to_json
81
+
82
+ album = Album.new
83
+ album.extend(AlbumRepresenter)
84
+
85
+ album.from_json('{"title":"Indestructible","songs":[{"title":"Tropical London"},{"title":"Roadblock"}]}')
86
+
87
+ puts album.songs.last.inspect
88
+
89
+ # Inline Representers # FIXME: what about collections?
90
+
91
+ reset_representer(AlbumRepresenter)
92
+
93
+ module AlbumRepresenter
94
+ include Roar::Representer::JSON
95
+
96
+ property :title
97
+
98
+ collection :songs, class: Song do
99
+ property :title
100
+ end
101
+ end
102
+
103
+ album = Album.new(title: "True North", songs: [Song.new(title: "The Island"), Song.new(:title => "Changing Tide")])
104
+ album.extend(AlbumRepresenter)
105
+ puts album.to_json
106
+
107
+
108
+
109
+ album = Album.new
110
+ album.extend(AlbumRepresenter)
111
+ album.from_json('{"title":"True North","songs":[{"title":"The Island"},{"title":"Changing Tide"}]}')
112
+ puts album.title
113
+ puts album.songs.first.title
114
+
115
+ # parse_strategy: :sync
116
+
117
+ reset_representer(AlbumRepresenter)
118
+
119
+ module AlbumRepresenter
120
+ include Roar::Representer::JSON
121
+
122
+ property :title
123
+
124
+ collection :songs, extend: SongRepresenter, parse_strategy: :sync
125
+ end
126
+
127
+
128
+ album = Album.new(title: "True North", songs: [Song.new(title: "The Island"), Song.new(:title => "Changing Tide")])
129
+ album.extend(AlbumRepresenter)
130
+
131
+ puts album.songs[0].object_id
132
+ album.from_json('{"title":"True North","songs":[{"title":"Secret Society"},{"title":"Changing Tide"}]}')
133
+ puts album.songs[0].title
134
+ puts album.songs[0].object_id##
135
+
136
+ # Coercion, renaming, ..
137
+
138
+ # Hypermedia
139
+
140
+ reset_representer(SongRepresenter)
141
+
142
+ module SongRepresenter
143
+ include Roar::Representer::JSON
144
+ include Roar::Representer::Feature::Hypermedia
145
+
146
+ property :title
147
+
148
+ link :self do
149
+ "http://songs/#{title}"
150
+ end
151
+ end
152
+
153
+ song.extend(SongRepresenter)
154
+ puts song.to_json
155
+
156
+ # roar-rails and URL helpers
157
+
158
+
159
+ # Passing options into link
160
+
161
+ reset_representer(SongRepresenter)
162
+
163
+ module SongRepresenter
164
+ include Roar::Representer::JSON
165
+
166
+ property :title
167
+
168
+ link :self do |opts|
169
+ "http://#{opts[:base_url]}songs/#{title}"
170
+ end
171
+ end
172
+
173
+ song.extend(SongRepresenter)
174
+ puts song.to_json(base_url: "localhost:3001/")
175
+
176
+
177
+ # Discovering Hypermedia
178
+
179
+ song = Song.new.extend(SongRepresenter)
180
+ song.from_json('{"title":"Roxanne","links":[{"rel":"self","href":"http://songs/Roxanne"}]}')
181
+ puts song.links[:self].href
182
+
183
+ # Media Formats: HAL
184
+
185
+ require 'roar/representer/json/hal'
186
+
187
+ module HAL
188
+ module SongRepresenter
189
+ include Roar::Representer::JSON::HAL
190
+
191
+ property :title
192
+
193
+ link :self do
194
+ "http://songs/#{title}"
195
+ end
196
+ end
197
+ end
198
+
199
+ song.extend(HAL::SongRepresenter)
200
+ puts song.to_json
201
+
202
+ reset_representer(AlbumRepresenter)
203
+
204
+ module AlbumRepresenter
205
+ include Roar::Representer::JSON::HAL
206
+
207
+ property :title
208
+
209
+ collection :songs, class: Song, embedded: true do
210
+ property :title
211
+ end
212
+ end
213
+
214
+ album = Album.new(title: "True North", songs: [Song.new(title: "The Island"), Song.new(:title => "Changing Tide")])
215
+ album.extend(AlbumRepresenter)
216
+ puts album.to_json
217
+
218
+ # Media Formats: JSON+Collection
219
+
220
+ require 'roar/representer/json/collection_json'
221
+
222
+
223
+ module Collection
224
+ module SongRepresenter
225
+ include Roar::Representer::JSON::CollectionJSON
226
+ version "1.0"
227
+ href { "http://localhost/songs/" }
228
+
229
+ property :title
230
+
231
+ items(:class => Song) do
232
+ href { "//songs/#{title}" }
233
+
234
+ property :title, :prompt => "Song title"
235
+
236
+ link(:download) { "//songs/#{title}.mp3" }
237
+ end
238
+
239
+ template do
240
+ property :title, :prompt => "Song title"
241
+ end
242
+
243
+ queries do
244
+ link :search do
245
+ {:href => "//search", :data => [{:name => "q", :value => ""}]}
246
+ end
247
+ end
248
+ end
249
+ end
250
+
251
+ song = Song.new(title: "Roxanne")
252
+ song.extend(Collection::SongRepresenter)
253
+ puts song.to_json
254
+
255
+
256
+
257
+ # Client-side
258
+ # share in gem, parse existing document.
259
+
260
+ reset_representer(SongRepresenter)
261
+
262
+ module SongRepresenter
263
+ include Roar::Representer::JSON
264
+ include Roar::Representer::Feature::Hypermedia
265
+
266
+ property :title
267
+ property :id
268
+
269
+ link :self do
270
+ "http://songs/#{title}"
271
+ end
272
+ end
273
+
274
+
275
+ require 'roar/representer/feature/client'
276
+
277
+ module Client
278
+ class Song < OpenStruct
279
+ include Roar::Representer::JSON
280
+ include SongRepresenter
281
+ include Roar::Representer::Feature::Client
282
+ end
283
+ end
284
+
285
+ song = Client::Song.new(title: "Roxanne")
286
+ song.post("http://localhost:4567/songs", "application/json")
287
+ puts song.id
288
+
289
+
290
+ song = Client::Song.new
291
+ song.get("http://localhost:4567/songs/1", "application/json")
292
+ puts song.title
293
+ puts song.links[:self].href
294
+
295
+ # XML
296
+
297
+ require 'roar/representer/xml'
298
+
299
+ module XML
300
+ module SongRepresenter
301
+ include Roar::Representer::XML
302
+ include Roar::Representer::Feature::Hypermedia
303
+
304
+ property :title
305
+ property :id
306
+
307
+ link :self do
308
+ "http://songs/#{title}"
309
+ end
310
+ end
311
+ end
312
+
313
+ song = Song.new(title: "Roxanne", id: 42)
314
+ song.extend(XML::SongRepresenter)
315
+ puts song.to_xml
316
+
317
+ # Coercion
318
+
319
+ reset_representer(SongRepresenter)
320
+
321
+ require 'roar/representer/feature/coercion'
322
+
323
+ module SongRepresenter
324
+ include Roar::Representer::JSON
325
+ include Roar::Representer::Feature::Coercion
326
+
327
+ property :title
328
+ property :released_at, type: DateTime
329
+ end
330
+
331
+ song = Song.new
332
+ song.extend(SongRepresenter)
333
+ song.from_json('{"released_at":"1981/03/31"}')
334
+
335
+ puts song.released_at
336
+
337
+
338
+ class LinkOptionsCollection < Array
339
+
340
+ end
341
+
342
+ module HyperlinkiRepresenter
343
+ include Roar::Representer::JSON
344
+
345
+ def to_hash(*) # setup the link
346
+ # FIXME: why does self.to_s throw a stack level too deep (SystemStackError) ?
347
+ "#{self}"
348
+ # how would the Link instance get access to its Definition in order to execute the block?
349
+ end
350
+ end
351
+
352
+ module Representer
353
+ include Roar::Representer::JSON
354
+
355
+ def self.links
356
+ [:self, :next]
357
+ end
358
+
359
+ collection :links, :extend => HyperlinkiRepresenter
360
+
361
+ def links
362
+ # get link configurations from representable_attrs object.
363
+ #self.representable_attrs.links
364
+ LinkOptionsCollection.new(["self", "next"])
365
+ end
366
+ end
367
+
368
+ puts "".extend(Representer).to_json
@@ -0,0 +1,18 @@
1
+ require "bundler/setup"
2
+ require "sinatra"
3
+ require "ostruct"
4
+ require "roar/representer/json"
5
+
6
+
7
+ get "/method" do
8
+ "<method>get</method>"
9
+ end
10
+
11
+ post "/songs" do
12
+ '{"id":"1","title":"Roxanne","links":[{"rel":"self","href":"http://localhost/songs/1"}]}'
13
+ end
14
+
15
+
16
+ get "/songs/1" do
17
+ '{"id":"1","title":"Roxanne","links":[{"rel":"self","href":"http://localhost/songs/1"}]}'
18
+ end
@@ -18,7 +18,7 @@ module Roar
18
18
  end
19
19
 
20
20
  module InstanceMethods
21
- def to_xml(*args)
21
+ def to_node(*args)
22
22
  before_serialize(*args)
23
23
  super
24
24
  end
@@ -1,3 +1,3 @@
1
1
  module Roar
2
- VERSION = "0.12.1"
2
+ VERSION = "0.12.2"
3
3
  end
@@ -1,10 +1,9 @@
1
1
  require 'test_helper'
2
- require 'roar/representer/feature/hypermedia'
3
- require 'roar/representer/json'
4
2
 
5
3
  class HypermediaTest < MiniTest::Spec
6
4
  describe "Hypermedia Feature" do
7
5
 
6
+ let (:song) { Song.new(:title => "Brandy Wine") }
8
7
 
9
8
  before do
10
9
  @bookmarks = Class.new do
@@ -29,23 +28,65 @@ class HypermediaTest < MiniTest::Spec
29
28
 
30
29
 
31
30
  describe "#to_xml" do
32
- it "sets up links and renders <link> correctly in XML" do
33
- assert_xml_equal '<bookmarks>
34
- <id>1</id>
35
- <link rel="self" href="http://bookmarks"/>
36
- <link rel="all" href="http://bookmarks/all"/>
37
- </bookmarks>', @bookmarks_with_links.new(:id => 1).to_xml
31
+ it "works when no links defined" do
32
+ repr = Module.new do
33
+ include Roar::Representer::XML
34
+ include Roar::Representer::Feature::Hypermedia
35
+
36
+ self.representation_wrap = "song"
37
+ property :title
38
+ end
39
+
40
+ song.extend(repr).to_xml.must_equal_xml "<song><title>Brandy Wine</title></song>"
38
41
  end
39
42
 
40
- it "still works even if there are no links defined" do
41
- assert_xml_equal '<bookmarks/>', @bookmarks.new.to_xml
43
+ let (:rpr) { Module.new do
44
+ include Roar::Representer::XML
45
+ include Roar::Representer::Feature::Hypermedia
46
+
47
+ self.representation_wrap = "song"
48
+ property :title
49
+
50
+ link(:self) { "/songs/#{title}" }
51
+ link(:all) { "/songs" }
52
+ end }
53
+
54
+ it "includes links in rendered document" do
55
+ song.extend(rpr).to_xml.must_equal_xml %{
56
+ <song>
57
+ <title>Brandy Wine</title>
58
+ <link rel="self" href="/songs/Brandy Wine"/>
59
+ <link rel="all" href="/songs"/>
60
+ </song>}
42
61
  end
43
62
 
44
- it "doesn't render links with :links => false" do
45
- assert_xml_equal '<bookmarks>
46
- <id>1</id>
47
- </bookmarks>',
48
- @bookmarks_with_links.new(:id => 1).to_xml(:links => false)
63
+ it "suppresses links when links: false" do
64
+ song.extend(rpr).to_xml(:links => false).must_equal_xml "<song><title>Brandy Wine</title></song>"
65
+ end
66
+
67
+ it "renders nested links" do
68
+ song_rpr = rpr
69
+
70
+ album_rpr = Module.new do
71
+ include Roar::Representer::XML
72
+ include Roar::Representer::Feature::Hypermedia
73
+
74
+ self.representation_wrap = "album"
75
+ collection :songs, :extend => song_rpr
76
+
77
+ link(:self) { "/albums/mixed" }
78
+ end
79
+
80
+ Album.new(:songs => [song]).extend(album_rpr).to_xml.must_equal_xml %{
81
+ <album>
82
+ <song>
83
+ <title>Brandy Wine</title>
84
+ <link rel="self" href="/songs/Brandy Wine"/>
85
+ <link rel="all" href="/songs"/>
86
+ </song>
87
+ <link rel="self" href="/albums/mixed"/>
88
+ </album>
89
+ }
49
90
  end
50
91
  end
51
92
 
@@ -122,7 +163,7 @@ end
122
163
  class LinkCollectionTest < MiniTest::Spec
123
164
  describe "LinkCollection" do
124
165
  subject { Roar::Representer::Feature::Hypermedia::LinkCollection.new }
125
-
166
+
126
167
  describe "#add" do
127
168
  it "keys by using rel string" do
128
169
  subject.size.must_equal 0