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.
- checksums.yaml +5 -5
- data/.travis.yml +23 -11
- data/gemfiles/rails-3.2.gemfile +2 -2
- data/gemfiles/rails-4-observers.gemfile +1 -1
- data/gemfiles/rails-4.1.gemfile +2 -2
- data/gemfiles/{mongoid.gemfile → rails-4.2.gemfile} +2 -3
- data/gemfiles/{mongo_mapper.gemfile → rails-5.0.gemfile} +2 -3
- data/gemfiles/rails-5.1.gemfile +10 -0
- data/gemfiles/rails-5.2.gemfile +10 -0
- data/lib/mongomodel.rb +15 -15
- data/lib/mongomodel/attributes/mongo.rb +7 -7
- data/lib/mongomodel/attributes/store.rb +4 -4
- data/lib/mongomodel/attributes/typecasting.rb +7 -7
- data/lib/mongomodel/compatibility/mongo_mapper.rb +3 -3
- data/lib/mongomodel/compatibility/mongoid.rb +3 -3
- data/lib/mongomodel/concerns/abstract_class.rb +3 -3
- data/lib/mongomodel/concerns/activemodel.rb +4 -4
- data/lib/mongomodel/concerns/associations.rb +8 -8
- data/lib/mongomodel/concerns/associations/base/association.rb +5 -5
- data/lib/mongomodel/concerns/associations/base/definition.rb +4 -4
- data/lib/mongomodel/concerns/associations/base/proxy.rb +1 -1
- data/lib/mongomodel/concerns/associations/belongs_to.rb +19 -19
- data/lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb +36 -36
- data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +34 -34
- data/lib/mongomodel/concerns/attribute_methods.rb +10 -10
- data/lib/mongomodel/concerns/attribute_methods/before_type_cast.rb +4 -4
- data/lib/mongomodel/concerns/attribute_methods/dirty.rb +95 -13
- data/lib/mongomodel/concerns/attribute_methods/forbidden.rb +1 -1
- data/lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb +6 -6
- data/lib/mongomodel/concerns/attribute_methods/nested.rb +18 -18
- data/lib/mongomodel/concerns/attribute_methods/protected.rb +3 -3
- data/lib/mongomodel/concerns/attribute_methods/query.rb +3 -3
- data/lib/mongomodel/concerns/attribute_methods/read.rb +4 -4
- data/lib/mongomodel/concerns/attribute_methods/write.rb +4 -4
- data/lib/mongomodel/concerns/attributes.rb +18 -18
- data/lib/mongomodel/concerns/callbacks.rb +7 -7
- data/lib/mongomodel/concerns/document_parent.rb +2 -2
- data/lib/mongomodel/concerns/logging.rb +2 -2
- data/lib/mongomodel/concerns/map_reduce.rb +11 -11
- data/lib/mongomodel/concerns/pretty_inspect.rb +3 -3
- data/lib/mongomodel/concerns/properties.rb +18 -18
- data/lib/mongomodel/concerns/record_status.rb +9 -13
- data/lib/mongomodel/concerns/serialization.rb +4 -4
- data/lib/mongomodel/concerns/timestamps.rb +4 -4
- data/lib/mongomodel/concerns/translation.rb +2 -2
- data/lib/mongomodel/concerns/validations.rb +5 -5
- data/lib/mongomodel/concerns/validations/associated.rb +1 -1
- data/lib/mongomodel/document.rb +6 -6
- data/lib/mongomodel/document/callbacks.rb +15 -21
- data/lib/mongomodel/document/collection_modifiers.rb +5 -5
- data/lib/mongomodel/document/dynamic_finders.rb +1 -1
- data/lib/mongomodel/document/indexes.rb +19 -19
- data/lib/mongomodel/document/optimistic_locking.rb +7 -7
- data/lib/mongomodel/document/persistence.rb +23 -23
- data/lib/mongomodel/document/scopes.rb +20 -20
- data/lib/mongomodel/document/validations.rb +6 -6
- data/lib/mongomodel/document/validations/uniqueness.rb +11 -11
- data/lib/mongomodel/embedded_document.rb +11 -11
- data/lib/mongomodel/locale/en.yml +0 -1
- data/lib/mongomodel/log_subscriber.rb +5 -5
- data/lib/mongomodel/railtie.rb +13 -13
- data/lib/mongomodel/support/collection.rb +31 -31
- data/lib/mongomodel/support/configuration.rb +11 -11
- data/lib/mongomodel/support/core_extensions.rb +1 -1
- data/lib/mongomodel/support/dynamic_finder.rb +12 -12
- data/lib/mongomodel/support/exceptions.rb +6 -6
- data/lib/mongomodel/support/instrumented_collection.rb +20 -20
- data/lib/mongomodel/support/map.rb +33 -33
- data/lib/mongomodel/support/mongo_operator.rb +6 -6
- data/lib/mongomodel/support/mongo_options.rb +18 -18
- data/lib/mongomodel/support/mongo_order.rb +16 -16
- data/lib/mongomodel/support/paginator.rb +8 -8
- data/lib/mongomodel/support/reference.rb +10 -10
- data/lib/mongomodel/support/scope.rb +37 -37
- data/lib/mongomodel/support/scope/array_methods.rb +1 -1
- data/lib/mongomodel/support/scope/batches.rb +1 -1
- data/lib/mongomodel/support/scope/dynamic_finders.rb +1 -1
- data/lib/mongomodel/support/scope/finder_methods.rb +7 -7
- data/lib/mongomodel/support/scope/load_methods.rb +1 -1
- data/lib/mongomodel/support/scope/pagination.rb +1 -1
- data/lib/mongomodel/support/scope/query_methods.rb +6 -6
- data/lib/mongomodel/support/scope/spawn_methods.rb +8 -8
- data/lib/mongomodel/support/types.rb +2 -2
- data/lib/mongomodel/support/types/array.rb +1 -1
- data/lib/mongomodel/support/types/boolean.rb +3 -3
- data/lib/mongomodel/support/types/custom.rb +3 -3
- data/lib/mongomodel/support/types/date.rb +2 -2
- data/lib/mongomodel/support/types/date_time.rb +6 -16
- data/lib/mongomodel/support/types/float.rb +1 -1
- data/lib/mongomodel/support/types/hash.rb +1 -1
- data/lib/mongomodel/support/types/integer.rb +13 -10
- data/lib/mongomodel/support/types/object.rb +5 -5
- data/lib/mongomodel/support/types/rational.rb +3 -3
- data/lib/mongomodel/support/types/time.rb +2 -2
- data/lib/mongomodel/version.rb +1 -1
- data/lib/rails/generators/mongo_model/config/templates/mongomodel.yml +3 -4
- data/lib/rails/generators/mongo_model/model/model_generator.rb +3 -3
- data/mongomodel.gemspec +5 -4
- data/spec/mongomodel/attributes/store_spec.rb +21 -21
- data/spec/mongomodel/concerns/activemodel_spec.rb +4 -4
- data/spec/mongomodel/concerns/associations/base/association_spec.rb +12 -12
- data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +34 -21
- data/spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb +53 -53
- data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +30 -30
- data/spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb +7 -7
- data/spec/mongomodel/concerns/attribute_methods/dirty_spec.rb +45 -41
- data/spec/mongomodel/concerns/attribute_methods/multi_parameter_assignment_spec.rb +7 -7
- data/spec/mongomodel/concerns/attribute_methods/nested_spec.rb +31 -31
- data/spec/mongomodel/concerns/attribute_methods/protected_spec.rb +15 -15
- data/spec/mongomodel/concerns/attribute_methods/query_spec.rb +19 -19
- data/spec/mongomodel/concerns/attribute_methods/read_spec.rb +9 -9
- data/spec/mongomodel/concerns/attribute_methods/write_spec.rb +6 -6
- data/spec/mongomodel/concerns/attribute_methods_spec.rb +13 -13
- data/spec/mongomodel/concerns/attributes_spec.rb +34 -34
- data/spec/mongomodel/concerns/callbacks_spec.rb +25 -21
- data/spec/mongomodel/concerns/logging_spec.rb +5 -3
- data/spec/mongomodel/concerns/map_reduce_spec.rb +19 -19
- data/spec/mongomodel/concerns/observing_spec.rb +3 -3
- data/spec/mongomodel/concerns/pretty_inspect_spec.rb +10 -10
- data/spec/mongomodel/concerns/properties_spec.rb +11 -11
- data/spec/mongomodel/concerns/serialization/json_serialization_spec.rb +13 -13
- data/spec/mongomodel/concerns/timestamps_spec.rb +39 -39
- data/spec/mongomodel/concerns/validations_spec.rb +41 -38
- data/spec/mongomodel/document/callbacks_spec.rb +20 -16
- data/spec/mongomodel/document/collection_modifiers_spec.rb +16 -16
- data/spec/mongomodel/document/dynamic_finders_spec.rb +46 -46
- data/spec/mongomodel/document/finders_spec.rb +15 -15
- data/spec/mongomodel/document/indexes_spec.rb +29 -29
- data/spec/mongomodel/document/optimistic_locking_spec.rb +16 -16
- data/spec/mongomodel/document/persistence_spec.rb +39 -39
- data/spec/mongomodel/document/scopes_spec.rb +17 -17
- data/spec/mongomodel/document/validations/uniqueness_spec.rb +46 -46
- data/spec/mongomodel/document/validations_spec.rb +35 -35
- data/spec/mongomodel/document_spec.rb +19 -19
- data/spec/mongomodel/embedded_document_spec.rb +19 -19
- data/spec/mongomodel/mongomodel_spec.rb +7 -6
- data/spec/mongomodel/support/collection_spec.rb +54 -54
- data/spec/mongomodel/support/configuration_spec.rb +1 -1
- data/spec/mongomodel/support/map_spec.rb +66 -66
- data/spec/mongomodel/support/mongo_operator_spec.rb +5 -5
- data/spec/mongomodel/support/mongo_options_spec.rb +42 -42
- data/spec/mongomodel/support/mongo_order_spec.rb +24 -24
- data/spec/mongomodel/support/paginator_spec.rb +15 -15
- data/spec/mongomodel/support/property_spec.rb +29 -23
- data/spec/mongomodel/support/scope_spec.rb +205 -204
- data/spec/spec_helper.rb +13 -2
- data/spec/support/callbacks.rb +3 -8
- data/spec/support/helpers/define_class.rb +7 -7
- data/spec/support/helpers/document_finder_stubs.rb +6 -6
- data/spec/support/helpers/specs_for.rb +1 -1
- data/spec/support/helpers/validations.rb +1 -1
- data/spec/support/matchers/find_with.rb +8 -8
- data/spec/support/matchers/respond_to_boolean.rb +3 -3
- data/spec/support/matchers/run_callbacks.rb +6 -9
- data/spec/support/models.rb +5 -5
- 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
|
-
|
|
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
|
|
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
|
|
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
|