rails-erd 1.7.2 → 2.0.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.
@@ -0,0 +1,388 @@
1
+ require File.expand_path("../test_helper", File.dirname(__FILE__))
2
+ require "rails_erd/diagram/mermaid"
3
+
4
+ class MermaidTest < ActiveSupport::TestCase
5
+ def setup
6
+ RailsERD.options.filetype = :png
7
+ RailsERD.options.warn = false
8
+ RailsERD.options.mermaid_style = :classdiagram
9
+ end
10
+
11
+ def teardown
12
+ FileUtils.rm Dir["erd*.*"] rescue nil
13
+ end
14
+
15
+ def diagram(options = {})
16
+ @diagram ||= Diagram::Mermaid.new(Domain.generate(options), options).tap do |diagram|
17
+ diagram.generate
18
+ end
19
+ end
20
+
21
+ def find_dot_nodes(diagram)
22
+ [].tap do |nodes|
23
+ diagram.graph.each_node do |name, node|
24
+ nodes << node
25
+ end
26
+ end
27
+ end
28
+
29
+ # Diagram properties =======================================================
30
+ test "file name should be mmd" do
31
+ create_simple_domain
32
+ begin
33
+ assert_equal "erd.mmd", Diagram::Mermaid.create
34
+ ensure
35
+ FileUtils.rm "erd.mmd" rescue nil
36
+ end
37
+ end
38
+
39
+ test "direction should be top to bottom by default" do
40
+ create_simple_domain
41
+
42
+ assert_equal "\tdirection TB", diagram.graph[1]
43
+ end
44
+
45
+ test "direction should be left to right when orientation is vertical" do
46
+ create_simple_domain
47
+
48
+ d = Diagram::Mermaid.new(Domain.generate, orientation: :vertical).tap { |diag| diag.generate }
49
+ assert_equal "\tdirection LR", d.graph[1]
50
+ end
51
+
52
+
53
+ # # Diagram generation =======================================================
54
+ test "create should create output for domain with attributes" do
55
+ create_model "Foo", :bar => :references, :column => :string do
56
+ belongs_to :bar
57
+ end
58
+
59
+ create_model "Bar", :column => :string
60
+
61
+ expected = [
62
+ "classDiagram",
63
+ "\tdirection TB",
64
+ "\tclass `Bar`",
65
+ "\t`Bar` : +string column",
66
+ "\tclass `Foo`",
67
+ "\t`Foo` : +string column",
68
+ "\t`Bar` --> `Foo`"
69
+ ]
70
+
71
+ assert_equal expected, diagram.graph
72
+ end
73
+
74
+ test "create should create output for domain without attributes" do
75
+ create_simple_domain
76
+
77
+ expected = [
78
+ "classDiagram",
79
+ "\tdirection TB",
80
+ "\tclass `Bar`",
81
+ "\tclass `Beer`",
82
+ "\t`Bar` --> `Beer`"
83
+ ]
84
+
85
+ assert_equal expected, diagram.graph
86
+ end
87
+
88
+ test "create should abort and complain if there are no connected models" do
89
+ message = nil
90
+ begin
91
+ Diagram::Mermaid.create
92
+ rescue => e
93
+ message = e.message
94
+ end
95
+ assert_match(/No entities found/, message)
96
+ end
97
+
98
+ test "create should abort and complain if output directory does not exist" do
99
+ message = nil
100
+
101
+ begin
102
+ create_simple_domain
103
+ Diagram::Mermaid.create(:filename => "does_not_exist/foo")
104
+ rescue => e
105
+ message = e.message
106
+ end
107
+
108
+ assert_match(/Output directory 'does_not_exist' does not exist/, message)
109
+ end
110
+
111
+ test "generate should add attributes to entity" do
112
+ RailsERD.options.markup = false
113
+ create_model "Foo", :bar => :references do
114
+ belongs_to :bar
115
+ end
116
+ create_model "Bar", :column => :string, :column_two => :boolean
117
+
118
+ expected = [
119
+ "classDiagram",
120
+ "\tdirection TB",
121
+ "\tclass `Bar`",
122
+ "\t`Bar` : +string column",
123
+ "\t`Bar` : +boolean column_two",
124
+ "\tclass `Foo`",
125
+ "\t`Bar` --> `Foo`"
126
+ ]
127
+
128
+ assert_equal expected, diagram.graph
129
+ end
130
+
131
+ test "generate should not add any attributes if attributes is set to false" do
132
+ create_model "Jar", :contents => :string
133
+ create_model "Lid", :jar => :references do
134
+ belongs_to :jar
135
+ end
136
+
137
+ expected = [
138
+ "classDiagram",
139
+ "\tdirection TB",
140
+ "\tclass `Jar`",
141
+ "\tclass `Lid`",
142
+ "\t`Jar` --> `Lid`"
143
+ ]
144
+
145
+ assert_equal expected, diagram(:attributes => false).graph
146
+ end
147
+
148
+ test "generate should create edge to polymorphic entity if polymorphism is true" do
149
+ create_model "Cannon", :defensible => :references do
150
+ belongs_to :defensible, :polymorphic => true
151
+ end
152
+
153
+ create_model "Stronghold" do
154
+ has_many :cannons, :as => :defensible
155
+ end
156
+
157
+ create_model "Galleon" do
158
+ has_many :cannons, :as => :defensible
159
+ end
160
+
161
+ expected = [
162
+ "classDiagram",
163
+ "\tdirection TB",
164
+ "\tclass `Cannon`",
165
+ "\tclass `Defensible`",
166
+ "\tclass `Galleon`",
167
+ "\tclass `Stronghold`",
168
+ "\t<<polymorphic>> `Defensible`",
169
+ "\t Defensible <|-- Galleon",
170
+ "\t Defensible <|-- Stronghold",
171
+ "\t`Defensible` --> `Cannon`",
172
+ "\t`Galleon` --> `Cannon`",
173
+ "\t`Stronghold` --> `Cannon`"
174
+ ]
175
+
176
+ assert_equal expected, diagram(:polymorphism => true).graph.uniq
177
+ end
178
+
179
+ test "generate should create edge to each child of polymorphic entity if polymorphism is false" do
180
+ create_model "Cannon", :defensible => :references do
181
+ belongs_to :defensible, :polymorphic => true
182
+ end
183
+
184
+ create_model "Stronghold" do
185
+ has_many :cannons, :as => :defensible
186
+ end
187
+
188
+ create_model "Galleon" do
189
+ has_many :cannons, :as => :defensible
190
+ end
191
+
192
+ expected = [
193
+ "classDiagram",
194
+ "\tdirection TB",
195
+ "\tclass `Cannon`",
196
+ "\tclass `Galleon`",
197
+ "\tclass `Stronghold`",
198
+ "\t`Defensible` --> `Cannon`",
199
+ "\t`Galleon` --> `Cannon`",
200
+ "\t`Stronghold` --> `Cannon`"
201
+ ]
202
+ assert_equal expected, diagram.graph.uniq
203
+ end
204
+
205
+ test "generate should support one to many relationships" do
206
+ create_one_to_many_assoc_domain
207
+
208
+ expected = [
209
+ "classDiagram",
210
+ "\tdirection TB",
211
+ "\tclass `Many`",
212
+ "\tclass `One`",
213
+ "\t`One` --> `Many`"
214
+ ]
215
+
216
+ assert_equal expected, diagram.graph.uniq
217
+ end
218
+
219
+ test "generate should support one to many indirect relationships" do
220
+ create_model "Foo" do
221
+ has_many :bazs
222
+ has_many :bars
223
+ end
224
+
225
+ create_model "Bar", :foo => :references do
226
+ belongs_to :foo
227
+ has_many :bazs, :through => :foo
228
+ end
229
+
230
+ create_model "Baz", :foo => :references do
231
+ belongs_to :foo
232
+ end
233
+
234
+ expected = [
235
+ "classDiagram",
236
+ "\tdirection TB",
237
+ "\tclass `Bar`",
238
+ "\tclass `Baz`",
239
+ "\tclass `Foo`",
240
+ "\t`Foo` --> `Baz`",
241
+ "\t`Foo` --> `Bar`",
242
+ "\t`Bar` ..> `Baz`"
243
+ ]
244
+
245
+ assert_equal expected, diagram.graph.uniq
246
+ end
247
+
248
+ test "generate should support many to many relationships" do
249
+ create_many_to_many_assoc_domain
250
+
251
+ expected = [
252
+ "classDiagram",
253
+ "\tdirection TB",
254
+ "\tclass `Many`",
255
+ "\tclass `More`",
256
+ "\t`Many` <--> `More`"
257
+ ]
258
+
259
+ assert_equal expected, diagram.graph.uniq
260
+ end
261
+
262
+ test "generate should support one to one relationships" do
263
+ create_one_to_one_assoc_domain
264
+
265
+ expected = [
266
+ "classDiagram",
267
+ "\tdirection TB",
268
+ "\tclass `One`",
269
+ "\tclass `Other`",
270
+ "\t`One` -- `Other`"
271
+ ]
272
+
273
+ assert_equal expected, diagram.graph.uniq
274
+ end
275
+
276
+ test "generate should support one to one recursive relationships" do
277
+ create_model "Emperor" do
278
+ belongs_to :predecessor, :class_name => "Emperor"
279
+ has_one :successor, :class_name => "Emperor", :foreign_key => :predecessor_id
280
+ end
281
+
282
+ expected = [
283
+ "classDiagram",
284
+ "\tdirection TB",
285
+ "\tclass `Emperor`",
286
+ "\t`Emperor` -- `Emperor`"
287
+ ]
288
+
289
+ assert_equal expected, diagram.graph.uniq
290
+ end
291
+
292
+ # erDiagram tests ============================================================
293
+
294
+ test "erdiagram style should use erDiagram header" do
295
+ create_simple_domain
296
+
297
+ result = diagram(:mermaid_style => :erdiagram).graph.uniq
298
+
299
+ assert_equal "erDiagram", result[0]
300
+ assert_equal "\tdirection TB", result[1]
301
+ # Entity blocks are joined with newlines
302
+ assert result.any? { |line| line.include?("Bar {") }
303
+ assert result.any? { |line| line.include?("Beer {") }
304
+ # Relationship uses crow's foot notation
305
+ assert result.any? { |line| line.include?("Bar") && line.include?("Beer") && line.include?("--") }
306
+ end
307
+
308
+ test "erdiagram style should include attributes with PK/FK markers" do
309
+ create_model "Foo", :bar => :references, :column => :string do
310
+ belongs_to :bar
311
+ end
312
+
313
+ create_model "Bar", :column => :string
314
+
315
+ result = diagram(:mermaid_style => :erdiagram, :attributes => [:primary_keys, :foreign_keys, :content]).graph.join("\n")
316
+
317
+ assert result.include?("erDiagram")
318
+ assert result.include?("id PK"), "Should include primary key marker"
319
+ assert result.include?("bar_id FK"), "Should include foreign key marker"
320
+ end
321
+
322
+ test "erdiagram style should use crow's foot notation for one to many" do
323
+ create_one_to_many_assoc_domain
324
+
325
+ result = diagram(:mermaid_style => :erdiagram).graph.uniq
326
+
327
+ assert result.include?("erDiagram")
328
+ # One to many should have }| or }o on the "many" side
329
+ relationship_line = result.find { |line| line.include?("One") && line.include?("Many") && line.include?("--") }
330
+ assert relationship_line, "Should have a relationship line between One and Many"
331
+ assert relationship_line.match?(/\}\||\}o/), "Should use crow's foot notation for many side"
332
+ end
333
+
334
+ test "erdiagram style should use crow's foot notation for many to many" do
335
+ create_many_to_many_assoc_domain
336
+
337
+ result = diagram(:mermaid_style => :erdiagram).graph.uniq
338
+
339
+ assert result.include?("erDiagram")
340
+ # Many to many should have }| or }o on both sides
341
+ relationship_line = result.find { |line| line.include?("Many") && line.include?("More") && line.include?("--") }
342
+ assert relationship_line, "Should have a relationship line between Many and More"
343
+ end
344
+
345
+ test "erdiagram style should use crow's foot notation for one to one" do
346
+ create_one_to_one_assoc_domain
347
+
348
+ result = diagram(:mermaid_style => :erdiagram).graph.uniq
349
+
350
+ assert result.any? { |line| line.include?("erDiagram") }
351
+ # One to one should have | on both sides (not })
352
+ relationship_line = result.find { |line| line.include?("One") && line.include?("Other") && line.include?("--") }
353
+ assert relationship_line, "Should have a relationship line between One and Other"
354
+ # Should not have } which indicates "many"
355
+ refute relationship_line.include?("}"), "One-to-one should not use } (many) notation: #{relationship_line}"
356
+ end
357
+
358
+ test "erdiagram style should use dotted line for indirect relationships" do
359
+ create_model "Foo" do
360
+ has_many :bazs
361
+ has_many :bars
362
+ end
363
+
364
+ create_model "Bar", :foo => :references do
365
+ belongs_to :foo
366
+ has_many :bazs, :through => :foo
367
+ end
368
+
369
+ create_model "Baz", :foo => :references do
370
+ belongs_to :foo
371
+ end
372
+
373
+ result = diagram(:mermaid_style => :erdiagram).graph.uniq
374
+
375
+ # Indirect relationship should use .. instead of --
376
+ indirect_line = result.find { |line| line.include?("Bar") && line.include?("Baz") }
377
+ assert indirect_line, "Should have a relationship line between Bar and Baz"
378
+ assert indirect_line.include?(".."), "Indirect relationship should use dotted line"
379
+ end
380
+
381
+ test "er option alias should work same as erdiagram" do
382
+ create_simple_domain
383
+
384
+ result = diagram(:mermaid_style => :er).graph
385
+
386
+ assert result.include?("erDiagram")
387
+ end
388
+ end
@@ -1,4 +1,6 @@
1
1
  require File.expand_path("../test_helper", File.dirname(__FILE__))
2
+ require "rails_erd/diagram/graphviz"
3
+ require "rails_erd/diagram/mermaid"
2
4
 
3
5
  class RakeTaskTest < ActiveSupport::TestCase
4
6
  include ActiveSupport::Testing::Isolation
@@ -32,10 +34,20 @@ class RakeTaskTest < ActiveSupport::TestCase
32
34
  end
33
35
 
34
36
  # Diagram generation =======================================================
35
- test "generate task should create output based on domain model" do
37
+ test "generate task should create output based on domain model with graphviz by default" do
36
38
  create_simple_domain
37
39
 
38
40
  Diagram.any_instance.expects(:save)
41
+ Rake::Task["erd:options"].execute
42
+ Rake::Task["erd:generate"].execute
43
+ end
44
+
45
+ test "generate task should create output based on domain model with mermaid" do
46
+ create_simple_domain
47
+
48
+ ENV["generator"] = "mermaid"
49
+ RailsERD::Diagram::Mermaid.any_instance.expects(:save)
50
+ Rake::Task["erd:options"].execute
39
51
  Rake::Task["erd:generate"].execute
40
52
  end
41
53
 
@@ -101,7 +113,7 @@ class RakeTaskTest < ActiveSupport::TestCase
101
113
  rescue => e
102
114
  message = e.message
103
115
  end
104
- assert_match(/#{Regexp.escape(<<-MSG.strip).gsub("xxx", ".*?")}/, message
116
+ assert_match(/#{Regexp.escape(<<-MSG.strip).gsub("`xxx'", "(`|').*?")}/, message
105
117
  Loading models failed!
106
118
  Error occurred while loading application: FooBar (RuntimeError)
107
119
  test/unit/rake_task_test.rb:#{l1}:in `xxx'
@@ -186,6 +198,15 @@ Error occurred while loading application: FooBar (RuntimeError)
186
198
  assert_equal :test, RailsERD.options.only_recursion_depth
187
199
  end
188
200
 
201
+ test "options task sets generator type" do
202
+ Rake::Task["erd:options"].execute
203
+ assert_equal :mermaid, RailsERD.options.generator
204
+
205
+ ENV["generator"] = "graphviz"
206
+ Rake::Task["erd:options"].execute
207
+ assert_equal :graphviz, RailsERD.options.generator
208
+ end
209
+
189
210
  test "options task should set single parameter to only as array xxx" do
190
211
  ENV["only"] = "model"
191
212
  Rake::Task["erd:options"].execute
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-erd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rolf Timmermans
8
8
  - Kerri Miller
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2022-08-13 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activerecord
@@ -17,56 +16,70 @@ dependencies:
17
16
  requirements:
18
17
  - - ">="
19
18
  - !ruby/object:Gem::Version
20
- version: '4.2'
19
+ version: '7.0'
21
20
  type: :runtime
22
21
  prerelease: false
23
22
  version_requirements: !ruby/object:Gem::Requirement
24
23
  requirements:
25
24
  - - ">="
26
25
  - !ruby/object:Gem::Version
27
- version: '4.2'
26
+ version: '7.0'
28
27
  - !ruby/object:Gem::Dependency
29
28
  name: activesupport
30
29
  requirement: !ruby/object:Gem::Requirement
31
30
  requirements:
32
31
  - - ">="
33
32
  - !ruby/object:Gem::Version
34
- version: '4.2'
33
+ version: '7.0'
35
34
  type: :runtime
36
35
  prerelease: false
37
36
  version_requirements: !ruby/object:Gem::Requirement
38
37
  requirements:
39
38
  - - ">="
40
39
  - !ruby/object:Gem::Version
41
- version: '4.2'
40
+ version: '7.0'
42
41
  - !ruby/object:Gem::Dependency
43
- name: ruby-graphviz
42
+ name: choice
44
43
  requirement: !ruby/object:Gem::Requirement
45
44
  requirements:
46
45
  - - "~>"
47
46
  - !ruby/object:Gem::Version
48
- version: '1.2'
47
+ version: 0.2.0
49
48
  type: :runtime
50
49
  prerelease: false
51
50
  version_requirements: !ruby/object:Gem::Requirement
52
51
  requirements:
53
52
  - - "~>"
54
53
  - !ruby/object:Gem::Version
55
- version: '1.2'
54
+ version: 0.2.0
56
55
  - !ruby/object:Gem::Dependency
57
- name: choice
56
+ name: ostruct
58
57
  requirement: !ruby/object:Gem::Requirement
59
58
  requirements:
60
- - - "~>"
59
+ - - ">="
61
60
  - !ruby/object:Gem::Version
62
- version: 0.2.0
61
+ version: '0'
63
62
  type: :runtime
64
63
  prerelease: false
65
64
  version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: ruby-graphviz
71
+ requirement: !ruby/object:Gem::Requirement
66
72
  requirements:
67
73
  - - "~>"
68
74
  - !ruby/object:Gem::Version
69
- version: 0.2.0
75
+ version: '1.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.2'
70
83
  - !ruby/object:Gem::Dependency
71
84
  name: pry
72
85
  requirement: !ruby/object:Gem::Requirement
@@ -117,6 +130,7 @@ files:
117
130
  - lib/rails_erd/config.rb
118
131
  - lib/rails_erd/diagram.rb
119
132
  - lib/rails_erd/diagram/graphviz.rb
133
+ - lib/rails_erd/diagram/mermaid.rb
120
134
  - lib/rails_erd/diagram/templates/node.html.erb
121
135
  - lib/rails_erd/diagram/templates/node.record.erb
122
136
  - lib/rails_erd/domain.rb
@@ -130,16 +144,19 @@ files:
130
144
  - lib/rails_erd/version.rb
131
145
  - lib/tasks/auto_generate_diagram.rake
132
146
  - test/support_files/erdconfig.another_example
147
+ - test/support_files/erdconfig.empty
133
148
  - test/support_files/erdconfig.example
134
149
  - test/support_files/erdconfig.exclude.example
135
150
  - test/test_helper.rb
136
151
  - test/unit/attribute_test.rb
137
152
  - test/unit/cardinality_test.rb
153
+ - test/unit/cli_test.rb
138
154
  - test/unit/config_test.rb
139
155
  - test/unit/diagram_test.rb
140
156
  - test/unit/domain_test.rb
141
157
  - test/unit/entity_test.rb
142
158
  - test/unit/graphviz_test.rb
159
+ - test/unit/mermaid_test.rb
143
160
  - test/unit/rake_task_test.rb
144
161
  - test/unit/relationship_test.rb
145
162
  - test/unit/specialization_test.rb
@@ -147,7 +164,6 @@ homepage: https://github.com/voormedia/rails-erd
147
164
  licenses:
148
165
  - MIT
149
166
  metadata: {}
150
- post_install_message:
151
167
  rdoc_options: []
152
168
  require_paths:
153
169
  - lib
@@ -155,29 +171,31 @@ required_ruby_version: !ruby/object:Gem::Requirement
155
171
  requirements:
156
172
  - - ">="
157
173
  - !ruby/object:Gem::Version
158
- version: '2.2'
174
+ version: '3.1'
159
175
  required_rubygems_version: !ruby/object:Gem::Requirement
160
176
  requirements:
161
177
  - - ">="
162
178
  - !ruby/object:Gem::Version
163
179
  version: '0'
164
180
  requirements: []
165
- rubygems_version: 3.3.15
166
- signing_key:
181
+ rubygems_version: 4.0.10
167
182
  specification_version: 4
168
183
  summary: Entity-relationship diagram for your Rails models.
169
184
  test_files:
170
185
  - test/support_files/erdconfig.another_example
186
+ - test/support_files/erdconfig.empty
171
187
  - test/support_files/erdconfig.example
172
188
  - test/support_files/erdconfig.exclude.example
173
189
  - test/test_helper.rb
174
190
  - test/unit/attribute_test.rb
175
191
  - test/unit/cardinality_test.rb
192
+ - test/unit/cli_test.rb
176
193
  - test/unit/config_test.rb
177
194
  - test/unit/diagram_test.rb
178
195
  - test/unit/domain_test.rb
179
196
  - test/unit/entity_test.rb
180
197
  - test/unit/graphviz_test.rb
198
+ - test/unit/mermaid_test.rb
181
199
  - test/unit/rake_task_test.rb
182
200
  - test/unit/relationship_test.rb
183
201
  - test/unit/specialization_test.rb