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,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMapper::Property::Serial do
4
+ before :all do
5
+ @name = :id
6
+ @type = described_class
7
+ @load_as = Integer
8
+ @value = 1
9
+ @other_value = 2
10
+ @invalid_value = 'foo'
11
+ end
12
+
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_integer, :min => 1, :serial => true) }
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMapper::Property::String do
4
+ before :all do
5
+ @name = :name
6
+ @type = described_class
7
+ @load_as = String
8
+ @value = 'value'
9
+ @other_value = 'return value'
10
+ @invalid_value = 1
11
+ end
12
+
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_string, :length => 50) }
21
+ end
22
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMapper::Property::Text do
4
+ before :all do
5
+ @name = :title
6
+ @type = described_class
7
+ @load_as = String
8
+ @value = 'value'
9
+ @other_value = 'return value'
10
+ @invalid_value = 1
11
+ end
12
+
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_string, :length => 65535, :lazy => true) }
21
+ end
22
+
23
+ describe 'migration with an index' do
24
+ supported_by :all do
25
+ before do
26
+ Object.send(:remove_const, :Foo) if Object.const_defined?(:Foo)
27
+ @model = DataMapper::Model.new('Foo') do
28
+ storage_names[:default] = 'anonymous'
29
+
30
+ property :id, DataMapper::Property::Serial
31
+ property :body, DataMapper::Property::Text, :index => true
32
+ end
33
+ end
34
+
35
+ it 'should allow a migration' do
36
+ lambda {
37
+ @model.auto_migrate!
38
+ }.should_not raise_error(DataObjects::SyntaxError)
39
+ end
40
+ end
41
+ end if defined?(DataObjects::SyntaxError)
42
+
43
+ describe 'migration with a unique index' do
44
+ supported_by :all do
45
+ before do
46
+
47
+ Object.send(:remove_const, :Foo) if Object.const_defined?(:Foo)
48
+ @model = DataMapper::Model.new('Foo') do
49
+ storage_names[:default] = 'anonymous'
50
+
51
+ property :id, DataMapper::Property::Serial
52
+ property :body, DataMapper::Property::Text, :unique_index => true
53
+ end
54
+ end
55
+
56
+ it 'should allow a migration' do
57
+ lambda {
58
+ @model.auto_migrate!
59
+ }.should_not raise_error(DataObjects::SyntaxError)
60
+ end
61
+ end
62
+ end if defined?(DataObjects::SyntaxError)
63
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe DataMapper::Property::Time do
4
+ before :all do
5
+ @name = :deleted_at
6
+ @type = described_class
7
+ @load_as = Time
8
+ @value = Time.now
9
+ @other_value = Time.now + 15
10
+ @invalid_value = 1
11
+ end
12
+
13
+ it_should_behave_like 'A public Property'
14
+
15
+ describe '.options' do
16
+ subject { described_class.options }
17
+
18
+ it { should be_kind_of(Hash) }
19
+
20
+ it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_time) }
21
+ end
22
+ end
@@ -0,0 +1,341 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ # instance methods
5
+ describe DataMapper::Property do
6
+
7
+ # define the model prior to supported_by
8
+ before :all do
9
+ class ::Track
10
+ include DataMapper::Resource
11
+
12
+ property :id, Serial
13
+ property :artist, String, :lazy => false, :index => :artist_album
14
+ property :title, String, :field => 'name', :index => true
15
+ property :album, String, :index => :artist_album
16
+ property :musicbrainz_hash, String, :unique => true, :unique_index => true
17
+ end
18
+
19
+ class ::Image
20
+ include DataMapper::Resource
21
+
22
+ property :md5hash, String, :key => true, :length => 32
23
+ property :title, String, :required => true, :unique => true
24
+ property :description, Text, :length => 1..1024, :lazy => [ :detail ]
25
+ property :width, Integer, :lazy => [:dimensions]
26
+ property :height, Integer, :lazy => [:dimensions]
27
+ property :format, String, :default => 'jpeg'
28
+ property :taken_at, Time, :default => proc { Time.now }
29
+ end
30
+ DataMapper.finalize
31
+ end
32
+
33
+ supported_by :all do
34
+ describe '#field' do
35
+ it 'returns @field value if it is present' do
36
+ Track.properties[:title].field.should eql('name')
37
+ end
38
+
39
+ it 'returns field for specific repository when it is present'
40
+
41
+ it 'sets field value using field naming convention on first reference'
42
+ end
43
+
44
+ describe '#default_for' do
45
+ it 'returns default value for non-callables' do
46
+ Image.properties[:format].default_for(Image.new).should == 'jpeg'
47
+ end
48
+
49
+ it 'returns result of a call for callable values' do
50
+ Image.properties[:taken_at].default_for(Image.new).year.should == Time.now.year
51
+ end
52
+ end
53
+
54
+ describe '#eql?' do
55
+ it 'is true for properties with the same model and name' do
56
+ Track.properties[:title].should eql(Track.properties[:title])
57
+ end
58
+
59
+
60
+ it 'is false for properties of different models' do
61
+ Track.properties[:title].should_not eql(Image.properties[:title])
62
+ end
63
+
64
+ it 'is false for properties with different names' do
65
+ Track.properties[:title].should_not eql(Track.properties[:id])
66
+ end
67
+ end
68
+
69
+ describe '#get!' do
70
+ before :all do
71
+ @image = Image.new
72
+
73
+ # now some dark Ruby magic
74
+ @image.instance_variable_set(:@description, 'Is set by magic')
75
+ end
76
+
77
+ it 'gets instance variable value from the resource directly' do
78
+ # if you know a better way to test direct instance variable access,
79
+ # go ahead and make changes to this example
80
+ Image.properties[:description].get!(@image).should == 'Is set by magic'
81
+ end
82
+ end
83
+
84
+ describe '#index' do
85
+ it 'returns true when property has an index' do
86
+ Track.properties[:title].index.should be(true)
87
+ end
88
+
89
+ it 'returns index name when property has a named index' do
90
+ Track.properties[:album].index.should eql(:artist_album)
91
+ end
92
+
93
+ it 'returns false when property has no index' do
94
+ Track.properties[:musicbrainz_hash].index.should be(false)
95
+ end
96
+ end
97
+
98
+ describe '#initialize' do
99
+ describe 'when tracking strategy is explicitly given' do
100
+ it 'uses tracking strategy from options'
101
+ end
102
+ end
103
+
104
+ describe '#inspect' do
105
+ before :all do
106
+ @str = Track.properties[:title].inspect
107
+ end
108
+
109
+ it 'features model name' do
110
+ @str.should =~ /@model=Track/
111
+ end
112
+
113
+ it 'features property name' do
114
+ @str.should =~ /@name=:title/
115
+ end
116
+ end
117
+
118
+ describe '#key?' do
119
+ describe 'returns true when property is a ' do
120
+ it 'serial key' do
121
+ Track.properties[:id].key?.should be(true)
122
+ end
123
+ it 'natural key' do
124
+ Image.properties[:md5hash].key?.should be(true)
125
+ end
126
+ end
127
+
128
+ it 'returns true when property is a part of composite key'
129
+
130
+ it 'returns false when property does not relate to a key' do
131
+ Track.properties[:title].key?.should be(false)
132
+ end
133
+ end
134
+
135
+ describe '#lazy?' do
136
+ it 'returns true when property is lazy loaded' do
137
+ Image.properties[:description].lazy?.should be(true)
138
+ end
139
+
140
+ it 'returns false when property is not lazy loaded' do
141
+ Track.properties[:artist].lazy?.should be(false)
142
+ end
143
+ end
144
+
145
+ describe "#lazy_load_properties" do
146
+ it "returns all lazy properties in the same context" do
147
+ Image.properties[:width].__send__(:lazy_load_properties).should == Image.properties.values_at(:width, :height)
148
+ end
149
+
150
+ it "returns all properties by default" do
151
+ Track.properties[:artist].__send__(:lazy_load_properties).should == Track.properties
152
+ end
153
+ end
154
+
155
+ describe '#length' do
156
+ it 'returns upper bound for Range values' do
157
+ Image.properties[:description].length.should eql(1024)
158
+ end
159
+
160
+ it 'returns value as is for integer values' do
161
+ Image.properties[:md5hash].length.should eql(32)
162
+ end
163
+ end
164
+
165
+ describe '#min' do
166
+ describe 'when :min and :max options not provided to constructor' do
167
+ before do
168
+ @property = Image.property(:integer_with_nil_min, Integer)
169
+ end
170
+
171
+ it 'should be nil' do
172
+ @property.min.should be_nil
173
+ end
174
+ end
175
+
176
+ describe 'when :min option not provided to constructor, but :max is provided' do
177
+ before do
178
+ @property = Image.property(:integer_with_default_min, Integer, :max => 1)
179
+ end
180
+
181
+ it 'should be the default value' do
182
+ @property.min.should == 0
183
+ end
184
+ end
185
+
186
+ describe 'when :min and :max options provided to constructor' do
187
+ before do
188
+ @min = 1
189
+ @property = Image.property(:integer_with_explicit_min, Integer, :min => @min, :max => 2)
190
+ end
191
+
192
+ it 'should be the expected value' do
193
+ @property.min.should == @min
194
+ end
195
+ end
196
+ end
197
+
198
+ describe '#max' do
199
+ describe 'when :min and :max options not provided to constructor' do
200
+ before do
201
+ @property = Image.property(:integer_with_nil_max, Integer)
202
+ end
203
+
204
+ it 'should be nil' do
205
+ @property.max.should be_nil
206
+ end
207
+ end
208
+
209
+ describe 'when :max option not provided to constructor, but :min is provided' do
210
+ before do
211
+ @property = Image.property(:integer_with_default_max, Integer, :min => 1)
212
+ end
213
+
214
+ it 'should be the default value' do
215
+ @property.max.should == 2**31-1
216
+ end
217
+ end
218
+
219
+ describe 'when :min and :max options provided to constructor' do
220
+ before do
221
+ @max = 2
222
+ @property = Image.property(:integer_with_explicit_max, Integer, :min => 1, :max => @max)
223
+ end
224
+
225
+ it 'should be the expected value' do
226
+ @property.max.should == @max
227
+ end
228
+ end
229
+ end
230
+
231
+ describe '#allow_nil?' do
232
+ it 'returns true when property can accept nil as its value' do
233
+ Track.properties[:artist].allow_nil?.should be(true)
234
+ end
235
+
236
+ it 'returns false when property nil value is prohibited for this property' do
237
+ Image.properties[:title].allow_nil?.should be(false)
238
+ end
239
+ end
240
+
241
+ describe '#serial?' do
242
+ it 'returns true when property is serial (auto incrementing)' do
243
+ Track.properties[:id].serial?.should be(true)
244
+ end
245
+
246
+ it 'returns false when property is NOT serial (auto incrementing)' do
247
+ Image.properties[:md5hash].serial?.should be(false)
248
+ end
249
+ end
250
+
251
+ describe '#set' do
252
+ before :all do
253
+ # keep in mind we must run these examples with a
254
+ # saved model instance
255
+ @image = Image.create(
256
+ :md5hash => '5268f0f3f452844c79843e820f998869',
257
+ :title => 'Rome at the sunset',
258
+ :description => 'Just wow'
259
+ )
260
+
261
+ @property = Image.properties[:title]
262
+ end
263
+
264
+ it 'triggers lazy loading for given resource'
265
+
266
+ it 'type casts given value' do
267
+ @property.set(@image, Addressable::URI.parse('http://test.example/'))
268
+ # get a string that has been typecasted using #to_str
269
+ @image.title.should == 'http://test.example/'
270
+ end
271
+
272
+ it 'sets new property value' do
273
+ @property.set(@image, 'Updated value')
274
+ @image.title.should == 'Updated value'
275
+ end
276
+ end
277
+
278
+ describe '#set!' do
279
+ before :all do
280
+ @image = Image.new(:md5hash => '5268f0f3f452844c79843e820f998869',
281
+ :title => 'Rome at the sunset',
282
+ :description => 'Just wow')
283
+
284
+ @property = Image.properties[:title]
285
+ end
286
+
287
+ it 'directly sets instance variable on given resource' do
288
+ @property.set!(@image, 'Set with dark Ruby magic')
289
+ @image.title.should == 'Set with dark Ruby magic'
290
+ end
291
+ end
292
+
293
+ describe '#unique?' do
294
+ it 'is true for fields that explicitly given uniq index' do
295
+ Track.properties[:musicbrainz_hash].unique?.should be(true)
296
+ end
297
+
298
+ it 'is true for serial fields' do
299
+ pending do
300
+ Track.properties[:title].unique?.should be(true)
301
+ end
302
+ end
303
+
304
+ it 'is true for keys' do
305
+ Image.properties[:md5hash].unique?.should be(true)
306
+ end
307
+ end
308
+
309
+ describe '#unique_index' do
310
+ it 'returns true when property has unique index' do
311
+ Track.properties[:musicbrainz_hash].unique_index.should be(true)
312
+ end
313
+
314
+ it 'returns false when property has no unique index' do
315
+ Track.properties[:title].unique_index.should be(false)
316
+ end
317
+
318
+ it 'returns true when property is unique' do
319
+ Image.properties[:title].unique_index.should be(true)
320
+ end
321
+
322
+ it 'returns :key when property is a key' do
323
+ Track.properties[:id].unique_index.should == :key
324
+ end
325
+ end
326
+
327
+ describe "exception on bad property names" do
328
+ it "is raised for 'model'" do
329
+ lambda {
330
+ Track.property :model, String
331
+ }.should raise_error(ArgumentError)
332
+ end
333
+
334
+ it "is raised for 'repository_name'" do
335
+ lambda {
336
+ Track.property :repository_name, String
337
+ }.should raise_error(ArgumentError)
338
+ end
339
+ end
340
+ end
341
+ end # DataMapper::Property