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,288 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMapper::Resource do
4
+ before :all do
5
+ module ::Blog
6
+ class User
7
+ include DataMapper::Resource
8
+
9
+ property :name, String, :key => true
10
+ property :age, Integer
11
+ property :summary, Text
12
+ property :description, Text
13
+ property :admin, Boolean, :accessor => :private
14
+
15
+ belongs_to :parent, self, :required => false
16
+ has n, :children, self, :inverse => :parent
17
+
18
+ belongs_to :referrer, self, :required => false
19
+ has n, :comments
20
+
21
+ # FIXME: figure out a different approach than stubbing things out
22
+ def comment=(*)
23
+ # do nothing with comment
24
+ end
25
+ end
26
+
27
+ class Author < User; end
28
+
29
+ class Comment
30
+ include DataMapper::Resource
31
+
32
+ property :id, Serial
33
+ property :body, Text
34
+
35
+ belongs_to :user
36
+ end
37
+
38
+ class Article
39
+ include DataMapper::Resource
40
+
41
+ property :id, Serial
42
+ property :body, Text
43
+
44
+ has n, :paragraphs
45
+ end
46
+
47
+ class Paragraph
48
+ include DataMapper::Resource
49
+
50
+ property :id, Serial
51
+ property :text, String
52
+
53
+ belongs_to :article
54
+ end
55
+ end
56
+
57
+ class ::Default
58
+ include DataMapper::Resource
59
+
60
+ property :name, String, :key => true, :default => 'a default value'
61
+ end
62
+ DataMapper.finalize
63
+
64
+ @user_model = Blog::User
65
+ @author_model = Blog::Author
66
+ @comment_model = Blog::Comment
67
+ @article_model = Blog::Article
68
+ @paragraph_model = Blog::Paragraph
69
+ end
70
+
71
+ supported_by :all do
72
+ before :all do
73
+ user = @user_model.create(:name => 'dbussink', :age => 25, :description => 'Test')
74
+
75
+ @user = @user_model.get(*user.key)
76
+ end
77
+
78
+ it_should_behave_like 'A public Resource'
79
+ it_should_behave_like 'A Resource supporting Strategic Eager Loading'
80
+
81
+ it 'A resource should respond to raise_on_save_failure' do
82
+ @user.should respond_to(:raise_on_save_failure)
83
+ end
84
+
85
+ describe '#raise_on_save_failure' do
86
+ after do
87
+ # reset to the default value
88
+ reset_raise_on_save_failure(@user_model)
89
+ reset_raise_on_save_failure(@user)
90
+ end
91
+
92
+ subject { @user.raise_on_save_failure }
93
+
94
+ describe 'when model.raise_on_save_failure has not been set' do
95
+ it { should be(false) }
96
+ end
97
+
98
+ describe 'when model.raise_on_save_failure has been set to true' do
99
+ before do
100
+ @user_model.raise_on_save_failure = true
101
+ end
102
+
103
+ it { should be(true) }
104
+ end
105
+
106
+ describe 'when resource.raise_on_save_failure has been set to true' do
107
+ before do
108
+ @user.raise_on_save_failure = true
109
+ end
110
+
111
+ it { should be(true) }
112
+ end
113
+ end
114
+
115
+ it 'A model should respond to raise_on_save_failure=' do
116
+ @user_model.should respond_to(:raise_on_save_failure=)
117
+ end
118
+
119
+ describe '#raise_on_save_failure=' do
120
+ after do
121
+ # reset to the default value
122
+ @user_model.raise_on_save_failure = false
123
+ end
124
+
125
+ subject { @user_model.raise_on_save_failure = @value }
126
+
127
+ describe 'with a true value' do
128
+ before do
129
+ @value = true
130
+ end
131
+
132
+ it { should be(true) }
133
+
134
+ it 'should set raise_on_save_failure' do
135
+ method(:subject).should change {
136
+ @user_model.raise_on_save_failure
137
+ }.from(false).to(true)
138
+ end
139
+ end
140
+
141
+ describe 'with a false value' do
142
+ before do
143
+ @value = false
144
+ end
145
+
146
+ it { should be(false) }
147
+
148
+ it 'should set raise_on_save_failure' do
149
+ method(:subject).should_not change {
150
+ @user_model.raise_on_save_failure
151
+ }
152
+ end
153
+ end
154
+ end
155
+
156
+ [ :save, :save! ].each do |method|
157
+ describe "##{method}" do
158
+ subject { @user.__send__(method) }
159
+
160
+ describe 'when raise_on_save_failure is true' do
161
+ before do
162
+ @user.raise_on_save_failure = true
163
+ end
164
+
165
+ describe 'and it is a savable resource' do
166
+ it { should be(true) }
167
+ end
168
+
169
+ # FIXME: We cannot trigger a failing save with invalid properties anymore.
170
+ # Invalid properties will result in their own exception.
171
+ # So Im mocking here, but a better approach is needed.
172
+
173
+ describe 'and it is an invalid resource' do
174
+ before do
175
+ @user.should_receive(:save_self).and_return(false)
176
+ end
177
+
178
+ it 'should raise an exception' do
179
+ method(:subject).should raise_error(DataMapper::SaveFailureError, "Blog::User##{method} returned false, Blog::User was not saved") { |error|
180
+ error.resource.should equal(@user)
181
+ }
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ [ :update, :update! ].each do |method|
189
+ describe 'with attributes where one is a foreign key' do
190
+ before :all do
191
+ rescue_if @skip do
192
+ @dkubb = @user.referrer = @user_model.create(:name => 'dkubb', :age => 33)
193
+ @user.save
194
+ @user = @user_model.get(*@user.key)
195
+ @user.referrer.should == @dkubb
196
+
197
+ @solnic = @user_model.create(:name => 'solnic', :age => 28)
198
+
199
+ @attributes = {}
200
+
201
+ relationship = @user_model.relationships[:referrer]
202
+ relationship.child_key.to_a.each_with_index do |k, i|
203
+ @attributes[k.name] = relationship.parent_key.to_a[i].get(@solnic)
204
+ end
205
+
206
+ @return = @user.__send__(method, @attributes)
207
+ end
208
+ end
209
+
210
+ it 'should return true' do
211
+ @return.should be(true)
212
+ end
213
+
214
+ it 'should update attributes of Resource' do
215
+ @attributes.each { |key, value| @user.__send__(key).should == value }
216
+ end
217
+
218
+ it 'should persist the changes' do
219
+ resource = @user_model.get(*@user.key)
220
+ @attributes.each { |key, value| resource.__send__(key).should == value }
221
+ end
222
+
223
+ it 'should return correct parent' do
224
+ resource = @user_model.get(*@user.key)
225
+ resource.referrer.should == @solnic
226
+ end
227
+ end
228
+ end
229
+
230
+ describe '#attribute_get' do
231
+ subject { object.attribute_get(name) }
232
+
233
+ let(:object) { @user }
234
+
235
+ context 'with a known property' do
236
+ let(:name) { :name }
237
+
238
+ it 'returns the attribute value' do
239
+ should == 'dbussink'
240
+ end
241
+ end
242
+
243
+ context 'with an unknown property' do
244
+ let(:name) { :unknown }
245
+
246
+ it 'returns nil' do
247
+ should be_nil
248
+ end
249
+ end
250
+ end
251
+
252
+ describe '#attribute_set' do
253
+ subject { object.attribute_set(name, value) }
254
+
255
+ let(:object) { @user.dup }
256
+
257
+ context 'with a known property' do
258
+ let(:name) { :name }
259
+ let(:value) { 'dkubb' }
260
+
261
+ it 'sets the attribute' do
262
+ expect { subject }.to change { object.name }.
263
+ from('dbussink').
264
+ to('dkubb')
265
+ end
266
+
267
+ it 'makes the object dirty' do
268
+ expect { subject }.to change { object.dirty? }.
269
+ from(false).
270
+ to(true)
271
+ end
272
+ end
273
+
274
+ context 'with an unknown property' do
275
+ let(:name) { :unknown }
276
+ let(:value) { mock('Unknown Value') }
277
+
278
+ it 'does not set the attribute' do
279
+ expect { subject }.to_not change { object.attributes.dup }
280
+ end
281
+
282
+ it 'does not make the object dirty' do
283
+ expect { subject }.to_not change { object.dirty? }
284
+ end
285
+ end
286
+ end
287
+ end
288
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'SEL', 'with STI subclasses' do
4
+ before :all do
5
+ module ::Blog
6
+ class Author
7
+ include DataMapper::Resource
8
+
9
+ property :id, Serial
10
+ property :name, String
11
+
12
+ has n, :messages
13
+ end
14
+
15
+ class Message
16
+ include DataMapper::Resource
17
+
18
+ property :id, Serial
19
+ property :type, Discriminator
20
+ property :title, String, :required => true
21
+
22
+ belongs_to :author
23
+ end
24
+
25
+ class Article < Message; end
26
+ class Comment < Message; end
27
+ end
28
+
29
+ DataMapper.finalize
30
+
31
+ @author_model = Blog::Author
32
+ @message_model = Blog::Message
33
+ @article_model = Blog::Article
34
+ @comment_model = Blog::Comment
35
+ end
36
+
37
+ supported_by :all do
38
+ before :all do
39
+ author1 = @author_model.create(:name => 'Dan Kubb')
40
+ author2 = @author_model.create(:name => 'Sindre Aarsaether')
41
+
42
+ @article_model.create(:title => 'SEL', :author => author1)
43
+ @article_model.create(:title => 'STI', :author => author1)
44
+ @comment_model.create(:title => 'SEL and STI error', :author => author2)
45
+ end
46
+
47
+ it 'should allow STI loading of mixed relationships' do
48
+ lambda {
49
+ @message_model.all.each { |message| message.author }
50
+ }.should_not raise_error(ArgumentError)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,145 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMapper do
4
+ describe '.setup' do
5
+ describe 'using connection string' do
6
+ before :all do
7
+ @return = DataMapper.setup(:setup_test, 'in_memory://user:pass@hostname:1234/path?foo=bar&baz=foo#fragment')
8
+
9
+ @options = @return.options
10
+ end
11
+
12
+ after :all do
13
+ DataMapper::Repository.adapters.delete(@return.name)
14
+ end
15
+
16
+ it 'should return an Adapter' do
17
+ @return.should be_kind_of(DataMapper::Adapters::AbstractAdapter)
18
+ end
19
+
20
+ it 'should set up the repository' do
21
+ DataMapper.repository(:setup_test).adapter.should equal(@return)
22
+ end
23
+
24
+ {
25
+ :adapter => 'in_memory',
26
+ :user => 'user',
27
+ :password => 'pass',
28
+ :host => 'hostname',
29
+ :port => 1234,
30
+ :path => '/path',
31
+ :fragment => 'fragment'
32
+ }.each do |key, val|
33
+ it "should extract the #{key.inspect} option from the uri" do
34
+ @options[key].should == val
35
+ end
36
+ end
37
+
38
+ it 'should alias the scheme of the uri as the adapter' do
39
+ @options[:scheme].should == @options[:adapter]
40
+ end
41
+
42
+ it 'should leave the query param intact' do
43
+ @options[:query].should == 'foo=bar&baz=foo'
44
+ end
45
+
46
+ it 'should extract the query param as top-level options' do
47
+ @options[:foo].should == 'bar'
48
+ @options[:baz].should == 'foo'
49
+ end
50
+ end
51
+
52
+ describe 'using options' do
53
+ before :all do
54
+ @return = DataMapper.setup(:setup_test, :adapter => :in_memory, :foo => 'bar')
55
+
56
+ @options = @return.options
57
+ end
58
+
59
+ after :all do
60
+ DataMapper::Repository.adapters.delete(@return.name)
61
+ end
62
+
63
+ it 'should return an Adapter' do
64
+ @return.should be_kind_of(DataMapper::Adapters::AbstractAdapter)
65
+ end
66
+
67
+ it 'should set up the repository' do
68
+ DataMapper.repository(:setup_test).adapter.should equal(@return)
69
+ end
70
+
71
+ {
72
+ :adapter => :in_memory,
73
+ :foo => 'bar'
74
+ }.each do |key, val|
75
+ it "should set the #{key.inspect} option" do
76
+ @options[key].should == val
77
+ end
78
+ end
79
+ end
80
+
81
+ describe 'using invalid options' do
82
+ it 'should raise an exception' do
83
+ lambda {
84
+ DataMapper.setup(:setup_test, :invalid)
85
+ }.should raise_error(ArgumentError, '+options+ should be Hash or Addressable::URI or String, but was Symbol')
86
+ end
87
+ end
88
+
89
+ describe 'using an instance of an adapter' do
90
+ before :all do
91
+ @adapter = DataMapper::Adapters::InMemoryAdapter.new(:setup_test)
92
+
93
+ @return = DataMapper.setup(@adapter)
94
+ end
95
+
96
+ after :all do
97
+ DataMapper::Repository.adapters.delete(@return.name)
98
+ end
99
+
100
+ it 'should return an Adapter' do
101
+ @return.should be_kind_of(DataMapper::Adapters::AbstractAdapter)
102
+ end
103
+
104
+ it 'should set up the repository' do
105
+ DataMapper.repository(:setup_test).adapter.should equal(@return)
106
+ end
107
+
108
+ it 'should use the adapter given' do
109
+ @return.should == @adapter
110
+ end
111
+
112
+ it 'should use the name given to the adapter' do
113
+ @return.name.should == @adapter.name
114
+ end
115
+ end
116
+
117
+ supported_by :postgres, :mysql, :sqlite3, :sqlserver do
118
+ { :path => :database, :user => :username }.each do |original_key, new_key|
119
+ describe "using #{new_key.inspect} option" do
120
+ before :all do
121
+ @return = DataMapper.setup(:setup_test, :adapter => @adapter.options[:adapter], new_key => @adapter.options[original_key])
122
+
123
+ @options = @return.options
124
+ end
125
+
126
+ after :all do
127
+ DataMapper::Repository.adapters.delete(@return.name)
128
+ end
129
+
130
+ it 'should return an Adapter' do
131
+ @return.should be_kind_of(DataMapper::Adapters::AbstractAdapter)
132
+ end
133
+
134
+ it 'should set up the repository' do
135
+ DataMapper.repository(:setup_test).adapter.should equal(@return)
136
+ end
137
+
138
+ it "should set the #{new_key.inspect} option" do
139
+ @options[new_key].should == @adapter.options[original_key]
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end