declare_schema 0.2.0.pre.1 → 0.3.1
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 +4 -4
- data/CHANGELOG.md +26 -2
- data/Gemfile.lock +13 -13
- data/README.md +20 -0
- data/lib/declare_schema/model.rb +30 -23
- data/lib/declare_schema/model/field_spec.rb +1 -1
- data/lib/declare_schema/version.rb +1 -1
- data/lib/generators/declare_schema/migration/migrator.rb +41 -29
- data/lib/generators/declare_schema/migration/templates/migration.rb.erb +1 -1
- data/spec/lib/declare_schema/api_spec.rb +6 -7
- data/spec/lib/declare_schema/generator_spec.rb +51 -10
- data/spec/lib/declare_schema/interactive_primary_key_spec.rb +3 -3
- data/spec/lib/declare_schema/migration_generator_spec.rb +422 -198
- data/spec/lib/declare_schema/prepare_testapp.rb +2 -0
- data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +72 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/acceptance_spec_helpers.rb +57 -0
- metadata +4 -2
@@ -12,7 +12,7 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
|
|
12
12
|
self.primary_key = "foo_id"
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
generate_migrations '-n', '-m'
|
16
16
|
expect(Foo.primary_key).to eq('foo_id')
|
17
17
|
|
18
18
|
### migrate from
|
@@ -24,7 +24,7 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
puts "\n\e[45m Please enter 'id' (no quotes) at the next prompt \e[0m"
|
27
|
-
|
27
|
+
generate_migrations '-n', '-m'
|
28
28
|
expect(Foo.primary_key).to eq('id')
|
29
29
|
|
30
30
|
nuke_model_class(Foo)
|
@@ -39,7 +39,7 @@ RSpec.describe 'DeclareSchema Migration Generator interactive primary key' do
|
|
39
39
|
end
|
40
40
|
|
41
41
|
puts "\n\e[45m Please enter 'drop id' (no quotes) at the next prompt \e[0m"
|
42
|
-
|
42
|
+
generate_migrations '-n', '-m'
|
43
43
|
expect(Foo.primary_key).to eq('foo_id')
|
44
44
|
|
45
45
|
### ensure it doesn't cause further migrations
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'rails'
|
4
|
+
|
3
5
|
RSpec.describe 'DeclareSchema Migration Generator' do
|
4
6
|
before do
|
5
7
|
load File.expand_path('prepare_testapp.rb', __dir__)
|
@@ -9,14 +11,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
9
11
|
it 'generates migrations' do
|
10
12
|
## The migration generator -- introduction
|
11
13
|
|
12
|
-
|
13
|
-
expect(up_down).to eq(["", ""])
|
14
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to migrate_up("").and migrate_down("")
|
14
15
|
|
15
16
|
class Advert < ActiveRecord::Base
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
|
-
expect(up_down).to eq(["", ""])
|
19
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to migrate_up("").and migrate_down("")
|
20
20
|
|
21
21
|
Generators::DeclareSchema::Migration::Migrator.ignore_tables = ["green_fishes"]
|
22
22
|
|
@@ -28,13 +28,17 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
28
28
|
name :string, limit: 255, null: true
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
|
32
|
+
up, _ = Generators::DeclareSchema::Migration::Migrator.run.tap do |migrations|
|
33
|
+
expect(migrations).to(
|
34
|
+
migrate_up(<<~EOS.strip)
|
35
|
+
create_table :adverts, id: :bigint do |t|
|
36
|
+
t.string :name, limit: 255
|
37
|
+
end
|
38
|
+
EOS
|
39
|
+
.and migrate_down("drop_table :adverts")
|
40
|
+
)
|
41
|
+
end
|
38
42
|
|
39
43
|
ActiveRecord::Migration.class_eval(up)
|
40
44
|
expect(Advert.columns.map(&:name)).to eq(["id", "name"])
|
@@ -46,19 +50,20 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
46
50
|
published_at :datetime, null: true
|
47
51
|
end
|
48
52
|
end
|
49
|
-
up, down = migrate
|
50
|
-
expect(up).to eq(<<~EOS.strip)
|
51
|
-
add_column :adverts, :body, :text
|
52
|
-
add_column :adverts, :published_at, :datetime
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
expect(migrate).to(
|
55
|
+
migrate_up(<<~EOS.strip)
|
56
|
+
add_column :adverts, :body, :text
|
57
|
+
add_column :adverts, :published_at, :datetime
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
add_index :adverts, [:id], unique: true, name: 'PRIMARY_KEY'
|
60
|
+
EOS
|
61
|
+
.and migrate_down(<<~EOS.strip)
|
62
|
+
remove_column :adverts, :body
|
63
|
+
remove_column :adverts, :published_at
|
64
|
+
EOS
|
65
|
+
)
|
66
|
+
# TODO: ^ TECH-4975 add_index should not be there
|
62
67
|
|
63
68
|
Advert.field_specs.clear # not normally needed
|
64
69
|
class Advert < ActiveRecord::Base
|
@@ -68,9 +73,11 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
71
|
-
|
72
|
-
|
73
|
-
|
76
|
+
expect(migrate).to(
|
77
|
+
migrate_up("remove_column :adverts, :published_at").and(
|
78
|
+
migrate_down("add_column :adverts, :published_at, :datetime")
|
79
|
+
)
|
80
|
+
)
|
74
81
|
|
75
82
|
nuke_model_class(Advert)
|
76
83
|
class Advert < ActiveRecord::Base
|
@@ -80,20 +87,22 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
80
87
|
end
|
81
88
|
end
|
82
89
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
90
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
91
|
+
migrate_up(<<~EOS.strip)
|
92
|
+
add_column :adverts, :title, :string, limit: 255
|
93
|
+
remove_column :adverts, :name
|
94
|
+
EOS
|
95
|
+
.and migrate_down(<<~EOS.strip)
|
96
|
+
remove_column :adverts, :title
|
97
|
+
add_column :adverts, :name, :string, limit: 255
|
98
|
+
EOS
|
99
|
+
)
|
88
100
|
|
89
|
-
expect(
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
up, down = Generators::DeclareSchema::Migration::Migrator.run(adverts: { name: :title })
|
95
|
-
expect(up).to eq("rename_column :adverts, :name, :title")
|
96
|
-
expect(down).to eq("rename_column :adverts, :title, :name")
|
101
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { name: :title })).to(
|
102
|
+
migrate_up("rename_column :adverts, :name, :title").and(
|
103
|
+
migrate_down("rename_column :adverts, :title, :name")
|
104
|
+
)
|
105
|
+
)
|
97
106
|
|
98
107
|
migrate
|
99
108
|
|
@@ -104,9 +113,11 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
104
113
|
end
|
105
114
|
end
|
106
115
|
|
107
|
-
|
108
|
-
|
109
|
-
|
116
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
117
|
+
migrate_up("change_column :adverts, :title, :text").and(
|
118
|
+
migrate_down("change_column :adverts, :title, :string, limit: 255")
|
119
|
+
)
|
120
|
+
)
|
110
121
|
|
111
122
|
class Advert < ActiveRecord::Base
|
112
123
|
fields do
|
@@ -115,11 +126,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
115
126
|
end
|
116
127
|
end
|
117
128
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
129
|
+
expect(migrate).to(
|
130
|
+
migrate_up(<<~EOS.strip)
|
131
|
+
change_column :adverts, :title, :string, limit: 255, default: "Untitled"
|
132
|
+
EOS
|
133
|
+
.and migrate_down(<<~EOS.strip)
|
134
|
+
change_column :adverts, :title, :string, limit: 255
|
135
|
+
EOS
|
136
|
+
)
|
123
137
|
|
124
138
|
### Limits
|
125
139
|
|
@@ -129,8 +143,9 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
129
143
|
end
|
130
144
|
end
|
131
145
|
|
132
|
-
up,
|
133
|
-
|
146
|
+
up, _ = Generators::DeclareSchema::Migration::Migrator.run.tap do |migrations|
|
147
|
+
expect(migrations).to migrate_up("add_column :adverts, :price, :integer, limit: 2")
|
148
|
+
end
|
134
149
|
|
135
150
|
# Now run the migration, then change the limit:
|
136
151
|
|
@@ -141,9 +156,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
141
156
|
end
|
142
157
|
end
|
143
158
|
|
144
|
-
|
145
|
-
|
146
|
-
|
159
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
160
|
+
migrate_up(<<~EOS.strip)
|
161
|
+
change_column :adverts, :price, :integer, limit: 3
|
162
|
+
EOS
|
163
|
+
.and migrate_down(<<~EOS.strip)
|
164
|
+
change_column :adverts, :price, :integer, limit: 2
|
165
|
+
EOS
|
166
|
+
)
|
147
167
|
|
148
168
|
# Note that limit on a decimal column is ignored (use :scale and :precision)
|
149
169
|
|
@@ -154,8 +174,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
154
174
|
end
|
155
175
|
end
|
156
176
|
|
157
|
-
|
158
|
-
expect(up).to eq("add_column :adverts, :price, :decimal")
|
177
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to migrate_up("add_column :adverts, :price, :decimal")
|
159
178
|
|
160
179
|
# Limits are generally not needed for `text` fields, because by default, `text` fields will use the maximum size
|
161
180
|
# allowed for that database type (0xffffffff for LONGTEXT in MySQL unlimited in Postgres, 1 billion in Sqlite).
|
@@ -170,12 +189,13 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
170
189
|
end
|
171
190
|
end
|
172
191
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
192
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
193
|
+
migrate_up(<<~EOS.strip)
|
194
|
+
add_column :adverts, :price, :decimal
|
195
|
+
add_column :adverts, :notes, :text, null: false
|
196
|
+
add_column :adverts, :description, :text, null: false
|
197
|
+
EOS
|
198
|
+
)
|
179
199
|
|
180
200
|
# (There is no limit on `add_column ... :description` above since these tests are run against SQLite.)
|
181
201
|
|
@@ -194,11 +214,12 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
194
214
|
end
|
195
215
|
end
|
196
216
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
217
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
218
|
+
migrate_up(<<~EOS.strip)
|
219
|
+
add_column :adverts, :notes, :text, null: false, limit: 4294967295
|
220
|
+
add_column :adverts, :description, :text, null: false, limit: 255
|
221
|
+
EOS
|
222
|
+
)
|
202
223
|
|
203
224
|
Advert.field_specs.delete :notes
|
204
225
|
|
@@ -237,9 +258,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
237
258
|
end
|
238
259
|
end
|
239
260
|
|
240
|
-
|
241
|
-
|
242
|
-
|
261
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
262
|
+
migrate_up(<<~EOS.strip)
|
263
|
+
change_column :adverts, :description, :text, limit: 4294967295, null: false
|
264
|
+
EOS
|
265
|
+
.and migrate_down(<<~EOS.strip)
|
266
|
+
change_column :adverts, :description, :text
|
267
|
+
EOS
|
268
|
+
)
|
243
269
|
|
244
270
|
# TODO TECH-4814: The above test should have this output:
|
245
271
|
# TODO => "change_column :adverts, :description, :text, limit: 255
|
@@ -252,9 +278,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
252
278
|
end
|
253
279
|
end
|
254
280
|
|
255
|
-
|
256
|
-
|
257
|
-
|
281
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
282
|
+
migrate_up(<<~EOS.strip)
|
283
|
+
change_column :adverts, :description, :text, limit: 4294967295, null: false
|
284
|
+
EOS
|
285
|
+
.and migrate_down(<<~EOS.strip)
|
286
|
+
change_column :adverts, :description, :text
|
287
|
+
EOS
|
288
|
+
)
|
258
289
|
::DeclareSchema::Model::FieldSpec::instance_variable_set(:@mysql_text_limits, false)
|
259
290
|
|
260
291
|
Advert.field_specs.clear
|
@@ -266,7 +297,7 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
266
297
|
end
|
267
298
|
end
|
268
299
|
|
269
|
-
up
|
300
|
+
up = Generators::DeclareSchema::Migration::Migrator.run.first
|
270
301
|
ActiveRecord::Migration.class_eval up
|
271
302
|
Advert.connection.schema_cache.clear!
|
272
303
|
Advert.reset_column_information
|
@@ -278,33 +309,43 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
278
309
|
|
279
310
|
class Category < ActiveRecord::Base; end
|
280
311
|
class Advert < ActiveRecord::Base
|
312
|
+
fields do
|
313
|
+
name :string, limit: 255, null: true
|
314
|
+
end
|
281
315
|
belongs_to :category
|
282
316
|
end
|
283
317
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
318
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
319
|
+
migrate_up(<<~EOS.strip)
|
320
|
+
add_column :adverts, :category_id, :integer, limit: 8, null: false
|
321
|
+
|
322
|
+
add_index :adverts, [:category_id], name: 'on_category_id'
|
323
|
+
EOS
|
324
|
+
.and migrate_down(<<~EOS.strip)
|
325
|
+
remove_column :adverts, :category_id
|
326
|
+
|
327
|
+
remove_index :adverts, name: :on_category_id rescue ActiveRecord::StatementInvalid
|
328
|
+
EOS
|
329
|
+
)
|
293
330
|
|
294
331
|
Advert.field_specs.delete(:category_id)
|
295
|
-
Advert.index_specs.delete_if {|spec| spec.fields==["category_id"]}
|
332
|
+
Advert.index_specs.delete_if { |spec| spec.fields==["category_id"] }
|
296
333
|
|
297
334
|
# If you specify a custom foreign key, the migration generator observes that:
|
298
335
|
|
299
336
|
class Category < ActiveRecord::Base; end
|
300
337
|
class Advert < ActiveRecord::Base
|
338
|
+
fields { }
|
301
339
|
belongs_to :category, foreign_key: "c_id", class_name: 'Category'
|
302
340
|
end
|
303
|
-
|
304
|
-
expect(
|
305
|
-
|
306
|
-
|
307
|
-
|
341
|
+
|
342
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
343
|
+
migrate_up(<<~EOS.strip)
|
344
|
+
add_column :adverts, :c_id, :integer, limit: 8, null: false
|
345
|
+
|
346
|
+
add_index :adverts, [:c_id], name: 'on_c_id'
|
347
|
+
EOS
|
348
|
+
)
|
308
349
|
|
309
350
|
Advert.field_specs.delete(:c_id)
|
310
351
|
Advert.index_specs.delete_if { |spec| spec.fields == ["c_id"] }
|
@@ -313,10 +354,15 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
313
354
|
|
314
355
|
class Category < ActiveRecord::Base; end
|
315
356
|
class Advert < ActiveRecord::Base
|
357
|
+
fields { }
|
316
358
|
belongs_to :category, index: false
|
317
359
|
end
|
318
|
-
|
319
|
-
expect(
|
360
|
+
|
361
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
362
|
+
migrate_up(<<~EOS.strip)
|
363
|
+
add_column :adverts, :category_id, :integer, limit: 8, null: false
|
364
|
+
EOS
|
365
|
+
)
|
320
366
|
|
321
367
|
Advert.field_specs.delete(:category_id)
|
322
368
|
Advert.index_specs.delete_if { |spec| spec.fields == ["category_id"] }
|
@@ -325,13 +371,17 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
325
371
|
|
326
372
|
class Category < ActiveRecord::Base; end
|
327
373
|
class Advert < ActiveRecord::Base
|
374
|
+
fields { }
|
328
375
|
belongs_to :category, index: 'my_index'
|
329
376
|
end
|
330
|
-
|
331
|
-
expect(
|
332
|
-
|
333
|
-
|
334
|
-
|
377
|
+
|
378
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
379
|
+
migrate_up(<<~EOS.strip)
|
380
|
+
add_column :adverts, :category_id, :integer, limit: 8, null: false
|
381
|
+
|
382
|
+
add_index :adverts, [:category_id], name: 'my_index'
|
383
|
+
EOS
|
384
|
+
)
|
335
385
|
|
336
386
|
Advert.field_specs.delete(:category_id)
|
337
387
|
Advert.index_specs.delete_if { |spec| spec.fields == ["category_id"] }
|
@@ -347,17 +397,19 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
347
397
|
optimistic_lock
|
348
398
|
end
|
349
399
|
end
|
350
|
-
|
351
|
-
expect(
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
400
|
+
|
401
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
402
|
+
migrate_up(<<~EOS.strip)
|
403
|
+
add_column :adverts, :created_at, :datetime
|
404
|
+
add_column :adverts, :updated_at, :datetime
|
405
|
+
add_column :adverts, :lock_version, :integer, null: false, default: 1
|
406
|
+
EOS
|
407
|
+
.and migrate_down(<<~EOS.strip)
|
408
|
+
remove_column :adverts, :created_at
|
409
|
+
remove_column :adverts, :updated_at
|
410
|
+
remove_column :adverts, :lock_version
|
411
|
+
EOS
|
412
|
+
)
|
361
413
|
|
362
414
|
Advert.field_specs.delete(:updated_at)
|
363
415
|
Advert.field_specs.delete(:created_at)
|
@@ -372,11 +424,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
372
424
|
title :string, index: true, limit: 255, null: true
|
373
425
|
end
|
374
426
|
end
|
375
|
-
|
376
|
-
expect(
|
377
|
-
|
378
|
-
|
379
|
-
|
427
|
+
|
428
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
429
|
+
migrate_up(<<~EOS.strip)
|
430
|
+
add_column :adverts, :title, :string, limit: 255
|
431
|
+
|
432
|
+
add_index :adverts, [:title], name: 'on_title'
|
433
|
+
EOS
|
434
|
+
)
|
380
435
|
|
381
436
|
Advert.index_specs.delete_if { |spec| spec.fields==["title"] }
|
382
437
|
|
@@ -387,11 +442,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
387
442
|
title :string, index: true, unique: true, null: true, limit: 255
|
388
443
|
end
|
389
444
|
end
|
390
|
-
|
391
|
-
expect(
|
392
|
-
|
393
|
-
|
394
|
-
|
445
|
+
|
446
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
447
|
+
migrate_up(<<~EOS.strip)
|
448
|
+
add_column :adverts, :title, :string, limit: 255
|
449
|
+
|
450
|
+
add_index :adverts, [:title], unique: true, name: 'on_title'
|
451
|
+
EOS
|
452
|
+
)
|
395
453
|
|
396
454
|
Advert.index_specs.delete_if { |spec| spec.fields == ["title"] }
|
397
455
|
|
@@ -402,24 +460,30 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
402
460
|
title :string, index: 'my_index', limit: 255, null: true
|
403
461
|
end
|
404
462
|
end
|
405
|
-
up, down = Generators::DeclareSchema::Migration::Migrator.run
|
406
|
-
expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
|
407
|
-
add_column :adverts, :title, :string, limit: 255
|
408
|
-
add_index :adverts, [:title], name: 'my_index'
|
409
|
-
EOS
|
410
463
|
|
411
|
-
|
464
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
465
|
+
migrate_up(<<~EOS.strip)
|
466
|
+
add_column :adverts, :title, :string, limit: 255
|
467
|
+
|
468
|
+
add_index :adverts, [:title], name: 'my_index'
|
469
|
+
EOS
|
470
|
+
)
|
471
|
+
|
472
|
+
Advert.index_specs.delete_if { |spec| spec.fields==["title"] }
|
412
473
|
|
413
474
|
# You can ask for an index outside of the fields block
|
414
475
|
|
415
476
|
class Advert < ActiveRecord::Base
|
416
477
|
index :title
|
417
478
|
end
|
418
|
-
|
419
|
-
expect(
|
420
|
-
|
421
|
-
|
422
|
-
|
479
|
+
|
480
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
481
|
+
migrate_up(<<~EOS.strip)
|
482
|
+
add_column :adverts, :title, :string, limit: 255
|
483
|
+
|
484
|
+
add_index :adverts, [:title], name: 'on_title'
|
485
|
+
EOS
|
486
|
+
)
|
423
487
|
|
424
488
|
Advert.index_specs.delete_if { |spec| spec.fields == ["title"] }
|
425
489
|
|
@@ -428,11 +492,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
428
492
|
class Advert < ActiveRecord::Base
|
429
493
|
index :title, unique: true, name: 'my_index'
|
430
494
|
end
|
431
|
-
|
432
|
-
expect(
|
433
|
-
|
434
|
-
|
435
|
-
|
495
|
+
|
496
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
497
|
+
migrate_up(<<~EOS.strip)
|
498
|
+
add_column :adverts, :title, :string, limit: 255
|
499
|
+
|
500
|
+
add_index :adverts, [:title], unique: true, name: 'my_index'
|
501
|
+
EOS
|
502
|
+
)
|
436
503
|
|
437
504
|
Advert.index_specs.delete_if { |spec| spec.fields == ["title"] }
|
438
505
|
|
@@ -441,11 +508,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
441
508
|
class Advert < ActiveRecord::Base
|
442
509
|
index [:title, :category_id]
|
443
510
|
end
|
444
|
-
|
445
|
-
expect(
|
446
|
-
|
447
|
-
|
448
|
-
|
511
|
+
|
512
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
513
|
+
migrate_up(<<~EOS.strip)
|
514
|
+
add_column :adverts, :title, :string, limit: 255
|
515
|
+
|
516
|
+
add_index :adverts, [:title, :category_id], name: 'on_title_and_category_id'
|
517
|
+
EOS
|
518
|
+
)
|
449
519
|
|
450
520
|
Advert.index_specs.delete_if { |spec| spec.fields==["title", "category_id"] }
|
451
521
|
|
@@ -468,19 +538,24 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
468
538
|
Advert.connection.schema_cache.clear!
|
469
539
|
Advert.reset_column_information
|
470
540
|
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
541
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run("adverts" => "ads")).to(
|
542
|
+
migrate_up(<<~EOS.strip)
|
543
|
+
rename_table :adverts, :ads
|
544
|
+
|
545
|
+
add_column :ads, :title, :string, limit: 255
|
546
|
+
add_column :ads, :body, :text
|
547
|
+
|
548
|
+
add_index :ads, [:id], unique: true, name: 'PRIMARY_KEY'
|
549
|
+
EOS
|
550
|
+
.and migrate_down(<<~EOS.strip)
|
551
|
+
remove_column :ads, :title
|
552
|
+
remove_column :ads, :body
|
553
|
+
|
554
|
+
rename_table :ads, :adverts
|
555
|
+
|
556
|
+
add_index :adverts, [:id], unique: true, name: 'PRIMARY_KEY'
|
557
|
+
EOS
|
558
|
+
)
|
484
559
|
|
485
560
|
# Set the table name back to what it should be and confirm we're in sync:
|
486
561
|
|
@@ -504,21 +579,27 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
504
579
|
body :text, null: true
|
505
580
|
end
|
506
581
|
end
|
507
|
-
|
508
|
-
expect(
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
582
|
+
|
583
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run("adverts" => "advertisements")).to(
|
584
|
+
migrate_up(<<~EOS.strip)
|
585
|
+
rename_table :adverts, :advertisements
|
586
|
+
|
587
|
+
add_column :advertisements, :title, :string, limit: 255
|
588
|
+
add_column :advertisements, :body, :text
|
589
|
+
remove_column :advertisements, :name
|
590
|
+
|
591
|
+
add_index :advertisements, [:id], unique: true, name: 'PRIMARY_KEY'
|
592
|
+
EOS
|
593
|
+
.and migrate_down(<<~EOS.strip)
|
594
|
+
remove_column :advertisements, :title
|
595
|
+
remove_column :advertisements, :body
|
596
|
+
add_column :adverts, :name, :string, limit: 255
|
597
|
+
|
598
|
+
rename_table :advertisements, :adverts
|
599
|
+
|
600
|
+
add_index :adverts, [:id], unique: true, name: 'PRIMARY_KEY'
|
601
|
+
EOS
|
602
|
+
)
|
522
603
|
|
523
604
|
### Drop a table
|
524
605
|
|
@@ -528,9 +609,28 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
528
609
|
|
529
610
|
# Dropping tables is where the automatic down-migration really comes in handy:
|
530
611
|
|
531
|
-
|
532
|
-
|
533
|
-
|
612
|
+
rails4_table_create = <<~EOS.strip
|
613
|
+
create_table "adverts", id: false, force: :cascade do |t|
|
614
|
+
t.integer "id", limit: 8
|
615
|
+
t.string "name", limit: 255
|
616
|
+
end
|
617
|
+
|
618
|
+
add_index "adverts", ["id"], name: "PRIMARY_KEY", unique: true
|
619
|
+
EOS
|
620
|
+
|
621
|
+
rails5_table_create = <<~EOS.strip
|
622
|
+
create_table "adverts", id: :integer, force: :cascade do |t|
|
623
|
+
t.string "name", limit: 255
|
624
|
+
t.index ["id"], name: "PRIMARY_KEY", unique: true
|
625
|
+
end
|
626
|
+
EOS
|
627
|
+
|
628
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run).to(
|
629
|
+
migrate_up(<<~EOS.strip)
|
630
|
+
drop_table :adverts
|
631
|
+
EOS
|
632
|
+
.and migrate_down(Rails::VERSION::MAJOR >= 5 ? rails5_table_create : rails4_table_create)
|
633
|
+
)
|
534
634
|
|
535
635
|
## STI
|
536
636
|
|
@@ -544,22 +644,28 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
544
644
|
title :string, default: "Untitled", limit: 255, null: true
|
545
645
|
end
|
546
646
|
end
|
547
|
-
up
|
647
|
+
up = Generators::DeclareSchema::Migration::Migrator.run.first
|
548
648
|
ActiveRecord::Migration.class_eval(up)
|
549
649
|
|
550
650
|
class FancyAdvert < Advert
|
551
651
|
end
|
552
652
|
class SuperFancyAdvert < FancyAdvert
|
553
653
|
end
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
654
|
+
|
655
|
+
up, _ = Generators::DeclareSchema::Migration::Migrator.run do |migrations|
|
656
|
+
expect(migrations).to(
|
657
|
+
migrate_up(<<~EOS.strip)
|
658
|
+
add_column :adverts, :type, :string, limit: 255
|
659
|
+
|
660
|
+
add_index :adverts, [:type], name: 'on_type'
|
661
|
+
EOS
|
662
|
+
.and migrate_down(<<~EOS.strip)
|
663
|
+
remove_column :adverts, :type
|
664
|
+
|
665
|
+
remove_index :adverts, name: :on_type rescue ActiveRecord::StatementInvalid
|
666
|
+
EOS
|
667
|
+
)
|
668
|
+
end
|
563
669
|
|
564
670
|
Advert.field_specs.delete(:type)
|
565
671
|
nuke_model_class(SuperFancyAdvert)
|
@@ -592,16 +698,17 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
592
698
|
body :text, null: true
|
593
699
|
end
|
594
700
|
end
|
595
|
-
up, down = Generators::DeclareSchema::Migration::Migrator.run(adverts: { title: :name })
|
596
|
-
expect(up).to eq(<<~EOS.strip)
|
597
|
-
rename_column :adverts, :title, :name
|
598
|
-
change_column :adverts, :name, :string, limit: 255, default: \"No Name\"
|
599
|
-
EOS
|
600
701
|
|
601
|
-
expect(
|
602
|
-
|
603
|
-
|
604
|
-
|
702
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { title: :name })).to(
|
703
|
+
migrate_up(<<~EOS.strip)
|
704
|
+
rename_column :adverts, :title, :name
|
705
|
+
change_column :adverts, :name, :string, limit: 255, default: "No Name"
|
706
|
+
EOS
|
707
|
+
.and migrate_down(<<~EOS.strip)
|
708
|
+
rename_column :adverts, :name, :title
|
709
|
+
change_column :adverts, :title, :string, limit: 255, default: "Untitled"
|
710
|
+
EOS
|
711
|
+
)
|
605
712
|
|
606
713
|
### Rename a table and add a column
|
607
714
|
|
@@ -613,13 +720,17 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
613
720
|
created_at :datetime
|
614
721
|
end
|
615
722
|
end
|
616
|
-
|
617
|
-
expect(
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
723
|
+
|
724
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: :ads)).to(
|
725
|
+
migrate_up(<<~EOS.strip)
|
726
|
+
rename_table :adverts, :ads
|
727
|
+
|
728
|
+
add_column :ads, :created_at, :datetime, null: false
|
729
|
+
change_column :ads, :title, :string, limit: 255, null: false, default: \"Untitled\"
|
730
|
+
|
731
|
+
add_index :ads, [:id], unique: true, name: 'PRIMARY_KEY'
|
732
|
+
EOS
|
733
|
+
)
|
623
734
|
|
624
735
|
class Advert < ActiveRecord::Base
|
625
736
|
fields do
|
@@ -640,11 +751,14 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
640
751
|
end
|
641
752
|
self.primary_key = "advert_id"
|
642
753
|
end
|
643
|
-
|
644
|
-
expect(
|
645
|
-
|
646
|
-
|
647
|
-
|
754
|
+
|
755
|
+
expect(Generators::DeclareSchema::Migration::Migrator.run(adverts: { id: :advert_id })).to(
|
756
|
+
migrate_up(<<~EOS.strip)
|
757
|
+
rename_column :adverts, :id, :advert_id
|
758
|
+
|
759
|
+
add_index :adverts, [:advert_id], unique: true, name: 'PRIMARY_KEY'
|
760
|
+
EOS
|
761
|
+
)
|
648
762
|
|
649
763
|
nuke_model_class(Advert)
|
650
764
|
ActiveRecord::Base.connection.execute("drop table `adverts`;")
|
@@ -682,5 +796,115 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
682
796
|
ActiveRecord::Migration.class_eval(up)
|
683
797
|
expect(Ad.field_specs['company'].options[:validates].inspect).to eq("{:presence=>true, :uniqueness=>{:case_sensitive=>false}}")
|
684
798
|
end
|
685
|
-
end
|
686
799
|
|
800
|
+
context "for Rails #{Rails::VERSION::MAJOR}" do
|
801
|
+
if Rails::VERSION::MAJOR >= 5
|
802
|
+
let(:optional_true) { { optional: true } }
|
803
|
+
let(:optional_false) { { optional: false } }
|
804
|
+
else
|
805
|
+
let(:optional_true) { {} }
|
806
|
+
let(:optional_false) { {} }
|
807
|
+
end
|
808
|
+
let(:optional_flag) { { false => optional_false, true => optional_true } }
|
809
|
+
|
810
|
+
describe 'belongs_to' do
|
811
|
+
before do
|
812
|
+
unless defined?(AdCategory)
|
813
|
+
class AdCategory < ActiveRecord::Base
|
814
|
+
fields { }
|
815
|
+
end
|
816
|
+
end
|
817
|
+
|
818
|
+
class Advert < ActiveRecord::Base
|
819
|
+
fields do
|
820
|
+
name :string, limit: 255, null: true
|
821
|
+
category_id :integer, limit: 8
|
822
|
+
nullable_category_id :integer, limit: 8, null: true
|
823
|
+
end
|
824
|
+
end
|
825
|
+
up = Generators::DeclareSchema::Migration::Migrator.run.first
|
826
|
+
ActiveRecord::Migration.class_eval(up)
|
827
|
+
end
|
828
|
+
|
829
|
+
it 'passes through optional: when given' do
|
830
|
+
class AdvertBelongsTo < ActiveRecord::Base
|
831
|
+
self.table_name = 'adverts'
|
832
|
+
fields { }
|
833
|
+
reset_column_information
|
834
|
+
belongs_to :ad_category, optional: true
|
835
|
+
end
|
836
|
+
expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_true)
|
837
|
+
end
|
838
|
+
|
839
|
+
describe 'contradictory settings' do # contradictory settings are ok--for example, during migration
|
840
|
+
it 'passes through optional: true, null: false' do
|
841
|
+
class AdvertBelongsTo < ActiveRecord::Base
|
842
|
+
self.table_name = 'adverts'
|
843
|
+
fields { }
|
844
|
+
reset_column_information
|
845
|
+
belongs_to :ad_category, optional: true, null: false
|
846
|
+
end
|
847
|
+
expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_true)
|
848
|
+
expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(false)
|
849
|
+
end
|
850
|
+
|
851
|
+
it 'passes through optional: false, null: true' do
|
852
|
+
class AdvertBelongsTo < ActiveRecord::Base
|
853
|
+
self.table_name = 'adverts'
|
854
|
+
fields { }
|
855
|
+
reset_column_information
|
856
|
+
belongs_to :ad_category, optional: false, null: true
|
857
|
+
end
|
858
|
+
expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_false)
|
859
|
+
expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(true)
|
860
|
+
end
|
861
|
+
end
|
862
|
+
|
863
|
+
[false, true].each do |nullable|
|
864
|
+
context "nullable=#{nullable}" do
|
865
|
+
it 'infers optional: from null:' do
|
866
|
+
eval <<~EOS
|
867
|
+
class AdvertBelongsTo < ActiveRecord::Base
|
868
|
+
fields { }
|
869
|
+
belongs_to :ad_category, null: #{nullable}
|
870
|
+
end
|
871
|
+
EOS
|
872
|
+
expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_flag[nullable])
|
873
|
+
expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(nullable)
|
874
|
+
end
|
875
|
+
|
876
|
+
it 'infers null: from optional:' do
|
877
|
+
eval <<~EOS
|
878
|
+
class AdvertBelongsTo < ActiveRecord::Base
|
879
|
+
fields { }
|
880
|
+
belongs_to :ad_category, optional: #{nullable}
|
881
|
+
end
|
882
|
+
EOS
|
883
|
+
expect(AdvertBelongsTo.reflections['ad_category'].options).to eq(optional_flag[nullable])
|
884
|
+
expect(AdvertBelongsTo.field_specs['ad_category_id'].options&.[](:null)).to eq(nullable)
|
885
|
+
end
|
886
|
+
end
|
887
|
+
end
|
888
|
+
end
|
889
|
+
end
|
890
|
+
|
891
|
+
describe 'migration base class' do
|
892
|
+
it 'adapts to Rails 4' do
|
893
|
+
class Advert < active_record_base_class.constantize
|
894
|
+
fields do
|
895
|
+
title :string, limit: 100
|
896
|
+
end
|
897
|
+
end
|
898
|
+
|
899
|
+
generate_migrations '-n', '-m'
|
900
|
+
|
901
|
+
migrations = Dir.glob('db/migrate/*declare_schema_migration*.rb')
|
902
|
+
expect(migrations.size).to eq(1), migrations.inspect
|
903
|
+
|
904
|
+
migration_content = File.read(migrations.first)
|
905
|
+
first_line = migration_content.split("\n").first
|
906
|
+
base_class = first_line.split(' < ').last
|
907
|
+
expect(base_class).to eq("(Rails::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)")
|
908
|
+
end
|
909
|
+
end
|
910
|
+
end
|