her5 0.8.1

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 (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +17 -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 +1017 -0
  10. data/Rakefile +11 -0
  11. data/UPGRADE.md +101 -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/gemfiles/Gemfile.activemodel-5.0.x +7 -0
  17. data/her5.gemspec +30 -0
  18. data/lib/her.rb +19 -0
  19. data/lib/her/api.rb +120 -0
  20. data/lib/her/collection.rb +12 -0
  21. data/lib/her/errors.rb +104 -0
  22. data/lib/her/json_api/model.rb +57 -0
  23. data/lib/her/middleware.rb +12 -0
  24. data/lib/her/middleware/accept_json.rb +17 -0
  25. data/lib/her/middleware/first_level_parse_json.rb +36 -0
  26. data/lib/her/middleware/json_api_parser.rb +68 -0
  27. data/lib/her/middleware/parse_json.rb +28 -0
  28. data/lib/her/middleware/second_level_parse_json.rb +36 -0
  29. data/lib/her/model.rb +75 -0
  30. data/lib/her/model/associations.rb +141 -0
  31. data/lib/her/model/associations/association.rb +107 -0
  32. data/lib/her/model/associations/association_proxy.rb +45 -0
  33. data/lib/her/model/associations/belongs_to_association.rb +101 -0
  34. data/lib/her/model/associations/has_many_association.rb +101 -0
  35. data/lib/her/model/associations/has_one_association.rb +80 -0
  36. data/lib/her/model/attributes.rb +297 -0
  37. data/lib/her/model/base.rb +33 -0
  38. data/lib/her/model/deprecated_methods.rb +61 -0
  39. data/lib/her/model/http.rb +113 -0
  40. data/lib/her/model/introspection.rb +65 -0
  41. data/lib/her/model/nested_attributes.rb +84 -0
  42. data/lib/her/model/orm.rb +207 -0
  43. data/lib/her/model/parse.rb +221 -0
  44. data/lib/her/model/paths.rb +126 -0
  45. data/lib/her/model/relation.rb +164 -0
  46. data/lib/her/version.rb +3 -0
  47. data/spec/api_spec.rb +114 -0
  48. data/spec/collection_spec.rb +26 -0
  49. data/spec/json_api/model_spec.rb +305 -0
  50. data/spec/middleware/accept_json_spec.rb +10 -0
  51. data/spec/middleware/first_level_parse_json_spec.rb +62 -0
  52. data/spec/middleware/json_api_parser_spec.rb +32 -0
  53. data/spec/middleware/second_level_parse_json_spec.rb +35 -0
  54. data/spec/model/associations/association_proxy_spec.rb +31 -0
  55. data/spec/model/associations_spec.rb +504 -0
  56. data/spec/model/attributes_spec.rb +389 -0
  57. data/spec/model/callbacks_spec.rb +145 -0
  58. data/spec/model/dirty_spec.rb +91 -0
  59. data/spec/model/http_spec.rb +158 -0
  60. data/spec/model/introspection_spec.rb +76 -0
  61. data/spec/model/nested_attributes_spec.rb +134 -0
  62. data/spec/model/orm_spec.rb +506 -0
  63. data/spec/model/parse_spec.rb +345 -0
  64. data/spec/model/paths_spec.rb +347 -0
  65. data/spec/model/relation_spec.rb +226 -0
  66. data/spec/model/validations_spec.rb +42 -0
  67. data/spec/model_spec.rb +44 -0
  68. data/spec/spec_helper.rb +26 -0
  69. data/spec/support/extensions/array.rb +5 -0
  70. data/spec/support/extensions/hash.rb +5 -0
  71. data/spec/support/macros/her_macros.rb +17 -0
  72. data/spec/support/macros/model_macros.rb +36 -0
  73. data/spec/support/macros/request_macros.rb +27 -0
  74. metadata +289 -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,44 @@
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 :serialization do
27
+ it 'should be serialized without an error' do
28
+ expect { Marshal.dump(subject.comments) }.not_to raise_error
29
+ end
30
+
31
+ it 'should correctly load serialized object' do
32
+ serialized_comments = Marshal.load(Marshal.dump(subject.comments))
33
+ subject.comments.size.should eq(serialized_comments.size)
34
+ subject.comments.first.id.should eq(serialized_comments.first.id)
35
+ subject.comments.first.body.should eq(serialized_comments.first.body)
36
+ end
37
+ end
38
+
39
+ describe :[] do
40
+ it { should_not have_key(:unknown_method_for_a_user) }
41
+ specify { subject[:name].should == "Tobias Fünke" }
42
+ specify { subject[:comments].first.body.should == "They're having a FIRESALE?" }
43
+ end
44
+ 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,36 @@
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, options={}, &block)
7
+ super_class = options[:super_class]
8
+ model_type = options[:type] || Her::Model
9
+ new_class = if super_class
10
+ Class.new(super_class)
11
+ else
12
+ Class.new
13
+ end
14
+ if klass =~ /::/
15
+ base, submodel = klass.split(/::/).map{ |s| s.to_sym }
16
+ Object.const_set(base, Module.new) unless Object.const_defined?(base)
17
+ Object.const_get(base).module_eval do
18
+ remove_const submodel if constants.map(&:to_sym).include?(submodel)
19
+ submodel = const_set(submodel, new_class)
20
+ submodel.send(:include, model_type)
21
+ submodel.class_eval(&block) if block_given?
22
+ end
23
+
24
+ @spawned_models << base
25
+ else
26
+ Object.instance_eval { remove_const klass } if Object.const_defined?(klass)
27
+ Object.const_set(klass, Class.new).send(:include, model_type)
28
+ Object.const_get(klass).class_eval(&block) if block_given?
29
+
30
+ @spawned_models << klass.to_sym
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ 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,289 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: her5
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.1
5
+ platform: ruby
6
+ authors:
7
+ - Rémi Prévost
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-08-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.13'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-its
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fivemat
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: json
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.8'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.8'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activemodel
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 3.0.0
90
+ - - "<="
91
+ - !ruby/object:Gem::Version
92
+ version: 5.0.0
93
+ type: :runtime
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: 3.0.0
100
+ - - "<="
101
+ - !ruby/object:Gem::Version
102
+ version: 5.0.0
103
+ - !ruby/object:Gem::Dependency
104
+ name: activesupport
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 3.0.0
110
+ - - "<="
111
+ - !ruby/object:Gem::Version
112
+ version: 5.0.0
113
+ type: :runtime
114
+ prerelease: false
115
+ version_requirements: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: 3.0.0
120
+ - - "<="
121
+ - !ruby/object:Gem::Version
122
+ version: 5.0.0
123
+ - !ruby/object:Gem::Dependency
124
+ name: faraday
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0.8'
130
+ - - "<"
131
+ - !ruby/object:Gem::Version
132
+ version: '1.0'
133
+ type: :runtime
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0.8'
140
+ - - "<"
141
+ - !ruby/object:Gem::Version
142
+ version: '1.0'
143
+ - !ruby/object:Gem::Dependency
144
+ name: multi_json
145
+ requirement: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '1.7'
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - "~>"
155
+ - !ruby/object:Gem::Version
156
+ version: '1.7'
157
+ description: Her5 is an ORM that maps REST resources and collections to Ruby objects.
158
+ THIS IS ONLY AN UPDATE TO MAKE HER (UNMAINTAINED) WORK WITH RAILS 5 I LOVE YOU
159
+ email:
160
+ - remi@exomel.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
+ - gemfiles/Gemfile.activemodel-5.0.x
180
+ - her5.gemspec
181
+ - lib/her.rb
182
+ - lib/her/api.rb
183
+ - lib/her/collection.rb
184
+ - lib/her/errors.rb
185
+ - lib/her/json_api/model.rb
186
+ - lib/her/middleware.rb
187
+ - lib/her/middleware/accept_json.rb
188
+ - lib/her/middleware/first_level_parse_json.rb
189
+ - lib/her/middleware/json_api_parser.rb
190
+ - lib/her/middleware/parse_json.rb
191
+ - lib/her/middleware/second_level_parse_json.rb
192
+ - lib/her/model.rb
193
+ - lib/her/model/associations.rb
194
+ - lib/her/model/associations/association.rb
195
+ - lib/her/model/associations/association_proxy.rb
196
+ - lib/her/model/associations/belongs_to_association.rb
197
+ - lib/her/model/associations/has_many_association.rb
198
+ - lib/her/model/associations/has_one_association.rb
199
+ - lib/her/model/attributes.rb
200
+ - lib/her/model/base.rb
201
+ - lib/her/model/deprecated_methods.rb
202
+ - lib/her/model/http.rb
203
+ - lib/her/model/introspection.rb
204
+ - lib/her/model/nested_attributes.rb
205
+ - lib/her/model/orm.rb
206
+ - lib/her/model/parse.rb
207
+ - lib/her/model/paths.rb
208
+ - lib/her/model/relation.rb
209
+ - lib/her/version.rb
210
+ - spec/api_spec.rb
211
+ - spec/collection_spec.rb
212
+ - spec/json_api/model_spec.rb
213
+ - spec/middleware/accept_json_spec.rb
214
+ - spec/middleware/first_level_parse_json_spec.rb
215
+ - spec/middleware/json_api_parser_spec.rb
216
+ - spec/middleware/second_level_parse_json_spec.rb
217
+ - spec/model/associations/association_proxy_spec.rb
218
+ - spec/model/associations_spec.rb
219
+ - spec/model/attributes_spec.rb
220
+ - spec/model/callbacks_spec.rb
221
+ - spec/model/dirty_spec.rb
222
+ - spec/model/http_spec.rb
223
+ - spec/model/introspection_spec.rb
224
+ - spec/model/nested_attributes_spec.rb
225
+ - spec/model/orm_spec.rb
226
+ - spec/model/parse_spec.rb
227
+ - spec/model/paths_spec.rb
228
+ - spec/model/relation_spec.rb
229
+ - spec/model/validations_spec.rb
230
+ - spec/model_spec.rb
231
+ - spec/spec_helper.rb
232
+ - spec/support/extensions/array.rb
233
+ - spec/support/extensions/hash.rb
234
+ - spec/support/macros/her_macros.rb
235
+ - spec/support/macros/model_macros.rb
236
+ - spec/support/macros/request_macros.rb
237
+ homepage: http://her-rb.org
238
+ licenses:
239
+ - MIT
240
+ metadata: {}
241
+ post_install_message:
242
+ rdoc_options: []
243
+ require_paths:
244
+ - lib
245
+ required_ruby_version: !ruby/object:Gem::Requirement
246
+ requirements:
247
+ - - ">="
248
+ - !ruby/object:Gem::Version
249
+ version: '0'
250
+ required_rubygems_version: !ruby/object:Gem::Requirement
251
+ requirements:
252
+ - - ">="
253
+ - !ruby/object:Gem::Version
254
+ version: '0'
255
+ requirements: []
256
+ rubyforge_project:
257
+ rubygems_version: 2.6.6
258
+ signing_key:
259
+ specification_version: 4
260
+ summary: A simple Representational State Transfer-based Hypertext Transfer Protocol-powered
261
+ Object Relational Mapper. Her?
262
+ test_files:
263
+ - spec/api_spec.rb
264
+ - spec/collection_spec.rb
265
+ - spec/json_api/model_spec.rb
266
+ - spec/middleware/accept_json_spec.rb
267
+ - spec/middleware/first_level_parse_json_spec.rb
268
+ - spec/middleware/json_api_parser_spec.rb
269
+ - spec/middleware/second_level_parse_json_spec.rb
270
+ - spec/model/associations/association_proxy_spec.rb
271
+ - spec/model/associations_spec.rb
272
+ - spec/model/attributes_spec.rb
273
+ - spec/model/callbacks_spec.rb
274
+ - spec/model/dirty_spec.rb
275
+ - spec/model/http_spec.rb
276
+ - spec/model/introspection_spec.rb
277
+ - spec/model/nested_attributes_spec.rb
278
+ - spec/model/orm_spec.rb
279
+ - spec/model/parse_spec.rb
280
+ - spec/model/paths_spec.rb
281
+ - spec/model/relation_spec.rb
282
+ - spec/model/validations_spec.rb
283
+ - spec/model_spec.rb
284
+ - spec/spec_helper.rb
285
+ - spec/support/extensions/array.rb
286
+ - spec/support/extensions/hash.rb
287
+ - spec/support/macros/her_macros.rb
288
+ - spec/support/macros/model_macros.rb
289
+ - spec/support/macros/request_macros.rb