her 0.3.1 → 0.3.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.
- data/README.md +4 -1
- data/Rakefile +2 -2
- data/her.gemspec +2 -2
- data/lib/her/model.rb +2 -4
- data/lib/her/model/hooks.rb +10 -7
- data/lib/her/model/http.rb +14 -2
- data/lib/her/model/introspection.rb +27 -27
- data/lib/her/model/orm.rb +132 -80
- data/lib/her/model/paths.rb +58 -46
- data/lib/her/model/relationships.rb +36 -18
- data/lib/her/version.rb +1 -1
- data/spec/middleware/accept_json_spec.rb +2 -2
- data/spec/middleware/first_level_parse_json_spec.rb +4 -4
- data/spec/middleware/second_level_parse_json_spec.rb +4 -4
- data/spec/model/hooks_spec.rb +43 -32
- data/spec/model/http_spec.rb +82 -34
- data/spec/model/introspection_spec.rb +8 -8
- data/spec/model/orm_spec.rb +172 -0
- data/spec/model/paths_spec.rb +116 -16
- data/spec/model/relationships_spec.rb +28 -3
- data/spec/spec_helper.rb +2 -1
- metadata +8 -8
data/lib/her/model/paths.rb
CHANGED
@@ -1,51 +1,7 @@
|
|
1
1
|
module Her
|
2
2
|
module Model
|
3
3
|
module Paths
|
4
|
-
|
5
|
-
#
|
6
|
-
# @example
|
7
|
-
# class User
|
8
|
-
# include Her::Model
|
9
|
-
# collection_path "/users"
|
10
|
-
# end
|
11
|
-
def collection_path(path=nil) # {{{
|
12
|
-
return @her_collection_path unless path
|
13
|
-
@her_resource_path = "#{path}/:id"
|
14
|
-
@her_collection_path = path
|
15
|
-
end # }}}
|
16
|
-
|
17
|
-
# Defines a custom resource path for the resource
|
18
|
-
#
|
19
|
-
# @example
|
20
|
-
# class User
|
21
|
-
# include Her::Model
|
22
|
-
# resource_path "/users/:id"
|
23
|
-
# end
|
24
|
-
def resource_path(path=nil) # {{{
|
25
|
-
return @her_resource_path unless path
|
26
|
-
@her_resource_path = path
|
27
|
-
end # }}}
|
28
|
-
|
29
|
-
# Return a custom path based on the collection path and variable parameters
|
30
|
-
#
|
31
|
-
# @example
|
32
|
-
# class User
|
33
|
-
# include Her::Model
|
34
|
-
# collection_path "/utilisateurs"
|
35
|
-
# end
|
36
|
-
#
|
37
|
-
# User.all # Fetched via GET /utilisateurs
|
38
|
-
def build_request_path(path=nil, parameters={}) # {{{
|
39
|
-
unless path.is_a?(String)
|
40
|
-
parameters = path || {}
|
41
|
-
path = parameters.include?(:id) ? @her_resource_path : @her_collection_path
|
42
|
-
end
|
43
|
-
path.gsub(/:([\w_]+)/) do
|
44
|
-
# Look for :key or :_key, otherwise raise an exception
|
45
|
-
parameters[$1.to_sym] || parameters["_#{$1}".to_sym] || raise(Her::Errors::PathError.new("Missing :_#{$1} parameter to build the request path (#{path})."))
|
46
|
-
end
|
47
|
-
end # }}}
|
48
|
-
|
4
|
+
extend ActiveSupport::Concern
|
49
5
|
# Return a path based on the collection path and a resource data
|
50
6
|
#
|
51
7
|
# @example
|
@@ -56,8 +12,64 @@ module Her
|
|
56
12
|
#
|
57
13
|
# User.find(1) # Fetched via GET /utilisateurs/1
|
58
14
|
def request_path # {{{
|
59
|
-
self.class.build_request_path(@data)
|
15
|
+
self.class.build_request_path(@data.dup)
|
60
16
|
end # }}}
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
# Defines a custom collection path for the resource
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# class User
|
23
|
+
# include Her::Model
|
24
|
+
# collection_path "/users"
|
25
|
+
# end
|
26
|
+
def collection_path(path=nil) # {{{
|
27
|
+
@her_collection_path ||= begin
|
28
|
+
superclass.collection_path.dup if superclass.respond_to?(:collection_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
return @her_collection_path unless path
|
32
|
+
@her_resource_path = "#{path}/:id"
|
33
|
+
@her_collection_path = path
|
34
|
+
end # }}}
|
35
|
+
|
36
|
+
# Defines a custom resource path for the resource
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
# class User
|
40
|
+
# include Her::Model
|
41
|
+
# resource_path "/users/:id"
|
42
|
+
# end
|
43
|
+
def resource_path(path=nil) # {{{
|
44
|
+
@her_resource_path ||= begin
|
45
|
+
superclass.resource_path.dup if superclass.respond_to?(:resource_path)
|
46
|
+
end
|
47
|
+
|
48
|
+
return @her_resource_path unless path
|
49
|
+
@her_resource_path = path
|
50
|
+
end # }}}
|
51
|
+
|
52
|
+
# Return a custom path based on the collection path and variable parameters
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# class User
|
56
|
+
# include Her::Model
|
57
|
+
# collection_path "/utilisateurs"
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# User.all # Fetched via GET /utilisateurs
|
61
|
+
def build_request_path(path=nil, parameters={}) # {{{
|
62
|
+
unless path.is_a?(String)
|
63
|
+
parameters = path || {}
|
64
|
+
path = parameters.include?(:id) ? resource_path : collection_path
|
65
|
+
end
|
66
|
+
|
67
|
+
path.gsub(/:([\w_]+)/) do
|
68
|
+
# Look for :key or :_key, otherwise raise an exception
|
69
|
+
parameters.delete($1.to_sym) || parameters.delete("_#{$1}".to_sym) || raise(Her::Errors::PathError.new("Missing :_#{$1} parameter to build the request path (#{path})."))
|
70
|
+
end
|
71
|
+
end # }}}
|
72
|
+
end
|
61
73
|
end
|
62
74
|
end
|
63
75
|
end
|
@@ -2,18 +2,24 @@ module Her
|
|
2
2
|
module Model
|
3
3
|
# This module adds relationships to models
|
4
4
|
module Relationships
|
5
|
-
# Return
|
5
|
+
# Return @her_relationships, lazily initialized with copy of the
|
6
|
+
# superclass' her_relationships, or an empty hash.
|
6
7
|
# @private
|
7
8
|
def relationships # {{{
|
8
|
-
@her_relationships
|
9
|
+
@her_relationships ||= begin
|
10
|
+
if superclass.respond_to?(:relationships)
|
11
|
+
superclass.relationships.dup
|
12
|
+
else
|
13
|
+
{}
|
14
|
+
end
|
15
|
+
end
|
9
16
|
end # }}}
|
10
17
|
|
11
18
|
# Parse relationships data after initializing a new object
|
12
19
|
# @private
|
13
20
|
def parse_relationships(data) # {{{
|
14
|
-
|
15
|
-
|
16
|
-
relationships.each do |relationship|
|
21
|
+
relationships.each_pair do |type, definitions|
|
22
|
+
definitions.each do |relationship|
|
17
23
|
name = relationship[:name]
|
18
24
|
klass = self.nearby_class(relationship[:class_name])
|
19
25
|
next if !data.include?(name) or data[name].nil?
|
@@ -49,17 +55,21 @@ module Her
|
|
49
55
|
# @user.articles # => [#<Article(articles/2) id=2 title="Hello world.">]
|
50
56
|
# # Fetched via GET "/users/1/articles"
|
51
57
|
def has_many(name, attrs={}) # {{{
|
52
|
-
@her_relationships ||= {}
|
53
58
|
attrs = {
|
54
59
|
:class_name => name.to_s.classify,
|
55
60
|
:name => name,
|
56
61
|
:path => "/#{name}"
|
57
62
|
}.merge(attrs)
|
58
|
-
(
|
63
|
+
(relationships[:has_many] ||= []) << attrs
|
59
64
|
|
60
|
-
define_method(name) do
|
65
|
+
define_method(name) do |*method_attrs|
|
66
|
+
method_attrs = method_attrs[0] || {}
|
61
67
|
klass = self.class.nearby_class(attrs[:class_name])
|
62
|
-
|
68
|
+
if method_attrs.any?
|
69
|
+
klass.get_collection("#{self.class.build_request_path(method_attrs.merge(:id => id))}#{attrs[:path]}")
|
70
|
+
else
|
71
|
+
@data[name] ||= klass.get_collection("#{self.class.build_request_path(:id => id)}#{attrs[:path]}")
|
72
|
+
end
|
63
73
|
end
|
64
74
|
end # }}}
|
65
75
|
|
@@ -82,17 +92,21 @@ module Her
|
|
82
92
|
# @user.organization # => #<Organization(organizations/2) id=2 name="Foobar Inc.">
|
83
93
|
# # Fetched via GET "/users/1/organization"
|
84
94
|
def has_one(name, attrs={}) # {{{
|
85
|
-
@her_relationships ||= {}
|
86
95
|
attrs = {
|
87
96
|
:class_name => name.to_s.classify,
|
88
97
|
:name => name,
|
89
98
|
:path => "/#{name}"
|
90
99
|
}.merge(attrs)
|
91
|
-
(
|
100
|
+
(relationships[:has_one] ||= []) << attrs
|
92
101
|
|
93
|
-
define_method(name) do
|
102
|
+
define_method(name) do |*method_attrs|
|
103
|
+
method_attrs = method_attrs[0] || {}
|
94
104
|
klass = self.class.nearby_class(attrs[:class_name])
|
95
|
-
|
105
|
+
if method_attrs.any?
|
106
|
+
klass.get_resource("#{self.class.build_request_path(method_attrs.merge(:id => id))}#{attrs[:path]}")
|
107
|
+
else
|
108
|
+
@data[name] ||= klass.get_resource("#{self.class.build_request_path(:id => id)}#{attrs[:path]}")
|
109
|
+
end
|
96
110
|
end
|
97
111
|
end # }}}
|
98
112
|
|
@@ -115,20 +129,24 @@ module Her
|
|
115
129
|
# @user.team # => #<Team(teams/2) id=2 name="Developers">
|
116
130
|
# # Fetched via GET "/teams/2"
|
117
131
|
def belongs_to(name, attrs={}) # {{{
|
118
|
-
@her_relationships ||= {}
|
119
132
|
attrs = {
|
120
133
|
:class_name => name.to_s.classify,
|
121
134
|
:name => name,
|
122
135
|
:foreign_key => "#{name}_id",
|
123
136
|
:path => "/#{name.to_s.pluralize}/:id"
|
124
137
|
}.merge(attrs)
|
125
|
-
(
|
138
|
+
(relationships[:belongs_to] ||= []) << attrs
|
126
139
|
|
127
|
-
define_method(name) do
|
140
|
+
define_method(name) do |*method_attrs|
|
141
|
+
method_attrs = method_attrs[0] || {}
|
128
142
|
klass = self.class.nearby_class(attrs[:class_name])
|
129
|
-
|
143
|
+
if method_attrs.any?
|
144
|
+
klass.get_resource("#{klass.build_request_path(method_attrs.merge(:id => @data[attrs[:foreign_key].to_sym]))}")
|
145
|
+
else
|
146
|
+
@data[name] ||= klass.get_resource("#{klass.build_request_path(:id => @data[attrs[:foreign_key].to_sym])}")
|
147
|
+
end
|
130
148
|
end
|
131
|
-
end
|
149
|
+
end # }}}
|
132
150
|
|
133
151
|
# @private
|
134
152
|
def relationship_accessor(type, attrs) # {{{
|
data/lib/her/version.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
require "spec_helper"
|
3
3
|
|
4
4
|
describe Her::Middleware::AcceptJSON do
|
5
|
-
it "adds an Accept header" do
|
5
|
+
it "adds an Accept header" do # {{{
|
6
6
|
described_class.new.add_header({}).tap do |headers|
|
7
7
|
headers["Accept"].should == "application/json"
|
8
8
|
end
|
9
|
-
end
|
9
|
+
end # }}}
|
10
10
|
end
|
@@ -5,15 +5,15 @@ describe Her::Middleware::FirstLevelParseJSON do
|
|
5
5
|
subject { described_class.new }
|
6
6
|
let(:body) { "{\"id\": 1, \"name\": \"Tobias Fünke\", \"errors\": 2, \"metadata\": 3}" }
|
7
7
|
|
8
|
-
it "parses body as json" do
|
8
|
+
it "parses body as json" do # {{{
|
9
9
|
subject.parse(body).tap do |json|
|
10
10
|
json[:data].should == { :id => 1, :name => "Tobias Fünke" }
|
11
11
|
json[:errors].should == 2
|
12
12
|
json[:metadata].should == 3
|
13
13
|
end
|
14
|
-
end
|
14
|
+
end # }}}
|
15
15
|
|
16
|
-
it "parses :body key as json in the env hash" do
|
16
|
+
it "parses :body key as json in the env hash" do # {{{
|
17
17
|
env = { :body => body }
|
18
18
|
subject.on_complete(env)
|
19
19
|
env[:body].tap do |json|
|
@@ -21,5 +21,5 @@ describe Her::Middleware::FirstLevelParseJSON do
|
|
21
21
|
json[:errors].should == 2
|
22
22
|
json[:metadata].should == 3
|
23
23
|
end
|
24
|
-
end
|
24
|
+
end # }}}
|
25
25
|
end
|
@@ -5,15 +5,15 @@ describe Her::Middleware::SecondLevelParseJSON do
|
|
5
5
|
subject { described_class.new }
|
6
6
|
let(:body) { "{\"data\": 1, \"errors\": 2, \"metadata\": 3}" }
|
7
7
|
|
8
|
-
it "parses body as json" do
|
8
|
+
it "parses body as json" do # {{{
|
9
9
|
subject.parse(body).tap do |json|
|
10
10
|
json[:data].should == 1
|
11
11
|
json[:errors].should == 2
|
12
12
|
json[:metadata].should == 3
|
13
13
|
end
|
14
|
-
end
|
14
|
+
end # }}}
|
15
15
|
|
16
|
-
it "parses :body key as json in the env hash" do
|
16
|
+
it "parses :body key as json in the env hash" do # {{{
|
17
17
|
env = { :body => body }
|
18
18
|
subject.on_complete(env)
|
19
19
|
env[:body].tap do |json|
|
@@ -21,5 +21,5 @@ describe Her::Middleware::SecondLevelParseJSON do
|
|
21
21
|
json[:errors].should == 2
|
22
22
|
json[:metadata].should == 3
|
23
23
|
end
|
24
|
-
end
|
24
|
+
end # }}}
|
25
25
|
end
|
data/spec/model/hooks_spec.rb
CHANGED
@@ -10,100 +10,111 @@ describe Her::Model::Hooks do
|
|
10
10
|
describe "method hooks" do
|
11
11
|
it "handles “before save” method hooks" do # {{{
|
12
12
|
Foo::User.before_save :set_internal_id
|
13
|
-
Foo::User.
|
14
|
-
Foo::User.
|
13
|
+
Foo::User.hooks[:before_save].length.should == 1
|
14
|
+
Foo::User.hooks[:before_save].first.class.should == Symbol
|
15
15
|
end # }}}
|
16
16
|
|
17
17
|
it "handles “before create” method hooks" do # {{{
|
18
18
|
Foo::User.before_create :set_internal_id
|
19
|
-
Foo::User.
|
20
|
-
Foo::User.
|
19
|
+
Foo::User.hooks[:before_create].length.should == 1
|
20
|
+
Foo::User.hooks[:before_create].first.class.should == Symbol
|
21
21
|
end # }}}
|
22
22
|
|
23
23
|
it "handles “before update” method hooks" do # {{{
|
24
24
|
Foo::User.before_update :set_internal_id
|
25
|
-
Foo::User.
|
26
|
-
Foo::User.
|
25
|
+
Foo::User.hooks[:before_update].length.should == 1
|
26
|
+
Foo::User.hooks[:before_update].first.class.should == Symbol
|
27
27
|
end # }}}
|
28
28
|
|
29
29
|
it "handles “before destroy” method hooks" do # {{{
|
30
30
|
Foo::User.before_destroy :set_internal_id
|
31
|
-
Foo::User.
|
32
|
-
Foo::User.
|
31
|
+
Foo::User.hooks[:before_destroy].length.should == 1
|
32
|
+
Foo::User.hooks[:before_destroy].first.class.should == Symbol
|
33
33
|
end # }}}
|
34
34
|
|
35
35
|
it "handles “after save” method hooks" do # {{{
|
36
36
|
Foo::User.after_save :set_internal_id
|
37
|
-
Foo::User.
|
38
|
-
Foo::User.
|
37
|
+
Foo::User.hooks[:after_save].length.should == 1
|
38
|
+
Foo::User.hooks[:after_save].first.class.should == Symbol
|
39
39
|
end # }}}
|
40
40
|
|
41
41
|
it "handles “after create” method hooks" do # {{{
|
42
42
|
Foo::User.after_create :set_internal_id
|
43
|
-
Foo::User.
|
44
|
-
Foo::User.
|
43
|
+
Foo::User.hooks[:after_create].length.should == 1
|
44
|
+
Foo::User.hooks[:after_create].first.class.should == Symbol
|
45
45
|
end # }}}
|
46
46
|
|
47
47
|
it "handles “after update” method hooks" do # {{{
|
48
48
|
Foo::User.after_update :set_internal_id
|
49
|
-
Foo::User.
|
50
|
-
Foo::User.
|
49
|
+
Foo::User.hooks[:after_update].length.should == 1
|
50
|
+
Foo::User.hooks[:after_update].first.class.should == Symbol
|
51
51
|
end # }}}
|
52
52
|
|
53
53
|
it "handles “after destroy” method hooks" do # {{{
|
54
54
|
Foo::User.after_destroy :set_internal_id
|
55
|
-
Foo::User.
|
56
|
-
Foo::User.
|
55
|
+
Foo::User.hooks[:after_destroy].length.should == 1
|
56
|
+
Foo::User.hooks[:after_destroy].first.class.should == Symbol
|
57
57
|
end # }}}
|
58
58
|
end
|
59
59
|
|
60
60
|
describe "block hooks" do
|
61
61
|
it "handles “before save” block hooks" do # {{{
|
62
62
|
Foo::User.before_save { |record| record.internal_id = 42 }
|
63
|
-
Foo::User.
|
64
|
-
Foo::User.
|
63
|
+
Foo::User.hooks[:before_save].length.should == 1
|
64
|
+
Foo::User.hooks[:before_save].first.class.should == Proc
|
65
65
|
end # }}}
|
66
66
|
|
67
67
|
it "handles “before create” block hooks" do # {{{
|
68
68
|
Foo::User.before_create { |record| record.internal_id = 42 }
|
69
|
-
Foo::User.
|
70
|
-
Foo::User.
|
69
|
+
Foo::User.hooks[:before_create].length.should == 1
|
70
|
+
Foo::User.hooks[:before_create].first.class.should == Proc
|
71
71
|
end # }}}
|
72
72
|
|
73
73
|
it "handles “before update” block hooks" do # {{{
|
74
74
|
Foo::User.before_update { |record| record.internal_id = 42 }
|
75
|
-
Foo::User.
|
76
|
-
Foo::User.
|
75
|
+
Foo::User.hooks[:before_update].length.should == 1
|
76
|
+
Foo::User.hooks[:before_update].first.class.should == Proc
|
77
77
|
end # }}}
|
78
78
|
|
79
79
|
it "handles “before destroy” block hooks" do # {{{
|
80
80
|
Foo::User.before_destroy { |record| record.internal_id = 42 }
|
81
|
-
Foo::User.
|
82
|
-
Foo::User.
|
81
|
+
Foo::User.hooks[:before_destroy].length.should == 1
|
82
|
+
Foo::User.hooks[:before_destroy].first.class.should == Proc
|
83
83
|
end # }}}
|
84
84
|
|
85
85
|
it "handles “after save” block hooks" do # {{{
|
86
86
|
Foo::User.after_save { |record| record.internal_id = 42 }
|
87
|
-
Foo::User.
|
88
|
-
Foo::User.
|
87
|
+
Foo::User.hooks[:after_save].length.should == 1
|
88
|
+
Foo::User.hooks[:after_save].first.class.should == Proc
|
89
89
|
end # }}}
|
90
90
|
|
91
91
|
it "handles “after create” block hooks" do # {{{
|
92
92
|
Foo::User.after_create { |record| record.internal_id = 42 }
|
93
|
-
Foo::User.
|
94
|
-
Foo::User.
|
93
|
+
Foo::User.hooks[:after_create].length.should == 1
|
94
|
+
Foo::User.hooks[:after_create].first.class.should == Proc
|
95
95
|
end # }}}
|
96
96
|
|
97
97
|
it "handles “after update” block hooks" do # {{{
|
98
98
|
Foo::User.after_update { |record| record.internal_id = 42 }
|
99
|
-
Foo::User.
|
100
|
-
Foo::User.
|
99
|
+
Foo::User.hooks[:after_update].length.should == 1
|
100
|
+
Foo::User.hooks[:after_update].first.class.should == Proc
|
101
101
|
end # }}}
|
102
102
|
|
103
103
|
it "handles “after destroy” block hooks" do # {{{
|
104
104
|
Foo::User.after_destroy { |record| record.internal_id = 42 }
|
105
|
-
Foo::User.
|
106
|
-
Foo::User.
|
105
|
+
Foo::User.hooks[:after_destroy].length.should == 1
|
106
|
+
Foo::User.hooks[:after_destroy].first.class.should == Proc
|
107
|
+
end # }}}
|
108
|
+
end
|
109
|
+
|
110
|
+
context "inheriting hooks from a superclass" do
|
111
|
+
it "copies hooks to the subclass" do # {{{
|
112
|
+
Foo::User.before_save :set_internal_id
|
113
|
+
Foo::User.after_create { |record| record.internal_id = 42 }
|
114
|
+
subclass = Class.new(Foo::User)
|
115
|
+
subclass.hooks.object_id.should_not == Foo::User.hooks.object_id
|
116
|
+
subclass.hooks[:before_save].should == [:set_internal_id]
|
117
|
+
subclass.hooks[:after_create].length.should == 1
|
107
118
|
end # }}}
|
108
119
|
end
|
109
120
|
end
|
data/spec/model/http_spec.rb
CHANGED
@@ -9,11 +9,8 @@ describe Her::Model::HTTP do
|
|
9
9
|
|
10
10
|
spawn_model "Foo::User"
|
11
11
|
Foo::User.uses_api api
|
12
|
-
|
13
|
-
Foo::User.
|
14
|
-
@her_api.should_not == nil
|
15
|
-
@her_api.base_uri.should == "https://api.example.com"
|
16
|
-
end
|
12
|
+
Foo::User.her_api.should_not == nil
|
13
|
+
Foo::User.her_api.base_uri.should == "https://api.example.com"
|
17
14
|
end # }}}
|
18
15
|
|
19
16
|
it "binds a model directly to Her::API" do # {{{
|
@@ -21,10 +18,8 @@ describe Her::Model::HTTP do
|
|
21
18
|
|
22
19
|
spawn_model "Foo::User"
|
23
20
|
|
24
|
-
Foo::User.
|
25
|
-
|
26
|
-
@her_api.base_uri.should == "https://api.example.com"
|
27
|
-
end
|
21
|
+
Foo::User.her_api.should_not == nil
|
22
|
+
Foo::User.her_api.base_uri.should == "https://api.example.com"
|
28
23
|
end # }}}
|
29
24
|
|
30
25
|
it "binds two models to two different instances of Her::API" do # {{{
|
@@ -36,10 +31,7 @@ describe Her::Model::HTTP do
|
|
36
31
|
|
37
32
|
spawn_model "Foo::User"
|
38
33
|
Foo::User.uses_api api1
|
39
|
-
|
40
|
-
Foo::User.class_eval do
|
41
|
-
@her_api.base_uri.should == "https://api1.example.com"
|
42
|
-
end
|
34
|
+
Foo::User.her_api.base_uri.should == "https://api1.example.com"
|
43
35
|
|
44
36
|
api2 = Her::API.new
|
45
37
|
api2.setup :url => "https://api2.example.com" do |builder|
|
@@ -49,10 +41,7 @@ describe Her::Model::HTTP do
|
|
49
41
|
|
50
42
|
spawn_model "Foo::Comment"
|
51
43
|
Foo::Comment.uses_api api2
|
52
|
-
|
53
|
-
Foo::Comment.class_eval do
|
54
|
-
@her_api.base_uri.should == "https://api2.example.com"
|
55
|
-
end
|
44
|
+
Foo::Comment.her_api.base_uri.should == "https://api2.example.com"
|
56
45
|
end # }}}
|
57
46
|
|
58
47
|
it "binds one model to Her::API and another one to an instance of Her::API" do # {{{
|
@@ -63,9 +52,7 @@ describe Her::Model::HTTP do
|
|
63
52
|
|
64
53
|
spawn_model "Foo::User"
|
65
54
|
|
66
|
-
Foo::User.
|
67
|
-
@her_api.base_uri.should == "https://api1.example.com"
|
68
|
-
end
|
55
|
+
Foo::User.her_api.base_uri.should == "https://api1.example.com"
|
69
56
|
|
70
57
|
api = Her::API.new
|
71
58
|
api.setup :url => "https://api2.example.com" do |builder|
|
@@ -75,10 +62,46 @@ describe Her::Model::HTTP do
|
|
75
62
|
|
76
63
|
spawn_model "Foo::Comment"
|
77
64
|
Foo::Comment.uses_api api
|
65
|
+
Foo::Comment.her_api.base_uri.should == "https://api2.example.com"
|
66
|
+
end # }}}
|
78
67
|
|
79
|
-
|
80
|
-
|
68
|
+
it "binds a a model to it's superclass' her_api" do # {{{
|
69
|
+
api = Her::API.new
|
70
|
+
api.setup :url => "http://api.example.com" do |builder|
|
71
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
72
|
+
builder.use Faraday::Request::UrlEncoded
|
73
|
+
end
|
74
|
+
|
75
|
+
spawn_model "Foo::Superclass" do
|
76
|
+
uses_api api
|
81
77
|
end
|
78
|
+
|
79
|
+
Foo::Subclass = Class.new(Foo::Superclass)
|
80
|
+
Foo::Subclass.her_api.should == Foo::Superclass.her_api
|
81
|
+
end # }}}
|
82
|
+
|
83
|
+
it "allows subclasses to change her_api without changing the parent class' her_api" do # {{{
|
84
|
+
api1 = Her::API.new
|
85
|
+
api1.setup :url => "http://api.example.com" do |builder|
|
86
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
87
|
+
builder.use Faraday::Request::UrlEncoded
|
88
|
+
end
|
89
|
+
|
90
|
+
spawn_model "Foo::Superclass" do
|
91
|
+
uses_api api1
|
92
|
+
end
|
93
|
+
|
94
|
+
api2 = Her::API.new
|
95
|
+
api2.setup :url => "http://api.example.com" do |builder|
|
96
|
+
builder.use Her::Middleware::FirstLevelParseJSON
|
97
|
+
builder.use Faraday::Request::UrlEncoded
|
98
|
+
end
|
99
|
+
|
100
|
+
Foo::Subclass = Class.new(Foo::Superclass) do
|
101
|
+
uses_api api2
|
102
|
+
end
|
103
|
+
|
104
|
+
Foo::Subclass.her_api.should_not == Foo::Superclass.her_api
|
82
105
|
end # }}}
|
83
106
|
end
|
84
107
|
|
@@ -107,7 +130,7 @@ describe Her::Model::HTTP do
|
|
107
130
|
spawn_model "Foo::User"
|
108
131
|
end # }}}
|
109
132
|
|
110
|
-
it "
|
133
|
+
it "handles GET wrapper method" do # {{{
|
111
134
|
@users = Foo::User.get(:popular)
|
112
135
|
@users.length.should == 2
|
113
136
|
@users.first.id.should == 1
|
@@ -116,65 +139,90 @@ describe Her::Model::HTTP do
|
|
116
139
|
@user.id.should == 1
|
117
140
|
end # }}}
|
118
141
|
|
119
|
-
it "
|
142
|
+
it "handles raw GET with a block" do # {{{
|
120
143
|
Foo::User.get_raw("/users") do |parsed_data|
|
121
144
|
parsed_data[:data].should == [{ :id => 1 }]
|
122
145
|
end
|
123
146
|
end # }}}
|
124
147
|
|
125
|
-
it "
|
148
|
+
it "handles raw GET with return value" do # {{{
|
149
|
+
parsed_data = Foo::User.get_raw("/users")
|
150
|
+
parsed_data[:data].should == [{ :id => 1 }]
|
151
|
+
end # }}}
|
152
|
+
|
153
|
+
it "handles raw POST with a block" do # {{{
|
126
154
|
Foo::User.post_raw("/users") do |parsed_data|
|
127
155
|
parsed_data[:data].should == [{ :id => 3 }]
|
128
156
|
end
|
129
157
|
end # }}}
|
130
158
|
|
131
|
-
it "
|
159
|
+
it "handles raw POST with return value" do # {{{
|
160
|
+
parsed_data = Foo::User.post_raw("/users")
|
161
|
+
parsed_data[:data].should == [{ :id => 3 }]
|
162
|
+
end # }}}
|
163
|
+
|
164
|
+
it "handles raw PUT with a block" do # {{{
|
132
165
|
Foo::User.put_raw("/users/4") do |parsed_data|
|
133
166
|
parsed_data[:data].should == [{ :id => 4 }]
|
134
167
|
end
|
135
168
|
end # }}}
|
136
169
|
|
137
|
-
it "
|
170
|
+
it "handles raw PUT with return value" do # {{{
|
171
|
+
parsed_data = Foo::User.put_raw("/users/4")
|
172
|
+
parsed_data[:data].should == [{ :id => 4 }]
|
173
|
+
end # }}}
|
174
|
+
|
175
|
+
it "handles raw PATCH with a block" do # {{{
|
138
176
|
Foo::User.patch_raw("/users/6") do |parsed_data|
|
139
177
|
parsed_data[:data].should == [{ :id => 6 }]
|
140
178
|
end
|
141
179
|
end # }}}
|
142
180
|
|
143
|
-
it "
|
181
|
+
it "handles raw PATCH with return value" do # {{{
|
182
|
+
parsed_data = Foo::User.patch_raw("/users/6")
|
183
|
+
parsed_data[:data].should == [{ :id => 6 }]
|
184
|
+
end # }}}
|
185
|
+
|
186
|
+
it "handles raw DELETE with a block" do # {{{
|
144
187
|
Foo::User.delete_raw("/users/5") do |parsed_data|
|
145
188
|
parsed_data[:data].should == [{ :id => 5 }]
|
146
189
|
end
|
147
190
|
end # }}}
|
148
191
|
|
149
|
-
it "
|
192
|
+
it "handles raw DELETE with return value" do # {{{
|
193
|
+
parsed_data = Foo::User.delete_raw("/users/5")
|
194
|
+
parsed_data[:data].should == [{ :id => 5 }]
|
195
|
+
end # }}}
|
196
|
+
|
197
|
+
it "handles querystring parameters" do # {{{
|
150
198
|
Foo::User.get_raw("/users", :page => 2) do |parsed_data|
|
151
199
|
parsed_data[:data].should == [{ :id => 2 }]
|
152
200
|
end
|
153
201
|
end # }}}
|
154
202
|
|
155
|
-
it "
|
203
|
+
it "handles GET collection" do # {{{
|
156
204
|
@users = Foo::User.get_collection("/users/popular")
|
157
205
|
@users.length.should == 2
|
158
206
|
@users.first.id.should == 1
|
159
207
|
end # }}}
|
160
208
|
|
161
|
-
it "
|
209
|
+
it "handles GET resource" do # {{{
|
162
210
|
@user = Foo::User.get_resource("/users/1")
|
163
211
|
@user.id.should == 1
|
164
212
|
end # }}}
|
165
213
|
|
166
|
-
it "
|
214
|
+
it "handles GET collection through a symbol" do # {{{
|
167
215
|
@users = Foo::User.get_collection(:popular)
|
168
216
|
@users.length.should == 2
|
169
217
|
@users.first.id.should == 1
|
170
218
|
end # }}}
|
171
219
|
|
172
|
-
it "
|
220
|
+
it "handles GET resource through a symbol" do # {{{
|
173
221
|
@user = Foo::User.get_resource(:"1")
|
174
222
|
@user.id.should == 1
|
175
223
|
end # }}}
|
176
224
|
|
177
|
-
it "
|
225
|
+
it "handles raw GET through a symbol" do # {{{
|
178
226
|
Foo::User.get_raw(:popular) do |parsed_data|
|
179
227
|
parsed_data[:data].should == [{ :id => 1 }, { :id => 2 }]
|
180
228
|
end
|