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.
@@ -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