her 0.5.3 → 0.5.4
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.
- checksums.yaml +8 -8
- data/.gitignore +2 -2
- data/.rspec +1 -2
- data/.travis.yml +2 -2
- data/README.md +10 -16
- data/UPGRADE.md +4 -0
- data/examples/grape-and-her/.env.default +3 -0
- data/examples/grape-and-her/Procfile +2 -0
- data/examples/grape-and-her/README.md +27 -0
- data/examples/grape-and-her/api/Gemfile +11 -0
- data/examples/grape-and-her/api/Rakefile +14 -0
- data/examples/grape-and-her/api/app/api.rb +49 -0
- data/examples/grape-and-her/api/app/models/organization.rb +7 -0
- data/examples/grape-and-her/api/app/models/user.rb +9 -0
- data/examples/grape-and-her/api/app/views/organizations/_base.rabl +2 -0
- data/examples/grape-and-her/api/app/views/organizations/index.rabl +3 -0
- data/examples/grape-and-her/api/app/views/organizations/show.rabl +3 -0
- data/examples/grape-and-her/api/app/views/users/_base.rabl +8 -0
- data/examples/grape-and-her/api/app/views/users/index.rabl +3 -0
- data/examples/grape-and-her/api/app/views/users/show.rabl +3 -0
- data/examples/grape-and-her/api/config.ru +5 -0
- data/examples/grape-and-her/api/config/boot.rb +17 -0
- data/examples/grape-and-her/api/config/unicorn.rb +7 -0
- data/examples/grape-and-her/api/db/migrations/001_create_users.rb +11 -0
- data/examples/grape-and-her/api/db/migrations/002_create_organizations.rb +8 -0
- data/examples/grape-and-her/consumer/Gemfile +23 -0
- data/examples/grape-and-her/consumer/app/assets/stylesheets/application.scss +190 -0
- data/examples/grape-and-her/consumer/app/assets/stylesheets/reset.scss +53 -0
- data/examples/grape-and-her/consumer/app/consumer.rb +74 -0
- data/examples/grape-and-her/consumer/app/models/organization.rb +13 -0
- data/examples/grape-and-her/consumer/app/models/user.rb +13 -0
- data/examples/grape-and-her/consumer/app/views/index.haml +9 -0
- data/examples/grape-and-her/consumer/app/views/layout.haml +20 -0
- data/examples/grape-and-her/consumer/app/views/organizations/index.haml +25 -0
- data/examples/grape-and-her/consumer/app/views/organizations/show.haml +11 -0
- data/examples/grape-and-her/consumer/app/views/users/index.haml +33 -0
- data/examples/grape-and-her/consumer/app/views/users/show.haml +9 -0
- data/examples/grape-and-her/consumer/config.ru +20 -0
- data/examples/grape-and-her/consumer/config/boot.rb +30 -0
- data/examples/grape-and-her/consumer/config/unicorn.rb +7 -0
- data/examples/grape-and-her/consumer/lib/response_logger.rb +18 -0
- data/her.gemspec +2 -2
- data/lib/her/model.rb +22 -26
- data/lib/her/model/associations.rb +19 -19
- data/lib/her/model/attributes.rb +173 -0
- data/lib/her/model/base.rb +17 -0
- data/lib/her/model/http.rb +58 -242
- data/lib/her/model/introspection.rb +7 -8
- data/lib/her/model/nested_attributes.rb +3 -3
- data/lib/her/model/orm.rb +15 -205
- data/lib/her/model/parse.rb +86 -0
- data/lib/her/model/paths.rb +54 -14
- data/lib/her/version.rb +1 -1
- data/spec/model/attributes_spec.rb +139 -0
- data/spec/model/dirty_spec.rb +40 -0
- data/spec/model/introspection_spec.rb +5 -5
- data/spec/model/orm_spec.rb +14 -128
- data/spec/model/paths_spec.rb +26 -0
- data/spec/model/validations_spec.rb +17 -0
- data/spec/spec_helper.rb +7 -32
- data/spec/support/extensions/array.rb +5 -0
- data/spec/support/extensions/hash.rb +5 -0
- data/spec/support/macros/model_macros.rb +29 -0
- metadata +52 -15
- data/examples/twitter-oauth/Gemfile +0 -13
- data/examples/twitter-oauth/app.rb +0 -50
- data/examples/twitter-oauth/config.ru +0 -5
- data/examples/twitter-oauth/views/index.haml +0 -9
- data/examples/twitter-search/Gemfile +0 -12
- data/examples/twitter-search/app.rb +0 -55
- data/examples/twitter-search/config.ru +0 -5
- data/examples/twitter-search/views/index.haml +0 -9
data/spec/spec_helper.rb
CHANGED
@@ -1,46 +1,21 @@
|
|
1
1
|
$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
2
2
|
|
3
3
|
require "rspec"
|
4
|
-
require "mocha/api"
|
5
4
|
require "her"
|
6
5
|
|
6
|
+
# Require everything in `spec/support`
|
7
|
+
Dir[File.expand_path('../../spec/support/**/*.rb', __FILE__)].map(&method(:require))
|
8
|
+
|
7
9
|
RSpec.configure do |config|
|
8
|
-
config.
|
10
|
+
config.include Her::Testing::Macros::ModelMacros
|
9
11
|
|
10
12
|
config.before :each do
|
11
|
-
@
|
13
|
+
@spawned_models = []
|
12
14
|
end
|
13
15
|
|
14
16
|
config.after :each do
|
15
|
-
@
|
16
|
-
Object.instance_eval { remove_const
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
class Hash
|
22
|
-
def to_json; MultiJson.dump(self); end
|
23
|
-
end
|
24
|
-
|
25
|
-
class Array
|
26
|
-
def to_json; MultiJson.dump(self); end
|
27
|
-
end
|
28
|
-
|
29
|
-
def spawn_model(klass, &block)
|
30
|
-
if klass =~ /::/
|
31
|
-
base, submodel = klass.split(/::/).map{ |s| s.to_sym }
|
32
|
-
Object.const_set(base, Module.new) unless Object.const_defined?(base)
|
33
|
-
Object.const_get(base).module_eval do
|
34
|
-
remove_const submodel if constants.include?(submodel)
|
35
|
-
submodel = const_set(submodel, Class.new)
|
36
|
-
submodel.send(:include, Her::Model)
|
37
|
-
submodel.class_eval(&block) if block_given?
|
17
|
+
@spawned_models.each do |model|
|
18
|
+
Object.instance_eval { remove_const model } if Object.const_defined?(model)
|
38
19
|
end
|
39
|
-
@globals << base
|
40
|
-
else
|
41
|
-
Object.instance_eval { remove_const klass } if Object.const_defined?(klass)
|
42
|
-
Object.const_set(klass, Class.new).send(:include, Her::Model)
|
43
|
-
Object.const_get(klass).class_eval(&block) if block_given?
|
44
|
-
@globals << klass.to_sym
|
45
20
|
end
|
46
21
|
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.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
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: her
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rémi Prévost
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04-
|
11
|
+
date: 2013-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.13'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: fivemat
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '1.2'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '1.2'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: activemodel
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,14 +100,14 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - ~>
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '1.
|
103
|
+
version: '1.7'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - ~>
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '1.
|
110
|
+
version: '1.7'
|
111
111
|
description: Her is an ORM that maps REST resources and collections to Ruby objects
|
112
112
|
email:
|
113
113
|
- remi@exomel.com
|
@@ -124,14 +124,41 @@ files:
|
|
124
124
|
- README.md
|
125
125
|
- Rakefile
|
126
126
|
- UPGRADE.md
|
127
|
-
- examples/
|
128
|
-
- examples/
|
129
|
-
- examples/
|
130
|
-
- examples/
|
131
|
-
- examples/
|
132
|
-
- examples/
|
133
|
-
- examples/
|
134
|
-
- examples/
|
127
|
+
- examples/grape-and-her/.env.default
|
128
|
+
- examples/grape-and-her/Procfile
|
129
|
+
- examples/grape-and-her/README.md
|
130
|
+
- examples/grape-and-her/api/Gemfile
|
131
|
+
- examples/grape-and-her/api/Rakefile
|
132
|
+
- examples/grape-and-her/api/app/api.rb
|
133
|
+
- examples/grape-and-her/api/app/models/organization.rb
|
134
|
+
- examples/grape-and-her/api/app/models/user.rb
|
135
|
+
- examples/grape-and-her/api/app/views/organizations/_base.rabl
|
136
|
+
- examples/grape-and-her/api/app/views/organizations/index.rabl
|
137
|
+
- examples/grape-and-her/api/app/views/organizations/show.rabl
|
138
|
+
- examples/grape-and-her/api/app/views/users/_base.rabl
|
139
|
+
- examples/grape-and-her/api/app/views/users/index.rabl
|
140
|
+
- examples/grape-and-her/api/app/views/users/show.rabl
|
141
|
+
- examples/grape-and-her/api/config.ru
|
142
|
+
- examples/grape-and-her/api/config/boot.rb
|
143
|
+
- examples/grape-and-her/api/config/unicorn.rb
|
144
|
+
- examples/grape-and-her/api/db/migrations/001_create_users.rb
|
145
|
+
- examples/grape-and-her/api/db/migrations/002_create_organizations.rb
|
146
|
+
- examples/grape-and-her/consumer/Gemfile
|
147
|
+
- examples/grape-and-her/consumer/app/assets/stylesheets/application.scss
|
148
|
+
- examples/grape-and-her/consumer/app/assets/stylesheets/reset.scss
|
149
|
+
- examples/grape-and-her/consumer/app/consumer.rb
|
150
|
+
- examples/grape-and-her/consumer/app/models/organization.rb
|
151
|
+
- examples/grape-and-her/consumer/app/models/user.rb
|
152
|
+
- examples/grape-and-her/consumer/app/views/index.haml
|
153
|
+
- examples/grape-and-her/consumer/app/views/layout.haml
|
154
|
+
- examples/grape-and-her/consumer/app/views/organizations/index.haml
|
155
|
+
- examples/grape-and-her/consumer/app/views/organizations/show.haml
|
156
|
+
- examples/grape-and-her/consumer/app/views/users/index.haml
|
157
|
+
- examples/grape-and-her/consumer/app/views/users/show.haml
|
158
|
+
- examples/grape-and-her/consumer/config.ru
|
159
|
+
- examples/grape-and-her/consumer/config/boot.rb
|
160
|
+
- examples/grape-and-her/consumer/config/unicorn.rb
|
161
|
+
- examples/grape-and-her/consumer/lib/response_logger.rb
|
135
162
|
- her.gemspec
|
136
163
|
- lib/her.rb
|
137
164
|
- lib/her/api.rb
|
@@ -144,11 +171,13 @@ files:
|
|
144
171
|
- lib/her/middleware/second_level_parse_json.rb
|
145
172
|
- lib/her/model.rb
|
146
173
|
- lib/her/model/associations.rb
|
174
|
+
- lib/her/model/attributes.rb
|
147
175
|
- lib/her/model/base.rb
|
148
176
|
- lib/her/model/http.rb
|
149
177
|
- lib/her/model/introspection.rb
|
150
178
|
- lib/her/model/nested_attributes.rb
|
151
179
|
- lib/her/model/orm.rb
|
180
|
+
- lib/her/model/parse.rb
|
152
181
|
- lib/her/model/paths.rb
|
153
182
|
- lib/her/version.rb
|
154
183
|
- spec/api_spec.rb
|
@@ -157,6 +186,7 @@ files:
|
|
157
186
|
- spec/middleware/first_level_parse_json_spec.rb
|
158
187
|
- spec/middleware/second_level_parse_json_spec.rb
|
159
188
|
- spec/model/associations_spec.rb
|
189
|
+
- spec/model/attributes_spec.rb
|
160
190
|
- spec/model/callbacks_spec.rb
|
161
191
|
- spec/model/dirty_spec.rb
|
162
192
|
- spec/model/http_spec.rb
|
@@ -167,6 +197,9 @@ files:
|
|
167
197
|
- spec/model/validations_spec.rb
|
168
198
|
- spec/model_spec.rb
|
169
199
|
- spec/spec_helper.rb
|
200
|
+
- spec/support/extensions/array.rb
|
201
|
+
- spec/support/extensions/hash.rb
|
202
|
+
- spec/support/macros/model_macros.rb
|
170
203
|
homepage: http://remiprev.github.com/her
|
171
204
|
licenses:
|
172
205
|
- MIT
|
@@ -199,6 +232,7 @@ test_files:
|
|
199
232
|
- spec/middleware/first_level_parse_json_spec.rb
|
200
233
|
- spec/middleware/second_level_parse_json_spec.rb
|
201
234
|
- spec/model/associations_spec.rb
|
235
|
+
- spec/model/attributes_spec.rb
|
202
236
|
- spec/model/callbacks_spec.rb
|
203
237
|
- spec/model/dirty_spec.rb
|
204
238
|
- spec/model/http_spec.rb
|
@@ -209,3 +243,6 @@ test_files:
|
|
209
243
|
- spec/model/validations_spec.rb
|
210
244
|
- spec/model_spec.rb
|
211
245
|
- spec/spec_helper.rb
|
246
|
+
- spec/support/extensions/array.rb
|
247
|
+
- spec/support/extensions/hash.rb
|
248
|
+
- spec/support/macros/model_macros.rb
|
@@ -1,50 +0,0 @@
|
|
1
|
-
# Create custom parser
|
2
|
-
class TwitterParser < Faraday::Response::Middleware
|
3
|
-
def on_complete(env)
|
4
|
-
json = MultiJson.load(env[:body], :symbolize_keys => true)
|
5
|
-
errors = [json.delete(:error)]
|
6
|
-
env[:body] = {
|
7
|
-
:data => json,
|
8
|
-
:errors => errors,
|
9
|
-
:metadata => {},
|
10
|
-
}
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
# See https://dev.twitter.com/apps
|
15
|
-
TWITTER_CREDENTIALS = {
|
16
|
-
:consumer_key => "",
|
17
|
-
:consumer_secret => "",
|
18
|
-
:token => "",
|
19
|
-
:token_secret => ""
|
20
|
-
}
|
21
|
-
|
22
|
-
# Initialize API
|
23
|
-
Her::API.setup :url => "https://api.twitter.com/1/" do |builder|
|
24
|
-
builder.use FaradayMiddleware::OAuth, TWITTER_CREDENTIALS
|
25
|
-
builder.use Faraday::Request::UrlEncoded
|
26
|
-
builder.use TwitterParser
|
27
|
-
builder.use Faraday::Adapter::NetHttp
|
28
|
-
end
|
29
|
-
|
30
|
-
# Define classes
|
31
|
-
class Tweet
|
32
|
-
include Her::Model
|
33
|
-
|
34
|
-
def self.timeline
|
35
|
-
get "/statuses/home_timeline.json"
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.mentions
|
39
|
-
get "/statuses/mentions.json"
|
40
|
-
end
|
41
|
-
|
42
|
-
def username
|
43
|
-
user[:screen_name]
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
get "/" do
|
48
|
-
@tweets = Tweet.mentions
|
49
|
-
haml :index
|
50
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
# Create custom parser
|
2
|
-
class TwitterSearchParser < Faraday::Response::Middleware
|
3
|
-
METADATA_KEYS = [:completed_in, :max_id, :max_id_str, :next_page, :page, :query, :refresh_url, :results_per_page, :since_id, :since_id_str]
|
4
|
-
|
5
|
-
def on_complete(env)
|
6
|
-
json = MultiJson.load(env[:body], :symbolize_keys => true)
|
7
|
-
data = json.delete(:results)
|
8
|
-
errors = [json.delete(:error)].compact
|
9
|
-
env[:body] = {
|
10
|
-
:data => data,
|
11
|
-
:errors => errors,
|
12
|
-
:metadata => json
|
13
|
-
}
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class MyCache < Hash
|
18
|
-
def read(key)
|
19
|
-
if cached = self[key]
|
20
|
-
Marshal.load(cached)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def write(key, data)
|
25
|
-
self[key] = Marshal.dump(data)
|
26
|
-
end
|
27
|
-
|
28
|
-
def fetch(key)
|
29
|
-
read(key) || yield.tap { |data| write(key, data) }
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
$cache = MyCache.new
|
34
|
-
|
35
|
-
# Initialize API
|
36
|
-
Her::API.setup :url => "http://search.twitter.com" do |connection|
|
37
|
-
connection.use Faraday::Request::UrlEncoded
|
38
|
-
connection.use FaradayMiddleware::Caching, $cache
|
39
|
-
connection.use TwitterSearchParser
|
40
|
-
connection.use Faraday::Adapter::NetHttp
|
41
|
-
end
|
42
|
-
|
43
|
-
# Define classes
|
44
|
-
class Tweet
|
45
|
-
include Her::Model
|
46
|
-
|
47
|
-
def self.search(query, attrs={})
|
48
|
-
get("/search.json", attrs.merge(:q => query))
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
get "/" do
|
53
|
-
@tweets = Tweet.search("justin bieber", :rpp => 30)
|
54
|
-
haml :index
|
55
|
-
end
|