jw-rails-erd 1.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +86 -0
- data/Rakefile +20 -0
- data/bin/erd +4 -0
- data/lib/generators/erd/USAGE +4 -0
- data/lib/generators/erd/install_generator.rb +14 -0
- data/lib/generators/erd/templates/auto_generate_diagram.rake +6 -0
- data/lib/rails-erd.rb +1 -0
- data/lib/rails_erd/cli.rb +164 -0
- data/lib/rails_erd/config.rb +97 -0
- data/lib/rails_erd/custom.rb +99 -0
- data/lib/rails_erd/diagram/graphviz.rb +295 -0
- data/lib/rails_erd/diagram/templates/node.html.erb +14 -0
- data/lib/rails_erd/diagram/templates/node.record.erb +4 -0
- data/lib/rails_erd/diagram.rb +188 -0
- data/lib/rails_erd/domain/attribute.rb +160 -0
- data/lib/rails_erd/domain/entity.rb +104 -0
- data/lib/rails_erd/domain/relationship/cardinality.rb +118 -0
- data/lib/rails_erd/domain/relationship.rb +203 -0
- data/lib/rails_erd/domain/specialization.rb +90 -0
- data/lib/rails_erd/domain.rb +153 -0
- data/lib/rails_erd/railtie.rb +10 -0
- data/lib/rails_erd/tasks.rake +58 -0
- data/lib/rails_erd/version.rb +4 -0
- data/lib/rails_erd.rb +73 -0
- data/lib/tasks/auto_generate_diagram.rake +21 -0
- data/test/support_files/erdconfig.another_example +3 -0
- data/test/support_files/erdconfig.example +19 -0
- data/test/support_files/erdconfig.exclude.example +19 -0
- data/test/test_helper.rb +160 -0
- data/test/unit/attribute_test.rb +316 -0
- data/test/unit/cardinality_test.rb +123 -0
- data/test/unit/config_test.rb +110 -0
- data/test/unit/diagram_test.rb +352 -0
- data/test/unit/domain_test.rb +258 -0
- data/test/unit/entity_test.rb +252 -0
- data/test/unit/graphviz_test.rb +461 -0
- data/test/unit/rake_task_test.rb +174 -0
- data/test/unit/relationship_test.rb +476 -0
- data/test/unit/specialization_test.rb +67 -0
- metadata +155 -0
@@ -0,0 +1,123 @@
|
|
1
|
+
require File.expand_path("../test_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class CardinalityTest < ActiveSupport::TestCase
|
4
|
+
def setup
|
5
|
+
@n = Domain::Relationship::Cardinality::N
|
6
|
+
end
|
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
|
+
|
14
|
+
# Cardinality construction =================================================
|
15
|
+
test "new should return cardinality object" do
|
16
|
+
assert_kind_of Domain::Relationship::Cardinality, Domain::Relationship::Cardinality.new(1, 1..@n)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Cardinality properties ===================================================
|
20
|
+
test "source_optional should return true if source range starts at zero" do
|
21
|
+
assert_equal true, Domain::Relationship::Cardinality.new(0..1, 1).source_optional?
|
22
|
+
end
|
23
|
+
|
24
|
+
test "source_optional should return false if source range starts at one or more" do
|
25
|
+
assert_equal false, Domain::Relationship::Cardinality.new(1..2, 0..1).source_optional?
|
26
|
+
end
|
27
|
+
|
28
|
+
test "destination_optional should return true if destination range starts at zero" do
|
29
|
+
assert_equal true, Domain::Relationship::Cardinality.new(1, 0..1).destination_optional?
|
30
|
+
end
|
31
|
+
|
32
|
+
test "destination_optional should return false if destination range starts at one or more" do
|
33
|
+
assert_equal false, Domain::Relationship::Cardinality.new(0..1, 1..2).destination_optional?
|
34
|
+
end
|
35
|
+
|
36
|
+
test "inverse should return inverse cardinality" do
|
37
|
+
assert_equal Domain::Relationship::Cardinality.new(23..45, 0..15), Domain::Relationship::Cardinality.new(0..15, 23..45).inverse
|
38
|
+
end
|
39
|
+
|
40
|
+
# Cardinality equality =====================================================
|
41
|
+
test "cardinalities are equal if they have the same boundaries" do
|
42
|
+
assert_equal Domain::Relationship::Cardinality.new(1, 1..Domain::Relationship::Cardinality::N),
|
43
|
+
Domain::Relationship::Cardinality.new(1, 1..Domain::Relationship::Cardinality::N)
|
44
|
+
end
|
45
|
+
|
46
|
+
test "cardinalities are not equal if they have a different source range" do
|
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)
|
49
|
+
end
|
50
|
+
|
51
|
+
test "cardinalities are not equal if they have a different destination range" do
|
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)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Cardinal names ===========================================================
|
57
|
+
test "one_to_one should return true if source and destination are exactly one" do
|
58
|
+
assert_equal true, Domain::Relationship::Cardinality.new(1, 1).one_to_one?
|
59
|
+
end
|
60
|
+
|
61
|
+
test "one_to_one should return true if source and destination range are less than or equal to one" do
|
62
|
+
assert_equal true, Domain::Relationship::Cardinality.new(0..1, 0..1).one_to_one?
|
63
|
+
end
|
64
|
+
|
65
|
+
test "one_to_one should return false if source range upper limit is more than one" do
|
66
|
+
assert_equal false, Domain::Relationship::Cardinality.new(0..15, 0..1).one_to_one?
|
67
|
+
end
|
68
|
+
|
69
|
+
test "one_to_one should return false if destination range upper limit is more than one" do
|
70
|
+
assert_equal false, Domain::Relationship::Cardinality.new(0..1, 0..15).one_to_one?
|
71
|
+
end
|
72
|
+
|
73
|
+
test "one_to_many should return true if source is exactly one and destination is higher than one" do
|
74
|
+
assert_equal true, Domain::Relationship::Cardinality.new(1, 15).one_to_many?
|
75
|
+
end
|
76
|
+
|
77
|
+
test "one_to_many should return true if source is less than or equal to one and destination is higher than one" do
|
78
|
+
assert_equal true, Domain::Relationship::Cardinality.new(0..1, 0..15).one_to_many?
|
79
|
+
end
|
80
|
+
|
81
|
+
test "one_to_many should return false if source range upper limit is more than one" do
|
82
|
+
assert_equal false, Domain::Relationship::Cardinality.new(0..15, 0..15).one_to_many?
|
83
|
+
end
|
84
|
+
|
85
|
+
test "one_to_many should return false if destination range upper limit is one" do
|
86
|
+
assert_equal false, Domain::Relationship::Cardinality.new(0..1, 1).one_to_many?
|
87
|
+
end
|
88
|
+
|
89
|
+
test "many_to_many should return true if source and destination are higher than one" do
|
90
|
+
assert_equal true, Domain::Relationship::Cardinality.new(15, 15).many_to_many?
|
91
|
+
end
|
92
|
+
|
93
|
+
test "many_to_many should return true if source and destination upper limits are higher than one" do
|
94
|
+
assert_equal true, Domain::Relationship::Cardinality.new(0..15, 0..15).many_to_many?
|
95
|
+
end
|
96
|
+
|
97
|
+
test "many_to_many should return false if source range upper limit is is one" do
|
98
|
+
assert_equal false, Domain::Relationship::Cardinality.new(1, 0..15).many_to_many?
|
99
|
+
end
|
100
|
+
|
101
|
+
test "many_to_many should return false if destination range upper limit is one" do
|
102
|
+
assert_equal false, Domain::Relationship::Cardinality.new(0..1, 1).many_to_many?
|
103
|
+
end
|
104
|
+
|
105
|
+
test "inverse of one_to_many should be many_to_one" do
|
106
|
+
assert_equal true, Domain::Relationship::Cardinality.new(0..1, 0..@n).inverse.many_to_one?
|
107
|
+
end
|
108
|
+
|
109
|
+
# Cardinality order ========================================================
|
110
|
+
test "cardinalities should be sorted in order of maniness" do
|
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)
|
120
|
+
assert_equal [card1, card2, card3, card4, card5, card6, card7, card8, card9],
|
121
|
+
[card9, card5, card8, card2, card4, card7, card1, card6, card3].sort
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path("../test_helper", File.dirname(__FILE__))
|
3
|
+
|
4
|
+
class ConfigTest < ActiveSupport::TestCase
|
5
|
+
|
6
|
+
test "load_config_gile should return blank hash when neither CURRENT_CONFIG_FILE nor USER_WIDE_CONFIG_FILE exist." do
|
7
|
+
expected_hash = {}
|
8
|
+
assert_equal expected_hash, RailsERD::Config.load
|
9
|
+
end
|
10
|
+
|
11
|
+
test "load_config_gile should return a hash from USER_WIDE_CONFIG_FILE when only USER_WIDE_CONFIG_FILE exists." do
|
12
|
+
set_user_config_file_to("erdconfig.example")
|
13
|
+
|
14
|
+
expected_hash = {
|
15
|
+
attributes: [:content, :foreign_key, :inheritance, :false],
|
16
|
+
disconnected: true,
|
17
|
+
filename: "erd",
|
18
|
+
filetype: :pdf,
|
19
|
+
indirect: true,
|
20
|
+
inheritance: false,
|
21
|
+
markup: true,
|
22
|
+
notation: :simple,
|
23
|
+
orientation: :horizontal,
|
24
|
+
polymorphism: false,
|
25
|
+
warn: true,
|
26
|
+
title: "sample title",
|
27
|
+
exclude: [],
|
28
|
+
only: []
|
29
|
+
}
|
30
|
+
assert_equal expected_hash, RailsERD::Config.load
|
31
|
+
end
|
32
|
+
|
33
|
+
test "load_config_file should return a hash from USER_WIDE_CONFIG_FILE when only USER_WIDE_CONFIG_FILE exists." do
|
34
|
+
set_user_config_file_to("erdconfig.exclude.example")
|
35
|
+
|
36
|
+
expected_hash = {
|
37
|
+
attributes: [:content, :foreign_key, :inheritance, :false],
|
38
|
+
disconnected: true,
|
39
|
+
filename: "erd",
|
40
|
+
filetype: :pdf,
|
41
|
+
indirect: true,
|
42
|
+
inheritance: false,
|
43
|
+
markup: true,
|
44
|
+
notation: :simple,
|
45
|
+
orientation: :horizontal,
|
46
|
+
polymorphism: false,
|
47
|
+
warn: true,
|
48
|
+
title: "sample title",
|
49
|
+
exclude: ['Book', 'Author'],
|
50
|
+
only: []
|
51
|
+
}
|
52
|
+
assert_equal expected_hash, RailsERD::Config.load
|
53
|
+
end
|
54
|
+
|
55
|
+
test "load_config_gile should return a hash from CURRENT_CONFIG_FILE when only CURRENT_CONFIG_FILE exists." do
|
56
|
+
set_local_config_file_to("erdconfig.another_example")
|
57
|
+
|
58
|
+
expected_hash = {
|
59
|
+
:attributes => [:primary_key]
|
60
|
+
}
|
61
|
+
assert_equal expected_hash, RailsERD::Config.load
|
62
|
+
end
|
63
|
+
|
64
|
+
test "load_config_gile should return a hash from CURRENT_CONFIG_FILE overriding USER_WIDE_CONFIG_FILE when both of them exist." do
|
65
|
+
set_user_config_file_to("erdconfig.example")
|
66
|
+
set_local_config_file_to("erdconfig.another_example")
|
67
|
+
|
68
|
+
expected_hash = {
|
69
|
+
attributes: [:primary_key],
|
70
|
+
disconnected: true,
|
71
|
+
filename: "erd",
|
72
|
+
filetype: :pdf,
|
73
|
+
indirect: true,
|
74
|
+
inheritance: false,
|
75
|
+
markup: true,
|
76
|
+
notation: :simple,
|
77
|
+
orientation: :horizontal,
|
78
|
+
polymorphism: false,
|
79
|
+
warn: true,
|
80
|
+
title: "sample title",
|
81
|
+
exclude: [],
|
82
|
+
only: []
|
83
|
+
}
|
84
|
+
assert_equal expected_hash, RailsERD::Config.load
|
85
|
+
end
|
86
|
+
|
87
|
+
test "normalize_value should return symbols in an array when key is :attributes and value is a comma-joined string." do
|
88
|
+
assert_equal [:content, :foreign_keys], normalize_value(:attributes, "content,foreign_keys")
|
89
|
+
end
|
90
|
+
|
91
|
+
test "normalize_value should return symbols in an array when key is :attributes and value is strings in an array." do
|
92
|
+
assert_equal [:content, :primary_keys], normalize_value(:attributes, ["content", "primary_keys"])
|
93
|
+
end
|
94
|
+
|
95
|
+
def normalize_value(key, value)
|
96
|
+
RailsERD::Config.new.send(:normalize_value, key, value)
|
97
|
+
end
|
98
|
+
|
99
|
+
def set_user_config_file_to(config_file)
|
100
|
+
RailsERD::Config.send :remove_const, :USER_WIDE_CONFIG_FILE
|
101
|
+
RailsERD::Config.send :const_set, :USER_WIDE_CONFIG_FILE,
|
102
|
+
File.expand_path("test/support_files/#{config_file}")
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_local_config_file_to(config_file)
|
106
|
+
RailsERD::Config.send :remove_const, :CURRENT_CONFIG_FILE
|
107
|
+
RailsERD::Config.send :const_set, :CURRENT_CONFIG_FILE,
|
108
|
+
File.expand_path("test/support_files/#{config_file}")
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,352 @@
|
|
1
|
+
require File.expand_path("../test_helper", File.dirname(__FILE__))
|
2
|
+
require "rails_erd/diagram"
|
3
|
+
|
4
|
+
class DiagramTest < ActiveSupport::TestCase
|
5
|
+
def retrieve_entities(options = {})
|
6
|
+
klass = Class.new(Diagram)
|
7
|
+
[].tap do |entities|
|
8
|
+
klass.class_eval do
|
9
|
+
each_entity do |entity, attributes|
|
10
|
+
entities << entity
|
11
|
+
end
|
12
|
+
end
|
13
|
+
klass.create(options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def retrieve_relationships(options = {})
|
18
|
+
klass = Class.new(Diagram)
|
19
|
+
[].tap do |relationships|
|
20
|
+
klass.class_eval do
|
21
|
+
each_relationship do |relationship|
|
22
|
+
relationships << relationship
|
23
|
+
end
|
24
|
+
end
|
25
|
+
klass.create(options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def retrieve_specializations(options = {})
|
30
|
+
klass = Class.new(Diagram)
|
31
|
+
[].tap do |specializations|
|
32
|
+
klass.class_eval do
|
33
|
+
each_specialization do |specialization|
|
34
|
+
specializations << specialization
|
35
|
+
end
|
36
|
+
end
|
37
|
+
klass.create(options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def retrieve_attribute_lists(options = {})
|
42
|
+
klass = Class.new(Diagram)
|
43
|
+
{}.tap do |attribute_lists|
|
44
|
+
klass.class_eval do
|
45
|
+
each_entity do |entity, attributes|
|
46
|
+
attribute_lists[entity.model] = attributes
|
47
|
+
end
|
48
|
+
end
|
49
|
+
klass.create(options)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Diagram ==================================================================
|
54
|
+
test "domain sould return given domain" do
|
55
|
+
domain = Object.new
|
56
|
+
assert_same domain, Class.new(Diagram).new(domain).domain
|
57
|
+
end
|
58
|
+
|
59
|
+
# Diagram DSL ==============================================================
|
60
|
+
test "create should succeed silently if called on abstract class" do
|
61
|
+
create_simple_domain
|
62
|
+
assert_nothing_raised do
|
63
|
+
Diagram.create
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
test "create should succeed if called on subclass" do
|
68
|
+
create_simple_domain
|
69
|
+
assert_nothing_raised do
|
70
|
+
Class.new(Diagram).create
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
test "create should call callbacks in instance in specific order" do
|
75
|
+
create_simple_domain
|
76
|
+
executed_calls = Class.new(Diagram) do
|
77
|
+
setup do
|
78
|
+
calls << :setup
|
79
|
+
end
|
80
|
+
|
81
|
+
each_entity do
|
82
|
+
calls << :entity
|
83
|
+
end
|
84
|
+
|
85
|
+
each_relationship do
|
86
|
+
calls << :relationship
|
87
|
+
end
|
88
|
+
|
89
|
+
save do
|
90
|
+
calls << :save
|
91
|
+
end
|
92
|
+
|
93
|
+
def calls
|
94
|
+
@calls ||= []
|
95
|
+
end
|
96
|
+
end.create
|
97
|
+
assert_equal [:setup, :entity, :entity, :relationship, :save], executed_calls
|
98
|
+
end
|
99
|
+
|
100
|
+
test "create class method should return result of save" do
|
101
|
+
create_simple_domain
|
102
|
+
subclass = Class.new(Diagram) do
|
103
|
+
save do
|
104
|
+
"foobar"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
assert_equal "foobar", subclass.create
|
108
|
+
end
|
109
|
+
|
110
|
+
test "create should return result of save" do
|
111
|
+
create_simple_domain
|
112
|
+
diagram = Class.new(Diagram) do
|
113
|
+
save do
|
114
|
+
"foobar"
|
115
|
+
end
|
116
|
+
end.new(Domain.generate)
|
117
|
+
assert_equal "foobar", diagram.create
|
118
|
+
end
|
119
|
+
|
120
|
+
# Entity filtering =========================================================
|
121
|
+
test "generate should yield entities" do
|
122
|
+
create_model "Foo"
|
123
|
+
assert_equal [Foo], retrieve_entities.map(&:model)
|
124
|
+
end
|
125
|
+
|
126
|
+
test "generate should filter excluded entity" do
|
127
|
+
create_model "Book"
|
128
|
+
create_model "Author"
|
129
|
+
assert_equal [Book], retrieve_entities(:exclude => [:Author]).map(&:model)
|
130
|
+
end
|
131
|
+
|
132
|
+
test "generate should filter excluded entities" do
|
133
|
+
create_model "Book"
|
134
|
+
create_model "Author"
|
135
|
+
create_model "Editor"
|
136
|
+
assert_equal [Book], retrieve_entities(:exclude => [:Author, :Editor]).map(&:model)
|
137
|
+
end
|
138
|
+
|
139
|
+
test "generate should include only specified entity" do
|
140
|
+
create_model "Book"
|
141
|
+
create_model "Author"
|
142
|
+
assert_equal [Book], retrieve_entities(:only => [:Book]).map(&:model)
|
143
|
+
end
|
144
|
+
|
145
|
+
test "generate should include only specified entities" do
|
146
|
+
create_model "Book"
|
147
|
+
create_model "Author"
|
148
|
+
create_model "Editor"
|
149
|
+
assert_equal [Author, Editor], retrieve_entities(:only => [:Author, :Editor]).map(&:model)
|
150
|
+
end
|
151
|
+
|
152
|
+
test "generate should include only specified entities (With the class names as strings)" do
|
153
|
+
create_model "Book"
|
154
|
+
create_model "Author"
|
155
|
+
create_model "Editor"
|
156
|
+
assert_equal [Author, Editor], retrieve_entities(:only => ['Author', 'Editor']).map(&:model)
|
157
|
+
end
|
158
|
+
|
159
|
+
test "generate should filter disconnected entities if disconnected is false" do
|
160
|
+
create_model "Book", :author => :references do
|
161
|
+
belongs_to :author
|
162
|
+
end
|
163
|
+
create_model "Author"
|
164
|
+
create_model "Table", :type => :string
|
165
|
+
assert_equal [Author, Book], retrieve_entities(:disconnected => false).map(&:model)
|
166
|
+
end
|
167
|
+
|
168
|
+
test "generate should yield disconnected entities if disconnected is true" do
|
169
|
+
create_model "Foo", :type => :string
|
170
|
+
assert_equal [Foo], retrieve_entities(:disconnected => true).map(&:model)
|
171
|
+
end
|
172
|
+
|
173
|
+
test "generate should filter specialized entities" do
|
174
|
+
create_model "Foo", :type => :string
|
175
|
+
Object.const_set :SpecialFoo, Class.new(Foo)
|
176
|
+
assert_equal [Foo], retrieve_entities.map(&:model)
|
177
|
+
end
|
178
|
+
|
179
|
+
test "generate should yield specialized entities if inheritance is true" do
|
180
|
+
create_model "Foo", :type => :string
|
181
|
+
Object.const_set :SpecialFoo, Class.new(Foo)
|
182
|
+
assert_equal [Foo, SpecialFoo], retrieve_entities(:inheritance => true).map(&:model)
|
183
|
+
end
|
184
|
+
|
185
|
+
test "generate should yield specialized entities with distinct tables" do
|
186
|
+
create_model "Foo"
|
187
|
+
Object.const_set :SpecialFoo, Class.new(Foo)
|
188
|
+
SpecialFoo.class_eval do
|
189
|
+
self.table_name = "special_foo"
|
190
|
+
end
|
191
|
+
create_table "special_foo", {}, true
|
192
|
+
assert_equal [Foo, SpecialFoo], retrieve_entities.map(&:model)
|
193
|
+
end
|
194
|
+
|
195
|
+
test "generate should filter generalized entities" do
|
196
|
+
create_model "Cannon"
|
197
|
+
create_model "Galleon" do
|
198
|
+
has_many :cannons, :as => :defensible
|
199
|
+
end
|
200
|
+
assert_equal ["Cannon", "Galleon"], retrieve_entities.map(&:name)
|
201
|
+
end
|
202
|
+
|
203
|
+
test "generate should yield generalized entities if polymorphism is true" do
|
204
|
+
create_model "Cannon"
|
205
|
+
create_model "Galleon" do
|
206
|
+
has_many :cannons, :as => :defensible
|
207
|
+
end
|
208
|
+
assert_equal ["Cannon", "Defensible", "Galleon"], retrieve_entities(:polymorphism => true).map(&:name)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Relationship filtering ===================================================
|
212
|
+
test "generate should yield relationships" do
|
213
|
+
create_simple_domain
|
214
|
+
assert_equal 1, retrieve_relationships.length
|
215
|
+
end
|
216
|
+
|
217
|
+
test "generate should yield indirect relationships if indirect is true" do
|
218
|
+
create_model "Foo" do
|
219
|
+
has_many :bazs
|
220
|
+
has_many :bars
|
221
|
+
end
|
222
|
+
create_model "Bar", :foo => :references do
|
223
|
+
belongs_to :foo
|
224
|
+
has_many :bazs, :through => :foo
|
225
|
+
end
|
226
|
+
create_model "Baz", :foo => :references do
|
227
|
+
belongs_to :foo
|
228
|
+
end
|
229
|
+
assert_equal [false, false, true], retrieve_relationships(:indirect => true).map(&:indirect?)
|
230
|
+
end
|
231
|
+
|
232
|
+
test "generate should filter indirect relationships if indirect is false" do
|
233
|
+
create_model "Foo" do
|
234
|
+
has_many :bazs
|
235
|
+
has_many :bars
|
236
|
+
end
|
237
|
+
create_model "Bar", :foo => :references do
|
238
|
+
belongs_to :foo
|
239
|
+
has_many :bazs, :through => :foo
|
240
|
+
end
|
241
|
+
create_model "Baz", :foo => :references do
|
242
|
+
belongs_to :foo
|
243
|
+
end
|
244
|
+
assert_equal [false, false], retrieve_relationships(:indirect => false).map(&:indirect?)
|
245
|
+
end
|
246
|
+
|
247
|
+
test "generate should yield relationships from specialized entities" do
|
248
|
+
create_model "Foo", :bar => :references
|
249
|
+
create_model "Bar", :type => :string
|
250
|
+
Object.const_set :SpecialBar, Class.new(Bar)
|
251
|
+
SpecialBar.class_eval do
|
252
|
+
has_many :foos
|
253
|
+
end
|
254
|
+
assert_equal 1, retrieve_relationships.length
|
255
|
+
end
|
256
|
+
|
257
|
+
test "generate should yield relationships to specialized entities" do
|
258
|
+
create_model "Foo", :type => :string, :bar => :references
|
259
|
+
Object.const_set :SpecialFoo, Class.new(Foo)
|
260
|
+
create_model "Bar" do
|
261
|
+
has_many :special_foos
|
262
|
+
end
|
263
|
+
assert_equal 1, retrieve_relationships.length
|
264
|
+
end
|
265
|
+
|
266
|
+
# Specialization filtering =================================================
|
267
|
+
test "generate should not yield specializations" do
|
268
|
+
create_specialization
|
269
|
+
create_polymorphic_generalization
|
270
|
+
create_abstract_generalization
|
271
|
+
assert_equal [], retrieve_specializations
|
272
|
+
end
|
273
|
+
|
274
|
+
test "generate should yield specializations but not generalizations if inheritance is true" do
|
275
|
+
create_specialization
|
276
|
+
create_polymorphic_generalization
|
277
|
+
create_abstract_generalization
|
278
|
+
assert_equal ["Beer"], retrieve_specializations(:inheritance => true).map { |s| s.specialized.name }
|
279
|
+
end
|
280
|
+
|
281
|
+
test "generate should yield generalizations but not specializations if polymorphism is true" do
|
282
|
+
create_specialization
|
283
|
+
create_polymorphic_generalization
|
284
|
+
create_abstract_generalization
|
285
|
+
assert_equal ["Galleon", "Palace"], retrieve_specializations(:polymorphism => true).map { |s| s.specialized.name }
|
286
|
+
end
|
287
|
+
|
288
|
+
test "generate should yield specializations and generalizations if polymorphism and inheritance is true" do
|
289
|
+
create_specialization
|
290
|
+
create_polymorphic_generalization
|
291
|
+
create_abstract_generalization
|
292
|
+
assert_equal ["Beer", "Galleon", "Palace"], retrieve_specializations(:inheritance => true,
|
293
|
+
:polymorphism => true).map { |s| s.specialized.name }
|
294
|
+
end
|
295
|
+
|
296
|
+
# Attribute filtering ======================================================
|
297
|
+
test "generate should yield content attributes by default" do
|
298
|
+
create_model "Book", :title => :string, :created_at => :datetime, :author => :references do
|
299
|
+
belongs_to :author
|
300
|
+
end
|
301
|
+
create_model "Author"
|
302
|
+
assert_equal %w{title}, retrieve_attribute_lists[Book].map(&:name)
|
303
|
+
end
|
304
|
+
|
305
|
+
test "generate should yield primary key attributes if included" do
|
306
|
+
create_model "Book", :title => :string
|
307
|
+
create_model "Page", :book => :references do
|
308
|
+
belongs_to :book
|
309
|
+
end
|
310
|
+
assert_equal %w{id}, retrieve_attribute_lists(:attributes => [:primary_keys])[Book].map(&:name)
|
311
|
+
end
|
312
|
+
|
313
|
+
test "generate should yield [] if attributes = false" do
|
314
|
+
create_model "Book", :title => :string
|
315
|
+
create_model "Page", :book => :references do
|
316
|
+
belongs_to :book
|
317
|
+
end
|
318
|
+
assert_equal [], retrieve_attribute_lists(:attributes => [:false])[Book].map(&:name)
|
319
|
+
end
|
320
|
+
|
321
|
+
test "generate should yield foreign key attributes if included" do
|
322
|
+
create_model "Book", :author => :references do
|
323
|
+
belongs_to :author
|
324
|
+
end
|
325
|
+
create_model "Author"
|
326
|
+
assert_equal %w{author_id}, retrieve_attribute_lists(:attributes => [:foreign_keys])[Book].map(&:name)
|
327
|
+
end
|
328
|
+
|
329
|
+
test "generate should yield timestamp attributes if included" do
|
330
|
+
create_model "Book", :created_at => :datetime, :created_on => :date, :updated_at => :datetime, :updated_on => :date
|
331
|
+
create_model "Page", :book => :references do
|
332
|
+
belongs_to :book
|
333
|
+
end
|
334
|
+
assert_equal %w{created_at created_on updated_at updated_on},
|
335
|
+
retrieve_attribute_lists(:attributes => [:timestamps])[Book].map(&:name)
|
336
|
+
end
|
337
|
+
|
338
|
+
test "generate should yield combinations of attributes if included" do
|
339
|
+
create_model "Book", :created_at => :datetime, :title => :string, :author => :references do
|
340
|
+
belongs_to :author
|
341
|
+
end
|
342
|
+
create_model "Author"
|
343
|
+
assert_equal %w{created_at title},
|
344
|
+
retrieve_attribute_lists(:attributes => [:content, :timestamps])[Book].map(&:name)
|
345
|
+
end
|
346
|
+
|
347
|
+
test "generate should yield no attributes for specialized entities" do
|
348
|
+
create_model "Beverage", :type => :string, :name => :string, :distillery => :string, :age => :integer
|
349
|
+
Object.const_set :Whisky, Class.new(Beverage)
|
350
|
+
assert_equal [], retrieve_attribute_lists(:inheritance => true)[Whisky].map(&:name)
|
351
|
+
end
|
352
|
+
end
|