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