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