declare_schema 0.2.0.pre.1 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- Rails::Generators.invoke('declare_schema:migration', %w[-n -m])
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
- Rails::Generators.invoke('declare_schema:migration', %w[-n -m])
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
- Rails::Generators.invoke('declare_schema:migration', %w[-n -m])
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
- up_down = Generators::DeclareSchema::Migration::Migrator.run
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
- up_down = Generators::DeclareSchema::Migration::Migrator.run
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
32
- expect(up).to eq(<<~EOS.strip)
33
- create_table :adverts, id: :bigint do |t|
34
- t.string :name, limit: 255
35
- end
36
- EOS
37
- expect(down).to eq("drop_table :adverts")
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
- add_index :adverts, [:id], unique: true, name: 'PRIMARY_KEY'
55
- EOS
56
- # TODO: ^ add_index should not be there?
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
- expect(down).to eq(<<~EOS.strip)
59
- remove_column :adverts, :body
60
- remove_column :adverts, :published_at
61
- EOS
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
- up, down = migrate
72
- expect(up).to eq("remove_column :adverts, :published_at")
73
- expect(down).to eq("add_column :adverts, :published_at, :datetime")
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
84
- expect(up).to eq(<<~EOS.strip)
85
- add_column :adverts, :title, :string, limit: 255
86
- remove_column :adverts, :name
87
- EOS
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(down).to eq(<<~EOS.strip)
90
- remove_column :adverts, :title
91
- add_column :adverts, :name, :string, limit: 255
92
- EOS
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
- up_down = Generators::DeclareSchema::Migration::Migrator.run
108
- expect(up_down).to eq(["change_column :adverts, :title, :text",
109
- "change_column :adverts, :title, :string, limit: 255"])
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
- up, down = migrate
119
- expect(up.split(',').slice(0,3).join(',')).to eq('change_column :adverts, :title, :string')
120
- expect(up.split(',').slice(3,2).sort.join(',')).to eq(" default: \"Untitled\", limit: 255")
121
- expect(down).to eq("change_column :adverts, :title, :string, limit: 255")
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, down = Generators::DeclareSchema::Migration::Migrator.run
133
- expect(up).to eq("add_column :adverts, :price, :integer, limit: 2")
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
145
- expect(up).to eq("change_column :adverts, :price, :integer, limit: 3")
146
- expect(down).to eq("change_column :adverts, :price, :integer, limit: 2")
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
174
- expect(up).to eq(<<~EOS.strip)
175
- add_column :adverts, :price, :decimal
176
- add_column :adverts, :notes, :text, null: false
177
- add_column :adverts, :description, :text, null: false
178
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
198
- expect(up).to eq(<<~EOS.strip)
199
- add_column :adverts, :notes, :text, null: false
200
- add_column :adverts, :description, :text, null: false, limit: 255
201
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
241
- expect(up).to eq("change_column :adverts, :description, :text, null: false")
242
- expect(down).to eq("change_column :adverts, :description, :text")
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
256
- expect(up).to eq("change_column :adverts, :description, :text, null: false")
257
- expect(down).to eq("change_column :adverts, :description, :text")
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, down = Generators::DeclareSchema::Migration::Migrator.run
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
285
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
286
- add_column :adverts, :category_id, :integer, limit: 8, null: false
287
- add_index :adverts, [:category_id], name: 'on_category_id'
288
- EOS
289
- expect(down.sub(/\n+/, "\n")).to eq(<<~EOS.strip)
290
- remove_column :adverts, :category_id
291
- remove_index :adverts, name: :on_category_id rescue ActiveRecord::StatementInvalid
292
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
304
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
305
- add_column :adverts, :c_id, :integer, limit: 8, null: false
306
- add_index :adverts, [:c_id], name: 'on_c_id'
307
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
319
- expect(up.gsub(/\n+/, "\n")).to eq("add_column :adverts, :category_id, :integer, limit: 8, null: false")
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
331
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
332
- add_column :adverts, :category_id, :integer, limit: 8, null: false
333
- add_index :adverts, [:category_id], name: 'my_index'
334
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
351
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
352
- add_column :adverts, :created_at, :datetime
353
- add_column :adverts, :updated_at, :datetime
354
- add_column :adverts, :lock_version, :integer, null: false, default: 1
355
- EOS
356
- expect(down.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
357
- remove_column :adverts, :created_at
358
- remove_column :adverts, :updated_at
359
- remove_column :adverts, :lock_version
360
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
376
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
377
- add_column :adverts, :title, :string, limit: 255
378
- add_index :adverts, [:title], name: 'on_title'
379
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
391
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
392
- add_column :adverts, :title, :string, limit: 255
393
- add_index :adverts, [:title], unique: true, name: 'on_title'
394
- EOS
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
- Advert.index_specs.delete_if {|spec| spec.fields==["title"]}
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
419
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
420
- add_column :adverts, :title, :string, limit: 255
421
- add_index :adverts, [:title], name: 'on_title'
422
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
432
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
433
- add_column :adverts, :title, :string, limit: 255
434
- add_index :adverts, [:title], unique: true, name: 'my_index'
435
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
445
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
446
- add_column :adverts, :title, :string, limit: 255
447
- add_index :adverts, [:title, :category_id], name: 'on_title_and_category_id'
448
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run("adverts" => "ads")
472
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
473
- rename_table :adverts, :ads
474
- add_column :ads, :title, :string, limit: 255
475
- add_column :ads, :body, :text
476
- add_index :ads, [:id], unique: true, name: 'PRIMARY_KEY'
477
- EOS
478
- expect(down.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
479
- remove_column :ads, :title
480
- remove_column :ads, :body
481
- rename_table :ads, :adverts
482
- add_index :adverts, [:id], unique: true, name: 'PRIMARY_KEY'
483
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run("adverts" => "advertisements")
508
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
509
- rename_table :adverts, :advertisements
510
- add_column :advertisements, :title, :string, limit: 255
511
- add_column :advertisements, :body, :text
512
- remove_column :advertisements, :name
513
- add_index :advertisements, [:id], unique: true, name: 'PRIMARY_KEY'
514
- EOS
515
- expect(down.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
516
- remove_column :advertisements, :title
517
- remove_column :advertisements, :body
518
- add_column :adverts, :name, :string, limit: 255
519
- rename_table :advertisements, :adverts
520
- add_index :adverts, [:id], unique: true, name: 'PRIMARY_KEY'
521
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
532
- expect(up).to eq("drop_table :adverts")
533
- expect(down.gsub(/,.*/m, '')).to eq("create_table \"adverts\"")
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, down = Generators::DeclareSchema::Migration::Migrator.run
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run
555
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
556
- add_column :adverts, :type, :string, limit: 255
557
- add_index :adverts, [:type], name: 'on_type'
558
- EOS
559
- expect(down.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
560
- remove_column :adverts, :type
561
- remove_index :adverts, name: :on_type rescue ActiveRecord::StatementInvalid
562
- EOS
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(down).to eq(<<~EOS.strip)
602
- rename_column :adverts, :name, :title
603
- change_column :adverts, :title, :string, limit: 255, default: \"Untitled\"
604
- EOS
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
- up, down = Generators::DeclareSchema::Migration::Migrator.run(adverts: :ads)
617
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
618
- rename_table :adverts, :ads
619
- add_column :ads, :created_at, :datetime, null: false
620
- change_column :ads, :title, :string, limit: 255, null: false, default: \"Untitled\"
621
- add_index :ads, [:id], unique: true, name: 'PRIMARY_KEY'
622
- EOS
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
- up, _down = Generators::DeclareSchema::Migration::Migrator.run(adverts: { id: :advert_id })
644
- expect(up.gsub(/\n+/, "\n")).to eq(<<~EOS.strip)
645
- rename_column :adverts, :id, :advert_id
646
- add_index :adverts, [:advert_id], unique: true, name: 'PRIMARY_KEY'
647
- EOS
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