rails-erd 0.3.0 → 0.4.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.
@@ -1,7 +1,7 @@
1
1
  module RailsERD
2
2
  # Rails ERD integrates with Rails 3. If you add it to your +Gemfile+, you
3
3
  # will gain a Rake task called +erd+, which you can use to generate diagrams
4
- # of your domain model. See the README.rdoc file for more information.
4
+ # of your domain model.
5
5
  class Railtie < Rails::Railtie
6
6
  rake_tasks do
7
7
  load "rails_erd/tasks.rake"
data/rails-erd.gemspec CHANGED
@@ -5,16 +5,16 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rails-erd}
8
- s.version = "0.3.0"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Rolf Timmermans"]
12
- s.date = %q{2010-10-03}
12
+ s.date = %q{2010-10-12}
13
13
  s.description = %q{Automatically generate an entity-relationship diagram (ERD) for your Rails models.}
14
14
  s.email = %q{r.timmermans@voormedia.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.rdoc"
17
+ "README.md"
18
18
  ]
19
19
  s.files = [
20
20
  ".gitignore",
@@ -22,20 +22,21 @@ Gem::Specification.new do |s|
22
22
  "Gemfile",
23
23
  "Gemfile.lock",
24
24
  "LICENSE",
25
- "README.rdoc",
25
+ "README.md",
26
26
  "Rakefile",
27
27
  "VERSION",
28
28
  "lib/rails-erd.rb",
29
29
  "lib/rails_erd.rb",
30
- "lib/rails_erd/attribute.rb",
31
30
  "lib/rails_erd/diagram.rb",
32
31
  "lib/rails_erd/diagram/graphviz.rb",
33
32
  "lib/rails_erd/diagram/templates/node.erb",
34
33
  "lib/rails_erd/domain.rb",
35
- "lib/rails_erd/entity.rb",
34
+ "lib/rails_erd/domain/attribute.rb",
35
+ "lib/rails_erd/domain/entity.rb",
36
+ "lib/rails_erd/domain/relationship.rb",
37
+ "lib/rails_erd/domain/relationship/cardinality.rb",
38
+ "lib/rails_erd/domain/specialization.rb",
36
39
  "lib/rails_erd/railtie.rb",
37
- "lib/rails_erd/relationship.rb",
38
- "lib/rails_erd/relationship/cardinality.rb",
39
40
  "lib/rails_erd/tasks.rake",
40
41
  "rails-erd.gemspec",
41
42
  "test/test_helper.rb",
@@ -46,7 +47,8 @@ Gem::Specification.new do |s|
46
47
  "test/unit/entity_test.rb",
47
48
  "test/unit/graphviz_test.rb",
48
49
  "test/unit/rake_task_test.rb",
49
- "test/unit/relationship_test.rb"
50
+ "test/unit/relationship_test.rb",
51
+ "test/unit/specialization_test.rb"
50
52
  ]
51
53
  s.homepage = %q{http://rails-erd.rubyforge.org/}
52
54
  s.rdoc_options = ["--charset=UTF-8"]
@@ -63,7 +65,8 @@ Gem::Specification.new do |s|
63
65
  "test/unit/entity_test.rb",
64
66
  "test/unit/graphviz_test.rb",
65
67
  "test/unit/rake_task_test.rb",
66
- "test/unit/relationship_test.rb"
68
+ "test/unit/relationship_test.rb",
69
+ "test/unit/specialization_test.rb"
67
70
  ]
68
71
 
69
72
  if s.respond_to? :specification_version then
@@ -71,20 +74,20 @@ Gem::Specification.new do |s|
71
74
  s.specification_version = 3
72
75
 
73
76
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
74
- s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0"])
77
+ s.add_runtime_dependency(%q<activerecord>, ["~> 3.0"])
75
78
  s.add_runtime_dependency(%q<activesupport>, ["~> 3.0"])
76
- s.add_runtime_dependency(%q<ruby-graphviz>, ["~> 0.9.17"])
79
+ s.add_runtime_dependency(%q<ruby-graphviz>, ["~> 0.9.18"])
77
80
  s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
78
81
  else
79
- s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
82
+ s.add_dependency(%q<activerecord>, ["~> 3.0"])
80
83
  s.add_dependency(%q<activesupport>, ["~> 3.0"])
81
- s.add_dependency(%q<ruby-graphviz>, ["~> 0.9.17"])
84
+ s.add_dependency(%q<ruby-graphviz>, ["~> 0.9.18"])
82
85
  s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
83
86
  end
84
87
  else
85
- s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
88
+ s.add_dependency(%q<activerecord>, ["~> 3.0"])
86
89
  s.add_dependency(%q<activesupport>, ["~> 3.0"])
87
- s.add_dependency(%q<ruby-graphviz>, ["~> 0.9.17"])
90
+ s.add_dependency(%q<ruby-graphviz>, ["~> 0.9.18"])
88
91
  s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
89
92
  end
90
93
  end
data/test/test_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require "rubygems"
2
- require "bundler"
3
- Bundler.require
2
+ require "bundler/setup"
4
3
 
4
+ require "active_record"
5
5
  require "test/unit"
6
6
  require "rails_erd/domain"
7
7
 
@@ -33,10 +33,14 @@ class ActiveSupport::TestCase
33
33
  end
34
34
  end
35
35
 
36
- def create_model(name, columns = {}, &block)
37
- klass = Object.const_set name.to_sym, Class.new(ActiveRecord::Base)
36
+ def create_model(name, *args, &block)
37
+ superklass = args.first.kind_of?(Class) ? args.shift : ActiveRecord::Base
38
+ columns = args.first || {}
39
+ klass = Object.const_set name.to_sym, Class.new(superklass)
38
40
  klass.class_eval(&block) if block_given?
39
- create_table Object.const_get(name.to_sym).table_name, columns, Object.const_get(name.to_sym).primary_key rescue nil
41
+ if superklass == ActiveRecord::Base
42
+ create_table Object.const_get(name.to_sym).table_name, columns, Object.const_get(name.to_sym).primary_key rescue nil
43
+ end
40
44
  end
41
45
 
42
46
  def create_models(*names)
@@ -90,6 +94,18 @@ class ActiveSupport::TestCase
90
94
  create_table "manies_mores", :many_id => :integer, :more_id => :integer
91
95
  end
92
96
 
97
+ def create_specialization
98
+ create_model "Beverage", :type => :string
99
+ Object.const_set :Beer, Class.new(Beverage)
100
+ end
101
+
102
+ def create_generalization
103
+ create_model "Cannon"
104
+ create_model "Galleon" do
105
+ has_many :cannons, :as => :defensible
106
+ end
107
+ end
108
+
93
109
  private
94
110
 
95
111
  def reset_domain
@@ -20,28 +20,28 @@ class AttributeTest < ActiveSupport::TestCase
20
20
  end
21
21
 
22
22
  def create_attribute(model, name)
23
- Attribute.new(Domain.generate, model, model.arel_table.attributes[name].column)
23
+ Domain::Attribute.new(Domain.generate, model, model.columns_hash[name])
24
24
  end
25
25
 
26
26
  # Attribute ================================================================
27
27
  test "column should return database column" do
28
28
  create_model "Foo", :my_column => :string
29
- assert_equal Foo.arel_table.attributes["my_column"].column,
30
- Attribute.from_model(Domain.new, Foo).reject(&:primary_key?).first.column
29
+ assert_equal Foo.columns_hash["my_column"],
30
+ Domain::Attribute.from_model(Domain.new, Foo).reject(&:primary_key?).first.column
31
31
  end
32
32
 
33
33
  test "spaceship should sort attributes by name" do
34
34
  create_model "Foo", :a => :string, :b => :string, :c => :string
35
- a = Attribute.new(Domain.new, Foo, Foo.arel_table.attributes["a"].column)
36
- b = Attribute.new(Domain.new, Foo, Foo.arel_table.attributes["b"].column)
37
- c = Attribute.new(Domain.new, Foo, Foo.arel_table.attributes["c"].column)
35
+ a = create_attribute(Foo, "a")
36
+ b = create_attribute(Foo, "b")
37
+ c = create_attribute(Foo, "c")
38
38
  assert_equal [a, b, c], [c, a, b].sort
39
39
  end
40
40
 
41
41
  test "inspect should show column" do
42
42
  create_model "Foo", :my_column => :string
43
- assert_match %r{#<RailsERD::Attribute:.* @column="my_column" @type=:string>},
44
- Attribute.new(Domain.new, Foo, Foo.arel_table.attributes["my_column"].column).inspect
43
+ assert_match %r{#<RailsERD::Domain::Attribute:.* @name="my_column" @type=:string>},
44
+ Domain::Attribute.new(Domain.new, Foo, Foo.columns_hash["my_column"]).inspect
45
45
  end
46
46
 
47
47
  test "type should return attribute type" do
@@ -112,6 +112,33 @@ class AttributeTest < ActiveSupport::TestCase
112
112
  create_attribute(Foo, "created_on"), create_attribute(Foo, "updated_on")].collect(&:timestamp?)
113
113
  end
114
114
 
115
+ test "inheritance should return false by default" do
116
+ create_model "Foo", :type => :string, :alternative => :string do
117
+ set_inheritance_column :alternative
118
+ end
119
+ assert_equal false, create_attribute(Foo, "type").inheritance?
120
+ end
121
+
122
+ test "inheritance should return if this column is used for single table inheritance" do
123
+ create_model "Foo", :type => :string, :alternative => :string do
124
+ set_inheritance_column :alternative
125
+ end
126
+ assert_equal true, create_attribute(Foo, "alternative").inheritance?
127
+ end
128
+
129
+ test "content should return true by default" do
130
+ create_model "Foo", :my_first_column => :string
131
+ assert_equal true, create_attribute(Foo, "my_first_column").content?
132
+ end
133
+
134
+ test "content should return false for primary keys, foreign keys, timestamps and inheritance columns" do
135
+ create_model "Book", :type => :string, :created_at => :datetime, :case => :references do
136
+ belongs_to :case
137
+ end
138
+ create_model "Case"
139
+ assert_equal [false] * 4, %w{id type created_at case_id}.map { |a| create_attribute(Book, a).content? }
140
+ end
141
+
115
142
  # Type descriptions ========================================================
116
143
  test "type_description should return short type description" do
117
144
  create_model "Foo", :a => :binary
@@ -2,115 +2,121 @@ require File.expand_path("../test_helper", File.dirname(__FILE__))
2
2
 
3
3
  class CardinalityTest < ActiveSupport::TestCase
4
4
  def setup
5
- @n = Relationship::Cardinality::N
5
+ @n = Domain::Relationship::Cardinality::N
6
6
  end
7
7
 
8
+ # Cardinality ==============================================================
9
+ test "inspect should show source and destination ranges" do
10
+ assert_match %r{#<RailsERD::Domain::Relationship::Cardinality:.* @source_range=1\.\.1 @destination_range=1\.\.Infinity>},
11
+ Domain::Relationship::Cardinality.new(1, 1..@n).inspect
12
+ end
13
+
8
14
  # Cardinality construction =================================================
9
15
  test "new should return cardinality object" do
10
- assert_kind_of Relationship::Cardinality, Relationship::Cardinality.new(1, 1..@n)
16
+ assert_kind_of Domain::Relationship::Cardinality, Domain::Relationship::Cardinality.new(1, 1..@n)
11
17
  end
12
18
 
13
19
  # Cardinality properties ===================================================
14
20
  test "source_optional should return true if source range starts at zero" do
15
- assert_equal true, Relationship::Cardinality.new(0..1, 1).source_optional?
21
+ assert_equal true, Domain::Relationship::Cardinality.new(0..1, 1).source_optional?
16
22
  end
17
23
 
18
24
  test "source_optional should return false if source range starts at one or more" do
19
- assert_equal false, Relationship::Cardinality.new(1..2, 0..1).source_optional?
25
+ assert_equal false, Domain::Relationship::Cardinality.new(1..2, 0..1).source_optional?
20
26
  end
21
27
 
22
28
  test "destination_optional should return true if destination range starts at zero" do
23
- assert_equal true, Relationship::Cardinality.new(1, 0..1).destination_optional?
29
+ assert_equal true, Domain::Relationship::Cardinality.new(1, 0..1).destination_optional?
24
30
  end
25
31
 
26
32
  test "destination_optional should return false if destination range starts at one or more" do
27
- assert_equal false, Relationship::Cardinality.new(0..1, 1..2).destination_optional?
33
+ assert_equal false, Domain::Relationship::Cardinality.new(0..1, 1..2).destination_optional?
28
34
  end
29
35
 
30
36
  test "inverse should return inverse cardinality" do
31
- assert_equal Relationship::Cardinality.new(23..45, 0..15), Relationship::Cardinality.new(0..15, 23..45).inverse
37
+ assert_equal Domain::Relationship::Cardinality.new(23..45, 0..15), Domain::Relationship::Cardinality.new(0..15, 23..45).inverse
32
38
  end
33
39
 
34
40
  # Cardinality equality =====================================================
35
41
  test "cardinalities are equal if they have the same boundaries" do
36
- assert_equal Relationship::Cardinality.new(1, 1..Relationship::Cardinality::N),
37
- Relationship::Cardinality.new(1, 1..Relationship::Cardinality::N)
42
+ assert_equal Domain::Relationship::Cardinality.new(1, 1..Domain::Relationship::Cardinality::N),
43
+ Domain::Relationship::Cardinality.new(1, 1..Domain::Relationship::Cardinality::N)
38
44
  end
39
45
 
40
46
  test "cardinalities are not equal if they have a different source range" do
41
- assert_not_equal Relationship::Cardinality.new(0..1, 1..Relationship::Cardinality::N),
42
- Relationship::Cardinality.new(1..1, 1..Relationship::Cardinality::N)
47
+ assert_not_equal Domain::Relationship::Cardinality.new(0..1, 1..Domain::Relationship::Cardinality::N),
48
+ Domain::Relationship::Cardinality.new(1..1, 1..Domain::Relationship::Cardinality::N)
43
49
  end
44
50
 
45
51
  test "cardinalities are not equal if they have a different destination range" do
46
- assert_not_equal Relationship::Cardinality.new(0..1, 1..Relationship::Cardinality::N),
47
- Relationship::Cardinality.new(0..1, 2..Relationship::Cardinality::N)
52
+ assert_not_equal Domain::Relationship::Cardinality.new(0..1, 1..Domain::Relationship::Cardinality::N),
53
+ Domain::Relationship::Cardinality.new(0..1, 2..Domain::Relationship::Cardinality::N)
48
54
  end
49
55
 
50
56
  # Cardinal names ===========================================================
51
57
  test "one_to_one should return true if source and destination are exactly one" do
52
- assert_equal true, Relationship::Cardinality.new(1, 1).one_to_one?
58
+ assert_equal true, Domain::Relationship::Cardinality.new(1, 1).one_to_one?
53
59
  end
54
60
 
55
61
  test "one_to_one should return true if source and destination range are less than or equal to one" do
56
- assert_equal true, Relationship::Cardinality.new(0..1, 0..1).one_to_one?
62
+ assert_equal true, Domain::Relationship::Cardinality.new(0..1, 0..1).one_to_one?
57
63
  end
58
64
 
59
65
  test "one_to_one should return false if source range upper limit is more than one" do
60
- assert_equal false, Relationship::Cardinality.new(0..15, 0..1).one_to_one?
66
+ assert_equal false, Domain::Relationship::Cardinality.new(0..15, 0..1).one_to_one?
61
67
  end
62
68
 
63
69
  test "one_to_one should return false if destination range upper limit is more than one" do
64
- assert_equal false, Relationship::Cardinality.new(0..1, 0..15).one_to_one?
70
+ assert_equal false, Domain::Relationship::Cardinality.new(0..1, 0..15).one_to_one?
65
71
  end
66
72
 
67
73
  test "one_to_many should return true if source is exactly one and destination is higher than one" do
68
- assert_equal true, Relationship::Cardinality.new(1, 15).one_to_many?
74
+ assert_equal true, Domain::Relationship::Cardinality.new(1, 15).one_to_many?
69
75
  end
70
76
 
71
77
  test "one_to_many should return true if source is less than or equal to one and destination is higher than one" do
72
- assert_equal true, Relationship::Cardinality.new(0..1, 0..15).one_to_many?
78
+ assert_equal true, Domain::Relationship::Cardinality.new(0..1, 0..15).one_to_many?
73
79
  end
74
80
 
75
81
  test "one_to_many should return false if source range upper limit is more than one" do
76
- assert_equal false, Relationship::Cardinality.new(0..15, 0..15).one_to_many?
82
+ assert_equal false, Domain::Relationship::Cardinality.new(0..15, 0..15).one_to_many?
77
83
  end
78
84
 
79
85
  test "one_to_many should return false if destination range upper limit is one" do
80
- assert_equal false, Relationship::Cardinality.new(0..1, 1).one_to_many?
86
+ assert_equal false, Domain::Relationship::Cardinality.new(0..1, 1).one_to_many?
81
87
  end
82
88
 
83
89
  test "many_to_many should return true if source and destination are higher than one" do
84
- assert_equal true, Relationship::Cardinality.new(15, 15).many_to_many?
90
+ assert_equal true, Domain::Relationship::Cardinality.new(15, 15).many_to_many?
85
91
  end
86
92
 
87
93
  test "many_to_many should return true if source and destination upper limits are higher than one" do
88
- assert_equal true, Relationship::Cardinality.new(0..15, 0..15).many_to_many?
94
+ assert_equal true, Domain::Relationship::Cardinality.new(0..15, 0..15).many_to_many?
89
95
  end
90
96
 
91
97
  test "many_to_many should return false if source range upper limit is is one" do
92
- assert_equal false, Relationship::Cardinality.new(1, 0..15).many_to_many?
98
+ assert_equal false, Domain::Relationship::Cardinality.new(1, 0..15).many_to_many?
93
99
  end
94
100
 
95
101
  test "many_to_many should return false if destination range upper limit is one" do
96
- assert_equal false, Relationship::Cardinality.new(0..1, 1).many_to_many?
102
+ assert_equal false, Domain::Relationship::Cardinality.new(0..1, 1).many_to_many?
97
103
  end
98
104
 
99
105
  test "inverse of one_to_many should be many_to_one" do
100
- assert_equal true, Relationship::Cardinality.new(0..1, 0..@n).inverse.many_to_one?
106
+ assert_equal true, Domain::Relationship::Cardinality.new(0..1, 0..@n).inverse.many_to_one?
101
107
  end
102
108
 
103
109
  # Cardinality order ========================================================
104
110
  test "cardinalities should be sorted in order of maniness" do
105
- card1 = Relationship::Cardinality.new(0..1, 1)
106
- card2 = Relationship::Cardinality.new(1, 1)
107
- card3 = Relationship::Cardinality.new(0..1, 1..3)
108
- card4 = Relationship::Cardinality.new(1, 1..2)
109
- card5 = Relationship::Cardinality.new(1, 1..@n)
110
- card6 = Relationship::Cardinality.new(1..5, 1..3)
111
- card7 = Relationship::Cardinality.new(1..2, 1..15)
112
- card8 = Relationship::Cardinality.new(1..15, 1..@n)
113
- card9 = Relationship::Cardinality.new(1..@n, 1..@n)
111
+ card1 = Domain::Relationship::Cardinality.new(0..1, 1)
112
+ card2 = Domain::Relationship::Cardinality.new(1, 1)
113
+ card3 = Domain::Relationship::Cardinality.new(0..1, 1..3)
114
+ card4 = Domain::Relationship::Cardinality.new(1, 1..2)
115
+ card5 = Domain::Relationship::Cardinality.new(1, 1..@n)
116
+ card6 = Domain::Relationship::Cardinality.new(1..5, 1..3)
117
+ card7 = Domain::Relationship::Cardinality.new(1..2, 1..15)
118
+ card8 = Domain::Relationship::Cardinality.new(1..15, 1..@n)
119
+ card9 = Domain::Relationship::Cardinality.new(1..@n, 1..@n)
114
120
  assert_equal [card1, card2, card3, card4, card5, card6, card7, card8, card9],
115
121
  [card9, card5, card8, card2, card4, card7, card1, card6, card3].sort
116
122
  end
@@ -9,35 +9,47 @@ class DiagramTest < ActiveSupport::TestCase
9
9
  RailsERD.send :remove_const, :Diagram
10
10
  end
11
11
 
12
+ def retrieve_entities(options = {})
13
+ klass = Class.new(Diagram)
14
+ [].tap do |entities|
15
+ klass.class_eval do
16
+ each_entity do |entity, attributes|
17
+ entities << entity
18
+ end
19
+ end
20
+ klass.create(options)
21
+ end
22
+ end
23
+
12
24
  def retrieve_relationships(options = {})
13
25
  klass = Class.new(Diagram)
14
26
  [].tap do |relationships|
15
27
  klass.class_eval do
16
- define_method :process_relationship do |relationship|
28
+ each_relationship do |relationship|
17
29
  relationships << relationship
18
30
  end
19
31
  end
20
32
  klass.create(options)
21
33
  end
22
34
  end
23
-
24
- def retrieve_entities(options = {})
35
+
36
+ def retrieve_specializations(options = {})
25
37
  klass = Class.new(Diagram)
26
- [].tap do |entities|
38
+ [].tap do |specializations|
27
39
  klass.class_eval do
28
- define_method :process_entity do |entity, attributes|
29
- entities << entity
40
+ each_specialization do |specialization|
41
+ specializations << specialization
30
42
  end
31
43
  end
32
44
  klass.create(options)
33
45
  end
34
46
  end
35
-
47
+
36
48
  def retrieve_attribute_lists(options = {})
37
49
  klass = Class.new(Diagram)
38
50
  {}.tap do |attribute_lists|
39
51
  klass.class_eval do
40
- define_method :process_entity do |entity, attributes|
52
+ each_entity do |entity, attributes|
41
53
  attribute_lists[entity.model] = attributes
42
54
  end
43
55
  end
@@ -46,10 +58,56 @@ class DiagramTest < ActiveSupport::TestCase
46
58
  end
47
59
 
48
60
  # Diagram ==================================================================
61
+ test "domain sould return given domain" do
62
+ domain = Object.new
63
+ assert_same domain, Class.new(Diagram).new(domain).domain
64
+ end
65
+
66
+ # Diagram DSL ==============================================================
67
+ test "create should succeed silently if called on abstract class" do
68
+ create_simple_domain
69
+ assert_nothing_raised do
70
+ Diagram.create
71
+ end
72
+ end
73
+
74
+ test "create should succeed if called on subclass" do
75
+ create_simple_domain
76
+ assert_nothing_raised do
77
+ Class.new(Diagram).create
78
+ end
79
+ end
80
+
81
+ test "create should call callbacks in instance in specific order" do
82
+ create_simple_domain
83
+ executed_calls = Class.new(Diagram) do
84
+ setup do
85
+ calls << :setup
86
+ end
87
+
88
+ each_entity do
89
+ calls << :entity
90
+ end
91
+
92
+ each_relationship do
93
+ calls << :relationship
94
+ end
95
+
96
+ save do
97
+ calls << :save
98
+ end
99
+
100
+ def calls
101
+ @calls ||= []
102
+ end
103
+ end.create
104
+ assert_equal [:setup, :entity, :entity, :relationship, :save], executed_calls
105
+ end
106
+
49
107
  test "create class method should return result of save" do
50
108
  create_simple_domain
51
109
  subclass = Class.new(Diagram) do
52
- def save
110
+ save do
53
111
  "foobar"
54
112
  end
55
113
  end
@@ -59,38 +117,13 @@ class DiagramTest < ActiveSupport::TestCase
59
117
  test "create should return result of save" do
60
118
  create_simple_domain
61
119
  diagram = Class.new(Diagram) do
62
- def save
120
+ save do
63
121
  "foobar"
64
122
  end
65
123
  end.new(Domain.generate)
66
124
  assert_equal "foobar", diagram.create
67
125
  end
68
126
 
69
- test "domain sould return given domain" do
70
- domain = Object.new
71
- assert_same domain, Class.new(Diagram).new(domain).domain
72
- end
73
-
74
- # Diagram abstractness =====================================================
75
- test "create should succeed silently if called on abstract class" do
76
- create_simple_domain
77
- assert_nothing_raised do
78
- Diagram.create
79
- end
80
- end
81
-
82
- test "create should succeed if called on class that implements process_entity and process_relationship" do
83
- create_simple_domain
84
- assert_nothing_raised do
85
- Class.new(Diagram) do
86
- def process_entity(*args)
87
- end
88
- def process_relationship(*args)
89
- end
90
- end.create
91
- end
92
- end
93
-
94
127
  # Entity filtering =========================================================
95
128
  test "generate should yield entities" do
96
129
  create_model "Foo"
@@ -111,13 +144,19 @@ class DiagramTest < ActiveSupport::TestCase
111
144
  assert_equal [Foo], retrieve_entities(:disconnected => true).map(&:model)
112
145
  end
113
146
 
114
- test "generate should filter descendant entities" do
147
+ test "generate should filter specialized entities" do
115
148
  create_model "Foo", :type => :string
116
149
  Object.const_set :SpecialFoo, Class.new(Foo)
117
150
  assert_equal [Foo], retrieve_entities.map(&:model)
118
151
  end
119
152
 
120
- test "generate should yield descended entities with distinct tables" do
153
+ test "generate should yield specialized entities if inheritance is true" do
154
+ create_model "Foo", :type => :string
155
+ Object.const_set :SpecialFoo, Class.new(Foo)
156
+ assert_equal [Foo, SpecialFoo], retrieve_entities(:inheritance => true).map(&:model)
157
+ end
158
+
159
+ test "generate should yield specialized entities with distinct tables" do
121
160
  create_model "Foo"
122
161
  Object.const_set :SpecialFoo, Class.new(Foo)
123
162
  SpecialFoo.class_eval do
@@ -126,6 +165,22 @@ class DiagramTest < ActiveSupport::TestCase
126
165
  create_table "special_foo", {}, true
127
166
  assert_equal [Foo, SpecialFoo], retrieve_entities.map(&:model)
128
167
  end
168
+
169
+ test "generate should filter generalized entities" do
170
+ create_model "Cannon"
171
+ create_model "Galleon" do
172
+ has_many :cannons, :as => :defensible
173
+ end
174
+ assert_equal ["Cannon", "Galleon"], retrieve_entities.map(&:name)
175
+ end
176
+
177
+ test "generate should yield generalized entities if polymorphism is true" do
178
+ create_model "Cannon"
179
+ create_model "Galleon" do
180
+ has_many :cannons, :as => :defensible
181
+ end
182
+ assert_equal ["Cannon", "Defensible", "Galleon"], retrieve_entities(:polymorphism => true).map(&:name)
183
+ end
129
184
 
130
185
  # Relationship filtering ===================================================
131
186
  test "generate should yield relationships" do
@@ -163,27 +218,53 @@ class DiagramTest < ActiveSupport::TestCase
163
218
  assert_equal [false, false], retrieve_relationships(:indirect => false).map(&:indirect?)
164
219
  end
165
220
 
166
- test "generate should filter relationships from descendant entities" do
221
+ test "generate should yield relationships from specialized entities" do
167
222
  create_model "Foo", :bar => :references
168
223
  create_model "Bar", :type => :string
169
224
  Object.const_set :SpecialBar, Class.new(Bar)
170
225
  SpecialBar.class_eval do
171
226
  has_many :foos
172
227
  end
173
- assert_equal [], retrieve_relationships
228
+ assert_equal 1, retrieve_relationships.length
174
229
  end
175
230
 
176
- test "generate should filter relationships to descendant entities" do
231
+ test "generate should yield relationships to specialized entities" do
177
232
  create_model "Foo", :type => :string, :bar => :references
178
233
  Object.const_set :SpecialFoo, Class.new(Foo)
179
234
  create_model "Bar" do
180
235
  has_many :special_foos
181
236
  end
182
- assert_equal [], retrieve_relationships
237
+ assert_equal 1, retrieve_relationships.length
238
+ end
239
+
240
+ # Specialization filtering =================================================
241
+ test "generate should not yield specializations" do
242
+ create_specialization
243
+ create_generalization
244
+ assert_equal [], retrieve_specializations
245
+ end
246
+
247
+ test "generate should yield specializations but not generalizations if inheritance is true" do
248
+ create_specialization
249
+ create_generalization
250
+ assert_equal ["Beer"], retrieve_specializations(:inheritance => true).map { |s| s.specialized.name }
251
+ end
252
+
253
+ test "generate should yield generalizations but not specializations if polymorphism is true" do
254
+ create_specialization
255
+ create_generalization
256
+ assert_equal ["Galleon"], retrieve_specializations(:polymorphism => true).map { |s| s.specialized.name }
257
+ end
258
+
259
+ test "generate should yield specializations and generalizations if polymorphism and inheritance is true" do
260
+ create_specialization
261
+ create_generalization
262
+ assert_equal ["Beer", "Galleon"], retrieve_specializations(:inheritance => true,
263
+ :polymorphism => true).map { |s| s.specialized.name }
183
264
  end
184
265
 
185
266
  # Attribute filtering ======================================================
186
- test "generate should yield regular attributes by default" do
267
+ test "generate should yield content attributes by default" do
187
268
  create_model "Book", :title => :string, :created_at => :datetime, :author => :references do
188
269
  belongs_to :author
189
270
  end
@@ -222,6 +303,12 @@ class DiagramTest < ActiveSupport::TestCase
222
303
  end
223
304
  create_model "Author"
224
305
  assert_equal %w{created_at title},
225
- retrieve_attribute_lists(:attributes => [:regular, :timestamps])[Book].map(&:name)
306
+ retrieve_attribute_lists(:attributes => [:content, :timestamps])[Book].map(&:name)
307
+ end
308
+
309
+ test "generate should yield no attributes for specialized entities" do
310
+ create_model "Beverage", :type => :string, :name => :string, :distillery => :string, :age => :integer
311
+ Object.const_set :Whisky, Class.new(Beverage)
312
+ assert_equal [], retrieve_attribute_lists(:inheritance => true)[Whisky].map(&:name)
226
313
  end
227
314
  end