sbf-dm-core 1.3.0.beta
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/.autotest +29 -0
- data/.document +5 -0
- data/.gitignore +44 -0
- data/.rspec +1 -0
- data/.rubocop.yml +468 -0
- data/.travis.yml +57 -0
- data/.yardopts +1 -0
- data/Gemfile +70 -0
- data/LICENSE +20 -0
- data/README.md +269 -0
- data/Rakefile +4 -0
- data/dm-core.gemspec +21 -0
- data/lib/dm-core/adapters/abstract_adapter.rb +233 -0
- data/lib/dm-core/adapters/in_memory_adapter.rb +110 -0
- data/lib/dm-core/adapters.rb +249 -0
- data/lib/dm-core/associations/many_to_many.rb +477 -0
- data/lib/dm-core/associations/many_to_one.rb +282 -0
- data/lib/dm-core/associations/one_to_many.rb +332 -0
- data/lib/dm-core/associations/one_to_one.rb +84 -0
- data/lib/dm-core/associations/relationship.rb +650 -0
- data/lib/dm-core/backwards.rb +11 -0
- data/lib/dm-core/collection.rb +1486 -0
- data/lib/dm-core/core_ext/kernel.rb +21 -0
- data/lib/dm-core/core_ext/pathname.rb +4 -0
- data/lib/dm-core/core_ext/symbol.rb +10 -0
- data/lib/dm-core/identity_map.rb +6 -0
- data/lib/dm-core/model/hook.rb +99 -0
- data/lib/dm-core/model/is.rb +30 -0
- data/lib/dm-core/model/property.rb +244 -0
- data/lib/dm-core/model/relationship.rb +366 -0
- data/lib/dm-core/model/scope.rb +87 -0
- data/lib/dm-core/model.rb +876 -0
- data/lib/dm-core/property/binary.rb +19 -0
- data/lib/dm-core/property/boolean.rb +35 -0
- data/lib/dm-core/property/class.rb +23 -0
- data/lib/dm-core/property/date.rb +45 -0
- data/lib/dm-core/property/date_time.rb +44 -0
- data/lib/dm-core/property/decimal.rb +47 -0
- data/lib/dm-core/property/discriminator.rb +40 -0
- data/lib/dm-core/property/float.rb +27 -0
- data/lib/dm-core/property/integer.rb +32 -0
- data/lib/dm-core/property/invalid_value_error.rb +17 -0
- data/lib/dm-core/property/lookup.rb +26 -0
- data/lib/dm-core/property/numeric.rb +35 -0
- data/lib/dm-core/property/object.rb +33 -0
- data/lib/dm-core/property/serial.rb +13 -0
- data/lib/dm-core/property/string.rb +47 -0
- data/lib/dm-core/property/text.rb +12 -0
- data/lib/dm-core/property/time.rb +46 -0
- data/lib/dm-core/property/typecast/numeric.rb +32 -0
- data/lib/dm-core/property/typecast/time.rb +33 -0
- data/lib/dm-core/property.rb +856 -0
- data/lib/dm-core/property_set.rb +177 -0
- data/lib/dm-core/query/conditions/comparison.rb +886 -0
- data/lib/dm-core/query/conditions/operation.rb +710 -0
- data/lib/dm-core/query/direction.rb +33 -0
- data/lib/dm-core/query/operator.rb +34 -0
- data/lib/dm-core/query/path.rb +113 -0
- data/lib/dm-core/query/sort.rb +38 -0
- data/lib/dm-core/query.rb +1352 -0
- data/lib/dm-core/relationship_set.rb +69 -0
- data/lib/dm-core/repository.rb +226 -0
- data/lib/dm-core/resource/persistence_state/clean.rb +36 -0
- data/lib/dm-core/resource/persistence_state/deleted.rb +26 -0
- data/lib/dm-core/resource/persistence_state/dirty.rb +91 -0
- data/lib/dm-core/resource/persistence_state/immutable.rb +32 -0
- data/lib/dm-core/resource/persistence_state/persisted.rb +25 -0
- data/lib/dm-core/resource/persistence_state/transient.rb +87 -0
- data/lib/dm-core/resource/persistence_state.rb +70 -0
- data/lib/dm-core/resource.rb +1220 -0
- data/lib/dm-core/spec/lib/adapter_helpers.rb +63 -0
- data/lib/dm-core/spec/lib/collection_helpers.rb +21 -0
- data/lib/dm-core/spec/lib/counter_adapter.rb +38 -0
- data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
- data/lib/dm-core/spec/lib/spec_helper.rb +74 -0
- data/lib/dm-core/spec/setup.rb +164 -0
- data/lib/dm-core/spec/shared/adapter_spec.rb +366 -0
- data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +1221 -0
- data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
- data/lib/dm-core/spec/shared/semipublic/property_spec.rb +184 -0
- data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
- data/lib/dm-core/support/assertions.rb +8 -0
- data/lib/dm-core/support/chainable.rb +18 -0
- data/lib/dm-core/support/deprecate.rb +12 -0
- data/lib/dm-core/support/descendant_set.rb +89 -0
- data/lib/dm-core/support/equalizer.rb +48 -0
- data/lib/dm-core/support/ext/array.rb +22 -0
- data/lib/dm-core/support/ext/blank.rb +25 -0
- data/lib/dm-core/support/ext/hash.rb +67 -0
- data/lib/dm-core/support/ext/module.rb +47 -0
- data/lib/dm-core/support/ext/object.rb +57 -0
- data/lib/dm-core/support/ext/string.rb +24 -0
- data/lib/dm-core/support/ext/try_dup.rb +12 -0
- data/lib/dm-core/support/hook.rb +388 -0
- data/lib/dm-core/support/inflections.rb +60 -0
- data/lib/dm-core/support/inflector/inflections.rb +211 -0
- data/lib/dm-core/support/inflector/methods.rb +151 -0
- data/lib/dm-core/support/lazy_array.rb +451 -0
- data/lib/dm-core/support/local_object_space.rb +13 -0
- data/lib/dm-core/support/logger.rb +201 -0
- data/lib/dm-core/support/mash.rb +176 -0
- data/lib/dm-core/support/naming_conventions.rb +109 -0
- data/lib/dm-core/support/ordered_set.rb +381 -0
- data/lib/dm-core/support/subject.rb +33 -0
- data/lib/dm-core/support/subject_set.rb +251 -0
- data/lib/dm-core/version.rb +3 -0
- data/lib/dm-core.rb +274 -0
- data/script/performance.rb +275 -0
- data/script/profile.rb +218 -0
- data/spec/lib/rspec_immediate_feedback_formatter.rb +54 -0
- data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +69 -0
- data/spec/public/associations/many_to_many_spec.rb +197 -0
- data/spec/public/associations/many_to_one_spec.rb +83 -0
- data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +40 -0
- data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +49 -0
- data/spec/public/associations/one_to_many_spec.rb +81 -0
- data/spec/public/associations/one_to_one_spec.rb +176 -0
- data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +46 -0
- data/spec/public/collection_spec.rb +69 -0
- data/spec/public/finalize_spec.rb +77 -0
- data/spec/public/model/hook_spec.rb +245 -0
- data/spec/public/model/property_spec.rb +91 -0
- data/spec/public/model/relationship_spec.rb +1040 -0
- data/spec/public/model_spec.rb +456 -0
- data/spec/public/property/binary_spec.rb +43 -0
- data/spec/public/property/boolean_spec.rb +21 -0
- data/spec/public/property/class_spec.rb +27 -0
- data/spec/public/property/date_spec.rb +21 -0
- data/spec/public/property/date_time_spec.rb +21 -0
- data/spec/public/property/decimal_spec.rb +23 -0
- data/spec/public/property/discriminator_spec.rb +134 -0
- data/spec/public/property/float_spec.rb +22 -0
- data/spec/public/property/integer_spec.rb +22 -0
- data/spec/public/property/object_spec.rb +117 -0
- data/spec/public/property/serial_spec.rb +22 -0
- data/spec/public/property/string_spec.rb +21 -0
- data/spec/public/property/text_spec.rb +62 -0
- data/spec/public/property/time_spec.rb +21 -0
- data/spec/public/property_spec.rb +333 -0
- data/spec/public/resource/state_spec.rb +72 -0
- data/spec/public/resource_spec.rb +289 -0
- data/spec/public/sel_spec.rb +53 -0
- data/spec/public/setup_spec.rb +145 -0
- data/spec/public/shared/association_collection_shared_spec.rb +309 -0
- data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
- data/spec/public/shared/collection_shared_spec.rb +1637 -0
- data/spec/public/shared/finder_shared_spec.rb +1647 -0
- data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
- data/spec/semipublic/adapters/in_memory_adapter_spec.rb +13 -0
- data/spec/semipublic/associations/many_to_many_spec.rb +94 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +63 -0
- data/spec/semipublic/associations/one_to_many_spec.rb +55 -0
- data/spec/semipublic/associations/one_to_one_spec.rb +53 -0
- data/spec/semipublic/associations/relationship_spec.rb +200 -0
- data/spec/semipublic/associations_spec.rb +177 -0
- data/spec/semipublic/collection_spec.rb +110 -0
- data/spec/semipublic/model_spec.rb +96 -0
- data/spec/semipublic/property/binary_spec.rb +13 -0
- data/spec/semipublic/property/boolean_spec.rb +47 -0
- data/spec/semipublic/property/class_spec.rb +33 -0
- data/spec/semipublic/property/date_spec.rb +43 -0
- data/spec/semipublic/property/date_time_spec.rb +46 -0
- data/spec/semipublic/property/decimal_spec.rb +83 -0
- data/spec/semipublic/property/discriminator_spec.rb +19 -0
- data/spec/semipublic/property/float_spec.rb +82 -0
- data/spec/semipublic/property/integer_spec.rb +82 -0
- data/spec/semipublic/property/lookup_spec.rb +29 -0
- data/spec/semipublic/property/serial_spec.rb +13 -0
- data/spec/semipublic/property/string_spec.rb +13 -0
- data/spec/semipublic/property/text_spec.rb +31 -0
- data/spec/semipublic/property/time_spec.rb +50 -0
- data/spec/semipublic/property_spec.rb +114 -0
- data/spec/semipublic/query/conditions/comparison_spec.rb +1502 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1296 -0
- data/spec/semipublic/query/path_spec.rb +471 -0
- data/spec/semipublic/query_spec.rb +3665 -0
- data/spec/semipublic/resource/state/clean_spec.rb +89 -0
- data/spec/semipublic/resource/state/deleted_spec.rb +79 -0
- data/spec/semipublic/resource/state/dirty_spec.rb +163 -0
- data/spec/semipublic/resource/state/immutable_spec.rb +107 -0
- data/spec/semipublic/resource/state/transient_spec.rb +163 -0
- data/spec/semipublic/resource/state_spec.rb +230 -0
- data/spec/semipublic/resource_spec.rb +23 -0
- data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +198 -0
- data/spec/semipublic/shared/resource_state_shared_spec.rb +91 -0
- data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/support/core_ext/hash.rb +10 -0
- data/spec/support/core_ext/inheritable_attributes.rb +46 -0
- data/spec/support/properties/huge_integer.rb +17 -0
- data/spec/unit/array_spec.rb +23 -0
- data/spec/unit/blank_spec.rb +73 -0
- data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
- data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
- data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
- data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
- data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
- data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
- data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
- data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
- data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
- data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
- data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
- data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
- data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
- data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
- data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
- data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
- data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
- data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
- data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
- data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
- data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
- data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
- data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
- data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
- data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
- data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
- data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
- data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
- data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
- data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
- data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
- data/spec/unit/hash_spec.rb +27 -0
- data/spec/unit/hook_spec.rb +1216 -0
- data/spec/unit/inflections_spec.rb +14 -0
- data/spec/unit/lazy_array_spec.rb +1949 -0
- data/spec/unit/mash_spec.rb +289 -0
- data/spec/unit/module_spec.rb +70 -0
- data/spec/unit/object_spec.rb +38 -0
- data/spec/unit/try_dup_spec.rb +46 -0
- data/tasks/ci.rake +1 -0
- data/tasks/spec.rake +18 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +323 -0
|
@@ -0,0 +1,1637 @@
|
|
|
1
|
+
shared_examples 'A public Collection' do
|
|
2
|
+
before :all do
|
|
3
|
+
%w(@article_model @article @other @original @articles @other_articles).each do |ivar|
|
|
4
|
+
raise "+#{ivar}+ is defined in before block" unless instance_variable_defined?(ivar)
|
|
5
|
+
raise "+#{ivar}+ does not be nil in before block" unless instance_variable_get(ivar)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
expect(@articles.loaded?).to eq loaded
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
before :all do
|
|
12
|
+
@no_join = defined?(DataMapper::Adapters::InMemoryAdapter) && @adapter.kind_of?(DataMapper::Adapters::InMemoryAdapter) ||
|
|
13
|
+
defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
|
|
14
|
+
|
|
15
|
+
@one_to_many = @articles.kind_of?(DataMapper::Associations::OneToMany::Collection)
|
|
16
|
+
@many_to_many = @articles.kind_of?(DataMapper::Associations::ManyToMany::Collection)
|
|
17
|
+
|
|
18
|
+
@skip = @no_join && @many_to_many
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
before do
|
|
22
|
+
pending if @skip
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
subject { @articles }
|
|
26
|
+
|
|
27
|
+
it { is_expected.to respond_to(:<<) }
|
|
28
|
+
|
|
29
|
+
describe '#<<' do
|
|
30
|
+
before :all do
|
|
31
|
+
@resource = @article_model.new(:title => 'Title')
|
|
32
|
+
|
|
33
|
+
@return = @articles << @resource
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'returns a Collection' do
|
|
37
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'returns self' do
|
|
41
|
+
expect(@return).to equal(@articles)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'appends one Resource to the Collection' do
|
|
45
|
+
expect(@articles.last).to equal(@resource)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it { is_expected.to respond_to(:blank?) }
|
|
50
|
+
|
|
51
|
+
describe '#blank?' do
|
|
52
|
+
describe 'when the collection is empty' do
|
|
53
|
+
it 'is true' do
|
|
54
|
+
expect(@articles.clear.blank?).to be(true)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe 'when the collection is not empty' do
|
|
59
|
+
it 'is false' do
|
|
60
|
+
expect(@articles.blank?).to be(false)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it { is_expected.to respond_to(:clean?) }
|
|
66
|
+
|
|
67
|
+
describe '#clean?' do
|
|
68
|
+
describe 'with all clean resources in the collection' do
|
|
69
|
+
it 'returns true' do
|
|
70
|
+
expect(@articles.clean?).to be(true)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe 'with a dirty resource in the collection' do
|
|
75
|
+
before :all do
|
|
76
|
+
@articles.each { |r| r.content = 'Changed' }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'returns true' do
|
|
80
|
+
expect(@articles.clean?).to be(false)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it { is_expected.to respond_to(:clear) }
|
|
86
|
+
|
|
87
|
+
describe '#clear' do
|
|
88
|
+
before :all do
|
|
89
|
+
@resources = @articles.entries
|
|
90
|
+
|
|
91
|
+
@return = @articles.clear
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'returns a Collection' do
|
|
95
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it 'returns self' do
|
|
99
|
+
expect(@return).to equal(@articles)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it 'makes the Collection empty' do
|
|
103
|
+
expect(@articles).to be_empty
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
%i(collect! map!).each do |method|
|
|
108
|
+
it { is_expected.to respond_to(method) }
|
|
109
|
+
|
|
110
|
+
describe "##{method}" do
|
|
111
|
+
before :all do
|
|
112
|
+
@resources = @articles.dup.entries
|
|
113
|
+
|
|
114
|
+
@return = @articles.send(method) { |resource| @article_model.new(:title => 'Ignored Title', :content => 'New Content') }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it 'returns a Collection' do
|
|
118
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'returns self' do
|
|
122
|
+
expect(@return).to equal(@articles)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'updates the Collection inline' do
|
|
126
|
+
@articles.each do |resource|
|
|
127
|
+
expect(DataMapper::Ext::Hash.only(resource.attributes, :title, :content)).to eq({title: 'Sample Article', content: 'New Content'})
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it { is_expected.to respond_to(:concat) }
|
|
134
|
+
|
|
135
|
+
describe '#concat' do
|
|
136
|
+
before :all do
|
|
137
|
+
@return = @articles.concat(@other_articles)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'returns a Collection' do
|
|
141
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'returns self' do
|
|
145
|
+
expect(@return).to equal(@articles)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'concatenates the two collections' do
|
|
149
|
+
expect(@return).to eq [@article, @other]
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
%i(create create!).each do |method|
|
|
154
|
+
it { is_expected.to respond_to(method) }
|
|
155
|
+
|
|
156
|
+
describe "##{method}" do
|
|
157
|
+
describe 'when scoped to a property' do
|
|
158
|
+
before :all do
|
|
159
|
+
@return = @resource = @articles.send(method)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it 'returns a Resource' do
|
|
163
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it 'is a saved Resource' do
|
|
167
|
+
expect(@resource).to be_saved
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it 'appends the Resource to the Collection' do
|
|
171
|
+
expect(@articles.last).to equal(@resource)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it 'uses the query conditions to set default values' do
|
|
175
|
+
expect(@resource.title).to eq 'Sample Article'
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it 'does not append a Resource if create fails' do
|
|
179
|
+
pending 'TODO: not sure how to best spec this'
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
describe 'when scoped to the key' do
|
|
184
|
+
before :all do
|
|
185
|
+
@articles = @articles.all(:id => 1)
|
|
186
|
+
|
|
187
|
+
@return = @resource = @articles.send(method)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it 'returns a Resource' do
|
|
191
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it 'is a saved Resource' do
|
|
195
|
+
expect(@resource).to be_saved
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it 'appends the Resource to the Collection' do
|
|
199
|
+
expect(@articles.last).to equal(@resource)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
it 'does not use the query conditions to set default values' do
|
|
203
|
+
expect(@resource.id).not_to eq 1
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it 'does not append a Resource if create fails' do
|
|
207
|
+
pending 'TODO: not sure how to best spec this'
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
describe 'when scoped to a property with multiple values' do
|
|
212
|
+
before :all do
|
|
213
|
+
@articles = @articles.all(:content => %w[ Sample Other ])
|
|
214
|
+
|
|
215
|
+
@return = @resource = @articles.send(method)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it 'returns a Resource' do
|
|
219
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it 'is a saved Resource' do
|
|
223
|
+
expect(@resource).to be_saved
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it 'appends the Resource to the Collection' do
|
|
227
|
+
expect(@articles.last).to equal(@resource)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it 'does not use the query conditions to set default values' do
|
|
231
|
+
expect(@resource.content).to be_nil
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it 'does not append a Resource if create fails' do
|
|
235
|
+
pending 'TODO: not sure how to best spec this'
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
describe 'when scoped with a condition other than eql' do
|
|
240
|
+
before :all do
|
|
241
|
+
@articles = @articles.all(:content.not => 'Sample')
|
|
242
|
+
|
|
243
|
+
@return = @resource = @articles.send(method)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
it 'returns a Resource' do
|
|
247
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it 'is a saved Resource' do
|
|
251
|
+
expect(@resource).to be_saved
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
it 'appends the Resource to the Collection' do
|
|
255
|
+
expect(@articles.last).to equal(@resource)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it 'does not use the query conditions to set default values' do
|
|
259
|
+
expect(@resource.content).to be_nil
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
it 'does not append a Resource if create fails' do
|
|
263
|
+
pending 'TODO: not sure how to best spec this'
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
%i(difference -).each do |method|
|
|
270
|
+
it { is_expected.to respond_to(method) }
|
|
271
|
+
|
|
272
|
+
describe "##{method}" do
|
|
273
|
+
subject { @articles.send(method, @other_articles) }
|
|
274
|
+
|
|
275
|
+
describe 'with a Collection' do
|
|
276
|
+
it { is_expected.to be_kind_of(DataMapper::Collection) }
|
|
277
|
+
it { is_expected.to eq [@article] }
|
|
278
|
+
it { expect(subject.query).to eq @articles.query.difference(@other_articles.query) }
|
|
279
|
+
it { is_expected.to eq @articles.to_a - @other_articles.to_a }
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
describe 'with an Array' do
|
|
283
|
+
before { @other_articles = @other_articles.to_ary }
|
|
284
|
+
|
|
285
|
+
it { is_expected.to be_kind_of(DataMapper::Collection) }
|
|
286
|
+
it { is_expected.to eq [@article] }
|
|
287
|
+
it { is_expected.to eq @articles.to_a - @other_articles.to_a }
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
describe 'with a Set' do
|
|
291
|
+
before { @other_articles = @other_articles.to_set }
|
|
292
|
+
|
|
293
|
+
it { is_expected.to be_kind_of(DataMapper::Collection) }
|
|
294
|
+
it { is_expected.to eq [@article] }
|
|
295
|
+
it { is_expected.to eq @articles.to_a - @other_articles.to_a }
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
it { is_expected.to respond_to(:delete) }
|
|
301
|
+
|
|
302
|
+
describe '#delete' do
|
|
303
|
+
describe 'with a Resource within the Collection' do
|
|
304
|
+
before :all do
|
|
305
|
+
@return = @resource = @articles.delete(@article)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it 'returns a DataMapper::Resource' do
|
|
309
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
it 'is the expected Resource' do
|
|
313
|
+
# compare keys because FK attributes may have been altered
|
|
314
|
+
# when removing from the Collection
|
|
315
|
+
expect(@resource.key).to eq @article.key
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it 'removes the Resource from the Collection' do
|
|
319
|
+
expect(@articles).not_to include(@resource)
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
describe 'with a Resource not within the Collection' do
|
|
324
|
+
before :all do
|
|
325
|
+
@return = @articles.delete(@other)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
it 'returns nil' do
|
|
329
|
+
expect(@return).to be_nil
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it { is_expected.to respond_to(:delete_at) }
|
|
335
|
+
|
|
336
|
+
describe '#delete_at' do
|
|
337
|
+
describe 'with an offset within the Collection' do
|
|
338
|
+
before :all do
|
|
339
|
+
@return = @resource = @articles.delete_at(0)
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
it 'returns a DataMapper::Resource' do
|
|
343
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
it 'is the expected Resource' do
|
|
347
|
+
expect(@resource.key).to eq @article.key
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it 'removes the Resource from the Collection' do
|
|
351
|
+
expect(@articles).not_to include(@resource)
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
describe 'with an offset not within the Collection' do
|
|
356
|
+
before :all do
|
|
357
|
+
@return = @articles.delete_at(1)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
it 'returns nil' do
|
|
361
|
+
expect(@return).to be_nil
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
it { is_expected.to respond_to(:delete_if) }
|
|
367
|
+
|
|
368
|
+
describe '#delete_if' do
|
|
369
|
+
describe 'with a block that matches a Resource in the Collection' do
|
|
370
|
+
before :all do
|
|
371
|
+
@resources = @articles.dup.entries
|
|
372
|
+
|
|
373
|
+
@return = @articles.delete_if { true }
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
it 'returns a Collection' do
|
|
377
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
it 'returns self' do
|
|
381
|
+
expect(@return).to equal(@articles)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
it 'removes the Resources from the Collection' do
|
|
385
|
+
@resources.each { |resource| expect(@articles).not_to include(resource) }
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
describe 'with a block that does not match a Resource in the Collection' do
|
|
390
|
+
before :all do
|
|
391
|
+
@resources = @articles.dup.entries
|
|
392
|
+
|
|
393
|
+
@return = @articles.delete_if { false }
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
it 'returns a Collection' do
|
|
397
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
it 'returns self' do
|
|
401
|
+
expect(@return).to equal(@articles)
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
it 'does not modify the Collection' do
|
|
405
|
+
expect(@articles).to eq @resources
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
%i(destroy destroy!).each do |method|
|
|
411
|
+
it { is_expected.to respond_to(method) }
|
|
412
|
+
|
|
413
|
+
describe "##{method}" do
|
|
414
|
+
describe 'on a normal collection' do
|
|
415
|
+
before :all do
|
|
416
|
+
@return = @articles.send(method)
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
it 'returns true' do
|
|
420
|
+
expect(@return).to be(true)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
it 'removes the Resources from the datasource' do
|
|
424
|
+
expect(@article_model.all(title: 'Sample Article')).to be_empty
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
it 'clears the collection' do
|
|
428
|
+
expect(@articles).to be_empty
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
describe 'on a limited collection' do
|
|
433
|
+
before :all do
|
|
434
|
+
@other = @articles.create
|
|
435
|
+
@limited = @articles.all(:limit => 1)
|
|
436
|
+
|
|
437
|
+
@return = @limited.send(method)
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
it 'returns true' do
|
|
441
|
+
expect(@return).to be(true)
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
it 'removes the Resources from the datasource' do
|
|
445
|
+
expect(@article_model.all(title: 'Sample Article')).to eq [@other]
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
it 'clears the collection' do
|
|
449
|
+
expect(@limited).to be_empty
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
it 'does not destroy the other Resource' do
|
|
453
|
+
expect(@article_model.get!(*@other.key)).not_to be_nil
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
it { is_expected.to respond_to(:dirty?) }
|
|
460
|
+
|
|
461
|
+
describe '#dirty?' do
|
|
462
|
+
describe 'with all clean resources in the collection' do
|
|
463
|
+
it 'returns false' do
|
|
464
|
+
expect(@articles.dirty?).to be(false)
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
describe 'with a dirty resource in the collection' do
|
|
469
|
+
before :all do
|
|
470
|
+
@articles.each { |r| r.content = 'Changed' }
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
it 'returns true' do
|
|
474
|
+
expect(@articles.dirty?).to be(true)
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
it { is_expected.to respond_to(:insert) }
|
|
480
|
+
|
|
481
|
+
describe '#insert' do
|
|
482
|
+
before :all do
|
|
483
|
+
@resources = @other_articles
|
|
484
|
+
|
|
485
|
+
@return = @articles.insert(0, *@resources)
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
it 'returns a Collection' do
|
|
489
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
it 'returns self' do
|
|
493
|
+
expect(@return).to equal(@articles)
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
it 'inserts one or more Resources at a given offset' do
|
|
497
|
+
expect(@articles).to eq @resources << @article
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
it { is_expected.to respond_to(:inspect) }
|
|
502
|
+
|
|
503
|
+
describe '#inspect' do
|
|
504
|
+
before :all do
|
|
505
|
+
@copy = @articles.dup
|
|
506
|
+
@copy << @article_model.new(:title => 'Ignored Title', :content => 'Other Article')
|
|
507
|
+
|
|
508
|
+
@return = @copy.inspect
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
it { expect(@return).to match(/\A\[.*\]\z/) }
|
|
512
|
+
it { expect(@return).to match(/\bid=#{@article.id}\b/) }
|
|
513
|
+
it { expect(@return).to match(/\bid=nil\b/) }
|
|
514
|
+
it { expect(@return).to match(/\btitle="Sample Article"\s/) }
|
|
515
|
+
it { expect(@return).not_to match(/\btitle="Ignored Title"\s/) }
|
|
516
|
+
it { expect(@return).to match(/\bcontent="Other Article"\s/) }
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
%i(intersection &).each do |method|
|
|
520
|
+
it { is_expected.to respond_to(method) }
|
|
521
|
+
|
|
522
|
+
describe "##{method}" do
|
|
523
|
+
subject { @articles.send(method, @other_articles) }
|
|
524
|
+
|
|
525
|
+
describe 'with a Collection' do
|
|
526
|
+
it { is_expected.to be_kind_of(DataMapper::Collection) }
|
|
527
|
+
it { is_expected.to eq [] }
|
|
528
|
+
it { expect(subject.query).to eq @articles.query.intersection(@other_articles.query) }
|
|
529
|
+
it { is_expected.to eq @articles.to_a & @other_articles.to_a }
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
describe 'with an Array' do
|
|
533
|
+
before { @other_articles = @other_articles.to_ary }
|
|
534
|
+
|
|
535
|
+
it { is_expected.to be_kind_of(DataMapper::Collection) }
|
|
536
|
+
it { is_expected.to eq [] }
|
|
537
|
+
it { is_expected.to eq @articles.to_a & @other_articles.to_a }
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
describe 'with a Set' do
|
|
541
|
+
before { @other_articles = @other_articles.to_set }
|
|
542
|
+
|
|
543
|
+
it { is_expected.to be_kind_of(DataMapper::Collection) }
|
|
544
|
+
it { is_expected.to eq [] }
|
|
545
|
+
it { is_expected.to eq @articles.to_a & @other_articles.to_a }
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
it { is_expected.to respond_to(:new) }
|
|
551
|
+
|
|
552
|
+
describe '#new' do
|
|
553
|
+
describe 'when scoped to a property' do
|
|
554
|
+
before :all do
|
|
555
|
+
@source = @articles.new(:attachment => "A File")
|
|
556
|
+
@return = @resource = @articles.new(:original => @source)
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
it 'returns a Resource' do
|
|
560
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
it 'is a new Resource' do
|
|
564
|
+
expect(@resource).to be_new
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
it 'appends the Resource to the Collection' do
|
|
568
|
+
expect(@articles.last).to equal(@resource)
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
it 'uses the query conditions to set default values' do
|
|
572
|
+
expect(@resource.title).to eq 'Sample Article'
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
it 'uses the query conditions to set default values when accessed through a m:1 relationship' do
|
|
576
|
+
expect(@resource.original.attachment).to eq 'A File'
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
describe 'when scoped to the key' do
|
|
581
|
+
before :all do
|
|
582
|
+
@articles = @articles.all(:id => 1)
|
|
583
|
+
|
|
584
|
+
@return = @resource = @articles.new
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
it 'returns a Resource' do
|
|
588
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
it 'is a new Resource' do
|
|
592
|
+
expect(@resource).to be_new
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
it 'appends the Resource to the Collection' do
|
|
596
|
+
expect(@articles.last).to equal(@resource)
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
it 'does not use the query conditions to set default values' do
|
|
600
|
+
expect(@resource.id).to be_nil
|
|
601
|
+
end
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
describe 'when scoped to a property with multiple values' do
|
|
605
|
+
before :all do
|
|
606
|
+
@articles = @articles.all(:content => %w[ Sample Other ])
|
|
607
|
+
|
|
608
|
+
@return = @resource = @articles.new
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
it 'returns a Resource' do
|
|
612
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
it 'is a new Resource' do
|
|
616
|
+
expect(@resource).to be_new
|
|
617
|
+
end
|
|
618
|
+
|
|
619
|
+
it 'appends the Resource to the Collection' do
|
|
620
|
+
expect(@articles.last).to equal(@resource)
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
it 'does not use the query conditions to set default values' do
|
|
624
|
+
expect(@resource.content).to be_nil
|
|
625
|
+
end
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
describe 'when scoped with a condition other than eql' do
|
|
629
|
+
before :all do
|
|
630
|
+
@articles = @articles.all(:content.not => 'Sample')
|
|
631
|
+
|
|
632
|
+
@return = @resource = @articles.new
|
|
633
|
+
end
|
|
634
|
+
|
|
635
|
+
it 'returns a Resource' do
|
|
636
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
it 'is a new Resource' do
|
|
640
|
+
expect(@resource).to be_new
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
it 'appends the Resource to the Collection' do
|
|
644
|
+
expect(@articles.last).to equal(@resource)
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
it 'does not use the query conditions to set default values' do
|
|
648
|
+
expect(@resource.content).to be_nil
|
|
649
|
+
end
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
it { is_expected.to respond_to(:pop) }
|
|
654
|
+
|
|
655
|
+
describe '#pop' do
|
|
656
|
+
before :all do
|
|
657
|
+
@new = @articles.create(:title => 'Sample Article') # TODO: freeze @new
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
describe 'with no arguments' do
|
|
661
|
+
before :all do
|
|
662
|
+
@return = @articles.pop
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
it 'returns a Resource' do
|
|
666
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
667
|
+
end
|
|
668
|
+
|
|
669
|
+
it 'is the last Resource in the Collection' do
|
|
670
|
+
expect(@return).to eq @new
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
it 'removes the Resource from the Collection' do
|
|
674
|
+
expect(@articles).not_to include(@new)
|
|
675
|
+
end
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
if RUBY_VERSION >= '1.8.7'
|
|
679
|
+
describe 'with a limit specified' do
|
|
680
|
+
before :all do
|
|
681
|
+
@return = @articles.pop(1)
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
it 'returns an Array' do
|
|
685
|
+
expect(@return).to be_kind_of(Array)
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
it 'returns the expected Resources' do
|
|
689
|
+
expect(@return).to eq [@new]
|
|
690
|
+
end
|
|
691
|
+
|
|
692
|
+
it 'removes the Resource from the Collection' do
|
|
693
|
+
expect(@articles).not_to include(@new)
|
|
694
|
+
end
|
|
695
|
+
end
|
|
696
|
+
end
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
it { is_expected.to respond_to(:push) }
|
|
700
|
+
|
|
701
|
+
describe '#push' do
|
|
702
|
+
before :all do
|
|
703
|
+
@resources = [ @article_model.new(:title => 'Title 1'), @article_model.new(:title => 'Title 2') ]
|
|
704
|
+
|
|
705
|
+
@return = @articles.push(*@resources)
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
it 'returns a Collection' do
|
|
709
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
it 'returns self' do
|
|
713
|
+
expect(@return).to equal(@articles)
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
it 'appends the Resources to the Collection' do
|
|
717
|
+
expect(@articles).to eq [@article] + @resources
|
|
718
|
+
end
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
it { is_expected.to respond_to(:reject!) }
|
|
722
|
+
|
|
723
|
+
describe '#reject!' do
|
|
724
|
+
describe 'with a block that matches a Resource in the Collection' do
|
|
725
|
+
before :all do
|
|
726
|
+
@resources = @articles.dup.entries
|
|
727
|
+
|
|
728
|
+
@return = @articles.reject! { true }
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
it 'returns a Collection' do
|
|
732
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
it 'returns self' do
|
|
736
|
+
expect(@return).to equal(@articles)
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
it 'removes the Resources from the Collection' do
|
|
740
|
+
@resources.each { |resource| expect(@articles).not_to include(resource) }
|
|
741
|
+
end
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
describe 'with a block that does not match a Resource in the Collection' do
|
|
745
|
+
before :all do
|
|
746
|
+
@resources = @articles.dup.entries
|
|
747
|
+
|
|
748
|
+
@return = @articles.reject! { false }
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
it 'returns nil' do
|
|
752
|
+
expect(@return).to be_nil
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
it 'does not modify the Collection' do
|
|
756
|
+
expect(@articles).to eq @resources
|
|
757
|
+
end
|
|
758
|
+
end
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
it { is_expected.to respond_to(:reload) }
|
|
762
|
+
|
|
763
|
+
describe '#reload' do
|
|
764
|
+
describe 'with no arguments' do
|
|
765
|
+
before :all do
|
|
766
|
+
@resources = @articles.dup.entries
|
|
767
|
+
|
|
768
|
+
@return = @collection = @articles.reload
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
# FIXME: this is spec order dependent, move this into a helper method
|
|
772
|
+
# and execute in the before :all block
|
|
773
|
+
unless loaded
|
|
774
|
+
it 'does not be a kicker' do
|
|
775
|
+
pending do
|
|
776
|
+
expect(@articles).not_to be_loaded
|
|
777
|
+
end
|
|
778
|
+
end
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
it 'returns a Collection' do
|
|
782
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
it 'returns self' do
|
|
786
|
+
expect(@return).to equal(@articles)
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
{title: true, content: false}.each do |attribute, expected|
|
|
790
|
+
it "has query field #{attribute.inspect} #{'not' unless expected} loaded".squeeze(' ') do
|
|
791
|
+
@collection.each { |resource| expect(resource.attribute_loaded?(attribute)).to eq expected }
|
|
792
|
+
end
|
|
793
|
+
end
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
describe 'with a Hash query' do
|
|
797
|
+
before :all do
|
|
798
|
+
@resources = @articles.dup.entries
|
|
799
|
+
|
|
800
|
+
@return = @collection = @articles.reload(:fields => [ :content ]) # :title is a default field
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
# FIXME: this is spec order dependent, move this into a helper method
|
|
804
|
+
# and execute in the before :all block
|
|
805
|
+
unless loaded
|
|
806
|
+
it 'does not be a kicker' do
|
|
807
|
+
pending do
|
|
808
|
+
expect(@articles).not_to be_loaded
|
|
809
|
+
end
|
|
810
|
+
end
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
it 'returns a Collection' do
|
|
814
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
it 'returns self' do
|
|
818
|
+
expect(@return).to equal(@articles)
|
|
819
|
+
end
|
|
820
|
+
|
|
821
|
+
%i(id content title).each do |attribute|
|
|
822
|
+
it "has query field #{attribute.inspect} loaded" do
|
|
823
|
+
@collection.each { |resource| expect(resource.attribute_loaded?(attribute)).to be(true) }
|
|
824
|
+
end
|
|
825
|
+
end
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
describe 'with a Query' do
|
|
829
|
+
before :all do
|
|
830
|
+
@query = DataMapper::Query.new(@repository, @article_model, :fields => [ :content ]) # :title is an original field
|
|
831
|
+
|
|
832
|
+
@return = @collection = @articles.reload(@query)
|
|
833
|
+
end
|
|
834
|
+
|
|
835
|
+
# FIXME: this is spec order dependent, move this into a helper method
|
|
836
|
+
# and execute in the before :all block
|
|
837
|
+
unless loaded
|
|
838
|
+
it 'does not be a kicker' do
|
|
839
|
+
pending do
|
|
840
|
+
expect(@articles).not_to be_loaded
|
|
841
|
+
end
|
|
842
|
+
end
|
|
843
|
+
end
|
|
844
|
+
|
|
845
|
+
it 'returns a Collection' do
|
|
846
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
847
|
+
end
|
|
848
|
+
|
|
849
|
+
it 'returns self' do
|
|
850
|
+
expect(@return).to equal(@articles)
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
%i(id content title).each do |attribute|
|
|
854
|
+
it "has query field #{attribute.inspect} loaded" do
|
|
855
|
+
@collection.each { |resource| expect(resource.attribute_loaded?(attribute)).to be(true) }
|
|
856
|
+
end
|
|
857
|
+
end
|
|
858
|
+
end
|
|
859
|
+
end
|
|
860
|
+
|
|
861
|
+
it { is_expected.to respond_to(:replace) }
|
|
862
|
+
|
|
863
|
+
describe '#replace' do
|
|
864
|
+
describe 'when provided an Array of Resources' do
|
|
865
|
+
before :all do
|
|
866
|
+
@resources = @articles.dup.entries
|
|
867
|
+
|
|
868
|
+
@return = @articles.replace(@other_articles)
|
|
869
|
+
end
|
|
870
|
+
|
|
871
|
+
it 'returns a Collection' do
|
|
872
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
873
|
+
end
|
|
874
|
+
|
|
875
|
+
it 'returns self' do
|
|
876
|
+
expect(@return).to equal(@articles)
|
|
877
|
+
end
|
|
878
|
+
|
|
879
|
+
it 'updates the Collection with new Resources' do
|
|
880
|
+
expect(@articles).to eq @other_articles
|
|
881
|
+
end
|
|
882
|
+
end
|
|
883
|
+
|
|
884
|
+
describe 'when provided an Array of Hashes' do
|
|
885
|
+
before :all do
|
|
886
|
+
@array = [ { :content => 'From Hash' } ].freeze
|
|
887
|
+
|
|
888
|
+
@return = @articles.replace(@array)
|
|
889
|
+
end
|
|
890
|
+
|
|
891
|
+
it 'returns a Collection' do
|
|
892
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
893
|
+
end
|
|
894
|
+
|
|
895
|
+
it 'returns self' do
|
|
896
|
+
expect(@return).to equal(@articles)
|
|
897
|
+
end
|
|
898
|
+
|
|
899
|
+
it 'initializes a Resource' do
|
|
900
|
+
expect(@return.first).to be_kind_of(DataMapper::Resource)
|
|
901
|
+
end
|
|
902
|
+
|
|
903
|
+
it 'is a new Resource' do
|
|
904
|
+
expect(@return.first).to be_new
|
|
905
|
+
end
|
|
906
|
+
|
|
907
|
+
it 'is a Resource with attributes matching the Hash' do
|
|
908
|
+
expect(DataMapper::Ext::Hash.only(@return.first.attributes, *@array.first.keys)).to eq @array.first
|
|
909
|
+
end
|
|
910
|
+
end
|
|
911
|
+
end
|
|
912
|
+
|
|
913
|
+
it { is_expected.to respond_to(:reverse!) }
|
|
914
|
+
|
|
915
|
+
describe '#reverse!' do
|
|
916
|
+
before :all do
|
|
917
|
+
@query = @articles.query
|
|
918
|
+
|
|
919
|
+
@new = @articles.create(:title => 'Sample Article')
|
|
920
|
+
|
|
921
|
+
@return = @articles.reverse!
|
|
922
|
+
end
|
|
923
|
+
|
|
924
|
+
it 'returns a Collection' do
|
|
925
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
926
|
+
end
|
|
927
|
+
|
|
928
|
+
it 'returns self' do
|
|
929
|
+
expect(@return).to equal(@articles)
|
|
930
|
+
end
|
|
931
|
+
|
|
932
|
+
it 'returns a Collection with reversed entries' do
|
|
933
|
+
expect(@return).to eq [@new, @article]
|
|
934
|
+
end
|
|
935
|
+
|
|
936
|
+
it 'returns a Query that equal to the original' do
|
|
937
|
+
expect(@return.query).to equal(@query)
|
|
938
|
+
end
|
|
939
|
+
end
|
|
940
|
+
|
|
941
|
+
%i(save save!).each do |method|
|
|
942
|
+
it { is_expected.to respond_to(method) }
|
|
943
|
+
|
|
944
|
+
describe "##{method}" do
|
|
945
|
+
describe 'when Resources are not saved' do
|
|
946
|
+
before :all do
|
|
947
|
+
@articles.new(:title => 'New Article', :content => 'New Article')
|
|
948
|
+
|
|
949
|
+
@return = @articles.send(method)
|
|
950
|
+
end
|
|
951
|
+
|
|
952
|
+
it 'returns true' do
|
|
953
|
+
expect(@return).to be(true)
|
|
954
|
+
end
|
|
955
|
+
|
|
956
|
+
it 'saves each Resource' do
|
|
957
|
+
@articles.each { |resource| expect(resource).to be_saved }
|
|
958
|
+
end
|
|
959
|
+
end
|
|
960
|
+
|
|
961
|
+
describe 'when Resources have been orphaned' do
|
|
962
|
+
before :all do
|
|
963
|
+
@resources = @articles.entries
|
|
964
|
+
@articles.replace([])
|
|
965
|
+
|
|
966
|
+
@return = @articles.send(method)
|
|
967
|
+
end
|
|
968
|
+
|
|
969
|
+
it 'returns true' do
|
|
970
|
+
expect(@return).to be(true)
|
|
971
|
+
end
|
|
972
|
+
end
|
|
973
|
+
end
|
|
974
|
+
end
|
|
975
|
+
|
|
976
|
+
it { is_expected.to respond_to(:shift) }
|
|
977
|
+
|
|
978
|
+
describe '#shift' do
|
|
979
|
+
describe 'with no arguments' do
|
|
980
|
+
before :all do
|
|
981
|
+
@return = @articles.shift
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
it 'returns a Resource' do
|
|
985
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
986
|
+
end
|
|
987
|
+
|
|
988
|
+
it 'is the first Resource in the Collection' do
|
|
989
|
+
expect(@return.key).to eq @article.key
|
|
990
|
+
end
|
|
991
|
+
|
|
992
|
+
it 'removes the Resource from the Collection' do
|
|
993
|
+
expect(@articles).not_to include(@return)
|
|
994
|
+
end
|
|
995
|
+
end
|
|
996
|
+
|
|
997
|
+
if RUBY_VERSION >= '1.8.7'
|
|
998
|
+
describe 'with a limit specified' do
|
|
999
|
+
before :all do
|
|
1000
|
+
@return = @articles.shift(1)
|
|
1001
|
+
end
|
|
1002
|
+
|
|
1003
|
+
it 'returns an Array' do
|
|
1004
|
+
expect(@return).to be_kind_of(Array)
|
|
1005
|
+
end
|
|
1006
|
+
|
|
1007
|
+
it 'returns the expected Resources' do
|
|
1008
|
+
expect(@return.size).to eq 1
|
|
1009
|
+
expect(@return.first.key).to eq @article.key
|
|
1010
|
+
end
|
|
1011
|
+
|
|
1012
|
+
it 'removes the Resource from the Collection' do
|
|
1013
|
+
expect(@articles).not_to include(@article)
|
|
1014
|
+
end
|
|
1015
|
+
end
|
|
1016
|
+
end
|
|
1017
|
+
end
|
|
1018
|
+
|
|
1019
|
+
it { is_expected.to respond_to(:slice!) }
|
|
1020
|
+
|
|
1021
|
+
describe '#slice!' do
|
|
1022
|
+
before :all do
|
|
1023
|
+
1.upto(10) { |number| @articles.create(:content => "Article #{number}") }
|
|
1024
|
+
|
|
1025
|
+
@copy = @articles.dup
|
|
1026
|
+
end
|
|
1027
|
+
|
|
1028
|
+
describe 'with a positive offset' do
|
|
1029
|
+
before :all do
|
|
1030
|
+
unless @skip
|
|
1031
|
+
@return = @resource = @articles.slice!(0)
|
|
1032
|
+
end
|
|
1033
|
+
end
|
|
1034
|
+
|
|
1035
|
+
it 'returns a Resource' do
|
|
1036
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
1037
|
+
end
|
|
1038
|
+
|
|
1039
|
+
it 'returns expected Resource' do
|
|
1040
|
+
expect(@return.key).to eq @article.key
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
it 'returns the same as Array#slice!' do
|
|
1044
|
+
expect(@return).to eq @copy.entries.slice!(0)
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
it 'removes the Resource from the Collection' do
|
|
1048
|
+
expect(@articles).not_to include(@resource)
|
|
1049
|
+
end
|
|
1050
|
+
end
|
|
1051
|
+
|
|
1052
|
+
describe 'with a positive offset and length' do
|
|
1053
|
+
before :all do
|
|
1054
|
+
unless @skip
|
|
1055
|
+
@return = @resources = @articles.slice!(5, 5)
|
|
1056
|
+
end
|
|
1057
|
+
end
|
|
1058
|
+
|
|
1059
|
+
it 'returns a Collection' do
|
|
1060
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
1061
|
+
end
|
|
1062
|
+
|
|
1063
|
+
it 'returns the expected Resource' do
|
|
1064
|
+
expect(@return).to eq @copy.entries.slice!(5, 5)
|
|
1065
|
+
end
|
|
1066
|
+
|
|
1067
|
+
it 'removes the Resources from the Collection' do
|
|
1068
|
+
@resources.each { |resource| expect(@articles).not_to include(resource) }
|
|
1069
|
+
end
|
|
1070
|
+
|
|
1071
|
+
it 'scopes the Collection' do
|
|
1072
|
+
expect(@resources.reload).to eq @copy.entries.slice!(5, 5)
|
|
1073
|
+
end
|
|
1074
|
+
end
|
|
1075
|
+
|
|
1076
|
+
describe 'with a positive range' do
|
|
1077
|
+
before :all do
|
|
1078
|
+
unless @skip
|
|
1079
|
+
@return = @resources = @articles.slice!(5..10)
|
|
1080
|
+
end
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
it 'returns a Collection' do
|
|
1084
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
1085
|
+
end
|
|
1086
|
+
|
|
1087
|
+
it 'returns the expected Resources' do
|
|
1088
|
+
expect(@return).to eq @copy.entries.slice!(5..10)
|
|
1089
|
+
end
|
|
1090
|
+
|
|
1091
|
+
it 'removes the Resources from the Collection' do
|
|
1092
|
+
@resources.each { |resource| expect(@articles).not_to include(resource) }
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
it 'scopes the Collection' do
|
|
1096
|
+
expect(@resources.reload).to eq @copy.entries.slice!(5..10)
|
|
1097
|
+
end
|
|
1098
|
+
end
|
|
1099
|
+
|
|
1100
|
+
describe 'with a negative offset' do
|
|
1101
|
+
before :all do
|
|
1102
|
+
unless @skip
|
|
1103
|
+
@return = @resource = @articles.slice!(-1)
|
|
1104
|
+
end
|
|
1105
|
+
end
|
|
1106
|
+
|
|
1107
|
+
it 'returns a Resource' do
|
|
1108
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
1109
|
+
end
|
|
1110
|
+
|
|
1111
|
+
it 'returns expected Resource' do
|
|
1112
|
+
expect(@return).to eq @copy.entries.slice!(-1)
|
|
1113
|
+
end
|
|
1114
|
+
|
|
1115
|
+
it 'removes the Resource from the Collection' do
|
|
1116
|
+
expect(@articles).not_to include(@resource)
|
|
1117
|
+
end
|
|
1118
|
+
end
|
|
1119
|
+
|
|
1120
|
+
describe 'with a negative offset and length' do
|
|
1121
|
+
before :all do
|
|
1122
|
+
unless @skip
|
|
1123
|
+
@return = @resources = @articles.slice!(-5, 5)
|
|
1124
|
+
end
|
|
1125
|
+
end
|
|
1126
|
+
|
|
1127
|
+
it 'returns a Collection' do
|
|
1128
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
1129
|
+
end
|
|
1130
|
+
|
|
1131
|
+
it 'returns the expected Resources' do
|
|
1132
|
+
expect(@return).to eq @copy.entries.slice!(-5, 5)
|
|
1133
|
+
end
|
|
1134
|
+
|
|
1135
|
+
it 'removes the Resources from the Collection' do
|
|
1136
|
+
@resources.each { |resource| expect(@articles).not_to include(resource) }
|
|
1137
|
+
end
|
|
1138
|
+
|
|
1139
|
+
it 'scopes the Collection' do
|
|
1140
|
+
expect(@resources.reload).to eq @copy.entries.slice!(-5, 5)
|
|
1141
|
+
end
|
|
1142
|
+
end
|
|
1143
|
+
|
|
1144
|
+
describe 'with a negative range' do
|
|
1145
|
+
before :all do
|
|
1146
|
+
unless @skip
|
|
1147
|
+
@return = @resources = @articles.slice!(-3..-2)
|
|
1148
|
+
end
|
|
1149
|
+
end
|
|
1150
|
+
|
|
1151
|
+
it 'returns a Collection' do
|
|
1152
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
1153
|
+
end
|
|
1154
|
+
|
|
1155
|
+
it 'returns the expected Resources' do
|
|
1156
|
+
expect(@return).to eq @copy.entries.slice!(-3..-2)
|
|
1157
|
+
end
|
|
1158
|
+
|
|
1159
|
+
it 'removes the Resources from the Collection' do
|
|
1160
|
+
@resources.each { |resource| expect(@articles).not_to include(resource) }
|
|
1161
|
+
end
|
|
1162
|
+
|
|
1163
|
+
it 'scopes the Collection' do
|
|
1164
|
+
expect(@resources.reload).to eq @copy.entries.slice!(-3..-2)
|
|
1165
|
+
end
|
|
1166
|
+
end
|
|
1167
|
+
|
|
1168
|
+
describe 'with an offset not within the Collection' do
|
|
1169
|
+
before :all do
|
|
1170
|
+
unless @skip
|
|
1171
|
+
@return = @articles.slice!(12)
|
|
1172
|
+
end
|
|
1173
|
+
end
|
|
1174
|
+
|
|
1175
|
+
it 'returns nil' do
|
|
1176
|
+
expect(@return).to be_nil
|
|
1177
|
+
end
|
|
1178
|
+
end
|
|
1179
|
+
|
|
1180
|
+
describe 'with an offset and length not within the Collection' do
|
|
1181
|
+
before :all do
|
|
1182
|
+
unless @skip
|
|
1183
|
+
@return = @articles.slice!(12, 1)
|
|
1184
|
+
end
|
|
1185
|
+
end
|
|
1186
|
+
|
|
1187
|
+
it 'returns nil' do
|
|
1188
|
+
expect(@return).to be_nil
|
|
1189
|
+
end
|
|
1190
|
+
end
|
|
1191
|
+
|
|
1192
|
+
describe 'with a range not within the Collection' do
|
|
1193
|
+
before :all do
|
|
1194
|
+
unless @skip
|
|
1195
|
+
@return = @articles.slice!(12..13)
|
|
1196
|
+
end
|
|
1197
|
+
end
|
|
1198
|
+
|
|
1199
|
+
it 'returns nil' do
|
|
1200
|
+
expect(@return).to be_nil
|
|
1201
|
+
end
|
|
1202
|
+
end
|
|
1203
|
+
end
|
|
1204
|
+
|
|
1205
|
+
it { is_expected.to respond_to(:sort!) }
|
|
1206
|
+
|
|
1207
|
+
describe '#sort!' do
|
|
1208
|
+
describe 'without a block' do
|
|
1209
|
+
before :all do
|
|
1210
|
+
@return = @articles.unshift(@other).sort!
|
|
1211
|
+
end
|
|
1212
|
+
|
|
1213
|
+
it 'returns a Collection' do
|
|
1214
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
1215
|
+
end
|
|
1216
|
+
|
|
1217
|
+
it 'returns self' do
|
|
1218
|
+
expect(@return).to equal(@articles)
|
|
1219
|
+
end
|
|
1220
|
+
|
|
1221
|
+
it 'modifies and sorts the Collection using default sort order' do
|
|
1222
|
+
expect(@articles).to eq [@article, @other]
|
|
1223
|
+
end
|
|
1224
|
+
end
|
|
1225
|
+
|
|
1226
|
+
describe 'with a block' do
|
|
1227
|
+
before :all do
|
|
1228
|
+
@return = @articles.unshift(@other).sort! { |a_resource, b_resource| b_resource.id <=> a_resource.id }
|
|
1229
|
+
end
|
|
1230
|
+
|
|
1231
|
+
it 'returns a Collection' do
|
|
1232
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
1233
|
+
end
|
|
1234
|
+
|
|
1235
|
+
it 'returns self' do
|
|
1236
|
+
expect(@return).to equal(@articles)
|
|
1237
|
+
end
|
|
1238
|
+
|
|
1239
|
+
it 'modifies and sorts the Collection using supplied block' do
|
|
1240
|
+
expect(@articles).to eq [@other, @article]
|
|
1241
|
+
end
|
|
1242
|
+
end
|
|
1243
|
+
end
|
|
1244
|
+
|
|
1245
|
+
%i(splice []=).each do |method|
|
|
1246
|
+
it { is_expected.to respond_to(method) }
|
|
1247
|
+
|
|
1248
|
+
describe "##{method}" do
|
|
1249
|
+
before :all do
|
|
1250
|
+
unless @skip
|
|
1251
|
+
orphans = (1..10).map do |number|
|
|
1252
|
+
articles = @articles.dup
|
|
1253
|
+
articles.create(:content => "Article #{number}")
|
|
1254
|
+
articles.pop # remove the article from the tail
|
|
1255
|
+
end
|
|
1256
|
+
|
|
1257
|
+
@articles.unshift(*orphans.first(5))
|
|
1258
|
+
@articles.concat(orphans.last(5))
|
|
1259
|
+
|
|
1260
|
+
expect(@articles).not_to be_loaded unless loaded
|
|
1261
|
+
|
|
1262
|
+
@copy = @articles.dup
|
|
1263
|
+
@new = @article_model.new(:content => 'New Article')
|
|
1264
|
+
end
|
|
1265
|
+
end
|
|
1266
|
+
|
|
1267
|
+
describe 'with a positive offset and a Resource' do
|
|
1268
|
+
before :all do
|
|
1269
|
+
rescue_if @skip do
|
|
1270
|
+
@original = @copy[1]
|
|
1271
|
+
|
|
1272
|
+
@return = @resource = @articles.send(method, 1, @new)
|
|
1273
|
+
end
|
|
1274
|
+
end
|
|
1275
|
+
|
|
1276
|
+
should_not_be_a_kicker
|
|
1277
|
+
|
|
1278
|
+
it 'returns a Resource' do
|
|
1279
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
1280
|
+
end
|
|
1281
|
+
|
|
1282
|
+
it 'returns expected Resource' do
|
|
1283
|
+
expect(@return).to equal(@new)
|
|
1284
|
+
end
|
|
1285
|
+
|
|
1286
|
+
it 'returns the same as Array#[]=' do
|
|
1287
|
+
expect(@return).to eq @copy.entries[1] = @new
|
|
1288
|
+
end
|
|
1289
|
+
|
|
1290
|
+
it 'includes the Resource in the Collection' do
|
|
1291
|
+
expect(@articles).to include(@resource)
|
|
1292
|
+
end
|
|
1293
|
+
end
|
|
1294
|
+
|
|
1295
|
+
describe 'with a positive offset and length and a Resource' do
|
|
1296
|
+
before :all do
|
|
1297
|
+
rescue_if @skip do
|
|
1298
|
+
@original = @copy[2]
|
|
1299
|
+
|
|
1300
|
+
@return = @resource = @articles.send(method, 2, 1, @new)
|
|
1301
|
+
end
|
|
1302
|
+
end
|
|
1303
|
+
|
|
1304
|
+
should_not_be_a_kicker
|
|
1305
|
+
|
|
1306
|
+
it 'returns a Resource' do
|
|
1307
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
1308
|
+
end
|
|
1309
|
+
|
|
1310
|
+
it 'returns the expected Resource' do
|
|
1311
|
+
expect(@return).to equal(@new)
|
|
1312
|
+
end
|
|
1313
|
+
|
|
1314
|
+
it 'returns the same as Array#[]=' do
|
|
1315
|
+
expect(@return).to eq @copy.entries[2, 1] = @new
|
|
1316
|
+
end
|
|
1317
|
+
|
|
1318
|
+
it 'includes the Resource in the Collection' do
|
|
1319
|
+
expect(@articles).to include(@resource)
|
|
1320
|
+
end
|
|
1321
|
+
end
|
|
1322
|
+
|
|
1323
|
+
describe 'with a positive range and a Resource' do
|
|
1324
|
+
before :all do
|
|
1325
|
+
rescue_if @skip do
|
|
1326
|
+
@originals = @copy.values_at(2..3)
|
|
1327
|
+
|
|
1328
|
+
@return = @resource = @articles.send(method, 2..3, @new)
|
|
1329
|
+
end
|
|
1330
|
+
end
|
|
1331
|
+
|
|
1332
|
+
should_not_be_a_kicker
|
|
1333
|
+
|
|
1334
|
+
it 'returns a Resource' do
|
|
1335
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
1336
|
+
end
|
|
1337
|
+
|
|
1338
|
+
it 'returns the expected Resources' do
|
|
1339
|
+
expect(@return).to equal(@new)
|
|
1340
|
+
end
|
|
1341
|
+
|
|
1342
|
+
it 'returns the same as Array#[]=' do
|
|
1343
|
+
expect(@return).to eq @copy.entries[2..3] = @new
|
|
1344
|
+
end
|
|
1345
|
+
|
|
1346
|
+
it 'includes the Resource in the Collection' do
|
|
1347
|
+
expect(@articles).to include(@resource)
|
|
1348
|
+
end
|
|
1349
|
+
end
|
|
1350
|
+
|
|
1351
|
+
describe 'with a negative offset and a Resource' do
|
|
1352
|
+
before :all do
|
|
1353
|
+
rescue_if @skip do
|
|
1354
|
+
@original = @copy[-1]
|
|
1355
|
+
|
|
1356
|
+
@return = @resource = @articles.send(method, -1, @new)
|
|
1357
|
+
end
|
|
1358
|
+
end
|
|
1359
|
+
|
|
1360
|
+
should_not_be_a_kicker
|
|
1361
|
+
|
|
1362
|
+
it 'returns a Resource' do
|
|
1363
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
1364
|
+
end
|
|
1365
|
+
|
|
1366
|
+
it 'returns expected Resource' do
|
|
1367
|
+
expect(@return).to equal(@new)
|
|
1368
|
+
end
|
|
1369
|
+
|
|
1370
|
+
it 'returns the same as Array#[]=' do
|
|
1371
|
+
expect(@return).to eq @copy.entries[-1] = @new
|
|
1372
|
+
end
|
|
1373
|
+
|
|
1374
|
+
it 'includes the Resource in the Collection' do
|
|
1375
|
+
expect(@articles).to include(@resource)
|
|
1376
|
+
end
|
|
1377
|
+
end
|
|
1378
|
+
|
|
1379
|
+
describe 'with a negative offset and length and a Resource' do
|
|
1380
|
+
before :all do
|
|
1381
|
+
rescue_if @skip do
|
|
1382
|
+
@original = @copy[-2]
|
|
1383
|
+
@return = @resource = @articles.send(method, -2, 1, @new)
|
|
1384
|
+
end
|
|
1385
|
+
end
|
|
1386
|
+
|
|
1387
|
+
should_not_be_a_kicker
|
|
1388
|
+
|
|
1389
|
+
it 'returns a Resource' do
|
|
1390
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
1391
|
+
end
|
|
1392
|
+
|
|
1393
|
+
it 'returns the expected Resource' do
|
|
1394
|
+
expect(@return).to equal(@new)
|
|
1395
|
+
end
|
|
1396
|
+
|
|
1397
|
+
it 'returns the same as Array#[]=' do
|
|
1398
|
+
expect(@return).to eq @copy.entries[-2, 1] = @new
|
|
1399
|
+
end
|
|
1400
|
+
|
|
1401
|
+
it 'includes the Resource in the Collection' do
|
|
1402
|
+
expect(@articles).to include(@resource)
|
|
1403
|
+
end
|
|
1404
|
+
end
|
|
1405
|
+
|
|
1406
|
+
describe 'with a negative range and a Resource' do
|
|
1407
|
+
before :all do
|
|
1408
|
+
rescue_if @skip do
|
|
1409
|
+
@originals = @articles.values_at(-3..-2)
|
|
1410
|
+
@return = @resource = @articles.send(method, -3..-2, @new)
|
|
1411
|
+
end
|
|
1412
|
+
end
|
|
1413
|
+
|
|
1414
|
+
should_not_be_a_kicker
|
|
1415
|
+
|
|
1416
|
+
it 'returns a Resource' do
|
|
1417
|
+
expect(@return).to be_kind_of(DataMapper::Resource)
|
|
1418
|
+
end
|
|
1419
|
+
|
|
1420
|
+
it 'returns the expected Resources' do
|
|
1421
|
+
expect(@return).to equal(@new)
|
|
1422
|
+
end
|
|
1423
|
+
|
|
1424
|
+
it 'returns the same as Array#[]=' do
|
|
1425
|
+
expect(@return).to eq @copy.entries[-3..-2] = @new
|
|
1426
|
+
end
|
|
1427
|
+
|
|
1428
|
+
it 'includes the Resource in the Collection' do
|
|
1429
|
+
expect(@articles).to include(@resource)
|
|
1430
|
+
end
|
|
1431
|
+
end
|
|
1432
|
+
end
|
|
1433
|
+
end
|
|
1434
|
+
|
|
1435
|
+
describe '#[]=' do
|
|
1436
|
+
describe 'when swapping resources' do
|
|
1437
|
+
before :all do
|
|
1438
|
+
rescue_if @skip do
|
|
1439
|
+
@articles.create(:content => 'Another Article')
|
|
1440
|
+
|
|
1441
|
+
@entries = @articles.entries
|
|
1442
|
+
|
|
1443
|
+
@articles[0], @articles[1] = @articles[1], @articles[0]
|
|
1444
|
+
end
|
|
1445
|
+
end
|
|
1446
|
+
|
|
1447
|
+
it 'includes the Resource in the Collection' do
|
|
1448
|
+
expect(@articles).to eq @entries.reverse
|
|
1449
|
+
end
|
|
1450
|
+
end
|
|
1451
|
+
end
|
|
1452
|
+
|
|
1453
|
+
%i(union | +).each do |method|
|
|
1454
|
+
it { is_expected.to respond_to(method) }
|
|
1455
|
+
|
|
1456
|
+
describe "##{method}" do
|
|
1457
|
+
subject { @articles.send(method, @other_articles) }
|
|
1458
|
+
|
|
1459
|
+
describe 'with a Collection' do
|
|
1460
|
+
it { is_expected.to be_kind_of(DataMapper::Collection) }
|
|
1461
|
+
it { is_expected.to eq [@article, @other] }
|
|
1462
|
+
it { expect(subject.query).to eq @articles.query.union(@other_articles.query) }
|
|
1463
|
+
it { is_expected.to eq @articles.to_a | @other_articles.to_a }
|
|
1464
|
+
end
|
|
1465
|
+
|
|
1466
|
+
describe 'with an Array' do
|
|
1467
|
+
before { @other_articles = @other_articles.to_ary }
|
|
1468
|
+
|
|
1469
|
+
it { is_expected.to be_kind_of(DataMapper::Collection) }
|
|
1470
|
+
it { is_expected.to eq [@article, @other] }
|
|
1471
|
+
it { is_expected.to eq @articles.to_a | @other_articles.to_a }
|
|
1472
|
+
end
|
|
1473
|
+
|
|
1474
|
+
describe 'with a Set' do
|
|
1475
|
+
before { @other_articles = @other_articles.to_set }
|
|
1476
|
+
|
|
1477
|
+
it { is_expected.to be_kind_of(DataMapper::Collection) }
|
|
1478
|
+
it { is_expected.to eq [@article, @other] }
|
|
1479
|
+
it { is_expected.to eq @articles.to_a | @other_articles.to_a }
|
|
1480
|
+
end
|
|
1481
|
+
end
|
|
1482
|
+
end
|
|
1483
|
+
|
|
1484
|
+
it { is_expected.to respond_to(:unshift) }
|
|
1485
|
+
|
|
1486
|
+
describe '#unshift' do
|
|
1487
|
+
before :all do
|
|
1488
|
+
@resources = [ @article_model.new(:title => 'Title 1'), @article_model.new(:title => 'Title 2') ]
|
|
1489
|
+
|
|
1490
|
+
@return = @articles.unshift(*@resources)
|
|
1491
|
+
end
|
|
1492
|
+
|
|
1493
|
+
it 'returns a Collection' do
|
|
1494
|
+
expect(@return).to be_kind_of(DataMapper::Collection)
|
|
1495
|
+
end
|
|
1496
|
+
|
|
1497
|
+
it 'returns self' do
|
|
1498
|
+
expect(@return).to equal(@articles)
|
|
1499
|
+
end
|
|
1500
|
+
|
|
1501
|
+
it 'prepends the Resources to the Collection' do
|
|
1502
|
+
expect(@articles).to eq @resources + [@article]
|
|
1503
|
+
end
|
|
1504
|
+
end
|
|
1505
|
+
|
|
1506
|
+
%i(update update!).each do |method|
|
|
1507
|
+
it { is_expected.to respond_to(method) }
|
|
1508
|
+
|
|
1509
|
+
describe "##{method}" do
|
|
1510
|
+
describe 'with attributes' do
|
|
1511
|
+
before :all do
|
|
1512
|
+
@attributes = { :title => 'Updated Title' }
|
|
1513
|
+
|
|
1514
|
+
@return = @articles.send(method, @attributes)
|
|
1515
|
+
end
|
|
1516
|
+
|
|
1517
|
+
should_not_be_a_kicker if method == :update!
|
|
1518
|
+
|
|
1519
|
+
it 'returns true' do
|
|
1520
|
+
expect(@return).to be(true)
|
|
1521
|
+
end
|
|
1522
|
+
|
|
1523
|
+
it 'updates attributes of all Resources' do
|
|
1524
|
+
@articles.each { |resource| @attributes.each { |key, value| expect(resource.__send__(key)).to eq value } }
|
|
1525
|
+
end
|
|
1526
|
+
|
|
1527
|
+
it 'persists the changes' do
|
|
1528
|
+
resource = @article_model.get!(*@article.key)
|
|
1529
|
+
@attributes.each { |key, value| expect(resource.__send__(key)).to eq value }
|
|
1530
|
+
end
|
|
1531
|
+
end
|
|
1532
|
+
|
|
1533
|
+
describe 'with attributes where one is a parent association' do
|
|
1534
|
+
before :all do
|
|
1535
|
+
@attributes = { :original => @other }
|
|
1536
|
+
|
|
1537
|
+
@return = @articles.send(method, @attributes)
|
|
1538
|
+
end
|
|
1539
|
+
|
|
1540
|
+
if method == :update!
|
|
1541
|
+
should_not_be_a_kicker
|
|
1542
|
+
end
|
|
1543
|
+
|
|
1544
|
+
it 'returns true' do
|
|
1545
|
+
expect(@return).to be(true)
|
|
1546
|
+
end
|
|
1547
|
+
|
|
1548
|
+
it 'updates attributes of all Resources' do
|
|
1549
|
+
@articles.each { |resource| @attributes.each { |key, value| expect(resource.__send__(key)).to eq value } }
|
|
1550
|
+
end
|
|
1551
|
+
|
|
1552
|
+
it 'persists the changes' do
|
|
1553
|
+
resource = @article_model.get!(*@article.key)
|
|
1554
|
+
@attributes.each { |key, value| expect(resource.__send__(key)).to eq value }
|
|
1555
|
+
end
|
|
1556
|
+
end
|
|
1557
|
+
|
|
1558
|
+
describe 'with attributes where a required property is nil' do
|
|
1559
|
+
before :all do
|
|
1560
|
+
expect { @articles.send(method, title: nil) }.to(raise_error(DataMapper::Property::InvalidValueError) do |error|
|
|
1561
|
+
expect(error.property).to eq @articles.model.title
|
|
1562
|
+
end)
|
|
1563
|
+
end
|
|
1564
|
+
|
|
1565
|
+
if method == :update!
|
|
1566
|
+
should_not_be_a_kicker
|
|
1567
|
+
end
|
|
1568
|
+
end
|
|
1569
|
+
|
|
1570
|
+
describe 'on a limited collection' do
|
|
1571
|
+
before :all do
|
|
1572
|
+
@other = @articles.create
|
|
1573
|
+
@limited = @articles.all(:limit => 1)
|
|
1574
|
+
@attributes = { :content => 'Updated Content' }
|
|
1575
|
+
|
|
1576
|
+
@return = @limited.send(method, @attributes)
|
|
1577
|
+
end
|
|
1578
|
+
|
|
1579
|
+
if method == :update!
|
|
1580
|
+
should_not_be_a_kicker(:@limited)
|
|
1581
|
+
end
|
|
1582
|
+
|
|
1583
|
+
it 'returns true' do
|
|
1584
|
+
expect(@return).to be(true)
|
|
1585
|
+
end
|
|
1586
|
+
|
|
1587
|
+
it 'bypasses validation' do
|
|
1588
|
+
pending 'TODO: not sure how to best spec this'
|
|
1589
|
+
end
|
|
1590
|
+
|
|
1591
|
+
it 'updates attributes of all Resources' do
|
|
1592
|
+
@limited.each { |resource| @attributes.each { |key, value| expect(resource.__send__(key)).to eq value } }
|
|
1593
|
+
end
|
|
1594
|
+
|
|
1595
|
+
it 'persists the changes' do
|
|
1596
|
+
resource = @article_model.get!(*@article.key)
|
|
1597
|
+
@attributes.each { |key, value| expect(resource.__send__(key)).to eq value }
|
|
1598
|
+
end
|
|
1599
|
+
|
|
1600
|
+
it 'does not update the other Resource' do
|
|
1601
|
+
@other.reload
|
|
1602
|
+
@attributes.each { |key, value| expect(@other.__send__(key)).not_to eq value }
|
|
1603
|
+
end
|
|
1604
|
+
end
|
|
1605
|
+
|
|
1606
|
+
describe 'on a dirty collection' do
|
|
1607
|
+
before :all do
|
|
1608
|
+
@articles.each { |r| r.content = 'Changed' }
|
|
1609
|
+
end
|
|
1610
|
+
|
|
1611
|
+
it 'raises an exception' do
|
|
1612
|
+
expect {
|
|
1613
|
+
@articles.send(method, :content => 'New Content')
|
|
1614
|
+
}.to raise_error(DataMapper::UpdateConflictError, "#{@articles.class}##{method} cannot be called on a dirty collection")
|
|
1615
|
+
end
|
|
1616
|
+
end
|
|
1617
|
+
end
|
|
1618
|
+
end
|
|
1619
|
+
|
|
1620
|
+
it 'responds to a public model method with #method_missing' do
|
|
1621
|
+
expect(@articles).to respond_to(:base_model)
|
|
1622
|
+
end
|
|
1623
|
+
|
|
1624
|
+
describe '#method_missing' do
|
|
1625
|
+
describe 'with a public model method' do
|
|
1626
|
+
before :all do
|
|
1627
|
+
@return = @articles.model.base_model
|
|
1628
|
+
end
|
|
1629
|
+
|
|
1630
|
+
should_not_be_a_kicker
|
|
1631
|
+
|
|
1632
|
+
it 'returns expected object' do
|
|
1633
|
+
expect(@return).to eq @article_model
|
|
1634
|
+
end
|
|
1635
|
+
end
|
|
1636
|
+
end
|
|
1637
|
+
end
|