mongomodel 0.5.5 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
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