schema_plus 2.0.0.pre16 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,256 +0,0 @@
1
- require 'spec_helper'
2
- require 'stringio'
3
-
4
- describe "Schema dump" do
5
-
6
- before(:all) do
7
- SchemaPlus::ForeignKeys.setup do |config|
8
- config.auto_create = false
9
- end
10
- ActiveRecord::Migration.suppress_messages do
11
- ActiveRecord::Schema.define do
12
- connection.tables.each do |table| drop_table table, force: :cascade end
13
-
14
- create_table :users, :force => true do |t|
15
- t.string :login
16
- t.datetime :deleted_at
17
- t.integer :first_post_id, index: { unique: true }
18
- end
19
-
20
- create_table :posts, :force => true do |t|
21
- t.text :body
22
- t.integer :user_id
23
- t.integer :first_comment_id
24
- t.string :string_no_default
25
- t.integer :short_id
26
- t.string :str_short
27
- t.integer :integer_col
28
- t.float :float_col
29
- t.decimal :decimal_col
30
- t.datetime :datetime_col
31
- t.timestamp :timestamp_col
32
- t.time :time_col
33
- t.date :date_col
34
- t.binary :binary_col
35
- t.boolean :boolean_col
36
- end
37
-
38
- create_table :comments, :force => true do |t|
39
- t.text :body
40
- t.integer :post_id
41
- t.integer :commenter_id
42
- end
43
- end
44
- end
45
- class ::User < ActiveRecord::Base ; end
46
- class ::Post < ActiveRecord::Base ; end
47
- class ::Comment < ActiveRecord::Base ; end
48
- end
49
-
50
- it "should include foreign_key definition" do
51
- with_foreign_key Post, :user_id, :users, :id do
52
- expect(dump_posts).to match(%r{t.integer\s+"user_id".*foreign_key.*users})
53
- end
54
- end
55
-
56
- it "should include foreign_key name" do
57
- with_foreign_key Post, :user_id, :users, :id, :name => "yippee" do
58
- expect(dump_posts).to match(/user_id.*foreign_key.*users.*name: "yippee"/)
59
- end
60
- end
61
-
62
- it "should respect foreign key's primary key" do
63
- with_foreign_key Post, :user_id, :users, :first_post_id do
64
- expect(dump_posts).to match(%r{t.integer\s+"user_id".*foreign_key.*primary_key: "first_post_id"})
65
- end
66
- end
67
-
68
-
69
- it "should include foreign_key exactly once" do
70
- with_foreign_key Post, :user_id, :users, :id, :name => "yippee" do
71
- expect(dump_posts.scan(/foreign_key.*yippee"/).length).to eq 1
72
- end
73
- end
74
-
75
-
76
- xit "should sort foreign_key definitions" do
77
- with_foreign_keys Comment, [ [ :post_id, :posts, :id ], [ :commenter_id, :users, :id ]] do
78
- expect(dump_schema).to match(/foreign_key.+commenter_id.+foreign_key.+post_id/m)
79
- end
80
- end
81
-
82
- context "with constraint dependencies" do
83
- it "should sort in Posts => Comments direction" do
84
- with_foreign_key Comment, :post_id, :posts, :id do
85
- expect(dump_schema).to match(%r{create_table "posts".*create_table "comments"}m)
86
- end
87
- end
88
- it "should sort in Comments => Posts direction" do
89
- with_foreign_key Post, :first_comment_id, :comments, :id do
90
- expect(dump_schema).to match(%r{create_table "comments".*create_table "posts"}m)
91
- end
92
- end
93
-
94
- it "should handle regexp in ignore_tables" do
95
- with_foreign_key Comment, :post_id, :posts, :id do
96
- dump = dump_schema(:ignore => /post/)
97
- expect(dump).to match(/create_table "comments"/)
98
- expect(dump).not_to match(/create_table "posts"/)
99
- end
100
- end
101
-
102
- end
103
-
104
- it "should include foreign_key options" do
105
- with_foreign_key Post, :user_id, :users, :id, :on_update => :cascade, :on_delete => :nullify do
106
- expect(dump_posts).to match(%q[t.integer\s*"user_id",.*foreign_key: {references: "users", name: "fk_posts_user_id", on_update: :cascade, on_delete: :nullify}])
107
- end
108
- end
109
-
110
- context "with cyclic foreign key constraints", :sqlite3 => :skip do
111
- before(:all) do
112
- ActiveRecord::Base.connection.add_foreign_key(Comment.table_name, User.table_name, column: :commenter_id)
113
- ActiveRecord::Base.connection.add_foreign_key(Comment.table_name, Post.table_name, column: :post_id)
114
- ActiveRecord::Base.connection.add_foreign_key(Post.table_name, Comment.table_name, column: :first_comment_id)
115
- ActiveRecord::Base.connection.add_foreign_key(Post.table_name, User.table_name, column: :user_id)
116
- ActiveRecord::Base.connection.add_foreign_key(User.table_name, Post.table_name, column: :first_post_id)
117
- end
118
-
119
- it "should not raise an error" do
120
- expect { dump_schema }.to_not raise_error
121
- end
122
-
123
- ["comments", "posts", "users"].each do |table|
124
- it "should dump constraints for table #{table.inspect} after the table definition" do
125
- dump = dump_schema.gsub(/#[^\n*]/m, '')
126
- expect(dump =~ %r{create_table "#{table}"}).to be < (dump =~ %r{foreign_key.*"#{table}"})
127
- end
128
- end
129
-
130
- ["comments", "posts"].each do |table|
131
- qtable = table.inspect
132
- it "should dump comments for delayed constraint definition referencing table #{qtable}" do
133
- expect(dump_schema).to match(%r{# foreign key references #{qtable}.*create_table #{qtable}.*add_foreign_key \S+, #{qtable}}m)
134
- end
135
- end
136
-
137
- context 'with complicated schemas' do
138
- before(:all) do
139
-
140
- SchemaPlus::ForeignKeys.setup do |config|
141
- config.auto_create = false
142
- end
143
- ActiveRecord::Migration.suppress_messages do
144
- ActiveRecord::Schema.define do
145
- connection.tables.each do |table| drop_table table, force: :cascade end
146
-
147
- create_table :grade_systems, force: true do |t|
148
- t.string :name
149
- t.integer :school_id
150
- t.integer :parent_id
151
- t.integer :profile_id
152
- end
153
-
154
- create_table :schools, force: true do |t|
155
- t.string :name
156
- t.integer :default_grade_system_id
157
- end
158
-
159
- create_table :academic_years, force: true do |t|
160
- t.string :name
161
- t.integer :school_id
162
- end
163
-
164
- create_table :buildings, force: true do |t|
165
- t.string :name
166
- t.integer :school_id
167
- end
168
-
169
- create_table :profiles, force: true do |t|
170
- t.integer :school_id
171
- t.integer :building_id
172
- end
173
-
174
- end
175
- end
176
-
177
- class ::AcademicYear < ActiveRecord::Base ; end
178
- class ::Building < ActiveRecord::Base ; end
179
- class ::GradeSystem < ActiveRecord::Base ; end
180
- class ::Profile < ActiveRecord::Base ; end
181
- class ::School < ActiveRecord::Base ; end
182
-
183
- ActiveRecord::Base.connection.add_foreign_key(School.table_name, GradeSystem.table_name, column: :default_grade_system_id)
184
- ActiveRecord::Base.connection.add_foreign_key(GradeSystem.table_name, School.table_name, column: :school_id)
185
- ActiveRecord::Base.connection.add_foreign_key(GradeSystem.table_name, GradeSystem.table_name, column: :parent_id)
186
- ActiveRecord::Base.connection.add_foreign_key(GradeSystem.table_name, Profile.table_name, column: :profile_id)
187
- ActiveRecord::Base.connection.add_foreign_key(Profile.table_name, Building.table_name, column: :building_id)
188
- ActiveRecord::Base.connection.add_foreign_key(Profile.table_name, School.table_name, column: :school_id)
189
- ActiveRecord::Base.connection.add_foreign_key(Building.table_name, School.table_name, column: :school_id)
190
- ActiveRecord::Base.connection.add_foreign_key(AcademicYear.table_name, School.table_name, column: :school_id)
191
- end
192
-
193
- it "should not raise an error" do
194
- expect { dump_schema }.to_not raise_error
195
- end
196
-
197
- ["buildings", "grade_systems", "profiles", "schools"].each do |table|
198
- it "should dump constraints for table #{table.inspect} after the table definition" do
199
- expect(dump_schema =~ %r{create_table "#{table}"}).to be < (dump_schema =~ %r{foreign_key.*"#{table}"})
200
- end
201
- end
202
- end
203
- end
204
-
205
- protected
206
- def to_regexp(string)
207
- Regexp.new(Regexp.escape(string))
208
- end
209
-
210
- def with_foreign_key(model, columns, referenced_table_name, referenced_columns, options = {}, &block)
211
- with_foreign_keys(model, [[columns, referenced_table_name, referenced_columns, options]], &block)
212
- end
213
-
214
- def with_foreign_keys(model, columnsets)
215
- table_columns = model.columns.reject{|column| column.name == 'id'}
216
- ActiveRecord::Migration.suppress_messages do
217
- ActiveRecord::Migration.create_table model.table_name, :force => true do |t|
218
- table_columns.each do |column|
219
- t.column column.name, column.type
220
- end
221
- columnsets.each do |columns, referenced_table_name, referenced_columns, options|
222
- t.foreign_key columns, referenced_table_name, (options||{}).merge(primary_key: referenced_columns)
223
- end
224
- end
225
- end
226
- model.reset_column_information
227
- begin
228
- yield
229
- ensure
230
- ActiveRecord::Migration.suppress_messages do
231
- ActiveRecord::Migration.create_table model.table_name, :force => true do |t|
232
- table_columns.each do |column|
233
- t.column column.name, column.type
234
- end
235
- end
236
- end
237
- end
238
- end
239
-
240
- def determine_foreign_key_name(model, columns, options)
241
- name = options[:name]
242
- name ||= model.foreign_keys.detect { |fk| fk.from_table == model.table_name.to_s && Array.wrap(fk.column) == Array.wrap(columns).collect(&:to_s) }.name
243
- end
244
-
245
- def dump_schema(opts={})
246
- stream = StringIO.new
247
- ActiveRecord::SchemaDumper.ignore_tables = Array.wrap(opts[:ignore]) || []
248
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
249
- stream.string
250
- end
251
-
252
- def dump_posts
253
- dump_schema(:ignore => %w[users comments])
254
- end
255
-
256
- end
@@ -1,99 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecord::Schema do
4
-
5
- let(:schema) { ActiveRecord::Schema }
6
-
7
- let(:connection) { ActiveRecord::Base.connection }
8
-
9
- context "defining with auto_index and auto_create" do
10
-
11
- around(:each) do |example|
12
- with_auto_index do
13
- with_auto_create do
14
- example.run
15
- end
16
- end
17
- end
18
-
19
- it "should pass" do
20
- expect { do_schema }.to_not raise_error
21
- end
22
-
23
- it "should create only explicity added indexes" do
24
- do_schema
25
- expected = SchemaDev::Rspec::Helpers.mysql? ? 2 : 1
26
- expect(connection.tables.collect { |table| connection.indexes(table) }.flatten.size).to eq(expected)
27
- end
28
-
29
- it "should create only explicity added foriegn keys" do
30
- do_schema
31
- expect(connection.tables.collect { |table| connection.foreign_keys(table) }.flatten.size).to eq(2)
32
- end
33
-
34
- protected
35
-
36
- def do_schema
37
- define_schema do
38
-
39
- create_table :users, :force => true do
40
- end
41
-
42
- create_table :colors, :force => true do
43
- end
44
-
45
- create_table :shoes, :force => true do
46
- end
47
-
48
- create_table :posts, :force => true do |t|
49
- t.integer :user_id, :references => :users, :index => true
50
- t.integer :shoe_id, :references => :shoes # should not have an index (except mysql)
51
- t.integer :color_id # should not have a foreign key nor index
52
- end
53
- end
54
- end
55
-
56
- end
57
-
58
- it "handles explicit foreign keys" do
59
- expect {
60
- with_auto_create(false) do
61
- define_schema do
62
- create_table :users, :force => :cascade do
63
- end
64
-
65
- create_table :posts, :force => :cascade do |t|
66
- t.integer :user_id
67
- t.foreign_key :users
68
- end
69
- end
70
- end
71
- }.not_to raise_error
72
- expect(connection.foreign_keys("posts").first.to_table).to eq "users"
73
- end
74
-
75
-
76
- protected
77
-
78
-
79
- def with_auto_index(value = true)
80
- old_value = SchemaPlus::ForeignKeys.config.auto_index
81
- SchemaPlus::ForeignKeys.config.auto_index = value
82
- begin
83
- yield
84
- ensure
85
- SchemaPlus::ForeignKeys.config.auto_index = old_value
86
- end
87
- end
88
-
89
- def with_auto_create(value = true)
90
- old_value = SchemaPlus::ForeignKeys.config.auto_create
91
- SchemaPlus::ForeignKeys.config.auto_create = value
92
- begin
93
- yield
94
- ensure
95
- SchemaPlus::ForeignKeys.config.auto_create = old_value
96
- end
97
- end
98
-
99
- end