mongomodel 0.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 (108) hide show
  1. data/LICENSE +22 -0
  2. data/README.md +34 -0
  3. data/Rakefile +47 -0
  4. data/bin/console +45 -0
  5. data/lib/mongomodel.rb +92 -0
  6. data/lib/mongomodel/attributes/mongo.rb +40 -0
  7. data/lib/mongomodel/attributes/store.rb +30 -0
  8. data/lib/mongomodel/attributes/typecasting.rb +51 -0
  9. data/lib/mongomodel/concerns/abstract_class.rb +17 -0
  10. data/lib/mongomodel/concerns/activemodel.rb +11 -0
  11. data/lib/mongomodel/concerns/associations.rb +103 -0
  12. data/lib/mongomodel/concerns/associations/base/association.rb +33 -0
  13. data/lib/mongomodel/concerns/associations/base/definition.rb +56 -0
  14. data/lib/mongomodel/concerns/associations/base/proxy.rb +58 -0
  15. data/lib/mongomodel/concerns/associations/belongs_to.rb +68 -0
  16. data/lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb +159 -0
  17. data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +175 -0
  18. data/lib/mongomodel/concerns/attribute_methods.rb +55 -0
  19. data/lib/mongomodel/concerns/attribute_methods/before_type_cast.rb +29 -0
  20. data/lib/mongomodel/concerns/attribute_methods/dirty.rb +35 -0
  21. data/lib/mongomodel/concerns/attribute_methods/protected.rb +127 -0
  22. data/lib/mongomodel/concerns/attribute_methods/query.rb +22 -0
  23. data/lib/mongomodel/concerns/attribute_methods/read.rb +29 -0
  24. data/lib/mongomodel/concerns/attribute_methods/write.rb +29 -0
  25. data/lib/mongomodel/concerns/attributes.rb +85 -0
  26. data/lib/mongomodel/concerns/callbacks.rb +294 -0
  27. data/lib/mongomodel/concerns/logging.rb +15 -0
  28. data/lib/mongomodel/concerns/pretty_inspect.rb +29 -0
  29. data/lib/mongomodel/concerns/properties.rb +69 -0
  30. data/lib/mongomodel/concerns/record_status.rb +42 -0
  31. data/lib/mongomodel/concerns/timestamps.rb +32 -0
  32. data/lib/mongomodel/concerns/validations.rb +38 -0
  33. data/lib/mongomodel/concerns/validations/associated.rb +46 -0
  34. data/lib/mongomodel/document.rb +20 -0
  35. data/lib/mongomodel/document/callbacks.rb +46 -0
  36. data/lib/mongomodel/document/dynamic_finders.rb +88 -0
  37. data/lib/mongomodel/document/finders.rb +82 -0
  38. data/lib/mongomodel/document/indexes.rb +91 -0
  39. data/lib/mongomodel/document/optimistic_locking.rb +48 -0
  40. data/lib/mongomodel/document/persistence.rb +143 -0
  41. data/lib/mongomodel/document/scopes.rb +161 -0
  42. data/lib/mongomodel/document/validations.rb +68 -0
  43. data/lib/mongomodel/document/validations/uniqueness.rb +78 -0
  44. data/lib/mongomodel/embedded_document.rb +42 -0
  45. data/lib/mongomodel/locale/en.yml +55 -0
  46. data/lib/mongomodel/support/collection.rb +109 -0
  47. data/lib/mongomodel/support/configuration.rb +35 -0
  48. data/lib/mongomodel/support/core_extensions.rb +10 -0
  49. data/lib/mongomodel/support/exceptions.rb +25 -0
  50. data/lib/mongomodel/support/mongo_options.rb +177 -0
  51. data/lib/mongomodel/support/types.rb +35 -0
  52. data/lib/mongomodel/support/types/array.rb +11 -0
  53. data/lib/mongomodel/support/types/boolean.rb +25 -0
  54. data/lib/mongomodel/support/types/custom.rb +38 -0
  55. data/lib/mongomodel/support/types/date.rb +20 -0
  56. data/lib/mongomodel/support/types/float.rb +13 -0
  57. data/lib/mongomodel/support/types/hash.rb +18 -0
  58. data/lib/mongomodel/support/types/integer.rb +13 -0
  59. data/lib/mongomodel/support/types/object.rb +21 -0
  60. data/lib/mongomodel/support/types/string.rb +9 -0
  61. data/lib/mongomodel/support/types/symbol.rb +9 -0
  62. data/lib/mongomodel/support/types/time.rb +12 -0
  63. data/lib/mongomodel/version.rb +3 -0
  64. data/spec/mongomodel/attributes/store_spec.rb +273 -0
  65. data/spec/mongomodel/concerns/activemodel_spec.rb +61 -0
  66. data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +153 -0
  67. data/spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb +165 -0
  68. data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +192 -0
  69. data/spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb +46 -0
  70. data/spec/mongomodel/concerns/attribute_methods/dirty_spec.rb +131 -0
  71. data/spec/mongomodel/concerns/attribute_methods/protected_spec.rb +86 -0
  72. data/spec/mongomodel/concerns/attribute_methods/query_spec.rb +27 -0
  73. data/spec/mongomodel/concerns/attribute_methods/read_spec.rb +52 -0
  74. data/spec/mongomodel/concerns/attribute_methods/write_spec.rb +43 -0
  75. data/spec/mongomodel/concerns/attributes_spec.rb +152 -0
  76. data/spec/mongomodel/concerns/callbacks_spec.rb +90 -0
  77. data/spec/mongomodel/concerns/logging_spec.rb +20 -0
  78. data/spec/mongomodel/concerns/pretty_inspect_spec.rb +68 -0
  79. data/spec/mongomodel/concerns/properties_spec.rb +29 -0
  80. data/spec/mongomodel/concerns/timestamps_spec.rb +170 -0
  81. data/spec/mongomodel/concerns/validations_spec.rb +159 -0
  82. data/spec/mongomodel/document/callbacks_spec.rb +80 -0
  83. data/spec/mongomodel/document/dynamic_finders_spec.rb +183 -0
  84. data/spec/mongomodel/document/finders_spec.rb +231 -0
  85. data/spec/mongomodel/document/indexes_spec.rb +121 -0
  86. data/spec/mongomodel/document/optimistic_locking_spec.rb +57 -0
  87. data/spec/mongomodel/document/persistence_spec.rb +319 -0
  88. data/spec/mongomodel/document/scopes_spec.rb +204 -0
  89. data/spec/mongomodel/document/validations/uniqueness_spec.rb +217 -0
  90. data/spec/mongomodel/document/validations_spec.rb +132 -0
  91. data/spec/mongomodel/document_spec.rb +74 -0
  92. data/spec/mongomodel/embedded_document_spec.rb +66 -0
  93. data/spec/mongomodel/mongomodel_spec.rb +33 -0
  94. data/spec/mongomodel/support/collection_spec.rb +248 -0
  95. data/spec/mongomodel/support/mongo_options_spec.rb +295 -0
  96. data/spec/mongomodel/support/property_spec.rb +83 -0
  97. data/spec/spec.opts +6 -0
  98. data/spec/spec_helper.rb +21 -0
  99. data/spec/specdoc.opts +6 -0
  100. data/spec/support/callbacks.rb +44 -0
  101. data/spec/support/helpers/define_class.rb +24 -0
  102. data/spec/support/helpers/specs_for.rb +11 -0
  103. data/spec/support/matchers/be_a_subclass_of.rb +5 -0
  104. data/spec/support/matchers/respond_to_boolean.rb +17 -0
  105. data/spec/support/matchers/run_callbacks.rb +20 -0
  106. data/spec/support/models.rb +23 -0
  107. data/spec/support/time.rb +6 -0
  108. metadata +232 -0
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ module MongoModel
4
+ specs_for(Document) do
5
+ describe "callbacks" do
6
+ define_class(:CallbackTestDocument, Document) do
7
+ include MongoModel::CallbackHelpers
8
+ end
9
+
10
+ let(:doc) { CallbackTestDocument.create! }
11
+
12
+ it "should run each type of callback when initializing" do
13
+ instance = CallbackTestDocument.new
14
+ instance.should run_callbacks(:after_initialize)
15
+ end
16
+
17
+ it "should run each type of callback on find" do
18
+ instance = CallbackTestDocument.find(doc.id)
19
+ instance.should run_callbacks(:after_initialize, :after_find)
20
+ end
21
+
22
+ it "should run each type of callback when validating a new document" do
23
+ instance = CallbackTestDocument.new
24
+ instance.valid?
25
+ instance.should run_callbacks(:after_initialize, :before_validation, :after_validation)
26
+ end
27
+
28
+ it "should run each type of callback when validating an existing document" do
29
+ instance = CallbackTestDocument.find(doc.id)
30
+ instance.valid?
31
+ instance.should run_callbacks(:after_initialize, :after_find, :before_validation, :after_validation)
32
+ end
33
+
34
+ it "should run each type of callback when creating a document" do
35
+ instance = CallbackTestDocument.create!
36
+ instance.should run_callbacks(:after_initialize, :before_validation, :after_validation, :before_save, :before_create, :after_create, :after_save)
37
+ end
38
+
39
+ it "should run each type of callback when saving an existing document" do
40
+ instance = CallbackTestDocument.find(doc.id)
41
+ instance.save
42
+ instance.should run_callbacks(:after_initialize, :after_find, :before_validation, :after_validation, :before_save, :before_update, :after_update, :after_save)
43
+ end
44
+
45
+ it "should run each type of callback when destroying a document" do
46
+ instance = CallbackTestDocument.find(doc.id)
47
+ instance.destroy
48
+ instance.should run_callbacks(:after_initialize, :after_find, :before_destroy, :after_destroy)
49
+ end
50
+
51
+ it "should not run destroy callbacks when deleting a document" do
52
+ instance = CallbackTestDocument.find(doc.id)
53
+ instance.delete
54
+ instance.should run_callbacks(:after_initialize, :after_find)
55
+ end
56
+ end
57
+
58
+ [ :before_save, :before_create ].each do |callback|
59
+ context "#{callback} callback return false" do
60
+ define_class(:CallbackTestDocument, Document) do
61
+ send(callback) { false }
62
+ end
63
+
64
+ subject { CallbackTestDocument.new }
65
+
66
+ describe "#save" do
67
+ it "should return false" do
68
+ subject.save.should be_false
69
+ end
70
+ end
71
+
72
+ describe "#save!" do
73
+ it "should raise a MongoModel::DocumentNotSaved exception" do
74
+ lambda { subject.save! }.should raise_error(MongoModel::DocumentNotSaved)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,183 @@
1
+ require 'spec_helper'
2
+
3
+ module MongoModel
4
+ specs_for(Document) do
5
+ describe "dynamic finders" do
6
+ define_class(:Person, Document) do
7
+ property :name, String
8
+ property :age, Integer
9
+ end
10
+
11
+ subject { Person }
12
+
13
+ before(:each) do
14
+ @john = Person.create!(:name => 'John', :age => 42, :id => '1')
15
+ @young_john = Person.create!(:name => 'John', :age => 12, :id => '2')
16
+ @tom1 = Person.create!(:name => 'Tom', :age => 23, :id => '3')
17
+ @tom2 = Person.create!(:name => 'Tom', :age => 23, :id => '4')
18
+ @mary = Person.create!(:name => 'Mary', :age => 33, :id => '5')
19
+ end
20
+
21
+ shared_examples_for "a dynamic finder" do
22
+ it { should respond_to(valid_finder) }
23
+ it { should_not respond_to(invalid_finder) }
24
+
25
+ it "should raise NoMethodError calling an invalid finder" do
26
+ lambda { subject.send(invalid_finder, "Foo") }.should raise_error(NoMethodError)
27
+ end
28
+
29
+ def self.should_find(*args, &block)
30
+ it "should return correct results when called with #{args.inspect}" do
31
+ expected = instance_eval(&block)
32
+ subject.send(valid_finder, *args).should == expected
33
+ end
34
+ end
35
+
36
+ def self.should_raise(*args, &block)
37
+ it "should raise DocumentNotFound exception if results not found" do
38
+ message = instance_eval(&block)
39
+ lambda { subject.send(valid_finder, *args) }.should raise_error(DocumentNotFound, message)
40
+ end
41
+ end
42
+
43
+ def self.should_initialize(*args, &block)
44
+ it "should initialize new instance" do
45
+ result = subject.send(valid_finder, *args)
46
+ result.should be_a_new_record
47
+ result.should be_an_instance_of(Person)
48
+ yield(result).should be_true
49
+ end
50
+ end
51
+
52
+ def self.should_create(*args, &block)
53
+ it "should create new instance" do
54
+ result = subject.send(valid_finder, *args)
55
+ result.should_not be_a_new_record
56
+ result.should be_an_instance_of(Person)
57
+ yield(result).should be_true
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "find first by single property" do
63
+ let(:valid_finder) { :find_by_name }
64
+ let(:invalid_finder) { :find_by_something_else }
65
+
66
+ it_should_behave_like "a dynamic finder"
67
+
68
+ should_find("John") { @john }
69
+ should_find("John", :conditions => { :age.lt => 20 }) { @young_john }
70
+ should_find("Jane") { nil }
71
+ end
72
+
73
+ describe "find first by single property (bang method)" do
74
+ let(:valid_finder) { :find_by_name! }
75
+ let(:invalid_finder) { :find_by_something_else! }
76
+
77
+ it_should_behave_like "a dynamic finder"
78
+
79
+ should_find("John") { @john }
80
+ should_raise("Jane") { 'Couldn\'t find Person with {:name=>"Jane"}' }
81
+ end
82
+
83
+ describe "find last by single property" do
84
+ let(:valid_finder) { :find_last_by_name }
85
+ let(:invalid_finder) { :find_last_by_something_else }
86
+
87
+ it_should_behave_like "a dynamic finder"
88
+
89
+ should_find("John") { @young_john }
90
+ should_find("Jane") { nil }
91
+ end
92
+
93
+ describe "find all by single property" do
94
+ let(:valid_finder) { :find_all_by_name }
95
+ let(:invalid_finder) { :find_all_by_something_else }
96
+
97
+ it_should_behave_like "a dynamic finder"
98
+
99
+ should_find("John") { [@john, @young_john] }
100
+ end
101
+
102
+ describe "find first by multiple properties" do
103
+ let(:valid_finder) { :find_by_name_and_age }
104
+ let(:invalid_finder) { :find_by_age_and_something_else }
105
+
106
+ it_should_behave_like "a dynamic finder"
107
+
108
+ should_find("Tom", 23) { @tom1 }
109
+ should_find("Tom", 5) { nil }
110
+ end
111
+
112
+ describe "find first by multiple properties (bang method)" do
113
+ let(:valid_finder) { :find_by_name_and_age! }
114
+ let(:invalid_finder) { :find_by_age_and_something_else! }
115
+
116
+ it_should_behave_like "a dynamic finder"
117
+
118
+ should_find("Tom", 23) { @tom1 }
119
+ should_raise("Tom", 5) { "Couldn\'t find Person with #{{:name=>"Tom", :age=>5}.inspect}" }
120
+ end
121
+
122
+ describe "find all by multiple properties" do
123
+ let(:valid_finder) { :find_all_by_name_and_age }
124
+ let(:invalid_finder) { :find_all_by_age_and_something_else }
125
+
126
+ it_should_behave_like "a dynamic finder"
127
+
128
+ should_find("Tom", 23) { [@tom1, @tom2] }
129
+ should_find("Tom", 5) { [] }
130
+ end
131
+
132
+ describe "find last by multiple properties" do
133
+ let(:valid_finder) { :find_last_by_name_and_age }
134
+ let(:invalid_finder) { :find_last_by_age_and_something_else }
135
+
136
+ it_should_behave_like "a dynamic finder"
137
+
138
+ should_find("Tom", 23) { @tom2 }
139
+ should_find("Tom", 5) { nil }
140
+ end
141
+
142
+ describe "find or initialize by single property" do
143
+ let(:valid_finder) { :find_or_initialize_by_name }
144
+ let(:invalid_finder) { :find_or_initialize_by_something_else }
145
+
146
+ it_should_behave_like "a dynamic finder"
147
+
148
+ should_find("John") { @john }
149
+ should_initialize("Jane") { |p| p.name == "Jane" }
150
+ end
151
+
152
+ describe "find or initialize by multiple properties" do
153
+ let(:valid_finder) { :find_or_initialize_by_name_and_age }
154
+ let(:invalid_finder) { :find_or_initialize_by_name_and_something_else }
155
+
156
+ it_should_behave_like "a dynamic finder"
157
+
158
+ should_find("John", 42) { @john }
159
+ should_initialize("John", 1) { |p| p.name == "John" && p.age == 1 }
160
+ end
161
+
162
+ describe "find or create by single property" do
163
+ let(:valid_finder) { :find_or_create_by_name }
164
+ let(:invalid_finder) { :find_or_create_by_something_else }
165
+
166
+ it_should_behave_like "a dynamic finder"
167
+
168
+ should_find("John") { @john }
169
+ should_create("Jane") { |p| p.name == "Jane" }
170
+ end
171
+
172
+ describe "find or create by multiple properties" do
173
+ let(:valid_finder) { :find_or_create_by_name_and_age }
174
+ let(:invalid_finder) { :find_or_create_by_name_and_something_else }
175
+
176
+ it_should_behave_like "a dynamic finder"
177
+
178
+ should_find("John", 42) { @john }
179
+ should_create("John", 1) { |p| p.name == "John" && p.age == 1 }
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,231 @@
1
+ require 'spec_helper'
2
+
3
+ module MongoModel
4
+ describe Document do
5
+ define_class(:User, Document) do
6
+ property :name, String
7
+ property :age, Integer
8
+ end
9
+
10
+ define_class(:NonUser, Document)
11
+
12
+ describe "#find" do
13
+ before(:each) do
14
+ User.collection.save({ '_id' => '1', 'name' => 'Fred', :age => 45 })
15
+ User.collection.save({ '_id' => '2', 'name' => 'Alistair', :age => 18 })
16
+ User.collection.save({ '_id' => '3', 'name' => 'Barney', :age => 10 })
17
+ end
18
+
19
+ describe "by id" do
20
+ context "document exists" do
21
+ subject { User.find('2') }
22
+
23
+ it "should return a User" do
24
+ subject.should be_a(User)
25
+ end
26
+
27
+ it "should load the document attributes" do
28
+ subject.id.should == '2'
29
+ subject.name.should == 'Alistair'
30
+ end
31
+
32
+ it { should_not be_a_new_record }
33
+
34
+ it "should stringify ids" do
35
+ User.find(2).id.should == '2'
36
+ end
37
+ end
38
+
39
+ context "document does not exist" do
40
+ it "should raise a DocumentNotFound exception" do
41
+ lambda {
42
+ User.find('4')
43
+ }.should raise_error(MongoModel::DocumentNotFound)
44
+ end
45
+ end
46
+
47
+ context "no id specified" do
48
+ it "should raise an ArgumentError" do
49
+ lambda {
50
+ User.find
51
+ }.should raise_error(ArgumentError)
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "by multiple ids" do
57
+ context "all documents exist" do
58
+ subject { User.find('1', '2') }
59
+
60
+ it "should return an array of Users" do
61
+ subject[0].should be_a(User)
62
+ subject[1].should be_a(User)
63
+ end
64
+
65
+ it "should load document attributes" do
66
+ subject[0].name.should == 'Fred'
67
+ subject[1].name.should == 'Alistair'
68
+ end
69
+
70
+ it "should load documents in correct order" do
71
+ result = User.find('2', '1')
72
+ result[0].id.should == '2'
73
+ result[1].id.should == '1'
74
+ end
75
+ end
76
+
77
+ context "some documents missing" do
78
+ it "should raise a DocumentNotFound exception" do
79
+ lambda {
80
+ User.find('1', '2', '4')
81
+ }.should raise_error(MongoModel::DocumentNotFound)
82
+ end
83
+ end
84
+ end
85
+
86
+ describe "first" do
87
+ context "documents exist" do
88
+ subject { User.find(:first) }
89
+
90
+ it "should return the first document" do
91
+ subject.id.should == '1'
92
+ subject.name.should == 'Fred'
93
+ end
94
+
95
+ it "should be aliased as #first" do
96
+ User.first.should == subject
97
+ end
98
+
99
+ context "with order" do
100
+ it "should find first document by order" do
101
+ User.find(:first, :order => :name.asc).name.should == 'Alistair'
102
+ end
103
+ end
104
+ end
105
+
106
+ context "no documents" do
107
+ before(:each) { User.collection.remove }
108
+
109
+ it "should return nil" do
110
+ User.find(:first).should be_nil
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "last" do
116
+ context "documents exist" do
117
+ subject { User.find(:last) }
118
+
119
+ it "should return the last document (by id)" do
120
+ subject.id.should == '3'
121
+ subject.name.should == 'Barney'
122
+ end
123
+
124
+ it "should be aliased as #last" do
125
+ User.last.should == subject
126
+ end
127
+
128
+ context "with order" do
129
+ it "should find last document by order" do
130
+ User.find(:last, :order => :name.asc).name.should == 'Fred'
131
+ end
132
+ end
133
+ end
134
+
135
+ context "no documents" do
136
+ before(:each) { User.collection.remove }
137
+
138
+ it "should return nil" do
139
+ User.find(:last).should be_nil
140
+ end
141
+ end
142
+ end
143
+
144
+ describe "all" do
145
+ subject { User.find(:all, :order => 'id ASC') }
146
+
147
+ it "should return all documents as User instances" do
148
+ subject.should have(3).users
149
+ subject.each { |d| d.should be_a(User) }
150
+ end
151
+
152
+ it "should load attributes for each document" do
153
+ subject[0].name.should == 'Fred'
154
+ subject[1].name.should == 'Alistair'
155
+ subject[2].name.should == 'Barney'
156
+ end
157
+
158
+ it "should be aliased as #all" do
159
+ User.all.should == subject
160
+ end
161
+
162
+ context "with exact-match conditions" do
163
+ subject { User.find(:all, :conditions => { :name => 'Alistair' }) }
164
+
165
+ it "should only return documents matching conditions" do
166
+ subject.should have(1).user
167
+ subject[0].name.should == 'Alistair'
168
+ end
169
+ end
170
+
171
+ context "with inequality conditions" do
172
+ subject { User.find(:all, :conditions => { :age.lt => 21 }) }
173
+
174
+ it "should only return documents matching conditions" do
175
+ subject.should have(2).users
176
+ subject[0].name.should == 'Alistair'
177
+ subject[1].name.should == 'Barney'
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ describe "#count" do
184
+ before(:each) do
185
+ 5.times { User.create(:age => 18) }
186
+ 7.times { User.create(:age => 42) }
187
+ 3.times { NonUser.create }
188
+ end
189
+
190
+ context "without arguments" do
191
+ it "should return the count for that particular model" do
192
+ User.count.should == 12
193
+ NonUser.count.should == 3
194
+ end
195
+ end
196
+
197
+ context "with conditions" do
198
+ it "should return the count for the model that match the conditions" do
199
+ User.count(:age => 18).should == 5
200
+ User.count(:age.gte => 18).should == 12
201
+ end
202
+ end
203
+ end
204
+
205
+ describe "#exists?" do
206
+ before(:each) do
207
+ User.create(:id => 'user-1', :name => 'Test', :age => 10)
208
+ end
209
+
210
+ context "by id" do
211
+ it "should return true if the document exists" do
212
+ User.exists?('user-1').should == true
213
+ end
214
+
215
+ it "should return false if the document does not exist" do
216
+ User.exists?('user-2').should == false
217
+ end
218
+ end
219
+
220
+ context "by conditions" do
221
+ it "should return true if the document exists" do
222
+ User.exists?(:name => 'Test').should == true
223
+ end
224
+
225
+ it "should return false if the document does not exist" do
226
+ User.exists?(:name => 'Nonexistant').should == false
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end