her 0.1.8.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -75,16 +75,18 @@ Her::API.setup :base_uri => "https://api.example.com", :add_middleware => [MyAut
75
75
 
76
76
  Now, each HTTP request made by Her will have the `X-API-Token` header.
77
77
 
78
- ### Parsing data
78
+ ### Parsing JSON data
79
79
 
80
- By default, Her handles JSON data. It expects the data to be formatted in a certain structure. The default is this:
80
+ By default, Her handles JSON data. It expects the resource/collection data to be returned at the first level.
81
+
82
+ **Note**: *Before 0.2, Her expected the resource/collection data to be returned in a `data` key within the JSON object. If you want the old behavior, you can use the `Her::Middleware::SecondLevelParseJSON` middleware.*
81
83
 
82
84
  ```javascript
83
85
  // The response of GET /users/1
84
- { "data" : { "id" : 1, "name" : "Tobias Fünke" } }
86
+ { "id" : 1, "name" : "Tobias Fünke" }
85
87
 
86
88
  // The response of GET /users
87
- { "data" : [{ "id" : 1, "name" : "Tobias Fünke" }] }
89
+ [{ "id" : 1, "name" : "Tobias Fünke" }]
88
90
  ```
89
91
 
90
92
  However, you can define your own parsing method, using a response middleware. The middleware is expected to set `env[:body]` to a hash with three keys: `data`, `errors` and `metadata`. The following code enables parsing JSON data and treating the result as first-level properties. Using the `parse_middleware` key, we then replace the default parser.
@@ -92,15 +94,17 @@ However, you can define your own parsing method, using a response middleware. Th
92
94
  ```ruby
93
95
  class MyCustomParser < Faraday::Response::Middleware
94
96
  def on_complete(env)
95
- json = JSON.parse(env[:body], :symbolize_names => true)
96
- errors = json.delete(:errors) || []
97
- metadata = json.delete(:metadata) || []
98
- env[:body] = { :data => json, :errors => errors, :metadata => metadata }
97
+ json = MultiJson.load(body, :symbolize_keys => true)
98
+ env[:body] = {
99
+ :data => json[:data],
100
+ :errors => json[:errors],
101
+ :metadata => json[:metadata]
102
+ }
99
103
  end
100
104
  end
101
105
 
102
106
  Her::API.setup :base_uri => "https://api.example.com", :parse_middleware => MyCustomParser
103
- # User.find(1) will now expect "https://api.example.com/users/1" to return something like '{ "id": 1, "name": "Tobias Fünke" }'
107
+ # User.find(1) will now expect "https://api.example.com/users/1" to return something like '{ "data" => { "id": 1, "name": "Tobias Fünke" }, "errors" => [] }'
104
108
  ```
105
109
 
106
110
  ## Relationships
@@ -302,4 +306,4 @@ Take a look at the `spec` folder before you do, and make sure `bundle exec rake
302
306
 
303
307
  ## License
304
308
 
305
- Her is © 2012 [Rémi Prévost](http://exomel.com) and may be freely distributed under the [LITL license](https://github.com/remiprev/her/blob/master/LICENSE). See the `LICENSE` file.
309
+ Her is © 2012 [Rémi Prévost](http://exomel.com) and may be freely distributed under the [MIT license](https://github.com/remiprev/her/blob/master/LICENSE). See the `LICENSE` file.
@@ -17,7 +17,7 @@ module Her
17
17
  # @option attrs [String] :base_uri The main HTTP API root (eg. `https://api.example.com`)
18
18
  # @option attrs [Array, Class] :middleware A list of the only middleware Her will use
19
19
  # @option attrs [Array, Class] :add_middleware A list of middleware to add to Her’s default middleware
20
- # @option attrs [Class] :parse_middleware A middleware that will replace {Her::Middleware::DefaultParseJSON} to parse the received JSON
20
+ # @option attrs [Class] :parse_middleware A middleware that will replace {Her::Middleware::FirstLevelParseJSON} to parse the received JSON
21
21
  #
22
22
  # @example Setting up the default API connection
23
23
  # Her::API.setup :base_uri => "https://api.example"
@@ -47,7 +47,7 @@ module Her
47
47
 
48
48
  @middleware = [attrs[:middleware]] if attrs[:middleware]
49
49
  @middleware = [attrs[:add_middleware]] + @middleware if attrs[:add_middleware]
50
- @middleware = [attrs[:parse_middleware]] + @middleware.reject { |item| item == Her::Middleware::DefaultParseJSON } if attrs[:parse_middleware]
50
+ @middleware = [attrs[:parse_middleware]] + @middleware.reject { |item| item == Her::Middleware::FirstLevelParseJSON } if attrs[:parse_middleware]
51
51
 
52
52
  @middleware.flatten!
53
53
  middleware = @middleware
@@ -85,7 +85,7 @@ module Her
85
85
 
86
86
  # @private
87
87
  def self.default_middleware # {{{
88
- [Her::Middleware::DefaultParseJSON, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]
88
+ [Her::Middleware::FirstLevelParseJSON, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]
89
89
  end # }}}
90
90
  end
91
91
  end
@@ -1,5 +1,6 @@
1
1
  module Her
2
2
  module Middleware
3
- autoload :DefaultParseJSON, "her/middleware/default_parse_json"
3
+ autoload :FirstLevelParseJSON, "her/middleware/first_level_parse_json"
4
+ autoload :SecondLevelParseJSON, "her/middleware/second_level_parse_json"
4
5
  end
5
6
  end
@@ -0,0 +1,29 @@
1
+ module Her
2
+ module Middleware
3
+ # This middleware treat the received first-level JSON structure as the resource data.
4
+ class FirstLevelParseJSON < Faraday::Response::Middleware
5
+ # Parse the response body
6
+ #
7
+ # @param [String] body The response body
8
+ # @return [Mixed] the parsed response
9
+ def parse(body) # {{{
10
+ json = MultiJson.load(body, :symbolize_keys => true)
11
+ errors = json.delete(:errors) || []
12
+ metadata = json.delete(:metadata) || []
13
+ {
14
+ :data => json,
15
+ :errors => errors,
16
+ :metadata => metadata
17
+ }
18
+ end # }}}
19
+
20
+ # This method is triggered when the response has been received. It modifies
21
+ # the value of `env[:body]`.
22
+ #
23
+ # @param [Hash] env The response environment
24
+ def on_complete(env) # {{{
25
+ env[:body] = parse(env[:body])
26
+ end # }}}
27
+ end
28
+ end
29
+ end
@@ -1,8 +1,8 @@
1
1
  module Her
2
2
  module Middleware
3
- # This is the default middleware used to parse JSON responses. It returns
4
- # a Hash with three elements: `data`, `errors` and `metadata`.
5
- class DefaultParseJSON < Faraday::Response::Middleware
3
+ # This middleware expects the resource/collection data to be contained in the `data`
4
+ # key of the JSON object
5
+ class SecondLevelParseJSON < Faraday::Response::Middleware
6
6
  # Parse the response body
7
7
  #
8
8
  # @param [String] body The response body
@@ -1,3 +1,3 @@
1
1
  module Her
2
- VERSION = "0.1.8.1"
2
+ VERSION = "0.2"
3
3
  end
@@ -23,11 +23,11 @@ describe Her::API do
23
23
 
24
24
  @api = Her::API.new
25
25
  @api.setup :base_uri => "https://api.example.com", :add_middleware => [Foo, Bar]
26
- @api.middleware.should == [Foo, Bar, Her::Middleware::DefaultParseJSON, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]
26
+ @api.middleware.should == [Foo, Bar, Her::Middleware::FirstLevelParseJSON, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]
27
27
 
28
28
  @api = Her::API.new
29
29
  @api.setup :base_uri => "https://api.example.com", :add_middleware => Foo
30
- @api.middleware.should == [Foo, Her::Middleware::DefaultParseJSON, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]
30
+ @api.middleware.should == [Foo, Her::Middleware::FirstLevelParseJSON, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]
31
31
  end # }}}
32
32
 
33
33
  it "overrides middleware" do # {{{
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe Her::Middleware::FirstLevelParseJSON do
5
+ subject { described_class.new }
6
+ let(:body) { "{\"id\": 1, \"name\": \"Tobias Fünke\", \"errors\": 2, \"metadata\": 3}" }
7
+
8
+ it "parses body as json" do
9
+ subject.parse(body).tap do |json|
10
+ json[:data].should == { :id => 1, :name => "Tobias Fünke" }
11
+ json[:errors].should == 2
12
+ json[:metadata].should == 3
13
+ end
14
+ end
15
+
16
+ it "parses :body key as json in the env hash" do
17
+ env = { :body => body }
18
+ subject.on_complete(env)
19
+ env[:body].tap do |json|
20
+ json[:data].should == { :id => 1, :name => "Tobias Fünke" }
21
+ json[:errors].should == 2
22
+ json[:metadata].should == 3
23
+ end
24
+ end
25
+ end
@@ -1,6 +1,7 @@
1
+ # encoding: utf-8
1
2
  require "spec_helper"
2
3
 
3
- describe Her::Middleware::DefaultParseJSON do
4
+ describe Her::Middleware::SecondLevelParseJSON do
4
5
  subject { described_class.new }
5
6
  let(:body) { "{\"data\": 1, \"errors\": 2, \"metadata\": 3}" }
6
7
 
@@ -4,10 +4,7 @@ require File.join(File.dirname(__FILE__), "../spec_helper.rb")
4
4
  describe Her::Model::Hooks do
5
5
  context "adding hooks to a model" do
6
6
  before do # {{{
7
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
8
- class User
9
- include Her::Model
10
- end
7
+ spawn_model :User
11
8
  end # }}}
12
9
 
13
10
  describe "method hooks" do
@@ -114,14 +111,13 @@ describe Her::Model::Hooks do
114
111
  context "perform hooks on a model" do
115
112
  before do # {{{
116
113
  Her::API.setup :base_uri => "https://api.example.com"
117
- FakeWeb.register_uri(:post, "https://api.example.com/users", :body => { :data => { :id => 1, :name => "Tobias Fünke" } }.to_json)
118
- FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "Tobias Fünke" } }.to_json)
119
- FakeWeb.register_uri(:put, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "Tobias Fünke" } }.to_json)
120
- FakeWeb.register_uri(:delete, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "Tobias Fünke" } }.to_json)
114
+ FakeWeb.register_uri(:post, "https://api.example.com/users", :body => { :id => 1, :name => "Tobias Fünke" }.to_json)
115
+ FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :id => 1, :name => "Tobias Fünke" }.to_json)
116
+ FakeWeb.register_uri(:put, "https://api.example.com/users/1", :body => { :id => 1, :name => "Tobias Fünke" }.to_json)
117
+ FakeWeb.register_uri(:delete, "https://api.example.com/users/1", :body => { :id => 1, :name => "Tobias Fünke" }.to_json)
121
118
 
122
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
119
+ spawn_model :User
123
120
  class User
124
- include Her::Model
125
121
  attr_accessor :internal_save_id, :internal_create_id, :internal_update_id, :internal_destroy_id
126
122
  attr_accessor :internal_after_save_id, :internal_after_create_id, :internal_after_update_id, :internal_after_destroy_id
127
123
 
@@ -7,10 +7,7 @@ describe Her::Model::HTTP do
7
7
  @api = Her::API.new
8
8
  @api.setup :base_uri => "https://api.example.com"
9
9
 
10
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
11
- class User
12
- include Her::Model
13
- end
10
+ spawn_model :User
14
11
  User.uses_api @api
15
12
 
16
13
  User.class_eval do
@@ -22,10 +19,7 @@ describe Her::Model::HTTP do
22
19
  it "binds a model directly to Her::API" do # {{{
23
20
  Her::API.setup :base_uri => "https://api.example.com"
24
21
 
25
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
26
- class User
27
- include Her::Model
28
- end
22
+ spawn_model :User
29
23
 
30
24
  User.class_eval do
31
25
  @her_api.should_not == nil
@@ -37,8 +31,7 @@ describe Her::Model::HTTP do
37
31
  @api1 = Her::API.new
38
32
  @api1.setup :base_uri => "https://api1.example.com"
39
33
 
40
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
41
- class User; include Her::Model; end
34
+ spawn_model :User
42
35
  User.uses_api @api1
43
36
 
44
37
  User.class_eval do
@@ -48,8 +41,7 @@ describe Her::Model::HTTP do
48
41
  @api2 = Her::API.new
49
42
  @api2.setup :base_uri => "https://api2.example.com"
50
43
 
51
- Object.instance_eval { remove_const :Comment } if Object.const_defined?(:Comment)
52
- class Comment; include Her::Model; end
44
+ spawn_model :Comment
53
45
  Comment.uses_api @api2
54
46
 
55
47
  Comment.class_eval do
@@ -59,8 +51,7 @@ describe Her::Model::HTTP do
59
51
 
60
52
  it "binds one model to Her::API and another one to an instance of Her::API" do # {{{
61
53
  Her::API.setup :base_uri => "https://api1.example.com"
62
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
63
- class User; include Her::Model; end
54
+ spawn_model :User
64
55
 
65
56
  User.class_eval do
66
57
  @her_api.base_uri.should == "https://api1.example.com"
@@ -69,8 +60,7 @@ describe Her::Model::HTTP do
69
60
  @api = Her::API.new
70
61
  @api.setup :base_uri => "https://api2.example.com"
71
62
 
72
- Object.instance_eval { remove_const :Comment } if Object.const_defined?(:Comment)
73
- class Comment; include Her::Model; end
63
+ spawn_model :Comment
74
64
  Comment.uses_api @api
75
65
 
76
66
  Comment.class_eval do
@@ -83,19 +73,16 @@ describe Her::Model::HTTP do
83
73
  before do # {{{
84
74
  @api = Her::API.new
85
75
  @api.setup :base_uri => "https://api.example.com"
86
- FakeWeb.register_uri(:get, "https://api.example.com/users", :body => { :data => [{ :id => 1 }] }.to_json)
87
- FakeWeb.register_uri(:get, "https://api.example.com/users?page=2", :body => { :data => [{ :id => 2 }] }.to_json)
88
- FakeWeb.register_uri(:get, "https://api.example.com/users/popular", :body => { :data => [{ :id => 1 }, { :id => 2 }] }.to_json)
89
- FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1 } }.to_json)
90
- FakeWeb.register_uri(:post, "https://api.example.com/users", :body => { :data => [{ :id => 3 }] }.to_json)
91
- FakeWeb.register_uri(:put, "https://api.example.com/users/4", :body => { :data => [{ :id => 4 }] }.to_json)
92
- FakeWeb.register_uri(:patch, "https://api.example.com/users/6", :body => { :data => [{ :id => 6 }] }.to_json)
93
- FakeWeb.register_uri(:delete, "https://api.example.com/users/5", :body => { :data => [{ :id => 5 }] }.to_json)
94
-
95
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
96
- class User
97
- include Her::Model
98
- end
76
+ FakeWeb.register_uri(:get, "https://api.example.com/users", :body => [{ :id => 1 }].to_json)
77
+ FakeWeb.register_uri(:get, "https://api.example.com/users?page=2", :body => [{ :id => 2 }].to_json)
78
+ FakeWeb.register_uri(:get, "https://api.example.com/users/popular", :body => [{ :id => 1 }, { :id => 2 }].to_json)
79
+ FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :id => 1 }.to_json)
80
+ FakeWeb.register_uri(:post, "https://api.example.com/users", :body => [{ :id => 3 }].to_json)
81
+ FakeWeb.register_uri(:put, "https://api.example.com/users/4", :body => [{ :id => 4 }].to_json)
82
+ FakeWeb.register_uri(:patch, "https://api.example.com/users/6", :body => [{ :id => 6 }].to_json)
83
+ FakeWeb.register_uri(:delete, "https://api.example.com/users/5", :body => [{ :id => 5 }].to_json)
84
+
85
+ spawn_model :User
99
86
  User.uses_api @api
100
87
  end # }}}
101
88
 
@@ -177,8 +164,8 @@ describe Her::Model::HTTP do
177
164
  before do # {{{
178
165
  @api = Her::API.new
179
166
  @api.setup :base_uri => "https://api.example.com"
180
- FakeWeb.register_uri(:get, "https://api.example.com/users/popular", :body => { :data => [{ :id => 1 }, { :id => 2 }] }.to_json)
181
- FakeWeb.register_uri(:post, "https://api.example.com/users/from_default", :body => { :data => { :id => 4 } }.to_json)
167
+ FakeWeb.register_uri(:get, "https://api.example.com/users/popular", :body => [{ :id => 1 }, { :id => 2 }].to_json)
168
+ FakeWeb.register_uri(:post, "https://api.example.com/users/from_default", :body => { :id => 4 }.to_json)
182
169
 
183
170
  class User
184
171
  include Her::Model
@@ -5,11 +5,8 @@ describe Her::Model::Introspection do
5
5
  context "introspecting a resource" do
6
6
  before do # {{{
7
7
  Her::API.setup :base_uri => "https://api.example.com"
8
- FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "Tobias Fünke" } }.to_json)
9
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
10
- class User
11
- include Her::Model
12
- end
8
+ FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :id => 1, :name => "Tobias Fünke" }.to_json)
9
+ spawn_model :User
13
10
  end # }}}
14
11
 
15
12
  describe "#inspect" do
@@ -6,13 +6,10 @@ describe Her::Model::ORM do
6
6
  before do # {{{
7
7
  @api = Her::API.new
8
8
  @api.setup :base_uri => "https://api.example.com"
9
- FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "Tobias Fünke" } }.to_json)
10
- FakeWeb.register_uri(:get, "https://api.example.com/users", :body => { :data => [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }] }.to_json)
9
+ FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :id => 1, :name => "Tobias Fünke" }.to_json)
10
+ FakeWeb.register_uri(:get, "https://api.example.com/users", :body => [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }].to_json)
11
11
 
12
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
13
- class User
14
- include Her::Model
15
- end
12
+ spawn_model :User
16
13
  User.uses_api @api
17
14
  end # }}}
18
15
 
@@ -40,12 +37,9 @@ describe Her::Model::ORM do
40
37
  context "creating resources" do
41
38
  before do # {{{
42
39
  Her::API.setup :base_uri => "https://api.example.com"
43
- FakeWeb.register_uri(:post, "https://api.example.com/users", :body => { :data => { :id => 1, :fullname => "Tobias Fünke" } }.to_json)
40
+ FakeWeb.register_uri(:post, "https://api.example.com/users", :body => { :id => 1, :fullname => "Tobias Fünke" }.to_json)
44
41
 
45
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
46
- class User
47
- include Her::Model
48
- end
42
+ spawn_model :User
49
43
  end # }}}
50
44
 
51
45
  it "handle one-line resource creation" do # {{{
@@ -65,13 +59,10 @@ describe Her::Model::ORM do
65
59
  before do # {{{
66
60
  @api = Her::API.new
67
61
  @api.setup :base_uri => "https://api.example.com"
68
- FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :fullname => "Tobias Fünke" } }.to_json)
69
- FakeWeb.register_uri(:put, "https://api.example.com/users/1", :body => { :data => { :id => 1, :fullname => "Lindsay Fünke" } }.to_json)
62
+ FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :id => 1, :fullname => "Tobias Fünke" }.to_json)
63
+ FakeWeb.register_uri(:put, "https://api.example.com/users/1", :body => { :id => 1, :fullname => "Lindsay Fünke" }.to_json)
70
64
 
71
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
72
- class User
73
- include Her::Model
74
- end
65
+ spawn_model :User
75
66
  end # }}}
76
67
 
77
68
  it "handle resource data update without saving it" do # {{{
@@ -98,13 +89,10 @@ describe Her::Model::ORM do
98
89
  before do # {{{
99
90
  @api = Her::API.new
100
91
  @api.setup :base_uri => "https://api.example.com"
101
- FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :fullname => "Tobias Fünke", :active => true } }.to_json)
102
- FakeWeb.register_uri(:delete, "https://api.example.com/users/1", :body => { :data => { :id => 1, :fullname => "Lindsay Fünke", :active => false } }.to_json)
92
+ FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :id => 1, :fullname => "Tobias Fünke", :active => true }.to_json)
93
+ FakeWeb.register_uri(:delete, "https://api.example.com/users/1", :body => { :id => 1, :fullname => "Lindsay Fünke", :active => false }.to_json)
103
94
 
104
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
105
- class User
106
- include Her::Model
107
- end
95
+ spawn_model :User
108
96
  end # }}}
109
97
 
110
98
  it "handle resource deletion through the .destroy class method" do # {{{
@@ -4,10 +4,7 @@ require File.join(File.dirname(__FILE__), "../spec_helper.rb")
4
4
  describe Her::Model::Relationships do
5
5
  context "setting relationships" do
6
6
  before do # {{{
7
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
8
- class User
9
- include Her::Model
10
- end
7
+ spawn_model :User
11
8
  end # }}}
12
9
 
13
10
  it "handles a single 'has_many' relationship" do # {{{
@@ -47,34 +44,20 @@ describe Her::Model::Relationships do
47
44
  context "handling relationships" do
48
45
  before do # {{{
49
46
  Her::API.setup :base_uri => "https://api.example.com"
50
- FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :data => { :id => 1, :name => "Tobias Fünke", :comments => [{ :id => 2, :body => "Tobias, you blow hard!" }, { :id => 3, :body => "I wouldn't mind kissing that man between the cheeks, so to speak" }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 1, :name => "Bluth Company" }, :organization_id => 1 } }.to_json)
51
- FakeWeb.register_uri(:get, "https://api.example.com/users/2", :body => { :data => { :id => 2, :name => "Lindsay Fünke", :organization_id => 1 } }.to_json)
52
- FakeWeb.register_uri(:get, "https://api.example.com/users/2/comments", :body => { :data => [{ :id => 4, :body => "They're having a FIRESALE?" }, { :id => 5, :body => "Is this the tiny town from Footloose?" }] }.to_json)
53
- FakeWeb.register_uri(:get, "https://api.example.com/users/2/role", :body => { :data => { :id => 2, :body => "User" } }.to_json)
54
- FakeWeb.register_uri(:get, "https://api.example.com/organizations/1", :body => { :data => { :id => 1, :name => "Bluth Company" } }.to_json)
55
-
56
- Object.instance_eval { remove_const :User } if Object.const_defined?(:User)
57
- class User
58
- include Her::Model
59
- has_many :comments
60
- has_one :role
61
- belongs_to :organization
62
- end
63
-
64
- Object.instance_eval { remove_const :Organization } if Object.const_defined?(:Organization)
65
- class Organization
66
- include Her::Model
67
- end
68
-
69
- Object.instance_eval { remove_const :Comment } if Object.const_defined?(:Comment)
70
- class Comment
71
- include Her::Model
72
- end
73
-
74
- Object.instance_eval { remove_const :Role } if Object.const_defined?(:Role)
75
- class Role
76
- include Her::Model
77
- end
47
+ FakeWeb.register_uri(:get, "https://api.example.com/users/1", :body => { :id => 1, :name => "Tobias Fünke", :comments => [{ :id => 2, :body => "Tobias, you blow hard!" }, { :id => 3, :body => "I wouldn't mind kissing that man between the cheeks, so to speak" }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 1, :name => "Bluth Company" }, :organization_id => 1 }.to_json)
48
+ FakeWeb.register_uri(:get, "https://api.example.com/users/2", :body => { :id => 2, :name => "Lindsay Fünke", :organization_id => 1 }.to_json)
49
+ FakeWeb.register_uri(:get, "https://api.example.com/users/2/comments", :body => [{ :id => 4, :body => "They're having a FIRESALE?" }, { :id => 5, :body => "Is this the tiny town from Footloose?" }].to_json)
50
+ FakeWeb.register_uri(:get, "https://api.example.com/users/2/role", :body => { :id => 2, :body => "User" }.to_json)
51
+ FakeWeb.register_uri(:get, "https://api.example.com/organizations/1", :body => { :id => 1, :name => "Bluth Company" }.to_json)
52
+
53
+ spawn_model :User
54
+ spawn_model :Organization
55
+ spawn_model :Comment
56
+ spawn_model :Role
57
+
58
+ User.has_many :comments
59
+ User.has_one :role
60
+ User.belongs_to :organization
78
61
 
79
62
  @user_with_included_data = User.find(1)
80
63
  @user_without_included_data = User.find(2)
@@ -12,7 +12,14 @@ RSpec.configure do |c|
12
12
  end
13
13
 
14
14
  class Hash
15
- def to_json
16
- MultiJson.dump(self)
17
- end
15
+ def to_json; MultiJson.dump(self); end
16
+ end
17
+
18
+ class Array
19
+ def to_json; MultiJson.dump(self); end
20
+ end
21
+
22
+ def spawn_model(klass, attrs={})
23
+ Object.instance_eval { remove_const klass } if Object.const_defined?(klass)
24
+ eval "class #{klass}; include Her::Model; end"
18
25
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: her
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8.1
4
+ version: '0.2'
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: 2012-04-24 00:00:00.000000000Z
12
+ date: 2012-04-27 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -172,7 +172,8 @@ files:
172
172
  - lib/her.rb
173
173
  - lib/her/api.rb
174
174
  - lib/her/middleware.rb
175
- - lib/her/middleware/default_parse_json.rb
175
+ - lib/her/middleware/first_level_parse_json.rb
176
+ - lib/her/middleware/second_level_parse_json.rb
176
177
  - lib/her/model.rb
177
178
  - lib/her/model/base.rb
178
179
  - lib/her/model/hooks.rb
@@ -182,7 +183,8 @@ files:
182
183
  - lib/her/model/relationships.rb
183
184
  - lib/her/version.rb
184
185
  - spec/api_spec.rb
185
- - spec/middleware/default_parse_json_spec.rb
186
+ - spec/middleware/first_level_parse_json_spec.rb
187
+ - spec/middleware/second_level_parse_json_spec.rb
186
188
  - spec/model/hooks_spec.rb
187
189
  - spec/model/http_spec.rb
188
190
  - spec/model/introspection_spec.rb
@@ -203,7 +205,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
203
205
  version: '0'
204
206
  segments:
205
207
  - 0
206
- hash: 3701075745278308572
208
+ hash: -2358268706124465287
207
209
  required_rubygems_version: !ruby/object:Gem::Requirement
208
210
  none: false
209
211
  requirements:
@@ -212,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
214
  version: '0'
213
215
  segments:
214
216
  - 0
215
- hash: 3701075745278308572
217
+ hash: -2358268706124465287
216
218
  requirements: []
217
219
  rubyforge_project:
218
220
  rubygems_version: 1.8.18
@@ -222,7 +224,8 @@ summary: A simple Representational State Transfer-based Hypertext Transfer Proto
222
224
  Object Relational Mapper. Her?
223
225
  test_files:
224
226
  - spec/api_spec.rb
225
- - spec/middleware/default_parse_json_spec.rb
227
+ - spec/middleware/first_level_parse_json_spec.rb
228
+ - spec/middleware/second_level_parse_json_spec.rb
226
229
  - spec/model/hooks_spec.rb
227
230
  - spec/model/http_spec.rb
228
231
  - spec/model/introspection_spec.rb