cooler 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cooler.gemspec
4
+ gemspec
5
+
6
+ gem 'rake'
data/Gemfile.lock ADDED
@@ -0,0 +1,38 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cooler (0.0.1)
5
+ activesupport (~> 3.2.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ZenTest (4.8.3)
11
+ activesupport (3.2.9)
12
+ i18n (~> 0.6)
13
+ multi_json (~> 1.0)
14
+ autotest (4.4.6)
15
+ ZenTest (>= 4.4.1)
16
+ diff-lcs (1.1.3)
17
+ i18n (0.6.1)
18
+ multi_json (1.4.0)
19
+ rake (10.0.2)
20
+ rr (1.0.4)
21
+ rspec (2.12.0)
22
+ rspec-core (~> 2.12.0)
23
+ rspec-expectations (~> 2.12.0)
24
+ rspec-mocks (~> 2.12.0)
25
+ rspec-core (2.12.1)
26
+ rspec-expectations (2.12.0)
27
+ diff-lcs (~> 1.1.3)
28
+ rspec-mocks (2.12.0)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ autotest (~> 4.4.0)
35
+ cooler!
36
+ rake
37
+ rr (~> 1.0.0)
38
+ rspec (~> 2.12.0)
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright © 2012 MoHound
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the “Software”), to deal
5
+ in the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Cooler
2
+
3
+ A mini ORM, agnostic to key value store databases.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new do |t|
5
+ t.rspec_opts = ["--color", "-c", "-f progress", "-r ./spec/spec_helper.rb"]
6
+ t.pattern = 'spec/**/*_spec.rb'
7
+ end
8
+
9
+ task :default => :spec
data/cooler.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cooler/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "cooler"
8
+ gem.version = Cooler::VERSION
9
+ gem.authors = ["Ivan Valdes"]
10
+ gem.email = ["ivan@mohound.com"]
11
+ gem.description = %q{Mini ORM, agnostic to key value store databases}
12
+ gem.summary = %q{Mini ORM, agnostic to key value store databases}
13
+ gem.homepage = "http://github.com/mohound/coolio"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+
21
+ gem.add_dependency('activesupport', '~> 3.2.0')
22
+ gem.add_development_dependency('rspec', '~> 2.12.0')
23
+ gem.add_development_dependency('rr', '~> 1.0.0')
24
+ gem.add_development_dependency('autotest', '~> 4.4.0')
25
+ end
@@ -0,0 +1,52 @@
1
+ module Cooler
2
+ # Defines functions to get and set keys from the database.
3
+ class Adapter
4
+ class << self
5
+ # Gets the get block.
6
+ attr_reader :get
7
+
8
+ # Gets the set block.
9
+ attr_reader :set
10
+ end
11
+
12
+ # Sets the block that handles getting a key.
13
+ #
14
+ # block - The block that receives as argument the String with the
15
+ # queried key. It should return a Hash.
16
+ #
17
+ # Examples
18
+ #
19
+ # Cooler::Adapter.get = ->(key) { JSON.parse(redis.get(key)) }
20
+ # Cooler::Adapter.get = Proc.new do |key|
21
+ # begin
22
+ # couchbase[key]
23
+ # rescue Couchbase::NotFound
24
+ # puts 'uh oh'
25
+ # end
26
+ # end
27
+ #
28
+ # Returns nothing.
29
+ def self.get=(block)
30
+ raise 'Argument must be a block' unless Proc === block
31
+ @get = block
32
+ end
33
+
34
+ # Sets the block that handles storing a key.
35
+ #
36
+ # block - The block that receives as argument the String with the
37
+ # queried key, and serialized object.
38
+ #
39
+ # Examples
40
+ #
41
+ # Cooler::Adapter.set = ->(key, value) { couchbase[key] = value }
42
+ # Cooler::Adapter.get = lambda do |key, value|
43
+ # redis.set(key, value.to_json)
44
+ # end
45
+ #
46
+ # Returns nothing.
47
+ def self.set=(block)
48
+ raise 'Argument must be a block' unless Proc === block
49
+ @set = block
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,5 @@
1
+ module Cooler
2
+ class NotFound < NameError
3
+ def http_status; 404 end
4
+ end
5
+ end
@@ -0,0 +1,187 @@
1
+ module Cooler
2
+ # Defines the base methods to define a model class.
3
+ module Model
4
+ # Called after including in some class. For more information, read:
5
+ # http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-included
6
+ #
7
+ # Returns nothing.
8
+ def self.included(base)
9
+ base.send :extend, ClassMethods
10
+ base.instance_variable_set :@default_values, {}
11
+ end
12
+
13
+ # Sets the key for an instance.
14
+ attr_writer :_key
15
+
16
+ # Defines class methods for a Model.
17
+ module ClassMethods
18
+ # Called after the class is inherited. It will copy its default
19
+ # values, so subclass can use them too. For more informaiton, read:
20
+ # http://www.ruby-doc.org/core-1.9.3/Class.html#method-i-inherited
21
+ #
22
+ # Returns nothing.
23
+ def inherited(subclass)
24
+ subclass.instance_variable_set :@default_values, default_values.dup
25
+ subclass.instance_variable_set :@key_block, @key_block.dup
26
+ end
27
+
28
+ # Gets the default values.
29
+ attr_reader :default_values
30
+
31
+ # Define the key for documents of this instance.
32
+ #
33
+ # block - A block that contains how to build the key for an instance.
34
+ # It receives the instance as an argument. This block should
35
+ # return a String.
36
+ #
37
+ # Examples
38
+ #
39
+ # key { |click| ['click', click.app_key, click.tracking].join('_') }
40
+ # key do |install|
41
+ # ['install', install.app_key, install.finger_print].join('_')
42
+ # end
43
+ #
44
+ # Returns nothing if passing a block, the block if not passing it.
45
+ def key(&block)
46
+ if block_given?
47
+ @key_block = block
48
+ end
49
+ @key_block || Proc.new { }
50
+ end
51
+
52
+ # Defines a default value for an attribute.
53
+ #
54
+ # attr - The String or Symbol attribute name, to add the default value.
55
+ # value - The Object to use as default value (optional).
56
+ # block - A block to be run as default value (optional).
57
+ #
58
+ # Examples
59
+ #
60
+ # default :clicks, []
61
+ # default :seconds, -> { Time.now.seconds }
62
+ # default :app_key, lambda { |install| install.app.key }
63
+ #
64
+ # Returns nothing.
65
+ # Raises an exception if attribute does not exist.
66
+ def default(attr, value, &block)
67
+ unless instance_methods.include?("#{attr}=".to_sym) &&
68
+ instance_methods.include?(attr.to_sym)
69
+ raise "Unknown attribute #{attr}"
70
+ end
71
+ @default_values[attr.to_sym] = value || block
72
+ end
73
+
74
+ # Gets an Object from Couchbase, and construct an instance by its
75
+ # key. In order to use Hash version, the class should define a key.
76
+ #
77
+ # key - The String that contains the key to query the object. Or the
78
+ # Hash with the value defined in the key to search. See examples
79
+ # for extra reference.
80
+ #
81
+ # Examples
82
+ #
83
+ # class Install
84
+ # key { |i| "install_#{i.app_key}" }
85
+ # end
86
+ #
87
+ # install = Install.get(app_key: '123')
88
+ # # => Gets object with key: 'install_123'
89
+ #
90
+ # install = Install.get('install_123')
91
+ # # => Gets object with key: 'install_123'
92
+ #
93
+ # Return a Model instance or nothing if not found.
94
+ def get(key)
95
+ if Hash === key
96
+ raise 'Key not defined' unless @key_block
97
+ key = @key_block.(OpenStruct.new(key))
98
+ end
99
+ result = Cooler::Adapter.get.(key) and new(key, result)
100
+ end
101
+
102
+ # Gets an Object from Couchbase, and construct an instance by its
103
+ # key. Raises an error if not found.
104
+ #
105
+ # key - The String that contains the key to query the object.
106
+ #
107
+ # Return a Model instance.
108
+ # Raises Cooler::NotFound if not found. Compatible with
109
+ # Sinatra::NotFound;
110
+ # http://www.sinatrarb.com/intro.html#Not%20Found
111
+ def get!(key)
112
+ get(key) || raise(Cooler::NotFound)
113
+ end
114
+
115
+ # Initializes a new instance, and saves it at the same time.
116
+ #
117
+ # attrs - May contain at the first position, the String key for the
118
+ # document owner of the instance. Then it a Hash with its
119
+ # attributes (default: {}).
120
+ #
121
+ # Returns the Object new instance.
122
+ def create(*attrs)
123
+ instance = new(*attrs)
124
+ instance.save
125
+ instance
126
+ end
127
+ end
128
+
129
+ # Initialize a Base.
130
+ #
131
+ # attrs - May contain at the first position, the String key for the
132
+ # document owner of the instance. Then it a Hash with its
133
+ # attributes (default: {}).
134
+ def initialize(*attrs)
135
+ @_key = attrs.shift if String === attrs.first
136
+ self.attributes = attrs.shift || {}
137
+ set_default_values
138
+ end
139
+
140
+ # The key for the document.
141
+ #
142
+ # Returns the String key for this document.
143
+ def _key
144
+ @_key || self.class.key.(self)
145
+ end
146
+
147
+ # Assigns attributes from the passed Hash. Only setteable attributes
148
+ # will be assigned.
149
+ #
150
+ # attributes - The Hash with the attributes to assign.
151
+ #
152
+ # Returns nothing.
153
+ def attributes=(attributes)
154
+ return unless Hash === attributes
155
+ attributes = attributes.symbolize_keys
156
+ attributes.each { |k, v| send("#{k}=", v) if respond_to?("#{k}=") }
157
+ end
158
+
159
+ # Provides basic serialization of the instance, it includes only
160
+ # its Struct attributes, and not those defined from attr_accessor.
161
+ #
162
+ # Returns the serialized Hash.
163
+ def serializable_hash
164
+ Hash[*each_pair.map { |k, v| [k, v] }.flatten]
165
+ end
166
+
167
+ # Saves persisted attributes to the database.
168
+ #
169
+ # Returns true if saved, false if not.
170
+ def save
171
+ Cooler::Adapter.set.(_key, serializable_hash)
172
+ !Cooler::Adapter.get.(_key).nil?
173
+ end
174
+
175
+ private
176
+ def set_default_values
177
+ self.class.default_values.each do |key, value|
178
+ if send(key).nil?
179
+ if Proc === value
180
+ value = value.arity.zero? ? value.() : value.(self)
181
+ end
182
+ send("#{key}=", value)
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,3 @@
1
+ module Cooler
2
+ VERSION = "0.0.1"
3
+ end
data/lib/cooler.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'cooler/version'
2
+ require 'cooler/errors'
3
+ require 'active_support/core_ext/hash/keys'
4
+ require 'ostruct'
5
+
6
+ module Cooler
7
+ autoload :Model, 'cooler/model.rb'
8
+ autoload :Adapter, 'cooler/adapter.rb'
9
+ end
@@ -0,0 +1,234 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cooler::Model do
4
+ describe 'initialize' do
5
+ it 'should return an empty instance if not passing arguments' do
6
+ instance = TestModel.new
7
+ instance.foo.should be_nil
8
+ instance.bar.should be_nil
9
+ end
10
+
11
+ it 'should populate attributes if passing a Hash' do
12
+ instance = TestModel.new(foo: 'bar', nil: true)
13
+ instance.foo.should == 'bar'
14
+ end
15
+
16
+ it 'should set its key' do
17
+ instance = TestModel.new('keykey', foo: 'bar')
18
+ instance._key.should == 'keykey'
19
+ instance.foo.should == 'bar'
20
+ end
21
+
22
+ it 'should not modify passed attributes' do
23
+ attrs = { 'foo' => 'bar' }
24
+ instance = TestModel.new(attrs)
25
+ attrs.should have_key('foo')
26
+ end
27
+ end
28
+
29
+ describe 'key' do
30
+ it 'should set its key to a new format' do
31
+ TestModelNewKey.key { |i| "foo_bar_#{i.foo}" }
32
+ t = TestModelNewKey.new(foo: 'baaar')
33
+ t._key.should == 'foo_bar_baaar'
34
+ end
35
+ end
36
+
37
+ describe '_key' do
38
+ it 'should be the passed key' do
39
+ instance = TestModel.new('keykey')
40
+ instance._key.should == 'keykey'
41
+ end
42
+
43
+ it 'should be the constructed key if not passing one' do
44
+ instance = TestModel.new
45
+ instance._key.should == 'test_'
46
+ instance.foo = 'bacon'
47
+ instance._key.should == 'test_bacon'
48
+ end
49
+
50
+ it 'should return nil if no key block registered' do
51
+ expect { TestModelNoKey.new._key.should be_nil }.to_not raise_error
52
+ end
53
+
54
+ it 'should be able to se its key' do
55
+ instance = TestModel.new
56
+ instance._key = 'CHUNKY'
57
+ instance._key.should == 'CHUNKY'
58
+ end
59
+ end
60
+
61
+ describe 'get' do
62
+ it "should return the instance if Adapter's get block returns something" do
63
+ mock(Cooler::Adapter).get do
64
+ ->(key) { key.should == 'test_bacon' && { foo: 'bar' } }
65
+ end
66
+ instance = TestModel.get('test_bacon')
67
+ instance.should be_an_instance_of(TestModel)
68
+ instance._key.should == 'test_bacon'
69
+ instance.foo.should == 'bar'
70
+ end
71
+
72
+ it 'should be nil if no results' do
73
+ mock(Cooler::Adapter).get { ->(k) { nil } }
74
+ TestModel.get('test_bacon').should be_nil
75
+ end
76
+
77
+ it 'should raise an error if no key defined and passing a Hash' do
78
+ expect { TestModelNoKey.get(foo: 'bar') }.to raise_error
79
+ end
80
+
81
+ it 'should get the instance if passing a Hash' do
82
+ mock(Cooler::Adapter).get do
83
+ ->(key) { key.should == 'test_chunky' && { foo: 'bar' } }
84
+ end
85
+ instance = TestModel.get(foo: 'chunky')
86
+ instance.should be_an_instance_of(TestModel)
87
+ instance._key.should == 'test_chunky'
88
+ instance.foo.should == 'bar'
89
+ end
90
+ end
91
+
92
+ describe 'get!' do
93
+ it 'should return the instance if found by Adapter' do
94
+ mock(Cooler::Adapter).get do
95
+ ->(k) { k.should == 'test_bacon' && { foo: 'bar' } }
96
+ end
97
+ instance = TestModel.get!('test_bacon')
98
+ instance.should be_an_instance_of(TestModel)
99
+ instance._key.should == 'test_bacon'
100
+ instance.foo.should == 'bar'
101
+ end
102
+
103
+ it 'should raise an exception if no results' do
104
+ mock(Cooler::Adapter).get { ->(k) { nil } }
105
+ expect { TestModel.get!('test_bacon') }.to raise_error(Cooler::NotFound)
106
+ end
107
+ end
108
+
109
+ describe 'attributes=' do
110
+ before(:each) do
111
+ @instance = TestModelUsingAttrAccessors.new
112
+ end
113
+
114
+ it 'should not do anything if not passing a Hash' do
115
+ expect { @instance.attributes = [] }.to_not raise_error
116
+ end
117
+
118
+ it 'should assign class properties' do
119
+ @instance.attributes = {'foo' => 'bar', chunky: 'BACON'}
120
+ @instance.foo.should == 'bar'
121
+ @instance.chunky.should == 'BACON'
122
+ end
123
+
124
+ it 'should assign attributes' do
125
+ @instance.attributes = {'bar' => 'foo', bacon: 'CHUNKY'}
126
+ @instance.bar.should == 'foo'
127
+ @instance.bacon.should == 'CHUNKY'
128
+ end
129
+
130
+ it 'should not modify passed attributes' do
131
+ @instance.attributes = attrs = { 'foo' => 'bar' }
132
+ attrs.should have_key('foo')
133
+ end
134
+ end
135
+
136
+ describe 'serializable_hash' do
137
+ it 'should only include class properties' do
138
+ instance = TestModelUsingAttrAccessors.new(foo: 'bar', bacon: 'CHUNKY')
139
+ instance.serializable_hash.keys.should_not include(:bacon)
140
+ instance.serializable_hash.keys.should include(:foo)
141
+ instance.serializable_hash[:foo].should == 'bar'
142
+ end
143
+ end
144
+
145
+ context 'using attribute accessors' do
146
+ it 'should assign the passed attribute when creating a new instance' do
147
+ instance = TestModelUsingAttrAccessors.new(foo: 'chunky', bar: 'bacon')
148
+ instance.foo.should == 'chunky'
149
+ instance.bar.should == 'bacon'
150
+ end
151
+ end
152
+
153
+ describe 'default' do
154
+ it 'should raise an exception if no such attribute' do
155
+ expect { TestModelWithDefaultValues.default :chunky }.
156
+ to raise_error
157
+ end
158
+
159
+ it 'should set the default value using an Object' do
160
+ TestModelWithDefaultValues.default :one, []
161
+ TestModelWithDefaultValues.default :four, []
162
+ instance = TestModelWithDefaultValues.new
163
+ instance.one.should == []
164
+ instance.four.should == []
165
+ end
166
+
167
+ it 'should set the default value using a block' do
168
+ TestModelWithDefaultValues.default :two, -> { 3*3 }
169
+ TestModelWithDefaultValues.default :four, lambda { 4*4 }
170
+ TestModelWithDefaultValues.default :five, Proc.new { 5*5 }
171
+ instance = TestModelWithDefaultValues.new
172
+ instance.two.should == 9
173
+ instance.four.should == 16
174
+ instance.five.should == 25
175
+ end
176
+
177
+ it 'should set the default value using a block passing the instance' do
178
+ TestModelWithDefaultValues.default :three, ->(i) { i.one }
179
+ TestModelWithDefaultValues.default :six, lambda { |i| i.two }
180
+ TestModelWithDefaultValues.default :seven, Proc.new { |i| i.four }
181
+ instance = TestModelWithDefaultValues.new(one: '1', two: '2', four: '4')
182
+ instance.three.should == '1'
183
+ instance.six.should == '2'
184
+ instance.seven.should == '4'
185
+ end
186
+
187
+ it 'should not set the default value if it already has another value' do
188
+ TestModelWithDefaultValues.default :eight, 8
189
+ TestModelWithDefaultValues.new(eight: '10').eight.should == '10'
190
+ end
191
+ end
192
+
193
+ describe 'save' do
194
+ it "should call Adapter's set to save its attributes and fail" do
195
+ instance = TestModelForSave.new(foo: 'bar', bar: 'BAR')
196
+ mock(Cooler::Adapter).set do
197
+ ->(key, value) do
198
+ key.should == 'Chunky_BAR'
199
+ value.should == { foo: 'bar' }
200
+ end
201
+ end
202
+ mock(Cooler::Adapter).get { ->(k) { nil } }
203
+ instance.save.should be_false
204
+ end
205
+
206
+ it 'should call Adapter to save its attributes and succed' do
207
+ instance = TestModelForSave.new(foo: 'bar', bar: 'BAR')
208
+ mock(Cooler::Adapter).set do
209
+ ->(key, value) do
210
+ key.should == 'Chunky_BAR'
211
+ value.should == { foo: 'bar' }
212
+ end
213
+ end
214
+ mock(Cooler::Adapter).get { ->(k) { k.should == 'Chunky_BAR' } }
215
+ instance.save.should be_true
216
+ end
217
+ end
218
+
219
+ describe 'create' do
220
+ it 'should call Adapter to save its attributes' do
221
+ mock(Cooler::Adapter).set do
222
+ ->(key, value) do
223
+ key.should == 'Chunky_BAR'
224
+ value.should == { foo: 'bar' }
225
+ end
226
+ end
227
+ mock(Cooler::Adapter).get do
228
+ ->(k) { k.should == 'Chunky_BAR' && { foo: 'bar' } }
229
+ end
230
+ instance = TestModelForSave.create(foo: 'bar', bar: 'BAR')
231
+ instance.should be_an_instance_of(TestModelForSave)
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,12 @@
1
+ dir = File.dirname(File.expand_path(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(dir, '..', 'lib'))
3
+ $LOAD_PATH.unshift(dir)
4
+
5
+ require 'cooler'
6
+
7
+ Dir[File.join(dir, 'support', '**', '*.rb')].each { |f| require f }
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :rr
11
+ config.order = 'random'
12
+ end
@@ -0,0 +1,36 @@
1
+ class TestModel < Struct.new(:foo, :bar)
2
+ include Cooler::Model
3
+ key { |i| "test_#{i.foo}" }
4
+ end
5
+
6
+ class TestModelNewKey < Struct.new(:foo, :bar)
7
+ include Cooler::Model
8
+ end
9
+
10
+ class TestModelDuplicateAttrs < Struct.new(:foo, :bar)
11
+ include Cooler::Model
12
+ end
13
+
14
+ class TestModelNoAttrs
15
+ include Cooler::Model
16
+ end
17
+
18
+ class TestModelNoKey
19
+ include Cooler::Model
20
+ end
21
+
22
+ class TestModelUsingAttrAccessors < Struct.new(:foo, :chunky)
23
+ include Cooler::Model
24
+ attr_accessor :bar, :bacon
25
+ end
26
+
27
+ class TestModelWithDefaultValues < Struct.new(:one, :two, :three)
28
+ include Cooler::Model
29
+ attr_accessor :four, :five, :six, :seven, :eight, :nine
30
+ end
31
+
32
+ class TestModelForSave < Struct.new(:foo)
33
+ include Cooler::Model
34
+ attr_accessor :bar
35
+ key { |i| "Chunky_#{i.bar}" }
36
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cooler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ivan Valdes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.12.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.12.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: rr
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: autotest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 4.4.0
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 4.4.0
78
+ description: Mini ORM, agnostic to key value store databases
79
+ email:
80
+ - ivan@mohound.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - Gemfile
87
+ - Gemfile.lock
88
+ - LICENSE
89
+ - README.md
90
+ - Rakefile
91
+ - cooler.gemspec
92
+ - lib/cooler.rb
93
+ - lib/cooler/adapter.rb
94
+ - lib/cooler/errors.rb
95
+ - lib/cooler/model.rb
96
+ - lib/cooler/version.rb
97
+ - spec/cooler/model_spec.rb
98
+ - spec/spec_helper.rb
99
+ - spec/support/test_models.rb
100
+ homepage: http://github.com/mohound/coolio
101
+ licenses: []
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ segments:
113
+ - 0
114
+ hash: 2911025146145919076
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ segments:
122
+ - 0
123
+ hash: 2911025146145919076
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 1.8.23
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: Mini ORM, agnostic to key value store databases
130
+ test_files:
131
+ - spec/cooler/model_spec.rb
132
+ - spec/spec_helper.rb
133
+ - spec/support/test_models.rb