roar 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.markdown CHANGED
@@ -1,3 +1,10 @@
1
+ h2. 0.9.0
2
+
3
+ * Using representable-0.12.x.
4
+ * `Representer::Base` is now simply `Representer`.
5
+ * Removed all the class methods from `HttpVerbs` except for `get`.
6
+
7
+
1
8
  h2. 0.8.3
2
9
 
3
10
  * Maintenance release for representable compat.
data/README.textile CHANGED
@@ -175,7 +175,7 @@ To create a new order, the frontend needs to POST to the REST backend. Here's ho
175
175
 
176
176
  <pre>
177
177
  order = Order.new(:client_id => current_user.id)
178
- order.post!("http://orders/")
178
+ order.post("http://orders/")
179
179
  </pre>
180
180
 
181
181
  A couple of noteworthy steps happen here.
@@ -184,7 +184,7 @@ A couple of noteworthy steps happen here.
184
184
  # Initial values like the client's id are passed as arguments and placed in the document.
185
185
  # The filled-out document is POSTed to the given URL.
186
186
  # The backend service creates an actual order record and sends back the representation.
187
- # In the @#post!@ call, the returned document is parsed and attributes in the representer instance are updated accordingly,
187
+ # In the @#post@ call, the returned document is parsed and attributes in the representer instance are updated accordingly,
188
188
 
189
189
  After the HTTP roundtrip, the order instance keeps all the information we need for proceeding the ordering workflow.
190
190
 
@@ -267,7 +267,7 @@ Here's what could happen in the frontend.
267
267
  <pre>
268
268
  beer = Article.new(:title => "Lonestar Beer")
269
269
  order.items << beer
270
- order.post!(order.links[:self])
270
+ order.post(order.links[:self])
271
271
  </pre>
272
272
 
273
273
  This was dead simple since representations can be composed of different documents in Roar.
@@ -43,7 +43,7 @@ module Roar
43
43
  singular_name = name.to_s.singularize
44
44
 
45
45
  super name, options.reverse_merge(
46
- :as => "representer/#{namespace}/#{singular_name}".classify.constantize,
46
+ :class => "representer/#{namespace}/#{singular_name}".classify.constantize,
47
47
  #:tag => singular_name # FIXME: how/where to decide if singular TAG or not?
48
48
  )
49
49
  end
@@ -0,0 +1,46 @@
1
+ require 'representable'
2
+
3
+ module Roar
4
+ module Representer
5
+ def self.included(base)
6
+ base.class_eval do
7
+ include Representable
8
+ extend ClassMethods
9
+ end
10
+ end
11
+
12
+
13
+ module ClassMethods
14
+ # Creates a representer instance and fills it with +attributes+.
15
+ # DISCUSS: remove.
16
+ def from_attributes(attributes) # DISCUSS: better move to #new? how do we handle the original #new then?
17
+ new.tap do |representer|
18
+ yield representer if block_given?
19
+ attributes.each { |p,v| representer.public_send("#{p}=", v) }
20
+ end
21
+ end
22
+ end
23
+
24
+
25
+ # Convert representer's attributes to a nested attributes hash.
26
+ def to_attributes
27
+ {}.tap do |attributes|
28
+ self.class.representable_attrs.each do |definition|
29
+ value = public_send(definition.getter)
30
+
31
+ if definition.typed?
32
+ value = definition.apply(value) do |v|
33
+ v.to_attributes # applied to each typed attribute (even in collections).
34
+ end
35
+ end
36
+
37
+ attributes[definition.name] = value
38
+ end
39
+ end
40
+ end
41
+
42
+ private
43
+ def before_serialize(*)
44
+ end
45
+ end
46
+ end
@@ -1,60 +1,54 @@
1
1
  require 'roar/representer/feature/transport'
2
2
 
3
3
  module Roar
4
- # Gives HTTP-power to representers where those can automatically serialize, send, process and deserialize HTTP-requests.
4
+ # Gives HTTP-power to representers. They can serialize, send, process and deserialize HTTP-requests.
5
5
  module Representer
6
6
  module Feature
7
7
  module HttpVerbs
8
8
  def self.included(base)
9
9
  base.extend ClassMethods
10
10
  end
11
- # TODO: read format and base url defaults from Roar::Config.
11
+
12
12
 
13
13
  module ClassMethods
14
- include Transport
15
-
14
+ # GETs +url+ with +format+ and returns deserialized representer.
16
15
  def get(url, format)
17
- document = get_uri(url, format).body
16
+ document = http.get_uri(url, format).body
18
17
  deserialize(document)
19
18
  end
20
19
 
21
- def post(url, body, format)
22
- representation = post_uri(url, body, format).body
23
- deserialize(representation)
24
- end
25
-
26
-
27
- def put(url, body, format)
28
- representation = put_uri(url, body, format).body
29
- deserialize(representation)
20
+ def http
21
+ Transport
30
22
  end
31
23
  end
32
24
 
25
+
26
+ # Serializes the object, POSTs it to +url+ with +format+, deserializes the returned document
27
+ # and updates properties accordingly.
33
28
  def post(url, format)
34
- self.class.post(url, serialize, format)
35
- end
36
- def post!(*args)
37
- rep = post(*args) # TODO: make this better.
38
-
39
- self.class.representable_attrs.each do |definition|
40
-
41
- send(definition.setter, rep.public_send(definition.getter))
42
- end # TODO: this sucks. do this with #properties and #replace_properties.
29
+ # DISCUSS: what if a redirect happens here?
30
+ document = http.post_uri(url, serialize, format).body
31
+ deserialize(document)
43
32
  end
44
33
 
45
- def get!(url, format) # FIXME: abstract to #replace_properties
46
- rep = self.class.get(url, format) # TODO: where's the format? why do we need class here?
47
-
48
- self.class.representable_attrs.each do |definition|
49
- send(definition.setter, rep.public_send(definition.getter))
50
- end # TODO: this sucks. do this with #properties and #replace_properties.
34
+ # GETs +url+ with +format+, deserializes the returned document and updates properties accordingly.
35
+ def get(url, format)
36
+ document = http.get_uri(url, format).body
37
+ deserialize(document)
51
38
  end
52
39
 
40
+ # Serializes the object, PUTs it to +url+ with +format+, deserializes the returned document
41
+ # and updates properties accordingly.
53
42
  def put(url, format)
54
- self.class.put(url, serialize, format)
43
+ document = http.put_uri(url, serialize, format).body
44
+ deserialize(document)
55
45
  end
56
46
 
57
47
  # TODO: implement delete, patch.
48
+ private
49
+ def http
50
+ Transport # DISCUSS: might be refering to separate http object soon.
51
+ end
58
52
  end
59
53
  end
60
54
  end
@@ -6,36 +6,38 @@ module Roar
6
6
  module Feature
7
7
  # Implements the HTTP verbs with Net::HTTP.
8
8
  module Transport
9
- # TODO: generically handle return codes/let Restfulie do it.
10
- def get_uri(uri, as)
11
- do_request(Net::HTTP::Get, uri, as)
12
- end
13
-
14
- def post_uri(uri, body, as)
15
- do_request(Net::HTTP::Post, uri, as)
16
- end
17
-
18
- def put_uri(uri, body, as)
19
- do_request(Net::HTTP::Put, uri, as)
20
- end
21
-
22
- def patch_uri(uri, body, as)
23
- do_request(Net::HTTP::Patch, uri, as)
24
- end
9
+ class << self
10
+ # TODO: generically handle return codes/let Restfulie do it.
11
+ def get_uri(uri, as)
12
+ do_request(Net::HTTP::Get, uri, as)
13
+ end
14
+
15
+ def post_uri(uri, body, as)
16
+ do_request(Net::HTTP::Post, uri, as)
17
+ end
18
+
19
+ def put_uri(uri, body, as)
20
+ do_request(Net::HTTP::Put, uri, as)
21
+ end
22
+
23
+ def patch_uri(uri, body, as)
24
+ do_request(Net::HTTP::Patch, uri, as)
25
+ end
26
+
27
+ def delete_uri(uri, as)
28
+ do_request(Net::HTTP::Delete, uri, as)
29
+ end
25
30
 
26
- def delete_uri(uri, as)
27
- do_request(Net::HTTP::Delete, uri, as)
28
- end
29
-
30
- private
31
- def do_request(what, uri, as, body="")
32
- # DISCUSS: can this be made easier?
33
- uri = URI.parse(uri)
34
- http = Net::HTTP.new(uri.host, uri.port)
35
- req = what.new(uri.request_uri)
36
- req.content_type = as
37
- req.body = body if body
38
- http.request(req)
31
+ private
32
+ def do_request(what, uri, as, body="")
33
+ # DISCUSS: can this be made easier?
34
+ uri = URI.parse(uri)
35
+ http = Net::HTTP.new(uri.host, uri.port)
36
+ req = what.new(uri.request_uri)
37
+ req.content_type = as
38
+ req.body = body if body
39
+ http.request(req)
40
+ end
39
41
  end
40
42
  end
41
43
  end
@@ -1,4 +1,4 @@
1
- require 'roar/representer/base'
1
+ require 'roar/representer'
2
2
  require 'representable/json'
3
3
 
4
4
  module Roar
@@ -6,7 +6,7 @@ module Roar
6
6
  module JSON
7
7
  def self.included(base)
8
8
  base.class_eval do
9
- include Base
9
+ include Representer
10
10
  include Representable::JSON
11
11
 
12
12
  extend ClassMethods
@@ -23,10 +23,6 @@ module Roar
23
23
  def from_json(document, options={})
24
24
  document ||= "{}" # DISCUSS: provide this for convenience, or better not?
25
25
 
26
- if block = deserialize_block_for_options(options) and
27
- return super(document, &block)
28
- end
29
-
30
26
  super
31
27
  end
32
28
 
@@ -34,6 +30,10 @@ module Roar
34
30
  def serialize(*args)
35
31
  to_json(*args)
36
32
  end
33
+
34
+ def deserialize(*args)
35
+ from_json(*args)
36
+ end
37
37
  end
38
38
 
39
39
 
@@ -44,7 +44,7 @@ module Roar
44
44
 
45
45
  # TODO: move to instance method, or remove?
46
46
  def links_definition_options
47
- {:as => Hyperlink , :collection => true}
47
+ {:class => Hyperlink , :collection => true}
48
48
  end
49
49
  end
50
50
 
@@ -1,4 +1,4 @@
1
- require 'roar/representer/base'
1
+ require 'roar/representer'
2
2
  require 'representable/xml'
3
3
 
4
4
  module Roar
@@ -8,7 +8,7 @@ module Roar
8
8
  module XML
9
9
  def self.included(base)
10
10
  base.class_eval do
11
- include Base
11
+ include Representer
12
12
  include Representable::XML
13
13
 
14
14
  extend ClassMethods
@@ -17,14 +17,6 @@ module Roar
17
17
  end
18
18
 
19
19
  module InstanceMethods
20
- def from_xml(document, options={})
21
- if block = deserialize_block_for_options(options)
22
- return super(document, &block)
23
- end
24
-
25
- super
26
- end
27
-
28
20
  def to_xml(*args)
29
21
  before_serialize(*args)
30
22
  super
@@ -34,6 +26,10 @@ module Roar
34
26
  def serialize(*args)
35
27
  to_xml(*args)
36
28
  end
29
+
30
+ def deserialize(*args)
31
+ from_xml(*args)
32
+ end
37
33
  end
38
34
 
39
35
 
@@ -41,7 +37,7 @@ module Roar
41
37
  include Representable::XML::ClassMethods
42
38
 
43
39
  def links_definition_options
44
- {:from => :link, :as => Hyperlink, :collection => true}
40
+ {:from => :link, :class => Hyperlink, :collection => true}
45
41
  end
46
42
 
47
43
  # Generic entry-point for parsing.
data/lib/roar/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Roar
2
- VERSION = "0.8.3"
2
+ VERSION = "0.9.0"
3
3
  end
data/roar.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
 
22
- s.add_runtime_dependency "representable", "~> 0.10.3"
22
+ s.add_runtime_dependency "representable", "~> 0.12"
23
23
  s.add_runtime_dependency "hooks", "~> 0.1.4"
24
24
 
25
25
  s.add_development_dependency "test_xml"
@@ -3,5 +3,5 @@ Dummy::Application.routes.draw do
3
3
  root :to => 'musician#index'
4
4
  resources :albums
5
5
  resources :songs
6
- get "articles/starts_with/{query}", :to => "albums#search",:as => :album_search
6
+ get "articles/starts_with/{query}", :to => "albums#search",:class => :album_search
7
7
  end
data/test/fake_server.rb CHANGED
@@ -1,30 +1,9 @@
1
1
  require "bundler/setup"
2
2
  require 'sinatra/base'
3
3
  require 'sinatra/reloader'
4
- require 'roar/representer/xml'
5
-
6
- # Usually shared in a gem between service and clients.
7
- module BandRepresenter
8
- include Roar::Representer::XML
9
- property :name
10
- property :label
11
- end
12
-
13
- Band = Struct.new(:name, :label)
14
- Band.class_eval do
15
- include Roar::Representer::XML
16
- include BandRepresenter
17
- end
18
4
 
19
5
 
20
- class FakeServer < Sinatra::Base
21
- BANDS = {"belvedere" => Band.new("Belvedere", "canadian maple")}
22
-
23
- get "/bands/:id" do
24
- BANDS[params[:id]].to_xml
25
- end
26
-
27
-
6
+ class FakeServer < Sinatra::Base
28
7
  get "/method" do
29
8
  "<method>get</method>"
30
9
  end
@@ -45,21 +24,18 @@ class FakeServer < Sinatra::Base
45
24
  # "<method>patch</method>"
46
25
  #end
47
26
 
48
- post "/band" do
49
- if request.content_type =~ /xml/
50
- %{<band><label>n/a</label><name>Strung Out</name>
51
- <link href="http://search" rel="search" />
52
- <link href="http://band/strungout" rel="self" />
53
- </band>}
54
- else
55
- '{"band": {"label": "n/a", "name": "Strung Out", "links": [{"href":"http://search", "rel": "search"}, {"href":"http://band/strungout", "rel": "self"}]}}'
56
- end
27
+ post "/bands" do
28
+ #if request.content_type =~ /xml/
29
+ '{"label": "n/a", "name": "Strung Out", "links": [{"href":"http://search", "rel": "search"}, {"href":"http://band/strungout", "rel": "self"}]}'
57
30
  end
58
31
 
59
- put "/band/strungout" do
60
- %{<band><label>Fat Wreck</label><name>Strung Out</name></band>}
32
+ put "/bands/strungout" do
33
+ {:name => "Strung Out", :label => "Fat Wreck"}.to_json
61
34
  end
62
35
 
36
+ get "/bands/slayer" do
37
+ {:name => "Slayer", :label => "Canadian Maple"}.to_json
38
+ end
63
39
 
64
40
 
65
41
  require Dir.pwd + '/order_representers'
@@ -1,67 +1,70 @@
1
1
  require 'test_helper'
2
2
  require 'roar/representer/feature/http_verbs'
3
+ require 'roar/representer/json'
3
4
 
4
5
  class HttpVerbsTest < MiniTest::Spec
5
- class Band
6
- include Roar::Representer::XML
6
+ module BandRepresenter
7
+ include Roar::Representer::JSON
7
8
 
8
9
  property :name
9
10
  property :label
10
-
11
- include Roar::Representer::Feature::HttpVerbs
12
11
  end
13
12
 
14
13
  describe "HttpVerbs" do
15
14
  before do
16
- @r = @band = Band.new
15
+ @band = Object.new
16
+ @band.extend(BandRepresenter)
17
+ @band.extend(Roar::Representer::Feature::HttpVerbs)
17
18
  end
18
19
 
19
- # TODO: assert that Restfulie#post receives the correct document.
20
-
21
- describe "#post" do
22
- it "#deserializes the incoming representation and returns it" do
23
- @r.name = "Strung Out"
24
- rep = @r.post("http://localhost:9999/band", "application/xml")
25
- assert_equal "Strung Out", rep.name
26
- assert_equal "n/a", rep.label
20
+ describe "HttpVerbs.get" do
21
+ it "returns instance from incoming representation" do
22
+ @Band = Class.new do
23
+ include Roar::Representer::JSON
24
+ include BandRepresenter
25
+ include Roar::Representer::Feature::HttpVerbs
26
+ end
27
+ @band = @Band.get("http://localhost:9999/bands/slayer", "application/json")
28
+ assert_equal "Slayer", @band.name
29
+ assert_equal "Canadian Maple", @band.label
27
30
  end
28
31
  end
29
32
 
30
- describe "#post!" do
31
- it "#post! deserializes the incoming representation and replaces attributes" do
32
- @r.name = "Strung Out"
33
- assert_equal nil, @r.label
34
- @r.post!("http://localhost:9999/band", "application/xml")
35
- assert_equal "Strung Out", @r.name
36
- assert_equal "n/a", @r.label
33
+ describe "#get" do
34
+ it "updates instance with incoming representation" do
35
+ @band.get("http://localhost:9999/bands/slayer", "application/json")
36
+ assert_equal "Slayer", @band.name
37
+ assert_equal "Canadian Maple", @band.label
37
38
  end
38
39
  end
39
40
 
40
- describe "#put!" do
41
- it "deserializes the incoming representation and returns it" do
42
- @r.name = "Strung Out"
43
- @r.label = "Fat Wreck"
44
- rep = @r.put("http://localhost:9999/band/strungout", "application/xml")
45
- assert_equal "Strung Out", rep.name
46
- assert_equal "Fat Wreck", rep.label
41
+ describe "#post" do
42
+ it "updates instance with incoming representation" do
43
+ @band.name = "Strung Out"
44
+ assert_equal nil, @band.label
45
+
46
+ @band.post("http://localhost:9999/bands", "application/xml")
47
+ assert_equal "Strung Out", @band.name
48
+ assert_equal "n/a", @band.label
47
49
  end
48
50
  end
49
51
 
50
- describe ".get" do
51
- it "returns the deserialized retrieved doc" do
52
- band = Band.get("http://localhost:9999/bands/belvedere", "application/xml")
53
- assert_equal "Belvedere", band.name
54
- assert_equal "canadian maple", band.label
52
+ describe "#put" do
53
+ it "updates instance with incoming representation" do
54
+ @band.name = "Strung Out"
55
+ @band.label = "Fat Wreck"
56
+ @band.put("http://localhost:9999/bands/strungout", "application/xml")
57
+ assert_equal "Strung Out", @band.name
58
+ assert_equal "Fat Wreck", @band.label
55
59
  end
56
60
  end
57
61
 
58
- describe "#get!" do
59
- it "retrieves, deserializes and updates properties" do
60
- band = @band.get!("http://localhost:9999/bands/belvedere", "application/xml")
61
- assert_equal "Belvedere", band.name
62
- assert_equal "canadian maple", band.label
63
- end
62
+ describe "#delete" do
63
+
64
64
  end
65
65
 
66
+ describe "#patch" do
67
+
68
+ end
66
69
  end
67
70
  end
@@ -59,7 +59,7 @@ class HypermediaTest
59
59
  it "sets up links even when nested" do
60
60
  class Page
61
61
  include Roar::Representer::JSON
62
- property :note, :as => Note
62
+ property :note, :class => Note
63
63
  end
64
64
 
65
65
  assert_equal "{\"note\":{\"links\":[{\"rel\":\"self\",\"href\":\"http://me\"}]}}", Page.from_attributes(note: Note.new).to_json
@@ -18,7 +18,7 @@ class IntegrationTest < MiniTest::Spec
18
18
  include Roar::Representer::JSON
19
19
  include Roar::Representer::Feature::Hypermedia
20
20
 
21
- collection :items, :as => Beer
21
+ collection :items, :class => Beer
22
22
  end
23
23
 
24
24
  describe "Beer service" do
@@ -45,7 +45,7 @@ class IntegrationTest < MiniTest::Spec
45
45
 
46
46
  attr_accessor :per_page, :current_page, :all_items
47
47
 
48
- collection :beers, :as => Beer
48
+ collection :beers, :class => Beer
49
49
  property :total
50
50
 
51
51
  def total
@@ -79,7 +79,7 @@ class IntegrationTest < MiniTest::Spec
79
79
 
80
80
 
81
81
  list.current_page = 2
82
- assert_equal "{\"beers\":[{\"name\":\"Eisenbahn\",\"links\":[{\"rel\":\"self\",\"href\":\"http://beers/eisenbahn\"}]},{\"name\":\"Colorado\",\"links\":[{\"rel\":\"self\",\"href\":\"http://beers/colorado\"}]}],\"total\":4,\"links\":[{\"rel\":\"next\"},{\"rel\":\"prev\",\"href\":\"http://beers/all?page=1\"}]}", list.to_json(wrap: false)
82
+ assert_equal "{\"beer_collection\":{\"beers\":[{\"name\":\"Eisenbahn\",\"links\":[{\"rel\":\"self\",\"href\":\"http://beers/eisenbahn\"}]},{\"name\":\"Colorado\",\"links\":[{\"rel\":\"self\",\"href\":\"http://beers/colorado\"}]}],\"total\":4,\"links\":[{\"rel\":\"next\"},{\"rel\":\"prev\",\"href\":\"http://beers/all?page=1\"}]}}", list.to_json
83
83
  end
84
84
  end
85
85
  end
@@ -13,36 +13,44 @@ class JsonRepresenterTest < MiniTest::Spec
13
13
 
14
14
  describe "JsonRepresenter" do
15
15
  before do
16
- @r = Order.new
16
+ @order = Order.new
17
17
  end
18
18
 
19
+
19
20
  describe "#to_json" do
20
- it "#serialize returns the serialized model" do
21
- @r.id = 1
22
- assert_equal '{"id":1}', @r.to_json
21
+ before do
22
+ @order.id = 1
23
+ end
24
+
25
+ it "returns the serialized model" do
26
+ assert_equal '{"id":1}', @order.to_json
27
+ end
28
+
29
+ it "is aliased by #serialize" do
30
+ assert_equal '{"id":1}', @order.serialize
23
31
  end
24
32
  end
25
33
 
26
- describe ".from_json" do
34
+ describe "#from_json" do
27
35
  it "returns the deserialized model" do
28
- @m = Order.from_json('{"id":1}')
29
- assert_equal 1, @m.id
36
+ @order.from_json('{"id":1}')
37
+ assert_equal 1, @order.id
30
38
  end
31
39
 
32
- it "accepts :except option" do
33
- order = Order.from_json({id: 1, pending: 1}.to_json, :except => [:id])
34
- assert_equal nil, order.id
35
- assert_equal 1, order.pending
36
- end
37
-
38
- it "accepts :include option" do
39
- order = Order.from_json({id: 1, pending: 1}.to_json, :include => [:id])
40
- assert_equal 1, order.id
41
- assert_equal nil, order.pending
40
+ it "is aliased by #deserialize" do
41
+ @order.deserialize('{"id":1}')
42
+ assert_equal 1, @order.id
42
43
  end
43
44
 
44
45
  it "works with a nil document" do
45
- assert Order.from_json(nil)
46
+ assert @order.from_json(nil)
47
+ end
48
+ end
49
+
50
+ describe "JSON.from_json" do
51
+ it "is aliased by #deserialize" do
52
+ @order = Order.deserialize('{"id":1}')
53
+ assert_equal 1, @order.id
46
54
  end
47
55
  end
48
56
  end
@@ -15,7 +15,7 @@ class ModelRepresentingTest < MiniTest::Spec
15
15
  include Roar::Representer::Feature::ModelRepresenting
16
16
  self.representation_wrap= :position
17
17
  property :id
18
- property :item, :as => ItemRepresenter
18
+ property :item, :class => ItemRepresenter
19
19
  end
20
20
 
21
21
  class OrderRepresenter
@@ -23,7 +23,7 @@ class ModelRepresentingTest < MiniTest::Spec
23
23
  include Roar::Representer::Feature::ModelRepresenting
24
24
  self.representation_wrap= :order
25
25
  property :id
26
- collection :items, :as => ItemRepresenter
26
+ collection :items, :class => ItemRepresenter
27
27
  end
28
28
 
29
29
  describe "#definition_class" do
@@ -18,7 +18,7 @@ module JSON
18
18
  class Order
19
19
  include Roar::Representer::JSON
20
20
  property :client_id
21
- collection :items, :as => Item
21
+ collection :items, :class => Item
22
22
 
23
23
 
24
24
  include Roar::Representer::Feature::HttpVerbs
@@ -1,10 +1,10 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class RepresenterTest < MiniTest::Spec
4
- describe "Representer::Base" do
4
+ describe "Representer" do
5
5
  before do
6
6
  @c = Class.new do
7
- include Roar::Representer::Base
7
+ include Roar::Representer
8
8
  end
9
9
  end
10
10
 
data/test/test_helper.rb CHANGED
@@ -4,7 +4,7 @@ Bundler.setup
4
4
  require 'test/unit'
5
5
  require 'minitest/spec'
6
6
 
7
- require 'roar/representer/base'
7
+ require 'roar/representer'
8
8
  require 'roar/representer/feature/hypermedia'
9
9
  require 'roar/representer/feature/http_verbs'
10
10
 
@@ -4,26 +4,23 @@ require 'roar/representer/feature/transport'
4
4
  class TransportTest < MiniTest::Spec
5
5
  describe "Transport" do
6
6
  before do
7
- @klass = Class.new(Object) do
8
- include Roar::Representer::Feature::Transport
9
- end
10
- @o = @klass.new
7
+ @transport = Roar::Representer::Feature::Transport
11
8
  end
12
9
 
13
10
  it "#get_uri returns response" do
14
- assert_equal "<method>get</method>", @o.get_uri("http://localhost:9999/method", "application/xml").body
11
+ assert_equal "<method>get</method>", @transport.get_uri("http://localhost:9999/method", "application/xml").body
15
12
  end
16
13
 
17
14
  it "#post_uri returns response" do
18
- assert_equal "<method>post</method>", @o.post_uri("http://localhost:9999/method", "booty", "application/xml").body
15
+ assert_equal "<method>post</method>", @transport.post_uri("http://localhost:9999/method", "booty", "application/xml").body
19
16
  end
20
17
 
21
18
  it "#put_uri returns response" do
22
- assert_equal "<method>put</method>", @o.put_uri("http://localhost:9999/method", "booty", "application/xml").body
19
+ assert_equal "<method>put</method>", @transport.put_uri("http://localhost:9999/method", "booty", "application/xml").body
23
20
  end
24
21
 
25
22
  it "#delete_uri returns response" do
26
- assert_equal "<method>delete</method>", @o.delete_uri("http://localhost:9999/method", "application/xml").body
23
+ assert_equal "<method>delete</method>", @transport.delete_uri("http://localhost:9999/method", "application/xml").body
27
24
  end
28
25
 
29
26
  # TODO: how to get PATCH into Sinatra?
@@ -10,7 +10,7 @@ class PositionRepresenter
10
10
  include Roar::Representer::XML
11
11
  self.representation_wrap= :position
12
12
  property :id
13
- property :item, :as => ItemRepresenter
13
+ property :item, :class => ItemRepresenter
14
14
  end
15
15
 
16
16
 
@@ -48,7 +48,7 @@ class XMLRepresenterFunctionalTest < MiniTest::Spec
48
48
 
49
49
  class TestXmlRepresenter
50
50
  include Roar::Representer::XML
51
- self.representation_wrap= :order # FIXME: get from represented?
51
+ self.representation_wrap= :order
52
52
  property :id
53
53
  end
54
54
 
@@ -71,19 +71,35 @@ class XMLRepresenterFunctionalTest < MiniTest::Spec
71
71
 
72
72
 
73
73
  describe "#to_xml" do
74
- it "serializes the current model" do
74
+ it "serializes the model" do
75
75
  assert_xml_equal "<order/>", @r.to_xml
76
76
 
77
+ @r.id = 1
78
+ assert_xml_equal "<order><id>1</id></order>", @r.to_xml
79
+
77
80
  @r.id = 2
78
- assert_xml_equal "<rap><id>2</id></rap>", @r.to_xml(:name => :rap)
81
+ assert_xml_equal "<rap><id>2</id></rap>", @r.to_xml(:wrap => :rap)
79
82
  end
80
83
 
81
- it "is aliased to #serialize" do
84
+ it "is aliased by #serialize" do
82
85
  assert_equal @r.to_xml, @r.serialize
83
86
  end
84
87
  end
85
88
 
86
89
  describe "#from_xml" do
90
+ it "deserializes object" do
91
+ @order = Order.new.from_xml("<order><id>1</id></order>")
92
+ assert_equal "1", @order.id
93
+ end
94
+
95
+ it "is aliased by #deserialize" do
96
+ @order = Order.new.deserialize("<order><id>1</id></order>")
97
+ assert_equal "1", @order.id
98
+ end
99
+ end
100
+
101
+
102
+ describe "XML.from_xml" do
87
103
  class Order
88
104
  include Roar::Representer::XML
89
105
  property :id
@@ -109,12 +125,6 @@ class XMLRepresenterFunctionalTest < MiniTest::Spec
109
125
 
110
126
 
111
127
  describe "without options" do
112
- it "#to_xml returns the serialized model" do
113
- @r.id = 1
114
- assert_xml_equal "<order><id>1</id></order>", @r.to_xml
115
- end
116
-
117
-
118
128
  it ".from_xml returns the deserialized model" do
119
129
  @m = TestXmlRepresenter.from_xml("<order><id>1</id></order>")
120
130
  assert_equal "1", @m.id
@@ -157,7 +167,7 @@ class XMLRepresenterFunctionalTest < MiniTest::Spec
157
167
 
158
168
  self.representation_wrap= :order
159
169
  property :id
160
- collection :items, :as => ItemRepresenter, :from => :item
170
+ collection :items, :class => ItemRepresenter, :from => :item
161
171
  end
162
172
 
163
173
  @r = @c.from_attributes("id" => 1)
@@ -192,8 +202,8 @@ class XmlHyperlinkRepresenterTest < MiniTest::Spec
192
202
  @l = Roar::Representer::XML::Hyperlink.from_xml(%{<link rel="self" href="http://roar.apotomo.de"/>})
193
203
  end
194
204
 
195
- it "responds to #representation_name" do
196
- assert_equal :link, @l.class.representation_wrap
205
+ it "responds to #to_xml" do
206
+ assert_xml_equal %{<link rel=\"self\" href=\"http://roar.apotomo.de\"/>}, @l.to_xml
197
207
  end
198
208
 
199
209
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 8
8
- - 3
9
- version: 0.8.3
7
+ - 9
8
+ - 0
9
+ version: 0.9.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Nick Sutterer
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-12-08 00:00:00 +01:00
17
+ date: 2011-12-20 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -27,9 +27,8 @@ dependencies:
27
27
  - !ruby/object:Gem::Version
28
28
  segments:
29
29
  - 0
30
- - 10
31
- - 3
32
- version: 0.10.3
30
+ - 12
31
+ version: "0.12"
33
32
  type: :runtime
34
33
  version_requirements: *id001
35
34
  - !ruby/object:Gem::Dependency
@@ -111,7 +110,7 @@ files:
111
110
  - lib/roar/rails/controller_methods.rb
112
111
  - lib/roar/rails/representer_methods.rb
113
112
  - lib/roar/rails/test_case.rb
114
- - lib/roar/representer/base.rb
113
+ - lib/roar/representer.rb
115
114
  - lib/roar/representer/feature/http_verbs.rb
116
115
  - lib/roar/representer/feature/hypermedia.rb
117
116
  - lib/roar/representer/feature/model_representing.rb
@@ -1,64 +0,0 @@
1
- require 'representable'
2
-
3
- module Roar
4
- module Representer
5
- module Base
6
- def self.included(base)
7
- base.class_eval do
8
- include Representable
9
- extend ClassMethods
10
-
11
- class << self
12
- alias_method :property, :representable_property
13
- alias_method :collection, :representable_collection
14
- end
15
- end
16
- end
17
-
18
-
19
- module ClassMethods
20
- # Creates a representer instance and fills it with +attributes+.
21
- def from_attributes(attributes) # DISCUSS: better move to #new? how do we handle the original #new then?
22
- new.tap do |representer|
23
- yield representer if block_given?
24
- attributes.each { |p,v| representer.public_send("#{p}=", v) }
25
- end
26
- end
27
- end
28
-
29
-
30
- # Convert representer's attributes to a nested attributes hash.
31
- def to_attributes
32
- {}.tap do |attributes|
33
- self.class.representable_attrs.each do |definition|
34
- value = public_send(definition.getter)
35
-
36
- if definition.typed?
37
- value = definition.apply(value) do |v|
38
- v.to_attributes # applied to each typed attribute (even in collections).
39
- end
40
- end
41
-
42
- attributes[definition.name] = value
43
- end
44
- end
45
- end
46
-
47
- private
48
- def before_serialize(*)
49
- end
50
-
51
- # Returns block used in #from_json and #from_xml to filter incoming arguments.
52
- # This method is subject to change and might be removed, soon.
53
- def deserialize_block_for_options(options)
54
- return unless props = options[:except] || options[:include]
55
-
56
- lambda do |name|
57
- res = props.include?(name)
58
- options[:include] ? res : !res
59
- end
60
- end
61
-
62
- end
63
- end
64
- end