rrod 0.0.1 → 1.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +33 -18
  4. data/lib/rrod/all.rb +24 -1
  5. data/lib/rrod/caster/nested_model.rb +16 -0
  6. data/lib/rrod/caster.rb +34 -0
  7. data/lib/rrod/cli.rb +9 -2
  8. data/lib/rrod/configuration.rb +40 -0
  9. data/lib/rrod/model/attribute.rb +80 -0
  10. data/lib/rrod/model/attribute_methods.rb +85 -0
  11. data/lib/rrod/model/collection.rb +37 -0
  12. data/lib/rrod/model/finders.rb +59 -0
  13. data/lib/rrod/model/persistence.rb +35 -0
  14. data/lib/rrod/model/schema.rb +30 -0
  15. data/lib/rrod/model/serialization.rb +12 -0
  16. data/lib/rrod/model.rb +38 -0
  17. data/lib/rrod/query.rb +30 -0
  18. data/lib/rrod/test_server/rspec.rb +50 -0
  19. data/lib/rrod/test_server/runner.rb +56 -0
  20. data/lib/rrod/test_server.rb +77 -0
  21. data/lib/rrod/version.rb +2 -3
  22. data/rrod.gemspec +7 -1
  23. data/spec/rrod/caster_spec.rb +117 -0
  24. data/spec/rrod/configuration_spec.rb +55 -0
  25. data/spec/rrod/model/attribute_methods_spec.rb +64 -0
  26. data/spec/rrod/model/attribute_spec.rb +102 -0
  27. data/spec/rrod/model/collection_spec.rb +39 -0
  28. data/spec/rrod/model/finders_spec.rb +78 -0
  29. data/spec/rrod/model/persistence_spec.rb +43 -0
  30. data/spec/rrod/model/schema_spec.rb +59 -0
  31. data/spec/rrod/model/serialization_spec.rb +17 -0
  32. data/spec/rrod/model/validations_spec.rb +50 -0
  33. data/spec/rrod/model_spec.rb +50 -0
  34. data/spec/rrod/query_spec.rb +34 -0
  35. data/spec/rrod_spec.rb +4 -0
  36. data/spec/spec_helper.rb +4 -0
  37. data/spec/support/models/car.rb +3 -0
  38. data/spec/support/models/person.rb +41 -0
  39. data/spec/support/test_server.yml.example +17 -0
  40. metadata +106 -5
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'support/models/car'
3
+
4
+ describe Rrod::Model::Persistence, integration: true do
5
+
6
+ let(:model) { Car }
7
+ let(:hash) { {wheels: 4, color: :black, make: 'Jeep'} }
8
+ let(:instance) { model.new(hash) }
9
+
10
+ describe "instance methods" do
11
+ describe "new models" do
12
+ it "is new" do
13
+ expect(instance).to be_new
14
+ end
15
+
16
+ it "aliases new_record?" do
17
+ expect(instance).to be_a_new_record
18
+ end
19
+
20
+ it "is not persisted" do
21
+ expect(instance).not_to be_persisted
22
+ end
23
+ end
24
+
25
+ describe "persisted models" do
26
+ before :each do
27
+ instance.save
28
+ end
29
+
30
+ it "is persisted" do
31
+ expect(instance).to be_persisted
32
+ end
33
+
34
+ it "is not new" do
35
+ expect(instance).to_not be_new
36
+ end
37
+
38
+ it "has an id" do
39
+ expect(instance.id).not_to be_nil
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'support/models/person'
3
+
4
+ describe Rrod::Model::Schema do
5
+
6
+ let(:model) { Person }
7
+ let(:instance) { model.new }
8
+
9
+ it "defines a reader for the attribute" do
10
+ expect(instance).to respond_to(:name)
11
+ end
12
+
13
+ it "defines a writer for the attribute" do
14
+ expect(instance).to respond_to(:name=)
15
+ end
16
+
17
+ it "will properly typecast when writing an attribute" do
18
+ instance.gender = 'female'
19
+ expect(instance.gender).to be :female
20
+ end
21
+
22
+ it "is using a schema if an attribute is declared" do
23
+ expect(Person.schema?).to be_true
24
+ end
25
+
26
+ describe "associations", integration: true do
27
+
28
+ it "allows embedding other Rrod::Model's as attributes" do
29
+ instance.address = Address.new
30
+ instance.address.street = '123 Fancy Pants Court'
31
+ instance.save(validate: false)
32
+ person = Person.find(instance.id)
33
+ expect(person.address).to be_an Address
34
+ expect(person.address.street).to eq '123 Fancy Pants Court'
35
+ end
36
+
37
+ it "allows embedding an array of Rrod::Model's as an attribute" do
38
+ instance.pets = [Pet.new(name: 'Molle')]
39
+ instance.save(validate: false)
40
+ person = Person.find(instance.id)
41
+ expect(person.pets).to be_an Rrod::Model::Collection
42
+ expect(person.pets.first).to be_a Pet
43
+ expect(person.pets.first.name).to eq 'Molle'
44
+ end
45
+
46
+ it "will properly serialize nested models" do
47
+ instance.address = Address.new(street: '123 Fancy Pants Lane')
48
+ instance.pets = [Pet.new(name: 'Molle')]
49
+ instance.name = 'Zoolander'
50
+ hash = instance.serializable_hash
51
+
52
+ expect(hash).to be_a Hash
53
+ expect(hash['pets']).to eq [{'name' => 'Molle'}]
54
+ expect(hash['address']).to eq 'street' => '123 Fancy Pants Lane'
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'support/models/car'
3
+
4
+ describe Rrod::Model::Serialization do
5
+ let(:model) { Car }
6
+ let(:attributes) { {wheels: 5, make: 'Jeep' } }
7
+ let(:instance) { model.new(attributes) }
8
+
9
+ it "serializes its attributes for json" do
10
+ expect(instance.as_json).to eq attributes.stringify_keys
11
+ end
12
+
13
+ it "calls to_json on its as_json representation" do
14
+ expect(instance.as_json).to eq(JSON.parse instance.to_json)
15
+ end
16
+
17
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ require 'support/models/person'
3
+
4
+ describe Rrod::Model do
5
+ describe "validations" do
6
+ let(:klass) { Person }
7
+ let(:validators) { klass.validators }
8
+ let(:instance) { klass.new }
9
+
10
+ it "adds validations as class methods" do
11
+ expect(validators.any? { |v| ActiveModel::Validations::LengthValidator === v }).to be_true
12
+ end
13
+
14
+ it "allows describing validations in the attribute" do
15
+ expect(validators.any? { |v| ActiveModel::Validations::PresenceValidator === v }).to be_true
16
+ end
17
+
18
+ it "raises a no method error if no validation exists" do
19
+ expect {
20
+ Class.new {
21
+ include Rrod::Model
22
+ attribute :kittens, Integer, bunnies: true
23
+ }
24
+ }.to raise_error(ArgumentError, /BunniesValidator/)
25
+ end
26
+
27
+
28
+ it "can determine an instances validity" do
29
+ expect(instance).not_to be_valid
30
+ end
31
+
32
+ it "will not save if invalid" do
33
+ expect(instance).not_to receive(:persist)
34
+ instance.save
35
+ end
36
+
37
+ it "will return false from saving if invalid" do
38
+ expect(instance.save).to be_false
39
+ end
40
+
41
+ it "sets up errors properlies" do
42
+ instance.valid?
43
+ expect(instance.errors).to be_present
44
+ end
45
+
46
+ it "will allow saving when not validating" do
47
+ expect(instance.save(validate: false)).to be_true
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ require 'support/models/car'
3
+
4
+ describe Rrod::Model do
5
+
6
+ let(:model) { Car }
7
+ let(:hash) { {wheels: 4, color: :black, make: 'Jeep'} }
8
+ let(:instance) { model.new(hash) }
9
+
10
+ describe "including" do
11
+ describe "class methods" do
12
+ it "delegates the client to the Rrod::Model module" do
13
+ expect(Rrod.configuration).to receive :client
14
+ model.client
15
+ end
16
+
17
+ it "has a riak client" do
18
+ expect(model.client).to be_a Riak::Client
19
+ end
20
+
21
+ it "has a bucket" do
22
+ expect(model.bucket).to be_a Riak::Bucket
23
+ end
24
+
25
+ it "names the bucket based off the class" do
26
+ expect(model.bucket.name).to eq 'cars'
27
+ end
28
+ end
29
+
30
+ describe "instance methods" do
31
+ it "delegates the client to the Car" do
32
+ expect(model).to receive :client
33
+ instance.client
34
+ end
35
+
36
+ it "has a riak client" do
37
+ expect(instance.client).to be_a Riak::Client
38
+ end
39
+
40
+ it "delegates its bucket to its class" do
41
+ expect(model).to receive :bucket
42
+ instance.bucket
43
+ end
44
+
45
+ it "has a bucket" do
46
+ expect(instance.bucket).to be_a Riak::Bucket
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rrod::Query do
4
+
5
+ let(:options) { {} }
6
+ let(:query) { described_class.new(options) }
7
+
8
+ describe "instantiation" do
9
+ it "raises an error if no options are given" do
10
+ expect { described_class.new }.to raise_error(ArgumentError)
11
+ end
12
+
13
+ it "raises an error if id is mixed with other options" do
14
+ expect { described_class.new(id: 'foo', bar: 'baz') }.to raise_error(ArgumentError)
15
+ end
16
+ end
17
+
18
+ describe "id" do
19
+ let(:options) { {id: 'brains are yummy'} }
20
+
21
+ it "exposes the id" do
22
+ expect(query.id).to eq 'brains are yummy'
23
+ end
24
+ end
25
+
26
+ describe "attributes" do
27
+ let(:options) { {color: 'black', wheels: 5} }
28
+
29
+ it "converts attributes to a search string" do
30
+ expect(query.to_s).to eq "color:black AND wheels:5"
31
+ end
32
+ end
33
+
34
+ end
data/spec/rrod_spec.rb CHANGED
@@ -4,5 +4,9 @@ describe Rrod do
4
4
  it "is the ruby riak database" do
5
5
  expect(described_class).to be_a Module
6
6
  end
7
+
8
+ it "has a version" do
9
+ expect(described_class.const_get "VERSION").to be_a String
10
+ end
7
11
  end
8
12
 
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  $:.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'pry'
2
3
  require 'rrod'
4
+ require 'rrod/test_server/rspec'
3
5
 
4
6
  RSpec.configure do |config|
5
7
  config.order = 'random'
@@ -7,3 +9,5 @@ RSpec.configure do |config|
7
9
  config.treat_symbols_as_metadata_keys_with_true_values = true
8
10
  config.filter_run :focus
9
11
  end
12
+
13
+ Rrod::TestServer::RSpec.enable!
@@ -0,0 +1,3 @@
1
+ class Car
2
+ include Rrod::Model
3
+ end
@@ -0,0 +1,41 @@
1
+ class Address
2
+ include Rrod::Model
3
+
4
+ attribute :street, String
5
+ attribute :city, String
6
+ attribute :state_abbr, String
7
+ attribute :zip, String
8
+ end
9
+
10
+ class Vaccination
11
+ include Rrod::Model
12
+
13
+ attribute :type, String
14
+ attribute :when, Date
15
+ end
16
+
17
+ class Pet
18
+ include Rrod::Model
19
+
20
+ attribute :name, String
21
+ attribute :species, String
22
+ attribute :friendly, Boolean
23
+
24
+ attribute :vaccinations, [Vaccination], default: -> {
25
+ Vaccination.new(type: :rabies, when: Date.today)
26
+ }
27
+ end
28
+
29
+ class Person
30
+ include Rrod::Model
31
+
32
+ attribute :name, String, presence: true
33
+ attribute :age, Integer, numericality: {min: 10}
34
+ attribute :gender, Symbol
35
+
36
+ attribute :address, Address
37
+
38
+ attribute :pets, [Pet]
39
+
40
+ validates_length_of :pets, minimum: 1
41
+ end
@@ -0,0 +1,17 @@
1
+ # Copied from riak-test-server
2
+
3
+ # This is where the test server node will be generated. Something on
4
+ # /tmp is usually ok.
5
+ root: .tmp/riak-client-test-server
6
+
7
+ # This is where Riak is installed on your system, that is, the path to
8
+ # the 'riak' and 'riak-admin' scripts. I use a self-built node, but
9
+ # here's where it will generally be on various platforms:
10
+ #
11
+ # Linux: /usr/sbin
12
+ # Solaris/OpenSolaris: /opt/riak/bin
13
+ # Mac OS/X (Homebrew): /usr/local/bin
14
+ # Source/Self built: /path/to/your/install/rel/riak/bin
15
+ #
16
+ source: /Users/sean/Development/riak/rel/riak/bin
17
+
metadata CHANGED
@@ -1,15 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rrod
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Hunter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-14 00:00:00.000000000 Z
11
+ date: 2013-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: riak-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.4.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: activemodel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '3.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '3.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '3.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '3.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: american_date
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: 1.1.0
13
69
  - !ruby/object:Gem::Dependency
14
70
  name: thor
15
71
  requirement: !ruby/object:Gem::Requirement
@@ -97,11 +153,41 @@ files:
97
153
  - bin/rrod
98
154
  - lib/rrod.rb
99
155
  - lib/rrod/all.rb
156
+ - lib/rrod/caster.rb
157
+ - lib/rrod/caster/nested_model.rb
100
158
  - lib/rrod/cli.rb
159
+ - lib/rrod/configuration.rb
160
+ - lib/rrod/model.rb
161
+ - lib/rrod/model/attribute.rb
162
+ - lib/rrod/model/attribute_methods.rb
163
+ - lib/rrod/model/collection.rb
164
+ - lib/rrod/model/finders.rb
165
+ - lib/rrod/model/persistence.rb
166
+ - lib/rrod/model/schema.rb
167
+ - lib/rrod/model/serialization.rb
168
+ - lib/rrod/query.rb
169
+ - lib/rrod/test_server.rb
170
+ - lib/rrod/test_server/rspec.rb
171
+ - lib/rrod/test_server/runner.rb
101
172
  - lib/rrod/version.rb
102
173
  - rrod.gemspec
174
+ - spec/rrod/caster_spec.rb
175
+ - spec/rrod/configuration_spec.rb
176
+ - spec/rrod/model/attribute_methods_spec.rb
177
+ - spec/rrod/model/attribute_spec.rb
178
+ - spec/rrod/model/collection_spec.rb
179
+ - spec/rrod/model/finders_spec.rb
180
+ - spec/rrod/model/persistence_spec.rb
181
+ - spec/rrod/model/schema_spec.rb
182
+ - spec/rrod/model/serialization_spec.rb
183
+ - spec/rrod/model/validations_spec.rb
184
+ - spec/rrod/model_spec.rb
185
+ - spec/rrod/query_spec.rb
103
186
  - spec/rrod_spec.rb
104
187
  - spec/spec_helper.rb
188
+ - spec/support/models/car.rb
189
+ - spec/support/models/person.rb
190
+ - spec/support/test_server.yml.example
105
191
  homepage: https://github.com/adamhunter/rrod
106
192
  licenses:
107
193
  - MIT
@@ -117,15 +203,30 @@ required_ruby_version: !ruby/object:Gem::Requirement
117
203
  version: '0'
118
204
  required_rubygems_version: !ruby/object:Gem::Requirement
119
205
  requirements:
120
- - - '>='
206
+ - - '>'
121
207
  - !ruby/object:Gem::Version
122
- version: '0'
208
+ version: 1.3.1
123
209
  requirements: []
124
210
  rubyforge_project:
125
- rubygems_version: 2.0.3
211
+ rubygems_version: 2.0.5
126
212
  signing_key:
127
213
  specification_version: 4
128
214
  summary: A persistence layer for your ruby objects, powered by Riak
129
215
  test_files:
216
+ - spec/rrod/caster_spec.rb
217
+ - spec/rrod/configuration_spec.rb
218
+ - spec/rrod/model/attribute_methods_spec.rb
219
+ - spec/rrod/model/attribute_spec.rb
220
+ - spec/rrod/model/collection_spec.rb
221
+ - spec/rrod/model/finders_spec.rb
222
+ - spec/rrod/model/persistence_spec.rb
223
+ - spec/rrod/model/schema_spec.rb
224
+ - spec/rrod/model/serialization_spec.rb
225
+ - spec/rrod/model/validations_spec.rb
226
+ - spec/rrod/model_spec.rb
227
+ - spec/rrod/query_spec.rb
130
228
  - spec/rrod_spec.rb
131
229
  - spec/spec_helper.rb
230
+ - spec/support/models/car.rb
231
+ - spec/support/models/person.rb
232
+ - spec/support/test_server.yml.example