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.
Files changed (254) hide show
  1. data/.autotest +29 -0
  2. data/.document +5 -0
  3. data/.gitignore +35 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +65 -0
  6. data/LICENSE +20 -0
  7. data/README.md +269 -0
  8. data/Rakefile +4 -0
  9. data/dm-core.gemspec +24 -0
  10. data/lib/dm-core.rb +292 -0
  11. data/lib/dm-core/adapters.rb +222 -0
  12. data/lib/dm-core/adapters/abstract_adapter.rb +237 -0
  13. data/lib/dm-core/adapters/in_memory_adapter.rb +113 -0
  14. data/lib/dm-core/associations/many_to_many.rb +499 -0
  15. data/lib/dm-core/associations/many_to_one.rb +290 -0
  16. data/lib/dm-core/associations/one_to_many.rb +348 -0
  17. data/lib/dm-core/associations/one_to_one.rb +86 -0
  18. data/lib/dm-core/associations/relationship.rb +663 -0
  19. data/lib/dm-core/backwards.rb +13 -0
  20. data/lib/dm-core/collection.rb +1515 -0
  21. data/lib/dm-core/core_ext/kernel.rb +23 -0
  22. data/lib/dm-core/core_ext/pathname.rb +6 -0
  23. data/lib/dm-core/core_ext/symbol.rb +10 -0
  24. data/lib/dm-core/identity_map.rb +7 -0
  25. data/lib/dm-core/model.rb +874 -0
  26. data/lib/dm-core/model/hook.rb +103 -0
  27. data/lib/dm-core/model/is.rb +32 -0
  28. data/lib/dm-core/model/property.rb +249 -0
  29. data/lib/dm-core/model/relationship.rb +378 -0
  30. data/lib/dm-core/model/scope.rb +89 -0
  31. data/lib/dm-core/property.rb +866 -0
  32. data/lib/dm-core/property/binary.rb +21 -0
  33. data/lib/dm-core/property/boolean.rb +20 -0
  34. data/lib/dm-core/property/class.rb +17 -0
  35. data/lib/dm-core/property/date.rb +10 -0
  36. data/lib/dm-core/property/date_time.rb +10 -0
  37. data/lib/dm-core/property/decimal.rb +36 -0
  38. data/lib/dm-core/property/discriminator.rb +44 -0
  39. data/lib/dm-core/property/float.rb +16 -0
  40. data/lib/dm-core/property/integer.rb +22 -0
  41. data/lib/dm-core/property/invalid_value_error.rb +22 -0
  42. data/lib/dm-core/property/lookup.rb +27 -0
  43. data/lib/dm-core/property/numeric.rb +38 -0
  44. data/lib/dm-core/property/object.rb +34 -0
  45. data/lib/dm-core/property/serial.rb +14 -0
  46. data/lib/dm-core/property/string.rb +38 -0
  47. data/lib/dm-core/property/text.rb +9 -0
  48. data/lib/dm-core/property/time.rb +10 -0
  49. data/lib/dm-core/property_set.rb +177 -0
  50. data/lib/dm-core/query.rb +1366 -0
  51. data/lib/dm-core/query/conditions/comparison.rb +911 -0
  52. data/lib/dm-core/query/conditions/operation.rb +721 -0
  53. data/lib/dm-core/query/direction.rb +36 -0
  54. data/lib/dm-core/query/operator.rb +35 -0
  55. data/lib/dm-core/query/path.rb +114 -0
  56. data/lib/dm-core/query/sort.rb +39 -0
  57. data/lib/dm-core/relationship_set.rb +72 -0
  58. data/lib/dm-core/repository.rb +226 -0
  59. data/lib/dm-core/resource.rb +1214 -0
  60. data/lib/dm-core/resource/persistence_state.rb +75 -0
  61. data/lib/dm-core/resource/persistence_state/clean.rb +40 -0
  62. data/lib/dm-core/resource/persistence_state/deleted.rb +30 -0
  63. data/lib/dm-core/resource/persistence_state/dirty.rb +96 -0
  64. data/lib/dm-core/resource/persistence_state/immutable.rb +34 -0
  65. data/lib/dm-core/resource/persistence_state/persisted.rb +29 -0
  66. data/lib/dm-core/resource/persistence_state/transient.rb +80 -0
  67. data/lib/dm-core/spec/lib/adapter_helpers.rb +64 -0
  68. data/lib/dm-core/spec/lib/collection_helpers.rb +21 -0
  69. data/lib/dm-core/spec/lib/counter_adapter.rb +38 -0
  70. data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
  71. data/lib/dm-core/spec/lib/spec_helper.rb +74 -0
  72. data/lib/dm-core/spec/setup.rb +174 -0
  73. data/lib/dm-core/spec/shared/adapter_spec.rb +341 -0
  74. data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
  75. data/lib/dm-core/spec/shared/resource_spec.rb +1232 -0
  76. data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
  77. data/lib/dm-core/spec/shared/semipublic/property_spec.rb +176 -0
  78. data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
  79. data/lib/dm-core/support/assertions.rb +8 -0
  80. data/lib/dm-core/support/chainable.rb +18 -0
  81. data/lib/dm-core/support/deprecate.rb +12 -0
  82. data/lib/dm-core/support/descendant_set.rb +89 -0
  83. data/lib/dm-core/support/equalizer.rb +48 -0
  84. data/lib/dm-core/support/ext/array.rb +22 -0
  85. data/lib/dm-core/support/ext/blank.rb +25 -0
  86. data/lib/dm-core/support/ext/hash.rb +67 -0
  87. data/lib/dm-core/support/ext/module.rb +47 -0
  88. data/lib/dm-core/support/ext/object.rb +57 -0
  89. data/lib/dm-core/support/ext/string.rb +24 -0
  90. data/lib/dm-core/support/ext/try_dup.rb +12 -0
  91. data/lib/dm-core/support/hook.rb +405 -0
  92. data/lib/dm-core/support/inflections.rb +60 -0
  93. data/lib/dm-core/support/inflector/inflections.rb +211 -0
  94. data/lib/dm-core/support/inflector/methods.rb +151 -0
  95. data/lib/dm-core/support/lazy_array.rb +451 -0
  96. data/lib/dm-core/support/local_object_space.rb +13 -0
  97. data/lib/dm-core/support/logger.rb +201 -0
  98. data/lib/dm-core/support/mash.rb +176 -0
  99. data/lib/dm-core/support/naming_conventions.rb +90 -0
  100. data/lib/dm-core/support/ordered_set.rb +380 -0
  101. data/lib/dm-core/support/subject.rb +33 -0
  102. data/lib/dm-core/support/subject_set.rb +250 -0
  103. data/lib/dm-core/version.rb +3 -0
  104. data/script/performance.rb +275 -0
  105. data/script/profile.rb +218 -0
  106. data/spec/lib/rspec_immediate_feedback_formatter.rb +54 -0
  107. data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +68 -0
  108. data/spec/public/associations/many_to_many_spec.rb +197 -0
  109. data/spec/public/associations/many_to_one_spec.rb +83 -0
  110. data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +40 -0
  111. data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +49 -0
  112. data/spec/public/associations/one_to_many_spec.rb +81 -0
  113. data/spec/public/associations/one_to_one_spec.rb +176 -0
  114. data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +46 -0
  115. data/spec/public/collection_spec.rb +69 -0
  116. data/spec/public/finalize_spec.rb +76 -0
  117. data/spec/public/model/hook_spec.rb +246 -0
  118. data/spec/public/model/property_spec.rb +88 -0
  119. data/spec/public/model/relationship_spec.rb +1040 -0
  120. data/spec/public/model_spec.rb +462 -0
  121. data/spec/public/property/binary_spec.rb +41 -0
  122. data/spec/public/property/boolean_spec.rb +22 -0
  123. data/spec/public/property/class_spec.rb +28 -0
  124. data/spec/public/property/date_spec.rb +22 -0
  125. data/spec/public/property/date_time_spec.rb +22 -0
  126. data/spec/public/property/decimal_spec.rb +23 -0
  127. data/spec/public/property/discriminator_spec.rb +135 -0
  128. data/spec/public/property/float_spec.rb +22 -0
  129. data/spec/public/property/integer_spec.rb +22 -0
  130. data/spec/public/property/object_spec.rb +107 -0
  131. data/spec/public/property/serial_spec.rb +22 -0
  132. data/spec/public/property/string_spec.rb +22 -0
  133. data/spec/public/property/text_spec.rb +63 -0
  134. data/spec/public/property/time_spec.rb +22 -0
  135. data/spec/public/property_spec.rb +341 -0
  136. data/spec/public/resource_spec.rb +288 -0
  137. data/spec/public/sel_spec.rb +53 -0
  138. data/spec/public/setup_spec.rb +145 -0
  139. data/spec/public/shared/association_collection_shared_spec.rb +309 -0
  140. data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
  141. data/spec/public/shared/collection_shared_spec.rb +1667 -0
  142. data/spec/public/shared/finder_shared_spec.rb +1629 -0
  143. data/spec/rcov.opts +6 -0
  144. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  145. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +13 -0
  146. data/spec/semipublic/associations/many_to_many_spec.rb +94 -0
  147. data/spec/semipublic/associations/many_to_one_spec.rb +63 -0
  148. data/spec/semipublic/associations/one_to_many_spec.rb +55 -0
  149. data/spec/semipublic/associations/one_to_one_spec.rb +53 -0
  150. data/spec/semipublic/associations/relationship_spec.rb +200 -0
  151. data/spec/semipublic/associations_spec.rb +177 -0
  152. data/spec/semipublic/collection_spec.rb +110 -0
  153. data/spec/semipublic/model_spec.rb +96 -0
  154. data/spec/semipublic/property/binary_spec.rb +13 -0
  155. data/spec/semipublic/property/boolean_spec.rb +47 -0
  156. data/spec/semipublic/property/class_spec.rb +33 -0
  157. data/spec/semipublic/property/date_spec.rb +43 -0
  158. data/spec/semipublic/property/date_time_spec.rb +46 -0
  159. data/spec/semipublic/property/decimal_spec.rb +83 -0
  160. data/spec/semipublic/property/discriminator_spec.rb +19 -0
  161. data/spec/semipublic/property/float_spec.rb +82 -0
  162. data/spec/semipublic/property/integer_spec.rb +82 -0
  163. data/spec/semipublic/property/lookup_spec.rb +29 -0
  164. data/spec/semipublic/property/serial_spec.rb +13 -0
  165. data/spec/semipublic/property/string_spec.rb +13 -0
  166. data/spec/semipublic/property/text_spec.rb +31 -0
  167. data/spec/semipublic/property/time_spec.rb +50 -0
  168. data/spec/semipublic/property_spec.rb +114 -0
  169. data/spec/semipublic/query/conditions/comparison_spec.rb +1501 -0
  170. data/spec/semipublic/query/conditions/operation_spec.rb +1294 -0
  171. data/spec/semipublic/query/path_spec.rb +471 -0
  172. data/spec/semipublic/query_spec.rb +3682 -0
  173. data/spec/semipublic/resource/state/clean_spec.rb +88 -0
  174. data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
  175. data/spec/semipublic/resource/state/dirty_spec.rb +162 -0
  176. data/spec/semipublic/resource/state/immutable_spec.rb +105 -0
  177. data/spec/semipublic/resource/state/transient_spec.rb +162 -0
  178. data/spec/semipublic/resource/state_spec.rb +230 -0
  179. data/spec/semipublic/resource_spec.rb +23 -0
  180. data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
  181. data/spec/semipublic/shared/resource_shared_spec.rb +199 -0
  182. data/spec/semipublic/shared/resource_state_shared_spec.rb +79 -0
  183. data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
  184. data/spec/spec.opts +5 -0
  185. data/spec/spec_helper.rb +38 -0
  186. data/spec/support/core_ext/hash.rb +10 -0
  187. data/spec/support/core_ext/inheritable_attributes.rb +46 -0
  188. data/spec/support/properties/huge_integer.rb +17 -0
  189. data/spec/unit/array_spec.rb +23 -0
  190. data/spec/unit/blank_spec.rb +73 -0
  191. data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
  192. data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
  193. data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
  194. data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
  195. data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
  196. data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
  197. data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
  198. data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
  199. data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
  200. data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
  201. data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
  202. data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
  203. data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
  204. data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
  205. data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
  206. data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
  207. data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
  208. data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
  209. data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
  210. data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
  211. data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
  212. data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
  213. data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
  214. data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
  215. data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
  216. data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
  217. data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
  218. data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
  219. data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
  220. data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
  221. data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
  222. data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
  223. data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
  224. data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
  225. data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
  226. data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
  227. data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
  228. data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
  229. data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
  230. data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
  231. data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
  232. data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
  233. data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
  234. data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
  235. data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
  236. data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
  237. data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
  238. data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
  239. data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
  240. data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
  241. data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
  242. data/spec/unit/hash_spec.rb +28 -0
  243. data/spec/unit/hook_spec.rb +1235 -0
  244. data/spec/unit/inflections_spec.rb +16 -0
  245. data/spec/unit/lazy_array_spec.rb +1949 -0
  246. data/spec/unit/mash_spec.rb +312 -0
  247. data/spec/unit/module_spec.rb +71 -0
  248. data/spec/unit/object_spec.rb +38 -0
  249. data/spec/unit/try_dup_spec.rb +46 -0
  250. data/tasks/ci.rake +1 -0
  251. data/tasks/spec.rake +38 -0
  252. data/tasks/yard.rake +9 -0
  253. data/tasks/yardstick.rake +19 -0
  254. metadata +365 -0
@@ -0,0 +1,309 @@
1
+ share_examples_for 'It can transfer a Resource from another association' do
2
+ before :all do
3
+ @no_join = defined?(DataMapper::Adapters::InMemoryAdapter) && @adapter.kind_of?(DataMapper::Adapters::InMemoryAdapter) ||
4
+ defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
5
+
6
+ @one_to_many = @articles.kind_of?(DataMapper::Associations::OneToMany::Collection)
7
+ @many_to_many = @articles.kind_of?(DataMapper::Associations::ManyToMany::Collection)
8
+
9
+ @skip = @no_join && @many_to_many
10
+ end
11
+
12
+ before :all do
13
+ unless @skip
14
+ %w[ @resource @original ].each do |ivar|
15
+ raise "+#{ivar}+ should be defined in before block" unless instance_variable_defined?(ivar)
16
+ raise "+#{ivar}+ should not be nil in before block" unless instance_variable_get(ivar)
17
+ end
18
+ end
19
+ end
20
+
21
+ before do
22
+ pending if @skip
23
+ end
24
+
25
+ it 'should remove the Resource from the original Collection' do
26
+ pending do
27
+ @original.should_not be_include(@resource)
28
+ end
29
+ end
30
+ end
31
+
32
+ share_examples_for 'A public Association Collection' do
33
+ before :all do
34
+ @no_join = defined?(DataMapper::Adapters::InMemoryAdapter) && @adapter.kind_of?(DataMapper::Adapters::InMemoryAdapter) ||
35
+ defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
36
+
37
+ @one_to_many = @articles.kind_of?(DataMapper::Associations::OneToMany::Collection)
38
+ @many_to_many = @articles.kind_of?(DataMapper::Associations::ManyToMany::Collection)
39
+
40
+ @skip = @no_join && @many_to_many
41
+ end
42
+
43
+ before :all do
44
+ unless @skip
45
+ %w[ @articles @other_articles ].each do |ivar|
46
+ raise "+#{ivar}+ should be defined in before block" unless instance_variable_get(ivar)
47
+ end
48
+ end
49
+
50
+ @articles.loaded?.should == loaded
51
+ end
52
+
53
+ before do
54
+ pending if @skip
55
+ end
56
+
57
+ describe '#<<' do
58
+ describe 'when provided a Resource belonging to another association' do
59
+ before :all do
60
+ @original = @other_articles
61
+ @resource = @original.first
62
+
63
+ rescue_if @skip do
64
+ @return = @articles << @resource
65
+ end
66
+ end
67
+
68
+ it 'should return a Collection' do
69
+ @return.should be_kind_of(DataMapper::Collection)
70
+ end
71
+
72
+ it 'should return self' do
73
+ @return.should equal(@articles)
74
+ end
75
+
76
+ it_should_behave_like 'It can transfer a Resource from another association'
77
+ end
78
+ end
79
+
80
+ describe '#collect!' do
81
+ describe 'when provided a Resource belonging to another association' do
82
+ before :all do
83
+ @original = @other_articles
84
+ @resource = @original.first
85
+ @return = @articles.collect! { |resource| @resource }
86
+ end
87
+
88
+ it 'should return a Collection' do
89
+ @return.should be_kind_of(DataMapper::Collection)
90
+ end
91
+
92
+ it 'should return self' do
93
+ @return.should equal(@articles)
94
+ end
95
+
96
+ it_should_behave_like 'It can transfer a Resource from another association'
97
+ end
98
+ end
99
+
100
+ describe '#concat' do
101
+ describe 'when provided a Resource belonging to another association' do
102
+ before :all do
103
+ @original = @other_articles
104
+ @resource = @original.first
105
+
106
+ rescue_if @skip do
107
+ @return = @articles.concat([ @resource ])
108
+ end
109
+ end
110
+
111
+ it 'should return a Collection' do
112
+ @return.should be_kind_of(DataMapper::Collection)
113
+ end
114
+
115
+ it 'should return self' do
116
+ @return.should equal(@articles)
117
+ end
118
+
119
+ it_should_behave_like 'It can transfer a Resource from another association'
120
+ end
121
+ end
122
+
123
+ describe '#create' do
124
+ describe 'when the parent is not saved' do
125
+ it 'should raise an exception' do
126
+ author = @author_model.new(:name => 'Dan Kubb')
127
+ lambda {
128
+ author.articles.create
129
+ }.should raise_error(DataMapper::UnsavedParentError)
130
+ end
131
+ end
132
+ end
133
+
134
+ describe '#destroy' do
135
+ describe 'when the parent is not saved' do
136
+ it 'should raise an exception' do
137
+ author = @author_model.new(:name => 'Dan Kubb')
138
+ lambda {
139
+ author.articles.destroy
140
+ }.should raise_error(DataMapper::UnsavedParentError, 'The source must be saved before mass-deleting the collection')
141
+ end
142
+ end
143
+ end
144
+
145
+ describe '#destroy!' do
146
+ describe 'when the parent is not saved' do
147
+ it 'should raise an exception' do
148
+ author = @author_model.new(:name => 'Dan Kubb')
149
+ lambda {
150
+ author.articles.destroy!
151
+ }.should raise_error(DataMapper::UnsavedParentError, 'The source must be saved before mass-deleting the collection')
152
+ end
153
+ end
154
+ end
155
+
156
+ describe '#insert' do
157
+ describe 'when provided a Resource belonging to another association' do
158
+ before :all do
159
+ @original = @other_articles
160
+ @resource = @original.first
161
+
162
+ rescue_if @skip do
163
+ @return = @articles.insert(0, @resource)
164
+ end
165
+ end
166
+
167
+ it 'should return a Collection' do
168
+ @return.should be_kind_of(DataMapper::Collection)
169
+ end
170
+
171
+ it 'should return self' do
172
+ @return.should equal(@articles)
173
+ end
174
+
175
+ it_should_behave_like 'It can transfer a Resource from another association'
176
+ end
177
+ end
178
+
179
+ it 'should respond to a public collection method with #method_missing' do
180
+ @articles.respond_to?(:to_a)
181
+ end
182
+
183
+ describe '#method_missing' do
184
+ describe 'with a public collection method' do
185
+ before :all do
186
+ @return = @articles.to_a
187
+ end
188
+
189
+ it 'should return expected object' do
190
+ @return.should == @articles
191
+ end
192
+ end
193
+
194
+ describe 'with unknown method' do
195
+ it 'should raise an exception' do
196
+ lambda {
197
+ @articles.unknown
198
+ }.should raise_error(NoMethodError)
199
+ end
200
+ end
201
+ end
202
+
203
+ describe '#new' do
204
+ before :all do
205
+ @resource = @author.articles.new
206
+ end
207
+
208
+ it 'should associate the Resource to the Collection' do
209
+ if @resource.respond_to?(:authors)
210
+ pending 'TODO: make sure the association is bidirectional' do
211
+ @resource.authors.should == [ @author ]
212
+ end
213
+ else
214
+ @resource.author.should == @author
215
+ end
216
+ end
217
+ end
218
+
219
+ describe '#push' do
220
+ describe 'when provided a Resource belonging to another association' do
221
+ before :all do
222
+ @original = @other_articles
223
+ @resource = @original.first
224
+
225
+ rescue_if @skip do
226
+ @return = @articles.push(@resource)
227
+ end
228
+ end
229
+
230
+ it 'should return a Collection' do
231
+ @return.should be_kind_of(DataMapper::Collection)
232
+ end
233
+
234
+ it 'should return self' do
235
+ @return.should equal(@articles)
236
+ end
237
+
238
+ it_should_behave_like 'It can transfer a Resource from another association'
239
+ end
240
+ end
241
+
242
+ describe '#replace' do
243
+ describe 'when provided a Resource belonging to another association' do
244
+ before :all do
245
+ @original = @other_articles
246
+ @resource = @original.first
247
+
248
+ rescue_if @skip do
249
+ @return = @articles.replace([ @resource ])
250
+ end
251
+ end
252
+
253
+ it 'should return a Collection' do
254
+ @return.should be_kind_of(DataMapper::Collection)
255
+ end
256
+
257
+ it 'should return self' do
258
+ @return.should equal(@articles)
259
+ end
260
+
261
+ it_should_behave_like 'It can transfer a Resource from another association'
262
+ end
263
+ end
264
+
265
+ describe '#unshift' do
266
+ describe 'when provided a Resource belonging to another association' do
267
+ before :all do
268
+ @original = @other_articles
269
+ @resource = @original.first
270
+
271
+ rescue_if @skip do
272
+ @return = @articles.unshift(@resource)
273
+ end
274
+ end
275
+
276
+ it 'should return a Collection' do
277
+ @return.should be_kind_of(DataMapper::Collection)
278
+ end
279
+
280
+ it 'should return self' do
281
+ @return.should equal(@articles)
282
+ end
283
+
284
+ it_should_behave_like 'It can transfer a Resource from another association'
285
+ end
286
+ end
287
+
288
+ describe '#update' do
289
+ describe 'when the parent is not saved' do
290
+ it 'should raise an exception' do
291
+ author = @author_model.new(:name => 'Dan Kubb')
292
+ lambda {
293
+ author.articles.update(:title => 'New Title')
294
+ }.should raise_error(DataMapper::UnsavedParentError, 'The source must be saved before mass-updating the collection')
295
+ end
296
+ end
297
+ end
298
+
299
+ describe '#update!' do
300
+ describe 'when the parent is not saved' do
301
+ it 'should raise an exception' do
302
+ author = @author_model.new(:name => 'Dan Kubb')
303
+ lambda {
304
+ author.articles.update!(:title => 'New Title')
305
+ }.should raise_error(DataMapper::UnsavedParentError, 'The source must be saved before mass-updating the collection')
306
+ end
307
+ end
308
+ end
309
+ end
@@ -0,0 +1,267 @@
1
+ share_examples_for 'Collection Finder Interface' do
2
+ before :all do
3
+ %w[ @article_model @article @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
+ end
8
+
9
+ before :all do
10
+ @no_join = defined?(DataMapper::Adapters::InMemoryAdapter) && @adapter.kind_of?(DataMapper::Adapters::InMemoryAdapter) ||
11
+ defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
12
+
13
+ @many_to_many = @articles.kind_of?(DataMapper::Associations::ManyToMany::Collection)
14
+
15
+ @skip = @no_join && @many_to_many
16
+ end
17
+
18
+ before do
19
+ pending if @skip
20
+ end
21
+
22
+ describe '#at' do
23
+ before :all do
24
+ @copy = @articles.dup
25
+ @copy.to_a
26
+ end
27
+
28
+ describe 'with positive offset', 'after prepending to the collection' do
29
+ before :all do
30
+ @return = @resource = @articles.unshift(@other).at(0)
31
+ end
32
+
33
+ should_not_be_a_kicker
34
+
35
+ it 'should return a Resource' do
36
+ @return.should be_kind_of(DataMapper::Resource)
37
+ end
38
+
39
+ it 'should return expected Resource' do
40
+ @resource.should equal(@other)
41
+ end
42
+ end
43
+
44
+ describe 'with negative offset', 'after appending to the collection' do
45
+ before :all do
46
+ @return = @resource = @articles.push(@other).at(-1)
47
+ end
48
+
49
+ should_not_be_a_kicker
50
+
51
+ it 'should return a Resource' do
52
+ @return.should be_kind_of(DataMapper::Resource)
53
+ end
54
+
55
+ it 'should return expected Resource' do
56
+ @resource.should equal(@other)
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '#first' do
62
+ before :all do
63
+ 1.upto(5) { |number| @articles.create(:content => "Article #{number}") }
64
+
65
+ @copy = @articles.dup
66
+ @copy.to_a
67
+
68
+ # reload the articles
69
+ @articles = @article_model.all(@articles.query)
70
+ end
71
+
72
+ describe 'with no arguments' do
73
+ before :all do
74
+ @return = @resource = @articles.first
75
+ end
76
+
77
+ it 'should return a Resource' do
78
+ @return.should be_kind_of(DataMapper::Resource)
79
+ end
80
+
81
+ it 'should be first Resource in the Collection' do
82
+ @resource.should equal(@copy.entries.first)
83
+ end
84
+
85
+ it 'should return the same Resource every time' do
86
+ @return.should equal(@articles.first)
87
+ end
88
+ end
89
+
90
+ describe 'with no arguments', 'after prepending to the collection' do
91
+ before :all do
92
+ @return = @resource = @articles.unshift(@other).first
93
+ end
94
+
95
+ it 'should return a Resource' do
96
+ @return.should be_kind_of(DataMapper::Resource)
97
+ end
98
+
99
+ it 'should return expected Resource' do
100
+ @resource.should equal(@other)
101
+ end
102
+
103
+ it 'should be first Resource in the Collection' do
104
+ @resource.should equal(@copy.entries.unshift(@other).first)
105
+ end
106
+ end
107
+
108
+ describe 'with empty query', 'after prepending to the collection' do
109
+ before :all do
110
+ @return = @resource = @articles.unshift(@other).first({})
111
+ end
112
+
113
+ it 'should return a Resource' do
114
+ @return.should be_kind_of(DataMapper::Resource)
115
+ end
116
+
117
+ it 'should return expected Resource' do
118
+ @resource.should equal(@other)
119
+ end
120
+
121
+ it 'should be first Resource in the Collection' do
122
+ @resource.should equal(@copy.entries.unshift(@other).first)
123
+ end
124
+ end
125
+
126
+ describe 'with a limit specified', 'after prepending to the collection' do
127
+ before :all do
128
+ @return = @resources = @articles.unshift(@other).first(1)
129
+ end
130
+
131
+ it 'should return a Collection' do
132
+ @return.should be_kind_of(DataMapper::Collection)
133
+ end
134
+
135
+ it 'should be the expected Collection' do
136
+ @resources.should == [ @other ]
137
+ end
138
+
139
+ it 'should be the first N Resources in the Collection' do
140
+ @resources.should == @copy.entries.unshift(@other).first(1)
141
+ end
142
+ end
143
+ end
144
+
145
+ [ :get, :get! ].each do |method|
146
+ describe 'with a key to a Resource within a Collection using a limit' do
147
+ before :all do
148
+ rescue_if @skip && method == :get! do
149
+ @articles = @articles.all(:limit => 1)
150
+
151
+ @return = @resource = @articles.send(method, *@article.key)
152
+ end
153
+ end
154
+
155
+ it 'should return a Resource' do
156
+ @return.should be_kind_of(DataMapper::Resource)
157
+ end
158
+
159
+ it 'should be matching Resource in the Collection' do
160
+ @resource.should == @article
161
+ end
162
+ end
163
+
164
+ describe 'with a key to a Resource within a Collection using an offset' do
165
+ before :all do
166
+ rescue_if @skip && method == :get! do
167
+ @new = @articles.create(:content => 'New Article')
168
+ @articles = @articles.all(:offset => 1, :limit => 1)
169
+
170
+ @return = @resource = @articles.send(method, *@new.key)
171
+ end
172
+ end
173
+
174
+ it 'should return a Resource' do
175
+ @return.should be_kind_of(DataMapper::Resource)
176
+ end
177
+
178
+ it 'should be matching Resource in the Collection' do
179
+ @resource.should equal(@new)
180
+ end
181
+ end
182
+ end
183
+
184
+ describe '#last' do
185
+ before :all do
186
+ 1.upto(5) { |number| @articles.create(:content => "Article #{number}") }
187
+
188
+ @copy = @articles.dup
189
+ @copy.to_a
190
+
191
+ # reload the articles
192
+ @articles = @article_model.all(@articles.query)
193
+ end
194
+
195
+ describe 'with no arguments' do
196
+ before :all do
197
+ @return = @resource = @articles.last
198
+ end
199
+
200
+ it 'should return a Resource' do
201
+ @return.should be_kind_of(DataMapper::Resource)
202
+ end
203
+
204
+ it 'should be last Resource in the Collection' do
205
+ @resource.should equal(@copy.entries.last)
206
+ end
207
+
208
+ it 'should return the same Resource every time' do
209
+ @return.should equal(@articles.last)
210
+ end
211
+ end
212
+
213
+ describe 'with no arguments', 'after appending to the collection' do
214
+ before :all do
215
+ @return = @resource = @articles.push(@other).last
216
+ end
217
+
218
+ it 'should return a Resource' do
219
+ @return.should be_kind_of(DataMapper::Resource)
220
+ end
221
+
222
+ it 'should return expected Resource' do
223
+ @resource.should equal(@other)
224
+ end
225
+
226
+ it 'should be last Resource in the Collection' do
227
+ @resource.should equal(@copy.entries.push(@other).last)
228
+ end
229
+ end
230
+
231
+ describe 'with empty query', 'after appending to the collection' do
232
+ before :all do
233
+ @return = @resource = @articles.push(@other).last({})
234
+ end
235
+
236
+ it 'should return a Resource' do
237
+ @return.should be_kind_of(DataMapper::Resource)
238
+ end
239
+
240
+ it 'should return expected Resource' do
241
+ @resource.should equal(@other)
242
+ end
243
+
244
+ it 'should be last Resource in the Collection' do
245
+ @resource.should equal(@copy.entries.push(@other).last)
246
+ end
247
+ end
248
+
249
+ describe 'with a limit specified', 'after appending to the collection' do
250
+ before :all do
251
+ @return = @resources = @articles.push(@other).last(1)
252
+ end
253
+
254
+ it 'should return a Collection' do
255
+ @return.should be_kind_of(DataMapper::Collection)
256
+ end
257
+
258
+ it 'should be the expected Collection' do
259
+ @resources.should == [ @other ]
260
+ end
261
+
262
+ it 'should be the last N Resources in the Collection' do
263
+ @resources.should == @copy.entries.push(@other).last(1)
264
+ end
265
+ end
266
+ end
267
+ end