rails-erd 0.3.0 → 0.4.0
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.
- data/.gitignore +1 -0
- data/CHANGES.rdoc +17 -1
- data/Gemfile +3 -2
- data/Gemfile.lock +8 -4
- data/README.md +60 -0
- data/Rakefile +10 -50
- data/VERSION +1 -1
- data/lib/rails_erd.rb +28 -1
- data/lib/rails_erd/diagram.rb +66 -33
- data/lib/rails_erd/diagram/graphviz.rb +123 -92
- data/lib/rails_erd/diagram/templates/node.erb +2 -2
- data/lib/rails_erd/domain.rb +51 -23
- data/lib/rails_erd/domain/attribute.rb +102 -0
- data/lib/rails_erd/domain/entity.rb +102 -0
- data/lib/rails_erd/domain/relationship.rb +189 -0
- data/lib/rails_erd/domain/relationship/cardinality.rb +118 -0
- data/lib/rails_erd/domain/specialization.rb +58 -0
- data/lib/rails_erd/railtie.rb +1 -1
- data/rails-erd.gemspec +19 -16
- data/test/test_helper.rb +21 -5
- data/test/unit/attribute_test.rb +35 -8
- data/test/unit/cardinality_test.rb +41 -35
- data/test/unit/diagram_test.rb +130 -43
- data/test/unit/domain_test.rb +131 -8
- data/test/unit/entity_test.rb +150 -46
- data/test/unit/graphviz_test.rb +52 -14
- data/test/unit/rake_task_test.rb +2 -2
- data/test/unit/relationship_test.rb +73 -24
- data/test/unit/specialization_test.rb +57 -0
- metadata +15 -13
- data/README.rdoc +0 -51
- data/lib/rails_erd/attribute.rb +0 -95
- data/lib/rails_erd/entity.rb +0 -73
- data/lib/rails_erd/relationship.rb +0 -177
- data/lib/rails_erd/relationship/cardinality.rb +0 -118
data/test/unit/graphviz_test.rb
CHANGED
@@ -9,7 +9,7 @@ class GraphvizTest < ActiveSupport::TestCase
|
|
9
9
|
|
10
10
|
def teardown
|
11
11
|
FileUtils.rm Dir["ERD.*"] rescue nil
|
12
|
-
RailsERD::Diagram.send :remove_const, :Graphviz
|
12
|
+
RailsERD::Diagram.send :remove_const, :Graphviz rescue nil
|
13
13
|
end
|
14
14
|
|
15
15
|
def diagram(options = {})
|
@@ -148,6 +148,17 @@ class GraphvizTest < ActiveSupport::TestCase
|
|
148
148
|
FileUtils.rm "foobar.png" rescue nil
|
149
149
|
end
|
150
150
|
end
|
151
|
+
|
152
|
+
test "create should abort and complain if output directory does not exist" do
|
153
|
+
message = nil
|
154
|
+
begin
|
155
|
+
create_simple_domain
|
156
|
+
Diagram::Graphviz.create :filename => "does_not_exist/foo"
|
157
|
+
rescue => e
|
158
|
+
message = e.message
|
159
|
+
end
|
160
|
+
assert_match /Output directory 'does_not_exist' does not exist/, message
|
161
|
+
end
|
151
162
|
|
152
163
|
# Graphviz output ==========================================================
|
153
164
|
test "generate should create directed graph" do
|
@@ -208,7 +219,7 @@ class GraphvizTest < ActiveSupport::TestCase
|
|
208
219
|
create_model "Lid", :jar => :references do
|
209
220
|
belongs_to :jar
|
210
221
|
end
|
211
|
-
|
222
|
+
assert_no_match %r{contents}, find_dot_node(diagram(:attributes => false), "Jar")[:label].to_gv
|
212
223
|
end
|
213
224
|
|
214
225
|
test "generate should create edge for each relationship" do
|
@@ -237,6 +248,33 @@ class GraphvizTest < ActiveSupport::TestCase
|
|
237
248
|
assert_match %r(\A<\s*<.*\|.*>\s*>\Z)m, find_dot_node(diagram(:orientation => :horizontal), "Author")[:label].to_gv
|
238
249
|
end
|
239
250
|
|
251
|
+
test "generate should create edge to generalized entity if polymorphism is true" do
|
252
|
+
create_model "Cannon", :defensible => :references do
|
253
|
+
belongs_to :defensible, :polymorphic => true
|
254
|
+
end
|
255
|
+
create_model "Stronghold" do
|
256
|
+
has_many :cannons, :as => :defensible
|
257
|
+
end
|
258
|
+
create_model "Galleon" do
|
259
|
+
has_many :cannons, :as => :defensible
|
260
|
+
end
|
261
|
+
assert_equal [["Defensible", "Cannon"], ["Defensible", "Galleon"], ["Defensible", "Stronghold"]],
|
262
|
+
find_dot_node_pairs(diagram(:polymorphism => true)).sort
|
263
|
+
end
|
264
|
+
|
265
|
+
test "generate should create edge to each child of generalized entity if polymorphism is false" do
|
266
|
+
create_model "Cannon", :defensible => :references do
|
267
|
+
belongs_to :defensible, :polymorphic => true
|
268
|
+
end
|
269
|
+
create_model "Stronghold" do
|
270
|
+
has_many :cannons, :as => :defensible
|
271
|
+
end
|
272
|
+
create_model "Galleon" do
|
273
|
+
has_many :cannons, :as => :defensible
|
274
|
+
end
|
275
|
+
assert_equal [["Galleon", "Cannon"], ["Stronghold", "Cannon"]], find_dot_node_pairs(diagram).sort
|
276
|
+
end
|
277
|
+
|
240
278
|
# Simple notation style ====================================================
|
241
279
|
test "generate should use no style for one to one cardinalities with simple notation" do
|
242
280
|
create_one_to_one_assoc_domain
|
@@ -254,38 +292,38 @@ class GraphvizTest < ActiveSupport::TestCase
|
|
254
292
|
end
|
255
293
|
|
256
294
|
# Advanced notation style ===================================================
|
257
|
-
test "generate should use open dots for one to one cardinalities with
|
295
|
+
test "generate should use open dots for one to one cardinalities with bachman notation" do
|
258
296
|
create_one_to_one_assoc_domain
|
259
|
-
assert_equal [["odot", "odot"]], find_dot_edge_styles(diagram(:notation => :
|
297
|
+
assert_equal [["odot", "odot"]], find_dot_edge_styles(diagram(:notation => :bachman))
|
260
298
|
end
|
261
299
|
|
262
|
-
test "generate should use dots for mandatory one to one cardinalities with
|
300
|
+
test "generate should use dots for mandatory one to one cardinalities with bachman notation" do
|
263
301
|
create_one_to_one_assoc_domain
|
264
302
|
One.class_eval do
|
265
303
|
validates_presence_of :other
|
266
304
|
end
|
267
|
-
assert_equal [["
|
305
|
+
assert_equal [["dot", "odot"]], find_dot_edge_styles(diagram(:notation => :bachman))
|
268
306
|
end
|
269
307
|
|
270
|
-
test "generate should use normal arrow and open dot head with dot tail for one to many cardinalities with
|
308
|
+
test "generate should use normal arrow and open dot head with dot tail for one to many cardinalities with bachman notation" do
|
271
309
|
create_one_to_many_assoc_domain
|
272
|
-
assert_equal [["odot", "odotnormal"]], find_dot_edge_styles(diagram(:notation => :
|
310
|
+
assert_equal [["odot", "odotnormal"]], find_dot_edge_styles(diagram(:notation => :bachman))
|
273
311
|
end
|
274
312
|
|
275
|
-
test "generate should use normal arrow and dot head for mandatory one to many cardinalities with
|
313
|
+
test "generate should use normal arrow and dot head for mandatory one to many cardinalities with bachman notation" do
|
276
314
|
create_one_to_many_assoc_domain
|
277
315
|
One.class_eval do
|
278
316
|
validates_presence_of :many
|
279
317
|
end
|
280
|
-
assert_equal [["
|
318
|
+
assert_equal [["dot", "odotnormal"]], find_dot_edge_styles(diagram(:notation => :bachman))
|
281
319
|
end
|
282
320
|
|
283
|
-
test "generate should use normal arrow and open dot head and tail for many to many cardinalities with
|
321
|
+
test "generate should use normal arrow and open dot head and tail for many to many cardinalities with bachman notation" do
|
284
322
|
create_many_to_many_assoc_domain
|
285
|
-
assert_equal [["odotnormal", "odotnormal"]], find_dot_edge_styles(diagram(:notation => :
|
323
|
+
assert_equal [["odotnormal", "odotnormal"]], find_dot_edge_styles(diagram(:notation => :bachman))
|
286
324
|
end
|
287
325
|
|
288
|
-
test "generate should use normal arrow and dot tail and head for mandatory many to many cardinalities with
|
326
|
+
test "generate should use normal arrow and dot tail and head for mandatory many to many cardinalities with bachman notation" do
|
289
327
|
create_many_to_many_assoc_domain
|
290
328
|
Many.class_eval do
|
291
329
|
validates_presence_of :more
|
@@ -293,6 +331,6 @@ class GraphvizTest < ActiveSupport::TestCase
|
|
293
331
|
More.class_eval do
|
294
332
|
validates_presence_of :many
|
295
333
|
end
|
296
|
-
assert_equal [["dotnormal", "dotnormal"]], find_dot_edge_styles(diagram(:notation => :
|
334
|
+
assert_equal [["dotnormal", "dotnormal"]], find_dot_edge_styles(diagram(:notation => :bachman))
|
297
335
|
end
|
298
336
|
end
|
data/test/unit/rake_task_test.rb
CHANGED
@@ -67,8 +67,8 @@ class RakeTaskTest < ActiveSupport::TestCase
|
|
67
67
|
end
|
68
68
|
|
69
69
|
test "options task should set known array command line options" do
|
70
|
-
ENV["attributes"] = "
|
70
|
+
ENV["attributes"] = "content,timestamps"
|
71
71
|
Rake::Task["erd:options"].execute
|
72
|
-
assert_equal [:
|
72
|
+
assert_equal [:content, :timestamps], RailsERD.options.attributes
|
73
73
|
end
|
74
74
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path("../test_helper", File.dirname(__FILE__))
|
2
2
|
|
3
3
|
class RelationshipTest < ActiveSupport::TestCase
|
4
|
-
N = Relationship::N
|
4
|
+
N = Domain::Relationship::N
|
5
5
|
|
6
6
|
def domain_cardinalities
|
7
7
|
Domain.generate.relationships.map(&:cardinality)
|
@@ -13,7 +13,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
13
13
|
belongs_to :bar
|
14
14
|
end
|
15
15
|
create_model "Bar"
|
16
|
-
assert_match %r{#<RailsERD::Relationship:.* @source=Bar @destination=Foo>}, Domain.generate.relationships.first.inspect
|
16
|
+
assert_match %r{#<RailsERD::Domain::Relationship:.* @source=Bar @destination=Foo>}, Domain.generate.relationships.first.inspect
|
17
17
|
end
|
18
18
|
|
19
19
|
test "source should return relationship source" do
|
@@ -22,7 +22,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
22
22
|
end
|
23
23
|
create_model "Bar"
|
24
24
|
domain = Domain.generate
|
25
|
-
assert_equal [domain.
|
25
|
+
assert_equal [domain.entity_by_name("Bar")], domain.relationships.map(&:source)
|
26
26
|
end
|
27
27
|
|
28
28
|
test "destination should return relationship destination" do
|
@@ -31,7 +31,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
31
31
|
end
|
32
32
|
create_model "Bar"
|
33
33
|
domain = Domain.generate
|
34
|
-
assert_equal [domain.
|
34
|
+
assert_equal [domain.entity_by_name("Foo")], domain.relationships.map(&:destination)
|
35
35
|
end
|
36
36
|
|
37
37
|
# Relationship properties ==================================================
|
@@ -138,11 +138,24 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
138
138
|
end
|
139
139
|
assert_equal [4], Domain.generate.relationships.map(&:strength)
|
140
140
|
end
|
141
|
+
|
142
|
+
test "strength should count polymorphic associations only once" do
|
143
|
+
create_model "Foo", :bar => :references do
|
144
|
+
belongs_to :bar, :polymorphic => true
|
145
|
+
end
|
146
|
+
create_model "Qux" do
|
147
|
+
has_many :foos, :as => :bar
|
148
|
+
end
|
149
|
+
create_model "Quux" do
|
150
|
+
has_many :foos, :as => :bar
|
151
|
+
end
|
152
|
+
assert_equal [1], Domain.generate.relationships.map(&:strength)
|
153
|
+
end
|
141
154
|
|
142
155
|
# Cardinalities ============================================================
|
143
156
|
test "cardinality should be zero-one to zero-one for optional one to one associations" do
|
144
157
|
create_one_to_one_assoc_domain
|
145
|
-
assert_equal [Relationship::Cardinality.new(0..1, 0..1)], domain_cardinalities
|
158
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..1)], domain_cardinalities
|
146
159
|
end
|
147
160
|
|
148
161
|
test "cardinality should be one to one for mutually mandatory one to one associations" do
|
@@ -153,12 +166,12 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
153
166
|
Other.class_eval do
|
154
167
|
validates_presence_of :one
|
155
168
|
end
|
156
|
-
assert_equal [Relationship::Cardinality.new(1, 1)], domain_cardinalities
|
169
|
+
assert_equal [Domain::Relationship::Cardinality.new(1, 1)], domain_cardinalities
|
157
170
|
end
|
158
171
|
|
159
172
|
test "cardinality should be zero-one to zero-many for optional one to many associations" do
|
160
173
|
create_one_to_many_assoc_domain
|
161
|
-
assert_equal [Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
174
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
162
175
|
end
|
163
176
|
|
164
177
|
test "cardinality should be one to zero-many for one to many associations with not null foreign key" do
|
@@ -169,7 +182,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
169
182
|
belongs_to :one
|
170
183
|
end
|
171
184
|
add_column :manies, :one_id, :integer, :null => false, :default => 0
|
172
|
-
assert_equal [Relationship::Cardinality.new(1, 0..N)], domain_cardinalities
|
185
|
+
assert_equal [Domain::Relationship::Cardinality.new(1, 0..N)], domain_cardinalities
|
173
186
|
end
|
174
187
|
|
175
188
|
test "cardinality should be one to one-many for mutually mandatory one to many associations" do
|
@@ -180,7 +193,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
180
193
|
Many.class_eval do
|
181
194
|
validates_presence_of :one
|
182
195
|
end
|
183
|
-
assert_equal [Relationship::Cardinality.new(1, 1..N)], domain_cardinalities
|
196
|
+
assert_equal [Domain::Relationship::Cardinality.new(1, 1..N)], domain_cardinalities
|
184
197
|
end
|
185
198
|
|
186
199
|
test "cardinality should be zero-one to one-n for maximised one to many associations" do
|
@@ -192,7 +205,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
192
205
|
validates_length_of :many, :maximum => 5
|
193
206
|
validates_length_of :many, :maximum => 2 # The lowest maximum should be used.
|
194
207
|
end
|
195
|
-
assert_equal [Relationship::Cardinality.new(0..1, 1..2)], domain_cardinalities
|
208
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 1..2)], domain_cardinalities
|
196
209
|
end
|
197
210
|
|
198
211
|
test "cardinality should be zero-one to n-many for minimised one to many associations" do
|
@@ -202,7 +215,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
202
215
|
validates_length_of :many, :minimum => 2
|
203
216
|
validates_length_of :many, :minimum => 5 # The highest minimum should be used.
|
204
217
|
end
|
205
|
-
assert_equal [Relationship::Cardinality.new(0..1, 5..N)], domain_cardinalities
|
218
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 5..N)], domain_cardinalities
|
206
219
|
end
|
207
220
|
|
208
221
|
test "cardinality should be zero-one to n-m for limited one to many associations with single validation" do
|
@@ -210,7 +223,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
210
223
|
One.class_eval do
|
211
224
|
validates_length_of :many, :minimum => 5, :maximum => 17
|
212
225
|
end
|
213
|
-
assert_equal [Relationship::Cardinality.new(0..1, 5..17)], domain_cardinalities
|
226
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 5..17)], domain_cardinalities
|
214
227
|
end
|
215
228
|
|
216
229
|
test "cardinality should be zero-one to n-m for limited one to many associations with multiple validations" do
|
@@ -221,12 +234,12 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
221
234
|
validates_length_of :many, :minimum => 5
|
222
235
|
validates_length_of :many, :minimum => 2, :maximum => 28
|
223
236
|
end
|
224
|
-
assert_equal [Relationship::Cardinality.new(0..1, 5..17)], domain_cardinalities
|
237
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 5..17)], domain_cardinalities
|
225
238
|
end
|
226
239
|
|
227
240
|
test "cardinality should be zero-many to zero-many for optional many to many associations" do
|
228
241
|
create_many_to_many_assoc_domain
|
229
|
-
assert_equal [Relationship::Cardinality.new(0..N, 0..N)], domain_cardinalities
|
242
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..N, 0..N)], domain_cardinalities
|
230
243
|
end
|
231
244
|
|
232
245
|
test "cardinality should be one-many to one-many for mutually mandatory many to many associations" do
|
@@ -237,7 +250,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
237
250
|
More.class_eval do
|
238
251
|
validates_presence_of :many
|
239
252
|
end
|
240
|
-
assert_equal [Relationship::Cardinality.new(1..N, 1..N)], domain_cardinalities
|
253
|
+
assert_equal [Domain::Relationship::Cardinality.new(1..N, 1..N)], domain_cardinalities
|
241
254
|
end
|
242
255
|
|
243
256
|
test "cardinality should be n-m to n-m for limited many to many associations with single validations" do
|
@@ -248,7 +261,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
248
261
|
More.class_eval do
|
249
262
|
validates_length_of :many, :maximum => 29, :minimum => 7
|
250
263
|
end
|
251
|
-
assert_equal [Relationship::Cardinality.new(3..18, 7..29)], domain_cardinalities
|
264
|
+
assert_equal [Domain::Relationship::Cardinality.new(3..18, 7..29)], domain_cardinalities
|
252
265
|
end
|
253
266
|
|
254
267
|
test "cardinality should be n-m to n-m for limited many to many associations with multiple validations" do
|
@@ -265,7 +278,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
265
278
|
validates_length_of :many, :minimum => 9
|
266
279
|
validates_length_of :many, :maximum => 17
|
267
280
|
end
|
268
|
-
assert_equal [Relationship::Cardinality.new(3..20, 9..17)], domain_cardinalities
|
281
|
+
assert_equal [Domain::Relationship::Cardinality.new(3..20, 9..17)], domain_cardinalities
|
269
282
|
end
|
270
283
|
|
271
284
|
# Cardinality for non-mutual relationships =================================
|
@@ -274,7 +287,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
274
287
|
create_model "Many", :one => :references do
|
275
288
|
belongs_to :one
|
276
289
|
end
|
277
|
-
assert_equal [Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
290
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
278
291
|
end
|
279
292
|
|
280
293
|
test "cardinality should be zero-one to zero-many for non mutual relationship with has_many association" do
|
@@ -282,7 +295,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
282
295
|
has_many :many
|
283
296
|
end
|
284
297
|
create_model "Many", :one => :references
|
285
|
-
assert_equal [Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
298
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
286
299
|
end
|
287
300
|
|
288
301
|
test "cardinality should be zero-one to zero-one for non mutual relationship with has_one association" do
|
@@ -290,7 +303,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
290
303
|
has_one :other
|
291
304
|
end
|
292
305
|
create_model "Other", :one => :references
|
293
|
-
assert_equal [Relationship::Cardinality.new(0..1, 0..1)], domain_cardinalities
|
306
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..1)], domain_cardinalities
|
294
307
|
end
|
295
308
|
|
296
309
|
test "cardinality should be zero-many to zero-many for non mutual relationship with has_and_belongs_to_many association" do
|
@@ -299,7 +312,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
299
312
|
create_model "More" do
|
300
313
|
has_and_belongs_to_many :many
|
301
314
|
end
|
302
|
-
assert_equal [Relationship::Cardinality.new(0..N, 0..N)], domain_cardinalities
|
315
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..N, 0..N)], domain_cardinalities
|
303
316
|
end
|
304
317
|
|
305
318
|
# Cardinality for multiple associations ====================================
|
@@ -314,7 +327,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
314
327
|
# many cards. The association has an infinite maximum cardinality.
|
315
328
|
has_one :preferred_credit_card, :class_name => "CreditCard"
|
316
329
|
end
|
317
|
-
assert_equal [Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
330
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
318
331
|
end
|
319
332
|
|
320
333
|
test "cardinality should be zero-one to one-many for conflicting validations in one to many associations" do
|
@@ -329,7 +342,7 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
329
342
|
# minimum cardinality of one.
|
330
343
|
validates_presence_of :books
|
331
344
|
end
|
332
|
-
assert_equal [Relationship::Cardinality.new(0..1, 1..N)], domain_cardinalities
|
345
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 1..N)], domain_cardinalities
|
333
346
|
end
|
334
347
|
|
335
348
|
test "cardinality should be n-m to n-m for conflicting validations in one to many associations" do
|
@@ -345,7 +358,23 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
345
358
|
validates_length_of :ice_spells, :in => 10..20
|
346
359
|
validates_length_of :fire_spells, :in => 50..100
|
347
360
|
end
|
348
|
-
assert_equal [Relationship::Cardinality.new(0..1, 50..100)], domain_cardinalities
|
361
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 50..100)], domain_cardinalities
|
362
|
+
end
|
363
|
+
|
364
|
+
test "cardinality should be one to one-many for mandatory one to many associations on polymorphic interfaces" do
|
365
|
+
create_model "Cannon", :defensible => :references do
|
366
|
+
belongs_to :defensible, :polymorphic => true
|
367
|
+
validates_presence_of :defensible
|
368
|
+
end
|
369
|
+
create_model "Stronghold" do
|
370
|
+
has_many :cannons, :as => :defensible
|
371
|
+
validates_presence_of :cannons
|
372
|
+
end
|
373
|
+
create_model "Galleon" do
|
374
|
+
has_many :cannons, :as => :defensible
|
375
|
+
validates_presence_of :cannons
|
376
|
+
end
|
377
|
+
assert_equal [Domain::Relationship::Cardinality.new(1, 1..N)], domain_cardinalities
|
349
378
|
end
|
350
379
|
|
351
380
|
# Cardinality classes ======================================================
|
@@ -415,4 +444,24 @@ class RelationshipTest < ActiveSupport::TestCase
|
|
415
444
|
domain = Domain.generate
|
416
445
|
assert_equal [:one_to_many], domain.relationships.map(&:cardinality).map(&:name)
|
417
446
|
end
|
447
|
+
|
448
|
+
test "cardinality should be one to many for has_many associations from generalized entity" do
|
449
|
+
create_model "Stronghold" do
|
450
|
+
has_many :cannons, :as => :defensible
|
451
|
+
end
|
452
|
+
create_model "Cannon", :defensible => :references do
|
453
|
+
belongs_to :defensible, :polymorphic => true
|
454
|
+
end
|
455
|
+
domain = Domain.generate
|
456
|
+
|
457
|
+
assert_equal [:one_to_many], domain.relationships.map(&:cardinality).map(&:name)
|
458
|
+
assert_equal [false], domain.relationships.map(&:one_to_one?)
|
459
|
+
assert_equal [true], domain.relationships.map(&:one_to_many?)
|
460
|
+
assert_equal [false], domain.relationships.map(&:many_to_many?)
|
461
|
+
|
462
|
+
assert_equal [true], domain.relationships.map(&:one_to?)
|
463
|
+
assert_equal [false], domain.relationships.map(&:many_to?)
|
464
|
+
assert_equal [false], domain.relationships.map(&:to_one?)
|
465
|
+
assert_equal [true], domain.relationships.map(&:to_many?)
|
466
|
+
end
|
418
467
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path("../test_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class SpecializationTest < ActiveSupport::TestCase
|
4
|
+
# Specialization ===========================================================
|
5
|
+
test "inspect should show source and destination" do
|
6
|
+
create_specialization
|
7
|
+
domain = Domain.generate
|
8
|
+
assert_match %r{#<RailsERD::Domain::Specialization:.* @generalized=Beverage @specialized=Beer>},
|
9
|
+
Domain::Specialization.new(domain, domain.entity_by_name("Beverage"), domain.entity_by_name("Beer")).inspect
|
10
|
+
end
|
11
|
+
|
12
|
+
test "generalized should return source entity" do
|
13
|
+
create_specialization
|
14
|
+
domain = Domain.generate
|
15
|
+
assert_equal domain.entity_by_name("Beverage"),
|
16
|
+
Domain::Specialization.new(domain, domain.entity_by_name("Beverage"), domain.entity_by_name("Beer")).generalized
|
17
|
+
end
|
18
|
+
|
19
|
+
test "specialized should return destination entity" do
|
20
|
+
create_specialization
|
21
|
+
domain = Domain.generate
|
22
|
+
assert_equal domain.entity_by_name("Beer"),
|
23
|
+
Domain::Specialization.new(domain, domain.entity_by_name("Beverage"), domain.entity_by_name("Beer")).specialized
|
24
|
+
end
|
25
|
+
|
26
|
+
# Specialization properties ================================================
|
27
|
+
test "inheritance should be true for inheritance specializations" do
|
28
|
+
create_specialization
|
29
|
+
assert_equal [true], Domain.generate.specializations.map(&:inheritance?)
|
30
|
+
end
|
31
|
+
|
32
|
+
test "polymorphic should be false for inheritance specializations" do
|
33
|
+
create_specialization
|
34
|
+
assert_equal [false], Domain.generate.specializations.map(&:polymorphic?)
|
35
|
+
end
|
36
|
+
|
37
|
+
test "inheritance should be false for polymorphic specializations" do
|
38
|
+
create_generalization
|
39
|
+
assert_equal [false], Domain.generate.specializations.map(&:inheritance?)
|
40
|
+
end
|
41
|
+
|
42
|
+
test "polymorphic should be true for polymorphic specializations" do
|
43
|
+
create_generalization
|
44
|
+
assert_equal [true], Domain.generate.specializations.map(&:polymorphic?)
|
45
|
+
end
|
46
|
+
|
47
|
+
test "inheritance should be false for polymorphic specializations to specialized entities" do
|
48
|
+
create_model "Cannon"
|
49
|
+
create_model "Ship", :type => :string
|
50
|
+
create_model "Galleon", Ship do
|
51
|
+
has_many :cannons, :as => :defensible
|
52
|
+
end
|
53
|
+
domain = Domain.generate
|
54
|
+
assert_equal false, domain.specializations.find { |s|
|
55
|
+
s.generalized == domain.entity_by_name("Defensible") }.inheritance?
|
56
|
+
end
|
57
|
+
end
|