declare_schema 0.10.0 → 0.10.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/Gemfile.lock +1 -1
  4. data/lib/declare_schema/model/foreign_key_definition.rb +4 -8
  5. data/lib/declare_schema/model/index_definition.rb +0 -19
  6. data/lib/declare_schema/schema_change/all.rb +22 -0
  7. data/lib/declare_schema/schema_change/base.rb +45 -0
  8. data/lib/declare_schema/schema_change/column_add.rb +27 -0
  9. data/lib/declare_schema/schema_change/column_change.rb +32 -0
  10. data/lib/declare_schema/schema_change/column_remove.rb +20 -0
  11. data/lib/declare_schema/schema_change/column_rename.rb +23 -0
  12. data/lib/declare_schema/schema_change/foreign_key_add.rb +25 -0
  13. data/lib/declare_schema/schema_change/foreign_key_remove.rb +20 -0
  14. data/lib/declare_schema/schema_change/index_add.rb +33 -0
  15. data/lib/declare_schema/schema_change/index_remove.rb +20 -0
  16. data/lib/declare_schema/schema_change/primary_key_change.rb +33 -0
  17. data/lib/declare_schema/schema_change/table_add.rb +37 -0
  18. data/lib/declare_schema/schema_change/table_change.rb +36 -0
  19. data/lib/declare_schema/schema_change/table_remove.rb +22 -0
  20. data/lib/declare_schema/schema_change/table_rename.rb +22 -0
  21. data/lib/declare_schema/version.rb +1 -1
  22. data/lib/generators/declare_schema/migration/migrator.rb +172 -174
  23. data/spec/lib/declare_schema/interactive_primary_key_spec.rb +52 -14
  24. data/spec/lib/declare_schema/migration_generator_spec.rb +175 -303
  25. data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +0 -12
  26. data/spec/lib/declare_schema/schema_change/base_spec.rb +75 -0
  27. data/spec/lib/declare_schema/schema_change/column_add_spec.rb +30 -0
  28. data/spec/lib/declare_schema/schema_change/column_change_spec.rb +33 -0
  29. data/spec/lib/declare_schema/schema_change/column_remove_spec.rb +30 -0
  30. data/spec/lib/declare_schema/schema_change/column_rename_spec.rb +28 -0
  31. data/spec/lib/declare_schema/schema_change/foreign_key_add_spec.rb +29 -0
  32. data/spec/lib/declare_schema/schema_change/foreign_key_remove_spec.rb +29 -0
  33. data/spec/lib/declare_schema/schema_change/index_add_spec.rb +56 -0
  34. data/spec/lib/declare_schema/schema_change/index_remove_spec.rb +29 -0
  35. data/spec/lib/declare_schema/schema_change/primary_key_change_spec.rb +69 -0
  36. data/spec/lib/declare_schema/schema_change/table_add_spec.rb +50 -0
  37. data/spec/lib/declare_schema/schema_change/table_change_spec.rb +30 -0
  38. data/spec/lib/declare_schema/schema_change/table_remove_spec.rb +27 -0
  39. data/spec/lib/declare_schema/schema_change/table_rename_spec.rb +27 -0
  40. data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +59 -11
  41. data/spec/support/acceptance_spec_helpers.rb +2 -2
  42. metadata +34 -5
@@ -62,12 +62,6 @@ RSpec.describe DeclareSchema::Model::ForeignKeyDefinition do
62
62
  end
63
63
  end
64
64
  end
65
-
66
- describe '#to_add_statement' do
67
- it 'returns add_foreign_key command' do
68
- expect(subject.to_add_statement).to eq('add_foreign_key("models", "networks", column: "network_id", name: "on_network_id")')
69
- end
70
- end
71
65
  end
72
66
 
73
67
  describe 'class << self' do
@@ -149,12 +143,6 @@ RSpec.describe DeclareSchema::Model::ForeignKeyDefinition do
149
143
  end
150
144
  end
151
145
  end
152
-
153
- describe '#to_add_statement' do
154
- it 'returns add_foreign_key command' do
155
- expect(subject.to_add_statement).to eq('add_foreign_key("models", "networks", column: "network_id", name: "on_network_id")')
156
- end
157
- end
158
146
  end
159
147
 
160
148
  describe 'class << self' do
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/base'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::Base do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ before :all do
11
+ class ChangeDefault < described_class
12
+ attr_reader :up_command, :down_command
13
+
14
+ def initialize(up:, down:)
15
+ @up_command = up
16
+ @down_command = down
17
+ end
18
+ end
19
+
20
+ class ChangeOverride < described_class
21
+ attr_reader :up_command, :down_command
22
+
23
+ def initialize(up:, down:)
24
+ @up_command = up
25
+ @down_command = down
26
+ end
27
+ end
28
+ end
29
+
30
+ describe 'class methods' do
31
+ describe 'format_options' do
32
+ subject { { limit: 8, 'key' => 'value', subhash: { subkey: :subvalue } } }
33
+
34
+ it 'formats using Ruby 2.0 symbol notation' do
35
+ expect(described_class.format_options(subject)).to eq(['limit: 8', '"key" => "value"', 'subhash: { subkey: :subvalue }'])
36
+ end
37
+ end
38
+ end
39
+
40
+ describe 'instance methods' do
41
+ describe '#up/#down' do
42
+ context 'with single-line commands' do
43
+ subject { ChangeDefault.new(up: "up_command", down: "down_command" )}
44
+
45
+ describe '#up' do
46
+ it 'responds with command and single spacing' do
47
+ expect(subject.up).to eq("up_command\n")
48
+ end
49
+ end
50
+
51
+ describe '#down' do
52
+ it 'responds with command and single spacing' do
53
+ expect(subject.down).to eq("down_command\n")
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'with multi-line commands' do
59
+ subject { ChangeDefault.new(up: "up_command 1\nup_command 2", down: "down_command 1\ndown_command 2" )}
60
+
61
+ describe '#up' do
62
+ it 'responds with command and double spacing' do
63
+ expect(subject.up).to eq("up_command 1\nup_command 2\n\n")
64
+ end
65
+ end
66
+
67
+ describe '#down' do
68
+ it 'responds with command and spacing' do
69
+ expect(subject.down).to eq("down_command 1\ndown_command 2\n\n")
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/column_add'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::ColumnAdd do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'networks' }
11
+ let(:column_name) { 'title' }
12
+ let(:column_type) { :integer }
13
+ let(:column_options) { { limit: 8 } }
14
+ let(:column_options_string) { "limit: 8" }
15
+ subject { described_class.new(table_name, column_name, column_type, column_options) }
16
+
17
+ describe '#up/down' do
18
+ describe '#up' do
19
+ it 'responds with command' do
20
+ expect(subject.up).to eq("add_column :#{table_name}, :#{column_name}, :#{column_type}, #{column_options_string}\n")
21
+ end
22
+ end
23
+
24
+ describe '#down' do
25
+ it 'responds with command' do
26
+ expect(subject.down).to eq("remove_column :#{table_name}, :#{column_name}\n")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/column_change'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::ColumnChange do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'networks' }
11
+ let(:column_name) { 'title' }
12
+ let(:old_type) { :string }
13
+ let(:old_options) { { limit: 255, null: false } }
14
+ let(:old_options_string) { "limit: 255, null: false" }
15
+ let(:new_type) { :text }
16
+ let(:new_options) { { limit: 0xffff, null: true } }
17
+ let(:new_options_string) { "limit: 65535, null: true" }
18
+ subject { described_class.new(table_name, column_name, old_type: old_type, old_options: old_options, new_type: new_type, new_options: new_options) }
19
+
20
+ describe '#up/down' do
21
+ describe '#up' do
22
+ it 'responds with command' do
23
+ expect(subject.up).to eq("change_column :#{table_name}, :#{column_name}, :#{new_type}, #{new_options_string}\n")
24
+ end
25
+ end
26
+
27
+ describe '#down' do
28
+ it 'responds with command' do
29
+ expect(subject.down).to eq("change_column :#{table_name}, :#{column_name}, :#{old_type}, #{old_options_string}\n")
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/column_remove'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::ColumnRemove do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'networks' }
11
+ let(:column_name) { 'title' }
12
+ let(:column_type) { :integer }
13
+ let(:column_options) { { limit: 8 } }
14
+ let(:column_options_string) { "limit: 8" }
15
+ subject { described_class.new(table_name, column_name, column_type, column_options) }
16
+
17
+ describe '#up/down' do
18
+ describe '#up' do
19
+ it 'responds with command' do
20
+ expect(subject.up).to eq("remove_column :#{table_name}, :#{column_name}\n")
21
+ end
22
+ end
23
+
24
+ describe '#down' do
25
+ it 'responds with command' do
26
+ expect(subject.down).to eq("add_column :#{table_name}, :#{column_name}, :#{column_type}, #{column_options_string}\n")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/column_rename'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::ColumnRename do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'networks' }
11
+ let(:old_name) { 'title' }
12
+ let(:new_name) { 'summary' }
13
+ subject { described_class.new(table_name, old_name, new_name) }
14
+
15
+ describe '#up/down' do
16
+ describe '#up' do
17
+ it 'responds with command' do
18
+ expect(subject.up).to eq("rename_column :#{table_name}, :#{old_name}, :#{new_name}\n")
19
+ end
20
+ end
21
+
22
+ describe '#down' do
23
+ it 'responds with command' do
24
+ expect(subject.down).to eq("rename_column :#{table_name}, :#{new_name}, :#{old_name}\n")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/foreign_key_add'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::ForeignKeyAdd do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'users' }
11
+ let(:parent_table_name) { 'organization' }
12
+ let(:column_name) { :organization_id }
13
+ let(:name) { 'on_organization_id' }
14
+ subject { described_class.new(table_name, parent_table_name, column_name: column_name, name: name) }
15
+
16
+ describe '#up/down' do
17
+ describe '#up' do
18
+ it 'responds with command' do
19
+ expect(subject.up).to eq("add_foreign_key :#{table_name}, :#{parent_table_name}, column: #{column_name.to_sym.inspect}, name: #{name.to_sym.inspect}\n")
20
+ end
21
+ end
22
+
23
+ describe '#down' do
24
+ it 'responds with command' do
25
+ expect(subject.down).to eq("remove_foreign_key :#{table_name}, name: #{name.to_sym.inspect}\n")
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/foreign_key_remove'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::ForeignKeyRemove do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'users' }
11
+ let(:parent_table_name) { 'organization' }
12
+ let(:column_name) { :organization_id }
13
+ let(:name) { 'on_organization_id' }
14
+ subject { described_class.new(table_name, parent_table_name, column_name: column_name, name: name) }
15
+
16
+ describe '#up/down' do
17
+ describe '#up' do
18
+ it 'responds with command' do
19
+ expect(subject.up).to eq("remove_foreign_key :#{table_name}, name: #{name.to_sym.inspect}\n")
20
+ end
21
+ end
22
+
23
+ describe '#down' do
24
+ it 'responds with command' do
25
+ expect(subject.down).to eq("add_foreign_key :#{table_name}, :#{parent_table_name}, column: #{column_name.to_sym.inspect}, name: #{name.to_sym.inspect}\n")
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/index_add'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::IndexAdd do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'users' }
11
+ let(:column_names) { [:last_name, 'first_name'] }
12
+ let(:name) { 'on_last_name_and_first_name' }
13
+ let(:unique) { false }
14
+ subject { described_class.new(table_name, column_names, name: name, unique: unique) }
15
+
16
+ describe '#up/down' do
17
+ describe '#up' do
18
+ context 'without where:' do
19
+ it 'responds with command' do
20
+ expect(subject.up).to eq("add_index :#{table_name}, #{column_names.map(&:to_sym).inspect}, name: #{name.to_sym.inspect}\n")
21
+ end
22
+ end
23
+
24
+ context 'with empty where:' do
25
+ subject { described_class.new(table_name, column_names, name: name, unique: unique, where: nil) }
26
+
27
+ it 'responds with command' do
28
+ expect(subject.up).to eq("add_index :#{table_name}, #{column_names.map(&:to_sym).inspect}, name: #{name.to_sym.inspect}\n")
29
+ end
30
+ end
31
+
32
+ context 'with where:' do
33
+ let(:where) { "'last_name like 'A%'"}
34
+ subject { described_class.new(table_name, column_names, name: name, unique: unique, where: where) }
35
+
36
+ it 'responds with command' do
37
+ expect(subject.up).to eq("add_index :#{table_name}, #{column_names.map(&:to_sym).inspect}, name: #{name.to_sym.inspect}, where: #{where.inspect}\n")
38
+ end
39
+ end
40
+
41
+ context 'with unique: true' do
42
+ let(:unique) { true }
43
+
44
+ it 'responds with command' do
45
+ expect(subject.up).to eq("add_index :#{table_name}, #{column_names.map(&:to_sym).inspect}, name: #{name.to_sym.inspect}, unique: true\n")
46
+ end
47
+ end
48
+ end
49
+
50
+ describe '#down' do
51
+ it 'responds with command' do
52
+ expect(subject.down).to eq("remove_index :#{table_name}, name: #{name.to_sym.inspect}\n")
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/index_remove'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::IndexRemove do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'users' }
11
+ let(:column_names) { [:last_name, 'first_name'] }
12
+ let(:name) { 'on_last_name_and_first_name' }
13
+ let(:unique) { true }
14
+ subject { described_class.new(table_name, column_names, name: name, unique: unique) }
15
+
16
+ describe '#up/down' do
17
+ describe '#up' do
18
+ it 'responds with command' do
19
+ expect(subject.up).to eq("remove_index :#{table_name}, name: #{name.to_sym.inspect}\n")
20
+ end
21
+ end
22
+
23
+ describe '#down' do
24
+ it 'responds with command' do
25
+ expect(subject.down).to eq("add_index :#{table_name}, #{column_names.map(&:to_sym).inspect}, name: #{name.to_sym.inspect}, unique: #{unique}\n")
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/primary_key_change'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::PrimaryKeyChange do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'users' }
11
+ let(:old_column_names) { ['id'] }
12
+ let(:new_column_names) { [:last_name, 'first_name'] }
13
+ let(:name) { 'PRIMARY' }
14
+ subject { described_class.new(table_name, old_column_names, new_column_names) }
15
+
16
+ describe '#up/down' do
17
+ context 'when PRIMARY KEY set -> set' do
18
+ describe '#up' do
19
+ it 'responds with command' do
20
+ command = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} DROP PRIMARY KEY, ADD PRIMARY KEY (#{new_column_names.join(', ')})"
21
+ expect(subject.up).to eq("execute #{command.inspect}\n")
22
+ end
23
+ end
24
+
25
+ describe '#down' do
26
+ it 'responds with command' do
27
+ command = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} DROP PRIMARY KEY, ADD PRIMARY KEY (#{old_column_names.join(', ')})"
28
+ expect(subject.down).to eq("execute #{command.inspect}\n")
29
+ end
30
+ end
31
+ end
32
+
33
+ context 'when PRIMARY KEY unset -> set' do
34
+ let(:old_column_names) { nil }
35
+
36
+ describe '#up' do
37
+ it 'responds with command' do
38
+ command = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} ADD PRIMARY KEY (#{new_column_names.join(', ')})"
39
+ expect(subject.up).to eq("execute #{command.inspect}\n")
40
+ end
41
+ end
42
+
43
+ describe '#down' do
44
+ it 'responds with command' do
45
+ command = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} DROP PRIMARY KEY"
46
+ expect(subject.down).to eq("execute #{command.inspect}\n")
47
+ end
48
+ end
49
+ end
50
+
51
+ context 'when PRIMARY KEY set -> unset' do
52
+ let(:new_column_names) { nil }
53
+
54
+ describe '#up' do
55
+ it 'responds with command' do
56
+ command = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} DROP PRIMARY KEY"
57
+ expect(subject.up).to eq("execute #{command.inspect}\n")
58
+ end
59
+ end
60
+
61
+ describe '#down' do
62
+ it 'responds with command' do
63
+ command = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} ADD PRIMARY KEY (#{old_column_names.join(', ')})"
64
+ expect(subject.down).to eq("execute #{command.inspect}\n")
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end