declare_schema 0.9.0 → 0.11.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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/declare_schema_build.yml +1 -1
  3. data/CHANGELOG.md +32 -0
  4. data/Gemfile.lock +1 -1
  5. data/README.md +12 -2
  6. data/lib/declare_schema.rb +12 -1
  7. data/lib/declare_schema/dsl.rb +39 -0
  8. data/lib/declare_schema/extensions/active_record/fields_declaration.rb +22 -3
  9. data/lib/declare_schema/model.rb +4 -6
  10. data/lib/declare_schema/model/column.rb +1 -1
  11. data/lib/declare_schema/model/foreign_key_definition.rb +6 -11
  12. data/lib/declare_schema/model/index_definition.rb +1 -20
  13. data/lib/declare_schema/schema_change/all.rb +22 -0
  14. data/lib/declare_schema/schema_change/base.rb +45 -0
  15. data/lib/declare_schema/schema_change/column_add.rb +27 -0
  16. data/lib/declare_schema/schema_change/column_change.rb +32 -0
  17. data/lib/declare_schema/schema_change/column_remove.rb +20 -0
  18. data/lib/declare_schema/schema_change/column_rename.rb +23 -0
  19. data/lib/declare_schema/schema_change/foreign_key_add.rb +25 -0
  20. data/lib/declare_schema/schema_change/foreign_key_remove.rb +20 -0
  21. data/lib/declare_schema/schema_change/index_add.rb +33 -0
  22. data/lib/declare_schema/schema_change/index_remove.rb +20 -0
  23. data/lib/declare_schema/schema_change/primary_key_change.rb +33 -0
  24. data/lib/declare_schema/schema_change/table_add.rb +37 -0
  25. data/lib/declare_schema/schema_change/table_change.rb +36 -0
  26. data/lib/declare_schema/schema_change/table_remove.rb +22 -0
  27. data/lib/declare_schema/schema_change/table_rename.rb +22 -0
  28. data/lib/declare_schema/version.rb +1 -1
  29. data/lib/generators/declare_schema/migration/USAGE +14 -24
  30. data/lib/generators/declare_schema/migration/migration_generator.rb +40 -38
  31. data/lib/generators/declare_schema/migration/migrator.rb +175 -177
  32. data/lib/generators/declare_schema/migration/templates/migration.rb.erb +3 -3
  33. data/lib/generators/declare_schema/support/model.rb +4 -4
  34. data/spec/lib/declare_schema/api_spec.rb +8 -8
  35. data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +41 -15
  36. data/spec/lib/declare_schema/field_spec_spec.rb +2 -2
  37. data/spec/lib/declare_schema/generator_spec.rb +5 -5
  38. data/spec/lib/declare_schema/interactive_primary_key_spec.rb +117 -28
  39. data/spec/lib/declare_schema/migration_generator_spec.rb +1990 -843
  40. data/spec/lib/declare_schema/model/column_spec.rb +49 -23
  41. data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +158 -57
  42. data/spec/lib/declare_schema/model/habtm_model_shim_spec.rb +0 -2
  43. data/spec/lib/declare_schema/model/index_definition_spec.rb +189 -78
  44. data/spec/lib/declare_schema/model/table_options_definition_spec.rb +75 -11
  45. data/spec/lib/declare_schema/schema_change/base_spec.rb +75 -0
  46. data/spec/lib/declare_schema/schema_change/column_add_spec.rb +30 -0
  47. data/spec/lib/declare_schema/schema_change/column_change_spec.rb +33 -0
  48. data/spec/lib/declare_schema/schema_change/column_remove_spec.rb +30 -0
  49. data/spec/lib/declare_schema/schema_change/column_rename_spec.rb +28 -0
  50. data/spec/lib/declare_schema/schema_change/foreign_key_add_spec.rb +29 -0
  51. data/spec/lib/declare_schema/schema_change/foreign_key_remove_spec.rb +29 -0
  52. data/spec/lib/declare_schema/schema_change/index_add_spec.rb +56 -0
  53. data/spec/lib/declare_schema/schema_change/index_remove_spec.rb +29 -0
  54. data/spec/lib/declare_schema/schema_change/primary_key_change_spec.rb +69 -0
  55. data/spec/lib/declare_schema/schema_change/table_add_spec.rb +50 -0
  56. data/spec/lib/declare_schema/schema_change/table_change_spec.rb +30 -0
  57. data/spec/lib/declare_schema/schema_change/table_remove_spec.rb +27 -0
  58. data/spec/lib/declare_schema/schema_change/table_rename_spec.rb +27 -0
  59. data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +59 -11
  60. data/spec/spec_helper.rb +1 -1
  61. data/spec/support/acceptance_spec_helpers.rb +2 -2
  62. metadata +35 -6
  63. data/test_responses.txt +0 -2
@@ -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
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/table_add'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::TableAdd do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'networks' }
11
+ let(:fields) { [[:string, :title, limit: 255, null: false ], [:boolean, :admin, null: false]] }
12
+ let(:create_table_options) { { id: :primary_key } }
13
+ let(:sql_options) { '' }
14
+
15
+ subject { described_class.new(table_name, fields, create_table_options, sql_options: sql_options) }
16
+
17
+ describe '#up/down' do
18
+ describe '#up' do
19
+ it 'responds with command' do
20
+ expect(subject.up).to eq(<<~EOS)
21
+ create_table :networks, id: :primary_key do |t|
22
+ t.string :title, limit: 255, null: false
23
+ t.boolean :admin, null: false
24
+ end
25
+
26
+ EOS
27
+ end
28
+
29
+ context 'with sql_options' do
30
+ let(:sql_options) { 'CHARACTER SET utf8mb4' }
31
+
32
+ it 'responds with command' do
33
+ expect(subject.up).to eq(<<~EOS)
34
+ create_table :networks, id: :primary_key, options: "CHARACTER SET utf8mb4" do |t|
35
+ t.string :title, limit: 255, null: false
36
+ t.boolean :admin, null: false
37
+ end
38
+
39
+ EOS
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#down' do
45
+ it 'responds with command' do
46
+ expect(subject.down).to eq("drop_table :#{table_name}\n")
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/table_change'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::TableChange do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'networks' }
11
+ let(:old_options) { { charset: 'utf8', collation: 'utf8_ci' } }
12
+ let(:new_options) { { charset: 'utf8mb4', collation: 'utf8mb4_bin' } }
13
+ subject { described_class.new(table_name, old_options, new_options) }
14
+
15
+ describe '#up/down' do
16
+ describe '#up' do
17
+ it 'responds with command' do
18
+ statement = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} CHARACTER SET utf8mb4 COLLATE utf8mb4_bin"
19
+ expect(subject.up).to eq("execute #{statement.inspect}\n")
20
+ end
21
+ end
22
+
23
+ describe '#down' do
24
+ it 'responds with command' do
25
+ statement = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} CHARACTER SET utf8 COLLATE utf8_ci"
26
+ expect(subject.down).to eq("execute #{statement.inspect}\n")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/table_remove'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::TableRemove do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:table_name) { 'networks' }
11
+ let(:add_table_back) { "create table networks(\n)" }
12
+ subject { described_class.new(table_name, add_table_back) }
13
+
14
+ describe '#up/down' do
15
+ describe '#up' do
16
+ it 'responds with command' do
17
+ expect(subject.up).to eq("drop_table :#{table_name}\n")
18
+ end
19
+ end
20
+
21
+ describe '#down' do
22
+ it 'responds with command' do
23
+ expect(subject.down).to eq("#{add_table_back}\n\n")
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/schema_change/table_rename'
4
+
5
+ RSpec.describe DeclareSchema::SchemaChange::TableRename do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+ end
9
+
10
+ let(:old_name) { 'networks' }
11
+ let(:new_name) { 'customers' }
12
+ subject { described_class.new(old_name, new_name) }
13
+
14
+ describe '#up/down' do
15
+ describe '#up' do
16
+ it 'responds with command' do
17
+ expect(subject.up).to eq("rename_table :#{old_name}, :#{new_name}\n")
18
+ end
19
+ end
20
+
21
+ describe '#down' do
22
+ it 'responds with command' do
23
+ expect(subject.down).to eq("rename_table :#{new_name}, :#{old_name}\n")
24
+ end
25
+ end
26
+ end
27
+ end
@@ -11,18 +11,8 @@ module Generators
11
11
  module DeclareSchema
12
12
  module Migration
13
13
  RSpec.describe Migrator do
14
- before do
15
- ActiveRecord::Base.connection.tables
16
- end
17
-
18
14
  subject { described_class.new }
19
15
 
20
- describe 'format_options' do
21
- it 'returns an array of option .inspect strings, with symbols using the modern : hash notation' do
22
- expect(subject.format_options({ limit: 4, 'key' => 'value "quoted"' })).to eq(["limit: 4", '"key" => "value \"quoted\""'])
23
- end
24
- end
25
-
26
16
  describe '#before_generating_migration' do
27
17
  it 'requires a block be passed' do
28
18
  expect { described_class.before_generating_migration }.to raise_error(ArgumentError, 'A block is required when setting the before_generating_migration callback')
@@ -67,7 +57,7 @@ module Generators
67
57
  end
68
58
  end
69
59
 
70
- describe 'load_rails_models' do
60
+ describe '#load_rails_models' do
71
61
  before do
72
62
  expect(Rails.application).to receive(:eager_load!)
73
63
  expect(Rails::Engine).to receive(:subclasses).and_return([])
@@ -90,6 +80,64 @@ module Generators
90
80
  it { should be_nil }
91
81
  end
92
82
  end
83
+
84
+ describe '#order_migrations' do
85
+ let(:class_name_order) do
86
+ %w[ TableRename
87
+ TableAdd
88
+ TableChange
89
+ ColumnAdd
90
+ ColumnRename
91
+ ColumnChange
92
+ PrimaryKeyChange
93
+ IndexAdd
94
+ ForeignKeyAdd
95
+ ForeignKeyRemove
96
+ IndexRemove
97
+ ColumnRemove
98
+ TableRemove ]
99
+ end
100
+ let(:one_of_each) do
101
+ class_name_order.map do |class_name|
102
+ klass = klass_from_class_name(class_name)
103
+ instance_double(klass).tap do |double|
104
+ allow(double).to receive(:class).and_return(klass)
105
+ end
106
+ end
107
+ end
108
+ let(:one_of_each_shuffled) { one_of_each.shuffle }
109
+
110
+ it 'orders properly' do
111
+ ordered = subject.order_migrations(one_of_each_shuffled)
112
+ expect(ordered.map { |c| c.class.name.sub(/.*::/, '') }).to eq(class_name_order)
113
+ end
114
+
115
+ context 'when there are dups' do
116
+ let(:one_of_each_with_dups) do
117
+ (class_name_order * 2).map do |class_name|
118
+ klass = klass_from_class_name(class_name)
119
+ instance_double(klass).tap do |double|
120
+ allow(double).to receive(:class).and_return(klass)
121
+ end
122
+ end
123
+ end
124
+ let(:one_of_each_with_dups_shuffled) { one_of_each_with_dups.shuffle }
125
+ let(:one_of_each_with_dups_shuffled_grouped) { one_of_each_with_dups_shuffled.group_by { |c| c.class.name } }
126
+
127
+ it 'sorts stably' do
128
+ ordered = subject.order_migrations(one_of_each_with_dups_shuffled)
129
+ ordered_grouped = ordered.group_by { |c| c.class.name }
130
+ ordered_grouped.each do |class_name, schema_changes|
131
+ shuffled_for_class = one_of_each_with_dups_shuffled_grouped[class_name]
132
+ expect(schema_changes.map(&:object_id)).to eq(shuffled_for_class.map(&:object_id))
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ def klass_from_class_name(class_name)
139
+ "::DeclareSchema::SchemaChange::#{class_name}".constantize
140
+ end
93
141
  end
94
142
  end
95
143
  end
data/spec/spec_helper.rb CHANGED
@@ -27,7 +27,7 @@ RSpec.configure do |config|
27
27
  RSpec::Support::ObjectFormatter.default_instance.max_formatted_output_length = 2_000
28
28
 
29
29
  def active_record_base_class
30
- if Rails::VERSION::MAJOR == 4
30
+ if ActiveSupport::VERSION::MAJOR == 4
31
31
  'ActiveRecord::Base'
32
32
  else
33
33
  'ApplicationRecord'
@@ -45,13 +45,13 @@ module AcceptanceSpecHelpers
45
45
 
46
46
  class MigrationUpEquals < RSpec::Matchers::BuiltIn::Eq
47
47
  def matches?(subject)
48
- super(subject[0].gsub(/, +([a-z_]+:)/i, ', \1')) # normalize multiple spaces to one
48
+ super(subject[0].strip.gsub(/, +([a-z_]+:)/i, ', \1').gsub(/\n+/, "\n")) # normalize multiple spaces and newlines to one
49
49
  end
50
50
  end
51
51
 
52
52
  class MigrationDownEquals < RSpec::Matchers::BuiltIn::Eq
53
53
  def matches?(subject)
54
- super(subject[1].gsub(/, +([a-z_]+:)/i, ', \1')) # normalize multiple spaces to one
54
+ super(subject[1].strip.gsub(/, +([a-z_]+:)/i, ', \1').gsub(/\n+/, "\n")) # normalize multiple spaces and newlines to one
55
55
  end
56
56
  end
57
57
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: declare_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca Development adapted from hobo_fields by Tom Locke
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-01 00:00:00.000000000 Z
11
+ date: 2021-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -57,6 +57,7 @@ files:
57
57
  - gemfiles/rails_6_sqlite.gemfile
58
58
  - lib/declare_schema.rb
59
59
  - lib/declare_schema/command.rb
60
+ - lib/declare_schema/dsl.rb
60
61
  - lib/declare_schema/extensions/active_record/fields_declaration.rb
61
62
  - lib/declare_schema/extensions/module.rb
62
63
  - lib/declare_schema/field_declaration_dsl.rb
@@ -68,6 +69,21 @@ files:
68
69
  - lib/declare_schema/model/index_definition.rb
69
70
  - lib/declare_schema/model/table_options_definition.rb
70
71
  - lib/declare_schema/railtie.rb
72
+ - lib/declare_schema/schema_change/all.rb
73
+ - lib/declare_schema/schema_change/base.rb
74
+ - lib/declare_schema/schema_change/column_add.rb
75
+ - lib/declare_schema/schema_change/column_change.rb
76
+ - lib/declare_schema/schema_change/column_remove.rb
77
+ - lib/declare_schema/schema_change/column_rename.rb
78
+ - lib/declare_schema/schema_change/foreign_key_add.rb
79
+ - lib/declare_schema/schema_change/foreign_key_remove.rb
80
+ - lib/declare_schema/schema_change/index_add.rb
81
+ - lib/declare_schema/schema_change/index_remove.rb
82
+ - lib/declare_schema/schema_change/primary_key_change.rb
83
+ - lib/declare_schema/schema_change/table_add.rb
84
+ - lib/declare_schema/schema_change/table_change.rb
85
+ - lib/declare_schema/schema_change/table_remove.rb
86
+ - lib/declare_schema/schema_change/table_rename.rb
71
87
  - lib/declare_schema/version.rb
72
88
  - lib/generators/declare_schema/migration/USAGE
73
89
  - lib/generators/declare_schema/migration/migration_generator.rb
@@ -90,16 +106,29 @@ files:
90
106
  - spec/lib/declare_schema/model/index_definition_spec.rb
91
107
  - spec/lib/declare_schema/model/table_options_definition_spec.rb
92
108
  - spec/lib/declare_schema/prepare_testapp.rb
109
+ - spec/lib/declare_schema/schema_change/base_spec.rb
110
+ - spec/lib/declare_schema/schema_change/column_add_spec.rb
111
+ - spec/lib/declare_schema/schema_change/column_change_spec.rb
112
+ - spec/lib/declare_schema/schema_change/column_remove_spec.rb
113
+ - spec/lib/declare_schema/schema_change/column_rename_spec.rb
114
+ - spec/lib/declare_schema/schema_change/foreign_key_add_spec.rb
115
+ - spec/lib/declare_schema/schema_change/foreign_key_remove_spec.rb
116
+ - spec/lib/declare_schema/schema_change/index_add_spec.rb
117
+ - spec/lib/declare_schema/schema_change/index_remove_spec.rb
118
+ - spec/lib/declare_schema/schema_change/primary_key_change_spec.rb
119
+ - spec/lib/declare_schema/schema_change/table_add_spec.rb
120
+ - spec/lib/declare_schema/schema_change/table_change_spec.rb
121
+ - spec/lib/declare_schema/schema_change/table_remove_spec.rb
122
+ - spec/lib/declare_schema/schema_change/table_rename_spec.rb
93
123
  - spec/lib/declare_schema_spec.rb
94
124
  - spec/lib/generators/declare_schema/migration/migrator_spec.rb
95
125
  - spec/spec_helper.rb
96
126
  - spec/support/acceptance_spec_helpers.rb
97
- - test_responses.txt
98
127
  homepage: https://github.com/Invoca/declare_schema
99
128
  licenses: []
100
129
  metadata:
101
130
  allowed_push_host: https://rubygems.org
102
- post_install_message:
131
+ post_install_message:
103
132
  rdoc_options: []
104
133
  require_paths:
105
134
  - lib
@@ -115,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
144
  version: 1.3.6
116
145
  requirements: []
117
146
  rubygems_version: 3.0.3
118
- signing_key:
147
+ signing_key:
119
148
  specification_version: 4
120
149
  summary: Database schema declaration and migration generator for Rails
121
150
  test_files: []
data/test_responses.txt DELETED
@@ -1,2 +0,0 @@
1
- id
2
- drop id