dm-core 0.10.2 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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