rails-erd 1.0.0 → 1.1.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/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2012 Voormedia B.V.
1
+ Copyright (c) 2010-2013 Voormedia B.V.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -51,7 +51,7 @@ About Rails ERD
51
51
 
52
52
  Rails ERD was created by Rolf Timmermans (r.timmermans *at* voormedia.com)
53
53
 
54
- Copyright 2010-2012 Voormedia - [www.voormedia.com](http://www.voormedia.com/)
54
+ Copyright 2010-2013 Voormedia - [www.voormedia.com](http://www.voormedia.com/)
55
55
 
56
56
 
57
57
  License
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  require "bundler"
2
2
  require "rake/testtask"
3
+ require "yard"
3
4
 
4
5
  Bundler::GemHelper.install_tasks
5
6
 
@@ -7,59 +8,13 @@ Rake::TestTask.new do |test|
7
8
  test.test_files = FileList["test/**/*_test.rb"]
8
9
  end
9
10
 
10
- task :default => :test
11
+ YARD::Rake::YardocTask.new do |yard|
12
+ yard.files = ["lib/**/*.rb", "-", "LICENSE", "CHANGES.md"]
13
+ end
11
14
 
12
- # # encoding: utf-8
13
- # require "jeweler"
14
- # require "rake/testtask"
15
- #
16
- # Jeweler::Tasks.new do |spec|
17
- # spec.name = "rails-erd"
18
- # spec.rubyforge_project = "rails-erd"
19
- # spec.summary = "Entity-relationship diagram for your Rails models."
20
- # spec.description = "Automatically generate an entity-relationship diagram (ERD) for your Rails models."
21
- #
22
- # spec.authors = ["Rolf Timmermans"]
23
- # spec.email = "r.timmermans@voormedia.com"
24
- # spec.homepage = "http://rails-erd.rubyforge.org/"
25
- #
26
- # # Don't bundle examples or website in gem.
27
- # excluded = Dir["{examples,site}/**/*"]
28
- # spec.files -= excluded
29
- # spec.test_files -= excluded
30
- # end
31
- #
32
- # Jeweler::GemcutterTasks.new
33
- #
34
- # Jeweler::RubyforgeTasks.new do |rubyforge|
35
- # rubyforge.doc_task = "rdoc"
36
- # rubyforge.remote_doc_path = "doc"
37
- # end
38
- #
39
- # Rake::TestTask.new do |test|
40
- # test.pattern = "test/unit/**/*_test.rb"
41
- # end
42
- #
43
- # task :default => :test
44
- #
45
- # begin
46
- # require "hanna/rdoctask"
47
- # Rake::RDocTask.new do |rdoc|
48
- # rdoc.rdoc_files = %w{CHANGES.rdoc LICENSE} + Dir["lib/**/*.rb"]
49
- # rdoc.title = "Rails ERD – API Documentation"
50
- # rdoc.rdoc_dir = "rdoc"
51
- # rdoc.main = "RailsERD"
52
- # end
53
- # rescue LoadError
54
- # end
55
- #
56
- # desc "Generate diagrams for bundled examples"
57
- # task :examples do
58
- # require File.expand_path("examples/generate", File.dirname(__FILE__))
59
- # end
60
- #
61
- # namespace :examples do
62
- # task :sfdp do
63
- # require File.expand_path("examples/sfdp", File.dirname(__FILE__))
64
- # end
65
- # end
15
+ desc "Generate diagrams for bundled examples"
16
+ task :examples do
17
+ require File.expand_path("examples/generate", File.dirname(__FILE__))
18
+ end
19
+
20
+ task :default => :test
data/lib/rails_erd/cli.rb CHANGED
@@ -34,7 +34,7 @@ Choice.options do
34
34
 
35
35
  option :polymorphism do
36
36
  long "--polymorphism"
37
- desc "Display polymorphic relationships."
37
+ desc "Display polymorphic and abstract entities."
38
38
  end
39
39
 
40
40
  option :no_indirect do
@@ -47,6 +47,16 @@ Choice.options do
47
47
  desc "Omit entities without relationships."
48
48
  end
49
49
 
50
+ option :only do
51
+ long "--only"
52
+ desc "Filter to only include listed models in diagram."
53
+ end
54
+
55
+ option :exclude do
56
+ long "--exclude"
57
+ desc "Filter to exclude listed models in diagram."
58
+ end
59
+
50
60
  separator ""
51
61
  separator "Output options:"
52
62
 
@@ -5,7 +5,7 @@ require "erb"
5
5
 
6
6
  # Fix bad RegEx test in Ruby-Graphviz.
7
7
  GraphViz::Types::LblString.class_eval do
8
- def output
8
+ def output # @private :nodoc:
9
9
  if /^<.*>$/m =~ @data
10
10
  @data
11
11
  else
@@ -84,7 +84,7 @@ module RailsERD
84
84
  module Simple
85
85
  def entity_style(entity, attributes)
86
86
  {}.tap do |options|
87
- options[:fontcolor] = options[:color] = :grey60 if entity.abstract?
87
+ options[:fontcolor] = options[:color] = :grey60 if entity.virtual?
88
88
  end
89
89
  end
90
90
 
@@ -188,7 +188,8 @@ module RailsERD
188
188
  save do
189
189
  raise "Saving diagram failed!\nOutput directory '#{File.dirname(filename)}' does not exist." unless File.directory?(File.dirname(filename))
190
190
  begin
191
- graph.output(filetype => filename)
191
+ # GraphViz doesn't like spaces in the filename
192
+ graph.output(filetype => filename.gsub(/\s/,"\\ "))
192
193
  filename
193
194
  rescue RuntimeError => e
194
195
  raise "Saving diagram failed!\nGraphviz produced errors. Verify it has support for filetype=#{options.filetype}, or use filetype=dot." <<
@@ -210,10 +211,11 @@ module RailsERD
210
211
  each_relationship do |relationship|
211
212
  from, to = relationship.source, relationship.destination
212
213
  unless draw_edge from.name, to.name, relationship_options(relationship)
213
- if from.children.any?
214
- from.children.each do |child|
215
- draw_edge child.name, to.name, relationship_options(relationship)
216
- end
214
+ from.children.each do |child|
215
+ draw_edge child.name, to.name, relationship_options(relationship)
216
+ end
217
+ to.children.each do |child|
218
+ draw_edge from.name, child.name, relationship_options(relationship)
217
219
  end
218
220
  end
219
221
  end
@@ -114,7 +114,7 @@ module RailsERD
114
114
  end
115
115
 
116
116
  def models
117
- @models ||= @source_models.reject(&:abstract_class?).select { |model| check_model_validity(model) }
117
+ @models ||= @source_models.select { |model| check_model_validity(model) }
118
118
  end
119
119
 
120
120
  def associations
@@ -122,7 +122,7 @@ module RailsERD
122
122
  end
123
123
 
124
124
  def check_model_validity(model)
125
- model.table_exists? or raise "table #{model.table_name} does not exist"
125
+ model.abstract_class? or model.table_exists? or raise "table #{model.table_name} does not exist"
126
126
  rescue => e
127
127
  warn "Ignoring invalid model #{model.name} (#{e.message})"
128
128
  end
@@ -62,12 +62,13 @@ module RailsERD
62
62
  end
63
63
 
64
64
  # Returns +true+ if this entity is a generalization, which does not
65
- # correspond with a database table. Generalized entities are constructed
65
+ # correspond with a database table. Generalized entities are either
66
+ # models that are defined as +abstract_class+ or they are constructed
66
67
  # from polymorphic interfaces. Any +has_one+ or +has_many+ association
67
68
  # that defines a polymorphic interface with <tt>:as => :name</tt> will
68
69
  # lead to a generalized entity to be created.
69
70
  def generalized?
70
- !model
71
+ !model or !!model.abstract_class?
71
72
  end
72
73
 
73
74
  # Returns +true+ if this entity descends from another entity, and is
@@ -75,15 +76,16 @@ module RailsERD
75
76
  # referred to as single-table inheritance. In entity-relationship
76
77
  # diagrams it is called specialization.
77
78
  def specialized?
78
- !generalized? and !model.descends_from_active_record?
79
+ !!model and !model.descends_from_active_record?
79
80
  end
80
81
 
81
82
  # Returns +true+ if this entity does not correspond directly with a
82
83
  # database table (if and only if the entity is specialized or
83
84
  # generalized).
84
- def abstract?
85
- specialized? or generalized?
85
+ def virtual?
86
+ generalized? or specialized?
86
87
  end
88
+ alias_method :abstract?, :virtual?
87
89
 
88
90
  # Returns all child entities, if this is a generalized entity.
89
91
  def children
@@ -31,7 +31,7 @@ module RailsERD
31
31
  # numbers (for source and destination). Can be any of
32
32
  # +:one_to_one:+, +:one_to_many+, or +:many_to_many+. The name
33
33
  # +:many_to_one+ also exists, but Rails ERD always normalises these
34
- # kinds of relationships by inversing them, so they become
34
+ # kinds of relationships by inverting them, so they become
35
35
  # +:one_to_many+ associations.
36
36
  #
37
37
  # You can also call the equivalent method with a question mark, which
@@ -1,12 +1,16 @@
1
1
  module RailsERD
2
2
  class Domain
3
3
  # Describes the specialization of an entity. Specialized entites correspond
4
- # to inheritance. In Rails, specialization is referred to as single table
5
- # inheritance.
4
+ # to inheritance or polymorphism. In Rails, specialization is referred to
5
+ # as single table inheritance, while generalization is referred to as
6
+ # polymorphism or abstract classes.
6
7
  class Specialization
7
8
  class << self
8
9
  def from_models(domain, models) # @private :nodoc:
9
- (inheritance_from_models(domain, models) + polymorphic_from_models(domain, models)).sort
10
+ models = polymorphic_from_models(domain, models) +
11
+ inheritance_from_models(domain, models) +
12
+ abstract_from_models(domain, models)
13
+ models.sort
10
14
  end
11
15
 
12
16
  private
@@ -24,6 +28,12 @@ module RailsERD
24
28
  new(domain, domain.entity_by_name(model.base_class.name), domain.entity_by_name(model.name))
25
29
  }
26
30
  end
31
+
32
+ def abstract_from_models(domain, models)
33
+ models.select(&:abstract_class?).collect(&:descendants).flatten.collect { |model|
34
+ new(domain, domain.entity_by_name(model.superclass.name), domain.entity_by_name(model.name))
35
+ }
36
+ end
27
37
  end
28
38
 
29
39
  extend Inspectable
@@ -42,13 +52,15 @@ module RailsERD
42
52
  @domain, @generalized, @specialized = domain, generalized, specialized
43
53
  end
44
54
 
45
- def inheritance?
46
- !polymorphic?
55
+ def generalization?
56
+ generalized.generalized?
47
57
  end
58
+ alias_method :polymorphic?, :generalization?
48
59
 
49
- def polymorphic?
50
- generalized.generalized?
60
+ def specialization?
61
+ !generalization?
51
62
  end
63
+ alias_method :inheritance?, :specialization?
52
64
 
53
65
  def <=>(other) # @private :nodoc:
54
66
  (generalized.name <=> other.generalized.name).nonzero? or (specialized.name <=> other.specialized.name)
@@ -1,4 +1,4 @@
1
1
  module RailsERD
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  BANNER = "RailsERD #{VERSION}"
4
4
  end
data/test/test_helper.rb CHANGED
@@ -39,10 +39,11 @@ class ActiveSupport::TestCase
39
39
  superklass = args.first.kind_of?(Class) ? args.shift : ActiveRecord::Base
40
40
  columns = args.first || {}
41
41
  klass = Object.const_set name.to_sym, Class.new(superklass)
42
- klass.class_eval(&block) if block_given?
43
- if superklass == ActiveRecord::Base
42
+ if superklass == ActiveRecord::Base || superklass.abstract_class?
44
43
  create_table Object.const_get(name.to_sym).table_name, columns, Object.const_get(name.to_sym).primary_key rescue nil
45
44
  end
45
+ klass.class_eval(&block) if block_given?
46
+ Object.const_get(name.to_sym)
46
47
  end
47
48
 
48
49
  def create_models(*names)
@@ -98,16 +99,23 @@ class ActiveSupport::TestCase
98
99
 
99
100
  def create_specialization
100
101
  create_model "Beverage", :type => :string
101
- Object.const_set :Beer, Class.new(Beverage)
102
+ create_model "Beer", Beverage
102
103
  end
103
104
 
104
- def create_generalization
105
+ def create_polymorphic_generalization
105
106
  create_model "Cannon"
106
107
  create_model "Galleon" do
107
108
  has_many :cannons, :as => :defensible
108
109
  end
109
110
  end
110
111
 
112
+ def create_abstract_generalization
113
+ create_model "Structure" do
114
+ self.abstract_class = true
115
+ end
116
+ create_model "Palace", Structure
117
+ end
118
+
111
119
  private
112
120
 
113
121
  def reset_domain
@@ -266,26 +266,30 @@ class DiagramTest < ActiveSupport::TestCase
266
266
  # Specialization filtering =================================================
267
267
  test "generate should not yield specializations" do
268
268
  create_specialization
269
- create_generalization
269
+ create_polymorphic_generalization
270
+ create_abstract_generalization
270
271
  assert_equal [], retrieve_specializations
271
272
  end
272
273
 
273
274
  test "generate should yield specializations but not generalizations if inheritance is true" do
274
275
  create_specialization
275
- create_generalization
276
+ create_polymorphic_generalization
277
+ create_abstract_generalization
276
278
  assert_equal ["Beer"], retrieve_specializations(:inheritance => true).map { |s| s.specialized.name }
277
279
  end
278
280
 
279
281
  test "generate should yield generalizations but not specializations if polymorphism is true" do
280
282
  create_specialization
281
- create_generalization
282
- assert_equal ["Galleon"], retrieve_specializations(:polymorphism => true).map { |s| s.specialized.name }
283
+ create_polymorphic_generalization
284
+ create_abstract_generalization
285
+ assert_equal ["Galleon", "Palace"], retrieve_specializations(:polymorphism => true).map { |s| s.specialized.name }
283
286
  end
284
287
 
285
288
  test "generate should yield specializations and generalizations if polymorphism and inheritance is true" do
286
289
  create_specialization
287
- create_generalization
288
- assert_equal ["Beer", "Galleon"], retrieve_specializations(:inheritance => true,
290
+ create_polymorphic_generalization
291
+ create_abstract_generalization
292
+ assert_equal ["Beer", "Galleon", "Palace"], retrieve_specializations(:inheritance => true,
289
293
  :polymorphism => true).map { |s| s.specialized.name }
290
294
  end
291
295
 
@@ -64,14 +64,12 @@ class DomainTest < ActiveSupport::TestCase
64
64
  assert_equal ["Defensible", "Galleon", "Stronghold"], Domain.generate.entities.collect(&:name)
65
65
  end
66
66
 
67
- test "entities should omit abstract models" do
68
- Object.const_set :Foo, Class.new(ActiveRecord::Base) { self.abstract_class = true }
69
- create_model "Bar", Foo do
70
- self.table_name = "bars"
67
+ test "entities should include abstract models" do
68
+ create_model "Structure" do
69
+ self.abstract_class = true
71
70
  end
72
- create_table "foos", {}, true
73
- create_table "bars", {}, true
74
- assert_equal ["Bar"], Domain.generate.entities.collect(&:name)
71
+ create_model "Palace", Structure
72
+ assert_equal ["Palace", "Structure"], Domain.generate.entities.collect(&:name)
75
73
  end
76
74
 
77
75
  # Relationship processing ==================================================
@@ -160,37 +158,22 @@ class DomainTest < ActiveSupport::TestCase
160
158
  assert_equal [Domain::Specialization] * 2, Domain.generate.specializations.collect(&:class)
161
159
  end
162
160
 
163
- test "specializations should return generalizations in domain model" do
164
- create_model "Post" do
165
- has_many :assets, :as => :attachable
166
- end
167
- create_model "Asset", :attachable => :references do
168
- belongs_to :attachable, :polymorphic => true
169
- end
161
+ test "specializations should return polymorphic generalizations in domain model" do
162
+ create_polymorphic_generalization
170
163
  assert_equal [Domain::Specialization], Domain.generate.specializations.collect(&:class)
171
164
  end
172
165
 
173
- test "specializations should return generalizations and specializations in domain model" do
174
- create_model "Content", :type => :string do
175
- has_many :assets, :as => :attachable
176
- end
177
- Object.const_set :Post, Class.new(Content)
178
- create_model "Asset", :attachable => :references do
179
- belongs_to :attachable, :polymorphic => true
180
- end
181
- assert_equal [Domain::Specialization] * 2, Domain.generate.specializations.collect(&:class)
166
+ test "specializations should return abstract generalizations in domain model" do
167
+ create_abstract_generalization
168
+ assert_equal [Domain::Specialization], Domain.generate.specializations.collect(&:class)
182
169
  end
183
170
 
184
- # test "generalizations should ..." do
185
- # # TODO
186
- # create_model "Post" do
187
- # has_many :assets, :as => :attachable
188
- # end
189
- # create_model "Asset", :attachable => :references do
190
- # belongs_to :attachable, :polymorphic => true
191
- # end
192
- # assert_equal [], Domain.generate.relationships
193
- # end
171
+ test "specializations should return polymorphic and abstract generalizations and specializations in domain model" do
172
+ create_specialization
173
+ create_polymorphic_generalization
174
+ create_abstract_generalization
175
+ assert_equal [Domain::Specialization] * 3, Domain.generate.specializations.collect(&:class)
176
+ end
194
177
 
195
178
  # Erroneous associations ===================================================
196
179
  test "relationships should omit bad has_many associations" do
@@ -236,7 +219,7 @@ class DomainTest < ActiveSupport::TestCase
236
219
  assert_match /model Bar exists, but is not included in domain/, output
237
220
  end
238
221
 
239
- test "relationships should output a warning when an association to a non existent generalization is encountere" do
222
+ test "relationships should output a warning when an association to a non existent generalization is encountered" do
240
223
  create_model "Foo" do
241
224
  has_many :bars, :as => :foo
242
225
  end
@@ -9,6 +9,11 @@ class EntityTest < ActiveSupport::TestCase
9
9
  Domain::Entity.new(Domain.new, name)
10
10
  end
11
11
 
12
+ def create_abstract_entity(name)
13
+ model = create_model(name) { self.abstract_class = true }
14
+ create_entity(model)
15
+ end
16
+
12
17
  # Entity ===================================================================
13
18
  test "model should return active record model" do
14
19
  create_models "Foo"
@@ -63,36 +68,6 @@ class EntityTest < ActiveSupport::TestCase
63
68
  assert_equal domain.relationships.select { |r| r.destination == foo }, foo.relationships
64
69
  end
65
70
 
66
- # test "parent should return nil for regular entities" do
67
- # create_model "Foo"
68
- # assert_nil create_entity(Foo).parent
69
- # end
70
- #
71
- # test "parent should return nil for specialized entities with distinct tables" do
72
- # create_model "Foo", :type => :string
73
- # Object.const_set :SpecialFoo, Class.new(Foo)
74
- # SpecialFoo.class_eval do
75
- # self.table_name = "special_foo"
76
- # end
77
- # create_table "special_foo", {}, true
78
- # assert_nil create_entity(SpecialFoo).parent
79
- # end
80
- #
81
- # test "parent should return parent entity for specialized entities" do
82
- # create_model "Foo", :type => :string
83
- # Object.const_set :SpecialFoo, Class.new(Foo)
84
- # domain = Domain.generate
85
- # assert_equal domain.entity_by_name("Foo"), Domain::Entity.from_models(domain, [SpecialFoo]).first.parent
86
- # end
87
- #
88
- # test "parent should return parent entity for specializations of specialized entities" do
89
- # create_model "Foo", :type => :string
90
- # Object.const_set :SpecialFoo, Class.new(Foo)
91
- # Object.const_set :VerySpecialFoo, Class.new(SpecialFoo)
92
- # domain = Domain.generate
93
- # assert_equal domain.entity_by_name("SpecialFoo"), Domain::Entity.from_models(domain, [VerySpecialFoo]).first.parent
94
- # end
95
-
96
71
  # Entity properties ========================================================
97
72
  test "connected should return false for unconnected entities" do
98
73
  create_models "Foo", "Bar"
@@ -148,10 +123,10 @@ class EntityTest < ActiveSupport::TestCase
148
123
  assert_equal true, create_entity(VerySpecialFoo).specialized?
149
124
  end
150
125
 
151
- test "abstract should return true for specialized entity" do
126
+ test "virtual should return true for specialized entity" do
152
127
  create_model "Foo", :type => :string
153
128
  Object.const_set :SpecialFoo, Class.new(Foo)
154
- assert_equal true, create_entity(SpecialFoo).abstract?
129
+ assert_equal true, create_entity(SpecialFoo).virtual?
155
130
  end
156
131
 
157
132
  test "generalized should return false for regular entity" do
@@ -159,9 +134,9 @@ class EntityTest < ActiveSupport::TestCase
159
134
  assert_equal false, create_entity(Concrete).generalized?
160
135
  end
161
136
 
162
- test "abstract should return false for regular entity" do
137
+ test "virtual should return false for regular entity" do
163
138
  create_model "Concrete"
164
- assert_equal false, create_entity(Concrete).abstract?
139
+ assert_equal false, create_entity(Concrete).virtual?
165
140
  end
166
141
 
167
142
  # Attribute processing =====================================================
@@ -196,8 +171,8 @@ class EntityTest < ActiveSupport::TestCase
196
171
  assert_equal false, create_generalized_entity("MyAbstractModel").specialized?
197
172
  end
198
173
 
199
- test "abstract should return true for generalized entity" do
200
- assert_equal true, create_generalized_entity("MyAbstractModel").abstract?
174
+ test "virtual should return true for generalized entity" do
175
+ assert_equal true, create_generalized_entity("MyAbstractModel").virtual?
201
176
  end
202
177
 
203
178
  test "relationships should return relationships for generalized entity" do
@@ -213,17 +188,37 @@ class EntityTest < ActiveSupport::TestCase
213
188
  assert_equal domain.relationships, defensible.relationships
214
189
  end
215
190
 
216
- test "relationships should return relationships for generalized entity in reverse alphabetic order" do
217
- create_model "Stronghold" do
218
- has_many :cannons, :as => :defensible
219
- end
220
- create_model "Cannon", :defensible => :references do
221
- belongs_to :defensible, :polymorphic => true
191
+ # Abstract generalized entity ==============================================
192
+ test "name should return given name for abstract generalized entity" do
193
+ assert_equal "MyAbstractModel", create_abstract_entity("MyAbstractModel").name
194
+ end
195
+
196
+ test "attributes should return empty array for abstract generalized entity" do
197
+ assert_equal [], create_abstract_entity("MyAbstractModel").attributes
198
+ end
199
+
200
+ test "generalized should return true for abstract generalized entity" do
201
+ assert_equal true, create_abstract_entity("MyAbstractModel").generalized?
202
+ end
203
+
204
+ test "specialized should return false for abstract generalized entity" do
205
+ assert_equal false, create_abstract_entity("MyAbstractModel").specialized?
206
+ end
207
+
208
+ test "virtual should return true for abstract generalized entity" do
209
+ assert_equal true, create_abstract_entity("MyAbstractModel").virtual?
210
+ end
211
+
212
+ test "relationships should return relationships for abstract generalized entity" do
213
+ create_model "Kingdom"
214
+ create_model "Structure" do
215
+ self.abstract_class = true
216
+ belongs_to :kingdom
222
217
  end
218
+ create_model "Palace", Structure, :kingdom => :references
223
219
 
224
220
  domain = Domain.generate
225
- defensible = domain.entity_by_name("Defensible")
226
- assert_equal domain.relationships, defensible.relationships
221
+ assert_equal domain.relationships, domain.entity_by_name("Structure").relationships
227
222
  end
228
223
 
229
224
  # Children =================================================================
@@ -8,7 +8,7 @@ class GraphvizTest < ActiveSupport::TestCase
8
8
  end
9
9
 
10
10
  def teardown
11
- FileUtils.rm Dir["erd.*"] rescue nil
11
+ FileUtils.rm Dir["erd*.*"] rescue nil
12
12
  RailsERD::Diagram.send :remove_const, :Graphviz rescue nil
13
13
  end
14
14
 
@@ -92,6 +92,12 @@ class GraphvizTest < ActiveSupport::TestCase
92
92
  assert File.exists?("erd.dot")
93
93
  end
94
94
 
95
+ test "create should create output for filenames that have spaces" do
96
+ create_simple_domain
97
+ Diagram::Graphviz.create :filename => "erd with spaces"
98
+ assert File.exists?("erd with spaces.png")
99
+ end
100
+
95
101
  test "create should write to file with dot extension without requiring graphviz" do
96
102
  create_simple_domain
97
103
  begin
@@ -298,7 +304,7 @@ class GraphvizTest < ActiveSupport::TestCase
298
304
  assert_equal [["m_Bar", "m_Foo"], ["m_Foo", "m_Bar"]], find_dot_node_pairs(diagram).sort
299
305
  end
300
306
 
301
- test "generate should create edge to generalized entity if polymorphism is true" do
307
+ test "generate should create edge to polymorphic entity if polymorphism is true" do
302
308
  create_model "Cannon", :defensible => :references do
303
309
  belongs_to :defensible, :polymorphic => true
304
310
  end
@@ -312,7 +318,7 @@ class GraphvizTest < ActiveSupport::TestCase
312
318
  find_dot_node_pairs(diagram(:polymorphism => true)).sort
313
319
  end
314
320
 
315
- test "generate should create edge to each child of generalized entity if polymorphism is false" do
321
+ test "generate should create edge to each child of polymorphic entity if polymorphism is false" do
316
322
  create_model "Cannon", :defensible => :references do
317
323
  belongs_to :defensible, :polymorphic => true
318
324
  end
@@ -325,6 +331,35 @@ class GraphvizTest < ActiveSupport::TestCase
325
331
  assert_equal [["m_Galleon", "m_Cannon"], ["m_Stronghold", "m_Cannon"]], find_dot_node_pairs(diagram).sort
326
332
  end
327
333
 
334
+ test "generate should create edge to abstract entity if polymorphism is true" do
335
+ create_model "Person", :settlement => :references
336
+ create_model "Country" do
337
+ has_many :settlements
338
+ end
339
+ create_model "Settlement" do
340
+ self.abstract_class = true
341
+ belongs_to :country
342
+ has_many :people
343
+ end
344
+ create_model "City", Settlement, :country => :references
345
+ assert_equal [["m_Country", "m_Settlement"], ["m_Settlement", "m_City"], ["m_Settlement", "m_Person"]],
346
+ find_dot_node_pairs(diagram(:polymorphism => true)).sort
347
+ end
348
+
349
+ test "generate should create edge to each child of abstract entity if polymorphism is false" do
350
+ create_model "Person", :settlement => :references
351
+ create_model "Country" do
352
+ has_many :settlements
353
+ end
354
+ create_model "Settlement" do
355
+ self.abstract_class = true
356
+ belongs_to :country
357
+ has_many :people
358
+ end
359
+ create_model "City", Settlement, :country => :references
360
+ assert_equal [["m_City", "m_Person"], ["m_Country", "m_City"]], find_dot_node_pairs(diagram).sort
361
+ end
362
+
328
363
  # Simple notation style ====================================================
329
364
  test "generate should use no style for one to one cardinalities with simple notation" do
330
365
  create_one_to_one_assoc_domain
@@ -35,12 +35,22 @@ class SpecializationTest < ActiveSupport::TestCase
35
35
  end
36
36
 
37
37
  test "inheritance should be false for polymorphic specializations" do
38
- create_generalization
38
+ create_polymorphic_generalization
39
39
  assert_equal [false], Domain.generate.specializations.map(&:inheritance?)
40
40
  end
41
41
 
42
42
  test "polymorphic should be true for polymorphic specializations" do
43
- create_generalization
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
44
54
  assert_equal [true], Domain.generate.specializations.map(&:polymorphic?)
45
55
  end
46
56
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-erd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-19 00:00:00.000000000 Z
12
+ date: 2013-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &70146121979600 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '3.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70146121979600
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: activesupport
27
- requirement: &70146121979080 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '3.0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *70146121979080
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '3.0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: ruby-graphviz
38
- requirement: &70146121978600 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ~>
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: 1.0.4
44
54
  type: :runtime
45
55
  prerelease: false
46
- version_requirements: *70146121978600
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.4
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: choice
49
- requirement: &70146121978120 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ~>
@@ -54,18 +69,12 @@ dependencies:
54
69
  version: 0.1.6
55
70
  type: :runtime
56
71
  prerelease: false
57
- version_requirements: *70146121978120
58
- - !ruby/object:Gem::Dependency
59
- name: rake
60
- requirement: &70146121977640 !ruby/object:Gem::Requirement
72
+ version_requirements: !ruby/object:Gem::Requirement
61
73
  none: false
62
74
  requirements:
63
75
  - - ~>
64
76
  - !ruby/object:Gem::Version
65
- version: '0.9'
66
- type: :development
67
- prerelease: false
68
- version_requirements: *70146121977640
77
+ version: 0.1.6
69
78
  description: Automatically generate an entity-relationship diagram (ERD) for your
70
79
  Rails models.
71
80
  email:
@@ -75,7 +84,6 @@ executables:
75
84
  extensions: []
76
85
  extra_rdoc_files: []
77
86
  files:
78
- - CHANGES.rdoc
79
87
  - LICENSE
80
88
  - README.md
81
89
  - Rakefile
@@ -120,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
120
128
  version: '0'
121
129
  segments:
122
130
  - 0
123
- hash: 3954294952765829690
131
+ hash: 1960804951299581689
124
132
  required_rubygems_version: !ruby/object:Gem::Requirement
125
133
  none: false
126
134
  requirements:
@@ -129,10 +137,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
137
  version: '0'
130
138
  segments:
131
139
  - 0
132
- hash: 3954294952765829690
140
+ hash: 1960804951299581689
133
141
  requirements: []
134
142
  rubyforge_project: rails-erd
135
- rubygems_version: 1.8.11
143
+ rubygems_version: 1.8.23
136
144
  signing_key:
137
145
  specification_version: 3
138
146
  summary: Entity-relationship diagram for your Rails models.
@@ -147,3 +155,4 @@ test_files:
147
155
  - test/unit/rake_task_test.rb
148
156
  - test/unit/relationship_test.rb
149
157
  - test/unit/specialization_test.rb
158
+ has_rdoc:
data/CHANGES.rdoc DELETED
@@ -1,94 +0,0 @@
1
- === 1.0.0:
2
-
3
- * The internal API is now stable and will be backwards compatible until
4
- the next major version.
5
- * Added experimental command line interface (erd). The CLI still requires a
6
- Rails application to be present, but it may one day support other kinds of
7
- applications.
8
- * Crow's foot notation (also known as the Information Engineering notation)
9
- can be used by adding 'notation=crowsfoot' to the 'rake erd' command
10
- (contributed by Jeremy Holland).
11
- * Filter models by using the only or exclude options (only=ModelOne,ModelTwo
12
- or exclude=ModelThree,ModelFour) from the command line (contributed by
13
- Milovan Zogovic).
14
- * Process column types that are unsupported by Rails (contributed by Erik
15
- Gustavson).
16
- * Ignore custom limit/scale attributes that cannot be converted to an integer
17
- (reported by Adam St. John).
18
-
19
- === 0.4.5:
20
-
21
- * Display more helpful error message when the application models could not be
22
- loaded successfully by the 'rake erd' task (reported by Greg Weber).
23
-
24
- === 0.4.4:
25
-
26
- * Added the ability to disable HTML markup in node labels (markup=false). This
27
- causes .dot files to be compatible with OmniGraffle, which otherwise fails
28
- to import graphs with HTML node labels (issue reported by Lucas Florio,
29
- implementation based on template by Troy Anderson).
30
- * Prevent models named after Graphviz reserved words (Node, Edge) from causing
31
- errors in .dot files (reported by gguthrie).
32
- * Improved error messages when Graphviz is throwing errors (reported by
33
- Michael Irwin).
34
-
35
- === 0.4.3:
36
-
37
- * Display the scale of decimal attributes when set. A decimal attribute with
38
- precision 5 and scale 2 is now indicated with (5,2).
39
- * Fixed deprecation warnings for edge Rails (upcoming 3.1).
40
-
41
- === 0.4.1:
42
-
43
- * Fix processing of associations with class_name set to absolute module paths.
44
- * Adjust model loading process to include models in non-standard paths eagerly.
45
-
46
- === 0.4.0:
47
-
48
- * Support to optionally display single table inheritance relationships
49
- (inheritance=true).
50
- * Support to optionally display polymorphic associations (polymorphism=true).
51
- * Adjustments to 'advanced' style so that it matches original Bachman style,
52
- and therefore now called 'bachman'.
53
- * Ignore models without tables (reported by Mark Chapman).
54
- * Mutual indirect relationships are now combined.
55
- * Changed API for diagram generation.
56
- * Restructured classes and renamed several API properties and methods.
57
- * Added new edge type to describe single table inheritance and polymorphic
58
- associations: Specialization.
59
- * Added compatibility for Active Record 3.1 (beta), removed dependency on Arel.
60
- * Rubinius compatibility.
61
-
62
- === 0.3.0:
63
-
64
- * Added the ability to support multiple styles of cardinality notations.
65
- Currently supported types are 'simple' and 'advanced'.
66
- * Added option to exclude indirect relationships (indirect=false).
67
- * Added option to change or disable the diagram title (title='Custom title').
68
- * Altered the type descriptions of attributes.
69
- * Renamed options for flexibility and clarity.
70
- * Improved internal logic to determine the cardinality of relationships.
71
- * More versatile API that allows you to inspect relationships and their
72
- cardinalities.
73
- * Changed line widths to 1.0 to avoid invisible node boundaries with older
74
- versions of Graphviz (reported by Mike McQuinn).
75
- * Bundled examples based on actual applications.
76
-
77
- === 0.2.0
78
-
79
- * Added simple way to create your own type of diagrams with a tiny amount of code.
80
- * Improved internal API and documentation.
81
- * Subtle changes in diagram style.
82
- * Fixed error where non-mutual relationships might be inadvertently classified
83
- as indirect relationships.
84
- * Fixed error where diagrams with a vertical layout might fail to be generated.
85
-
86
- === 0.1.1
87
-
88
- * Fixed small errors in Ruby 1.8.7.
89
- * Abort generation of diagrams when there are no models.
90
-
91
- === 0.1.0
92
-
93
- * Released on September 20th, 2010.
94
- * First public release.