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.
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,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
- module Rrod
2
- VERSION = "0.0.1"
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", "~> 2.14"
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