her 0.2.1 → 0.2.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Her
2
2
 
3
- Her is an ORM (Object Relational Mapper) that maps REST resources to Ruby objects. It is designed to build applications that are powered by a RESTful API and no database.
3
+ Her is an ORM (Object Relational Mapper) that maps REST resources to Ruby objects. It is designed to build applications that are powered by a RESTful API instead of a database.
4
4
 
5
5
  [![Build Status](https://secure.travis-ci.org/remiprev/her.png)](http://travis-ci.org/remiprev/her)
6
6
 
@@ -56,7 +56,7 @@ User.find(1)
56
56
 
57
57
  ## Middleware
58
58
 
59
- Since Her relies on [Faraday](https://github.com/technoweenie/faraday) to send HTTP requests, you can add additional middleware to handle requests and responses.
59
+ Since Her relies on [Faraday](https://github.com/technoweenie/faraday) to send HTTP requests, you can add additional middleware to handle requests and responses. Using a block in the `setup` call, you have access to Faraday’s `builder` object and are able to customize the middleware stack used on each request and response.
60
60
 
61
61
  ### Authentication
62
62
 
@@ -64,14 +64,19 @@ Her doesn’t support any kind of authentication. However, it’s very easy to i
64
64
 
65
65
  ```ruby
66
66
  class MyAuthentication < Faraday::Middleware
67
+ def initialize(app, options={})
68
+ @options = options
69
+ end
70
+
67
71
  def call(env)
68
- env[:request_headers]["X-API-Token"] = "bb2b2dd75413d32c1ac421d39e95b978d1819ff611f68fc2fdd5c8b9c7331192"
72
+ env[:request_headers]["X-API-Token"] = @options[:token] if @options.include?(:token)
69
73
  @app.call(env)
70
74
  end
71
75
  end
72
76
 
73
77
  Her::API.setup :base_uri => "https://api.example.com" do |builder|
74
- builder.use MyAuthentication
78
+ # This token could be stored in the client session
79
+ builder.use MyAuthentication, :token => "bb2b2dd75413d32c1ac421d39e95b978d1819ff611f68fc2fdd5c8b9c7331192"
75
80
  end
76
81
  ```
77
82
 
@@ -91,14 +96,14 @@ By default, Her handles JSON data. It expects the resource/collection data to be
91
96
  [{ "id" : 1, "name" : "Tobias Fünke" }]
92
97
  ```
93
98
 
94
- However, you can define your own parsing method, using a response middleware. The middleware is expected to set `env[:body]` to a hash with three keys: `data`, `errors` and `metadata`. The following code enables parsing JSON data and treating the result as first-level properties. Using the builder block, we then replace the default parser.
99
+ However, you can define your own parsing method, using a response middleware. The middleware is expected to set `env[:body]` to a hash with three keys: `data`, `errors` and `metadata`. The following code enables parsing JSON data and treating the result as first-level properties. Using the builder block, we then replace the default parser with our custom parser.
95
100
 
96
101
  ```ruby
97
102
  class MyCustomParser < Faraday::Response::Middleware
98
103
  def on_complete(env)
99
104
  json = MultiJson.load(env[:body], :symbolize_keys => true)
100
105
  env[:body] = {
101
- :data => json[:data],
106
+ :data => json[:result],
102
107
  :errors => json[:errors],
103
108
  :metadata => json[:metadata]
104
109
  }
@@ -106,10 +111,10 @@ class MyCustomParser < Faraday::Response::Middleware
106
111
  end
107
112
 
108
113
  Her::API.setup :base_uri => "https://api.example.com" do |builder|
109
- builder.delete Her::Middleware::DefaultParseJSON
110
- builder.use MyCustomParser
114
+ # We use the `swap` method to replace Her’s default parser middleware
115
+ builder.swap Her::Middleware::DefaultParseJSON, MyCustomParser
111
116
  end
112
- # User.find(1) will now expect "https://api.example.com/users/1" to return something like '{ "data" => { "id": 1, "name": "Tobias Fünke" }, "errors" => [] }'
117
+ # User.find(1) will now expect "https://api.example.com/users/1" to return something like '{ "result" => { "id": 1, "name": "Tobias Fünke" }, "errors" => [] }'
113
118
  ```
114
119
 
115
120
  ### OAuth
@@ -136,7 +141,8 @@ TWITTER_CREDENTIALS = {
136
141
  }
137
142
 
138
143
  Her::API.setup :base_uri => "https://api.twitter.com/1/" do |builder|
139
- builder.use FaradayMiddleware::OAuth, TWITTER_CREDENTIALS
144
+ # We need to insert the middleware at the beginning of the stack (hence the `insert 0`)
145
+ builder.insert 0, FaradayMiddleware::OAuth, TWITTER_CREDENTIALS
140
146
  end
141
147
 
142
148
  class Tweet
@@ -161,12 +167,26 @@ In your Ruby code:
161
167
 
162
168
  ```ruby
163
169
  class MyCache
164
- def write(key, value); end
165
- def read(key); end
166
- def fetch(key, &block); end
170
+ def initialize
171
+ @cache = {}
172
+ end
173
+
174
+ def write(key, value)
175
+ @cache[key] = value
176
+ end
177
+
178
+ def read(key)
179
+ @cache[key]
180
+ end
181
+
182
+ def fetch(key, &block)
183
+ return value = read(key) if value.nil?
184
+ write key, yield
185
+ end
167
186
  end
168
187
 
169
188
  # A cache system must respond to `#write`, `#read` and `#fetch`.
189
+ # We should be probably using something like Memcached here, not a global object
170
190
  $cache = MyCache.new
171
191
 
172
192
  Her::API.setup :base_uri => "https://api.example.com" do |builder|
@@ -178,12 +198,15 @@ class User
178
198
  end
179
199
 
180
200
  @user = User.find(1)
181
- @user = User.find(1) # This request will be fetched from the cache
201
+ # GET /users/1
202
+
203
+ @user = User.find(1)
204
+ # This request will be fetched from the cache
182
205
  ```
183
206
 
184
207
  ## Relationships
185
208
 
186
- You can define `has_many`, `has_one` and `belongs_to` relationships in your models. The relationship data is handled in two different ways. When parsing a resource from JSON data, if there’s a relationship data included, it will be used to create new Ruby objects.
209
+ You can define `has_many`, `has_one` and `belongs_to` relationships in your models. The relationship data is handled in two different ways. If there’s relationship data when parsing a resource, it will be used to create new Ruby objects.
187
210
 
188
211
  If no relationship data was included when parsing a resource, calling a method with the same name as the relationship will fetch the data (providing there’s an HTTP request available for it in the API).
189
212
 
@@ -210,7 +233,7 @@ class Organization
210
233
  end
211
234
  ```
212
235
 
213
- If there’s relationship data in the resource, no extra HTTP request is made when calling the `#comments` method and an array of resources are returned:
236
+ If there’s relationship data in the resource, no extra HTTP request is made when calling the `#comments` method and an array of resources is returned:
214
237
 
215
238
  ```ruby
216
239
  @user = User.find(1) # { :data => { :id => 1, :name => "George Michael Bluth", :comments => [{ :id => 1, :text => "Foo" }, { :id => 2, :text => "Bar" }], :role => { :id => 1, :name => "Admin" }, :organization => { :id => 2, :name => "Bluth Company" } }}
@@ -226,21 +249,21 @@ If there’s no relationship data in the resource, an extra HTTP request (to `GE
226
249
  @user.comments # => [#<Comment id=1>, #<Comment id=2>] fetched from /users/1/comments
227
250
  ```
228
251
 
229
- For `has_one` relationship, an extra HTTP request (to `GET /users/1/role`) is made when calling the `#role` method:
252
+ For `has_one` relationships, an extra HTTP request (to `GET /users/1/role`) is made when calling the `#role` method:
230
253
 
231
254
  ```ruby
232
255
  @user = User.find(1) # { :data => { :id => 1, :name => "George Michael Bluth" }}
233
256
  @user.role # => #<Role id=1> fetched from /users/1/role
234
257
  ```
235
258
 
236
- For `belongs_to` relationship, an extra HTTP request (to `GET /organizations/2`) is made when calling the `#organization` method:
259
+ For `belongs_to` relationships, an extra HTTP request (to `GET /organizations/2`) is made when calling the `#organization` method:
237
260
 
238
261
  ```ruby
239
262
  @user = User.find(1) # { :data => { :id => 1, :name => "George Michael Bluth", :organization_id => 2 }}
240
263
  @user.organization # => #<Organization id=2> fetched from /organizations/2
241
264
  ```
242
265
 
243
- However, subsequent calls to `#comments` or `#role` will not trigger the extra HTTP request.
266
+ However, subsequent calls to `#comments`, `#role` and `#organization` will not trigger extra HTTP requests as the data has already been fetched.
244
267
 
245
268
  ## Hooks
246
269
 
@@ -260,8 +283,6 @@ end
260
283
  # POST /users&fullname=Tobias+Fünke&internal_id=42
261
284
  ```
262
285
 
263
- In the future, adding hooks to all models will be possible, as well as defining and triggering your own hooks (eg. for your custom requests).
264
-
265
286
  ## Custom requests
266
287
 
267
288
  You can easily define custom requests for your models using `custom_get`, `custom_post`, etc.
@@ -343,12 +364,12 @@ end
343
364
  # GET /hello_users/1
344
365
  ```
345
366
 
346
- You can include custom variables in your paths:
367
+ You can also include custom variables in your paths:
347
368
 
348
369
  ```ruby
349
370
  class User
350
371
  include Her::Model
351
- collection_path "/organizations/:organization_id/users/:id"
372
+ collection_path "/organizations/:organization_id/users"
352
373
  end
353
374
 
354
375
  @user = User.find(1, :_organization_id => 2)
@@ -356,6 +377,10 @@ end
356
377
 
357
378
  @user = User.all(:_organization_id => 2)
358
379
  # GET /organizations/2/users
380
+
381
+ @user = User.new(:fullname => "Tobias Fünke", :organization_id => 2)
382
+ @user.save
383
+ # POST /organizations/2/users
359
384
  ```
360
385
 
361
386
  ## Multiple APIs
@@ -394,7 +419,7 @@ Category.all
394
419
  ## Things to be done
395
420
 
396
421
  * Better error handling
397
- * Better documentation
422
+ * Better API documentation (using YARD)
398
423
 
399
424
  ## Contributors
400
425
 
@@ -403,6 +428,7 @@ Feel free to contribute and submit issues/pull requests [on GitHub](https://gith
403
428
  * [@jfcixmedia](https://github.com/jfcixmedia)
404
429
  * [@EtienneLem](https://github.com/EtienneLem)
405
430
  * [@rafaelss](https://github.com/rafaelss)
431
+ * [@tysontate](https://github.com/tysontate)
406
432
 
407
433
  Take a look at the `spec` folder before you do, and make sure `bundle exec rake spec` passes after your modifications :)
408
434
 
@@ -1,5 +1,5 @@
1
1
  # Create custom parser
2
- class TwitterSearchParser < Faraday::Response::Middleware
2
+ class TwitterParser < Faraday::Response::Middleware
3
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
4
 
5
5
  def on_complete(env)
@@ -21,7 +21,10 @@ TWITTER_CREDENTIALS = {
21
21
  }
22
22
 
23
23
  # Initialize API
24
- Her::API.setup :base_uri => "https://api.twitter.com/1/", :parse_middleware => TwitterSearchParser, :add_middleware => [FaradayMiddleware::OAuth => TWITTER_CREDENTIALS]
24
+ Her::API.setup :base_uri => "https://api.twitter.com/1/" do |builder|
25
+ builder.insert 0, FaradayMiddleware::OAuth, TWITTER_CREDENTIALS
26
+ builder.swap Her::Middleware::DefaultParseJSON, TwitterParser
27
+ end
25
28
 
26
29
  # Define classes
27
30
  class Tweet
@@ -31,12 +34,16 @@ class Tweet
31
34
  get "/statuses/home_timeline.json"
32
35
  end
33
36
 
37
+ def self.mentions
38
+ get "/statuses/mentions.json"
39
+ end
40
+
34
41
  def username
35
42
  user[:screen_name]
36
43
  end
37
44
  end
38
45
 
39
46
  get "/" do
40
- @tweets = Tweet.timeline
47
+ @tweets = Tweet.mentions
41
48
  haml :index
42
49
  end
@@ -3,6 +3,7 @@ source :rubygems
3
3
  gem "sinatra"
4
4
  gem "haml"
5
5
  gem "thin", :require => false
6
+ gem "faraday_middleware"
6
7
 
7
8
  gem "her", :path => File.join(File.dirname(__FILE__),"../..")
8
9
 
@@ -12,8 +12,32 @@ class TwitterSearchParser < Faraday::Response::Middleware
12
12
  end
13
13
  end
14
14
 
15
+ class MyCache
16
+ def initialize
17
+ @cache = {}
18
+ end
19
+
20
+ def write(key, value)
21
+ @cache[key] = value
22
+ end
23
+
24
+ def read(key)
25
+ @cache[key]
26
+ end
27
+
28
+ def fetch(key, &block)
29
+ return value = read(key) if value.nil?
30
+ write key, yield
31
+ end
32
+ end
33
+
34
+ $cache = MyCache.new
35
+
15
36
  # Initialize API
16
- Her::API.setup :base_uri => "http://search.twitter.com", :parse_middleware => TwitterSearchParser
37
+ Her::API.setup :base_uri => "http://search.twitter.com" do |builder|
38
+ builder.swap Her::Middleware::FirstLevelParseJSON, TwitterSearchParser
39
+ builder.use FaradayMiddleware::Caching, $cache
40
+ end
17
41
 
18
42
  # Define classes
19
43
  class Tweet
@@ -3,14 +3,12 @@ module Her
3
3
  # so it knows where to make those requests. In Rails, this is usually done in `config/initializers/her.rb`:
4
4
  class API
5
5
  # @private
6
- attr_reader :base_uri, :middleware
6
+ attr_reader :base_uri, :middleware, :connection
7
7
 
8
8
  # Setup a default API connection. Accepted arguments and options are the same as {API#setup}.
9
- def self.setup(attrs={}) # {{{
9
+ def self.setup(attrs={}, &block) # {{{
10
10
  @@default_api = new
11
- connection = @@default_api.setup(attrs)
12
- yield connection.builder if block_given?
13
- connection
11
+ @@default_api.setup(attrs, &block)
14
12
  end # }}}
15
13
 
16
14
  # Setup the API connection.
@@ -60,19 +58,12 @@ module Her
60
58
 
61
59
  @middleware.flatten!
62
60
  middleware = @middleware
63
- @connection = Faraday.new(:url => @base_uri) do |builder|
64
- middleware.each do |item|
65
- klass = item.is_a?(Hash) ? item.keys.first : item
66
- args = item.is_a?(Hash) ? item.values.first : nil
67
- if args
68
- builder.use klass, args
69
- else
70
- builder.use klass
71
- end
61
+ @connection = Faraday.new(:url => @base_uri) do |connection|
62
+ middleware.each do |klass|
63
+ connection.use klass
72
64
  end
65
+ yield connection.builder if block_given?
73
66
  end
74
- yield @connection.builder if block_given?
75
- @connection
76
67
  end # }}}
77
68
 
78
69
  # Define a custom parsing procedure. The procedure is passed the response object and is
@@ -35,8 +35,9 @@ module Her
35
35
  extend Her::Model::Paths
36
36
 
37
37
  # Define default settings
38
- collection_path "/#{self.to_s.downcase.pluralize}"
39
- resource_path "/#{self.to_s.downcase.pluralize}/:id"
38
+ base_path = self.name.split("::").last.downcase.pluralize
39
+ collection_path "/#{base_path}"
40
+ resource_path "/#{base_path}/:id"
40
41
  uses_api Her::API.default_api
41
42
  end
42
43
  end
@@ -1,3 +1,3 @@
1
1
  module Her
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -16,20 +16,52 @@ describe Her::API do
16
16
  @api.setup :base_uri => "https://api.example.com"
17
17
  @api.base_uri.should == "https://api.example.com"
18
18
  end # }}}
19
+
20
+ it "sets custom middleware with #use" do # {{{
21
+ class Foo; end;
22
+ class Bar; end;
23
+
24
+ @api = Her::API.new
25
+ @api.setup :base_uri => "https://api.example.com" do |builder|
26
+ builder.use Foo
27
+ builder.use Bar
28
+ end
29
+ @api.connection.builder.handlers.should == [Her::Middleware::FirstLevelParseJSON, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp, Foo, Bar]
30
+ end # }}}
31
+
32
+ it "sets custom middleware with #insert" do # {{{
33
+ class Foo; end;
34
+ class Bar; end;
35
+
36
+ @api = Her::API.new
37
+ @api.setup :base_uri => "https://api.example.com" do |builder|
38
+ builder.use Foo
39
+ builder.insert 0, Bar
40
+ end
41
+ @api.connection.builder.handlers.should == [Bar, Her::Middleware::FirstLevelParseJSON, Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp, Foo]
42
+ end # }}}
43
+
44
+ it "delete some default middleware" do # {{{
45
+ @api = Her::API.new
46
+ @api.setup :base_uri => "https://api.example.com" do |builder|
47
+ builder.delete Faraday::Request::UrlEncoded
48
+ end
49
+ @api.connection.builder.handlers.should == [Her::Middleware::FirstLevelParseJSON, Faraday::Adapter::NetHttp]
50
+ end # }}}
19
51
  end
20
52
 
21
53
  describe "#request" do
22
54
  it "makes HTTP requests" do # {{{
23
55
  FakeWeb.register_uri(:get, "https://api.example.com/foo", :body => "Foo, it is.")
24
56
 
25
- class Foo < Faraday::Response::Middleware
57
+ class SimpleParser < Faraday::Response::Middleware
26
58
  def on_complete(env)
27
59
  env[:body] = { :data => env[:body] }
28
60
  end
29
61
  end
30
62
 
31
63
  @api = Her::API.new
32
- @api.setup :base_uri => "https://api.example.com", :parse_middleware => Foo
64
+ @api.setup :base_uri => "https://api.example.com", :parse_middleware => SimpleParser
33
65
  parsed_data = @api.request(:_method => :get, :_path => "/foo")
34
66
  parsed_data[:data] == "Foo, it is."
35
67
  end # }}}
@@ -63,8 +95,7 @@ describe Her::API do
63
95
 
64
96
  @api = Her::API.new
65
97
  @api.setup :base_uri => "https://api.example.com" do |connection|
66
- connection.delete Her::Middleware::DefaultParseJSON
67
- connection.use CustomParser
98
+ connection.swap Her::Middleware::DefaultParseJSON, CustomParser
68
99
  end
69
100
  parsed_data = @api.request(:_method => :get, :_path => "users/1")
70
101
  parsed_data[:data].should == { :id => 1, :name => "George Michael Bluth" }
@@ -3,38 +3,53 @@ require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
3
 
4
4
  describe Her::Model::Paths do
5
5
  context "building request paths" do
6
- before do # {{{
7
- spawn_model :User
8
- end # }}}
9
-
10
- describe "#build_request_path" do
11
- it "builds paths with defaults" do # {{{
12
- User.build_request_path(id: "foo").should == "/users/foo"
13
- User.build_request_path.should == "/users"
14
- end # }}}
15
-
16
- it "builds paths with custom collection path" do # {{{
17
- User.collection_path "/utilisateurs"
18
- User.build_request_path(id: "foo").should == "/utilisateurs/foo"
19
- User.build_request_path.should == "/utilisateurs"
6
+ context "simple model" do
7
+ before do # {{{
8
+ spawn_model :User
20
9
  end # }}}
21
10
 
22
- it "builds paths with custom collection path with multiple variables" do # {{{
23
- User.collection_path "/organizations/:organization_id/utilisateurs"
24
- User.build_request_path(:id => "foo", :_organization_id => "acme").should == "/organizations/acme/utilisateurs/foo"
25
- User.build_request_path(:_organization_id => "acme").should == "/organizations/acme/utilisateurs"
26
- end # }}}
11
+ describe "#build_request_path" do
12
+ it "builds paths with defaults" do # {{{
13
+ User.build_request_path(id: "foo").should == "/users/foo"
14
+ User.build_request_path.should == "/users"
15
+ end # }}}
16
+
17
+ it "builds paths with custom collection path" do # {{{
18
+ User.collection_path "/utilisateurs"
19
+ User.build_request_path(id: "foo").should == "/utilisateurs/foo"
20
+ User.build_request_path.should == "/utilisateurs"
21
+ end # }}}
22
+
23
+ it "builds paths with custom collection path with multiple variables" do # {{{
24
+ User.collection_path "/organizations/:organization_id/utilisateurs"
25
+ User.build_request_path(:id => "foo", :_organization_id => "acme").should == "/organizations/acme/utilisateurs/foo"
26
+ User.build_request_path(:_organization_id => "acme").should == "/organizations/acme/utilisateurs"
27
+ end # }}}
28
+
29
+ it "builds paths with custom item path" do # {{{
30
+ User.resource_path "/utilisateurs/:id"
31
+ User.build_request_path(id: "foo").should == "/utilisateurs/foo"
32
+ User.build_request_path.should == "/users"
33
+ end # }}}
34
+
35
+ it "raises exceptions when building a path without required custom variables" do # {{{
36
+ User.collection_path "/organizations/:organization_id/utilisateurs"
37
+ expect { User.build_request_path(:id => "foo") }.should raise_error(Her::Errors::PathError)
38
+ end # }}}
39
+ end
40
+ end
27
41
 
28
- it "builds paths with custom item path" do # {{{
29
- User.resource_path "/utilisateurs/:id"
30
- User.build_request_path(id: "foo").should == "/utilisateurs/foo"
31
- User.build_request_path.should == "/users"
42
+ context "nested model" do
43
+ before do # {{{
44
+ spawn_submodel :Base, :User
32
45
  end # }}}
33
46
 
34
- it "raises exceptions when building a path without required custom variables" do # {{{
35
- User.collection_path "/organizations/:organization_id/utilisateurs"
36
- expect { User.build_request_path(:id => "foo") }.should raise_error(Her::Errors::PathError)
37
- end # }}}
47
+ describe "#build_request_path" do
48
+ it "builds paths with defaults" do # {{{
49
+ Base::User.build_request_path(id: "foo").should == "/users/foo"
50
+ Base::User.build_request_path.should == "/users"
51
+ end # }}}
52
+ end
38
53
  end
39
54
  end
40
55
 
@@ -19,8 +19,13 @@ class Array
19
19
  def to_json; MultiJson.dump(self); end
20
20
  end
21
21
 
22
- def spawn_model(klass, attrs={}, &block)
22
+ def spawn_model(klass, &block)
23
23
  Object.instance_eval { remove_const klass } if Object.const_defined?(klass)
24
24
  Object.const_set(klass, Class.new).send(:include, Her::Model)
25
25
  Object.const_get(klass).class_eval(&block) if block_given?
26
26
  end
27
+
28
+ def spawn_submodel(mod, klass)
29
+ Object.instance_eval { remove_const mod } if Object.const_defined?(mod)
30
+ Object.const_set(mod, Module.new).const_set(klass, Class.new).send(:include, Her::Model)
31
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: her
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-30 00:00:00.000000000Z
12
+ date: 2012-05-01 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -281,7 +281,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
281
281
  version: '0'
282
282
  segments:
283
283
  - 0
284
- hash: 453966821948784652
284
+ hash: -2369072493348034064
285
285
  required_rubygems_version: !ruby/object:Gem::Requirement
286
286
  none: false
287
287
  requirements:
@@ -290,7 +290,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
290
290
  version: '0'
291
291
  segments:
292
292
  - 0
293
- hash: 453966821948784652
293
+ hash: -2369072493348034064
294
294
  requirements: []
295
295
  rubyforge_project:
296
296
  rubygems_version: 1.8.18