herr 0.7.3

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.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +15 -0
  5. data/.yardopts +2 -0
  6. data/CONTRIBUTING.md +26 -0
  7. data/Gemfile +10 -0
  8. data/LICENSE +7 -0
  9. data/README.md +990 -0
  10. data/Rakefile +11 -0
  11. data/UPGRADE.md +81 -0
  12. data/gemfiles/Gemfile.activemodel-3.2.x +7 -0
  13. data/gemfiles/Gemfile.activemodel-4.0 +7 -0
  14. data/gemfiles/Gemfile.activemodel-4.1 +7 -0
  15. data/gemfiles/Gemfile.activemodel-4.2 +7 -0
  16. data/her.gemspec +30 -0
  17. data/lib/her.rb +16 -0
  18. data/lib/her/api.rb +115 -0
  19. data/lib/her/collection.rb +12 -0
  20. data/lib/her/errors.rb +27 -0
  21. data/lib/her/middleware.rb +10 -0
  22. data/lib/her/middleware/accept_json.rb +17 -0
  23. data/lib/her/middleware/first_level_parse_json.rb +36 -0
  24. data/lib/her/middleware/parse_json.rb +21 -0
  25. data/lib/her/middleware/second_level_parse_json.rb +36 -0
  26. data/lib/her/model.rb +72 -0
  27. data/lib/her/model/associations.rb +141 -0
  28. data/lib/her/model/associations/association.rb +103 -0
  29. data/lib/her/model/associations/association_proxy.rb +46 -0
  30. data/lib/her/model/associations/belongs_to_association.rb +96 -0
  31. data/lib/her/model/associations/has_many_association.rb +100 -0
  32. data/lib/her/model/associations/has_one_association.rb +79 -0
  33. data/lib/her/model/attributes.rb +266 -0
  34. data/lib/her/model/base.rb +33 -0
  35. data/lib/her/model/deprecated_methods.rb +61 -0
  36. data/lib/her/model/http.rb +114 -0
  37. data/lib/her/model/introspection.rb +65 -0
  38. data/lib/her/model/nested_attributes.rb +45 -0
  39. data/lib/her/model/orm.rb +205 -0
  40. data/lib/her/model/parse.rb +227 -0
  41. data/lib/her/model/paths.rb +121 -0
  42. data/lib/her/model/relation.rb +164 -0
  43. data/lib/her/version.rb +3 -0
  44. data/spec/api_spec.rb +131 -0
  45. data/spec/collection_spec.rb +26 -0
  46. data/spec/middleware/accept_json_spec.rb +10 -0
  47. data/spec/middleware/first_level_parse_json_spec.rb +62 -0
  48. data/spec/middleware/second_level_parse_json_spec.rb +35 -0
  49. data/spec/model/associations_spec.rb +416 -0
  50. data/spec/model/attributes_spec.rb +268 -0
  51. data/spec/model/callbacks_spec.rb +145 -0
  52. data/spec/model/dirty_spec.rb +86 -0
  53. data/spec/model/http_spec.rb +194 -0
  54. data/spec/model/introspection_spec.rb +76 -0
  55. data/spec/model/nested_attributes_spec.rb +134 -0
  56. data/spec/model/orm_spec.rb +479 -0
  57. data/spec/model/parse_spec.rb +373 -0
  58. data/spec/model/paths_spec.rb +341 -0
  59. data/spec/model/relation_spec.rb +226 -0
  60. data/spec/model/validations_spec.rb +42 -0
  61. data/spec/model_spec.rb +31 -0
  62. data/spec/spec_helper.rb +26 -0
  63. data/spec/support/extensions/array.rb +5 -0
  64. data/spec/support/extensions/hash.rb +5 -0
  65. data/spec/support/macros/her_macros.rb +17 -0
  66. data/spec/support/macros/model_macros.rb +29 -0
  67. data/spec/support/macros/request_macros.rb +27 -0
  68. metadata +280 -0
@@ -0,0 +1,226 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
+
4
+ describe Her::Model::Relation do
5
+ describe :where do
6
+ context "for base classes" do
7
+ before do
8
+ Her::API.setup :url => "https://api.example.com" do |builder|
9
+ builder.use Her::Middleware::FirstLevelParseJSON
10
+ builder.adapter :test do |stub|
11
+ stub.get("/users?foo=1&bar=2") { |env| ok! [{ :id => 2, :fullname => "Tobias Fünke" }] }
12
+ stub.get("/users?admin=1") { |env| ok! [{ :id => 1, :fullname => "Tobias Fünke" }] }
13
+
14
+ stub.get("/users") do |env|
15
+ ok! [
16
+ { :id => 1, :fullname => "Tobias Fünke" },
17
+ { :id => 2, :fullname => "Lindsay Fünke" },
18
+ @created_user,
19
+ ].compact
20
+ end
21
+
22
+ stub.post('/users') do |env|
23
+ @created_user = { :id => 3, :fullname => 'George Michael Bluth' }
24
+ ok! @created_user
25
+ end
26
+ end
27
+ end
28
+
29
+ spawn_model "Foo::User"
30
+ end
31
+
32
+ it "doesn't fetch the data immediatly" do
33
+ Foo::User.should_receive(:request).never
34
+ @users = Foo::User.where(:admin => 1)
35
+ end
36
+
37
+ it "fetches the data and passes query parameters" do
38
+ Foo::User.should_receive(:request).once.and_call_original
39
+ @users = Foo::User.where(:admin => 1)
40
+ @users.should respond_to(:length)
41
+ @users.size.should eql 1
42
+ end
43
+
44
+ it "chains multiple where statements" do
45
+ @user = Foo::User.where(:foo => 1).where(:bar => 2).first
46
+ @user.id.should == 2
47
+ end
48
+
49
+ it "does not reuse relations" do
50
+ Foo::User.all.size.should eql 2
51
+ Foo::User.create(:fullname => 'George Michael Bluth').id.should == 3
52
+ Foo::User.all.size.should eql 3
53
+ end
54
+ end
55
+
56
+ context "for parent class" do
57
+ before do
58
+ Her::API.setup :url => "https://api.example.com" do |builder|
59
+ builder.use Her::Middleware::FirstLevelParseJSON
60
+ builder.adapter :test do |stub|
61
+ stub.get("/users?page=2") { |env| ok! [{ :id => 1, :fullname => "Tobias Fünke" }, { :id => 2, :fullname => "Lindsay Fünke" }] }
62
+ end
63
+ end
64
+
65
+ spawn_model("Foo::Model") do
66
+ scope :page, lambda { |page| where(:page => page) }
67
+ end
68
+
69
+ class User < Foo::Model; end
70
+ @spawned_models << :User
71
+ end
72
+
73
+ it "propagates the scopes through its children" do
74
+ @users = User.page(2)
75
+ @users.length.should == 2
76
+ end
77
+ end
78
+ end
79
+
80
+ describe :create do
81
+ before do
82
+ Her::API.setup :url => "https://api.example.com" do |builder|
83
+ builder.use Her::Middleware::FirstLevelParseJSON
84
+ builder.use Faraday::Request::UrlEncoded
85
+ builder.adapter :test do |stub|
86
+ stub.post("/users") { |env| ok! :id => 1, :fullname => params(env)[:fullname], :email => params(env)[:email] }
87
+ end
88
+ end
89
+
90
+ spawn_model "Foo::User"
91
+ end
92
+
93
+ context "with a single where call" do
94
+ it "creates a resource and passes the query parameters" do
95
+ @user = Foo::User.where(:fullname => "Tobias Fünke", :email => "tobias@bluth.com").create
96
+ @user.id.should == 1
97
+ @user.fullname.should == "Tobias Fünke"
98
+ @user.email.should == "tobias@bluth.com"
99
+ end
100
+ end
101
+
102
+ context "with multiple where calls" do
103
+ it "creates a resource and passes the query parameters" do
104
+ @user = Foo::User.where(:fullname => "Tobias Fünke").create(:email => "tobias@bluth.com")
105
+ @user.id.should == 1
106
+ @user.fullname.should == "Tobias Fünke"
107
+ @user.email.should == "tobias@bluth.com"
108
+ end
109
+ end
110
+ end
111
+
112
+ describe :build do
113
+ before { spawn_model "Foo::User" }
114
+
115
+ it "handles new resource with build" do
116
+ @new_user = Foo::User.where(:fullname => "Tobias Fünke").build
117
+ @new_user.new?.should be_truthy
118
+ @new_user.fullname.should == "Tobias Fünke"
119
+ end
120
+ end
121
+
122
+ describe :scope do
123
+ before do
124
+ Her::API.setup :url => "https://api.example.com" do |builder|
125
+ builder.use Her::Middleware::FirstLevelParseJSON
126
+ builder.adapter :test do |stub|
127
+ stub.get("/users?what=4&where=3") { |env| ok! [{ :id => 3, :fullname => "Maeby Fünke" }] }
128
+ stub.get("/users?what=2") { |env| ok! [{ :id => 2, :fullname => "Lindsay Fünke" }] }
129
+ stub.get("/users?where=6") { |env| ok! [{ :id => 4, :fullname => "Tobias Fünke" }] }
130
+ end
131
+ end
132
+
133
+ spawn_model 'Foo::User' do
134
+ scope :foo, lambda { |v| where(:what => v) }
135
+ scope :bar, lambda { |v| where(:where => v) }
136
+ scope :baz, lambda { bar(6) }
137
+ end
138
+ end
139
+
140
+ it "passes query parameters" do
141
+ @user = Foo::User.foo(2).first
142
+ @user.id.should == 2
143
+ end
144
+
145
+ it "passes multiple query parameters" do
146
+ @user = Foo::User.foo(4).bar(3).first
147
+ @user.id.should == 3
148
+ end
149
+
150
+ it "handles embedded scopes" do
151
+ @user = Foo::User.baz.first
152
+ @user.id.should == 4
153
+ end
154
+ end
155
+
156
+ describe :default_scope do
157
+ context "for new objects" do
158
+ before do
159
+ spawn_model 'Foo::User' do
160
+ default_scope lambda { where(:active => true) }
161
+ default_scope lambda { where(:admin => true) }
162
+ end
163
+ end
164
+
165
+ it "should apply the scope to the attributes" do
166
+ Foo::User.new.should be_active
167
+ Foo::User.new.should be_admin
168
+ end
169
+ end
170
+
171
+ context "for fetched resources" do
172
+ before do
173
+ Her::API.setup :url => "https://api.example.com" do |builder|
174
+ builder.use Her::Middleware::FirstLevelParseJSON
175
+ builder.use Faraday::Request::UrlEncoded
176
+ builder.adapter :test do |stub|
177
+ stub.post("/users") { |env| ok! :id => 3, :active => (params(env)[:active] == "true" ? true : false) }
178
+ end
179
+ end
180
+
181
+ spawn_model 'Foo::User' do
182
+ default_scope lambda { where(:active => true) }
183
+ end
184
+ end
185
+
186
+ it("should apply the scope to the request") { Foo::User.create.should be_active }
187
+ end
188
+
189
+ context "for fetched collections" do
190
+ before do
191
+ Her::API.setup :url => "https://api.example.com" do |builder|
192
+ builder.use Her::Middleware::FirstLevelParseJSON
193
+ builder.use Faraday::Request::UrlEncoded
194
+ builder.adapter :test do |stub|
195
+ stub.get("/users?active=true") { |env| ok! [{ :id => 3, :active => (params(env)[:active] == "true" ? true : false) }] }
196
+ end
197
+ end
198
+
199
+ spawn_model 'Foo::User' do
200
+ default_scope lambda { where(:active => true) }
201
+ end
202
+ end
203
+
204
+ it("should apply the scope to the request") { Foo::User.all.first.should be_active }
205
+ end
206
+ end
207
+
208
+ describe :map do
209
+ before do
210
+ Her::API.setup :url => "https://api.example.com" do |builder|
211
+ builder.use Her::Middleware::FirstLevelParseJSON
212
+ builder.adapter :test do |stub|
213
+ stub.get("/users") do |env|
214
+ ok! [{ :id => 1, :fullname => "Tobias Fünke" }, { :id => 2, :fullname => "Lindsay Fünke" }]
215
+ end
216
+ end
217
+ end
218
+
219
+ spawn_model 'Foo::User'
220
+ end
221
+
222
+ it "delegates the method to the fetched collection" do
223
+ Foo::User.all.map(&:fullname).should == ["Tobias Fünke", "Lindsay Fünke"]
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
+
4
+ describe "Her::Model and ActiveModel::Validations" do
5
+ context "validating attributes" do
6
+ before do
7
+ spawn_model "Foo::User" do
8
+ attributes :fullname, :email
9
+ validates_presence_of :fullname
10
+ validates_presence_of :email
11
+ end
12
+ end
13
+
14
+ it "validates attributes when calling #valid?" do
15
+ user = Foo::User.new
16
+ user.should_not be_valid
17
+ user.errors.full_messages.should include("Fullname can't be blank")
18
+ user.errors.full_messages.should include("Email can't be blank")
19
+ user.fullname = "Tobias Fünke"
20
+ user.email = "tobias@bluthcompany.com"
21
+ user.should be_valid
22
+ end
23
+ end
24
+
25
+ context "handling server errors" do
26
+ before do
27
+ spawn_model("Foo::Model") do
28
+ def errors
29
+ @response_errors
30
+ end
31
+ end
32
+
33
+ class User < Foo::Model; end
34
+ @spawned_models << :User
35
+ end
36
+
37
+ it "validates attributes when calling #valid?" do
38
+ user = User.new(:_errors => ["Email cannot be blank"])
39
+ user.errors.should include("Email cannot be blank")
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe Her::Model do
5
+ before do
6
+ Her::API.setup :url => "https://api.example.com" do |connection|
7
+ connection.use Her::Middleware::FirstLevelParseJSON
8
+ connection.adapter :test do |stub|
9
+ stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
10
+ stub.get("/users/1/comments") { |env| [200, {}, [{ :id => 4, :body => "They're having a FIRESALE?" }].to_json] }
11
+ end
12
+ end
13
+
14
+ spawn_model("Foo::User") { has_many :comments }
15
+ spawn_model("Foo::Comment")
16
+ end
17
+ subject { Foo::User.find(1) }
18
+
19
+ describe :has_key? do
20
+ it { should_not have_key(:unknown_method_for_a_user) }
21
+ it { should_not have_key(:unknown_method_for_a_user) }
22
+ it { should have_key(:name) }
23
+ it { should have_key(:comments) }
24
+ end
25
+
26
+ describe :[] do
27
+ it { should_not have_key(:unknown_method_for_a_user) }
28
+ specify { subject[:name].should == "Tobias Fünke" }
29
+ specify { subject[:comments].first.body.should == "They're having a FIRESALE?" }
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
2
+
3
+ require "rspec"
4
+ require "rspec/its"
5
+ require "her"
6
+
7
+ # Require everything in `spec/support`
8
+ Dir[File.expand_path('../../spec/support/**/*.rb', __FILE__)].map(&method(:require))
9
+
10
+ # Remove ActiveModel deprecation message
11
+ I18n.enforce_available_locales = false
12
+
13
+ RSpec.configure do |config|
14
+ config.include Her::Testing::Macros::ModelMacros
15
+ config.include Her::Testing::Macros::RequestMacros
16
+
17
+ config.before :each do
18
+ @spawned_models = []
19
+ end
20
+
21
+ config.after :each do
22
+ @spawned_models.each do |model|
23
+ Object.instance_eval { remove_const model } if Object.const_defined?(model)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ class Array
2
+ def to_json
3
+ MultiJson.dump(self)
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Hash
2
+ def to_json
3
+ MultiJson.dump(self)
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ module Her
2
+ module Testing
3
+ module Macros
4
+ def ok!(body)
5
+ [200, {}, body.to_json]
6
+ end
7
+
8
+ def error!(body)
9
+ [400, {}, body.to_json]
10
+ end
11
+
12
+ def params(env)
13
+ Faraday::Utils.parse_query(env[:body])
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ module Her
2
+ module Testing
3
+ module Macros
4
+ module ModelMacros
5
+ # Create a class and automatically inject Her::Model into it
6
+ def spawn_model(klass, &block)
7
+ if klass =~ /::/
8
+ base, submodel = klass.split(/::/).map{ |s| s.to_sym }
9
+ Object.const_set(base, Module.new) unless Object.const_defined?(base)
10
+ Object.const_get(base).module_eval do
11
+ remove_const submodel if constants.map(&:to_sym).include?(submodel)
12
+ submodel = const_set(submodel, Class.new)
13
+ submodel.send(:include, Her::Model)
14
+ submodel.class_eval(&block) if block_given?
15
+ end
16
+
17
+ @spawned_models << base
18
+ else
19
+ Object.instance_eval { remove_const klass } if Object.const_defined?(klass)
20
+ Object.const_set(klass, Class.new).send(:include, Her::Model)
21
+ Object.const_get(klass).class_eval(&block) if block_given?
22
+
23
+ @spawned_models << klass.to_sym
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ module Her
2
+ module Testing
3
+ module Macros
4
+ module RequestMacros
5
+ def ok!(body)
6
+ [200, {}, body.to_json]
7
+ end
8
+
9
+ def error!(body)
10
+ [400, {}, body.to_json]
11
+ end
12
+
13
+ def params(env)
14
+ @params ||= begin
15
+ parsed_query = Faraday::Utils.parse_nested_query(env[:body])
16
+
17
+ if parsed_query
18
+ parsed_query.with_indifferent_access.merge(env[:params])
19
+ else
20
+ env[:params].with_indifferent_access
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,280 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: herr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.3
5
+ platform: ruby
6
+ authors:
7
+ - Rémi Prévost
8
+ - Dermot Haughey
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-02-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '10.0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '10.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '2.13'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '2.13'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec-its
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: fivemat
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '1.2'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.2'
70
+ - !ruby/object:Gem::Dependency
71
+ name: json
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.8'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '1.8'
84
+ - !ruby/object:Gem::Dependency
85
+ name: activemodel
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 3.0.0
91
+ - - "<="
92
+ - !ruby/object:Gem::Version
93
+ version: '4.2'
94
+ type: :runtime
95
+ prerelease: false
96
+ version_requirements: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 3.0.0
101
+ - - "<="
102
+ - !ruby/object:Gem::Version
103
+ version: '4.2'
104
+ - !ruby/object:Gem::Dependency
105
+ name: activesupport
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 3.0.0
111
+ - - "<="
112
+ - !ruby/object:Gem::Version
113
+ version: '4.2'
114
+ type: :runtime
115
+ prerelease: false
116
+ version_requirements: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 3.0.0
121
+ - - "<="
122
+ - !ruby/object:Gem::Version
123
+ version: '4.2'
124
+ - !ruby/object:Gem::Dependency
125
+ name: faraday
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0.8'
131
+ - - "<"
132
+ - !ruby/object:Gem::Version
133
+ version: '1.0'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0.8'
141
+ - - "<"
142
+ - !ruby/object:Gem::Version
143
+ version: '1.0'
144
+ - !ruby/object:Gem::Dependency
145
+ name: multi_json
146
+ requirement: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: '1.7'
151
+ type: :runtime
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - "~>"
156
+ - !ruby/object:Gem::Version
157
+ version: '1.7'
158
+ description: Herr is an ORM that maps REST resources and collections to Ruby objects
159
+ email:
160
+ - hderms@gmail.com
161
+ executables: []
162
+ extensions: []
163
+ extra_rdoc_files: []
164
+ files:
165
+ - ".gitignore"
166
+ - ".rspec"
167
+ - ".travis.yml"
168
+ - ".yardopts"
169
+ - CONTRIBUTING.md
170
+ - Gemfile
171
+ - LICENSE
172
+ - README.md
173
+ - Rakefile
174
+ - UPGRADE.md
175
+ - gemfiles/Gemfile.activemodel-3.2.x
176
+ - gemfiles/Gemfile.activemodel-4.0
177
+ - gemfiles/Gemfile.activemodel-4.1
178
+ - gemfiles/Gemfile.activemodel-4.2
179
+ - her.gemspec
180
+ - lib/her.rb
181
+ - lib/her/api.rb
182
+ - lib/her/collection.rb
183
+ - lib/her/errors.rb
184
+ - lib/her/middleware.rb
185
+ - lib/her/middleware/accept_json.rb
186
+ - lib/her/middleware/first_level_parse_json.rb
187
+ - lib/her/middleware/parse_json.rb
188
+ - lib/her/middleware/second_level_parse_json.rb
189
+ - lib/her/model.rb
190
+ - lib/her/model/associations.rb
191
+ - lib/her/model/associations/association.rb
192
+ - lib/her/model/associations/association_proxy.rb
193
+ - lib/her/model/associations/belongs_to_association.rb
194
+ - lib/her/model/associations/has_many_association.rb
195
+ - lib/her/model/associations/has_one_association.rb
196
+ - lib/her/model/attributes.rb
197
+ - lib/her/model/base.rb
198
+ - lib/her/model/deprecated_methods.rb
199
+ - lib/her/model/http.rb
200
+ - lib/her/model/introspection.rb
201
+ - lib/her/model/nested_attributes.rb
202
+ - lib/her/model/orm.rb
203
+ - lib/her/model/parse.rb
204
+ - lib/her/model/paths.rb
205
+ - lib/her/model/relation.rb
206
+ - lib/her/version.rb
207
+ - spec/api_spec.rb
208
+ - spec/collection_spec.rb
209
+ - spec/middleware/accept_json_spec.rb
210
+ - spec/middleware/first_level_parse_json_spec.rb
211
+ - spec/middleware/second_level_parse_json_spec.rb
212
+ - spec/model/associations_spec.rb
213
+ - spec/model/attributes_spec.rb
214
+ - spec/model/callbacks_spec.rb
215
+ - spec/model/dirty_spec.rb
216
+ - spec/model/http_spec.rb
217
+ - spec/model/introspection_spec.rb
218
+ - spec/model/nested_attributes_spec.rb
219
+ - spec/model/orm_spec.rb
220
+ - spec/model/parse_spec.rb
221
+ - spec/model/paths_spec.rb
222
+ - spec/model/relation_spec.rb
223
+ - spec/model/validations_spec.rb
224
+ - spec/model_spec.rb
225
+ - spec/spec_helper.rb
226
+ - spec/support/extensions/array.rb
227
+ - spec/support/extensions/hash.rb
228
+ - spec/support/macros/her_macros.rb
229
+ - spec/support/macros/model_macros.rb
230
+ - spec/support/macros/request_macros.rb
231
+ homepage: http://her-rb.org
232
+ licenses:
233
+ - MIT
234
+ metadata: {}
235
+ post_install_message:
236
+ rdoc_options: []
237
+ require_paths:
238
+ - lib
239
+ required_ruby_version: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ required_rubygems_version: !ruby/object:Gem::Requirement
245
+ requirements:
246
+ - - ">="
247
+ - !ruby/object:Gem::Version
248
+ version: '0'
249
+ requirements: []
250
+ rubyforge_project:
251
+ rubygems_version: 2.4.3
252
+ signing_key:
253
+ specification_version: 4
254
+ summary: A simple Representational State Transfer-based Hypertext Transfer Protocol-powered
255
+ Object Relational Mapper. Forked from 'her'
256
+ test_files:
257
+ - spec/api_spec.rb
258
+ - spec/collection_spec.rb
259
+ - spec/middleware/accept_json_spec.rb
260
+ - spec/middleware/first_level_parse_json_spec.rb
261
+ - spec/middleware/second_level_parse_json_spec.rb
262
+ - spec/model/associations_spec.rb
263
+ - spec/model/attributes_spec.rb
264
+ - spec/model/callbacks_spec.rb
265
+ - spec/model/dirty_spec.rb
266
+ - spec/model/http_spec.rb
267
+ - spec/model/introspection_spec.rb
268
+ - spec/model/nested_attributes_spec.rb
269
+ - spec/model/orm_spec.rb
270
+ - spec/model/parse_spec.rb
271
+ - spec/model/paths_spec.rb
272
+ - spec/model/relation_spec.rb
273
+ - spec/model/validations_spec.rb
274
+ - spec/model_spec.rb
275
+ - spec/spec_helper.rb
276
+ - spec/support/extensions/array.rb
277
+ - spec/support/extensions/hash.rb
278
+ - spec/support/macros/her_macros.rb
279
+ - spec/support/macros/model_macros.rb
280
+ - spec/support/macros/request_macros.rb