rails-erd 0.4.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -49,6 +49,16 @@ class AttributeTest < ActiveSupport::TestCase
49
49
  assert_equal :binary, create_attribute(Foo, "a").type
50
50
  end
51
51
 
52
+ test "type should return native type if unsupported by rails" do
53
+ create_model "Foo"
54
+ ActiveRecord::Schema.define do
55
+ suppress_messages do
56
+ add_column "foos", "a", "REAL"
57
+ end
58
+ end
59
+ assert_equal :real, create_attribute(Foo, "a").type
60
+ end
61
+
52
62
  # Attribute properties =====================================================
53
63
  test "mandatory should return false by default" do
54
64
  create_model "Foo", :column => :string
@@ -75,7 +85,7 @@ class AttributeTest < ActiveSupport::TestCase
75
85
 
76
86
  test "primary_key should return true if column is used as primary key" do
77
87
  create_model "Bar", :my_key => :integer do
78
- set_primary_key :my_key
88
+ self.primary_key = :my_key
79
89
  end
80
90
  assert_equal true, create_attribute(Bar, "my_key").primary_key?
81
91
  end
@@ -114,14 +124,14 @@ class AttributeTest < ActiveSupport::TestCase
114
124
 
115
125
  test "inheritance should return false by default" do
116
126
  create_model "Foo", :type => :string, :alternative => :string do
117
- set_inheritance_column :alternative
127
+ self.inheritance_column = :alternative
118
128
  end
119
129
  assert_equal false, create_attribute(Foo, "type").inheritance?
120
130
  end
121
131
 
122
132
  test "inheritance should return if this column is used for single table inheritance" do
123
133
  create_model "Foo", :type => :string, :alternative => :string do
124
- set_inheritance_column :alternative
134
+ self.inheritance_column = :alternative
125
135
  end
126
136
  assert_equal true, create_attribute(Foo, "alternative").inheritance?
127
137
  end
@@ -145,6 +155,16 @@ class AttributeTest < ActiveSupport::TestCase
145
155
  assert_equal "binary", create_attribute(Foo, "a").type_description
146
156
  end
147
157
 
158
+ test "type_description should return short type description if unsupported by rails" do
159
+ create_model "Foo"
160
+ ActiveRecord::Schema.define do
161
+ suppress_messages do
162
+ add_column "foos", "a", "REAL"
163
+ end
164
+ end
165
+ assert_equal "real", create_attribute(Foo, "a").type_description
166
+ end
167
+
148
168
  test "type_description should return short type description without limit if standard" do
149
169
  with_native_limit :string, 456 do
150
170
  create_model "Foo"
@@ -209,6 +229,28 @@ class AttributeTest < ActiveSupport::TestCase
209
229
  assert_equal nil, create_attribute(Foo, "num").limit
210
230
  end
211
231
 
232
+ test "limit should return nil if type is unsupported by rails" do
233
+ create_model "Foo"
234
+ ActiveRecord::Schema.define do
235
+ suppress_messages do
236
+ add_column "foos", "a", "REAL"
237
+ end
238
+ end
239
+ assert_equal nil, create_attribute(Foo, "a").limit
240
+ end
241
+
242
+ test "limit should return nil for oddball column types that misuse the limit attribute" do
243
+ create_model "Business", :location => :integer
244
+ attribute = create_attribute(Business, "location")
245
+ attribute.column.class_eval do
246
+ define_method :limit do
247
+ # https://github.com/voormedia/rails-erd/issues/21
248
+ { :srid => 4326, :type => "point", :geographic => true }
249
+ end
250
+ end
251
+ assert_equal nil, attribute.limit
252
+ end
253
+
212
254
  test "scale should return scale for decimal columns if nonstandard" do
213
255
  create_model "Foo"
214
256
  add_column :foos, :num, :decimal, :precision => 5, :scale => 2
@@ -226,4 +268,25 @@ class AttributeTest < ActiveSupport::TestCase
226
268
  add_column :foos, :num, :decimal, :precision => 5
227
269
  assert_equal 0, create_attribute(Foo, "num").scale
228
270
  end
271
+
272
+ test "scale should return nil if type is unsupported by rails" do
273
+ create_model "Foo"
274
+ ActiveRecord::Schema.define do
275
+ suppress_messages do
276
+ add_column "foos", "a", "REAL"
277
+ end
278
+ end
279
+ assert_equal nil, create_attribute(Foo, "a").scale
280
+ end
281
+
282
+ test "scale should return nil for oddball column types that misuse the scale attribute" do
283
+ create_model "Kobold", :size => :integer
284
+ attribute = create_attribute(Kobold, "size")
285
+ attribute.column.class_eval do
286
+ define_method :scale do
287
+ 1..5
288
+ end
289
+ end
290
+ assert_equal nil, attribute.scale
291
+ end
229
292
  end
@@ -4,7 +4,7 @@ class CardinalityTest < ActiveSupport::TestCase
4
4
  def setup
5
5
  @n = Domain::Relationship::Cardinality::N
6
6
  end
7
-
7
+
8
8
  # Cardinality ==============================================================
9
9
  test "inspect should show source and destination ranges" do
10
10
  assert_match %r{#<RailsERD::Domain::Relationship::Cardinality:.* @source_range=1\.\.1 @destination_range=1\.\.Infinity>},
@@ -15,7 +15,7 @@ class CardinalityTest < ActiveSupport::TestCase
15
15
  test "new should return cardinality object" do
16
16
  assert_kind_of Domain::Relationship::Cardinality, Domain::Relationship::Cardinality.new(1, 1..@n)
17
17
  end
18
-
18
+
19
19
  # Cardinality properties ===================================================
20
20
  test "source_optional should return true if source range starts at zero" do
21
21
  assert_equal true, Domain::Relationship::Cardinality.new(0..1, 1).source_optional?
@@ -32,11 +32,11 @@ class CardinalityTest < ActiveSupport::TestCase
32
32
  test "destination_optional should return false if destination range starts at one or more" do
33
33
  assert_equal false, Domain::Relationship::Cardinality.new(0..1, 1..2).destination_optional?
34
34
  end
35
-
35
+
36
36
  test "inverse should return inverse cardinality" do
37
37
  assert_equal Domain::Relationship::Cardinality.new(23..45, 0..15), Domain::Relationship::Cardinality.new(0..15, 23..45).inverse
38
38
  end
39
-
39
+
40
40
  # Cardinality equality =====================================================
41
41
  test "cardinalities are equal if they have the same boundaries" do
42
42
  assert_equal Domain::Relationship::Cardinality.new(1, 1..Domain::Relationship::Cardinality::N),
@@ -52,7 +52,7 @@ class CardinalityTest < ActiveSupport::TestCase
52
52
  assert_not_equal Domain::Relationship::Cardinality.new(0..1, 1..Domain::Relationship::Cardinality::N),
53
53
  Domain::Relationship::Cardinality.new(0..1, 2..Domain::Relationship::Cardinality::N)
54
54
  end
55
-
55
+
56
56
  # Cardinal names ===========================================================
57
57
  test "one_to_one should return true if source and destination are exactly one" do
58
58
  assert_equal true, Domain::Relationship::Cardinality.new(1, 1).one_to_one?
@@ -65,11 +65,11 @@ class CardinalityTest < ActiveSupport::TestCase
65
65
  test "one_to_one should return false if source range upper limit is more than one" do
66
66
  assert_equal false, Domain::Relationship::Cardinality.new(0..15, 0..1).one_to_one?
67
67
  end
68
-
68
+
69
69
  test "one_to_one should return false if destination range upper limit is more than one" do
70
70
  assert_equal false, Domain::Relationship::Cardinality.new(0..1, 0..15).one_to_one?
71
71
  end
72
-
72
+
73
73
  test "one_to_many should return true if source is exactly one and destination is higher than one" do
74
74
  assert_equal true, Domain::Relationship::Cardinality.new(1, 15).one_to_many?
75
75
  end
@@ -81,7 +81,7 @@ class CardinalityTest < ActiveSupport::TestCase
81
81
  test "one_to_many should return false if source range upper limit is more than one" do
82
82
  assert_equal false, Domain::Relationship::Cardinality.new(0..15, 0..15).one_to_many?
83
83
  end
84
-
84
+
85
85
  test "one_to_many should return false if destination range upper limit is one" do
86
86
  assert_equal false, Domain::Relationship::Cardinality.new(0..1, 1).one_to_many?
87
87
  end
@@ -97,11 +97,11 @@ class CardinalityTest < ActiveSupport::TestCase
97
97
  test "many_to_many should return false if source range upper limit is is one" do
98
98
  assert_equal false, Domain::Relationship::Cardinality.new(1, 0..15).many_to_many?
99
99
  end
100
-
100
+
101
101
  test "many_to_many should return false if destination range upper limit is one" do
102
102
  assert_equal false, Domain::Relationship::Cardinality.new(0..1, 1).many_to_many?
103
103
  end
104
-
104
+
105
105
  test "inverse of one_to_many should be many_to_one" do
106
106
  assert_equal true, Domain::Relationship::Cardinality.new(0..1, 0..@n).inverse.many_to_one?
107
107
  end
@@ -4,11 +4,11 @@ class DiagramTest < ActiveSupport::TestCase
4
4
  def setup
5
5
  load "rails_erd/diagram.rb"
6
6
  end
7
-
7
+
8
8
  def teardown
9
9
  RailsERD.send :remove_const, :Diagram
10
10
  end
11
-
11
+
12
12
  def retrieve_entities(options = {})
13
13
  klass = Class.new(Diagram)
14
14
  [].tap do |entities|
@@ -20,7 +20,7 @@ class DiagramTest < ActiveSupport::TestCase
20
20
  klass.create(options)
21
21
  end
22
22
  end
23
-
23
+
24
24
  def retrieve_relationships(options = {})
25
25
  klass = Class.new(Diagram)
26
26
  [].tap do |relationships|
@@ -32,7 +32,7 @@ class DiagramTest < ActiveSupport::TestCase
32
32
  klass.create(options)
33
33
  end
34
34
  end
35
-
35
+
36
36
  def retrieve_specializations(options = {})
37
37
  klass = Class.new(Diagram)
38
38
  [].tap do |specializations|
@@ -56,7 +56,7 @@ class DiagramTest < ActiveSupport::TestCase
56
56
  klass.create(options)
57
57
  end
58
58
  end
59
-
59
+
60
60
  # Diagram ==================================================================
61
61
  test "domain sould return given domain" do
62
62
  domain = Object.new
@@ -84,19 +84,19 @@ class DiagramTest < ActiveSupport::TestCase
84
84
  setup do
85
85
  calls << :setup
86
86
  end
87
-
87
+
88
88
  each_entity do
89
89
  calls << :entity
90
90
  end
91
-
91
+
92
92
  each_relationship do
93
93
  calls << :relationship
94
94
  end
95
-
95
+
96
96
  save do
97
97
  calls << :save
98
98
  end
99
-
99
+
100
100
  def calls
101
101
  @calls ||= []
102
102
  end
@@ -123,13 +123,39 @@ class DiagramTest < ActiveSupport::TestCase
123
123
  end.new(Domain.generate)
124
124
  assert_equal "foobar", diagram.create
125
125
  end
126
-
126
+
127
127
  # Entity filtering =========================================================
128
128
  test "generate should yield entities" do
129
129
  create_model "Foo"
130
130
  assert_equal [Foo], retrieve_entities.map(&:model)
131
131
  end
132
132
 
133
+ test "generate should filter excluded entity" do
134
+ create_model "Book"
135
+ create_model "Author"
136
+ assert_equal [Book], retrieve_entities(:exclude => :Author).map(&:model)
137
+ end
138
+
139
+ test "generate should filter excluded entities" do
140
+ create_model "Book"
141
+ create_model "Author"
142
+ create_model "Editor"
143
+ assert_equal [Book], retrieve_entities(:exclude => [:Author, :Editor]).map(&:model)
144
+ end
145
+
146
+ test "generate should include only specified entity" do
147
+ create_model "Book"
148
+ create_model "Author"
149
+ assert_equal [Book], retrieve_entities(:only => [:Book]).map(&:model)
150
+ end
151
+
152
+ test "generate should include only specified entities" 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
+
133
159
  test "generate should filter disconnected entities if disconnected is false" do
134
160
  create_model "Book", :author => :references do
135
161
  belongs_to :author
@@ -149,7 +175,7 @@ class DiagramTest < ActiveSupport::TestCase
149
175
  Object.const_set :SpecialFoo, Class.new(Foo)
150
176
  assert_equal [Foo], retrieve_entities.map(&:model)
151
177
  end
152
-
178
+
153
179
  test "generate should yield specialized entities if inheritance is true" do
154
180
  create_model "Foo", :type => :string
155
181
  Object.const_set :SpecialFoo, Class.new(Foo)
@@ -160,7 +186,7 @@ class DiagramTest < ActiveSupport::TestCase
160
186
  create_model "Foo"
161
187
  Object.const_set :SpecialFoo, Class.new(Foo)
162
188
  SpecialFoo.class_eval do
163
- set_table_name "special_foo"
189
+ self.table_name = "special_foo"
164
190
  end
165
191
  create_table "special_foo", {}, true
166
192
  assert_equal [Foo, SpecialFoo], retrieve_entities.map(&:model)
@@ -173,7 +199,7 @@ class DiagramTest < ActiveSupport::TestCase
173
199
  end
174
200
  assert_equal ["Cannon", "Galleon"], retrieve_entities.map(&:name)
175
201
  end
176
-
202
+
177
203
  test "generate should yield generalized entities if polymorphism is true" do
178
204
  create_model "Cannon"
179
205
  create_model "Galleon" do
@@ -181,7 +207,7 @@ class DiagramTest < ActiveSupport::TestCase
181
207
  end
182
208
  assert_equal ["Cannon", "Defensible", "Galleon"], retrieve_entities(:polymorphism => true).map(&:name)
183
209
  end
184
-
210
+
185
211
  # Relationship filtering ===================================================
186
212
  test "generate should yield relationships" do
187
213
  create_simple_domain
@@ -202,7 +228,7 @@ class DiagramTest < ActiveSupport::TestCase
202
228
  end
203
229
  assert_equal [false, false, true], retrieve_relationships(:indirect => true).map(&:indirect?)
204
230
  end
205
-
231
+
206
232
  test "generate should filter indirect relationships if indirect is false" do
207
233
  create_model "Foo" do
208
234
  has_many :bazs
@@ -227,7 +253,7 @@ class DiagramTest < ActiveSupport::TestCase
227
253
  end
228
254
  assert_equal 1, retrieve_relationships.length
229
255
  end
230
-
256
+
231
257
  test "generate should yield relationships to specialized entities" do
232
258
  create_model "Foo", :type => :string, :bar => :references
233
259
  Object.const_set :SpecialFoo, Class.new(Foo)
@@ -243,7 +269,7 @@ class DiagramTest < ActiveSupport::TestCase
243
269
  create_generalization
244
270
  assert_equal [], retrieve_specializations
245
271
  end
246
-
272
+
247
273
  test "generate should yield specializations but not generalizations if inheritance is true" do
248
274
  create_specialization
249
275
  create_generalization
@@ -305,7 +331,7 @@ class DiagramTest < ActiveSupport::TestCase
305
331
  assert_equal %w{created_at title},
306
332
  retrieve_attribute_lists(:attributes => [:content, :timestamps])[Book].map(&:name)
307
333
  end
308
-
334
+
309
335
  test "generate should yield no attributes for specialized entities" do
310
336
  create_model "Beverage", :type => :string, :name => :string, :distillery => :string, :age => :integer
311
337
  Object.const_set :Whisky, Class.new(Beverage)
@@ -5,7 +5,7 @@ class DomainTest < ActiveSupport::TestCase
5
5
  test "generate should return domain" do
6
6
  assert_kind_of Domain, Domain.generate
7
7
  end
8
-
8
+
9
9
  test "name should return rails application name" do
10
10
  begin
11
11
  Object::Quux = Module.new
@@ -18,11 +18,11 @@ class DomainTest < ActiveSupport::TestCase
18
18
  Object.send :remove_const, :Rails
19
19
  end
20
20
  end
21
-
21
+
22
22
  test "name should return nil outside rails" do
23
23
  assert_nil Domain.generate.name
24
24
  end
25
-
25
+
26
26
  test "inspect should display object id only" do
27
27
  create_model "Foo", :bar => :references do
28
28
  belongs_to :bar
@@ -30,18 +30,18 @@ class DomainTest < ActiveSupport::TestCase
30
30
  create_model "Bar"
31
31
  assert_match %r{#<RailsERD::Domain:.*>}, Domain.generate.inspect
32
32
  end
33
-
33
+
34
34
  # Entity processing ========================================================
35
35
  test "entity_by_name should return associated entity for given name" do
36
36
  create_model "Foo"
37
37
  assert_equal Foo, Domain.generate.entity_by_name("Foo").model
38
38
  end
39
-
39
+
40
40
  test "entities should return domain entities" do
41
41
  create_models "Foo", "Bar"
42
42
  assert_equal [Domain::Entity] * 2, Domain.generate.entities.collect(&:class)
43
43
  end
44
-
44
+
45
45
  test "entities should return all domain entities sorted by name" do
46
46
  create_models "Foo", "Bar", "Baz", "Qux"
47
47
  assert_equal [Bar, Baz, Foo, Qux], Domain.generate.entities.collect(&:model)
@@ -63,22 +63,22 @@ class DomainTest < ActiveSupport::TestCase
63
63
  end
64
64
  assert_equal ["Defensible", "Galleon", "Stronghold"], Domain.generate.entities.collect(&:name)
65
65
  end
66
-
66
+
67
67
  test "entities should omit abstract models" do
68
68
  Object.const_set :Foo, Class.new(ActiveRecord::Base) { self.abstract_class = true }
69
69
  create_model "Bar", Foo do
70
- set_table_name "bars"
70
+ self.table_name = "bars"
71
71
  end
72
72
  create_table "foos", {}, true
73
73
  create_table "bars", {}, true
74
74
  assert_equal ["Bar"], Domain.generate.entities.collect(&:name)
75
75
  end
76
-
76
+
77
77
  # Relationship processing ==================================================
78
78
  test "relationships should return empty array for empty domain" do
79
79
  assert_equal [], Domain.generate.relationships
80
80
  end
81
-
81
+
82
82
  test "relationships should return relationships in domain model" do
83
83
  create_models "Baz", "Qux"
84
84
  create_model "Foo", :bar => :references, :qux => :references do
@@ -90,7 +90,7 @@ class DomainTest < ActiveSupport::TestCase
90
90
  end
91
91
  assert_equal [Domain::Relationship] * 3, Domain.generate.relationships.collect(&:class)
92
92
  end
93
-
93
+
94
94
  test "relationships should count mutual relationship as one" do
95
95
  create_model "Foo", :bar => :references do
96
96
  belongs_to :bar
@@ -116,7 +116,7 @@ class DomainTest < ActiveSupport::TestCase
116
116
  end
117
117
  assert_equal [Domain::Relationship], Domain.generate.relationships.select(&:indirect?).collect(&:class)
118
118
  end
119
-
119
+
120
120
  test "relationships should count relationship between same models with distinct foreign key seperately" do
121
121
  create_model "Foo", :bar => :references, :special_bar => :references do
122
122
  belongs_to :bar
@@ -126,7 +126,7 @@ class DomainTest < ActiveSupport::TestCase
126
126
  end
127
127
  assert_equal [Domain::Relationship] * 2, Domain.generate.relationships.collect(&:class)
128
128
  end
129
-
129
+
130
130
  test "relationships should use model name first in alphabet as source for many to many relationships" do
131
131
  create_table "many_more", :many_id => :integer, :more_id => :integer
132
132
  create_model "Many" do
@@ -138,7 +138,7 @@ class DomainTest < ActiveSupport::TestCase
138
138
  relationship = Domain.generate.relationships.first
139
139
  assert_equal ["Many", "More"], [relationship.source.name, relationship.destination.name]
140
140
  end
141
-
141
+
142
142
  # Specialization processing ================================================
143
143
  test "specializations should return empty array for empty domain" do
144
144
  assert_equal [], Domain.generate.specializations
@@ -159,7 +159,7 @@ class DomainTest < ActiveSupport::TestCase
159
159
  Object.const_set :BelgianBeer, Class.new(Beer)
160
160
  assert_equal [Domain::Specialization] * 2, Domain.generate.specializations.collect(&:class)
161
161
  end
162
-
162
+
163
163
  test "specializations should return generalizations in domain model" do
164
164
  create_model "Post" do
165
165
  has_many :assets, :as => :attachable
@@ -180,7 +180,7 @@ class DomainTest < ActiveSupport::TestCase
180
180
  end
181
181
  assert_equal [Domain::Specialization] * 2, Domain.generate.specializations.collect(&:class)
182
182
  end
183
-
183
+
184
184
  # test "generalizations should ..." do
185
185
  # # TODO
186
186
  # create_model "Post" do
@@ -191,7 +191,7 @@ class DomainTest < ActiveSupport::TestCase
191
191
  # end
192
192
  # assert_equal [], Domain.generate.relationships
193
193
  # end
194
-
194
+
195
195
  # Erroneous associations ===================================================
196
196
  test "relationships should omit bad has_many associations" do
197
197
  create_model "Foo" do
@@ -199,14 +199,14 @@ class DomainTest < ActiveSupport::TestCase
199
199
  end
200
200
  assert_equal [], Domain.generate(:warn => false).relationships
201
201
  end
202
-
202
+
203
203
  test "relationships should omit bad has_many through association" do
204
204
  create_model "Foo" do
205
205
  has_many :flabs, :through => :bars
206
206
  end
207
207
  assert_equal [], Domain.generate(:warn => false).relationships
208
208
  end
209
-
209
+
210
210
  test "relationships should omit association to model outside domain" do
211
211
  create_model "Foo" do
212
212
  has_many :bars
@@ -258,7 +258,7 @@ class DomainTest < ActiveSupport::TestCase
258
258
  end
259
259
  assert_equal "", output
260
260
  end
261
-
261
+
262
262
  # Erroneous models =========================================================
263
263
  test "entities should omit bad models" do
264
264
  Object.const_set :Foo, Class.new(ActiveRecord::Base)