squares 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +189 -0
- data/Rakefile +7 -0
- data/lib/squares/base.rb +144 -0
- data/lib/squares/version.rb +3 -0
- data/lib/squares.rb +6 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/squares/base_spec.rb +164 -0
- data/spec/squares_spec.rb +7 -0
- data/squares.gemspec +26 -0
- metadata +132 -0
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
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
data/lib/squares/base.rb
ADDED
@@ -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
|
+
|
data/lib/squares.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -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
|
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
|