pwnash-mongo_mapper 0.7.5 → 0.7.6

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/lib/mongo_mapper.rb +6 -8
  2. data/lib/mongo_mapper/document.rb +6 -281
  3. data/lib/mongo_mapper/embedded_document.rb +5 -45
  4. data/lib/mongo_mapper/extensions.rb +190 -0
  5. data/lib/mongo_mapper/plugins.rb +27 -18
  6. data/lib/mongo_mapper/plugins/associations.rb +7 -6
  7. data/lib/mongo_mapper/plugins/associations/base.rb +1 -0
  8. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +1 -0
  9. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +1 -0
  10. data/lib/mongo_mapper/plugins/associations/collection.rb +1 -0
  11. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +1 -0
  12. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +2 -1
  13. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +1 -0
  14. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +4 -4
  15. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +1 -0
  16. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +1 -0
  17. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +1 -0
  18. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +1 -0
  19. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +1 -0
  20. data/lib/mongo_mapper/plugins/associations/proxy.rb +1 -0
  21. data/lib/mongo_mapper/plugins/callbacks.rb +4 -3
  22. data/lib/mongo_mapper/plugins/clone.rb +1 -0
  23. data/lib/mongo_mapper/plugins/descendants.rb +1 -0
  24. data/lib/mongo_mapper/plugins/dirty.rb +1 -0
  25. data/lib/mongo_mapper/plugins/document.rb +40 -0
  26. data/lib/mongo_mapper/plugins/dynamic_querying.rb +42 -0
  27. data/lib/mongo_mapper/{support/find.rb → plugins/dynamic_querying/dynamic_finder.rb} +2 -36
  28. data/lib/mongo_mapper/plugins/embedded_document.rb +48 -0
  29. data/lib/mongo_mapper/plugins/equality.rb +1 -0
  30. data/lib/mongo_mapper/plugins/identity_map.rb +8 -11
  31. data/lib/mongo_mapper/plugins/indexes.rb +11 -0
  32. data/lib/mongo_mapper/plugins/inspect.rb +1 -0
  33. data/lib/mongo_mapper/plugins/keys.rb +7 -9
  34. data/lib/mongo_mapper/plugins/keys/key.rb +12 -2
  35. data/lib/mongo_mapper/plugins/logger.rb +1 -0
  36. data/lib/mongo_mapper/plugins/modifiers.rb +3 -2
  37. data/lib/mongo_mapper/plugins/pagination.rb +1 -0
  38. data/lib/mongo_mapper/plugins/pagination/proxy.rb +1 -0
  39. data/lib/mongo_mapper/plugins/persistence.rb +1 -0
  40. data/lib/mongo_mapper/plugins/protected.rb +1 -0
  41. data/lib/mongo_mapper/plugins/query_logger.rb +5 -10
  42. data/lib/mongo_mapper/plugins/querying.rb +236 -0
  43. data/lib/mongo_mapper/plugins/rails.rb +1 -0
  44. data/lib/mongo_mapper/plugins/sci.rb +31 -0
  45. data/lib/mongo_mapper/plugins/serialization.rb +1 -0
  46. data/lib/mongo_mapper/plugins/timestamps.rb +1 -0
  47. data/lib/mongo_mapper/plugins/userstamps.rb +1 -0
  48. data/lib/mongo_mapper/plugins/validations.rb +5 -1
  49. data/lib/mongo_mapper/query.rb +53 -120
  50. data/lib/mongo_mapper/support.rb +2 -213
  51. data/lib/mongo_mapper/support/descendant_appends.rb +3 -6
  52. data/lib/mongo_mapper/version.rb +2 -1
  53. metadata +156 -190
  54. data/.gitignore +0 -10
  55. data/Rakefile +0 -37
  56. data/mongo_mapper.gemspec +0 -216
  57. data/performance/read_write.rb +0 -52
  58. data/specs.watchr +0 -51
  59. data/test/NOTE_ON_TESTING +0 -1
  60. data/test/active_model_lint_test.rb +0 -13
  61. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +0 -63
  62. data/test/functional/associations/test_belongs_to_proxy.rb +0 -101
  63. data/test/functional/associations/test_in_array_proxy.rb +0 -325
  64. data/test/functional/associations/test_many_documents_as_proxy.rb +0 -229
  65. data/test/functional/associations/test_many_documents_proxy.rb +0 -536
  66. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +0 -176
  67. data/test/functional/associations/test_many_embedded_proxy.rb +0 -256
  68. data/test/functional/associations/test_many_polymorphic_proxy.rb +0 -302
  69. data/test/functional/associations/test_one_embedded_proxy.rb +0 -68
  70. data/test/functional/associations/test_one_proxy.rb +0 -196
  71. data/test/functional/test_associations.rb +0 -44
  72. data/test/functional/test_binary.rb +0 -27
  73. data/test/functional/test_callbacks.rb +0 -151
  74. data/test/functional/test_dirty.rb +0 -163
  75. data/test/functional/test_document.rb +0 -1219
  76. data/test/functional/test_embedded_document.rb +0 -210
  77. data/test/functional/test_identity_map.rb +0 -507
  78. data/test/functional/test_indexing.rb +0 -44
  79. data/test/functional/test_logger.rb +0 -20
  80. data/test/functional/test_modifiers.rb +0 -416
  81. data/test/functional/test_pagination.rb +0 -93
  82. data/test/functional/test_protected.rb +0 -163
  83. data/test/functional/test_string_id_compatibility.rb +0 -67
  84. data/test/functional/test_timestamps.rb +0 -64
  85. data/test/functional/test_userstamps.rb +0 -28
  86. data/test/functional/test_validations.rb +0 -342
  87. data/test/models.rb +0 -227
  88. data/test/support/custom_matchers.rb +0 -37
  89. data/test/support/timing.rb +0 -16
  90. data/test/test_helper.rb +0 -64
  91. data/test/unit/associations/test_base.rb +0 -212
  92. data/test/unit/associations/test_proxy.rb +0 -105
  93. data/test/unit/serializers/test_json_serializer.rb +0 -202
  94. data/test/unit/test_descendant_appends.rb +0 -71
  95. data/test/unit/test_document.rb +0 -225
  96. data/test/unit/test_dynamic_finder.rb +0 -123
  97. data/test/unit/test_embedded_document.rb +0 -657
  98. data/test/unit/test_keys.rb +0 -216
  99. data/test/unit/test_mongo_mapper.rb +0 -118
  100. data/test/unit/test_pagination.rb +0 -160
  101. data/test/unit/test_plugins.rb +0 -50
  102. data/test/unit/test_query.rb +0 -374
  103. data/test/unit/test_rails.rb +0 -181
  104. data/test/unit/test_rails_compatibility.rb +0 -52
  105. data/test/unit/test_serialization.rb +0 -51
  106. data/test/unit/test_support.rb +0 -390
  107. data/test/unit/test_time_zones.rb +0 -39
  108. data/test/unit/test_validations.rb +0 -544
@@ -1,93 +0,0 @@
1
- require 'test_helper'
2
-
3
- class PaginationTest < Test::Unit::TestCase
4
- context "Paginating" do
5
- setup do
6
- @document = Doc do
7
- set_collection_name 'users'
8
-
9
- key :first_name, String
10
- key :last_name, String
11
- key :age, Integer
12
-
13
- def self.per_page; 1 end
14
- end
15
-
16
- @doc1 = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
17
- @doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
18
- @doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
19
- end
20
-
21
- should "return the total pages" do
22
- result = @document.paginate(:per_page => 2, :page => 1)
23
- result.total_pages.should == 2
24
- end
25
-
26
- should "return the total pages when defaulting to the document class per_page" do
27
- result = @document.paginate(:page => 1)
28
- result.total_pages.should == 3
29
- end
30
-
31
- should "return the total of records" do
32
- result = @document.paginate(:per_page => 2, :page => 1)
33
- result.total_entries.should == 3
34
- end
35
-
36
- should "return the items" do
37
- result = @document.paginate(:per_page => 2, :page => 1, :order => 'first_name')
38
- result.size.should == 2
39
- result.should == [@doc1, @doc3]
40
- end
41
-
42
- should "accept conditions" do
43
- result = @document.paginate({
44
- :last_name => 'Nunemaker',
45
- :order => "age DESC",
46
- :per_page => 2,
47
- :page => 1,
48
- })
49
- result.should == [@doc1, @doc3]
50
- result.first.age.should == 27
51
-
52
- result = @document.paginate({
53
- :conditions => {:last_name => 'Nunemaker'},
54
- :order => "age DESC",
55
- :per_page => 2,
56
- :page => 1} )
57
- result.should == [@doc1, @doc3]
58
- result.first.age.should == 27
59
- end
60
-
61
- should "withstand rigor" do
62
- result = @document.paginate({
63
- :per_page => 1,
64
- :page => 1,
65
- :order => 'age desc',
66
- :last_name => 'Nunemaker'
67
- })
68
- result.should == [@doc1]
69
- result.total_entries.should == 2
70
- result.total_pages.should == 2
71
-
72
- result = @document.paginate({
73
- :per_page => 1,
74
- :page => 2,
75
- :order => 'age desc',
76
- :last_name => 'Nunemaker'
77
- })
78
- result.should == [@doc3]
79
- result.total_entries.should == 2
80
- result.total_pages.should == 2
81
-
82
- result = @document.paginate({
83
- :per_page => 2,
84
- :page => 1,
85
- :order => 'age desc',
86
- :last_name => 'Nunemaker'
87
- })
88
- result.should == [@doc1, @doc3]
89
- result.total_entries.should == 2
90
- result.total_pages.should == 1
91
- end
92
- end
93
- end
@@ -1,163 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ProtectedTest < Test::Unit::TestCase
4
- context 'A document with protected attributes' do
5
- setup do
6
- @doc_class = Doc do
7
- key :name, String
8
- key :admin, Boolean, :default => false
9
-
10
- attr_protected :admin
11
- end
12
-
13
- @doc = @doc_class.create(:name => 'Steve Sloan')
14
- end
15
-
16
- should 'have protected attributes class method' do
17
- @doc_class.protected_attributes.should == [:admin].to_set
18
- end
19
-
20
- should "default protected attributes to nil" do
21
- Doc().protected_attributes.should be_nil
22
- end
23
-
24
- should "have protected attributes instance method" do
25
- @doc.protected_attributes.should equal(@doc_class.protected_attributes)
26
- end
27
-
28
- should "work with :protected shortcut when defining key" do
29
- Doc() do
30
- key :user_id, ObjectId, :protected => true
31
- end.protected_attributes.should == [:user_id].to_set
32
- end
33
-
34
- should 'assign protected attribute through accessor' do
35
- @doc.admin = true
36
- @doc.admin.should be_true
37
- end
38
-
39
- should "ignore protected attribute on #initialize" do
40
- doc = @doc_class.new(:name => 'John', :admin => true)
41
- doc.admin.should be_false
42
- doc.name.should == 'John'
43
- end
44
-
45
- should "not ignore protected attributes on #initialize from the database" do
46
- doc = @doc_class.new(:name => 'John')
47
- doc.admin = true
48
- doc.save!
49
-
50
- doc = @doc_class.first(:name => 'John')
51
- doc.admin.should be_true
52
- doc.name.should == 'John'
53
- end
54
-
55
- should 'ignore protected attribute on #update_attributes' do
56
- @doc.update_attributes(:name => 'Ren Hoek', :admin => true)
57
- @doc.name.should == 'Ren Hoek'
58
- @doc.admin.should be_false
59
- end
60
-
61
- should 'ignore protected attribute on #update_attributes!' do
62
- @doc.update_attributes!(:name => 'Stimpson J. Cat', :admin => true)
63
- @doc.name.should == 'Stimpson J. Cat'
64
- @doc.admin.should be_false
65
- end
66
-
67
- should 'be indifferent to whether the protected keys are strings or symbols' do
68
- @doc.update_attributes!("name" => 'Stimpson J. Cat', "admin" => true)
69
- @doc.name.should == 'Stimpson J. Cat'
70
- @doc.admin.should be_false
71
- end
72
-
73
- should "accept nil as constructor's argument without raising exception" do
74
- lambda { @doc_class.new(nil) }.should_not raise_error
75
- end
76
- end
77
-
78
- context "Single collection inherited protected attributes" do
79
- setup do
80
- class ::GrandParent
81
- include MongoMapper::Document
82
-
83
- key :site_id, ObjectId
84
- attr_protected :site_id
85
- end
86
- GrandParent.collection.remove
87
-
88
- class ::Child < ::GrandParent
89
- key :position, Integer
90
-
91
- attr_protected :position
92
- end
93
-
94
- class ::GrandChild < ::Child; end
95
-
96
- class ::OtherChild < ::GrandParent
97
- key :blog_id, ObjectId
98
-
99
- attr_protected :blog_id
100
- end
101
- end
102
-
103
- teardown do
104
- Object.send :remove_const, 'GrandParent' if defined?(::GrandParent)
105
- Object.send :remove_const, 'Child' if defined?(::Child)
106
- Object.send :remove_const, 'GrandChild' if defined?(::GrandChild)
107
- Object.send :remove_const, 'OtherChild' if defined?(::OtherChild)
108
- end
109
-
110
- should "share keys down the inheritance trail" do
111
- GrandParent.protected_attributes.should == [:site_id].to_set
112
- Child.protected_attributes.should == [:site_id, :position].to_set
113
- GrandChild.protected_attributes.should == [:site_id, :position].to_set
114
- OtherChild.protected_attributes.should == [:site_id, :blog_id].to_set
115
- end
116
- end
117
-
118
- context 'An embedded document with protected attributes' do
119
- setup do
120
- @doc_class = Doc('Project')
121
- @edoc_class = EDoc('Person') do
122
- key :name, String
123
- key :admin, Boolean, :default => false
124
-
125
- attr_protected :admin
126
- end
127
- @doc_class.many :people, :class => @edoc_class
128
-
129
- @doc = @doc_class.create(:title => 'MongoMapper')
130
- @edoc = @edoc_class.new(:name => 'Steve Sloan')
131
- @doc.people << @edoc
132
- end
133
-
134
- should 'have protected attributes class method' do
135
- @edoc_class.protected_attributes.should == [:admin].to_set
136
- end
137
-
138
- should "default protected attributes to nil" do
139
- EDoc().protected_attributes.should be_nil
140
- end
141
-
142
- should "have protected attributes instance method" do
143
- @edoc.protected_attributes.should equal(@edoc_class.protected_attributes)
144
- end
145
-
146
- should 'assign protected attribute through accessor' do
147
- @edoc.admin = true
148
- @edoc.admin.should be_true
149
- end
150
-
151
- should 'ignore protected attribute on #update_attributes' do
152
- @edoc.update_attributes(:name => 'Ren Hoek', :admin => true)
153
- @edoc.name.should == 'Ren Hoek'
154
- @edoc.admin.should be_false
155
- end
156
-
157
- should 'ignore protected attribute on #update_attributes!' do
158
- @edoc.update_attributes!(:name => 'Stimpson J. Cat', :admin => true)
159
- @edoc.name.should == 'Stimpson J. Cat'
160
- @edoc.admin.should be_false
161
- end
162
- end
163
- end
@@ -1,67 +0,0 @@
1
- require 'test_helper'
2
-
3
- class StringIdCompatibilityTest < Test::Unit::TestCase
4
- def setup
5
- @note_class = EDoc do
6
- key :_id, String
7
- end
8
-
9
- @task_class = Doc do
10
- key :_id, String
11
- key :project_id, String
12
- belongs_to :project
13
- end
14
-
15
- @project_class = Doc do
16
- include MongoMapper::Document
17
- key :_id, String
18
- end
19
-
20
- @task_class.belongs_to :project, :class => @project_class
21
- @project_class.many :notes, :class => @note_class
22
- @project_class.many :tasks, :class => @task_class, :foreign_key => 'project_id', :order => :position.asc
23
- end
24
-
25
- should "assign correct _id for documents" do
26
- project = @project_class.create
27
- project._id.should == project.id
28
- project._id.should be_instance_of(String)
29
- project.id.size.should == 24
30
- lambda {
31
- BSON::ObjectID.from_string(project.id)
32
- }.should_not raise_error
33
- end
34
-
35
- should "assign correct _id for embedded documents" do
36
- note = @note_class.new
37
- note.id.should == note._id
38
- note.id.size.should == 24
39
- end
40
-
41
- should "find records" do
42
- project = @project_class.create
43
- @project_class.find(project.id).should == project
44
- end
45
-
46
- should "save embedded docs" do
47
- n1 = @note_class.new
48
- n2 = @note_class.new
49
- n3 = @note_class.new
50
- project = @project_class.create(:notes => [n1, n2, n3])
51
-
52
- project = project.reload
53
- project.notes.size.should == 3
54
- project.notes.should == [n1, n2, n3]
55
- end
56
-
57
- should "be able to associate records" do
58
- t1 = @task_class.new(:body => 'First task', :position => 1)
59
- t2 = @task_class.new(:body => 'Second task', :position => 2)
60
- t3 = @task_class.new(:body => 'Third task', :position => 3)
61
- project = @project_class.create(:name => 'MM', :tasks => [t1, t2, t3])
62
-
63
- project = project.reload
64
- project.tasks.count.should == 3
65
- project.tasks.should == [t1, t2, t3]
66
- end
67
- end
@@ -1,64 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TimestampsTest < Test::Unit::TestCase
4
- context "timestamping" do
5
- setup do
6
- @klass = Doc do
7
- set_collection_name 'users'
8
-
9
- key :first_name, String
10
- key :last_name, String
11
- key :age, Integer
12
- key :date, Date
13
- end
14
- @klass.timestamps!
15
- end
16
-
17
- should "set created_at and updated_at on create" do
18
- doc = @klass.new(:first_name => 'John', :age => 27)
19
- doc.created_at.should be(nil)
20
- doc.updated_at.should be(nil)
21
- doc.save
22
- doc.created_at.should_not be(nil)
23
- doc.updated_at.should_not be(nil)
24
- end
25
-
26
- should "not overwrite created_at if it already exists" do
27
- original_created_at = 1.month.ago
28
- doc = @klass.new(:first_name => 'John', :age => 27, :created_at => original_created_at)
29
- doc.created_at.to_i.should == original_created_at.to_i
30
- doc.updated_at.should be_nil
31
- doc.save
32
- doc.created_at.to_i.should == original_created_at.to_i
33
- doc.updated_at.should_not be_nil
34
- end
35
-
36
- should "set updated_at on field update but leave created_at alone" do
37
- doc = @klass.create(:first_name => 'John', :age => 27)
38
- old_created_at = doc.created_at
39
- old_updated_at = doc.updated_at
40
- doc.first_name = 'Johnny'
41
-
42
- Timecop.freeze(Time.now + 5.seconds) do
43
- doc.save
44
- end
45
-
46
- doc.created_at.should == old_created_at
47
- doc.updated_at.should_not == old_updated_at
48
- end
49
-
50
- should "set updated_at on document update but leave created_at alone" do
51
- doc = @klass.create(:first_name => 'John', :age => 27)
52
- old_created_at = doc.created_at
53
- old_updated_at = doc.updated_at
54
-
55
- Timecop.freeze(Time.now + 5.seconds) do
56
- @klass.update(doc._id, { :first_name => 'Johnny' })
57
- end
58
-
59
- doc = doc.reload
60
- doc.created_at.should == old_created_at
61
- doc.updated_at.should_not == old_updated_at
62
- end
63
- end
64
- end
@@ -1,28 +0,0 @@
1
- require 'test_helper'
2
-
3
- class UserstampsTest < Test::Unit::TestCase
4
- context "userstamping" do
5
- setup do
6
- @document = Doc do
7
- set_collection_name 'users'
8
- userstamps!
9
- end
10
- end
11
-
12
- should "add creator_id key" do
13
- @document.keys.keys.should include('creator_id')
14
- end
15
-
16
- should "add updater_id key" do
17
- @document.keys.keys.should include('updater_id')
18
- end
19
-
20
- should "add belongs_to creator" do
21
- @document.associations.keys.should include('creator')
22
- end
23
-
24
- should "add belongs_to updater" do
25
- @document.associations.keys.should include('updater')
26
- end
27
- end
28
- end
@@ -1,342 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ValidationsTest < Test::Unit::TestCase
4
- context "Saving a new document that is invalid" do
5
- setup do
6
- @document = Doc do
7
- key :name, String, :required => true
8
- end
9
- end
10
-
11
- should "not insert document" do
12
- doc = @document.new
13
- doc.save
14
- @document.count.should == 0
15
- end
16
-
17
- should "populate document's errors" do
18
- doc = @document.new
19
- doc.errors.size.should == 0
20
- doc.save
21
- doc.errors.full_messages.should == ["Name can't be empty"]
22
- end
23
- end
24
-
25
- context "Saving a document that is invalid (destructive)" do
26
- setup do
27
- @document = Doc do
28
- key :name, String, :required => true
29
- end
30
- end
31
-
32
- should "raise error" do
33
- doc = @document.new
34
- lambda { doc.save! }.should raise_error(MongoMapper::DocumentNotValid)
35
- end
36
- end
37
-
38
- context "Creating a document that is invalid (destructive)" do
39
- setup do
40
- @document = Doc do
41
- key :name, String, :required => true
42
- end
43
- end
44
-
45
- should "raise error" do
46
- lambda { @document.create! }.should raise_error(MongoMapper::DocumentNotValid)
47
- end
48
-
49
- should "create a new document" do
50
- instance = @document.create!(:name => "James")
51
- instance.new_record?.should be_false
52
- end
53
- end
54
-
55
- context "Saving an existing document that is invalid" do
56
- setup do
57
- @document = Doc do
58
- key :name, String, :required => true
59
- end
60
-
61
- @doc = @document.create(:name => 'John Nunemaker')
62
- end
63
-
64
- should "not update document" do
65
- @doc.name = nil
66
- @doc.save
67
- @doc.reload.name.should == 'John Nunemaker'
68
- end
69
-
70
- should "populate document's errors" do
71
- @doc.name = nil
72
- @doc.save
73
- @doc.errors.full_messages.should == ["Name can't be empty"]
74
- end
75
- end
76
-
77
- context "Adding validation errors" do
78
- setup do
79
- @document = Doc do
80
- key :action, String
81
- def action_present
82
- errors.add(:action, 'is invalid') if action.blank?
83
- end
84
- end
85
- end
86
-
87
- should "work with validate_on_create callback" do
88
- @document.validate_on_create :action_present
89
-
90
- doc = @document.new
91
- doc.action = nil
92
- doc.should have_error_on(:action)
93
-
94
- doc.action = 'kick'
95
- doc.should_not have_error_on(:action)
96
- doc.save
97
-
98
- doc.action = nil
99
- doc.should_not have_error_on(:action)
100
- end
101
-
102
- should "work with validate_on_update callback" do
103
- @document.validate_on_update :action_present
104
-
105
- doc = @document.new
106
- doc.action = nil
107
- doc.should_not have_error_on(:action)
108
- doc.save
109
-
110
- doc.action = nil
111
- doc.should have_error_on(:action)
112
-
113
- doc.action = 'kick'
114
- doc.should_not have_error_on(:action)
115
- end
116
- end
117
-
118
- context "validating uniqueness of" do
119
- setup do
120
- @document = Doc do
121
- key :name, String
122
- validates_uniqueness_of :name
123
- end
124
- end
125
-
126
- should "not fail if object is new" do
127
- doc = @document.new
128
- doc.should_not have_error_on(:name)
129
- end
130
-
131
- should "not fail when new object is out of scope" do
132
- document = Doc do
133
- key :name
134
- key :adult
135
- validates_uniqueness_of :name, :scope => :adult
136
- end
137
- doc = document.new("name" => "joe", :adult => true)
138
- doc.save.should be_true
139
-
140
- doc2 = document.new("name" => "joe", :adult => false)
141
- doc2.should be_valid
142
- end
143
-
144
- should "allow to update an object" do
145
- doc = @document.new("name" => "joe")
146
- doc.save.should be_true
147
-
148
- @document \
149
- .stubs(:first) \
150
- .with(:name => 'joe') \
151
- .returns(doc)
152
-
153
- doc.name = "joe"
154
- doc.valid?.should be_true
155
- doc.should_not have_error_on(:name)
156
- end
157
-
158
- should "fail if object name is not unique" do
159
- doc = @document.new("name" => "joe")
160
- doc.save.should be_true
161
-
162
- @document \
163
- .stubs(:first) \
164
- .with(:name => 'joe') \
165
- .returns(doc)
166
-
167
- doc2 = @document.new("name" => "joe")
168
- doc2.should have_error_on(:name)
169
- end
170
-
171
- should "allow multiple blank entries if :allow_blank => true" do
172
- document = Doc do
173
- key :name
174
- validates_uniqueness_of :name, :allow_blank => :true
175
- end
176
-
177
- doc = document.new("name" => "")
178
- doc.save.should be_true
179
-
180
- document \
181
- .stubs(:first) \
182
- .with(:name => '') \
183
- .returns(doc)
184
-
185
- doc2 = document.new("name" => "")
186
- doc2.should_not have_error_on(:name)
187
- end
188
-
189
- should "allow multiple nil entries if :allow_nil => true" do
190
- document = Doc do
191
- key :name
192
- validates_uniqueness_of :name, :allow_nil => :true
193
- end
194
-
195
- doc = document.new('name' => nil)
196
- doc.save.should be_true
197
-
198
- doc2 = document.new('name' => nil)
199
- doc2.should_not have_error_on(:name)
200
- end
201
-
202
- should "allow entries that differ only in case by default" do
203
- document = Doc do
204
- key :name
205
- validates_uniqueness_of :name
206
- end
207
-
208
- doc = document.new("name" => "BLAMMO")
209
- doc.save.should be_true
210
-
211
- doc2 = document.new("name" => "blammo")
212
- doc2.should_not have_error_on(:name)
213
- end
214
-
215
- context "with :case_sensitive => false" do
216
- setup do
217
- @document = Doc do
218
- key :name
219
- validates_uniqueness_of :name, :case_sensitive => false
220
- end
221
- end
222
-
223
- should "fail on entries that differ only in case" do
224
- doc = @document.new("name" => "BLAMMO")
225
- doc.save.should be_true
226
-
227
- doc2 = @document.new("name" => "blammo")
228
- doc2.should have_error_on(:name)
229
- end
230
-
231
- should "not raise an error if value is nil" do
232
- doc = @document.new("name" => nil)
233
- lambda { doc.valid? }.should_not raise_error
234
- end
235
-
236
- should "not raise an error if special Regexp characters used" do
237
- doc = @document.new("name" => '?')
238
- lambda { doc.valid? }.should_not raise_error
239
- end
240
-
241
- should "check for uniqueness using entire string" do
242
- doc = @document.new("name" => "John Doe")
243
- doc.save.should be_true
244
-
245
- doc2 = @document.new("name" => "John")
246
- doc2.valid?.should be_true
247
- end
248
- end
249
-
250
- context "scoped by a single attribute" do
251
- setup do
252
- @document = Doc do
253
- key :name, String
254
- key :scope, String
255
- validates_uniqueness_of :name, :scope => :scope
256
- end
257
- end
258
-
259
- should "fail if the same name exists in the scope" do
260
- doc = @document.new("name" => "joe", "scope" => "one")
261
- doc.save.should be_true
262
-
263
- @document \
264
- .stubs(:first) \
265
- .with(:name => 'joe', :scope => "one") \
266
- .returns(doc)
267
-
268
- doc2 = @document.new("name" => "joe", "scope" => "one")
269
- doc2.should have_error_on(:name)
270
- end
271
-
272
- should "pass if the same name exists in a different scope" do
273
- doc = @document.new("name" => "joe", "scope" => "one")
274
- doc.save.should be_true
275
-
276
- @document \
277
- .stubs(:first) \
278
- .with(:name => 'joe', :scope => 'two') \
279
- .returns(nil)
280
-
281
- doc2 = @document.new("name" => "joe", "scope" => "two")
282
- doc2.should_not have_error_on(:name)
283
- end
284
- end
285
-
286
- context "scoped by a multiple attributes" do
287
- setup do
288
- @document = Doc do
289
- key :name, String
290
- key :first_scope, String
291
- key :second_scope, String
292
- validates_uniqueness_of :name, :scope => [:first_scope, :second_scope]
293
- end
294
- end
295
-
296
- should "fail if the same name exists in the scope" do
297
- doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
298
- doc.save.should be_true
299
-
300
- @document \
301
- .stubs(:first) \
302
- .with(:name => 'joe', :first_scope => 'one', :second_scope => 'two') \
303
- .returns(doc)
304
-
305
- doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
306
- doc2.should have_error_on(:name)
307
- end
308
-
309
- should "pass if the same name exists in a different scope" do
310
- doc = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "two")
311
- doc.save.should be_true
312
-
313
- @document \
314
- .stubs(:first) \
315
- .with(:name => 'joe', :first_scope => 'one', :second_scope => 'one') \
316
- .returns(nil)
317
-
318
- doc2 = @document.new("name" => "joe", "first_scope" => "one", "second_scope" => "one")
319
- doc2.should_not have_error_on(:name)
320
- end
321
- end
322
- end
323
-
324
- context "validates uniqueness of with :unique shortcut" do
325
- should "work" do
326
- @document = Doc do
327
- key :name, String, :unique => true
328
- end
329
-
330
- doc = @document.create(:name => 'John')
331
- doc.should_not have_error_on(:name)
332
-
333
- @document \
334
- .stubs(:first) \
335
- .with(:name => 'John') \
336
- .returns(doc)
337
-
338
- second_john = @document.create(:name => 'John')
339
- second_john.should have_error_on(:name, 'has already been taken')
340
- end
341
- end
342
- end