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,30 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe 'AbstractAdapter' do
4
+ before :all do
5
+ @adapter = DataMapper::Adapters::AbstractAdapter.new(:abstract, :foo => 'bar')
6
+ @adapter_class = @adapter.class
7
+ @scheme = DataMapper::Inflector.underscore(DataMapper::Inflector.demodulize(@adapter_class).chomp('Adapter'))
8
+ @adapter_name = "test_#{@scheme}".to_sym
9
+ end
10
+
11
+ describe 'initialization' do
12
+
13
+ describe 'name' do
14
+ it 'has a name' do
15
+ expect(@adapter.name).to eq :abstract
16
+ end
17
+ end
18
+
19
+ it 'sets options' do
20
+ expect(@adapter.options).to eq({foo: 'bar'})
21
+ end
22
+
23
+ it 'sets naming conventions' do
24
+ expect(@adapter.resource_naming_convention).to eq DataMapper::NamingConventions::Resource::UnderscoredAndPluralized
25
+ expect(@adapter.field_naming_convention).to eq DataMapper::NamingConventions::Field::Underscored
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,13 @@
1
+ require_relative '../../spec_helper'
2
+ require 'dm-core/spec/shared/adapter_spec'
3
+
4
+ describe 'Adapter' do
5
+ supported_by :in_memory do
6
+ describe 'DataMapper::Adapters::InMemoryAdapter' do
7
+ let(:adapter) { DataMapper::Spec.adapter }
8
+ let(:repository) { DataMapper.repository(adapter.name) }
9
+
10
+ it_behaves_like 'An Adapter'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,94 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe 'Many to Many Associations' do
4
+ before :all do
5
+ module ::Blog
6
+ class Article
7
+ include DataMapper::Resource
8
+
9
+ property :title, String, :key => true
10
+ property :body, Text, :required => true
11
+
12
+ has n, :without_default_join, 'WithoutDefault'
13
+ has n, :with_default_join, 'WithDefault'
14
+ has n, :with_default_callable_join, 'WithDefaultCallable'
15
+ end
16
+
17
+ class Author
18
+ include DataMapper::Resource
19
+
20
+ property :name, String, :key => true
21
+
22
+ has n, :without_default_join, 'WithoutDefault'
23
+ has n, :with_default_join, 'WithDefault'
24
+ has n, :with_default_callable_join, 'WithDefaultCallable'
25
+
26
+ has n, :without_default, 'Article', :through => :without_default_join, :via => :article
27
+ has n, :with_default, 'Article', :through => :with_default_join, :via => :article
28
+ has n, :with_default_callable, 'Article', :through => :with_default_callable_join, :via => :article
29
+ end
30
+
31
+ class WithoutDefault
32
+ include DataMapper::Resource
33
+
34
+ belongs_to :article, :key => true
35
+ belongs_to :author, :key => true
36
+ end
37
+
38
+ class WithDefault
39
+ include DataMapper::Resource
40
+
41
+ belongs_to :article, :key => true
42
+ belongs_to :author, :key => true
43
+ end
44
+
45
+ class WithDefaultCallable
46
+ include DataMapper::Resource
47
+
48
+ belongs_to :article, :key => true
49
+ belongs_to :author, :key => true
50
+ end
51
+ end
52
+
53
+
54
+ @article_model = Blog::Article
55
+ @author_model = Blog::Author
56
+
57
+ DataMapper.finalize
58
+
59
+ n = @article_model.n
60
+
61
+ @default_value = [ @author_model.new(:name => 'Dan Kubb') ]
62
+ @default_value_callable = [ @author_model.new(:name => 'John Doe') ]
63
+
64
+ @subject_without_default = @article_model.has(n, :without_default, 'Author', :through => :without_default_join, :via => :author)
65
+ @subject_with_default = @article_model.has(n, :with_default, 'Author', :through => :with_default_join, :via => :author, :default => @default_value)
66
+ @subject_with_default_callable = @article_model.has(n, :with_default_callable, 'Author', :through => :with_default_callable_join, :via => :author, :default => lambda { |resource, relationship| @default_value_callable })
67
+
68
+ DataMapper.finalize
69
+ end
70
+
71
+ supported_by :all do
72
+ before :all do
73
+ @no_join = defined?(DataMapper::Adapters::InMemoryAdapter) && @adapter.kind_of?(DataMapper::Adapters::InMemoryAdapter) ||
74
+ defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
75
+ end
76
+
77
+ before do
78
+ pending if @no_join
79
+ end
80
+
81
+ before :all do
82
+ @default_value.each { |resource| resource.save }
83
+ @default_value_callable.each { |resource| resource.save }
84
+ end
85
+
86
+ describe 'acts like a subject' do
87
+ before do
88
+ @resource = @article_model.new(:title => 'DataMapper Rocks!', :body => 'TSIA')
89
+ end
90
+
91
+ it_behaves_like 'A semipublic Subject'
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,63 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe 'Many to One Associations' do
4
+ before :all do
5
+ class ::User
6
+ include DataMapper::Resource
7
+
8
+ property :name, String, :key => true
9
+ property :age, Integer
10
+ property :description, Text
11
+
12
+ has n, :comments
13
+ end
14
+
15
+ class ::Comment
16
+ include DataMapper::Resource
17
+
18
+ property :id, Serial
19
+
20
+ belongs_to :user
21
+ end
22
+
23
+ @user_model = User
24
+ @comment_model = Comment
25
+
26
+ DataMapper.finalize
27
+
28
+ @default_value = @user_model.new(:name => 'dkubb', :age => 34, :description => 'Test')
29
+ @default_value_callable = @user_model.new(:name => 'jdoe', :age => 21, :description => 'Test')
30
+
31
+ @subject_without_default = @user_model.belongs_to(:without_default, @user_model, :required => false, :child_key => [ :without_default_id ])
32
+ @subject_with_default = @user_model.belongs_to(:with_default, @user_model, :required => false, :child_key => [ :with_default_id ], :default => @default_value)
33
+ @subject_with_default_callable = @user_model.belongs_to(:with_default_callable, @user_model, :required => false, :child_key => [ :with_default_callable_id ], :default => lambda { |resource, relationship| @default_value_callable })
34
+
35
+ @default_value.with_default = nil
36
+ @default_value.with_default_callable = nil
37
+
38
+ DataMapper.finalize
39
+ end
40
+
41
+ supported_by :all do
42
+ before :all do
43
+ @default_value.save
44
+ @default_value_callable.save
45
+ end
46
+
47
+ before :all do
48
+ comment = @comment_model.create(:user => { :name => 'dbussink', :age => 25, :description => 'Test' })
49
+
50
+ @user = @comment_model.get(*comment.key).user
51
+ end
52
+
53
+ it_behaves_like 'A semipublic Resource'
54
+
55
+ describe 'acts like a subject' do
56
+ before do
57
+ @resource = @user_model.new(:name => 'A subject')
58
+ end
59
+
60
+ it_behaves_like 'A semipublic Subject'
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,55 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe 'One to Many Associations' do
4
+ before :all do
5
+ module ::Blog
6
+ class Article
7
+ include DataMapper::Resource
8
+
9
+ property :title, String, :key => true
10
+ property :body, Text, :required => true
11
+ end
12
+
13
+ class Author
14
+ include DataMapper::Resource
15
+
16
+ property :name, String, :key => true
17
+
18
+ belongs_to :without_default, 'Article', :child_key => [ :without_default_id ], :required => false
19
+ belongs_to :with_default, 'Article', :child_key => [ :with_default_id ], :required => false
20
+ belongs_to :with_default_callable, 'Article', :child_key => [ :with_default_callable_id ], :required => false
21
+ end
22
+ end
23
+
24
+ @article_model = Blog::Article
25
+ @author_model = Blog::Author
26
+
27
+ DataMapper.finalize
28
+
29
+ n = @article_model.n
30
+
31
+ @default_value = [ @author_model.new(:name => 'Dan Kubb') ]
32
+ @default_value_callable = [ @author_model.new(:name => 'John Doe') ]
33
+
34
+ @subject_without_default = @article_model.has(n, :without_default, @author_model, :child_key => [ :without_default_id ])
35
+ @subject_with_default = @article_model.has(n, :with_default, @author_model, :child_key => [ :with_default_id ], :default => @default_value)
36
+ @subject_with_default_callable = @article_model.has(n, :with_default_callable, @author_model, :child_key => [ :with_default_callable_id ], :default => lambda { |resource, relationship| @default_value_callable })
37
+
38
+ DataMapper.finalize
39
+ end
40
+
41
+ supported_by :all do
42
+ before :all do
43
+ @default_value.each { |resource| resource.save }
44
+ @default_value_callable.each { |resource| resource.save }
45
+ end
46
+
47
+ describe 'acts like a subject' do
48
+ before do
49
+ @resource = @article_model.new(:title => 'DataMapper Rocks!', :body => 'TSIA')
50
+ end
51
+
52
+ it_behaves_like 'A semipublic Subject'
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,53 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe 'One to One Associations' do
4
+ before :all do
5
+ module ::Blog
6
+ class Article
7
+ include DataMapper::Resource
8
+
9
+ property :title, String, :key => true
10
+ property :body, Text, :required => true
11
+ end
12
+
13
+ class Author
14
+ include DataMapper::Resource
15
+
16
+ property :name, String, :key => true
17
+
18
+ belongs_to :without_default, 'Article', :child_key => [ :without_default_id ], :required => false
19
+ belongs_to :with_default, 'Article', :child_key => [ :with_default_id ], :required => false
20
+ belongs_to :with_default_callable, 'Article', :child_key => [ :with_default_callable_id ], :required => false
21
+ end
22
+ end
23
+
24
+ @article_model = Blog::Article
25
+ @author_model = Blog::Author
26
+
27
+ DataMapper.finalize
28
+
29
+ @default_value = @author_model.new(:name => 'Dan Kubb')
30
+ @default_value_callable = @author_model.new(:name => 'John Doe')
31
+
32
+ @subject_without_default = @article_model.has(1, :without_default, @author_model, :child_key => [ :without_default_id ])
33
+ @subject_with_default = @article_model.has(1, :with_default, @author_model, :child_key => [ :with_default_id ], :default => @default_value)
34
+ @subject_with_default_callable = @article_model.has(1, :with_default_callable, @author_model, :child_key => [ :with_default_callable_id ], :default => lambda { |resource, relationship| @default_value_callable })
35
+
36
+ DataMapper.finalize
37
+ end
38
+
39
+ supported_by :all do
40
+ before :all do
41
+ @default_value.save
42
+ @default_value_callable.save
43
+ end
44
+
45
+ describe 'acts like a subject' do
46
+ before do
47
+ @resource = @article_model.new(:title => 'DataMapper Rocks!', :body => 'TSIA')
48
+ end
49
+
50
+ it_behaves_like 'A semipublic Subject'
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,200 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe DataMapper::Associations::Relationship do
4
+ before :all do
5
+ module ::Blog
6
+ class Article
7
+ include DataMapper::Resource
8
+
9
+ property :title, String, :key => true
10
+ end
11
+
12
+ class Comment
13
+ include DataMapper::Resource
14
+
15
+ property :id, Serial
16
+ property :body, Text
17
+ end
18
+ end
19
+
20
+ @article_model = Blog::Article
21
+ @comment_model = Blog::Comment
22
+ end
23
+
24
+ def n
25
+ 1.0/0
26
+ end
27
+
28
+ describe '#inverse' do
29
+ describe 'with matching relationships' do
30
+ before :all do
31
+ @comments_relationship = @article_model.has(n, :comments)
32
+ @article_relationship = @comment_model.belongs_to(:article)
33
+
34
+ # TODO: move this to spec/public/model/relationship_spec.rb
35
+ expect(@comments_relationship.child_repository_name).to be_nil
36
+ expect(@comments_relationship.parent_repository_name).to eq :default
37
+
38
+ # TODO: move this to spec/public/model/relationship_spec.rb
39
+ expect(@article_relationship.child_repository_name).to eq :default
40
+ expect(@article_relationship.parent_repository_name).to be_nil
41
+ DataMapper.finalize
42
+ end
43
+
44
+ it 'returns the inverted relationships' do
45
+ expect(@comments_relationship.inverse).to equal(@article_relationship)
46
+ expect(@article_relationship.inverse).to equal(@comments_relationship)
47
+ end
48
+ end
49
+
50
+ describe 'with matching relationships where the child repository is not nil' do
51
+ before :all do
52
+ @comments_relationship = @article_model.has(n, :comments, :repository => :default)
53
+ @article_relationship = @comment_model.belongs_to(:article)
54
+
55
+ # TODO: move this to spec/public/model/relationship_spec.rb
56
+ expect(@comments_relationship.child_repository_name).to eq :default
57
+ expect(@comments_relationship.parent_repository_name).to eq :default
58
+
59
+ # TODO: move this to spec/public/model/relationship_spec.rb
60
+ expect(@article_relationship.child_repository_name).to eq :default
61
+ expect(@article_relationship.parent_repository_name).to be_nil
62
+ DataMapper.finalize
63
+ end
64
+
65
+ it 'returns the inverted relationships' do
66
+ expect(@comments_relationship.inverse).to equal(@article_relationship)
67
+ expect(@article_relationship.inverse).to equal(@comments_relationship)
68
+ end
69
+ end
70
+
71
+ describe 'with matching relationships where the parent repository is not nil' do
72
+ before :all do
73
+ @comments_relationship = @article_model.has(n, :comments)
74
+ @article_relationship = @comment_model.belongs_to(:article, :repository => :default)
75
+
76
+ # TODO: move this to spec/public/model/relationship_spec.rb
77
+ expect(@comments_relationship.child_repository_name).to be_nil
78
+ expect(@comments_relationship.parent_repository_name).to eq :default
79
+
80
+ # TODO: move this to spec/public/model/relationship_spec.rb
81
+ expect(@article_relationship.child_repository_name).to eq :default
82
+ expect(@article_relationship.parent_repository_name).to eq :default
83
+ DataMapper.finalize
84
+ end
85
+
86
+ it 'returns the inverted relationships' do
87
+ expect(@comments_relationship.inverse).to equal(@article_relationship)
88
+ expect(@article_relationship.inverse).to equal(@comments_relationship)
89
+ end
90
+ end
91
+
92
+ describe 'with no matching relationship', 'from the parent side' do
93
+ before :all do
94
+ # added to force OneToMany::Relationship#inverse to consider the
95
+ # child_key differences
96
+ @comment_model.belongs_to(:other_article, @article_model, :child_key => [ :other_article_id ])
97
+
98
+ @relationship = @article_model.has(n, :comments)
99
+
100
+ @inverse = @relationship.inverse
101
+
102
+ # after Relationship#inverse to ensure no match
103
+ @expected = @comment_model.belongs_to(:article)
104
+ DataMapper.finalize
105
+ end
106
+
107
+ it 'returns a Relationship' do
108
+ expect(@inverse).to be_kind_of(DataMapper::Associations::Relationship)
109
+ end
110
+
111
+ it 'returns an inverted relationship' do
112
+ expect(@inverse).to eq @expected
113
+ end
114
+
115
+ it 'is an anonymous relationship' do
116
+ expect(@inverse).not_to equal(@expected)
117
+ end
118
+
119
+ it 'has a source repository equal to the target repository of the relationship' do
120
+ expect(@inverse.source_repository_name).to eq @relationship.target_repository_name
121
+ end
122
+
123
+ it "has the relationship as it's inverse" do
124
+ expect(@inverse.inverse).to equal(@relationship)
125
+ end
126
+ end
127
+
128
+ describe 'with no matching relationship', 'from the child side' do
129
+ before :all do
130
+ @relationship = @comment_model.belongs_to(:article)
131
+
132
+ @inverse = @relationship.inverse
133
+
134
+ # after Relationship#inverse to ensure no match
135
+ @expected = @article_model.has(n, :comments)
136
+ DataMapper.finalize
137
+ end
138
+
139
+ it 'returns a Relationship' do
140
+ expect(@inverse).to be_kind_of(DataMapper::Associations::Relationship)
141
+ end
142
+
143
+ it 'returns an inverted relationship' do
144
+ expect(@inverse).to eq @expected
145
+ end
146
+
147
+ it 'is an anonymous relationship' do
148
+ expect(@inverse).not_to equal(@expected)
149
+ end
150
+
151
+ it 'has a source repository equal to the target repository of the relationship' do
152
+ expect(@inverse.source_repository_name).to eq @relationship.target_repository_name
153
+ end
154
+
155
+ it "has the relationship as it's inverse" do
156
+ expect(@inverse.inverse).to equal(@relationship)
157
+ end
158
+ end
159
+ end
160
+
161
+ describe '#valid?' do
162
+ before :all do
163
+ @relationship = @article_model.has(n, :comments)
164
+ DataMapper.finalize
165
+ end
166
+
167
+ supported_by :all do
168
+ describe 'with valid resource' do
169
+ before :all do
170
+ @article = @article_model.create(:title => 'Relationships in DataMapper')
171
+ @resource = @article.comments.create
172
+ end
173
+
174
+ it 'returns true' do
175
+ expect(@relationship.valid?(@resource)).to be(true)
176
+ end
177
+ end
178
+
179
+ describe 'with a resource of the wrong class' do
180
+ before :all do
181
+ @resource = @article_model.new
182
+ end
183
+
184
+ it 'returns false' do
185
+ expect(@relationship.valid?(@resource)).to be(false)
186
+ end
187
+ end
188
+
189
+ describe 'with a resource without a valid parent' do
190
+ before :all do
191
+ @resource = @comment_model.new
192
+ end
193
+
194
+ it 'returns false' do
195
+ expect(@relationship.valid?(@resource)).to be(false)
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,177 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMapper::Associations do
4
+ before :all do
5
+ class ::Car
6
+ include DataMapper::Resource
7
+
8
+ property :id, Serial
9
+ end
10
+
11
+ class ::Engine
12
+ include DataMapper::Resource
13
+
14
+ property :id, Serial
15
+ end
16
+
17
+ class ::Door
18
+ include DataMapper::Resource
19
+
20
+ property :id, Serial
21
+ end
22
+
23
+ class ::Window
24
+ include DataMapper::Resource
25
+
26
+ property :id, Serial
27
+ end
28
+ end
29
+
30
+ def n
31
+ 1.0/0
32
+ end
33
+
34
+ describe '#has' do
35
+ describe '1' do
36
+ before :all do
37
+ @relationship = Car.has(1, :engine)
38
+ end
39
+
40
+ it 'returns a Relationship' do
41
+ expect(@relationship).to be_a_kind_of(DataMapper::Associations::OneToOne::Relationship)
42
+ end
43
+
44
+ it 'returns a Relationship with the child model' do
45
+ expect(@relationship.child_model).to eq Engine
46
+ end
47
+
48
+ it 'returns a Relationship with a min of 1' do
49
+ expect(@relationship.min).to eq 1
50
+ end
51
+
52
+ it 'returns a Relationship with a max of 1' do
53
+ expect(@relationship.max).to eq 1
54
+ end
55
+ end
56
+
57
+ describe 'n..n' do
58
+ before :all do
59
+ @relationship = Car.has(1..4, :doors)
60
+ end
61
+
62
+ it 'returns a Relationship' do
63
+ expect(@relationship).to be_a_kind_of(DataMapper::Associations::OneToMany::Relationship)
64
+ end
65
+
66
+ it 'returns a Relationship with the child model' do
67
+ expect(@relationship.child_model).to eq Door
68
+ end
69
+
70
+ it 'returns a Relationship with a min of 1' do
71
+ expect(@relationship.min).to eq 1
72
+ end
73
+
74
+ it 'returns a Relationship with a max of 4' do
75
+ expect(@relationship.max).to eq 4
76
+ end
77
+ end
78
+
79
+ describe 'n..n through' do
80
+ before :all do
81
+ Door.has(1, :window)
82
+ Car.has(1..4, :doors)
83
+
84
+ @relationship = Car.has(1..4, :windows, :through => :doors)
85
+ end
86
+
87
+ it 'returns a Relationship' do
88
+ expect(@relationship).to be_a_kind_of(DataMapper::Associations::ManyToMany::Relationship)
89
+ end
90
+
91
+ it 'returns a Relationship with the child model' do
92
+ expect(@relationship.child_model).to eq Window
93
+ end
94
+
95
+ it 'returns a Relationship with a min of 1' do
96
+ expect(@relationship.min).to eq 1
97
+ end
98
+
99
+ it 'returns a Relationship with a max of 4' do
100
+ expect(@relationship.max).to eq 4
101
+ end
102
+ end
103
+
104
+ describe 'n' do
105
+ before :all do
106
+ @relationship = Car.has(n, :doors)
107
+ end
108
+
109
+ it 'returns a Relationship' do
110
+ expect(@relationship).to be_a_kind_of(DataMapper::Associations::OneToMany::Relationship)
111
+ end
112
+
113
+ it 'returns a Relationship with the child model' do
114
+ expect(@relationship.child_model).to eq Door
115
+ end
116
+
117
+ it 'returns a Relationship with a min of 0' do
118
+ expect(@relationship.min).to eq 0
119
+ end
120
+
121
+ it 'returns a Relationship with a max of n' do
122
+ expect(@relationship.max).to eq n
123
+ end
124
+ end
125
+
126
+ describe 'n through' do
127
+ before :all do
128
+ Door.has(1, :windows)
129
+ Car.has(1..4, :doors)
130
+
131
+ @relationship = Car.has(n, :windows, :through => :doors)
132
+ end
133
+
134
+ it 'returns a Relationship' do
135
+ expect(@relationship).to be_a_kind_of(DataMapper::Associations::ManyToMany::Relationship)
136
+ end
137
+
138
+ it 'returns a Relationship with the child model' do
139
+ expect(@relationship.child_model).to eq Window
140
+ end
141
+
142
+ it 'returns a Relationship with a min of 0' do
143
+ expect(@relationship.min).to eq 0
144
+ end
145
+
146
+ it 'returns a Relationship with a max of n' do
147
+ expect(@relationship.max).to eq n
148
+ end
149
+ end
150
+ end
151
+
152
+ describe '#belongs_to' do
153
+ before :all do
154
+ @relationship = Engine.belongs_to(:car)
155
+ end
156
+
157
+ it 'returns a Relationship' do
158
+ expect(@relationship).to be_a_kind_of(DataMapper::Associations::ManyToOne::Relationship)
159
+ end
160
+
161
+ it 'returns a Relationship with the parent model' do
162
+ expect(@relationship.parent_model).to eq Car
163
+ end
164
+
165
+ it 'returns a Relationship with a min of 1' do
166
+ expect(@relationship.min).to eq 1
167
+ end
168
+
169
+ it 'returns a Relationship with a max of 1' do
170
+ expect(@relationship.max).to eq 1
171
+ end
172
+
173
+ it 'returns a Relationship that is required' do
174
+ expect(@relationship.required?).to be(true)
175
+ end
176
+ end
177
+ end