jw-rails-erd 1.4.5
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.
- checksums.yaml +7 -0
- data/README.md +86 -0
- data/Rakefile +20 -0
- data/bin/erd +4 -0
- data/lib/generators/erd/USAGE +4 -0
- data/lib/generators/erd/install_generator.rb +14 -0
- data/lib/generators/erd/templates/auto_generate_diagram.rake +6 -0
- data/lib/rails-erd.rb +1 -0
- data/lib/rails_erd/cli.rb +164 -0
- data/lib/rails_erd/config.rb +97 -0
- data/lib/rails_erd/custom.rb +99 -0
- data/lib/rails_erd/diagram/graphviz.rb +295 -0
- data/lib/rails_erd/diagram/templates/node.html.erb +14 -0
- data/lib/rails_erd/diagram/templates/node.record.erb +4 -0
- data/lib/rails_erd/diagram.rb +188 -0
- data/lib/rails_erd/domain/attribute.rb +160 -0
- data/lib/rails_erd/domain/entity.rb +104 -0
- data/lib/rails_erd/domain/relationship/cardinality.rb +118 -0
- data/lib/rails_erd/domain/relationship.rb +203 -0
- data/lib/rails_erd/domain/specialization.rb +90 -0
- data/lib/rails_erd/domain.rb +153 -0
- data/lib/rails_erd/railtie.rb +10 -0
- data/lib/rails_erd/tasks.rake +58 -0
- data/lib/rails_erd/version.rb +4 -0
- data/lib/rails_erd.rb +73 -0
- data/lib/tasks/auto_generate_diagram.rake +21 -0
- data/test/support_files/erdconfig.another_example +3 -0
- data/test/support_files/erdconfig.example +19 -0
- data/test/support_files/erdconfig.exclude.example +19 -0
- data/test/test_helper.rb +160 -0
- data/test/unit/attribute_test.rb +316 -0
- data/test/unit/cardinality_test.rb +123 -0
- data/test/unit/config_test.rb +110 -0
- data/test/unit/diagram_test.rb +352 -0
- data/test/unit/domain_test.rb +258 -0
- data/test/unit/entity_test.rb +252 -0
- data/test/unit/graphviz_test.rb +461 -0
- data/test/unit/rake_task_test.rb +174 -0
- data/test/unit/relationship_test.rb +476 -0
- data/test/unit/specialization_test.rb +67 -0
- metadata +155 -0
@@ -0,0 +1,476 @@
|
|
1
|
+
require File.expand_path("../test_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class RelationshipTest < ActiveSupport::TestCase
|
4
|
+
N = Domain::Relationship::N
|
5
|
+
|
6
|
+
def domain_cardinalities
|
7
|
+
Domain.generate.relationships.map(&:cardinality)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Relationship =============================================================
|
11
|
+
test "inspect should show source and destination" do
|
12
|
+
create_model "Foo", :bar => :references do
|
13
|
+
belongs_to :bar
|
14
|
+
end
|
15
|
+
create_model "Bar"
|
16
|
+
assert_match %r{#<RailsERD::Domain::Relationship:.* @source=Bar @destination=Foo>}, Domain.generate.relationships.first.inspect
|
17
|
+
end
|
18
|
+
|
19
|
+
test "source should return relationship source" do
|
20
|
+
create_model "Foo", :bar => :references do
|
21
|
+
belongs_to :bar
|
22
|
+
end
|
23
|
+
create_model "Bar"
|
24
|
+
domain = Domain.generate
|
25
|
+
assert_equal [domain.entity_by_name("Bar")], domain.relationships.map(&:source)
|
26
|
+
end
|
27
|
+
|
28
|
+
test "destination should return relationship destination" do
|
29
|
+
create_model "Foo", :bar => :references do
|
30
|
+
belongs_to :bar
|
31
|
+
end
|
32
|
+
create_model "Bar"
|
33
|
+
domain = Domain.generate
|
34
|
+
assert_equal [domain.entity_by_name("Foo")], domain.relationships.map(&:destination)
|
35
|
+
end
|
36
|
+
|
37
|
+
test "destination should return relationship destination if specified with absolute module path" do
|
38
|
+
create_model "Foo", :bar => :references
|
39
|
+
create_model "Bar" do
|
40
|
+
has_many :foos, :class_name => "::Foo"
|
41
|
+
end
|
42
|
+
domain = Domain.generate
|
43
|
+
assert_equal [domain.entity_by_name("Foo")], domain.relationships.map(&:destination)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Relationship properties ==================================================
|
47
|
+
test "mutual should return false for one way relationship" do
|
48
|
+
create_model "Foo", :bar => :references do
|
49
|
+
belongs_to :bar
|
50
|
+
end
|
51
|
+
create_model "Bar"
|
52
|
+
assert_equal [false], Domain.generate.relationships.map(&:mutual?)
|
53
|
+
end
|
54
|
+
|
55
|
+
test "mutual should return true for mutual relationship" do
|
56
|
+
create_model "Foo", :bar => :references do
|
57
|
+
belongs_to :bar
|
58
|
+
end
|
59
|
+
create_model "Bar" do
|
60
|
+
has_many :foos
|
61
|
+
end
|
62
|
+
assert_equal [true], Domain.generate.relationships.map(&:mutual?)
|
63
|
+
end
|
64
|
+
|
65
|
+
test "mutual should return true for mutual many to many relationship" do
|
66
|
+
create_many_to_many_assoc_domain
|
67
|
+
assert_equal [true], Domain.generate.relationships.map(&:mutual?)
|
68
|
+
end
|
69
|
+
|
70
|
+
test "recursive should return false for ordinary relationship" do
|
71
|
+
create_model "Foo", :bar => :references do
|
72
|
+
belongs_to :bar
|
73
|
+
end
|
74
|
+
create_model "Bar" do
|
75
|
+
has_many :foos
|
76
|
+
end
|
77
|
+
assert_equal [false], Domain.generate.relationships.map(&:recursive?)
|
78
|
+
end
|
79
|
+
|
80
|
+
test "recursive should return true for self referencing relationship" do
|
81
|
+
create_model "Foo", :foo => :references do
|
82
|
+
belongs_to :foo
|
83
|
+
end
|
84
|
+
assert_equal [true], Domain.generate.relationships.map(&:recursive?)
|
85
|
+
end
|
86
|
+
|
87
|
+
test "indirect should return false for ordinary relationship" do
|
88
|
+
create_model "Foo", :bar => :references do
|
89
|
+
belongs_to :bar
|
90
|
+
end
|
91
|
+
create_model "Bar" do
|
92
|
+
has_many :foos
|
93
|
+
end
|
94
|
+
assert_equal [false], Domain.generate.relationships.map(&:indirect?)
|
95
|
+
end
|
96
|
+
|
97
|
+
test "indirect should return false for non mutual ordinary relationship" do
|
98
|
+
create_model "Foo", :bar => :references do
|
99
|
+
belongs_to :bar
|
100
|
+
end
|
101
|
+
create_model "Bar"
|
102
|
+
assert_equal [false], Domain.generate.relationships.map(&:indirect?)
|
103
|
+
end
|
104
|
+
|
105
|
+
test "indirect should return true if relationship is a through association" do
|
106
|
+
create_model "Foo", :baz => :references, :bar => :references do
|
107
|
+
belongs_to :baz
|
108
|
+
belongs_to :bar
|
109
|
+
end
|
110
|
+
create_model "Bar" do
|
111
|
+
has_many :foos
|
112
|
+
has_many :bazs, :through => :foos
|
113
|
+
end
|
114
|
+
create_model "Baz" do
|
115
|
+
has_many :foos
|
116
|
+
end
|
117
|
+
assert_equal true, Domain.generate.relationships.find { |rel|
|
118
|
+
rel.source.model == Bar and rel.destination.model == Baz }.indirect?
|
119
|
+
end
|
120
|
+
|
121
|
+
test "strength should return one for relationship with one association" do
|
122
|
+
create_model "Foo", :bar => :references
|
123
|
+
create_model "Bar" do
|
124
|
+
has_many :foos
|
125
|
+
end
|
126
|
+
assert_equal [1], Domain.generate.relationships.map(&:strength)
|
127
|
+
end
|
128
|
+
|
129
|
+
test "strength should return two for relationship with two associations" do
|
130
|
+
create_model "Foo", :bar => :references do
|
131
|
+
belongs_to :bar
|
132
|
+
end
|
133
|
+
create_model "Bar" do
|
134
|
+
has_many :foos
|
135
|
+
end
|
136
|
+
assert_equal [2], Domain.generate.relationships.map(&:strength)
|
137
|
+
end
|
138
|
+
|
139
|
+
test "strength should return number of associations that make up the relationship" do
|
140
|
+
create_model "Foo", :bar => :references do
|
141
|
+
belongs_to :bar
|
142
|
+
belongs_to :special_bar, :class_name => "Bar", :foreign_key => :bar_id
|
143
|
+
end
|
144
|
+
create_model "Bar" do
|
145
|
+
has_many :foos
|
146
|
+
has_many :special_foos, :class_name => "Foo", :foreign_key => :bar_id
|
147
|
+
end
|
148
|
+
assert_equal [4], Domain.generate.relationships.map(&:strength)
|
149
|
+
end
|
150
|
+
|
151
|
+
test "strength should count polymorphic associations only once" do
|
152
|
+
create_model "Foo", :bar => :references do
|
153
|
+
belongs_to :bar, :polymorphic => true
|
154
|
+
end
|
155
|
+
create_model "Qux" do
|
156
|
+
has_many :foos, :as => :bar
|
157
|
+
end
|
158
|
+
create_model "Quux" do
|
159
|
+
has_many :foos, :as => :bar
|
160
|
+
end
|
161
|
+
assert_equal [1], Domain.generate.relationships.map(&:strength)
|
162
|
+
end
|
163
|
+
|
164
|
+
# Cardinalities ============================================================
|
165
|
+
test "cardinality should be zero-one to zero-one for optional one to one associations" do
|
166
|
+
create_one_to_one_assoc_domain
|
167
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..1)], domain_cardinalities
|
168
|
+
end
|
169
|
+
|
170
|
+
test "cardinality should be one to one for mutually mandatory one to one associations" do
|
171
|
+
create_one_to_one_assoc_domain
|
172
|
+
One.class_eval do
|
173
|
+
validates_presence_of :other
|
174
|
+
end
|
175
|
+
Other.class_eval do
|
176
|
+
validates_presence_of :one
|
177
|
+
end
|
178
|
+
assert_equal [Domain::Relationship::Cardinality.new(1, 1)], domain_cardinalities
|
179
|
+
end
|
180
|
+
|
181
|
+
test "cardinality should be zero-one to zero-many for optional one to many associations" do
|
182
|
+
create_one_to_many_assoc_domain
|
183
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
184
|
+
end
|
185
|
+
|
186
|
+
test "cardinality should be one to zero-many for one to many associations with not null foreign key" do
|
187
|
+
create_model "One" do
|
188
|
+
has_many :many
|
189
|
+
end
|
190
|
+
create_model "Many" do
|
191
|
+
belongs_to :one
|
192
|
+
end
|
193
|
+
add_column :manies, :one_id, :integer, :null => false, :default => 0
|
194
|
+
assert_equal [Domain::Relationship::Cardinality.new(1, 0..N)], domain_cardinalities
|
195
|
+
end
|
196
|
+
|
197
|
+
test "cardinality should be one to one-many for mutually mandatory one to many associations" do
|
198
|
+
create_one_to_many_assoc_domain
|
199
|
+
One.class_eval do
|
200
|
+
validates_presence_of :many
|
201
|
+
end
|
202
|
+
Many.class_eval do
|
203
|
+
validates_presence_of :one
|
204
|
+
end
|
205
|
+
assert_equal [Domain::Relationship::Cardinality.new(1, 1..N)], domain_cardinalities
|
206
|
+
end
|
207
|
+
|
208
|
+
test "cardinality should be zero-one to one-n for maximised one to many associations" do
|
209
|
+
create_one_to_many_assoc_domain
|
210
|
+
One.class_eval do
|
211
|
+
validates_presence_of :many
|
212
|
+
|
213
|
+
# This kind of validation is bizarre, but we support it.
|
214
|
+
validates_length_of :many, :maximum => 5
|
215
|
+
validates_length_of :many, :maximum => 2 # The lowest maximum should be used.
|
216
|
+
end
|
217
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 1..2)], domain_cardinalities
|
218
|
+
end
|
219
|
+
|
220
|
+
test "cardinality should be zero-one to n-many for minimised one to many associations" do
|
221
|
+
create_one_to_many_assoc_domain
|
222
|
+
One.class_eval do
|
223
|
+
validates_presence_of :many
|
224
|
+
validates_length_of :many, :minimum => 2
|
225
|
+
validates_length_of :many, :minimum => 5 # The highest minimum should be used.
|
226
|
+
end
|
227
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 5..N)], domain_cardinalities
|
228
|
+
end
|
229
|
+
|
230
|
+
test "cardinality should be zero-one to n-m for limited one to many associations with single validation" do
|
231
|
+
create_one_to_many_assoc_domain
|
232
|
+
One.class_eval do
|
233
|
+
validates_length_of :many, :minimum => 5, :maximum => 17
|
234
|
+
end
|
235
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 5..17)], domain_cardinalities
|
236
|
+
end
|
237
|
+
|
238
|
+
test "cardinality should be zero-one to n-m for limited one to many associations with multiple validations" do
|
239
|
+
create_one_to_many_assoc_domain
|
240
|
+
One.class_eval do
|
241
|
+
validates_presence_of :many
|
242
|
+
validates_length_of :many, :maximum => 17
|
243
|
+
validates_length_of :many, :minimum => 5
|
244
|
+
validates_length_of :many, :minimum => 2, :maximum => 28
|
245
|
+
end
|
246
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 5..17)], domain_cardinalities
|
247
|
+
end
|
248
|
+
|
249
|
+
test "cardinality should be zero-many to zero-many for optional many to many associations" do
|
250
|
+
create_many_to_many_assoc_domain
|
251
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..N, 0..N)], domain_cardinalities
|
252
|
+
end
|
253
|
+
|
254
|
+
test "cardinality should be one-many to one-many for mutually mandatory many to many associations" do
|
255
|
+
create_many_to_many_assoc_domain
|
256
|
+
Many.class_eval do
|
257
|
+
validates_presence_of :more
|
258
|
+
end
|
259
|
+
More.class_eval do
|
260
|
+
validates_presence_of :many
|
261
|
+
end
|
262
|
+
assert_equal [Domain::Relationship::Cardinality.new(1..N, 1..N)], domain_cardinalities
|
263
|
+
end
|
264
|
+
|
265
|
+
test "cardinality should be n-m to n-m for limited many to many associations with single validations" do
|
266
|
+
create_many_to_many_assoc_domain
|
267
|
+
Many.class_eval do
|
268
|
+
validates_length_of :more, :minimum => 3, :maximum => 18
|
269
|
+
end
|
270
|
+
More.class_eval do
|
271
|
+
validates_length_of :many, :maximum => 29, :minimum => 7
|
272
|
+
end
|
273
|
+
assert_equal [Domain::Relationship::Cardinality.new(7..29, 3..18)], domain_cardinalities
|
274
|
+
end
|
275
|
+
|
276
|
+
test "cardinality should be n-m to n-m for limited many to many associations with multiple validations" do
|
277
|
+
create_many_to_many_assoc_domain
|
278
|
+
Many.class_eval do
|
279
|
+
validates_presence_of :more
|
280
|
+
validates_length_of :more, :minimum => 3
|
281
|
+
validates_length_of :more, :maximum => 20
|
282
|
+
validates_length_of :more, :maximum => 33
|
283
|
+
end
|
284
|
+
More.class_eval do
|
285
|
+
validates_presence_of :many
|
286
|
+
validates_length_of :many, :minimum => 2
|
287
|
+
validates_length_of :many, :minimum => 9
|
288
|
+
validates_length_of :many, :maximum => 17
|
289
|
+
end
|
290
|
+
assert_equal [Domain::Relationship::Cardinality.new(9..17, 3..20)], domain_cardinalities
|
291
|
+
end
|
292
|
+
|
293
|
+
# Cardinality for non-mutual relationships =================================
|
294
|
+
test "cardinality should be zero-one to zero-many for non mutual relationship with belongs_to association" do
|
295
|
+
create_model "One"
|
296
|
+
create_model "Many", :one => :references do
|
297
|
+
belongs_to :one
|
298
|
+
end
|
299
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
300
|
+
end
|
301
|
+
|
302
|
+
test "cardinality should be zero-one to zero-many for non mutual relationship with has_many association" do
|
303
|
+
create_model "One" do
|
304
|
+
has_many :many
|
305
|
+
end
|
306
|
+
create_model "Many", :one => :references
|
307
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
308
|
+
end
|
309
|
+
|
310
|
+
test "cardinality should be zero-one to zero-one for non mutual relationship with has_one association" do
|
311
|
+
create_model "One" do
|
312
|
+
has_one :other
|
313
|
+
end
|
314
|
+
create_model "Other", :one => :references
|
315
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..1)], domain_cardinalities
|
316
|
+
end
|
317
|
+
|
318
|
+
test "cardinality should be zero-many to zero-many for non mutual relationship with has_and_belongs_to_many association" do
|
319
|
+
create_table "many_more", :many_id => :integer, :more_id => :integer
|
320
|
+
create_model "Many"
|
321
|
+
create_model "More" do
|
322
|
+
has_and_belongs_to_many :many
|
323
|
+
end
|
324
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..N, 0..N)], domain_cardinalities
|
325
|
+
end
|
326
|
+
|
327
|
+
# Cardinality for multiple associations ====================================
|
328
|
+
test "cardinality should be zero-one to zero-many for conflicting one to many associations" do
|
329
|
+
create_model "CreditCard", :person => :references do
|
330
|
+
belongs_to :person
|
331
|
+
end
|
332
|
+
create_model "Person" do
|
333
|
+
has_many :credit_cards
|
334
|
+
|
335
|
+
# A person may have a preferred card, but they are still able to have
|
336
|
+
# many cards. The association has an infinite maximum cardinality.
|
337
|
+
has_one :preferred_credit_card, :class_name => "CreditCard"
|
338
|
+
end
|
339
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 0..N)], domain_cardinalities
|
340
|
+
end
|
341
|
+
|
342
|
+
test "cardinality should be zero-one to one-many for conflicting validations in one to many associations" do
|
343
|
+
create_model "Book", :author => :references do
|
344
|
+
belongs_to :author
|
345
|
+
end
|
346
|
+
create_model "Author" do
|
347
|
+
has_many :books
|
348
|
+
has_many :published_books, :class_name => "Book"
|
349
|
+
|
350
|
+
# The author certainly has books, therefore, this association has a
|
351
|
+
# minimum cardinality of one.
|
352
|
+
validates_presence_of :books
|
353
|
+
end
|
354
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 1..N)], domain_cardinalities
|
355
|
+
end
|
356
|
+
|
357
|
+
test "cardinality should be n-m to n-m for conflicting validations in one to many associations" do
|
358
|
+
create_model "Spell", :wizard => :references do
|
359
|
+
end
|
360
|
+
create_model "Wizard" do
|
361
|
+
has_many :ice_spells, :class_name => "Spell"
|
362
|
+
has_many :fire_spells, :class_name => "Spell"
|
363
|
+
|
364
|
+
# Well, this can make sense, based on the conditions for the associations.
|
365
|
+
# We don't go that far yet. We ignore the lower values and opt for the
|
366
|
+
# higher values. It'll be okay. Really... You'll never need this.
|
367
|
+
validates_length_of :ice_spells, :in => 10..20
|
368
|
+
validates_length_of :fire_spells, :in => 50..100
|
369
|
+
end
|
370
|
+
assert_equal [Domain::Relationship::Cardinality.new(0..1, 50..100)], domain_cardinalities
|
371
|
+
end
|
372
|
+
|
373
|
+
test "cardinality should be one to one-many for mandatory one to many associations on polymorphic interfaces" do
|
374
|
+
create_model "Cannon", :defensible => :references do
|
375
|
+
belongs_to :defensible, :polymorphic => true
|
376
|
+
validates_presence_of :defensible
|
377
|
+
end
|
378
|
+
create_model "Stronghold" do
|
379
|
+
has_many :cannons, :as => :defensible
|
380
|
+
validates_presence_of :cannons
|
381
|
+
end
|
382
|
+
create_model "Galleon" do
|
383
|
+
has_many :cannons, :as => :defensible
|
384
|
+
validates_presence_of :cannons
|
385
|
+
end
|
386
|
+
assert_equal [Domain::Relationship::Cardinality.new(1, 1..N)], domain_cardinalities
|
387
|
+
end
|
388
|
+
|
389
|
+
# Cardinality classes ======================================================
|
390
|
+
test "cardinality should be one to one for has_one associations" do
|
391
|
+
create_one_to_one_assoc_domain
|
392
|
+
domain = Domain.generate
|
393
|
+
|
394
|
+
# In these test, we are liberal with the number of assertions per test.
|
395
|
+
assert_equal [:one_to_one], domain.relationships.map(&:cardinality).map(&:name)
|
396
|
+
|
397
|
+
assert_equal [true], domain.relationships.map(&:one_to_one?)
|
398
|
+
assert_equal [false], domain.relationships.map(&:one_to_many?)
|
399
|
+
assert_equal [false], domain.relationships.map(&:many_to_many?)
|
400
|
+
|
401
|
+
assert_equal [true], domain.relationships.map(&:one_to?)
|
402
|
+
assert_equal [false], domain.relationships.map(&:many_to?)
|
403
|
+
assert_equal [true], domain.relationships.map(&:to_one?)
|
404
|
+
assert_equal [false], domain.relationships.map(&:to_many?)
|
405
|
+
end
|
406
|
+
|
407
|
+
test "cardinality should be one to many for has_many associations" do
|
408
|
+
create_one_to_many_assoc_domain
|
409
|
+
domain = Domain.generate
|
410
|
+
|
411
|
+
assert_equal [:one_to_many], domain.relationships.map(&:cardinality).map(&:name)
|
412
|
+
assert_equal [false], domain.relationships.map(&:one_to_one?)
|
413
|
+
assert_equal [true], domain.relationships.map(&:one_to_many?)
|
414
|
+
assert_equal [false], domain.relationships.map(&:many_to_many?)
|
415
|
+
|
416
|
+
assert_equal [true], domain.relationships.map(&:one_to?)
|
417
|
+
assert_equal [false], domain.relationships.map(&:many_to?)
|
418
|
+
assert_equal [false], domain.relationships.map(&:to_one?)
|
419
|
+
assert_equal [true], domain.relationships.map(&:to_many?)
|
420
|
+
end
|
421
|
+
|
422
|
+
test "cardinality should be many to many for has_and_belongs_to_many associations" do
|
423
|
+
create_many_to_many_assoc_domain
|
424
|
+
domain = Domain.generate
|
425
|
+
|
426
|
+
assert_equal [:many_to_many], domain.relationships.map(&:cardinality).map(&:name)
|
427
|
+
|
428
|
+
assert_equal [false], domain.relationships.map(&:one_to_one?)
|
429
|
+
assert_equal [false], domain.relationships.map(&:one_to_many?)
|
430
|
+
assert_equal [true], domain.relationships.map(&:many_to_many?)
|
431
|
+
|
432
|
+
assert_equal [false], domain.relationships.map(&:one_to?)
|
433
|
+
assert_equal [true], domain.relationships.map(&:many_to?)
|
434
|
+
assert_equal [false], domain.relationships.map(&:to_one?)
|
435
|
+
assert_equal [true], domain.relationships.map(&:to_many?)
|
436
|
+
end
|
437
|
+
|
438
|
+
test "cardinality should be one to many for multiple associations with maximum cardinality of has_many" do
|
439
|
+
create_model "Foo", :bar => :references
|
440
|
+
create_model "Bar" do
|
441
|
+
has_one :foo
|
442
|
+
has_many :foos
|
443
|
+
end
|
444
|
+
domain = Domain.generate
|
445
|
+
assert_equal [:one_to_many], domain.relationships.map(&:cardinality).map(&:name)
|
446
|
+
end
|
447
|
+
|
448
|
+
test "cardinality should be one to many if forward association is missing" do
|
449
|
+
create_model "Foo", :bar => :references do
|
450
|
+
belongs_to :bar
|
451
|
+
end
|
452
|
+
create_model "Bar"
|
453
|
+
domain = Domain.generate
|
454
|
+
assert_equal [:one_to_many], domain.relationships.map(&:cardinality).map(&:name)
|
455
|
+
end
|
456
|
+
|
457
|
+
test "cardinality should be one to many for has_many associations from generalized entity" do
|
458
|
+
create_model "Stronghold" do
|
459
|
+
has_many :cannons, :as => :defensible
|
460
|
+
end
|
461
|
+
create_model "Cannon", :defensible => :references do
|
462
|
+
belongs_to :defensible, :polymorphic => true
|
463
|
+
end
|
464
|
+
domain = Domain.generate
|
465
|
+
|
466
|
+
assert_equal [:one_to_many], domain.relationships.map(&:cardinality).map(&:name)
|
467
|
+
assert_equal [false], domain.relationships.map(&:one_to_one?)
|
468
|
+
assert_equal [true], domain.relationships.map(&:one_to_many?)
|
469
|
+
assert_equal [false], domain.relationships.map(&:many_to_many?)
|
470
|
+
|
471
|
+
assert_equal [true], domain.relationships.map(&:one_to?)
|
472
|
+
assert_equal [false], domain.relationships.map(&:many_to?)
|
473
|
+
assert_equal [false], domain.relationships.map(&:to_one?)
|
474
|
+
assert_equal [true], domain.relationships.map(&:to_many?)
|
475
|
+
end
|
476
|
+
end
|
@@ -0,0 +1,67 @@
|
|
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_polymorphic_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_polymorphic_generalization
|
44
|
+
assert_equal [true], Domain.generate.specializations.map(&:polymorphic?)
|
45
|
+
end
|
46
|
+
|
47
|
+
test "inheritance should be false for abstract specializations" do
|
48
|
+
create_abstract_generalization
|
49
|
+
assert_equal [false], Domain.generate.specializations.map(&:inheritance?)
|
50
|
+
end
|
51
|
+
|
52
|
+
test "polymorphic should be true for abstract specializations" do
|
53
|
+
create_abstract_generalization
|
54
|
+
assert_equal [true], Domain.generate.specializations.map(&:polymorphic?)
|
55
|
+
end
|
56
|
+
|
57
|
+
test "inheritance should be false for polymorphic specializations to specialized entities" do
|
58
|
+
create_model "Cannon"
|
59
|
+
create_model "Ship", :type => :string
|
60
|
+
create_model "Galleon", Ship do
|
61
|
+
has_many :cannons, :as => :defensible
|
62
|
+
end
|
63
|
+
domain = Domain.generate
|
64
|
+
assert_equal false, domain.specializations.find { |s|
|
65
|
+
s.generalized == domain.entity_by_name("Defensible") }.inheritance?
|
66
|
+
end
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jw-rails-erd
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.4.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rolf Timmermans
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ruby-graphviz
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: choice
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.2.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.2.0
|
69
|
+
description: Automatically generate an entity-relationship diagram (ERD) for your
|
70
|
+
Rails models.
|
71
|
+
email:
|
72
|
+
- r.timmermans@voormedia.com
|
73
|
+
executables:
|
74
|
+
- erd
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- README.md
|
79
|
+
- Rakefile
|
80
|
+
- bin/erd
|
81
|
+
- lib/generators/erd/USAGE
|
82
|
+
- lib/generators/erd/install_generator.rb
|
83
|
+
- lib/generators/erd/templates/auto_generate_diagram.rake
|
84
|
+
- lib/rails-erd.rb
|
85
|
+
- lib/rails_erd.rb
|
86
|
+
- lib/rails_erd/cli.rb
|
87
|
+
- lib/rails_erd/config.rb
|
88
|
+
- lib/rails_erd/custom.rb
|
89
|
+
- lib/rails_erd/diagram.rb
|
90
|
+
- lib/rails_erd/diagram/graphviz.rb
|
91
|
+
- lib/rails_erd/diagram/templates/node.html.erb
|
92
|
+
- lib/rails_erd/diagram/templates/node.record.erb
|
93
|
+
- lib/rails_erd/domain.rb
|
94
|
+
- lib/rails_erd/domain/attribute.rb
|
95
|
+
- lib/rails_erd/domain/entity.rb
|
96
|
+
- lib/rails_erd/domain/relationship.rb
|
97
|
+
- lib/rails_erd/domain/relationship/cardinality.rb
|
98
|
+
- lib/rails_erd/domain/specialization.rb
|
99
|
+
- lib/rails_erd/railtie.rb
|
100
|
+
- lib/rails_erd/tasks.rake
|
101
|
+
- lib/rails_erd/version.rb
|
102
|
+
- lib/tasks/auto_generate_diagram.rake
|
103
|
+
- test/support_files/erdconfig.another_example
|
104
|
+
- test/support_files/erdconfig.example
|
105
|
+
- test/support_files/erdconfig.exclude.example
|
106
|
+
- test/test_helper.rb
|
107
|
+
- test/unit/attribute_test.rb
|
108
|
+
- test/unit/cardinality_test.rb
|
109
|
+
- test/unit/config_test.rb
|
110
|
+
- test/unit/diagram_test.rb
|
111
|
+
- test/unit/domain_test.rb
|
112
|
+
- test/unit/entity_test.rb
|
113
|
+
- test/unit/graphviz_test.rb
|
114
|
+
- test/unit/rake_task_test.rb
|
115
|
+
- test/unit/relationship_test.rb
|
116
|
+
- test/unit/specialization_test.rb
|
117
|
+
homepage: https://github.com/jamescway/rails-erd
|
118
|
+
licenses:
|
119
|
+
- MIT
|
120
|
+
metadata: {}
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
require_paths:
|
124
|
+
- lib
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 1.9.3
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
requirements: []
|
136
|
+
rubyforge_project:
|
137
|
+
rubygems_version: 2.5.0
|
138
|
+
signing_key:
|
139
|
+
specification_version: 4
|
140
|
+
summary: Entity-relationship diagram for your Rails models.
|
141
|
+
test_files:
|
142
|
+
- test/support_files/erdconfig.another_example
|
143
|
+
- test/support_files/erdconfig.example
|
144
|
+
- test/support_files/erdconfig.exclude.example
|
145
|
+
- test/test_helper.rb
|
146
|
+
- test/unit/attribute_test.rb
|
147
|
+
- test/unit/cardinality_test.rb
|
148
|
+
- test/unit/config_test.rb
|
149
|
+
- test/unit/diagram_test.rb
|
150
|
+
- test/unit/domain_test.rb
|
151
|
+
- test/unit/entity_test.rb
|
152
|
+
- test/unit/graphviz_test.rb
|
153
|
+
- test/unit/rake_task_test.rb
|
154
|
+
- test/unit/relationship_test.rb
|
155
|
+
- test/unit/specialization_test.rb
|