herr 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
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