rrod 0.0.1 → 1.0.0.alpha.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +33 -18
- data/lib/rrod/all.rb +24 -1
- data/lib/rrod/caster/nested_model.rb +16 -0
- data/lib/rrod/caster.rb +34 -0
- data/lib/rrod/cli.rb +9 -2
- data/lib/rrod/configuration.rb +40 -0
- data/lib/rrod/model/attribute.rb +80 -0
- data/lib/rrod/model/attribute_methods.rb +85 -0
- data/lib/rrod/model/collection.rb +37 -0
- data/lib/rrod/model/finders.rb +59 -0
- data/lib/rrod/model/persistence.rb +35 -0
- data/lib/rrod/model/schema.rb +30 -0
- data/lib/rrod/model/serialization.rb +12 -0
- data/lib/rrod/model.rb +38 -0
- data/lib/rrod/query.rb +30 -0
- data/lib/rrod/test_server/rspec.rb +50 -0
- data/lib/rrod/test_server/runner.rb +56 -0
- data/lib/rrod/test_server.rb +77 -0
- data/lib/rrod/version.rb +2 -3
- data/rrod.gemspec +7 -1
- data/spec/rrod/caster_spec.rb +117 -0
- data/spec/rrod/configuration_spec.rb +55 -0
- data/spec/rrod/model/attribute_methods_spec.rb +64 -0
- data/spec/rrod/model/attribute_spec.rb +102 -0
- data/spec/rrod/model/collection_spec.rb +39 -0
- data/spec/rrod/model/finders_spec.rb +78 -0
- data/spec/rrod/model/persistence_spec.rb +43 -0
- data/spec/rrod/model/schema_spec.rb +59 -0
- data/spec/rrod/model/serialization_spec.rb +17 -0
- data/spec/rrod/model/validations_spec.rb +50 -0
- data/spec/rrod/model_spec.rb +50 -0
- data/spec/rrod/query_spec.rb +34 -0
- data/spec/rrod_spec.rb +4 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/models/car.rb +3 -0
- data/spec/support/models/person.rb +41 -0
- data/spec/support/test_server.yml.example +17 -0
- metadata +106 -5
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rrod/test_server'
|
2
|
+
|
3
|
+
module Rrod
|
4
|
+
class TestServer
|
5
|
+
module RSpec
|
6
|
+
|
7
|
+
def self.enable!
|
8
|
+
Rrod.configure do |config|
|
9
|
+
# We have to use http to set bucket props (to enable search index)
|
10
|
+
# https://github.com/basho/riak-ruby-client/blob/v1.4.2/lib/riak/client.rb#L500
|
11
|
+
config.http_port = Rrod::TestServer.http_port
|
12
|
+
config.pb_port = Rrod::TestServer.pb_port
|
13
|
+
end
|
14
|
+
|
15
|
+
::RSpec.configure do |config|
|
16
|
+
config.before(:each, :integration => true) do
|
17
|
+
if Rrod::TestServer.fatal
|
18
|
+
fail "Test server not working: #{Rrod::TestServer.fatal}"
|
19
|
+
end
|
20
|
+
|
21
|
+
if example.metadata[:test_server] == false
|
22
|
+
Rrod::TestServer.stop
|
23
|
+
else
|
24
|
+
Rrod::TestServer.create unless Rrod::TestServer.exist?
|
25
|
+
unless Rrod::TestServer.started?
|
26
|
+
@rspec_started = true
|
27
|
+
Rrod::TestServer.start
|
28
|
+
Rrod::TestServer.wait_for_search
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
config.after(:each, :integration => true) do
|
34
|
+
# i really don't understand this...
|
35
|
+
if !Rrod::TestServer.fatal &&
|
36
|
+
Rrod::TestServer.started? &&
|
37
|
+
example.metadata[:test_server] != false
|
38
|
+
Rrod::TestServer.drop
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
config.after(:suite) do
|
43
|
+
Rrod::TestServer.stop if @rspec_started && Rrod::TestServer.started?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rrod/test_server'
|
2
|
+
|
3
|
+
module Rrod
|
4
|
+
class TestServer
|
5
|
+
class Runner
|
6
|
+
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
def self.run
|
10
|
+
instance.run
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.signal_queue
|
14
|
+
@signal_queue ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
define_signal_traps
|
19
|
+
|
20
|
+
Rrod::TestServer.tap { |server|
|
21
|
+
puts "starting rrod test server"
|
22
|
+
server.config[:root].tap { |root| FileUtils.rm_rf root if Dir.exists? root }
|
23
|
+
server.create unless server.exist?
|
24
|
+
server.start unless server.started?
|
25
|
+
begin puts "waiting for search..." end until server.search_started?
|
26
|
+
puts "started."
|
27
|
+
}
|
28
|
+
|
29
|
+
setup_run_loop
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def setup_run_loop
|
35
|
+
loop do
|
36
|
+
case self.class.signal_queue.shift
|
37
|
+
when nil
|
38
|
+
sleep 1 # not really sure what to do here
|
39
|
+
when :INT, :TERM, :QUIT
|
40
|
+
puts
|
41
|
+
puts "shutting down rrod test server"
|
42
|
+
Rrod::TestServer.stop
|
43
|
+
break
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def define_signal_traps
|
49
|
+
[:INT, :TERM, :QUIT].each do |signal|
|
50
|
+
Signal.trap(signal) { self.class.signal_queue << signal }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# The test server was copied directly out of
|
2
|
+
# riak-ruby-client/spec/support/test_server.rb
|
3
|
+
# and refactored into a class that can be used
|
4
|
+
# to control the server's lifecycle
|
5
|
+
|
6
|
+
require 'yaml'
|
7
|
+
require 'riak/test_server'
|
8
|
+
|
9
|
+
module Rrod
|
10
|
+
class TestServer
|
11
|
+
attr_reader :fatal
|
12
|
+
|
13
|
+
extend Forwardable
|
14
|
+
include Singleton
|
15
|
+
|
16
|
+
DELEGATES = %w[wait_for_search start stop create drop http_port pb_port config started? search_started? exist?]
|
17
|
+
|
18
|
+
class << self
|
19
|
+
extend Forwardable
|
20
|
+
def_delegators(:instance, * [:fatal] + DELEGATES)
|
21
|
+
end
|
22
|
+
|
23
|
+
def_delegators(:server, *DELEGATES)
|
24
|
+
|
25
|
+
def config
|
26
|
+
loaded = YAML.load_file(Rrod.configuration.test_server_yml)
|
27
|
+
{ min_port: 15_000 }.merge loaded.symbolize_keys
|
28
|
+
rescue Errno::ENOENT => e
|
29
|
+
message = "Cannot find Rrod::TestServer configuration. #{e.message}"
|
30
|
+
raise MissingConfigurationError.new(message)
|
31
|
+
end
|
32
|
+
|
33
|
+
def server
|
34
|
+
@server ||= try_creating_riak_test_server!
|
35
|
+
end
|
36
|
+
|
37
|
+
def search_started?
|
38
|
+
wait_for_search.chomp.eql? "riak_search is up"
|
39
|
+
end
|
40
|
+
|
41
|
+
def wait_for_search
|
42
|
+
Timeout.timeout(Rrod.configuration.test_server_search_startup_timeout) do
|
43
|
+
server.send :riak_admin, 'wait-for-service', 'riak_search', server.name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def warn_crash_log
|
48
|
+
if @server && crash_log = @server.log + 'crash.log'
|
49
|
+
warn crash_log.read if crash_log.exist?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
attr_writer :fatal
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# TODO refactor warnings
|
60
|
+
def try_creating_riak_test_server!
|
61
|
+
Riak::TestServer.create(config)
|
62
|
+
rescue SocketError => e
|
63
|
+
warn "Couldn't connect to Riak TestServer!"
|
64
|
+
warn "Skipping remaining integration tests."
|
65
|
+
warn_crash_log
|
66
|
+
self.fatal = e
|
67
|
+
rescue => e
|
68
|
+
warn "Can't run integration specs without the test server. Please create/verify spec/support/test_server.yml."
|
69
|
+
warn "Skipping remaining integration tests."
|
70
|
+
warn e.inspect
|
71
|
+
warn_crash_log
|
72
|
+
self.fatal = e
|
73
|
+
end
|
74
|
+
|
75
|
+
MissingConfigurationError = Class.new(StandardError)
|
76
|
+
end
|
77
|
+
end
|
data/lib/rrod/version.rb
CHANGED
@@ -1,3 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
end
|
1
|
+
Rrod = Module.new unless defined? Rrod
|
2
|
+
Rrod::VERSION = '1.0.0.alpha.1'
|
data/rrod.gemspec
CHANGED
@@ -18,11 +18,17 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency "riak-client", "~> 1.4.2"
|
22
|
+
spec.add_dependency "activemodel", ">= 3.2"
|
23
|
+
spec.add_dependency "activesupport", ">= 3.2"
|
24
|
+
spec.add_dependency "american_date", ">= 1.1.0"
|
25
|
+
|
26
|
+
# cli deps
|
21
27
|
spec.add_dependency "thor", "~> 0.18"
|
22
28
|
spec.add_dependency "pry", "~> 0.9"
|
23
29
|
|
24
30
|
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
-
spec.add_development_dependency "rspec",
|
31
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
26
32
|
|
27
33
|
spec.add_development_dependency "rake"
|
28
34
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rrod::Caster do
|
4
|
+
let(:type) { nil }
|
5
|
+
let(:caster) { "#{described_class}::#{type}".constantize }
|
6
|
+
|
7
|
+
describe "BigDecimal" do
|
8
|
+
let(:type) { 'BigDecimal' }
|
9
|
+
it "converts to big decimal" do
|
10
|
+
expect(caster.rrod_cast("42")).to eq 42
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "Boolean" do
|
15
|
+
let(:type) { 'Boolean' }
|
16
|
+
it "converts to true" do
|
17
|
+
expect(caster.rrod_cast(true)).to be true
|
18
|
+
end
|
19
|
+
it "converts 'true' to true" do
|
20
|
+
expect(caster.rrod_cast("true")).to be true
|
21
|
+
end
|
22
|
+
it "converts 1 to true" do
|
23
|
+
expect(caster.rrod_cast(1)).to be true
|
24
|
+
end
|
25
|
+
it "converts '1' to true" do
|
26
|
+
expect(caster.rrod_cast("1")).to be true
|
27
|
+
end
|
28
|
+
it "converts to false" do
|
29
|
+
expect(caster.rrod_cast(false)).to be false
|
30
|
+
end
|
31
|
+
it "converts 'false' to false" do
|
32
|
+
expect(caster.rrod_cast("false")).to be false
|
33
|
+
end
|
34
|
+
it "converts 0 to false" do
|
35
|
+
expect(caster.rrod_cast(0)).to be false
|
36
|
+
end
|
37
|
+
it "converts '0' to false" do
|
38
|
+
expect(caster.rrod_cast("0")).to be false
|
39
|
+
end
|
40
|
+
it "converts nil to false" do
|
41
|
+
expect(caster.rrod_cast(nil)).to be false
|
42
|
+
end
|
43
|
+
it "converts everything else to true" do
|
44
|
+
expect(caster.rrod_cast(Object.new)).to be true
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "Date" do
|
50
|
+
let(:type) { 'Date' }
|
51
|
+
let(:date) { Date.parse("2013-10-31") }
|
52
|
+
it "converts db format to date" do
|
53
|
+
expect(caster.rrod_cast("2013-10-31")).to eq date
|
54
|
+
end
|
55
|
+
it "converts standard format to date" do
|
56
|
+
expect(caster.rrod_cast("31-10-2013")).to eq date
|
57
|
+
end
|
58
|
+
it "converts american format to date" do
|
59
|
+
expect(caster.rrod_cast("10/31/2013")).to eq date
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "DateTime" do
|
64
|
+
let(:type) { 'DateTime' }
|
65
|
+
let(:datetime) { "12:13:14".to_datetime }
|
66
|
+
it "converts time to datetime" do
|
67
|
+
expect(caster.rrod_cast("12:13:14")).to eq datetime
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "Float" do
|
72
|
+
let(:type) { 'Float' }
|
73
|
+
let(:floater) { 3.142 }
|
74
|
+
it "converts to floating point" do
|
75
|
+
expect(caster.rrod_cast("3.142")).to eq floater
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "Integer" do
|
80
|
+
let(:type) { 'Integer' }
|
81
|
+
it "converts to integer" do
|
82
|
+
expect(caster.rrod_cast('4')).to eq 4
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "Numeric" do
|
87
|
+
let(:type) { 'Numeric' }
|
88
|
+
it "converts to floating point" do
|
89
|
+
expect(caster.rrod_cast("3.142")).to eq 3.142
|
90
|
+
end
|
91
|
+
it "converts to integer" do
|
92
|
+
expect(caster.rrod_cast("3")).to eq 3
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "String" do
|
97
|
+
let(:type) { 'String' }
|
98
|
+
it "converts to string" do
|
99
|
+
expect(caster.rrod_cast(:string)).to eq 'string'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "Symbol" do
|
104
|
+
let(:type) { 'Symbol' }
|
105
|
+
it "converts to symbol" do
|
106
|
+
expect(caster.rrod_cast('symbol')).to eq :symbol
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "Time" do
|
111
|
+
let(:type) { 'Time' }
|
112
|
+
let(:time) { "12:13:14".to_time }
|
113
|
+
it "converts to time" do
|
114
|
+
expect(caster.rrod_cast("12:13:14")).to eq time
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rrod do
|
4
|
+
|
5
|
+
it "adds a configure method to the Rrod module" do
|
6
|
+
expect(Rrod).to respond_to(:configure)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "yields the configuration to the block given to config" do
|
10
|
+
Rrod.configure do |config|
|
11
|
+
config.pb_port = 123456
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "adds a configuration object to the Rrod module" do
|
16
|
+
expect(Rrod.configuration).to be_a Rrod::Configuration
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe Rrod::Configuration do
|
22
|
+
|
23
|
+
let(:config) { described_class.new }
|
24
|
+
|
25
|
+
describe "defaults" do
|
26
|
+
it "will use spec/support/test_server.yml for the test_server_yml" do
|
27
|
+
expect(config.test_server_yml).to match('spec/support/test_server.yml')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "client" do
|
32
|
+
it "creates a client based on its options" do
|
33
|
+
config.pb_port = 123456
|
34
|
+
expect(Riak::Client).to receive(:new).with(pb_port: 123456, protocol: 'pbc')
|
35
|
+
config.client
|
36
|
+
end
|
37
|
+
|
38
|
+
it "will not create a client if one exists" do
|
39
|
+
config.client = Riak::Client.new
|
40
|
+
expect(Riak::Client).not_to receive(:new)
|
41
|
+
config.client
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "attributes" do
|
46
|
+
%w[http_port pb_port protocol client test_server_yml
|
47
|
+
test_server_search_startup_timeout nodes].each do |attribute|
|
48
|
+
it "allows configuration of #{attribute}" do
|
49
|
+
expect(config).to respond_to attribute
|
50
|
+
expect(config).to respond_to "#{attribute}="
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,64 @@
|
|
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 "instantiation" do
|
11
|
+
it "can create an object with an arbitrary hash" do
|
12
|
+
expect(instance.wheels).to eq 4
|
13
|
+
expect(instance.color).to eq :black
|
14
|
+
expect(instance.make).to eq 'Jeep'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "always has an id property" do
|
18
|
+
expect(instance).to respond_to :id
|
19
|
+
expect(instance.id).to be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "manages attribute keys as strings" do
|
23
|
+
expect(instance.attributes).to eq hash.stringify_keys
|
24
|
+
end
|
25
|
+
|
26
|
+
it "ignores modifications to the attribute hash" do
|
27
|
+
instance.attributes[:model] = 'Wrangler'
|
28
|
+
expect(instance.attributes[:model]).to be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it "will return nil for an attribute that exists in the hash but does not have a corresponding method" do
|
32
|
+
instance.instance_variable_get(:@attributes)['foo'] = 'bar'
|
33
|
+
expect(instance).not_to respond_to(:foo)
|
34
|
+
expect(instance.attributes).to include('foo' => nil)
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "mass assignment" do
|
38
|
+
it "will merge attributes when mass assigning" do
|
39
|
+
instance.attributes = {wheels: 5}
|
40
|
+
expect(instance.wheels).to eq 5
|
41
|
+
end
|
42
|
+
|
43
|
+
it "will not add additional attribute methods after instantiation" do
|
44
|
+
expect { instance.attributes = {model: 'Wrangler'} }.to raise_error
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "with schema" do
|
49
|
+
let(:model) { Class.new(Car) { attribute :wheels, Integer } }
|
50
|
+
|
51
|
+
it "does not allow creating with arbitrary attributes" do
|
52
|
+
expect { model.new(model: 'Jeep') }.to raise_error(NoMethodError, /model=/)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "can be created with the specified attributes" do
|
56
|
+
expect(model.new(wheels: 5).wheels).to be 5
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "query generation" do
|
61
|
+
it "lets you use strings with apostrophes in them"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rrod::Model::Attribute do
|
4
|
+
let(:options) { {presence: true} }
|
5
|
+
let(:model) { Class.new { include Rrod::Model } }
|
6
|
+
let(:instance) { model.new }
|
7
|
+
let(:name) { :name }
|
8
|
+
let(:type) { String }
|
9
|
+
let(:attribute) { described_class.new(model, name, type, options) }
|
10
|
+
|
11
|
+
it "has a model" do
|
12
|
+
expect(attribute.model).to be model
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has a name" do
|
16
|
+
expect(attribute.name).to be name
|
17
|
+
end
|
18
|
+
|
19
|
+
it "typecasts name to a symbol when initializing" do
|
20
|
+
attribute = described_class.new(model, "unicorn_tears", Integer)
|
21
|
+
expect(attribute.name).to be :unicorn_tears
|
22
|
+
end
|
23
|
+
|
24
|
+
it "has a type" do
|
25
|
+
expect(attribute.type).to be type
|
26
|
+
end
|
27
|
+
|
28
|
+
it "has options" do
|
29
|
+
expect(attribute.options).to eq(options)
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "defaults" do
|
33
|
+
context "when a value" do
|
34
|
+
let(:options) { {default: 'SOO fluffy!'} }
|
35
|
+
it "can provide a default value" do
|
36
|
+
expect(attribute.default).to eq 'SOO fluffy!'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when a proc" do
|
41
|
+
let(:options) { {default: -> { 'alligator' }} }
|
42
|
+
|
43
|
+
it "can provide a default value if a proc" do
|
44
|
+
expect(attribute.default).to eq 'alligator'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "defining attribute methods" do
|
50
|
+
before(:each) { attribute.define }
|
51
|
+
|
52
|
+
describe "getters" do
|
53
|
+
it "is defined on the declaring class" do
|
54
|
+
expect(instance).to respond_to(name)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "setters" do
|
59
|
+
it "is defined on the declaring class" do
|
60
|
+
expect(instance).to respond_to("#{name}=")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "casting" do
|
66
|
+
it "will use the types rrod_cast method if available" do
|
67
|
+
type = Class.new {
|
68
|
+
def self.rrod_cast(value)
|
69
|
+
value.to_s.upcase
|
70
|
+
end
|
71
|
+
}
|
72
|
+
model.attribute :example, type
|
73
|
+
instance.example = 'shorty'
|
74
|
+
expect(instance.example).to eq 'SHORTY'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "will look for a register Rrod caster if the type cannot cast itself" do
|
78
|
+
model.attribute :example, String
|
79
|
+
instance.example = :whazzup
|
80
|
+
expect(instance.example).to eq('whazzup')
|
81
|
+
end
|
82
|
+
|
83
|
+
it "will simply return the value if all else fails" do
|
84
|
+
model.attribute :example, Class.new
|
85
|
+
instance.example = self
|
86
|
+
expect(instance.example).to be self
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "nested rrod models" do
|
90
|
+
let(:type) { [Class.new { include Rrod::Model }] }
|
91
|
+
|
92
|
+
it "can detect if the type is a nested rrod model" do
|
93
|
+
expect(attribute.send :nested_model?).to be true
|
94
|
+
end
|
95
|
+
|
96
|
+
it "adds a rrod_cast method to the nested rrod model reference object" do
|
97
|
+
attribute
|
98
|
+
expect(type).to respond_to(:rrod_cast)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/models/person'
|
3
|
+
|
4
|
+
describe Rrod::Model::Collection do
|
5
|
+
let(:array) { [Pet.new] }
|
6
|
+
let(:collection) { described_class.new(array) }
|
7
|
+
|
8
|
+
describe "initialization" do
|
9
|
+
it "takes a collection" do
|
10
|
+
expect(collection.collection).to eq(array)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "defaults to an empty collection" do
|
14
|
+
expect(described_class.new.collection).to be_an Array
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "errors" do
|
18
|
+
describe "non enumerable" do
|
19
|
+
let(:array) { Object.new }
|
20
|
+
it "raises" do
|
21
|
+
expect { collection }.to raise_error(Rrod::Model::Collection::InvalidCollectionTypeError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "not all Rrod::Model" do
|
26
|
+
let(:array) { [Pet.new, Object.new] }
|
27
|
+
it "raises if not all `Rrod::Model`s" do
|
28
|
+
expect { collection }.to raise_error(Rrod::Model::Collection::InvalidMemberTypeError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "clears the collection" do
|
32
|
+
collection = described_class.new
|
33
|
+
begin; collection.collection = array; rescue; end
|
34
|
+
expect(collection.collection).to be_empty
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/models/car'
|
3
|
+
|
4
|
+
describe Rrod::Model::Finders, 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
|
+
before :each do
|
11
|
+
instance.save
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can be found by id" do
|
15
|
+
found = model.find(instance.id)
|
16
|
+
expect(found).to be_a model
|
17
|
+
end
|
18
|
+
|
19
|
+
it "will raise an error if it can't be found" do
|
20
|
+
expect { model.find("id that is not there") }.to raise_error(Rrod::Model::NotFound)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "is persisted" do
|
24
|
+
found = model.find(instance.id)
|
25
|
+
expect(found).to be_persisted
|
26
|
+
end
|
27
|
+
|
28
|
+
it "sets the robject on the found instance" do
|
29
|
+
found = model.find(instance.id)
|
30
|
+
expect(found.robject).to be_a Riak::RObject
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "finding by attributes in the hash" do
|
34
|
+
describe "find_first_by" do
|
35
|
+
it "can find one" do
|
36
|
+
found = model.find_first_by(make: 'Jeep')
|
37
|
+
expect(found).to be_a model
|
38
|
+
expect(found.make).to eq "Jeep"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "will work properly when finding by id" do
|
42
|
+
found = model.find_first_by(id: instance.id)
|
43
|
+
expect(found).to be_a model
|
44
|
+
end
|
45
|
+
|
46
|
+
it "will return nil if one can't be found" do
|
47
|
+
found = model.find_first_by(id: "id that is not there")
|
48
|
+
expect(found).to be nil
|
49
|
+
end
|
50
|
+
|
51
|
+
it "will raise an exception if one can't be found with a !" do
|
52
|
+
expect { model.find_first_by! zombies: true }.to raise_error(Rrod::Model::NotFound)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "find_all_by" do
|
57
|
+
it "can find all" do
|
58
|
+
founds = model.find_all_by(make: 'Jeep', wheels: 4)
|
59
|
+
found = founds.first
|
60
|
+
expect(founds).to be_an Array
|
61
|
+
expect(found).to be_a model
|
62
|
+
expect(found.make).to eq "Jeep"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "will raise an exception if finding all by id" do
|
66
|
+
expect {model.find_all_by(id: instance.id)}.to raise_error(ArgumentError)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "will return [] if none can be found" do
|
70
|
+
expect(model.find_all_by zombies: 'yes plz').to eq []
|
71
|
+
end
|
72
|
+
|
73
|
+
it "will raise an exception if none can be found with a !" do
|
74
|
+
expect { model.find_all_by! brains: :none }.to raise_error(Rrod::Model::NotFound)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|