squares 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 09592e711ca540e1b0fb97bb9e841af69cb34175
4
+ data.tar.gz: e3d626d74d1184b164f5ba4f90b1cf1c7567610e
5
+ SHA512:
6
+ metadata.gz: 60351a2a9e968f992a4c578e2853729a090d15e3c4ec0d9d8d153d99686eb7b81081c4808ad3485d35ed71938ea3130b0079ec9f3d2bfc6ac888881128d4e3df
7
+ data.tar.gz: fc865c89c8de7e4fbbb5f6ffc0ca5e344a772848b29456f2cbc7618ede6c6e601e2c38951a2b088fad7aed3e166b76262510d1808961fe5cfe6788ae019e6ee0
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .ruby-version
16
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in squares.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Joel Helbling
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # Squares \[\*\]
2
+
3
+ A lightweight ORM backed by any hash-like storage. Hand-crafted from a solid piece of pure
4
+ aircraft-grade Ruby and drawing distilled awesomeness from atmospheric pollutants, its only
5
+ dependency is you.
6
+
7
+ ## Installation Blah, Blah, Blah
8
+
9
+ _I swear, this part of the README just rolled right out of `bundle gem squares`._
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'squares'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install squares
24
+
25
+ _And yeah, I did enjoy typing `bundle gem squares`. It sounds like something to
26
+ eat. Now I'm hungry._
27
+
28
+ ## Usage
29
+
30
+ _Because you are going to use it._
31
+
32
+ ```ruby
33
+ require 'squares'
34
+ ```
35
+
36
+ ### Write Models
37
+
38
+ _How come they never write back?_
39
+
40
+ ```ruby
41
+ class Person < Squares::Base
42
+ properties :real_name, :age
43
+ end
44
+ ```
45
+
46
+ You can also provide a default value if you switch to the `property` variant:
47
+
48
+ ```ruby
49
+ class Person < Squares::Base
50
+ property :eye_color, default: 'brown'
51
+ end
52
+ ```
53
+
54
+ ### Bootstrapping
55
+
56
+ _A funny word for "setup & configure". Bootstrapping. Bootstrapping. See? Funny._
57
+
58
+ Now you can bootstrap `;)` your model to a hash-like storage object like so:
59
+
60
+ ```ruby
61
+ people_storage = Redis::Namespace.new(
62
+ Person.underscore_name,
63
+ :redis => $redis_connection )
64
+
65
+ Person.store = people_storage
66
+ ```
67
+
68
+ Or setup a bunch of 'em like this:
69
+
70
+ ```ruby
71
+ [Person, Place, Thing].each do |model|
72
+ model.store = LevelDB::DB.new("./tmp/#{model.underscore_name}")
73
+ end
74
+ ```
75
+
76
+ ...or if you just want to use a plain ole in-memory hash:
77
+
78
+ ```ruby
79
+ tom_sellecks_mustache = {}
80
+ Soup.store = tom_sellecks_mustache
81
+ ```
82
+
83
+ Squares actually defaults the store to an empty hash, which means if you're ok
84
+ with in-memory, transient storage (e.g. when writing tests, etc.) you don't have
85
+ to do any config-- er, bootstrapping `;)` at all!
86
+
87
+ ### Onward To The Fun
88
+
89
+ Squares does not auto-generate an `:id` for each new object --you'll do that
90
+ and it will be used as the "key" in the hash storage. In the following example,
91
+ we're creating a new `Person` and using 'spiderman' as the key:
92
+
93
+ ```ruby
94
+ pete = Person.new('spiderman', real_name: 'Peter Parker', age: 17)
95
+ # ^^^ key ^^^ ^^^^^^^^^^^ properties ^^^^^^^^^^^
96
+ pete.save
97
+
98
+ Person.has_key? 'spiderman' #=> true
99
+ pete.id #=> 'spiderman'
100
+ ```
101
+
102
+ When we retrieve an object, it returns an instance of that model:
103
+
104
+ ```ruby
105
+ wallcrawler = Person['spiderman']
106
+ wallcrawler = Person.find 'spiderman' #=> same, shmame.
107
+ wallcrawler.id #=> 'spiderman'
108
+ wallcrawler.real_name #=> 'Peter Parker'
109
+ wallcrawler.class #=> Person
110
+ ```
111
+
112
+ Of course, for some types of storage, the model object has to be serialized and
113
+ de-serialized when it's stored and retrieved. Squares uses `Marshal.dump` and
114
+ `Marshal.restore` to do that. This means that custom marshalling can be added
115
+ to your models (see [documentation on ruby Marshal][marshal]).
116
+
117
+ ### Even More Fun
118
+
119
+ You can use the ActiveRecord-esque `.where` method with a block to retrieve records
120
+ for which the block returns true:
121
+
122
+ ```ruby
123
+ Person.where { |p| p.left_handed == true } #=> all the lefties
124
+ ```
125
+
126
+ The `.where` method is actually just an alias of `.select`...which means, yeah!
127
+ Squares are enumerable, yay!
128
+
129
+ ```ruby
130
+ Person.map(&:name) #=> an array containing all the names
131
+ ```
132
+
133
+ ### What It Doesn't Do
134
+
135
+ Much like Wolverine, Squares doesn't do relationships. You'll have to
136
+ maintain those in your code. If you have an issue with that, leave me
137
+ an issue, and I'll think about what that might mean.
138
+
139
+ Squares neither knows nor cares about the type or contents of your model
140
+ instance's properties. This has consequences.
141
+
142
+ First, anything you stash had darn well better be marshal-able, or there
143
+ will be blood on the roller-rink. Or at least errors. Yeah, I've made
144
+ sure there won't be blood (you're welcome), but watch out for errors.
145
+ If you run into problems, refer to the [documentation on ruby Marshal][marshal].
146
+
147
+ Second, there is no magic-fu for stuff like generating question methods
148
+ for boolean properties. For example, it doesn't make a `#left_handed?` method
149
+ out of your `property :left_handed`). But hey, you know what you can
150
+ do? Behold:
151
+
152
+ ```ruby
153
+ class Person
154
+ property :awesome?, default: true #=> What?! is that a "?"
155
+ end
156
+ ```
157
+
158
+ Ok, don't interrupt me, I'm selling here...
159
+
160
+ ```ruby
161
+ you = Person.new
162
+ you.awesome? #=> true
163
+ ```
164
+
165
+ Of course, Squares doesn't mind how you use `#awesome?` and the corresponding `#awesome=` methods:
166
+
167
+ ```ruby
168
+ you.awesome = 'yak hair'
169
+ you.awesome? #=> 'yak hair'
170
+ ```
171
+
172
+ or
173
+
174
+ ```ruby
175
+ you.awesome = nil
176
+ you.awesome? #=> nil
177
+ ```
178
+
179
+ But hey, who cares, as long as yak hair is truthy?
180
+
181
+ [marshal]:http://www.ruby-doc.org/core-2.1.5/Marshal.html
182
+
183
+ ## Contributing
184
+
185
+ 1. Fork it ( https://github.com/joelhelbling/squares/fork )
186
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
187
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
188
+ 4. Push to the branch (`git push origin my-new-feature`)
189
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
@@ -0,0 +1,144 @@
1
+ module Squares
2
+ class Base
3
+ attr_accessor :id
4
+
5
+ def initialize *args
6
+ apply *args
7
+ end
8
+
9
+ def save
10
+ store[@id] = Marshal.dump self
11
+ nil
12
+ end
13
+
14
+ def == other
15
+ @id == other.id && properties_equal(other)
16
+ end
17
+
18
+ def properties
19
+ self.class.properties
20
+ end
21
+
22
+ private
23
+
24
+ def properties_equal other
25
+ ! properties.detect do |property|
26
+ self.send(property) != other.send(property)
27
+ end
28
+ end
29
+
30
+ def apply *args
31
+ @id, value_hash = *args
32
+ self.class.properties.each do |property|
33
+ value = args.last.to_h[property] || self.class.defaults[property]
34
+ # self.class.method_for(property)
35
+ self.send "#{property.to_s.gsub(/\?$/,'')}=".to_sym, value
36
+ end
37
+ end
38
+
39
+ def store
40
+ self.class.store
41
+ end
42
+
43
+ #############
44
+ class << self
45
+ include Enumerable
46
+
47
+ def [] id
48
+ if item = store[id]
49
+ Marshal.restore item
50
+ end
51
+ end
52
+ alias_method :find, :[]
53
+
54
+ def []= *args
55
+ id, instance = *args
56
+ if instance.class == self
57
+ instance.id = id
58
+ instance.save
59
+ elsif instance.respond_to?(:to_h)
60
+ self.new(id, instance).save
61
+ else
62
+ raise ArgumentError.new(<<-ERR)
63
+ You must provide an instance of #{self.name} or at least
64
+ something which responds to #to_h"
65
+ ERR
66
+ end
67
+ end
68
+ alias_method :create, :[]=
69
+
70
+ def has_key? key
71
+ store.has_key? key
72
+ end
73
+ alias_method :key?, :has_key?
74
+ alias_method :member?, :has_key?
75
+ alias_method :includes?, :has_key?
76
+
77
+ def each &block
78
+ store.values.map{ |i| Marshal.restore i }.each &block
79
+ end
80
+ alias_method :where, :select
81
+
82
+ def property prop, opts
83
+ @_properties ||= []
84
+ @_properties << prop
85
+ uniquify_properties
86
+ if prop.to_s.match(/\?$/)
87
+ define_method prop do
88
+ instance_variable_get "@#{self.class.instance_var_for prop}"
89
+ end
90
+ define_method prop.to_s.gsub(/\?$/, '=') do |v|
91
+ instance_variable_set "@#{self.class.instance_var_for prop}", v
92
+ end
93
+ else
94
+ attr_accessor prop
95
+ end
96
+ if default = opts[:default]
97
+ defaults[prop] = default
98
+ end
99
+ end
100
+
101
+ def properties *props
102
+ props.each do |prop|
103
+ property prop, {}
104
+ end
105
+ @_properties
106
+ end
107
+
108
+ def defaults
109
+ @_defaults ||= {}
110
+ end
111
+
112
+ def underscore_name
113
+ self.name.
114
+ gsub(/::/, '/').
115
+ gsub(/([^\/])([A-Z])/, '\1_\2').
116
+ downcase
117
+ end
118
+
119
+ def store= storage
120
+ @store = storage
121
+ end
122
+
123
+ def store
124
+ @store ||= {}
125
+ end
126
+
127
+ def instance_var_for property
128
+ if property.to_s.match(/\?$/)
129
+ "#{property.to_s.gsub(/\?$/,'')}__question__".to_sym
130
+ else
131
+ property
132
+ end
133
+ end
134
+
135
+ private
136
+
137
+ def uniquify_properties
138
+ @_properties = @_properties.uniq.compact
139
+ end
140
+
141
+ end
142
+ end
143
+ end
144
+
@@ -0,0 +1,3 @@
1
+ module Squares
2
+ VERSION = "0.2.0"
3
+ end
data/lib/squares.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'squares/version'
2
+ require 'squares/base'
3
+
4
+ module Squares
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,5 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ require 'pry'
4
+ require 'rspec-given'
5
+ require 'squares'
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+ require 'squares/base'
3
+
4
+ module Marvel
5
+ class SuperHero < Squares::Base
6
+ properties :real_name, :special_powers
7
+ end
8
+ class Villain < Squares::Base
9
+ properties :vehicle, :lair
10
+ property :really_evil?, default: true
11
+ end
12
+ end
13
+
14
+ module Squares
15
+ describe Base do
16
+ Given(:storage) { {} }
17
+ Given(:test_class) { Marvel::SuperHero }
18
+ Given { test_class.store = storage }
19
+
20
+ Given(:id) { 'Captain America' }
21
+ Given(:name) { 'Steve Rogers' }
22
+ Given(:powers) { ['super strength', 'strategy', 'leadership'] }
23
+ When(:hero) { test_class.new id, real_name: name, special_powers: powers }
24
+
25
+ describe 'class' do
26
+
27
+ describe '.underscore_name' do
28
+ Then { test_class.underscore_name == 'marvel/super_hero' }
29
+ end
30
+
31
+ describe '.properties' do
32
+ Then { test_class.properties == [:real_name, :special_powers] }
33
+ end
34
+
35
+ describe '.use_storage' do
36
+ Given(:storage) { {attack: :fwoosh } }
37
+ When { test_class.store = storage }
38
+ Then { test_class.store == storage }
39
+ end
40
+
41
+ describe '.[]' do
42
+ Given { storage[id] = Marshal.dump hero }
43
+ When(:recovered_hero) { Marvel::SuperHero['Captain America'] }
44
+ Then { recovered_hero.class == Marvel::SuperHero }
45
+ Then { recovered_hero.id == 'Captain America' }
46
+ Then { recovered_hero.real_name == 'Steve Rogers' }
47
+ Then { recovered_hero.special_powers.include? 'leadership' }
48
+ end
49
+
50
+ describe '.[]= creates & stores a new instance' do
51
+ Given(:id) { 'Spiderman' }
52
+ Given(:name) { 'Peter Parker' }
53
+ Given(:powers) { [ 'wall crawling', 'web spinning', 'cracking wise' ] }
54
+
55
+ context 'whether created with an instance' do
56
+ Given(:instance) { test_class.new(id, real_name: name, special_powers: powers) }
57
+
58
+ When { test_class[id] = instance }
59
+ When(:spidey) { Marshal.restore storage.values.first }
60
+
61
+ Then { spidey.class == Marvel::SuperHero }
62
+ Then { spidey.id == 'Spiderman' }
63
+ Then { spidey.real_name == 'Peter Parker' }
64
+ Then { spidey.special_powers.include? 'cracking wise' }
65
+ end
66
+
67
+ context 'or creating using a hash' do
68
+ When { test_class[id] = { real_name: name, special_powers: powers } }
69
+
70
+ When(:spidey) { Marshal.restore storage.values.first }
71
+ Then { spidey.class == Marvel::SuperHero }
72
+ Then { spidey.id == 'Spiderman' }
73
+ Then { spidey.real_name == 'Peter Parker' }
74
+ Then { spidey.special_powers.include? 'cracking wise' }
75
+ end
76
+
77
+ context 'but creating with an invalid object' do
78
+ Then { expect{ test_class[id] = 12 } .to raise_error(ArgumentError) }
79
+ end
80
+ end
81
+
82
+ describe '.has_key?' do
83
+ Given { hero.save }
84
+ Then { expect(test_class).to have_key(id) }
85
+ Then { expect(test_class).to be_key(id) }
86
+ Then { expect(test_class).to be_member(id) }
87
+ Then { expect(test_class).to be_includes(id) }
88
+ end
89
+
90
+ describe 'more cool stuff' do
91
+ Given do
92
+ Marvel::SuperHero['Superman'] = { real_name: 'Clark Kent', special_powers: ['flying'] }
93
+ Marvel::SuperHero['Hulk'] = { real_name: 'Bruce Banner', special_powers: ['smash'] }
94
+ Marvel::SuperHero['Batman'] = { real_name: 'Bruce Wayne', special_powers: ['stuff'] }
95
+ end
96
+
97
+ describe '.where' do
98
+ When(:result) { Marvel::SuperHero.where { |h| h.real_name =~ /^Bruce/ } }
99
+ Then { result.count == 2 }
100
+ end
101
+
102
+ describe 'models are enumerable!' do
103
+ When(:result) { Marvel::SuperHero.map(&:special_powers).flatten }
104
+ Then { result == %w[ flying smash stuff ] }
105
+ end
106
+ end
107
+
108
+ end
109
+
110
+ describe 'instances' do
111
+ describe '#{{property}}' do
112
+ Then { hero.id == id }
113
+ Then { hero.real_name == name }
114
+ Then { hero.special_powers == powers }
115
+ end
116
+
117
+ describe '#save' do
118
+ When { hero.save }
119
+ When(:frozen_hero) { Marshal.restore storage.values.first }
120
+ Then { storage.keys.first == 'Captain America' }
121
+ Then { frozen_hero.real_name == 'Steve Rogers' }
122
+ Then { frozen_hero.class == Marvel::SuperHero }
123
+ end
124
+
125
+ describe '#==' do
126
+ Given(:hero1) { test_class.new id, real_name: name, special_powers: powers }
127
+ Given(:hero2) { test_class.new id, real_name: name, special_powers: powers }
128
+
129
+ context 'when they are equal' do
130
+ Then { hero1 == hero2 }
131
+ end
132
+
133
+ context 'when some property(ies) are not equal' do
134
+ Given { hero2.real_name = 'Steven Rogers' }
135
+ Then { hero1 != hero2 }
136
+ end
137
+ end
138
+
139
+ describe 'default values' do
140
+ Given do
141
+ class Marvel::SuperHero < Squares::Base
142
+ property :hair_color, default: 'black'
143
+ end
144
+ end
145
+ When(:hero) { test_class.new id, real_name: name }
146
+ Then { hero.special_powers == nil }
147
+ Then { hero.hair_color == 'black' }
148
+ Then { Marvel::SuperHero.defaults == { hair_color: 'black' } }
149
+ end
150
+
151
+ end
152
+
153
+ describe "models' properties don't bleed into each other" do
154
+ When(:villain) { Marvel::Villain.new 'Dr. Octopus', vehicle: 'jets', lair: 'abandonned sewer' }
155
+ Then { villain.class == Marvel::Villain }
156
+ Then { Marvel::Villain.properties == [:vehicle, :lair, :really_evil?] }
157
+ Then { villain.properties == [:vehicle, :lair, :really_evil?] }
158
+ Then { expect(villain).to_not respond_to(:hair_color) }
159
+ Then { expect(villain).to respond_to(:really_evil?) }
160
+ Then { expect(villain).to respond_to(:really_evil=) }
161
+ Then { expect(villain).to be_really_evil }
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Squares do
4
+ it 'has a version number' do
5
+ expect(Squares::VERSION).not_to be nil
6
+ end
7
+ end
data/squares.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'squares/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "squares"
8
+ spec.version = Squares::VERSION
9
+ spec.authors = ["Joel Helbling"]
10
+ spec.email = ["joel@joelhelbling.com"]
11
+ spec.summary = %q{Lightweight ORM backed by any hash-like storage. [*]}
12
+ spec.description = %q{Redis, LevelDB or plain old hashes --any form of hash-like storage can be used to back Squares.}
13
+ spec.homepage = "http://github.com/joelhelbling/squares"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "rspec-given"
25
+ spec.add_development_dependency "pry"
26
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: squares
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Joel Helbling
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-given
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Redis, LevelDB or plain old hashes --any form of hash-like storage can
84
+ be used to back Squares.
85
+ email:
86
+ - joel@joelhelbling.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - lib/squares.rb
99
+ - lib/squares/base.rb
100
+ - lib/squares/version.rb
101
+ - spec/spec_helper.rb
102
+ - spec/squares/base_spec.rb
103
+ - spec/squares_spec.rb
104
+ - squares.gemspec
105
+ homepage: http://github.com/joelhelbling/squares
106
+ licenses:
107
+ - MIT
108
+ metadata: {}
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.4.3
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: Lightweight ORM backed by any hash-like storage. [*]
129
+ test_files:
130
+ - spec/spec_helper.rb
131
+ - spec/squares/base_spec.rb
132
+ - spec/squares_spec.rb