sbf-dm-core 1.3.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +29 -0
  3. data/.document +5 -0
  4. data/.gitignore +44 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +468 -0
  7. data/.travis.yml +57 -0
  8. data/.yardopts +1 -0
  9. data/Gemfile +70 -0
  10. data/LICENSE +20 -0
  11. data/README.md +269 -0
  12. data/Rakefile +4 -0
  13. data/dm-core.gemspec +21 -0
  14. data/lib/dm-core/adapters/abstract_adapter.rb +233 -0
  15. data/lib/dm-core/adapters/in_memory_adapter.rb +110 -0
  16. data/lib/dm-core/adapters.rb +249 -0
  17. data/lib/dm-core/associations/many_to_many.rb +477 -0
  18. data/lib/dm-core/associations/many_to_one.rb +282 -0
  19. data/lib/dm-core/associations/one_to_many.rb +332 -0
  20. data/lib/dm-core/associations/one_to_one.rb +84 -0
  21. data/lib/dm-core/associations/relationship.rb +650 -0
  22. data/lib/dm-core/backwards.rb +11 -0
  23. data/lib/dm-core/collection.rb +1486 -0
  24. data/lib/dm-core/core_ext/kernel.rb +21 -0
  25. data/lib/dm-core/core_ext/pathname.rb +4 -0
  26. data/lib/dm-core/core_ext/symbol.rb +10 -0
  27. data/lib/dm-core/identity_map.rb +6 -0
  28. data/lib/dm-core/model/hook.rb +99 -0
  29. data/lib/dm-core/model/is.rb +30 -0
  30. data/lib/dm-core/model/property.rb +244 -0
  31. data/lib/dm-core/model/relationship.rb +366 -0
  32. data/lib/dm-core/model/scope.rb +87 -0
  33. data/lib/dm-core/model.rb +876 -0
  34. data/lib/dm-core/property/binary.rb +19 -0
  35. data/lib/dm-core/property/boolean.rb +35 -0
  36. data/lib/dm-core/property/class.rb +23 -0
  37. data/lib/dm-core/property/date.rb +45 -0
  38. data/lib/dm-core/property/date_time.rb +44 -0
  39. data/lib/dm-core/property/decimal.rb +47 -0
  40. data/lib/dm-core/property/discriminator.rb +40 -0
  41. data/lib/dm-core/property/float.rb +27 -0
  42. data/lib/dm-core/property/integer.rb +32 -0
  43. data/lib/dm-core/property/invalid_value_error.rb +17 -0
  44. data/lib/dm-core/property/lookup.rb +26 -0
  45. data/lib/dm-core/property/numeric.rb +35 -0
  46. data/lib/dm-core/property/object.rb +33 -0
  47. data/lib/dm-core/property/serial.rb +13 -0
  48. data/lib/dm-core/property/string.rb +47 -0
  49. data/lib/dm-core/property/text.rb +12 -0
  50. data/lib/dm-core/property/time.rb +46 -0
  51. data/lib/dm-core/property/typecast/numeric.rb +32 -0
  52. data/lib/dm-core/property/typecast/time.rb +33 -0
  53. data/lib/dm-core/property.rb +856 -0
  54. data/lib/dm-core/property_set.rb +177 -0
  55. data/lib/dm-core/query/conditions/comparison.rb +886 -0
  56. data/lib/dm-core/query/conditions/operation.rb +710 -0
  57. data/lib/dm-core/query/direction.rb +33 -0
  58. data/lib/dm-core/query/operator.rb +34 -0
  59. data/lib/dm-core/query/path.rb +113 -0
  60. data/lib/dm-core/query/sort.rb +38 -0
  61. data/lib/dm-core/query.rb +1352 -0
  62. data/lib/dm-core/relationship_set.rb +69 -0
  63. data/lib/dm-core/repository.rb +226 -0
  64. data/lib/dm-core/resource/persistence_state/clean.rb +36 -0
  65. data/lib/dm-core/resource/persistence_state/deleted.rb +26 -0
  66. data/lib/dm-core/resource/persistence_state/dirty.rb +91 -0
  67. data/lib/dm-core/resource/persistence_state/immutable.rb +32 -0
  68. data/lib/dm-core/resource/persistence_state/persisted.rb +25 -0
  69. data/lib/dm-core/resource/persistence_state/transient.rb +87 -0
  70. data/lib/dm-core/resource/persistence_state.rb +70 -0
  71. data/lib/dm-core/resource.rb +1220 -0
  72. data/lib/dm-core/spec/lib/adapter_helpers.rb +63 -0
  73. data/lib/dm-core/spec/lib/collection_helpers.rb +21 -0
  74. data/lib/dm-core/spec/lib/counter_adapter.rb +38 -0
  75. data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
  76. data/lib/dm-core/spec/lib/spec_helper.rb +74 -0
  77. data/lib/dm-core/spec/setup.rb +164 -0
  78. data/lib/dm-core/spec/shared/adapter_spec.rb +366 -0
  79. data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
  80. data/lib/dm-core/spec/shared/resource_spec.rb +1221 -0
  81. data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
  82. data/lib/dm-core/spec/shared/semipublic/property_spec.rb +184 -0
  83. data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
  84. data/lib/dm-core/support/assertions.rb +8 -0
  85. data/lib/dm-core/support/chainable.rb +18 -0
  86. data/lib/dm-core/support/deprecate.rb +12 -0
  87. data/lib/dm-core/support/descendant_set.rb +89 -0
  88. data/lib/dm-core/support/equalizer.rb +48 -0
  89. data/lib/dm-core/support/ext/array.rb +22 -0
  90. data/lib/dm-core/support/ext/blank.rb +25 -0
  91. data/lib/dm-core/support/ext/hash.rb +67 -0
  92. data/lib/dm-core/support/ext/module.rb +47 -0
  93. data/lib/dm-core/support/ext/object.rb +57 -0
  94. data/lib/dm-core/support/ext/string.rb +24 -0
  95. data/lib/dm-core/support/ext/try_dup.rb +12 -0
  96. data/lib/dm-core/support/hook.rb +388 -0
  97. data/lib/dm-core/support/inflections.rb +60 -0
  98. data/lib/dm-core/support/inflector/inflections.rb +211 -0
  99. data/lib/dm-core/support/inflector/methods.rb +151 -0
  100. data/lib/dm-core/support/lazy_array.rb +451 -0
  101. data/lib/dm-core/support/local_object_space.rb +13 -0
  102. data/lib/dm-core/support/logger.rb +201 -0
  103. data/lib/dm-core/support/mash.rb +176 -0
  104. data/lib/dm-core/support/naming_conventions.rb +109 -0
  105. data/lib/dm-core/support/ordered_set.rb +381 -0
  106. data/lib/dm-core/support/subject.rb +33 -0
  107. data/lib/dm-core/support/subject_set.rb +251 -0
  108. data/lib/dm-core/version.rb +3 -0
  109. data/lib/dm-core.rb +274 -0
  110. data/script/performance.rb +275 -0
  111. data/script/profile.rb +218 -0
  112. data/spec/lib/rspec_immediate_feedback_formatter.rb +54 -0
  113. data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +69 -0
  114. data/spec/public/associations/many_to_many_spec.rb +197 -0
  115. data/spec/public/associations/many_to_one_spec.rb +83 -0
  116. data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +40 -0
  117. data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +49 -0
  118. data/spec/public/associations/one_to_many_spec.rb +81 -0
  119. data/spec/public/associations/one_to_one_spec.rb +176 -0
  120. data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +46 -0
  121. data/spec/public/collection_spec.rb +69 -0
  122. data/spec/public/finalize_spec.rb +77 -0
  123. data/spec/public/model/hook_spec.rb +245 -0
  124. data/spec/public/model/property_spec.rb +91 -0
  125. data/spec/public/model/relationship_spec.rb +1040 -0
  126. data/spec/public/model_spec.rb +456 -0
  127. data/spec/public/property/binary_spec.rb +43 -0
  128. data/spec/public/property/boolean_spec.rb +21 -0
  129. data/spec/public/property/class_spec.rb +27 -0
  130. data/spec/public/property/date_spec.rb +21 -0
  131. data/spec/public/property/date_time_spec.rb +21 -0
  132. data/spec/public/property/decimal_spec.rb +23 -0
  133. data/spec/public/property/discriminator_spec.rb +134 -0
  134. data/spec/public/property/float_spec.rb +22 -0
  135. data/spec/public/property/integer_spec.rb +22 -0
  136. data/spec/public/property/object_spec.rb +117 -0
  137. data/spec/public/property/serial_spec.rb +22 -0
  138. data/spec/public/property/string_spec.rb +21 -0
  139. data/spec/public/property/text_spec.rb +62 -0
  140. data/spec/public/property/time_spec.rb +21 -0
  141. data/spec/public/property_spec.rb +333 -0
  142. data/spec/public/resource/state_spec.rb +72 -0
  143. data/spec/public/resource_spec.rb +289 -0
  144. data/spec/public/sel_spec.rb +53 -0
  145. data/spec/public/setup_spec.rb +145 -0
  146. data/spec/public/shared/association_collection_shared_spec.rb +309 -0
  147. data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
  148. data/spec/public/shared/collection_shared_spec.rb +1637 -0
  149. data/spec/public/shared/finder_shared_spec.rb +1647 -0
  150. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  151. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +13 -0
  152. data/spec/semipublic/associations/many_to_many_spec.rb +94 -0
  153. data/spec/semipublic/associations/many_to_one_spec.rb +63 -0
  154. data/spec/semipublic/associations/one_to_many_spec.rb +55 -0
  155. data/spec/semipublic/associations/one_to_one_spec.rb +53 -0
  156. data/spec/semipublic/associations/relationship_spec.rb +200 -0
  157. data/spec/semipublic/associations_spec.rb +177 -0
  158. data/spec/semipublic/collection_spec.rb +110 -0
  159. data/spec/semipublic/model_spec.rb +96 -0
  160. data/spec/semipublic/property/binary_spec.rb +13 -0
  161. data/spec/semipublic/property/boolean_spec.rb +47 -0
  162. data/spec/semipublic/property/class_spec.rb +33 -0
  163. data/spec/semipublic/property/date_spec.rb +43 -0
  164. data/spec/semipublic/property/date_time_spec.rb +46 -0
  165. data/spec/semipublic/property/decimal_spec.rb +83 -0
  166. data/spec/semipublic/property/discriminator_spec.rb +19 -0
  167. data/spec/semipublic/property/float_spec.rb +82 -0
  168. data/spec/semipublic/property/integer_spec.rb +82 -0
  169. data/spec/semipublic/property/lookup_spec.rb +29 -0
  170. data/spec/semipublic/property/serial_spec.rb +13 -0
  171. data/spec/semipublic/property/string_spec.rb +13 -0
  172. data/spec/semipublic/property/text_spec.rb +31 -0
  173. data/spec/semipublic/property/time_spec.rb +50 -0
  174. data/spec/semipublic/property_spec.rb +114 -0
  175. data/spec/semipublic/query/conditions/comparison_spec.rb +1502 -0
  176. data/spec/semipublic/query/conditions/operation_spec.rb +1296 -0
  177. data/spec/semipublic/query/path_spec.rb +471 -0
  178. data/spec/semipublic/query_spec.rb +3665 -0
  179. data/spec/semipublic/resource/state/clean_spec.rb +89 -0
  180. data/spec/semipublic/resource/state/deleted_spec.rb +79 -0
  181. data/spec/semipublic/resource/state/dirty_spec.rb +163 -0
  182. data/spec/semipublic/resource/state/immutable_spec.rb +107 -0
  183. data/spec/semipublic/resource/state/transient_spec.rb +163 -0
  184. data/spec/semipublic/resource/state_spec.rb +230 -0
  185. data/spec/semipublic/resource_spec.rb +23 -0
  186. data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
  187. data/spec/semipublic/shared/resource_shared_spec.rb +198 -0
  188. data/spec/semipublic/shared/resource_state_shared_spec.rb +91 -0
  189. data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
  190. data/spec/spec_helper.rb +34 -0
  191. data/spec/support/core_ext/hash.rb +10 -0
  192. data/spec/support/core_ext/inheritable_attributes.rb +46 -0
  193. data/spec/support/properties/huge_integer.rb +17 -0
  194. data/spec/unit/array_spec.rb +23 -0
  195. data/spec/unit/blank_spec.rb +73 -0
  196. data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
  197. data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
  198. data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
  199. data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
  200. data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
  201. data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
  202. data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
  203. data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
  204. data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
  205. data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
  206. data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
  207. data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
  208. data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
  209. data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
  210. data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
  211. data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
  212. data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
  213. data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
  214. data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
  215. data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
  216. data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
  217. data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
  218. data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
  219. data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
  220. data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
  221. data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
  222. data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
  223. data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
  224. data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
  225. data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
  226. data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
  227. data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
  228. data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
  229. data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
  230. data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
  231. data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
  232. data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
  233. data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
  234. data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
  235. data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
  236. data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
  237. data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
  238. data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
  239. data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
  240. data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
  241. data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
  242. data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
  243. data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
  244. data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
  245. data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
  246. data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
  247. data/spec/unit/hash_spec.rb +27 -0
  248. data/spec/unit/hook_spec.rb +1216 -0
  249. data/spec/unit/inflections_spec.rb +14 -0
  250. data/spec/unit/lazy_array_spec.rb +1949 -0
  251. data/spec/unit/mash_spec.rb +289 -0
  252. data/spec/unit/module_spec.rb +70 -0
  253. data/spec/unit/object_spec.rb +38 -0
  254. data/spec/unit/try_dup_spec.rb +46 -0
  255. data/tasks/ci.rake +1 -0
  256. data/tasks/spec.rake +18 -0
  257. data/tasks/yard.rake +9 -0
  258. data/tasks/yardstick.rake +19 -0
  259. metadata +323 -0
@@ -0,0 +1,69 @@
1
+ require_relative '../spec_helper'
2
+
3
+ # run the specs once with a loaded collection and once not
4
+ [ false, true ].each do |loaded|
5
+ describe DataMapper::Collection do
6
+ extend DataMapper::Spec::CollectionHelpers::GroupMethods
7
+
8
+ self.loaded = loaded
9
+
10
+ before :all do
11
+ module ::Blog
12
+ class Article
13
+ include DataMapper::Resource
14
+
15
+ property :id, Serial
16
+ property :title, String, :required => true
17
+ property :content, Text
18
+ property :subtitle, String
19
+ property :author, String, :required => true
20
+ property :attachment, Object
21
+
22
+ belongs_to :original, self, :required => false
23
+ has n, :revisions, self, :child_key => [ :original_id ]
24
+ has 1, :previous, self, :child_key => [ :original_id ], :order => [ :id.desc ]
25
+ has n, :publications, :through => Resource
26
+ end
27
+
28
+ class Publication
29
+ include DataMapper::Resource
30
+
31
+ property :id, Serial
32
+ property :name, String
33
+
34
+ has n, :articles, :through => Resource
35
+ end
36
+ end
37
+
38
+ DataMapper.finalize
39
+
40
+ @article_model = Blog::Article
41
+ @publication_model = Blog::Publication
42
+ end
43
+
44
+ supported_by :all do
45
+ before :all do
46
+ @author = 'Dan Kubb'
47
+
48
+ @original = @article_model.create(:title => 'Original Article', :author => @author)
49
+ @article = @article_model.create(:title => 'Sample Article', :content => 'Sample', :original => @original, :author => @author)
50
+ @other = @article_model.create(:title => 'Other Article', :content => 'Other', :author => @author)
51
+
52
+ # load the targets without references to a single source
53
+ load_collection = lambda do |query|
54
+ @article_model.all(query)
55
+ end
56
+
57
+ @articles = load_collection.call(:title => 'Sample Article', :author => @author)
58
+ @other_articles = load_collection.call(:title => 'Other Article', :author => @author)
59
+
60
+ @articles.entries if loaded
61
+ end
62
+
63
+ it_behaves_like 'A public Collection'
64
+ it_behaves_like 'A Collection supporting Strategic Eager Loading'
65
+ it_behaves_like 'Finder Interface'
66
+ it_behaves_like 'Collection Finder Interface'
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,77 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe DataMapper do
4
+ describe '.finalize' do
5
+ subject { DataMapper.finalize }
6
+
7
+ it 'does not raise with valid models' do
8
+ class ::ValidObject
9
+ include DataMapper::Resource
10
+ property :id, Integer, :key => true
11
+ end
12
+ begin
13
+ expect(method(:subject)).not_to raise_error
14
+ ensure
15
+ DataMapper::Model.descendants.delete(ValidObject)
16
+ Object.send(:remove_const, :ValidObject)
17
+ end
18
+ end
19
+
20
+ it 'does not raise on valid child model' do
21
+ class ::ValidChild
22
+ include DataMapper::Resource
23
+ belongs_to :valid_object, :key => true
24
+ end
25
+ class ::ValidObject
26
+ include DataMapper::Resource
27
+ property :id, Integer, :key => true
28
+ end
29
+ begin
30
+ expect(method(:subject)).not_to raise_error
31
+ ensure
32
+ DataMapper::Model.descendants.delete(ValidChild)
33
+ DataMapper::Model.descendants.delete(ValidObject)
34
+ Object.send(:remove_const, :ValidChild)
35
+ Object.send(:remove_const, :ValidObject)
36
+ end
37
+ end
38
+
39
+ it 'raises on an anonymous model' do
40
+ model = Class.new do
41
+ include DataMapper::Resource
42
+ property :id, Integer, :key => true
43
+ end
44
+ begin
45
+ expect(method(:subject)).to raise_error(DataMapper::IncompleteModelError, "#{model.inspect} must have a name")
46
+ ensure
47
+ DataMapper::Model.descendants.delete(model)
48
+ end
49
+ end
50
+
51
+ it 'Raises on an empty model' do
52
+ class ::EmptyObject
53
+ include DataMapper::Resource
54
+ end
55
+ begin
56
+ expect(method(:subject)).to raise_error(DataMapper::IncompleteModelError,
57
+ 'EmptyObject must have at least one property or many to one relationship in default to be valid')
58
+ ensure
59
+ DataMapper::Model.descendants.delete(EmptyObject)
60
+ Object.send(:remove_const, :EmptyObject)
61
+ end
62
+ end
63
+
64
+ it 'Raises on a keyless model' do
65
+ class ::KeylessObject
66
+ include DataMapper::Resource
67
+ property :name, String
68
+ end
69
+ begin
70
+ expect(method(:subject)).to raise_error(DataMapper::IncompleteModelError, 'KeylessObject must have a key in default to be valid')
71
+ ensure
72
+ DataMapper::Model.descendants.delete(KeylessObject)
73
+ Object.send(:remove_const, :KeylessObject)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,245 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe DataMapper::Model::Hook do
4
+ before :all do
5
+ class ::ModelHookSpecs
6
+ include DataMapper::Resource
7
+
8
+ property :id, Serial
9
+ property :value, Integer, :required => true, :default => 1
10
+
11
+ def an_instance_method
12
+ end
13
+ end
14
+
15
+ class ::ModelHookSpecsSubclass < ModelHookSpecs; end
16
+
17
+ DataMapper.finalize
18
+ end
19
+
20
+ before :all do
21
+ @resource = ModelHookSpecs.new
22
+ end
23
+
24
+ describe '#before' do
25
+ describe 'an instance method' do
26
+ before do
27
+ @hooks = hooks = []
28
+ ModelHookSpecs.before(:an_instance_method) { hooks << :before_instance_method }
29
+
30
+ @resource.an_instance_method
31
+ end
32
+
33
+ it 'executes before instance method hook' do
34
+ expect(@hooks).to eq [:before_instance_method]
35
+ end
36
+ end
37
+
38
+ describe 'save' do
39
+ supported_by :all do
40
+ before do
41
+ @hooks = hooks = []
42
+ ModelHookSpecs.before(:save) { hooks << :before_save }
43
+
44
+ @resource.save
45
+ end
46
+
47
+ it 'executes before save hook' do
48
+ expect(@hooks).to eq [:before_save]
49
+ end
50
+ end
51
+ end
52
+
53
+ describe 'create' do
54
+ supported_by :all do
55
+ before do
56
+ @hooks = hooks = []
57
+ ModelHookSpecs.before(:create) { hooks << :before_create }
58
+
59
+ @resource.save
60
+ end
61
+
62
+ it 'executes before create hook' do
63
+ expect(@hooks).to eq [:before_create]
64
+ end
65
+ end
66
+ end
67
+
68
+ describe 'update' do
69
+ supported_by :all do
70
+ before do
71
+ @hooks = hooks = []
72
+ ModelHookSpecs.before(:update) { hooks << :before_update }
73
+
74
+ @resource.save
75
+ @resource.update(:value => 2)
76
+ end
77
+
78
+ it 'executes before update hook' do
79
+ expect(@hooks).to eq [:before_update]
80
+ end
81
+ end
82
+ end
83
+
84
+ describe 'destroy' do
85
+ supported_by :all do
86
+ before do
87
+ @hooks = hooks = []
88
+ ModelHookSpecs.before(:destroy) { hooks << :before_destroy }
89
+
90
+ @resource.save
91
+ @resource.destroy
92
+ end
93
+
94
+ it 'executes before destroy hook' do
95
+ expect(@hooks).to eq [:before_destroy]
96
+ end
97
+ end
98
+ end
99
+
100
+ describe 'with an inherited hook' do
101
+ supported_by :all do
102
+ before do
103
+ @hooks = hooks = []
104
+ ModelHookSpecs.before(:an_instance_method) { hooks << :inherited_hook }
105
+ end
106
+
107
+ it 'executes inherited hook' do
108
+ ModelHookSpecsSubclass.new.an_instance_method
109
+ expect(@hooks).to eq [:inherited_hook]
110
+ end
111
+ end
112
+ end
113
+
114
+ describe 'with a hook declared in the subclasss' do
115
+ supported_by :all do
116
+ before do
117
+ @hooks = hooks = []
118
+ ModelHookSpecsSubclass.before(:an_instance_method) { hooks << :hook }
119
+ end
120
+
121
+ it 'executes hook' do
122
+ ModelHookSpecsSubclass.new.an_instance_method
123
+ expect(@hooks).to eq [:hook]
124
+ end
125
+
126
+ it 'does not alter hooks in the parent class' do
127
+ expect(@hooks).to be_empty
128
+ ModelHookSpecs.new.an_instance_method
129
+ expect(@hooks).to eq []
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ describe '#after' do
136
+ describe 'an instance method' do
137
+ before do
138
+ @hooks = hooks = []
139
+ ModelHookSpecs.after(:an_instance_method) { hooks << :after_instance_method }
140
+
141
+ @resource.an_instance_method
142
+ end
143
+
144
+ it 'executes after instance method hook' do
145
+ expect(@hooks).to eq [:after_instance_method]
146
+ end
147
+ end
148
+
149
+ describe 'save' do
150
+ supported_by :all do
151
+ before do
152
+ @hooks = hooks = []
153
+ ModelHookSpecs.after(:save) { hooks << :after_save }
154
+
155
+ @resource.save
156
+ end
157
+
158
+ it 'executes after save hook' do
159
+ expect(@hooks).to eq [:after_save]
160
+ end
161
+ end
162
+ end
163
+
164
+ describe 'create' do
165
+ supported_by :all do
166
+ before do
167
+ @hooks = hooks = []
168
+ ModelHookSpecs.after(:create) { hooks << :after_create }
169
+
170
+ @resource.save
171
+ end
172
+
173
+ it 'executes after create hook' do
174
+ expect(@hooks).to eq [:after_create]
175
+ end
176
+ end
177
+ end
178
+
179
+ describe 'update' do
180
+ supported_by :all do
181
+ before do
182
+ @hooks = hooks = []
183
+ ModelHookSpecs.after(:update) { hooks << :after_update }
184
+
185
+ @resource.save
186
+ @resource.update(:value => 2)
187
+ end
188
+
189
+ it 'executes after update hook' do
190
+ expect(@hooks).to eq [:after_update]
191
+ end
192
+ end
193
+ end
194
+
195
+ describe 'destroy' do
196
+ supported_by :all do
197
+ before do
198
+ @hooks = hooks = []
199
+ ModelHookSpecs.after(:destroy) { hooks << :after_destroy }
200
+
201
+ @resource.save
202
+ @resource.destroy
203
+ end
204
+
205
+ it 'executes after destroy hook' do
206
+ expect(@hooks).to eq [:after_destroy]
207
+ end
208
+ end
209
+ end
210
+
211
+ describe 'with an inherited hook' do
212
+ supported_by :all do
213
+ before do
214
+ @hooks = hooks = []
215
+ ModelHookSpecs.after(:an_instance_method) { hooks << :inherited_hook }
216
+ end
217
+
218
+ it 'executes inherited hook' do
219
+ ModelHookSpecsSubclass.new.an_instance_method
220
+ expect(@hooks).to eq [:inherited_hook]
221
+ end
222
+ end
223
+ end
224
+
225
+ describe 'with a hook declared in the subclasss' do
226
+ supported_by :all do
227
+ before do
228
+ @hooks = hooks = []
229
+ ModelHookSpecsSubclass.after(:an_instance_method) { hooks << :hook }
230
+ end
231
+
232
+ it 'executes hook' do
233
+ ModelHookSpecsSubclass.new.an_instance_method
234
+ expect(@hooks).to eq [:hook]
235
+ end
236
+
237
+ it 'does not alter hooks in the parent class' do
238
+ expect(@hooks).to be_empty
239
+ ModelHookSpecs.new.an_instance_method
240
+ expect(@hooks).to eq []
241
+ end
242
+ end
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,91 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ shared_examples 'a correct property declaration' do
4
+ it 'defines a name accessor' do
5
+ expect(@model).not_to be_method_defined(@property_name)
6
+ subject
7
+ expect(@model).to be_method_defined(@property_name)
8
+ end
9
+
10
+ it 'defines a name= mutator' do
11
+ expect(@model).not_to be_method_defined(:"#{@property_name}=")
12
+ subject
13
+ expect(@model).to be_method_defined(:"#{@property_name}=")
14
+ end
15
+ end
16
+
17
+ describe DataMapper::Model::Property do
18
+ before do
19
+ Object.send(:remove_const, :ModelPropertySpecs) if defined?(ModelPropertySpecs)
20
+ class ::ModelPropertySpecs
21
+ include DataMapper::Resource
22
+
23
+ property :id, Serial
24
+ end
25
+ DataMapper.finalize
26
+ end
27
+
28
+ describe '#property' do
29
+ context 'using default repository' do
30
+ before do
31
+ Object.send(:remove_const, :UserDefault) if defined?(::UserDefault)
32
+
33
+ class ::UserDefault
34
+ include DataMapper::Resource
35
+ property :id, Serial
36
+ end
37
+
38
+ @model = ::UserDefault
39
+ @property_name = :name
40
+ end
41
+
42
+ subject do
43
+ ::UserDefault.property(:name, String)
44
+ end
45
+
46
+ it_behaves_like 'a correct property declaration'
47
+ end
48
+
49
+ context 'using alternate repository' do
50
+ before do
51
+ Object.send(:remove_const, :UserAlternate) if defined?(::UserAlternate)
52
+
53
+ class ::UserAlternate
54
+ include DataMapper::Resource
55
+ property :id, Serial
56
+ repository(:alternate) { property :age, Integer }
57
+ end
58
+
59
+ @model = UserAlternate
60
+ @property_name = :alt_name
61
+ end
62
+
63
+ subject do
64
+ ::UserAlternate.property(:alt_name, String)
65
+ end
66
+
67
+ it_behaves_like 'a correct property declaration'
68
+ end
69
+
70
+ it 'raises an exception if the method exists' do
71
+ expect {
72
+ ModelPropertySpecs.property(:key, String)
73
+ }.to raise_error(ArgumentError,
74
+ '+name+ was :key, which cannot be used as a property name since it collides with an existing method or a query option')
75
+ end
76
+
77
+ it 'raises an exception if the property is boolean and method with question mark already exists' do
78
+ expect {
79
+ ModelPropertySpecs.property(:destroyed, DataMapper::Property::Boolean)
80
+ }.to raise_error(ArgumentError,
81
+ '+name+ was :destroyed, which cannot be used as a property name since it collides with an existing method or a query option')
82
+ end
83
+
84
+ it 'raises an exception if the name is the same as one of the query options' do
85
+ expect {
86
+ ModelPropertySpecs.property(:order, String)
87
+ }.to raise_error(ArgumentError,
88
+ '+name+ was :order, which cannot be used as a property name since it collides with an existing method or a query option')
89
+ end
90
+ end
91
+ end