dm-core 0.10.2 → 1.0.0.rc1

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 (183) hide show
  1. data/.gitignore +10 -1
  2. data/Gemfile +143 -0
  3. data/Rakefile +9 -5
  4. data/VERSION +1 -1
  5. data/dm-core.gemspec +160 -57
  6. data/lib/dm-core.rb +131 -56
  7. data/lib/dm-core/adapters.rb +98 -14
  8. data/lib/dm-core/adapters/abstract_adapter.rb +24 -4
  9. data/lib/dm-core/adapters/in_memory_adapter.rb +7 -2
  10. data/lib/dm-core/associations/many_to_many.rb +19 -30
  11. data/lib/dm-core/associations/many_to_one.rb +58 -42
  12. data/lib/dm-core/associations/one_to_many.rb +33 -23
  13. data/lib/dm-core/associations/one_to_one.rb +27 -11
  14. data/lib/dm-core/associations/relationship.rb +4 -4
  15. data/lib/dm-core/collection.rb +23 -16
  16. data/lib/dm-core/core_ext/array.rb +36 -0
  17. data/lib/dm-core/core_ext/hash.rb +30 -0
  18. data/lib/dm-core/core_ext/module.rb +46 -0
  19. data/lib/dm-core/core_ext/object.rb +31 -0
  20. data/lib/dm-core/core_ext/pathname.rb +20 -0
  21. data/lib/dm-core/core_ext/string.rb +22 -0
  22. data/lib/dm-core/core_ext/try_dup.rb +44 -0
  23. data/lib/dm-core/model.rb +88 -27
  24. data/lib/dm-core/model/hook.rb +75 -18
  25. data/lib/dm-core/model/property.rb +50 -9
  26. data/lib/dm-core/model/relationship.rb +31 -31
  27. data/lib/dm-core/model/scope.rb +3 -3
  28. data/lib/dm-core/property.rb +196 -516
  29. data/lib/dm-core/property/binary.rb +7 -0
  30. data/lib/dm-core/property/boolean.rb +35 -0
  31. data/lib/dm-core/property/class.rb +24 -0
  32. data/lib/dm-core/property/date.rb +47 -0
  33. data/lib/dm-core/property/date_time.rb +48 -0
  34. data/lib/dm-core/property/decimal.rb +43 -0
  35. data/lib/dm-core/property/discriminator.rb +48 -0
  36. data/lib/dm-core/property/float.rb +24 -0
  37. data/lib/dm-core/property/integer.rb +32 -0
  38. data/lib/dm-core/property/numeric.rb +43 -0
  39. data/lib/dm-core/property/object.rb +32 -0
  40. data/lib/dm-core/property/serial.rb +8 -0
  41. data/lib/dm-core/property/string.rb +49 -0
  42. data/lib/dm-core/property/text.rb +12 -0
  43. data/lib/dm-core/property/time.rb +48 -0
  44. data/lib/dm-core/property/typecast/numeric.rb +32 -0
  45. data/lib/dm-core/property/typecast/time.rb +28 -0
  46. data/lib/dm-core/property_set.rb +10 -4
  47. data/lib/dm-core/query.rb +14 -37
  48. data/lib/dm-core/query/conditions/comparison.rb +8 -6
  49. data/lib/dm-core/query/conditions/operation.rb +33 -2
  50. data/lib/dm-core/query/operator.rb +2 -5
  51. data/lib/dm-core/query/path.rb +4 -6
  52. data/lib/dm-core/repository.rb +21 -6
  53. data/lib/dm-core/resource.rb +316 -133
  54. data/lib/dm-core/resource/state.rb +79 -0
  55. data/lib/dm-core/resource/state/clean.rb +40 -0
  56. data/lib/dm-core/resource/state/deleted.rb +30 -0
  57. data/lib/dm-core/resource/state/dirty.rb +86 -0
  58. data/lib/dm-core/resource/state/immutable.rb +34 -0
  59. data/lib/dm-core/resource/state/persisted.rb +29 -0
  60. data/lib/dm-core/resource/state/transient.rb +70 -0
  61. data/lib/dm-core/spec/lib/adapter_helpers.rb +52 -0
  62. data/lib/dm-core/spec/lib/collection_helpers.rb +20 -0
  63. data/{spec → lib/dm-core/spec}/lib/counter_adapter.rb +5 -1
  64. data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
  65. data/lib/dm-core/spec/lib/spec_helper.rb +68 -0
  66. data/lib/dm-core/spec/setup.rb +165 -0
  67. data/lib/dm-core/spec/{adapter_shared_spec.rb → shared/adapter_spec.rb} +21 -7
  68. data/{spec/public/shared/resource_shared_spec.rb → lib/dm-core/spec/shared/resource_spec.rb} +120 -83
  69. data/{spec/public/shared/sel_shared_spec.rb → lib/dm-core/spec/shared/sel_spec.rb} +5 -6
  70. data/lib/dm-core/support/assertions.rb +8 -0
  71. data/lib/dm-core/support/equalizer.rb +1 -0
  72. data/lib/dm-core/support/hook.rb +420 -0
  73. data/lib/dm-core/support/lazy_array.rb +453 -0
  74. data/lib/dm-core/support/local_object_space.rb +12 -0
  75. data/lib/dm-core/support/logger.rb +193 -6
  76. data/lib/dm-core/support/naming_conventions.rb +8 -8
  77. data/lib/dm-core/support/subject.rb +33 -0
  78. data/lib/dm-core/type.rb +4 -0
  79. data/lib/dm-core/types/boolean.rb +2 -0
  80. data/lib/dm-core/types/decimal.rb +9 -0
  81. data/lib/dm-core/types/discriminator.rb +2 -0
  82. data/lib/dm-core/types/object.rb +3 -0
  83. data/lib/dm-core/types/serial.rb +2 -0
  84. data/lib/dm-core/types/text.rb +2 -0
  85. data/lib/dm-core/version.rb +1 -1
  86. data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +67 -0
  87. data/spec/public/model/hook_spec.rb +209 -0
  88. data/spec/public/model/property_spec.rb +35 -0
  89. data/spec/public/model/relationship_spec.rb +33 -20
  90. data/spec/public/model_spec.rb +142 -10
  91. data/spec/public/property/binary_spec.rb +14 -0
  92. data/spec/public/property/boolean_spec.rb +14 -0
  93. data/spec/public/property/class_spec.rb +20 -0
  94. data/spec/public/property/date_spec.rb +14 -0
  95. data/spec/public/property/date_time_spec.rb +14 -0
  96. data/spec/public/property/decimal_spec.rb +14 -0
  97. data/spec/public/{types → property}/discriminator_spec.rb +2 -12
  98. data/spec/public/property/float_spec.rb +14 -0
  99. data/spec/public/property/integer_spec.rb +14 -0
  100. data/spec/public/property/object_spec.rb +9 -17
  101. data/spec/public/property/serial_spec.rb +14 -0
  102. data/spec/public/property/string_spec.rb +14 -0
  103. data/spec/public/property/text_spec.rb +52 -0
  104. data/spec/public/property/time_spec.rb +14 -0
  105. data/spec/public/property_spec.rb +28 -87
  106. data/spec/public/resource_spec.rb +101 -0
  107. data/spec/public/sel_spec.rb +5 -15
  108. data/spec/public/shared/collection_shared_spec.rb +16 -30
  109. data/spec/public/shared/finder_shared_spec.rb +2 -4
  110. data/spec/public/shared/property_shared_spec.rb +176 -0
  111. data/spec/semipublic/adapters/abstract_adapter_spec.rb +1 -1
  112. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +2 -2
  113. data/spec/semipublic/associations/many_to_many_spec.rb +89 -0
  114. data/spec/semipublic/associations/many_to_one_spec.rb +24 -1
  115. data/spec/semipublic/associations/one_to_many_spec.rb +51 -0
  116. data/spec/semipublic/associations/one_to_one_spec.rb +49 -0
  117. data/spec/semipublic/associations/relationship_spec.rb +3 -3
  118. data/spec/semipublic/associations_spec.rb +1 -1
  119. data/spec/semipublic/property/binary_spec.rb +13 -0
  120. data/spec/semipublic/property/boolean_spec.rb +65 -0
  121. data/spec/semipublic/property/class_spec.rb +33 -0
  122. data/spec/semipublic/property/date_spec.rb +43 -0
  123. data/spec/semipublic/property/date_time_spec.rb +46 -0
  124. data/spec/semipublic/property/decimal_spec.rb +82 -0
  125. data/spec/semipublic/property/discriminator_spec.rb +19 -0
  126. data/spec/semipublic/property/float_spec.rb +82 -0
  127. data/spec/semipublic/property/integer_spec.rb +82 -0
  128. data/spec/semipublic/property/serial_spec.rb +13 -0
  129. data/spec/semipublic/property/string_spec.rb +13 -0
  130. data/spec/semipublic/property/text_spec.rb +31 -0
  131. data/spec/semipublic/property/time_spec.rb +50 -0
  132. data/spec/semipublic/property_spec.rb +2 -532
  133. data/spec/semipublic/query/conditions/comparison_spec.rb +171 -169
  134. data/spec/semipublic/query/conditions/operation_spec.rb +53 -51
  135. data/spec/semipublic/query/path_spec.rb +17 -17
  136. data/spec/semipublic/query_spec.rb +47 -78
  137. data/spec/semipublic/resource/state/clean_spec.rb +88 -0
  138. data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
  139. data/spec/semipublic/resource/state/dirty_spec.rb +133 -0
  140. data/spec/semipublic/resource/state/immutable_spec.rb +99 -0
  141. data/spec/semipublic/resource/state/transient_spec.rb +128 -0
  142. data/spec/semipublic/resource/state_spec.rb +226 -0
  143. data/spec/semipublic/shared/property_shared_spec.rb +143 -0
  144. data/spec/semipublic/shared/resource_shared_spec.rb +16 -15
  145. data/spec/semipublic/shared/resource_state_shared_spec.rb +78 -0
  146. data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
  147. data/spec/spec_helper.rb +21 -97
  148. data/spec/support/types/huge_integer.rb +17 -0
  149. data/spec/unit/array_spec.rb +48 -0
  150. data/spec/unit/hash_spec.rb +35 -0
  151. data/spec/unit/hook_spec.rb +1234 -0
  152. data/spec/unit/lazy_array_spec.rb +1959 -0
  153. data/spec/unit/module_spec.rb +70 -0
  154. data/spec/unit/object_spec.rb +37 -0
  155. data/spec/unit/try_dup_spec.rb +45 -0
  156. data/tasks/local_gemfile.rake +18 -0
  157. data/tasks/spec.rake +0 -3
  158. metadata +197 -71
  159. data/deps.rip +0 -2
  160. data/lib/dm-core/adapters/data_objects_adapter.rb +0 -712
  161. data/lib/dm-core/adapters/mysql_adapter.rb +0 -42
  162. data/lib/dm-core/adapters/oracle_adapter.rb +0 -229
  163. data/lib/dm-core/adapters/postgres_adapter.rb +0 -22
  164. data/lib/dm-core/adapters/sqlite3_adapter.rb +0 -17
  165. data/lib/dm-core/adapters/sqlserver_adapter.rb +0 -114
  166. data/lib/dm-core/adapters/yaml_adapter.rb +0 -111
  167. data/lib/dm-core/core_ext/enumerable.rb +0 -28
  168. data/lib/dm-core/migrations.rb +0 -1427
  169. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +0 -366
  170. data/lib/dm-core/transaction.rb +0 -508
  171. data/lib/dm-core/types/paranoid_boolean.rb +0 -42
  172. data/lib/dm-core/types/paranoid_datetime.rb +0 -41
  173. data/spec/lib/adapter_helpers.rb +0 -105
  174. data/spec/lib/collection_helpers.rb +0 -18
  175. data/spec/lib/pending_helpers.rb +0 -46
  176. data/spec/public/migrations_spec.rb +0 -503
  177. data/spec/public/transaction_spec.rb +0 -153
  178. data/spec/semipublic/adapters/mysql_adapter_spec.rb +0 -17
  179. data/spec/semipublic/adapters/oracle_adapter_spec.rb +0 -194
  180. data/spec/semipublic/adapters/postgres_adapter_spec.rb +0 -17
  181. data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +0 -17
  182. data/spec/semipublic/adapters/sqlserver_adapter_spec.rb +0 -17
  183. data/spec/semipublic/adapters/yaml_adapter_spec.rb +0 -12
@@ -0,0 +1,46 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
2
+
3
+ describe DataMapper::Property::DateTime do
4
+ before :all do
5
+ @name = :created_at
6
+ @type = DataMapper::Property::DateTime
7
+ @value = DateTime.now
8
+ @other_value = DateTime.now+15
9
+ @invalid_value = 1
10
+ end
11
+
12
+ it_should_behave_like "A semipublic Property"
13
+
14
+ describe '#typecast_to_primitive' do
15
+ describe 'and value given as a hash with keys like :year, :month, etc' do
16
+ it 'builds a DateTime instance from hash values' do
17
+ result = @property.typecast(
18
+ 'year' => '2006',
19
+ 'month' => '11',
20
+ 'day' => '23',
21
+ 'hour' => '12',
22
+ 'min' => '0',
23
+ 'sec' => '0'
24
+ )
25
+
26
+ result.should be_kind_of(DateTime)
27
+ result.year.should eql(2006)
28
+ result.month.should eql(11)
29
+ result.day.should eql(23)
30
+ result.hour.should eql(12)
31
+ result.min.should eql(0)
32
+ result.sec.should eql(0)
33
+ end
34
+ end
35
+
36
+ describe 'and value is a string' do
37
+ it 'parses the string' do
38
+ @property.typecast('Dec, 2006').month.should == 12
39
+ end
40
+ end
41
+
42
+ it 'does not typecast non-datetime values' do
43
+ @property.typecast('not-datetime').should eql('not-datetime')
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
2
+
3
+ describe DataMapper::Property::Decimal do
4
+ before :all do
5
+ @name = :rate
6
+ @type = DataMapper::Property::Decimal
7
+ @value = BigDecimal('1.0')
8
+ @other_value = BigDecimal('2.0')
9
+ @invalid_value = true
10
+ end
11
+
12
+ it_should_behave_like "A semipublic Property"
13
+
14
+ describe '#typecast_to_primitive' do
15
+ it 'returns same value if a decimal' do
16
+ @value = BigDecimal('24.0')
17
+ @property.typecast(@value).should equal(@value)
18
+ end
19
+
20
+ it 'returns decimal representation of a zero string integer' do
21
+ @property.typecast('0').should eql(BigDecimal('0.0'))
22
+ end
23
+
24
+ it 'returns decimal representation of a positive string integer' do
25
+ @property.typecast('24').should eql(BigDecimal('24.0'))
26
+ end
27
+
28
+ it 'returns decimal representation of a negative string integer' do
29
+ @property.typecast('-24').should eql(BigDecimal('-24.0'))
30
+ end
31
+
32
+ it 'returns decimal representation of a zero string float' do
33
+ @property.typecast('0.0').should eql(BigDecimal('0.0'))
34
+ end
35
+
36
+ it 'returns decimal representation of a positive string float' do
37
+ @property.typecast('24.35').should eql(BigDecimal('24.35'))
38
+ end
39
+
40
+ it 'returns decimal representation of a negative string float' do
41
+ @property.typecast('-24.35').should eql(BigDecimal('-24.35'))
42
+ end
43
+
44
+ it 'returns decimal representation of a zero string float, with no leading digits' do
45
+ @property.typecast('.0').should eql(BigDecimal('0.0'))
46
+ end
47
+
48
+ it 'returns decimal representation of a positive string float, with no leading digits' do
49
+ @property.typecast('.41').should eql(BigDecimal('0.41'))
50
+ end
51
+
52
+ it 'returns decimal representation of a zero integer' do
53
+ @property.typecast(0).should eql(BigDecimal('0.0'))
54
+ end
55
+
56
+ it 'returns decimal representation of a positive integer' do
57
+ @property.typecast(24).should eql(BigDecimal('24.0'))
58
+ end
59
+
60
+ it 'returns decimal representation of a negative integer' do
61
+ @property.typecast(-24).should eql(BigDecimal('-24.0'))
62
+ end
63
+
64
+ it 'returns decimal representation of a zero float' do
65
+ @property.typecast(0.0).should eql(BigDecimal('0.0'))
66
+ end
67
+
68
+ it 'returns decimal representation of a positive float' do
69
+ @property.typecast(24.35).should eql(BigDecimal('24.35'))
70
+ end
71
+
72
+ it 'returns decimal representation of a negative float' do
73
+ @property.typecast(-24.35).should eql(BigDecimal('-24.35'))
74
+ end
75
+
76
+ [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
77
+ it "does not typecast non-numeric value #{value.inspect}" do
78
+ @property.typecast(value).should equal(value)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
2
+
3
+ describe DataMapper::Property::Discriminator do
4
+ before :all do
5
+ Object.send(:remove_const, :Foo) if defined?(Foo)
6
+ Object.send(:remove_const, :Bar) if defined?(Bar)
7
+
8
+ class ::Foo; end
9
+ class ::Bar; end
10
+
11
+ @name = :type
12
+ @type = DataMapper::Property::Discriminator
13
+ @value = Foo
14
+ @other_value = Bar
15
+ @invalid_value = 1
16
+ end
17
+
18
+ it_should_behave_like "A semipublic Property"
19
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
2
+
3
+ describe DataMapper::Property::Float do
4
+ before :all do
5
+ @name = :rating
6
+ @type = DataMapper::Property::Float
7
+ @value = 0.1
8
+ @other_value = 0.2
9
+ @invalid_value = '1'
10
+ end
11
+
12
+ it_should_behave_like "A semipublic Property"
13
+
14
+ describe '#typecast_to_primitive' do
15
+ it 'returns same value if a float' do
16
+ @value = 24.0
17
+ @property.typecast(@value).should equal(@value)
18
+ end
19
+
20
+ it 'returns float representation of a zero string integer' do
21
+ @property.typecast('0').should eql(0.0)
22
+ end
23
+
24
+ it 'returns float representation of a positive string integer' do
25
+ @property.typecast('24').should eql(24.0)
26
+ end
27
+
28
+ it 'returns float representation of a negative string integer' do
29
+ @property.typecast('-24').should eql(-24.0)
30
+ end
31
+
32
+ it 'returns float representation of a zero string float' do
33
+ @property.typecast('0.0').should eql(0.0)
34
+ end
35
+
36
+ it 'returns float representation of a positive string float' do
37
+ @property.typecast('24.35').should eql(24.35)
38
+ end
39
+
40
+ it 'returns float representation of a negative string float' do
41
+ @property.typecast('-24.35').should eql(-24.35)
42
+ end
43
+
44
+ it 'returns float representation of a zero string float, with no leading digits' do
45
+ @property.typecast('.0').should eql(0.0)
46
+ end
47
+
48
+ it 'returns float representation of a positive string float, with no leading digits' do
49
+ @property.typecast('.41').should eql(0.41)
50
+ end
51
+
52
+ it 'returns float representation of a zero integer' do
53
+ @property.typecast(0).should eql(0.0)
54
+ end
55
+
56
+ it 'returns float representation of a positive integer' do
57
+ @property.typecast(24).should eql(24.0)
58
+ end
59
+
60
+ it 'returns float representation of a negative integer' do
61
+ @property.typecast(-24).should eql(-24.0)
62
+ end
63
+
64
+ it 'returns float representation of a zero decimal' do
65
+ @property.typecast(BigDecimal('0.0')).should eql(0.0)
66
+ end
67
+
68
+ it 'returns float representation of a positive decimal' do
69
+ @property.typecast(BigDecimal('24.35')).should eql(24.35)
70
+ end
71
+
72
+ it 'returns float representation of a negative decimal' do
73
+ @property.typecast(BigDecimal('-24.35')).should eql(-24.35)
74
+ end
75
+
76
+ [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
77
+ it "does not typecast non-numeric value #{value.inspect}" do
78
+ @property.typecast(value).should equal(value)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
2
+
3
+ describe DataMapper::Property::Integer do
4
+ before :all do
5
+ @name = :age
6
+ @type = DataMapper::Property::Integer
7
+ @value = 1
8
+ @other_value = 2
9
+ @invalid_value = '1'
10
+ end
11
+
12
+ it_should_behave_like "A semipublic Property"
13
+
14
+ describe '#typecast_to_primitive' do
15
+ it 'returns same value if an integer' do
16
+ @value = 24
17
+ @property.typecast(@value).should equal(@value)
18
+ end
19
+
20
+ it 'returns integer representation of a zero string integer' do
21
+ @property.typecast('0').should eql(0)
22
+ end
23
+
24
+ it 'returns integer representation of a positive string integer' do
25
+ @property.typecast('24').should eql(24)
26
+ end
27
+
28
+ it 'returns integer representation of a negative string integer' do
29
+ @property.typecast('-24').should eql(-24)
30
+ end
31
+
32
+ it 'returns integer representation of a zero string float' do
33
+ @property.typecast('0.0').should eql(0)
34
+ end
35
+
36
+ it 'returns integer representation of a positive string float' do
37
+ @property.typecast('24.35').should eql(24)
38
+ end
39
+
40
+ it 'returns integer representation of a negative string float' do
41
+ @property.typecast('-24.35').should eql(-24)
42
+ end
43
+
44
+ it 'returns integer representation of a zero string float, with no leading digits' do
45
+ @property.typecast('.0').should eql(0)
46
+ end
47
+
48
+ it 'returns integer representation of a positive string float, with no leading digits' do
49
+ @property.typecast('.41').should eql(0)
50
+ end
51
+
52
+ it 'returns integer representation of a zero float' do
53
+ @property.typecast(0.0).should eql(0)
54
+ end
55
+
56
+ it 'returns integer representation of a positive float' do
57
+ @property.typecast(24.35).should eql(24)
58
+ end
59
+
60
+ it 'returns integer representation of a negative float' do
61
+ @property.typecast(-24.35).should eql(-24)
62
+ end
63
+
64
+ it 'returns integer representation of a zero decimal' do
65
+ @property.typecast(BigDecimal('0.0')).should eql(0)
66
+ end
67
+
68
+ it 'returns integer representation of a positive decimal' do
69
+ @property.typecast(BigDecimal('24.35')).should eql(24)
70
+ end
71
+
72
+ it 'returns integer representation of a negative decimal' do
73
+ @property.typecast(BigDecimal('-24.35')).should eql(-24)
74
+ end
75
+
76
+ [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
77
+ it "does not typecast non-numeric value #{value.inspect}" do
78
+ @property.typecast(value).should equal(value)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
2
+
3
+ describe DataMapper::Property::Serial do
4
+ before :all do
5
+ @name = :id
6
+ @type = DataMapper::Property::Serial
7
+ @value = 1
8
+ @other_value = 2
9
+ @invalid_value = 'foo'
10
+ end
11
+
12
+ it_should_behave_like "A semipublic Property"
13
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
2
+
3
+ describe DataMapper::Property::String do
4
+ before :all do
5
+ @name = :name
6
+ @type = DataMapper::Property::String
7
+ @value = 'value'
8
+ @other_value = 'return value'
9
+ @invalid_value = 1
10
+ end
11
+
12
+ it_should_behave_like "A semipublic Property"
13
+ end
@@ -0,0 +1,31 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
2
+
3
+ describe DataMapper::Property::Text do
4
+ before :all do
5
+ @name = :title
6
+ @type = DataMapper::Property::Text
7
+ @value = 'value'
8
+ @other_value = 'return value'
9
+ @invalid_value = 1
10
+ end
11
+
12
+ it_should_behave_like "A semipublic Property"
13
+
14
+ describe '#load' do
15
+ before :all do
16
+ @value = mock('value')
17
+ end
18
+
19
+ subject { @property.load(@value) }
20
+
21
+ before do
22
+ @property = @type.new(@model, @name)
23
+ end
24
+
25
+ it 'should delegate to #type.load' do
26
+ return_value = mock('return value')
27
+ @property.should_receive(:load).with(@value).and_return(return_value)
28
+ should == return_value
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,50 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '../..', 'spec_helper'))
2
+
3
+ describe DataMapper::Property::Time do
4
+ before :all do
5
+ @name = :deleted_at
6
+ @type = DataMapper::Property::Time
7
+ @value = Time.now
8
+ @other_value = Time.now+15
9
+ @invalid_value = 1
10
+ end
11
+
12
+ it_should_behave_like "A semipublic Property"
13
+
14
+ describe '#typecast_to_primitive' do
15
+ describe 'and value given as a hash with keys like :year, :month, etc' do
16
+ it 'builds a Time instance from hash values' do
17
+ result = @property.typecast(
18
+ 'year' => '2006',
19
+ 'month' => '11',
20
+ 'day' => '23',
21
+ 'hour' => '12',
22
+ 'min' => '0',
23
+ 'sec' => '0'
24
+ )
25
+
26
+ result.should be_kind_of(Time)
27
+ result.year.should eql(2006)
28
+ result.month.should eql(11)
29
+ result.day.should eql(23)
30
+ result.hour.should eql(12)
31
+ result.min.should eql(0)
32
+ result.sec.should eql(0)
33
+ end
34
+ end
35
+
36
+ describe 'and value is a string' do
37
+ it 'parses the string' do
38
+ result = @property.typecast('22:24')
39
+ result.hour.should eql(22)
40
+ result.min.should eql(24)
41
+ end
42
+ end
43
+
44
+ it 'does not typecast non-time values' do
45
+ pending_if 'Time#parse is too permissive', RUBY_VERSION <= '1.9.1' do
46
+ @property.typecast('not-time').should eql('not-time')
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,84 +1,5 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
2
 
3
- # class methods
4
- describe DataMapper::Property do
5
- before :all do
6
- module ::Blog
7
- class Article
8
- include DataMapper::Resource
9
-
10
- property :id, Serial
11
- end
12
- end
13
- end
14
-
15
- describe '.new' do
16
- before :all do
17
- @model = Blog::Article
18
- @name = :title
19
- @type = String
20
- end
21
-
22
- describe 'when provided no options' do
23
- before :all do
24
- @property = DataMapper::Property.new(@model, @name, @type)
25
- end
26
-
27
- it 'should return a Property' do
28
- @property.should be_kind_of(DataMapper::Property)
29
- end
30
-
31
- it 'should set the model' do
32
- @property.model.should equal(@model)
33
- end
34
-
35
- it 'should set the type' do
36
- @property.type.should equal(@type)
37
- end
38
-
39
- it 'should set the options to an empty Hash' do
40
- @property.options.should == {}
41
- end
42
- end
43
-
44
- [ :index, :unique_index, :unique, :lazy ].each do |attribute|
45
- [ true, false, :title, [ :title ] ].each do |value|
46
- describe "when provided #{(options = { attribute => value }).inspect}" do
47
- before :all do
48
- @property = DataMapper::Property.new(@model, @name, @type, options)
49
- end
50
-
51
- it 'should return a Property' do
52
- @property.should be_kind_of(DataMapper::Property)
53
- end
54
-
55
- it 'should set the model' do
56
- @property.model.should equal(@model)
57
- end
58
-
59
- it 'should set the type' do
60
- @property.type.should equal(@type)
61
- end
62
-
63
- it "should set the options to #{options.inspect}" do
64
- @property.options.should == options
65
- end
66
- end
67
- end
68
-
69
- [ [], nil ].each do |value|
70
- describe "when provided #{(invalid_options = { attribute => value }).inspect}" do
71
- it 'should raise an exception' do
72
- lambda {
73
- DataMapper::Property.new(@model, @name, @type, invalid_options)
74
- }.should raise_error(ArgumentError, "options[#{attribute.inspect}] must be either true, false, a Symbol or an Array of Symbols")
75
- end
76
- end
77
- end
78
- end
79
- end
80
- end
81
-
82
3
  # instance methods
83
4
  describe DataMapper::Property do
84
5
  before :all do
@@ -89,471 +10,20 @@ describe DataMapper::Property do
89
10
  property :id, Integer, :key => true
90
11
  property :name, String
91
12
  property :rating, Float
92
- property :rate, BigDecimal
13
+ property :rate, Decimal
93
14
  property :type, Class
94
15
  property :alias, String
95
16
  property :active, Boolean
96
17
  property :deleted_at, Time
97
18
  property :created_at, DateTime
98
19
  property :created_on, Date
20
+ property :info, Text
99
21
  end
100
22
  end
101
23
 
102
24
  @model = Blog::Author
103
25
  end
104
26
 
105
- describe '#typecast' do
106
- describe "when type is able to do typecasting on it's own" do
107
- it 'delegates all the work to the type'
108
- end
109
-
110
- describe 'when value is nil' do
111
- it 'returns value unchanged' do
112
- @model.properties[:name].typecast(nil).should be(nil)
113
- end
114
- end
115
-
116
- describe 'when value is a Ruby primitive' do
117
- it 'returns value unchanged' do
118
- @model.properties[:id].typecast([3200, 2400]).should == [3200, 2400]
119
- end
120
- end
121
-
122
- describe 'when type primitive is a String' do
123
- before :all do
124
- @property = @model.properties[:name]
125
- end
126
-
127
- it 'returns same value if a string' do
128
- @value = '1.0'
129
- @property.typecast(@value).should equal(@value)
130
- end
131
- end
132
-
133
- describe 'when type primitive is a Float' do
134
- before :all do
135
- @property = @model.properties[:rating]
136
- end
137
-
138
- it 'returns same value if a float' do
139
- @value = 24.0
140
- @property.typecast(@value).should equal(@value)
141
- end
142
-
143
- it 'returns float representation of a zero string integer' do
144
- @property.typecast('0').should eql(0.0)
145
- end
146
-
147
- it 'returns float representation of a positive string integer' do
148
- @property.typecast('24').should eql(24.0)
149
- end
150
-
151
- it 'returns float representation of a negative string integer' do
152
- @property.typecast('-24').should eql(-24.0)
153
- end
154
-
155
- it 'returns float representation of a zero string float' do
156
- @property.typecast('0.0').should eql(0.0)
157
- end
158
-
159
- it 'returns float representation of a positive string float' do
160
- @property.typecast('24.35').should eql(24.35)
161
- end
162
-
163
- it 'returns float representation of a negative string float' do
164
- @property.typecast('-24.35').should eql(-24.35)
165
- end
166
-
167
- it 'returns float representation of a zero string float, with no leading digits' do
168
- @property.typecast('.0').should eql(0.0)
169
- end
170
-
171
- it 'returns float representation of a positive string float, with no leading digits' do
172
- @property.typecast('.41').should eql(0.41)
173
- end
174
-
175
- it 'returns float representation of a zero integer' do
176
- @property.typecast(0).should eql(0.0)
177
- end
178
-
179
- it 'returns float representation of a positive integer' do
180
- @property.typecast(24).should eql(24.0)
181
- end
182
-
183
- it 'returns float representation of a negative integer' do
184
- @property.typecast(-24).should eql(-24.0)
185
- end
186
-
187
- it 'returns float representation of a zero decimal' do
188
- @property.typecast(BigDecimal('0.0')).should eql(0.0)
189
- end
190
-
191
- it 'returns float representation of a positive decimal' do
192
- @property.typecast(BigDecimal('24.35')).should eql(24.35)
193
- end
194
-
195
- it 'returns float representation of a negative decimal' do
196
- @property.typecast(BigDecimal('-24.35')).should eql(-24.35)
197
- end
198
-
199
- [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
200
- it "does not typecast non-numeric value #{value.inspect}" do
201
- @property.typecast(value).should equal(value)
202
- end
203
- end
204
- end
205
-
206
- describe 'when type primitive is a Integer' do
207
- before :all do
208
- @property = @model.properties[:id]
209
- end
210
-
211
- it 'returns same value if an integer' do
212
- @value = 24
213
- @property.typecast(@value).should equal(@value)
214
- end
215
-
216
- it 'returns integer representation of a zero string integer' do
217
- @property.typecast('0').should eql(0)
218
- end
219
-
220
- it 'returns integer representation of a positive string integer' do
221
- @property.typecast('24').should eql(24)
222
- end
223
-
224
- it 'returns integer representation of a negative string integer' do
225
- @property.typecast('-24').should eql(-24)
226
- end
227
-
228
- it 'returns integer representation of a zero string float' do
229
- @property.typecast('0.0').should eql(0)
230
- end
231
-
232
- it 'returns integer representation of a positive string float' do
233
- @property.typecast('24.35').should eql(24)
234
- end
235
-
236
- it 'returns integer representation of a negative string float' do
237
- @property.typecast('-24.35').should eql(-24)
238
- end
239
-
240
- it 'returns integer representation of a zero string float, with no leading digits' do
241
- @property.typecast('.0').should eql(0)
242
- end
243
-
244
- it 'returns integer representation of a positive string float, with no leading digits' do
245
- @property.typecast('.41').should eql(0)
246
- end
247
-
248
- it 'returns integer representation of a zero float' do
249
- @property.typecast(0.0).should eql(0)
250
- end
251
-
252
- it 'returns integer representation of a positive float' do
253
- @property.typecast(24.35).should eql(24)
254
- end
255
-
256
- it 'returns integer representation of a negative float' do
257
- @property.typecast(-24.35).should eql(-24)
258
- end
259
-
260
- it 'returns integer representation of a zero decimal' do
261
- @property.typecast(BigDecimal('0.0')).should eql(0)
262
- end
263
-
264
- it 'returns integer representation of a positive decimal' do
265
- @property.typecast(BigDecimal('24.35')).should eql(24)
266
- end
267
-
268
- it 'returns integer representation of a negative decimal' do
269
- @property.typecast(BigDecimal('-24.35')).should eql(-24)
270
- end
271
-
272
- [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
273
- it "does not typecast non-numeric value #{value.inspect}" do
274
- @property.typecast(value).should equal(value)
275
- end
276
- end
277
- end
278
-
279
- describe 'when type primitive is a BigDecimal' do
280
- before :all do
281
- @property = @model.properties[:rate]
282
- end
283
-
284
- it 'returns same value if a decimal' do
285
- @value = BigDecimal('24.0')
286
- @property.typecast(@value).should equal(@value)
287
- end
288
-
289
- it 'returns decimal representation of a zero string integer' do
290
- @property.typecast('0').should eql(BigDecimal('0.0'))
291
- end
292
-
293
- it 'returns decimal representation of a positive string integer' do
294
- @property.typecast('24').should eql(BigDecimal('24.0'))
295
- end
296
-
297
- it 'returns decimal representation of a negative string integer' do
298
- @property.typecast('-24').should eql(BigDecimal('-24.0'))
299
- end
300
-
301
- it 'returns decimal representation of a zero string float' do
302
- @property.typecast('0.0').should eql(BigDecimal('0.0'))
303
- end
304
-
305
- it 'returns decimal representation of a positive string float' do
306
- @property.typecast('24.35').should eql(BigDecimal('24.35'))
307
- end
308
-
309
- it 'returns decimal representation of a negative string float' do
310
- @property.typecast('-24.35').should eql(BigDecimal('-24.35'))
311
- end
312
-
313
- it 'returns decimal representation of a zero string float, with no leading digits' do
314
- @property.typecast('.0').should eql(BigDecimal('0.0'))
315
- end
316
-
317
- it 'returns decimal representation of a positive string float, with no leading digits' do
318
- @property.typecast('.41').should eql(BigDecimal('0.41'))
319
- end
320
-
321
- it 'returns decimal representation of a zero integer' do
322
- @property.typecast(0).should eql(BigDecimal('0.0'))
323
- end
324
-
325
- it 'returns decimal representation of a positive integer' do
326
- @property.typecast(24).should eql(BigDecimal('24.0'))
327
- end
328
-
329
- it 'returns decimal representation of a negative integer' do
330
- @property.typecast(-24).should eql(BigDecimal('-24.0'))
331
- end
332
-
333
- it 'returns decimal representation of a zero float' do
334
- @property.typecast(0.0).should eql(BigDecimal('0.0'))
335
- end
336
-
337
- it 'returns decimal representation of a positive float' do
338
- @property.typecast(24.35).should eql(BigDecimal('24.35'))
339
- end
340
-
341
- it 'returns decimal representation of a negative float' do
342
- @property.typecast(-24.35).should eql(BigDecimal('-24.35'))
343
- end
344
-
345
- [ Object.new, true, '00.0', '0.', '-.0', 'string' ].each do |value|
346
- it "does not typecast non-numeric value #{value.inspect}" do
347
- @property.typecast(value).should equal(value)
348
- end
349
- end
350
- end
351
-
352
- describe 'when type primitive is a DateTime' do
353
- before :all do
354
- @property = @model.properties[:created_at]
355
- end
356
-
357
- describe 'and value given as a hash with keys like :year, :month, etc' do
358
- it 'builds a DateTime instance from hash values' do
359
- result = @property.typecast(
360
- 'year' => '2006',
361
- 'month' => '11',
362
- 'day' => '23',
363
- 'hour' => '12',
364
- 'min' => '0',
365
- 'sec' => '0'
366
- )
367
-
368
- result.should be_kind_of(DateTime)
369
- result.year.should eql(2006)
370
- result.month.should eql(11)
371
- result.day.should eql(23)
372
- result.hour.should eql(12)
373
- result.min.should eql(0)
374
- result.sec.should eql(0)
375
- end
376
- end
377
-
378
- describe 'and value is a string' do
379
- it 'parses the string' do
380
- @property.typecast('Dec, 2006').month.should == 12
381
- end
382
- end
383
-
384
- it 'does not typecast non-datetime values' do
385
- @property.typecast('not-datetime').should eql('not-datetime')
386
- end
387
- end
388
-
389
- describe 'when type primitive is a Date' do
390
- before :all do
391
- @property = @model.properties[:created_on]
392
- end
393
-
394
- describe 'and value given as a hash with keys like :year, :month, etc' do
395
- it 'builds a Date instance from hash values' do
396
- result = @property.typecast(
397
- 'year' => '2007',
398
- 'month' => '3',
399
- 'day' => '25'
400
- )
401
-
402
- result.should be_kind_of(Date)
403
- result.year.should eql(2007)
404
- result.month.should eql(3)
405
- result.day.should eql(25)
406
- end
407
- end
408
-
409
- describe 'and value is a string' do
410
- it 'parses the string' do
411
- result = @property.typecast('Dec 20th, 2006')
412
- result.month.should == 12
413
- result.day.should == 20
414
- result.year.should == 2006
415
- end
416
- end
417
-
418
- it 'does not typecast non-date values' do
419
- @property.typecast('not-date').should eql('not-date')
420
- end
421
- end
422
-
423
- describe 'when type primitive is a Time' do
424
- before :all do
425
- @property = @model.properties[:deleted_at]
426
- end
427
-
428
- describe 'and value given as a hash with keys like :year, :month, etc' do
429
- it 'builds a Time instance from hash values' do
430
- result = @property.typecast(
431
- 'year' => '2006',
432
- 'month' => '11',
433
- 'day' => '23',
434
- 'hour' => '12',
435
- 'min' => '0',
436
- 'sec' => '0'
437
- )
438
-
439
- result.should be_kind_of(Time)
440
- result.year.should eql(2006)
441
- result.month.should eql(11)
442
- result.day.should eql(23)
443
- result.hour.should eql(12)
444
- result.min.should eql(0)
445
- result.sec.should eql(0)
446
- end
447
- end
448
-
449
- describe 'and value is a string' do
450
- it 'parses the string' do
451
- result = @property.typecast('22:24')
452
- result.hour.should eql(22)
453
- result.min.should eql(24)
454
- end
455
- end
456
-
457
- it 'does not typecast non-time values' do
458
- pending_if 'Time#parse is too permissive', RUBY_VERSION <= '1.9.1' do
459
- @property.typecast('not-time').should eql('not-time')
460
- end
461
- end
462
- end
463
-
464
- describe 'when type primitive is a Class' do
465
- before :all do
466
- @property = @model.properties[:type]
467
- end
468
-
469
- it 'returns same value if a class' do
470
- @property.typecast(@model).should equal(@model)
471
- end
472
-
473
- it 'returns the class if found' do
474
- @property.typecast(@model.name).should eql(@model)
475
- end
476
-
477
- it 'does not typecast non-class values' do
478
- @property.typecast('NoClass').should eql('NoClass')
479
- end
480
- end
481
-
482
- describe 'when type primitive is a Boolean' do
483
- before :all do
484
- @property = @model.properties[:active]
485
- end
486
-
487
- [ true, 'true', 'TRUE', '1', 1, 't', 'T' ].each do |value|
488
- it "returns true when value is #{value.inspect}" do
489
- @property.typecast(value).should be_true
490
- end
491
- end
492
-
493
- [ false, 'false', 'FALSE', '0', 0, 'f', 'F' ].each do |value|
494
- it "returns false when value is #{value.inspect}" do
495
- @property.typecast(value).should be_false
496
- end
497
- end
498
-
499
- [ 'string', 2, 1.0, BigDecimal('1.0'), DateTime.now, Time.now, Date.today, Class, Object.new, ].each do |value|
500
- it "does not typecast value #{value.inspect}" do
501
- @property.typecast(value).should equal(value)
502
- end
503
- end
504
- end
505
- end
506
-
507
- describe '#valid?' do
508
- describe 'when provided a valid value' do
509
- it 'should return true' do
510
- @model.properties[:name].valid?('Dan Kubb').should be_true
511
- end
512
- end
513
-
514
- describe 'when provide an invalid value' do
515
- it 'should return false' do
516
- @model.properties[:name].valid?(1).should be_false
517
- end
518
- end
519
-
520
- describe 'when provide a nil value when required' do
521
- it 'should return false' do
522
- @model.properties[:id].valid?(nil).should be_false
523
- end
524
- end
525
-
526
- describe 'when provide a nil value when not required' do
527
- it 'should return false' do
528
- @model.properties[:alias].valid?(nil).should be_true
529
- end
530
- end
531
-
532
- describe 'when type primitive is a Boolean' do
533
- before do
534
- @property = @model.properties[:active]
535
- end
536
-
537
- [ true, false ].each do |value|
538
- it "returns true when value is #{value.inspect}" do
539
- @property.valid?(value).should be_true
540
- end
541
- end
542
-
543
- [ 'true', 'TRUE', '1', 1, 't', 'T', 'false', 'FALSE', '0', 0, 'f', 'F' ].each do |value|
544
- it "returns false for #{value.inspect}" do
545
- @property.valid?(value).should be_false
546
- end
547
- end
548
- end
549
- end
550
-
551
- describe '#value' do
552
- it 'returns value for core types'
553
-
554
- it 'triggers dump operation for custom types'
555
- end
556
-
557
27
  describe 'override property definition in other repository' do
558
28
  before(:all) do
559
29
  module ::Blog