mongomodel 0.5.5 → 0.5.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 (156) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +23 -11
  3. data/gemfiles/rails-3.2.gemfile +2 -2
  4. data/gemfiles/rails-4-observers.gemfile +1 -1
  5. data/gemfiles/rails-4.1.gemfile +2 -2
  6. data/gemfiles/{mongoid.gemfile → rails-4.2.gemfile} +2 -3
  7. data/gemfiles/{mongo_mapper.gemfile → rails-5.0.gemfile} +2 -3
  8. data/gemfiles/rails-5.1.gemfile +10 -0
  9. data/gemfiles/rails-5.2.gemfile +10 -0
  10. data/lib/mongomodel.rb +15 -15
  11. data/lib/mongomodel/attributes/mongo.rb +7 -7
  12. data/lib/mongomodel/attributes/store.rb +4 -4
  13. data/lib/mongomodel/attributes/typecasting.rb +7 -7
  14. data/lib/mongomodel/compatibility/mongo_mapper.rb +3 -3
  15. data/lib/mongomodel/compatibility/mongoid.rb +3 -3
  16. data/lib/mongomodel/concerns/abstract_class.rb +3 -3
  17. data/lib/mongomodel/concerns/activemodel.rb +4 -4
  18. data/lib/mongomodel/concerns/associations.rb +8 -8
  19. data/lib/mongomodel/concerns/associations/base/association.rb +5 -5
  20. data/lib/mongomodel/concerns/associations/base/definition.rb +4 -4
  21. data/lib/mongomodel/concerns/associations/base/proxy.rb +1 -1
  22. data/lib/mongomodel/concerns/associations/belongs_to.rb +19 -19
  23. data/lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb +36 -36
  24. data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +34 -34
  25. data/lib/mongomodel/concerns/attribute_methods.rb +10 -10
  26. data/lib/mongomodel/concerns/attribute_methods/before_type_cast.rb +4 -4
  27. data/lib/mongomodel/concerns/attribute_methods/dirty.rb +95 -13
  28. data/lib/mongomodel/concerns/attribute_methods/forbidden.rb +1 -1
  29. data/lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb +6 -6
  30. data/lib/mongomodel/concerns/attribute_methods/nested.rb +18 -18
  31. data/lib/mongomodel/concerns/attribute_methods/protected.rb +3 -3
  32. data/lib/mongomodel/concerns/attribute_methods/query.rb +3 -3
  33. data/lib/mongomodel/concerns/attribute_methods/read.rb +4 -4
  34. data/lib/mongomodel/concerns/attribute_methods/write.rb +4 -4
  35. data/lib/mongomodel/concerns/attributes.rb +18 -18
  36. data/lib/mongomodel/concerns/callbacks.rb +7 -7
  37. data/lib/mongomodel/concerns/document_parent.rb +2 -2
  38. data/lib/mongomodel/concerns/logging.rb +2 -2
  39. data/lib/mongomodel/concerns/map_reduce.rb +11 -11
  40. data/lib/mongomodel/concerns/pretty_inspect.rb +3 -3
  41. data/lib/mongomodel/concerns/properties.rb +18 -18
  42. data/lib/mongomodel/concerns/record_status.rb +9 -13
  43. data/lib/mongomodel/concerns/serialization.rb +4 -4
  44. data/lib/mongomodel/concerns/timestamps.rb +4 -4
  45. data/lib/mongomodel/concerns/translation.rb +2 -2
  46. data/lib/mongomodel/concerns/validations.rb +5 -5
  47. data/lib/mongomodel/concerns/validations/associated.rb +1 -1
  48. data/lib/mongomodel/document.rb +6 -6
  49. data/lib/mongomodel/document/callbacks.rb +15 -21
  50. data/lib/mongomodel/document/collection_modifiers.rb +5 -5
  51. data/lib/mongomodel/document/dynamic_finders.rb +1 -1
  52. data/lib/mongomodel/document/indexes.rb +19 -19
  53. data/lib/mongomodel/document/optimistic_locking.rb +7 -7
  54. data/lib/mongomodel/document/persistence.rb +23 -23
  55. data/lib/mongomodel/document/scopes.rb +20 -20
  56. data/lib/mongomodel/document/validations.rb +6 -6
  57. data/lib/mongomodel/document/validations/uniqueness.rb +11 -11
  58. data/lib/mongomodel/embedded_document.rb +11 -11
  59. data/lib/mongomodel/locale/en.yml +0 -1
  60. data/lib/mongomodel/log_subscriber.rb +5 -5
  61. data/lib/mongomodel/railtie.rb +13 -13
  62. data/lib/mongomodel/support/collection.rb +31 -31
  63. data/lib/mongomodel/support/configuration.rb +11 -11
  64. data/lib/mongomodel/support/core_extensions.rb +1 -1
  65. data/lib/mongomodel/support/dynamic_finder.rb +12 -12
  66. data/lib/mongomodel/support/exceptions.rb +6 -6
  67. data/lib/mongomodel/support/instrumented_collection.rb +20 -20
  68. data/lib/mongomodel/support/map.rb +33 -33
  69. data/lib/mongomodel/support/mongo_operator.rb +6 -6
  70. data/lib/mongomodel/support/mongo_options.rb +18 -18
  71. data/lib/mongomodel/support/mongo_order.rb +16 -16
  72. data/lib/mongomodel/support/paginator.rb +8 -8
  73. data/lib/mongomodel/support/reference.rb +10 -10
  74. data/lib/mongomodel/support/scope.rb +37 -37
  75. data/lib/mongomodel/support/scope/array_methods.rb +1 -1
  76. data/lib/mongomodel/support/scope/batches.rb +1 -1
  77. data/lib/mongomodel/support/scope/dynamic_finders.rb +1 -1
  78. data/lib/mongomodel/support/scope/finder_methods.rb +7 -7
  79. data/lib/mongomodel/support/scope/load_methods.rb +1 -1
  80. data/lib/mongomodel/support/scope/pagination.rb +1 -1
  81. data/lib/mongomodel/support/scope/query_methods.rb +6 -6
  82. data/lib/mongomodel/support/scope/spawn_methods.rb +8 -8
  83. data/lib/mongomodel/support/types.rb +2 -2
  84. data/lib/mongomodel/support/types/array.rb +1 -1
  85. data/lib/mongomodel/support/types/boolean.rb +3 -3
  86. data/lib/mongomodel/support/types/custom.rb +3 -3
  87. data/lib/mongomodel/support/types/date.rb +2 -2
  88. data/lib/mongomodel/support/types/date_time.rb +6 -16
  89. data/lib/mongomodel/support/types/float.rb +1 -1
  90. data/lib/mongomodel/support/types/hash.rb +1 -1
  91. data/lib/mongomodel/support/types/integer.rb +13 -10
  92. data/lib/mongomodel/support/types/object.rb +5 -5
  93. data/lib/mongomodel/support/types/rational.rb +3 -3
  94. data/lib/mongomodel/support/types/time.rb +2 -2
  95. data/lib/mongomodel/version.rb +1 -1
  96. data/lib/rails/generators/mongo_model/config/templates/mongomodel.yml +3 -4
  97. data/lib/rails/generators/mongo_model/model/model_generator.rb +3 -3
  98. data/mongomodel.gemspec +5 -4
  99. data/spec/mongomodel/attributes/store_spec.rb +21 -21
  100. data/spec/mongomodel/concerns/activemodel_spec.rb +4 -4
  101. data/spec/mongomodel/concerns/associations/base/association_spec.rb +12 -12
  102. data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +34 -21
  103. data/spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb +53 -53
  104. data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +30 -30
  105. data/spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb +7 -7
  106. data/spec/mongomodel/concerns/attribute_methods/dirty_spec.rb +45 -41
  107. data/spec/mongomodel/concerns/attribute_methods/multi_parameter_assignment_spec.rb +7 -7
  108. data/spec/mongomodel/concerns/attribute_methods/nested_spec.rb +31 -31
  109. data/spec/mongomodel/concerns/attribute_methods/protected_spec.rb +15 -15
  110. data/spec/mongomodel/concerns/attribute_methods/query_spec.rb +19 -19
  111. data/spec/mongomodel/concerns/attribute_methods/read_spec.rb +9 -9
  112. data/spec/mongomodel/concerns/attribute_methods/write_spec.rb +6 -6
  113. data/spec/mongomodel/concerns/attribute_methods_spec.rb +13 -13
  114. data/spec/mongomodel/concerns/attributes_spec.rb +34 -34
  115. data/spec/mongomodel/concerns/callbacks_spec.rb +25 -21
  116. data/spec/mongomodel/concerns/logging_spec.rb +5 -3
  117. data/spec/mongomodel/concerns/map_reduce_spec.rb +19 -19
  118. data/spec/mongomodel/concerns/observing_spec.rb +3 -3
  119. data/spec/mongomodel/concerns/pretty_inspect_spec.rb +10 -10
  120. data/spec/mongomodel/concerns/properties_spec.rb +11 -11
  121. data/spec/mongomodel/concerns/serialization/json_serialization_spec.rb +13 -13
  122. data/spec/mongomodel/concerns/timestamps_spec.rb +39 -39
  123. data/spec/mongomodel/concerns/validations_spec.rb +41 -38
  124. data/spec/mongomodel/document/callbacks_spec.rb +20 -16
  125. data/spec/mongomodel/document/collection_modifiers_spec.rb +16 -16
  126. data/spec/mongomodel/document/dynamic_finders_spec.rb +46 -46
  127. data/spec/mongomodel/document/finders_spec.rb +15 -15
  128. data/spec/mongomodel/document/indexes_spec.rb +29 -29
  129. data/spec/mongomodel/document/optimistic_locking_spec.rb +16 -16
  130. data/spec/mongomodel/document/persistence_spec.rb +39 -39
  131. data/spec/mongomodel/document/scopes_spec.rb +17 -17
  132. data/spec/mongomodel/document/validations/uniqueness_spec.rb +46 -46
  133. data/spec/mongomodel/document/validations_spec.rb +35 -35
  134. data/spec/mongomodel/document_spec.rb +19 -19
  135. data/spec/mongomodel/embedded_document_spec.rb +19 -19
  136. data/spec/mongomodel/mongomodel_spec.rb +7 -6
  137. data/spec/mongomodel/support/collection_spec.rb +54 -54
  138. data/spec/mongomodel/support/configuration_spec.rb +1 -1
  139. data/spec/mongomodel/support/map_spec.rb +66 -66
  140. data/spec/mongomodel/support/mongo_operator_spec.rb +5 -5
  141. data/spec/mongomodel/support/mongo_options_spec.rb +42 -42
  142. data/spec/mongomodel/support/mongo_order_spec.rb +24 -24
  143. data/spec/mongomodel/support/paginator_spec.rb +15 -15
  144. data/spec/mongomodel/support/property_spec.rb +29 -23
  145. data/spec/mongomodel/support/scope_spec.rb +205 -204
  146. data/spec/spec_helper.rb +13 -2
  147. data/spec/support/callbacks.rb +3 -8
  148. data/spec/support/helpers/define_class.rb +7 -7
  149. data/spec/support/helpers/document_finder_stubs.rb +6 -6
  150. data/spec/support/helpers/specs_for.rb +1 -1
  151. data/spec/support/helpers/validations.rb +1 -1
  152. data/spec/support/matchers/find_with.rb +8 -8
  153. data/spec/support/matchers/respond_to_boolean.rb +3 -3
  154. data/spec/support/matchers/run_callbacks.rb +6 -9
  155. data/spec/support/models.rb +5 -5
  156. metadata +23 -7
@@ -7,7 +7,7 @@ module MongoModel
7
7
  define_class(:TestDocument, described_class)
8
8
  define_class(:TestObserver, Observer) do
9
9
  observe :test_document
10
-
10
+
11
11
  attr_accessor :callback
12
12
 
13
13
  def after_save(model)
@@ -20,11 +20,11 @@ module MongoModel
20
20
  it "has an #instance method to access the observer singleton" do
21
21
  TestObserver.instance.should eq(TestObserver.instance)
22
22
  end
23
-
23
+
24
24
  it "invokes the TestObserver singleton's after_save method after saving" do
25
25
  callback = double
26
26
  callback.should_receive(:call).with(subject)
27
-
27
+
28
28
  TestObserver.instance.callback = callback
29
29
  subject.save
30
30
  end
@@ -8,22 +8,22 @@ module MongoModel
8
8
  described_class.inspect.should == described_class.name
9
9
  end
10
10
  end
11
-
11
+
12
12
  context "on subclasses" do
13
13
  context "without properties" do
14
14
  define_class(:TestDocument, described_class)
15
-
15
+
16
16
  it "returns class name" do
17
17
  TestDocument.inspect.should == 'TestDocument()'
18
18
  end
19
19
  end
20
-
20
+
21
21
  context "with properties" do
22
22
  define_class(:TestDocument, described_class) do
23
23
  property :name, String
24
24
  property :age, Integer
25
25
  end
26
-
26
+
27
27
  it "returns class name and property definitions" do
28
28
  TestDocument.inspect.should == 'TestDocument(name: String, age: Integer)'
29
29
  end
@@ -31,7 +31,7 @@ module MongoModel
31
31
  end
32
32
  end
33
33
  end
34
-
34
+
35
35
  specs_for(Document) do
36
36
  describe "#inspect" do
37
37
  context "on subclass instances" do
@@ -39,16 +39,16 @@ module MongoModel
39
39
  property :name, String
40
40
  property :age, Integer
41
41
  end
42
-
42
+
43
43
  subject { TestDocument.new(:id => 'abc-123', :name => 'Doc name', :age => 54) }
44
-
44
+
45
45
  it "returns class name and property values" do
46
46
  subject.inspect.should == '#<TestDocument id: abc-123, name: "Doc name", age: 54>'
47
47
  end
48
48
  end
49
49
  end
50
50
  end
51
-
51
+
52
52
  specs_for(EmbeddedDocument) do
53
53
  describe "#inspect" do
54
54
  context "on subclass instances" do
@@ -56,9 +56,9 @@ module MongoModel
56
56
  property :name, String
57
57
  property :age, Integer
58
58
  end
59
-
59
+
60
60
  subject { TestDocument.new(:name => 'Doc name', :age => 54) }
61
-
61
+
62
62
  it "returns class name and property values" do
63
63
  subject.inspect.should == '#<TestDocument name: "Doc name", age: 54>'
64
64
  end
@@ -6,18 +6,18 @@ module MongoModel
6
6
  property :name, String
7
7
  property :age, Integer, :default => 21
8
8
  end
9
-
9
+
10
10
  define_class(:SkilledPerson, :Person) do
11
11
  property :skill, String
12
12
  end
13
-
13
+
14
14
  it "has a populated hash of properties" do
15
15
  Person.properties.should include({
16
16
  :name => Properties::Property.new(:name, String),
17
17
  :age => Properties::Property.new(:age, Integer, :default => 21)
18
18
  })
19
19
  end
20
-
20
+
21
21
  it "extends properties in subclasses" do
22
22
  SkilledPerson.properties.should include({
23
23
  :name => Properties::Property.new(:name, String),
@@ -25,41 +25,41 @@ module MongoModel
25
25
  :skill => Properties::Property.new(:skill, String)
26
26
  })
27
27
  end
28
-
28
+
29
29
  it "has a set of internal property names" do
30
30
  Person.internal_properties.should include(Person.properties[:type])
31
31
  Person.internal_properties.should include(Person.properties[:id]) if described_class == Document
32
32
  end
33
-
33
+
34
34
  describe "when used as a property inside a document" do
35
35
  define_class(:Factory, Document) do
36
36
  property :manager, Person
37
37
  end
38
-
38
+
39
39
  let(:person) { SkilledPerson.new(:name => "Joe", :age => 44, :skill => "Management") }
40
40
  let(:with_manager) { Factory.create!(:manager => person) }
41
41
  let(:without_manager) { Factory.create! }
42
-
42
+
43
43
  it "loads correctly when property is set" do
44
44
  factory = Factory.find(with_manager.id)
45
45
  factory.manager.should be_an_instance_of(SkilledPerson)
46
46
  factory.manager.name.should == "Joe"
47
47
  factory.manager.skill.should == "Management"
48
48
  end
49
-
49
+
50
50
  it "loads correctly when property is nil" do
51
51
  factory = Factory.find(without_manager.id)
52
52
  factory.manager.should be_nil
53
53
  end
54
54
  end
55
-
55
+
56
56
  describe "when using a property type that defines #mongomodel_accessors" do
57
57
  define_class(:ParentClass, described_class) do
58
58
  property :custom, CustomClassWithAccessors
59
59
  end
60
-
60
+
61
61
  subject { ParentClass.new }
62
-
62
+
63
63
  it "includes methods from the module" do
64
64
  subject.should respond_to(:custom_accessor)
65
65
  subject.custom_accessor.should == "Custom accessor method"
@@ -8,30 +8,30 @@ module MongoModel
8
8
  property :paid, Boolean
9
9
  property :prefs, Hash
10
10
  property :internal, String, :internal => true
11
-
11
+
12
12
  def hello
13
13
  "Hi friend!"
14
14
  end
15
15
  end
16
-
16
+
17
17
  let(:instance) do
18
18
  TestModel.new(:id => "abc-123", :name => 'Hello World', :age => 25, :paid => true, :prefs => { :foo => 'bar' }, :internal => 'hideme')
19
19
  end
20
-
20
+
21
21
  it "includes root in the JSON response when include_root_in_json = true" do
22
22
  TestModel.include_root_in_json = true
23
-
23
+
24
24
  json = instance.to_json
25
25
  json.should match(/^\{"test_model":\{/)
26
26
  end
27
-
27
+
28
28
  it "does not include root in the JSON response when include_root_in_json = false" do
29
29
  TestModel.include_root_in_json = false
30
-
30
+
31
31
  json = instance.to_json
32
32
  json.should_not match(/^\{"test_model":\{/)
33
33
  end
34
-
34
+
35
35
  it "encodes all public attributes" do
36
36
  json = instance.to_json
37
37
  json.should match(/"name":"Hello World"/)
@@ -39,19 +39,19 @@ module MongoModel
39
39
  json.should match(/"paid":true/)
40
40
  json.should match(/"prefs":\{"foo":"bar"\}/)
41
41
  end
42
-
42
+
43
43
  if described_class == Document
44
44
  it "encodes the id" do
45
45
  json = instance.to_json
46
46
  json.should match(/"id":"abc-123"/)
47
47
  end
48
48
  end
49
-
49
+
50
50
  it "does not encode internal attributes" do
51
51
  json = instance.to_json
52
52
  json.should_not match(/"internal":"hideme"/)
53
53
  end
54
-
54
+
55
55
  it "allows attribute filtering with only" do
56
56
  json = instance.to_json(:only => [:name, :age])
57
57
  json.should match(/"name":"Hello World"/)
@@ -59,7 +59,7 @@ module MongoModel
59
59
  json.should_not match(/"paid":true/)
60
60
  json.should_not match(/"prefs":\{"foo":"bar"\}/)
61
61
  end
62
-
62
+
63
63
  it "allows attribute filtering with except" do
64
64
  json = instance.to_json(:except => [:name, :age])
65
65
  json.should_not match(/"name":"Hello World"/)
@@ -67,13 +67,13 @@ module MongoModel
67
67
  json.should match(/"paid":true/)
68
68
  json.should match(/"prefs":\{"foo":"bar"\}/)
69
69
  end
70
-
70
+
71
71
  it "allows methods to be included" do
72
72
  json = instance.to_json(:methods => [:hello, :type])
73
73
  json.should match(/"hello":"Hi friend!"/)
74
74
  json.should match(/"type":"TestModel"/)
75
75
  end
76
-
76
+
77
77
  it "encodes keys in the serializable_hash as strings" do
78
78
  hash = instance.serializable_hash(:methods => :hello)
79
79
  hash.should have_key("name")
@@ -7,163 +7,163 @@ module MongoModel
7
7
  define_class(:TestDocument, described_class) do
8
8
  timestamps!
9
9
  end
10
-
10
+
11
11
  it "defines a Time property updated_at" do
12
12
  TestDocument.properties.should include(:updated_at)
13
13
  TestDocument.properties[:updated_at].type.should == Time
14
14
  end
15
-
15
+
16
16
  it "defines a Time property created_at" do
17
17
  TestDocument.properties.should include(:created_at)
18
18
  TestDocument.properties[:created_at].type.should == Time
19
19
  end
20
20
  end
21
-
21
+
22
22
  context "with updated_at property" do
23
23
  define_class(:TestDocument, described_class) do
24
24
  property :updated_at, Time
25
25
  end
26
-
26
+
27
27
  if specing?(EmbeddedDocument)
28
28
  define_class(:ParentDocument, Document) do
29
29
  property :child, TestDocument
30
30
  end
31
-
31
+
32
32
  let(:parent) { ParentDocument.new(:child => subject) }
33
33
  let(:doc) { parent }
34
34
  else
35
35
  let(:doc) { subject }
36
36
  end
37
-
37
+
38
38
  subject { TestDocument.new }
39
-
39
+
40
40
  before(:each) do
41
41
  @now = Types::Time.new.cast(Time.now)
42
42
  Time.stub(:now).and_return(@now)
43
43
  end
44
-
44
+
45
45
  it "sets the updated_at property to the current time when saved" do
46
46
  doc.save
47
47
  subject.updated_at.should == @now
48
48
  end
49
49
  end
50
-
50
+
51
51
  context "with updated_on property" do
52
52
  define_class(:TestDocument, described_class) do
53
53
  property :updated_on, Date
54
54
  end
55
-
55
+
56
56
  if specing?(EmbeddedDocument)
57
57
  define_class(:ParentDocument, Document) do
58
58
  property :child, TestDocument
59
59
  end
60
-
60
+
61
61
  let(:parent) { ParentDocument.new(:child => subject) }
62
62
  let(:doc) { parent }
63
63
  else
64
64
  let(:doc) { subject }
65
65
  end
66
-
66
+
67
67
  subject { TestDocument.new }
68
-
68
+
69
69
  it "sets the updated_on property to the current date when saved" do
70
70
  doc.save
71
71
  subject.updated_on.should == Date.today
72
72
  end
73
73
  end
74
-
74
+
75
75
  context "with created_at property" do
76
76
  define_class(:TestDocument, described_class) do
77
77
  property :created_at, Time
78
78
  end
79
-
79
+
80
80
  if specing?(EmbeddedDocument)
81
81
  define_class(:ParentDocument, Document) do
82
82
  property :child, TestDocument
83
83
  end
84
-
84
+
85
85
  let(:parent) { ParentDocument.new(:child => subject) }
86
86
  let(:doc) { parent }
87
87
  else
88
88
  let(:doc) { subject }
89
89
  end
90
-
90
+
91
91
  subject { TestDocument.new }
92
-
92
+
93
93
  before(:each) do
94
94
  @now = Types::Time.new.cast(Time.now)
95
95
  Time.stub(:now).and_return(@now)
96
96
  end
97
-
97
+
98
98
  it "sets the created_at property to the current time when created" do
99
99
  doc.save
100
100
  subject.created_at.should == @now
101
101
  end
102
-
102
+
103
103
  it "does not change the created_at property when updated" do
104
104
  @next = 1.day.from_now
105
-
105
+
106
106
  Time.stub(:now).and_return(@now)
107
-
107
+
108
108
  doc.save
109
-
109
+
110
110
  Time.stub(:now).and_return(@next)
111
-
111
+
112
112
  doc.save
113
113
  subject.created_at.should == @now
114
114
  end
115
-
115
+
116
116
  it "preserves created_at attribute when set explicitly" do
117
117
  @a_year_ago = 1.year.ago
118
-
118
+
119
119
  subject.created_at = @a_year_ago
120
120
  doc.save
121
-
121
+
122
122
  subject.created_at.should == @a_year_ago
123
123
  end
124
124
  end
125
-
125
+
126
126
  context "with created_on property" do
127
127
  define_class(:TestDocument, described_class) do
128
128
  property :created_on, Date
129
129
  end
130
-
130
+
131
131
  if specing?(EmbeddedDocument)
132
132
  define_class(:ParentDocument, Document) do
133
133
  property :child, TestDocument
134
134
  end
135
-
135
+
136
136
  let(:parent) { ParentDocument.new(:child => subject) }
137
137
  let(:doc) { parent }
138
138
  else
139
139
  let(:doc) { subject }
140
140
  end
141
-
141
+
142
142
  subject { TestDocument.new }
143
-
143
+
144
144
  it "sets the created_on property to the current date when created" do
145
145
  doc.save
146
146
  subject.created_on.should == Date.today
147
147
  end
148
-
148
+
149
149
  it "does not change the created_on property when updated" do
150
150
  doc.save
151
-
151
+
152
152
  @today = Date.today
153
153
  @tomorrow = 1.day.from_now
154
-
154
+
155
155
  Time.stub(:now).and_return(@tomorrow)
156
-
156
+
157
157
  doc.save
158
158
  subject.created_on.should == @today
159
159
  end
160
-
160
+
161
161
  it "preserves created_on attribute when set explicitly" do
162
162
  @a_year_ago = 1.year.ago.to_date
163
-
163
+
164
164
  subject.created_on = @a_year_ago
165
165
  doc.save
166
-
166
+
167
167
  subject.created_on.should == @a_year_ago
168
168
  end
169
169
  end
@@ -6,111 +6,114 @@ module MongoModel
6
6
  define_class(:TestDocument, described_class) do
7
7
  property :title, String
8
8
  validates_presence_of :title
9
-
9
+
10
10
  extend ValidationHelpers
11
11
  end
12
-
12
+
13
13
  if specing?(EmbeddedDocument)
14
14
  define_class(:ParentDocument, Document) do
15
15
  property :child, TestDocument
16
16
  end
17
-
17
+
18
18
  let(:child) { TestDocument.new }
19
19
  let(:parent) { ParentDocument.new(:child => child) }
20
20
  let(:doc) { parent }
21
-
21
+
22
22
  subject { parent.child }
23
23
  else
24
24
  let(:doc) { TestDocument.new }
25
-
25
+
26
26
  subject { doc }
27
27
  end
28
-
28
+
29
29
  it "has an errors collection" do
30
30
  subject.errors.should be_an_instance_of(ActiveModel::Errors)
31
31
  end
32
-
32
+
33
33
  context "when validations are not met" do
34
34
  before(:each) { subject.valid? }
35
-
35
+
36
36
  it { should_not be_valid }
37
- it { should have(1).error }
37
+
38
+ it "should have 1 error" do
39
+ subject.errors.size.should == 1
40
+ end
38
41
  end
39
-
42
+
40
43
  describe "validation on create" do
41
44
  before(:each) do
42
45
  TestDocument.clear_validations!
43
46
  TestDocument.validates_presence_of :title, :on => :create
44
47
  end
45
-
48
+
46
49
  context "new document" do
47
50
  it { should_not be_valid }
48
51
  end
49
-
52
+
50
53
  context "existing document" do
51
54
  before(:each) do
52
55
  subject.title = 'Valid title'
53
56
  doc.save!
54
57
  subject.title = nil
55
58
  end
56
-
59
+
57
60
  it { should be_valid }
58
61
  end
59
62
  end
60
-
63
+
61
64
  describe "validation on update" do
62
65
  before(:each) do
63
66
  TestDocument.clear_validations!
64
67
  TestDocument.validates_presence_of :title, :on => :update
65
68
  end
66
-
69
+
67
70
  context "new document" do
68
71
  it { should be_valid }
69
72
  end
70
-
73
+
71
74
  context "existing document" do
72
75
  before(:each) do
73
76
  subject.title = 'Valid title'
74
77
  doc.save!
75
78
  subject.title = nil
76
79
  end
77
-
80
+
78
81
  it { should_not be_valid }
79
82
  end
80
83
  end
81
-
84
+
82
85
  describe "validation on custom context" do
83
86
  before(:each) do
84
87
  TestDocument.clear_validations!
85
88
  TestDocument.validates_presence_of :title, :on => :custom
86
89
  end
87
-
90
+
88
91
  it { should be_valid }
89
-
92
+
90
93
  it "is not valid in custom context" do
91
- subject.valid?(:custom).should be_false
94
+ subject.valid?(:custom).should be false
92
95
  end
93
96
  end
94
97
  end
95
-
98
+
96
99
  describe "validation shortcuts" do
97
100
  define_class(:TestDocument, described_class)
98
101
  define_class(:SubDocument, EmbeddedDocument)
99
-
102
+
100
103
  describe ":required => true" do
101
104
  it "adds a validates_presence_of validation" do
102
105
  TestDocument.should_receive(:validates_presence_of).with(:title)
103
106
  TestDocument.property :title, String, :required => true
104
107
  end
105
108
  end
106
-
109
+
107
110
  describe ":format => /regex/" do
108
111
  it "adds a validates_format_of validation" do
109
112
  TestDocument.should_receive(:validates_format_of).with(:email, /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i)
110
113
  TestDocument.property :email, String, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
111
114
  end
112
115
  end
113
-
116
+
114
117
  describe ":validate => false" do
115
118
  it "skips validations on embedded/associated models" do
116
119
  TestDocument.should_not_receive(:validates_associated).with(:sub_object)
@@ -119,52 +122,52 @@ module MongoModel
119
122
  end
120
123
  end
121
124
  end
122
-
125
+
123
126
  specs_for(EmbeddedDocument) do
124
127
  describe "validations" do
125
128
  define_class(:ChildDocument, EmbeddedDocument) do
126
129
  property :title, String
127
130
  validates_presence_of :title
128
-
131
+
129
132
  extend ValidationHelpers
130
133
  end
131
-
134
+
132
135
  define_class(:ParentDocument, Document) do
133
136
  property :child, ChildDocument
134
137
  end
135
-
138
+
136
139
  let(:child) { ChildDocument.new }
137
140
  let(:parent) { ParentDocument.new(:child => child) }
138
-
141
+
139
142
  subject { parent.child }
140
-
143
+
141
144
  context "child document is invalid" do
142
145
  before(:each) { parent.valid? }
143
-
146
+
144
147
  specify "parent should be invalid" do
145
148
  parent.should_not be_valid
146
149
  end
147
-
150
+
148
151
  specify "parent should have error on child" do
149
- parent.should have(1).error
152
+ parent.errors.size.should == 1
150
153
  parent.errors[:child].should_not be_nil
151
154
  end
152
-
155
+
153
156
  specify "child should be invalid" do
154
157
  child.should_not be_valid
155
158
  end
156
-
159
+
157
160
  specify "child should have error" do
158
161
  child.errors[:title].should_not be_nil
159
162
  end
160
163
  end
161
-
164
+
162
165
  context "parent has no child" do
163
166
  before(:each) do
164
167
  parent.child = nil
165
168
  parent.valid?
166
169
  end
167
-
170
+
168
171
  specify "parent should be valid" do
169
172
  parent.should be_valid
170
173
  end