rails-erd 1.0.0 → 1.1.0

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