mark_mapper 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.rdoc +39 -0
- data/examples/attr_accessible.rb +24 -0
- data/examples/attr_protected.rb +24 -0
- data/examples/cache_key.rb +26 -0
- data/examples/custom_types.rb +26 -0
- data/examples/identity_map.rb +30 -0
- data/examples/identity_map/automatic.rb +2 -0
- data/examples/keys.rb +42 -0
- data/examples/modifiers/set.rb +27 -0
- data/examples/plugins.rb +40 -0
- data/examples/querying.rb +39 -0
- data/examples/sample_app.rb +43 -0
- data/examples/scopes.rb +56 -0
- data/examples/validating/embedded_docs.rb +31 -0
- data/lib/mark_mapper.rb +125 -0
- data/lib/mark_mapper/config.rb +90 -0
- data/lib/mark_mapper/connection.rb +60 -0
- data/lib/mark_mapper/criteria_hash.rb +194 -0
- data/lib/mark_mapper/document.rb +46 -0
- data/lib/mark_mapper/embedded_document.rb +32 -0
- data/lib/mark_mapper/exceptions.rb +33 -0
- data/lib/mark_mapper/extensions/array.rb +27 -0
- data/lib/mark_mapper/extensions/boolean.rb +45 -0
- data/lib/mark_mapper/extensions/date.rb +29 -0
- data/lib/mark_mapper/extensions/duplicable.rb +86 -0
- data/lib/mark_mapper/extensions/float.rb +18 -0
- data/lib/mark_mapper/extensions/hash.rb +26 -0
- data/lib/mark_mapper/extensions/integer.rb +27 -0
- data/lib/mark_mapper/extensions/kernel.rb +11 -0
- data/lib/mark_mapper/extensions/nil_class.rb +18 -0
- data/lib/mark_mapper/extensions/object.rb +30 -0
- data/lib/mark_mapper/extensions/object_id.rb +18 -0
- data/lib/mark_mapper/extensions/set.rb +20 -0
- data/lib/mark_mapper/extensions/string.rb +31 -0
- data/lib/mark_mapper/extensions/symbol.rb +87 -0
- data/lib/mark_mapper/extensions/time.rb +29 -0
- data/lib/mark_mapper/locale/en.yml +5 -0
- data/lib/mark_mapper/middleware/identity_map.rb +41 -0
- data/lib/mark_mapper/normalizers/criteria_hash_key.rb +17 -0
- data/lib/mark_mapper/normalizers/criteria_hash_value.rb +66 -0
- data/lib/mark_mapper/normalizers/fields_value.rb +26 -0
- data/lib/mark_mapper/normalizers/hash_key.rb +19 -0
- data/lib/mark_mapper/normalizers/integer.rb +19 -0
- data/lib/mark_mapper/normalizers/options_hash_value.rb +83 -0
- data/lib/mark_mapper/normalizers/sort_value.rb +55 -0
- data/lib/mark_mapper/options_hash.rb +103 -0
- data/lib/mark_mapper/pagination.rb +6 -0
- data/lib/mark_mapper/pagination/collection.rb +32 -0
- data/lib/mark_mapper/pagination/paginator.rb +46 -0
- data/lib/mark_mapper/plugins.rb +22 -0
- data/lib/mark_mapper/plugins/accessible.rb +61 -0
- data/lib/mark_mapper/plugins/active_model.rb +18 -0
- data/lib/mark_mapper/plugins/associations.rb +96 -0
- data/lib/mark_mapper/plugins/associations/base.rb +98 -0
- data/lib/mark_mapper/plugins/associations/belongs_to_association.rb +63 -0
- data/lib/mark_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +35 -0
- data/lib/mark_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
- data/lib/mark_mapper/plugins/associations/collection.rb +29 -0
- data/lib/mark_mapper/plugins/associations/embedded_collection.rb +44 -0
- data/lib/mark_mapper/plugins/associations/in_array_proxy.rb +133 -0
- data/lib/mark_mapper/plugins/associations/many_association.rb +63 -0
- data/lib/mark_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
- data/lib/mark_mapper/plugins/associations/many_documents_proxy.rb +142 -0
- data/lib/mark_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
- data/lib/mark_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
- data/lib/mark_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
- data/lib/mark_mapper/plugins/associations/one_as_proxy.rb +22 -0
- data/lib/mark_mapper/plugins/associations/one_association.rb +48 -0
- data/lib/mark_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
- data/lib/mark_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
- data/lib/mark_mapper/plugins/associations/one_proxy.rb +95 -0
- data/lib/mark_mapper/plugins/associations/proxy.rb +138 -0
- data/lib/mark_mapper/plugins/associations/single_association.rb +46 -0
- data/lib/mark_mapper/plugins/caching.rb +21 -0
- data/lib/mark_mapper/plugins/callbacks.rb +42 -0
- data/lib/mark_mapper/plugins/clone.rb +24 -0
- data/lib/mark_mapper/plugins/counter_cache.rb +97 -0
- data/lib/mark_mapper/plugins/dirty.rb +61 -0
- data/lib/mark_mapper/plugins/document.rb +41 -0
- data/lib/mark_mapper/plugins/dumpable.rb +22 -0
- data/lib/mark_mapper/plugins/dynamic_querying.rb +45 -0
- data/lib/mark_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
- data/lib/mark_mapper/plugins/embedded_callbacks.rb +81 -0
- data/lib/mark_mapper/plugins/embedded_document.rb +53 -0
- data/lib/mark_mapper/plugins/equality.rb +23 -0
- data/lib/mark_mapper/plugins/identity_map.rb +144 -0
- data/lib/mark_mapper/plugins/indexable.rb +86 -0
- data/lib/mark_mapper/plugins/inspect.rb +16 -0
- data/lib/mark_mapper/plugins/keys.rb +470 -0
- data/lib/mark_mapper/plugins/keys/key.rb +134 -0
- data/lib/mark_mapper/plugins/keys/static.rb +45 -0
- data/lib/mark_mapper/plugins/logger.rb +18 -0
- data/lib/mark_mapper/plugins/modifiers.rb +140 -0
- data/lib/mark_mapper/plugins/pagination.rb +16 -0
- data/lib/mark_mapper/plugins/partial_updates.rb +77 -0
- data/lib/mark_mapper/plugins/persistence.rb +79 -0
- data/lib/mark_mapper/plugins/protected.rb +45 -0
- data/lib/mark_mapper/plugins/querying.rb +173 -0
- data/lib/mark_mapper/plugins/querying/decorated_markmapper_query.rb +75 -0
- data/lib/mark_mapper/plugins/rails.rb +79 -0
- data/lib/mark_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
- data/lib/mark_mapper/plugins/sci.rb +82 -0
- data/lib/mark_mapper/plugins/scopes.rb +28 -0
- data/lib/mark_mapper/plugins/serialization.rb +109 -0
- data/lib/mark_mapper/plugins/timestamps.rb +29 -0
- data/lib/mark_mapper/plugins/touch.rb +18 -0
- data/lib/mark_mapper/plugins/userstamps.rb +18 -0
- data/lib/mark_mapper/plugins/validations.rb +96 -0
- data/lib/mark_mapper/query.rb +278 -0
- data/lib/mark_mapper/railtie.rb +52 -0
- data/lib/mark_mapper/railtie/database.rake +65 -0
- data/lib/mark_mapper/translation.rb +10 -0
- data/lib/mark_mapper/version.rb +4 -0
- data/lib/rails/generators/mark_mapper/config/config_generator.rb +37 -0
- data/lib/rails/generators/mark_mapper/config/templates/marklogic.yml +19 -0
- data/lib/rails/generators/mark_mapper/model/model_generator.rb +40 -0
- data/lib/rails/generators/mark_mapper/model/templates/model.rb +17 -0
- data/spec/config/mark_mapper.yml +6 -0
- data/spec/examples_spec.rb +25 -0
- data/spec/functional/accessible_spec.rb +198 -0
- data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +64 -0
- data/spec/functional/associations/belongs_to_proxy_spec.rb +255 -0
- data/spec/functional/associations/in_array_proxy_spec.rb +349 -0
- data/spec/functional/associations/many_documents_as_proxy_spec.rb +230 -0
- data/spec/functional/associations/many_documents_proxy_spec.rb +968 -0
- data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +238 -0
- data/spec/functional/associations/many_embedded_proxy_spec.rb +288 -0
- data/spec/functional/associations/many_polymorphic_proxy_spec.rb +302 -0
- data/spec/functional/associations/one_as_proxy_spec.rb +489 -0
- data/spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb +207 -0
- data/spec/functional/associations/one_embedded_proxy_spec.rb +100 -0
- data/spec/functional/associations/one_proxy_spec.rb +406 -0
- data/spec/functional/associations_spec.rb +48 -0
- data/spec/functional/caching_spec.rb +75 -0
- data/spec/functional/callbacks_spec.rb +330 -0
- data/spec/functional/counter_cache_spec.rb +235 -0
- data/spec/functional/dirty_spec.rb +316 -0
- data/spec/functional/document_spec.rb +310 -0
- data/spec/functional/dumpable_spec.rb +24 -0
- data/spec/functional/dynamic_querying_spec.rb +75 -0
- data/spec/functional/embedded_document_spec.rb +316 -0
- data/spec/functional/equality_spec.rb +20 -0
- data/spec/functional/extensions_spec.rb +16 -0
- data/spec/functional/identity_map_spec.rb +483 -0
- data/spec/functional/keys_spec.rb +339 -0
- data/spec/functional/logger_spec.rb +20 -0
- data/spec/functional/modifiers_spec.rb +446 -0
- data/spec/functional/options_hash_spec.rb +41 -0
- data/spec/functional/pagination_spec.rb +89 -0
- data/spec/functional/partial_updates_spec.rb +530 -0
- data/spec/functional/protected_spec.rb +199 -0
- data/spec/functional/querying_spec.rb +984 -0
- data/spec/functional/rails_spec.rb +55 -0
- data/spec/functional/sci_spec.rb +374 -0
- data/spec/functional/scopes_spec.rb +204 -0
- data/spec/functional/static_keys_spec.rb +153 -0
- data/spec/functional/timestamps_spec.rb +97 -0
- data/spec/functional/touch_spec.rb +125 -0
- data/spec/functional/userstamps_spec.rb +46 -0
- data/spec/functional/validations_spec.rb +416 -0
- data/spec/quality_spec.rb +51 -0
- data/spec/spec_helper.rb +150 -0
- data/spec/support/matchers.rb +15 -0
- data/spec/support/models.rb +256 -0
- data/spec/symbol_operator_spec.rb +70 -0
- data/spec/symbol_spec.rb +9 -0
- data/spec/unit/associations/base_spec.rb +146 -0
- data/spec/unit/associations/belongs_to_association_spec.rb +30 -0
- data/spec/unit/associations/many_association_spec.rb +64 -0
- data/spec/unit/associations/one_association_spec.rb +48 -0
- data/spec/unit/associations/proxy_spec.rb +103 -0
- data/spec/unit/clone_spec.rb +79 -0
- data/spec/unit/config_generator_spec.rb +24 -0
- data/spec/unit/criteria_hash_spec.rb +218 -0
- data/spec/unit/document_spec.rb +251 -0
- data/spec/unit/dynamic_finder_spec.rb +125 -0
- data/spec/unit/embedded_document_spec.rb +676 -0
- data/spec/unit/equality_spec.rb +38 -0
- data/spec/unit/exceptions_spec.rb +12 -0
- data/spec/unit/extensions_spec.rb +368 -0
- data/spec/unit/identity_map_middleware_spec.rb +134 -0
- data/spec/unit/inspect_spec.rb +47 -0
- data/spec/unit/key_spec.rb +276 -0
- data/spec/unit/keys_spec.rb +155 -0
- data/spec/unit/mark_mapper_spec.rb +37 -0
- data/spec/unit/model_generator_spec.rb +45 -0
- data/spec/unit/normalizers/criteria_hash_key_spec.rb +37 -0
- data/spec/unit/normalizers/criteria_hash_value_spec.rb +200 -0
- data/spec/unit/normalizers/fields_value_spec.rb +45 -0
- data/spec/unit/normalizers/hash_key_spec.rb +15 -0
- data/spec/unit/normalizers/integer_spec.rb +24 -0
- data/spec/unit/normalizers/options_hash_value_spec.rb +99 -0
- data/spec/unit/normalizers/sort_value_spec.rb +98 -0
- data/spec/unit/options_hash_spec.rb +64 -0
- data/spec/unit/pagination/collection_spec.rb +30 -0
- data/spec/unit/pagination/paginator_spec.rb +118 -0
- data/spec/unit/pagination_spec.rb +11 -0
- data/spec/unit/plugins_spec.rb +89 -0
- data/spec/unit/query_spec.rb +837 -0
- data/spec/unit/rails_compatibility_spec.rb +40 -0
- data/spec/unit/rails_reflect_on_association_spec.rb +118 -0
- data/spec/unit/rails_spec.rb +188 -0
- data/spec/unit/serialization_spec.rb +169 -0
- data/spec/unit/serializers/json_serializer_spec.rb +218 -0
- data/spec/unit/serializers/xml_serializer_spec.rb +198 -0
- data/spec/unit/time_zones_spec.rb +44 -0
- data/spec/unit/translation_spec.rb +27 -0
- data/spec/unit/validations_spec.rb +588 -0
- metadata +307 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Clone" do
|
4
|
+
context "Document" do
|
5
|
+
before do
|
6
|
+
@document = Doc()
|
7
|
+
@embedded = EDoc()
|
8
|
+
@document.many :widgets, :class => @embedded
|
9
|
+
@tags = ['red', 'green', 'blue']
|
10
|
+
@doc = @document.create({
|
11
|
+
:name => "foo",
|
12
|
+
:age => 27,
|
13
|
+
:tags => @tags,
|
14
|
+
:widgets => [@embedded.new, @embedded.new],
|
15
|
+
})
|
16
|
+
end
|
17
|
+
|
18
|
+
context "#clone" do
|
19
|
+
it "should be new" do
|
20
|
+
@doc.clone.should be_new
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should copy the attributes" do
|
24
|
+
clone = @doc.clone
|
25
|
+
clone.name.should == "foo"
|
26
|
+
clone.age.should == 27
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should clone duplicable attributes" do
|
30
|
+
@doc.clone.tags.should_not equal(@tags)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should clone many embedded documents" do
|
34
|
+
@doc.clone.widgets.object_id.should_not equal(@doc.widgets.object_id)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should not be destroyed" do
|
38
|
+
@doc.destroy
|
39
|
+
@doc.clone.should_not be_destroyed
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should generate a new id" do
|
43
|
+
@doc.clone.id.should_not be_nil
|
44
|
+
@doc.clone.id.should_not equal(@doc.id)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should clone a cloned document" do
|
48
|
+
expect { @doc.clone.clone }.to_not raise_error
|
49
|
+
@doc.clone.clone.id.should be_a MarkLogic::ObjectId
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "EmbeddedDocument" do
|
55
|
+
before do
|
56
|
+
@document = EDoc do
|
57
|
+
key :name, String
|
58
|
+
key :age, Integer
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "#clone" do
|
63
|
+
it "should regenerate the id" do
|
64
|
+
doc = @document.new(:name => "foo", :age => 27)
|
65
|
+
doc_id = doc.id
|
66
|
+
clone = doc.clone
|
67
|
+
clone_id = clone.id
|
68
|
+
clone_id.should_not == doc_id
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should copy the attributes" do
|
72
|
+
doc = @document.new(:name => "foo", :age => 27)
|
73
|
+
clone = doc.clone
|
74
|
+
clone.name.should == "foo"
|
75
|
+
clone.age.should == 27
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# require 'spec_helper'
|
2
|
+
# require 'rails/generators'
|
3
|
+
# require 'rails/generators/test_case'
|
4
|
+
# require 'rails/generators/mark_mapper/config/config_generator'
|
5
|
+
|
6
|
+
# describe MarkMapper::Generators::ConfigGenerator do
|
7
|
+
# include GeneratorSpec::TestCase
|
8
|
+
|
9
|
+
# destination File.expand_path('../../tmp', File.dirname(__FILE__))
|
10
|
+
# before do
|
11
|
+
# prepare_destination
|
12
|
+
# end
|
13
|
+
|
14
|
+
# it 'marklogic.yml are properly created' do
|
15
|
+
# run_generator
|
16
|
+
# assert_file 'config/marklogic.yml', /#{File.basename(destination_root)}/
|
17
|
+
# end
|
18
|
+
|
19
|
+
# it 'marklogic.yml are properly created with defined database_name' do
|
20
|
+
# run_generator %w{dummy}
|
21
|
+
# assert_file 'config/marklogic.yml', /dummy/
|
22
|
+
# end
|
23
|
+
|
24
|
+
# end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
describe MarkMapper::CriteriaHash do
|
5
|
+
context "#initialize_copy" do
|
6
|
+
before do
|
7
|
+
@original = described_class.new({
|
8
|
+
:comments => {:_id => 1}, :tags => ['marklogic', 'ruby'],
|
9
|
+
}, :object_ids => [:_id])
|
10
|
+
@cloned = @original.clone
|
11
|
+
end
|
12
|
+
|
13
|
+
it "duplicates source hash" do
|
14
|
+
@cloned.source.should_not equal(@original.source)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "duplicates options hash" do
|
18
|
+
@cloned.options.should_not equal(@original.options)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "clones duplicable? values" do
|
22
|
+
@cloned[:comments].should_not equal(@original[:comments])
|
23
|
+
@cloned[:tags].should_not equal(@original[:tags])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "#object_ids=" do
|
28
|
+
it "works with array" do
|
29
|
+
criteria = described_class.new
|
30
|
+
criteria.object_ids = [:_id]
|
31
|
+
criteria.object_ids.should == [:_id]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "flattens multi-dimensional array" do
|
35
|
+
criteria = described_class.new
|
36
|
+
criteria.object_ids = [[:_id]]
|
37
|
+
criteria.object_ids.should == [:_id]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "raises argument error if not array" do
|
41
|
+
expect { described_class.new.object_ids = {} }.to raise_error(ArgumentError)
|
42
|
+
expect { described_class.new.object_ids = nil }.to raise_error(ArgumentError)
|
43
|
+
expect { described_class.new.object_ids = 'foo' }.to raise_error(ArgumentError)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "#[]=" do
|
48
|
+
context "with key and value" do
|
49
|
+
let(:key_normalizer) { lambda { |*args| :normalized_key } }
|
50
|
+
let(:value_normalizer) { lambda { |*args| 'normalized_value' } }
|
51
|
+
|
52
|
+
it "sets normalized key to normalized value in source" do
|
53
|
+
criteria = described_class.new({}, :value_normalizer => value_normalizer, :key_normalizer => key_normalizer)
|
54
|
+
criteria[:foo] = 'bar'
|
55
|
+
criteria.source[:normalized_key].should eq('normalized_value')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "with conditions" do
|
60
|
+
it "sets each of conditions keys in source" do
|
61
|
+
criteria = described_class.new
|
62
|
+
criteria[:conditions] = {:_id => 'john', :foo => 'bar'}
|
63
|
+
criteria.source[:_id].should eq('john')
|
64
|
+
criteria.source[:foo].should eq('bar')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with symbol operators" do
|
69
|
+
it "sets nests key with operator and value" do
|
70
|
+
criteria = described_class.new
|
71
|
+
criteria[:age.gt] = 20
|
72
|
+
criteria[:age.lt] = 10
|
73
|
+
criteria.source[:age].should eq({:$gt => 20, :$lt => 10})
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "#merge" do
|
79
|
+
it "works when no keys match" do
|
80
|
+
c1 = described_class.new(:foo => 'bar')
|
81
|
+
c2 = described_class.new(:baz => 'wick')
|
82
|
+
c1.merge(c2).source.should eq(:foo => 'bar', :baz => 'wick')
|
83
|
+
end
|
84
|
+
|
85
|
+
it "turns matching keys with simple values into array" do
|
86
|
+
c1 = described_class.new(:foo => 'bar')
|
87
|
+
c2 = described_class.new(:foo => 'baz')
|
88
|
+
c1.merge(c2).source.should eq(:foo => {:$eq => %w[bar baz]})
|
89
|
+
end
|
90
|
+
|
91
|
+
it "uniques matching key values" do
|
92
|
+
c1 = described_class.new(:foo => 'bar')
|
93
|
+
c2 = described_class.new(:foo => 'bar')
|
94
|
+
c1.merge(c2).source.should eq(:foo => {:$eq => %w[bar]})
|
95
|
+
end
|
96
|
+
|
97
|
+
it "correctly merges arrays and non-arrays" do
|
98
|
+
c1 = described_class.new(:foo => 'bar')
|
99
|
+
c2 = described_class.new(:foo => %w[bar baz])
|
100
|
+
c1.merge(c2).source.should eq(:foo => {:$eq => %w[bar baz]})
|
101
|
+
c2.merge(c1).source.should eq(:foo => {:$eq => %w[bar baz]})
|
102
|
+
end
|
103
|
+
|
104
|
+
it "correctly merges two bson object ids" do
|
105
|
+
id1 = SecureRandom.hex
|
106
|
+
id2 = SecureRandom.hex
|
107
|
+
c1 = described_class.new(:foo => id1)
|
108
|
+
c2 = described_class.new(:foo => id2)
|
109
|
+
c1.merge(c2).source.should eq(:foo => {:$eq => [id1, id2]})
|
110
|
+
end
|
111
|
+
|
112
|
+
it "correctly merges array and an object id" do
|
113
|
+
id1 = SecureRandom.hex
|
114
|
+
id2 = SecureRandom.hex
|
115
|
+
c1 = described_class.new(:foo => [id1])
|
116
|
+
c2 = described_class.new(:foo => id2)
|
117
|
+
c1.merge(c2).source.should eq(:foo => {:$eq => [id1, id2]})
|
118
|
+
c2.merge(c1).source.should eq(:foo => {:$eq => [id1, id2]})
|
119
|
+
end
|
120
|
+
|
121
|
+
it "is able to merge two modifier hashes" do
|
122
|
+
c1 = described_class.new(:$eq => [1, 2])
|
123
|
+
c2 = described_class.new(:$eq => [2, 3])
|
124
|
+
c1.merge(c2).source.should eq(:$eq => [1, 2, 3])
|
125
|
+
end
|
126
|
+
|
127
|
+
it "is able to merge two modifier hashes with hash values" do
|
128
|
+
c1 = described_class.new(:arr => {:$elemMatch => {:foo => 'bar'}})
|
129
|
+
c2 = described_class.new(:arr => {:$elemMatch => {:omg => 'ponies'}})
|
130
|
+
c1.merge(c2).source.should eq(:arr => {:$elemMatch => {:foo => 'bar', :omg => 'ponies'}})
|
131
|
+
end
|
132
|
+
|
133
|
+
it "merges matching keys with a single modifier" do
|
134
|
+
c1 = described_class.new(:foo => {:$eq => [1, 2, 3]})
|
135
|
+
c2 = described_class.new(:foo => {:$eq => [1, 4, 5]})
|
136
|
+
c1.merge(c2).source.should eq(:foo => {:$eq => [1, 2, 3, 4, 5]})
|
137
|
+
end
|
138
|
+
|
139
|
+
it "merges matching keys with multiple modifiers" do
|
140
|
+
c1 = described_class.new(:foo => {:$eq => [1, 2, 3]})
|
141
|
+
c2 = described_class.new(:foo => {:$all => [1, 4, 5]})
|
142
|
+
c1.merge(c2).source.should eq(:foo => {:$eq => [1, 2, 3], :$all => [1, 4, 5]})
|
143
|
+
end
|
144
|
+
|
145
|
+
it "does not update mergee" do
|
146
|
+
c1 = described_class.new(:foo => 'bar')
|
147
|
+
c2 = described_class.new(:foo => 'baz')
|
148
|
+
c1.merge(c2).should_not equal(c1)
|
149
|
+
c1[:foo].should == 'bar'
|
150
|
+
end
|
151
|
+
|
152
|
+
context "given multiple $or clauses" do
|
153
|
+
before do
|
154
|
+
@c1 = described_class.new(:$or => [{:a => 1}, {:b => 2}])
|
155
|
+
@c2 = described_class.new(:$or => [{:a => 3}, {:b => 4}])
|
156
|
+
@c3 = described_class.new(:$or => [{:a => 4}, {:b => 4}])
|
157
|
+
end
|
158
|
+
|
159
|
+
it "merges two $ors into a compound $and" do
|
160
|
+
merged = @c1.merge(@c2)
|
161
|
+
merged[:$and].should == [
|
162
|
+
{:$or => [{:a => 1}, {:b => 2}]},
|
163
|
+
{:$or => [{:a => 3}, {:b => 4}]}
|
164
|
+
]
|
165
|
+
end
|
166
|
+
|
167
|
+
it "merges an $and and a $or into a compound $and" do
|
168
|
+
merged = @c1.merge(@c2).merge(@c3)
|
169
|
+
merged[:$and].should == [
|
170
|
+
{:$or => [{:a => 1}, {:b => 2}]},
|
171
|
+
{:$or => [{:a => 3}, {:b => 4}]},
|
172
|
+
{:$or => [{:a => 4}, {:b => 4}]}
|
173
|
+
]
|
174
|
+
end
|
175
|
+
|
176
|
+
it "merges an $or and an $and into a compound $and" do
|
177
|
+
merged = @c3.merge @c1.merge(@c2)
|
178
|
+
merged[:$and].should == [
|
179
|
+
{:$or => [{:a => 1}, {:b => 2}]},
|
180
|
+
{:$or => [{:a => 3}, {:b => 4}]},
|
181
|
+
{:$or => [{:a => 4}, {:b => 4}]}
|
182
|
+
]
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context "#merge!" do
|
188
|
+
it "updates mergee" do
|
189
|
+
c1 = described_class.new(:foo => 'bar')
|
190
|
+
c2 = described_class.new(:foo => 'baz')
|
191
|
+
c1.merge!(c2).should equal(c1)
|
192
|
+
c1[:foo].should == {:$eq => ['bar', 'baz']}
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context "#simple?" do
|
197
|
+
it "returns true if only filtering by _id" do
|
198
|
+
described_class.new(:_id => 'id').should be_simple
|
199
|
+
end
|
200
|
+
|
201
|
+
it "returns true if only filtering by Sci" do
|
202
|
+
described_class.new(:_id => 'id', :_type => 'Foo').should be_simple
|
203
|
+
described_class.new(:_type => 'Foo', :_id => 'id').should be_simple # reverse order
|
204
|
+
end
|
205
|
+
|
206
|
+
it "returns false if querying by more than max number of simple keys" do
|
207
|
+
described_class.new(:one => 1, :two => 2, :three => 3).should_not be_simple
|
208
|
+
end
|
209
|
+
|
210
|
+
it "returns false if querying by anthing other than _id/Sci" do
|
211
|
+
described_class.new(:foo => 'bar').should_not be_simple
|
212
|
+
end
|
213
|
+
|
214
|
+
it "returns false if querying only by _type" do
|
215
|
+
described_class.new(:_type => 'Foo').should_not be_simple
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe "Document" do
|
5
|
+
context "The Document Class" do
|
6
|
+
before do
|
7
|
+
@document = Doc()
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should return false for embeddable" do
|
11
|
+
Doc().embeddable?.should be_falsey
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have logger method" do
|
15
|
+
@document.logger.should == MarkMapper.logger
|
16
|
+
@document.logger.should be_instance_of(Logger)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should use default database by default" do
|
20
|
+
@document.database.should == MarkMapper.application.content_databases[0]
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have a connection" do
|
24
|
+
@document.connection.should be_instance_of(MarkLogic::Connection)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should allow setting different connection without affecting the default" do
|
28
|
+
conn = MarkLogic::Connection.new(HOST, PORT)
|
29
|
+
@document.connection conn
|
30
|
+
@document.connection.should be conn
|
31
|
+
@document.connection.should_not be MarkMapper.connection
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should allow setting a different database without affecting the default" do
|
35
|
+
db = MarkLogic::Database.new('test2', CONNECTION)
|
36
|
+
@document.database = db
|
37
|
+
@document.database.should == db
|
38
|
+
@document.database_name.should == 'test2'
|
39
|
+
@document.database.database_name.should == 'test2'
|
40
|
+
|
41
|
+
another_document = Doc()
|
42
|
+
another_document.database.database_name.should == MarkMapper.application.content_databases[0].database_name
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should allow setting the collection name" do
|
46
|
+
@document.set_collection_name('foobar')
|
47
|
+
@document.collection.name.should == 'foobar'
|
48
|
+
end
|
49
|
+
|
50
|
+
context ".collection" do
|
51
|
+
it "should default collection name to class name tableized" do
|
52
|
+
class ::Item
|
53
|
+
include MarkMapper::Document
|
54
|
+
end.collection.name.should == 'items'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should default collection name of namespaced class to tableized with dot separation" do
|
58
|
+
module ::BloggyPoo
|
59
|
+
class Post
|
60
|
+
include MarkMapper::Document
|
61
|
+
end.collection.name.should == 'bloggy_poo.posts'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should be an instance of a MarkLogic::Collection" do
|
66
|
+
@document.collection.should be_instance_of(MarkLogic::Collection)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end # Document class
|
70
|
+
|
71
|
+
context "Documents that inherit from other documents" do
|
72
|
+
it "should default collection name to inherited class" do
|
73
|
+
Message.collection_name.should == 'messages'
|
74
|
+
Enter.collection_name.should == 'messages'
|
75
|
+
Exit.collection_name.should == 'messages'
|
76
|
+
Chat.collection_name.should == 'messages'
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should default associations to inherited class" do
|
80
|
+
Message.associations.keys.should include(:room)
|
81
|
+
Enter.associations.keys.should include(:room)
|
82
|
+
Exit.associations.keys.should include(:room)
|
83
|
+
Chat.associations.keys.should include(:room)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "descendants" do
|
88
|
+
it "should default to an empty array" do
|
89
|
+
Enter.descendants.should == []
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should be recorded" do
|
93
|
+
Message.descendants.should == [Enter, Exit, Chat]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "An instance of a document" do
|
98
|
+
before do
|
99
|
+
@document = Doc do
|
100
|
+
key :name, String
|
101
|
+
key :age, Integer
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should respond to cache_key" do
|
106
|
+
@document.new.should respond_to(:cache_key)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should create id during initialization" do
|
110
|
+
@document.new._id.should be_instance_of(MarkLogic::ObjectId)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should have access to logger" do
|
114
|
+
doc = @document.new
|
115
|
+
doc.logger.should == @document.logger
|
116
|
+
doc.logger.should be_instance_of(Logger)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should have access to the class's collection" do
|
120
|
+
doc = @document.new
|
121
|
+
doc.collection.name.should == @document.collection.name
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should use default values if defined for keys" do
|
125
|
+
@document.key :active, Boolean, :default => true
|
126
|
+
|
127
|
+
@document.new.active.should be_truthy
|
128
|
+
@document.new(:active => false).active.should be_falsey
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should use default values if defined even when custom data type" do
|
132
|
+
@document.key :window, WindowSize, :default => WindowSize.new(600, 480)
|
133
|
+
|
134
|
+
doc = @document.new
|
135
|
+
doc.window.should == WindowSize.new(600, 480)
|
136
|
+
end
|
137
|
+
|
138
|
+
context "root document" do
|
139
|
+
it "should set self to the root document on embedded documents" do
|
140
|
+
klass = Doc()
|
141
|
+
pets = EDoc()
|
142
|
+
|
143
|
+
klass.many :pets, :class => pets
|
144
|
+
|
145
|
+
doc = klass.new(:pets => [{}])
|
146
|
+
doc.pets.first._root_document.should == doc
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "new?" do
|
151
|
+
it "should be true if no id" do
|
152
|
+
@document.new.new?.should be_truthy
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should be true if id but using custom id and not saved yet" do
|
156
|
+
@document.key :_id, String
|
157
|
+
doc = silence_stderr { @document.new }
|
158
|
+
doc.id = '1234'
|
159
|
+
doc.new?.should be_truthy
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "equality" do
|
164
|
+
before do
|
165
|
+
@oid = MarkLogic::ObjectId.new
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should delegate hash to _id" do
|
169
|
+
doc = @document.new
|
170
|
+
doc.hash.should == doc._id.hash
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should delegate eql to ==" do
|
174
|
+
doc = @document.new
|
175
|
+
other = @document.new
|
176
|
+
doc.eql?(other).should == (doc == other)
|
177
|
+
doc.eql?(doc).should == (doc == doc)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should know if same object as another" do
|
181
|
+
doc = @document.new
|
182
|
+
doc.should equal(doc)
|
183
|
+
doc.should_not equal(@document.new)
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should allow set operations on array of documents" do
|
187
|
+
@document.key :parent_id, ObjectId
|
188
|
+
@document.belongs_to :parent, :class => @document
|
189
|
+
|
190
|
+
parent = @document.create
|
191
|
+
child = @document.create(:parent => parent)
|
192
|
+
|
193
|
+
([child.parent] & [parent]).should == [parent]
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should be equal if id and class are the same" do
|
197
|
+
(@document.new('_id' => @oid) == @document.new('_id' => @oid)).should be(true)
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should not be equal if class same but id different" do
|
201
|
+
(@document.new('_id' => @oid) == @document.new('_id' => MarkLogic::ObjectId.new)).should be(false)
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should not be equal if id same but class different" do
|
205
|
+
another_document = Doc()
|
206
|
+
(@document.new('_id' => @oid) == another_document.new('_id' => @oid)).should be(false)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context "nil attributes" do
|
211
|
+
|
212
|
+
it "should list all the keys and default non nil attributes" do
|
213
|
+
doc = @document.new
|
214
|
+
doc.keys.keys.sort.should == ['_id', 'age', 'name']
|
215
|
+
doc.attributes.keys.sort.should == ['_id']
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should list all the keys and non nil attributes" do
|
219
|
+
doc = @document.new(:name => "John")
|
220
|
+
doc.keys.keys.sort.should == ['_id', 'age', 'name']
|
221
|
+
doc.attributes.keys.sort.should == ['_id','name']
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should list all the keys and pickup changed nil attributes" do
|
225
|
+
doc = @document.new(:name => "John")
|
226
|
+
doc.keys.keys.sort.should == ['_id', 'age', 'name']
|
227
|
+
doc.attributes.keys.sort.should == ['_id','name']
|
228
|
+
|
229
|
+
doc.name = nil
|
230
|
+
|
231
|
+
doc.keys.keys.sort.should == ['_id', 'age', 'name']
|
232
|
+
doc.attributes.keys.sort.should == ['_id']
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should list all the keys and pickup changed nil and non-nil attributes" do
|
236
|
+
doc = @document.new(:name => "John")
|
237
|
+
doc.keys.keys.sort.should == ['_id', 'age', 'name']
|
238
|
+
doc.attributes.keys.sort.should == ['_id','name']
|
239
|
+
|
240
|
+
doc.name = nil
|
241
|
+
doc.age = 12
|
242
|
+
|
243
|
+
doc.keys.keys.sort.should == ['_id', 'age', 'name']
|
244
|
+
doc.attributes.keys.sort.should == ['_id','age']
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
end # instance of a document
|
250
|
+
end # DocumentTest
|
251
|
+
|