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
@@ -76,5 +76,106 @@ describe DataMapper::Resource do
76
76
 
77
77
  it_should_behave_like 'A public Resource'
78
78
  it_should_behave_like 'A Resource supporting Strategic Eager Loading'
79
+
80
+ it 'A resource should respond to raise_on_save_failure' do
81
+ @user.should respond_to(:raise_on_save_failure)
82
+ end
83
+
84
+ describe '#raise_on_save_failure' do
85
+ after do
86
+ # reset to the default value
87
+ reset_raise_on_save_failure(@user_model)
88
+ reset_raise_on_save_failure(@user)
89
+ end
90
+
91
+ subject { @user.raise_on_save_failure }
92
+
93
+ describe 'when model.raise_on_save_failure has not been set' do
94
+ it { should be(false) }
95
+ end
96
+
97
+ describe 'when model.raise_on_save_failure has been set to true' do
98
+ before do
99
+ @user_model.raise_on_save_failure = true
100
+ end
101
+
102
+ it { should be(true) }
103
+ end
104
+
105
+ describe 'when resource.raise_on_save_failure has been set to true' do
106
+ before do
107
+ @user.raise_on_save_failure = true
108
+ end
109
+
110
+ it { should be(true) }
111
+ end
112
+ end
113
+
114
+ it 'A model should respond to raise_on_save_failure=' do
115
+ @user_model.should respond_to(:raise_on_save_failure=)
116
+ end
117
+
118
+ describe '#raise_on_save_failure=' do
119
+ after do
120
+ # reset to the default value
121
+ @user_model.raise_on_save_failure = false
122
+ end
123
+
124
+ subject { @user_model.raise_on_save_failure = @value }
125
+
126
+ describe 'with a true value' do
127
+ before do
128
+ @value = true
129
+ end
130
+
131
+ it { should be(true) }
132
+
133
+ it 'should set raise_on_save_failure' do
134
+ method(:subject).should change {
135
+ @user_model.raise_on_save_failure
136
+ }.from(false).to(true)
137
+ end
138
+ end
139
+
140
+ describe 'with a false value' do
141
+ before do
142
+ @value = false
143
+ end
144
+
145
+ it { should be(false) }
146
+
147
+ it 'should set raise_on_save_failure' do
148
+ method(:subject).should_not change {
149
+ @user_model.raise_on_save_failure
150
+ }
151
+ end
152
+ end
153
+ end
154
+
155
+ [ :save, :save! ].each do |method|
156
+ describe "##{method}" do
157
+ subject { @user.__send__(method) }
158
+
159
+ describe 'when raise_on_save_failure is true' do
160
+ before do
161
+ @user.raise_on_save_failure = true
162
+ end
163
+
164
+ describe 'and it is a savable resource' do
165
+ it { should be(true) }
166
+ end
167
+
168
+ describe 'and it is an invalid resource' do
169
+ before do
170
+ @user.name = nil # name is required
171
+ end
172
+
173
+ it 'should raise an exception' do
174
+ method(:subject).should raise_error(DataMapper::SaveFailureError, "Blog::User##{method} returned false, Blog::User was not saved")
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
79
180
  end
80
181
  end
@@ -34,22 +34,12 @@ describe 'SEL', 'with STI subclasses' do
34
34
 
35
35
  supported_by :all do
36
36
  before :all do
37
- @skip = defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
38
- end
39
-
40
- before :all do
41
- rescue_if 'TODO: fix YAML serialization/deserialization', @skip do
42
- author1 = @author_model.create(:name => 'Dan Kubb')
43
- author2 = @author_model.create(:name => 'Sindre Aarsaether')
44
-
45
- @article_model.create(:title => 'SEL', :author => author1)
46
- @article_model.create(:title => 'STI', :author => author1)
47
- @comment_model.create(:title => 'SEL and STI error', :author => author2)
48
- end
49
- end
37
+ author1 = @author_model.create(:name => 'Dan Kubb')
38
+ author2 = @author_model.create(:name => 'Sindre Aarsaether')
50
39
 
51
- before do
52
- pending if @skip
40
+ @article_model.create(:title => 'SEL', :author => author1)
41
+ @article_model.create(:title => 'STI', :author => author1)
42
+ @comment_model.create(:title => 'SEL and STI error', :author => author2)
53
43
  end
54
44
 
55
45
  it 'should allow STI loading of mixed relationships' do
@@ -51,13 +51,13 @@ share_examples_for 'A public Collection' do
51
51
  describe '#blank?' do
52
52
  describe 'when the collection is empty' do
53
53
  it 'should be true' do
54
- @articles.clear.blank?.should be_true
54
+ @articles.clear.blank?.should be(true)
55
55
  end
56
56
  end
57
57
 
58
58
  describe 'when the collection is not empty' do
59
59
  it 'should be false' do
60
- @articles.blank?.should be_false
60
+ @articles.blank?.should be(false)
61
61
  end
62
62
  end
63
63
  end
@@ -67,7 +67,7 @@ share_examples_for 'A public Collection' do
67
67
  describe '#clean?' do
68
68
  describe 'with all clean resources in the collection' do
69
69
  it 'should return true' do
70
- @articles.clean?.should be_true
70
+ @articles.clean?.should be(true)
71
71
  end
72
72
  end
73
73
 
@@ -77,7 +77,7 @@ share_examples_for 'A public Collection' do
77
77
  end
78
78
 
79
79
  it 'should return true' do
80
- @articles.clean?.should be_false
80
+ @articles.clean?.should be(false)
81
81
  end
82
82
  end
83
83
  end
@@ -422,7 +422,7 @@ share_examples_for 'A public Collection' do
422
422
  end
423
423
 
424
424
  it 'should return true' do
425
- @return.should be_true
425
+ @return.should be(true)
426
426
  end
427
427
 
428
428
  it 'should remove the Resources from the datasource' do
@@ -443,7 +443,7 @@ share_examples_for 'A public Collection' do
443
443
  end
444
444
 
445
445
  it 'should return true' do
446
- @return.should be_true
446
+ @return.should be(true)
447
447
  end
448
448
 
449
449
  it 'should remove the Resources from the datasource' do
@@ -466,7 +466,7 @@ share_examples_for 'A public Collection' do
466
466
  describe '#dirty?' do
467
467
  describe 'with all clean resources in the collection' do
468
468
  it 'should return false' do
469
- @articles.dirty?.should be_false
469
+ @articles.dirty?.should be(false)
470
470
  end
471
471
  end
472
472
 
@@ -476,7 +476,7 @@ share_examples_for 'A public Collection' do
476
476
  end
477
477
 
478
478
  it 'should return true' do
479
- @articles.dirty?.should be_true
479
+ @articles.dirty?.should be(true)
480
480
  end
481
481
  end
482
482
  end
@@ -874,7 +874,7 @@ share_examples_for 'A public Collection' do
874
874
 
875
875
  [ :id, :content, :title ].each do |attribute|
876
876
  it "should have query field #{attribute.inspect} loaded" do
877
- @collection.each { |resource| resource.attribute_loaded?(attribute).should be_true }
877
+ @collection.each { |resource| resource.attribute_loaded?(attribute).should be(true) }
878
878
  end
879
879
  end
880
880
  end
@@ -906,7 +906,7 @@ share_examples_for 'A public Collection' do
906
906
 
907
907
  [ :id, :content, :title ].each do |attribute|
908
908
  it "should have query field #{attribute.inspect} loaded" do
909
- @collection.each { |resource| resource.attribute_loaded?(attribute).should be_true }
909
+ @collection.each { |resource| resource.attribute_loaded?(attribute).should be(true) }
910
910
  end
911
911
  end
912
912
  end
@@ -1004,7 +1004,7 @@ share_examples_for 'A public Collection' do
1004
1004
  end
1005
1005
 
1006
1006
  it 'should return true' do
1007
- @return.should be_true
1007
+ @return.should be(true)
1008
1008
  end
1009
1009
 
1010
1010
  it 'should save each Resource' do
@@ -1021,7 +1021,7 @@ share_examples_for 'A public Collection' do
1021
1021
  end
1022
1022
 
1023
1023
  it 'should return true' do
1024
- @return.should be_true
1024
+ @return.should be(true)
1025
1025
  end
1026
1026
  end
1027
1027
  end
@@ -1572,20 +1572,6 @@ share_examples_for 'A public Collection' do
1572
1572
  it { should respond_to(method) }
1573
1573
 
1574
1574
  describe "##{method}" do
1575
- describe 'with no arguments' do
1576
- before :all do
1577
- @return = @articles.send(method)
1578
- end
1579
-
1580
- if method == :update!
1581
- should_not_be_a_kicker
1582
- end
1583
-
1584
- it 'should return true' do
1585
- @return.should be_true
1586
- end
1587
- end
1588
-
1589
1575
  describe 'with attributes' do
1590
1576
  before :all do
1591
1577
  @attributes = { :title => 'Updated Title' }
@@ -1598,7 +1584,7 @@ share_examples_for 'A public Collection' do
1598
1584
  end
1599
1585
 
1600
1586
  it 'should return true' do
1601
- @return.should be_true
1587
+ @return.should be(true)
1602
1588
  end
1603
1589
 
1604
1590
  it 'should update attributes of all Resources' do
@@ -1623,7 +1609,7 @@ share_examples_for 'A public Collection' do
1623
1609
  end
1624
1610
 
1625
1611
  it 'should return true' do
1626
- @return.should be_true
1612
+ @return.should be(true)
1627
1613
  end
1628
1614
 
1629
1615
  it 'should update attributes of all Resources' do
@@ -1646,7 +1632,7 @@ share_examples_for 'A public Collection' do
1646
1632
  end
1647
1633
 
1648
1634
  it 'should return false' do
1649
- @return.should be_false
1635
+ @return.should be(false)
1650
1636
  end
1651
1637
  end
1652
1638
 
@@ -1664,7 +1650,7 @@ share_examples_for 'A public Collection' do
1664
1650
  end
1665
1651
 
1666
1652
  it 'should return true' do
1667
- @return.should be_true
1653
+ @return.should be(true)
1668
1654
  end
1669
1655
 
1670
1656
  it 'should bypass validation' do
@@ -1325,8 +1325,7 @@ share_examples_for 'Finder Interface' do
1325
1325
  @article.previous = @new
1326
1326
  @new.previous = @other
1327
1327
 
1328
- @article.save
1329
- @new.save
1328
+ @article.save.should be(true)
1330
1329
  end
1331
1330
 
1332
1331
  describe 'with no arguments' do
@@ -1388,8 +1387,7 @@ share_examples_for 'Finder Interface' do
1388
1387
  @article.revisions << @new
1389
1388
  @new.revisions << @other
1390
1389
 
1391
- @article.save
1392
- @new.save
1390
+ @article.save.should be(true)
1393
1391
  end
1394
1392
 
1395
1393
  describe 'with no arguments' do
@@ -0,0 +1,176 @@
1
+ share_examples_for 'A public Property' do
2
+ before :all do
3
+ %w[ @type @primitive @name @value @other_value ].each do |ivar|
4
+ raise "+#{ivar}+ should be defined in before block" unless instance_variable_defined?(ivar)
5
+ end
6
+
7
+ module ::Blog
8
+ class Article
9
+ include DataMapper::Resource
10
+ property :id, Serial
11
+ end
12
+ end
13
+
14
+ @model = Blog::Article
15
+ end
16
+
17
+ describe "with a sub-type" do
18
+ before :all do
19
+ class ::SubType < @type; end
20
+ @subtype = ::SubType
21
+ @type.accept_options :foo, :bar
22
+ end
23
+
24
+ after :all do
25
+ Object.send(:remove_const, :SubType)
26
+ end
27
+
28
+ describe ".accept_options" do
29
+ describe "when provided :foo, :bar" do
30
+ it "should add new options" do
31
+ [@type, @subtype].each do |type|
32
+ type.accepted_options.include?(:foo).should be(true)
33
+ type.accepted_options.include?(:bar).should be(true)
34
+ end
35
+ end
36
+
37
+ it "should create predefined option setters" do
38
+ [@type, @subtype].each do |type|
39
+ type.should respond_to(:foo)
40
+ type.should respond_to(:bar)
41
+ end
42
+ end
43
+
44
+ describe "auto-generated option setters" do
45
+ before :all do
46
+ [@type, @subtype].each do |type|
47
+ type.foo true
48
+ type.bar 1
49
+ @property = type.new(@model, @name)
50
+ end
51
+ end
52
+
53
+ it "should set the pre-defined option values" do
54
+ @property.options[:foo].should == true
55
+ @property.options[:bar].should == 1
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ describe ".descendants" do
62
+ it "should include the sub-type" do
63
+ @type.descendants.include?(SubType).should be(true)
64
+ end
65
+ end
66
+
67
+ describe ".primitive" do
68
+ it "should return the primitive class" do
69
+ [@type, @subtype].each do |type|
70
+ type.primitive.should be(@primitive)
71
+ end
72
+ end
73
+
74
+ it "should change the primitive class" do
75
+ @subtype.primitive Object
76
+ @subtype.primitive.should be(Object)
77
+ end
78
+ end
79
+ end
80
+
81
+ [:allow_blank, :allow_nil].each do |opt|
82
+ describe "##{method = "#{opt}?"}" do
83
+ [true, false].each do |value|
84
+ describe "when created with :#{opt} => #{value}" do
85
+ before :all do
86
+ @property = @type.new(@model, @name, opt => value)
87
+ end
88
+
89
+ it "should return #{value}" do
90
+ @property.send(method).should be(value)
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "when created with :#{opt} => true and :required => true" do
96
+ it "should fail with ArgumentError" do
97
+ lambda {
98
+ @property = @type.new(@model, @name, opt => true, :required => true)
99
+ }.should raise_error(ArgumentError,
100
+ "options[:required] cannot be mixed with :allow_nil or :allow_blank")
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ [:key?, :required?, :index, :unique_index, :unique?].each do |method|
107
+ describe "##{method}" do
108
+ [true, false].each do |value|
109
+ describe "when created with :#{method} => #{value}" do
110
+ before :all do
111
+ opt = method.to_s.sub('?', '').to_sym
112
+ @property = @type.new(@model, @name, opt => value)
113
+ end
114
+
115
+ it "should return #{value}" do
116
+ @property.send(method).should be(value)
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ describe "#lazy?" do
124
+ describe "when created with :lazy => true, :key => false" do
125
+ before :all do
126
+ @property = @type.new(@model, @name, :lazy => true, :key => false)
127
+ end
128
+
129
+ it "should return true" do
130
+ @property.lazy?.should be(true)
131
+ end
132
+ end
133
+
134
+ describe "when created with :lazy => true, :key => true" do
135
+ before :all do
136
+ @property = @type.new(@model, @name, :lazy => true, :key => true)
137
+ end
138
+
139
+ it "should return false" do
140
+ @property.lazy?.should be(false)
141
+ end
142
+ end
143
+ end
144
+
145
+ describe "#custom?" do
146
+ describe "when DM::Type is not provided" do
147
+ before :all do
148
+ @property = @type.new(@model, @name)
149
+ end
150
+
151
+ it "should be false" do
152
+ @property.custom?.should be(false)
153
+ end
154
+ end
155
+ end
156
+
157
+ [:instance_of?, :kind_of?].each do |method|
158
+ describe "##{method}" do
159
+ before :all do
160
+ @property = @type.new(@model, @name)
161
+ end
162
+
163
+ describe "when provided Property" do
164
+ it "should return true" do
165
+ @property.send(method, DataMapper::Property).should be(true)
166
+ end
167
+ end
168
+
169
+ describe "when provided property class" do
170
+ it "should return true" do
171
+ @property.send(method, @type).should be(true)
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end