cooler 0.0.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.
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