declare_schema 1.4.0.colin.7 → 1.4.0.colin.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +4 -1
- data/lib/declare_schema/model/field_spec.rb +2 -0
- data/lib/declare_schema/model/foreign_key_definition.rb +39 -43
- data/lib/declare_schema/model/habtm_model_shim.rb +18 -25
- data/lib/declare_schema/model/index_definition.rb +43 -30
- data/lib/declare_schema/model/table_options_definition.rb +11 -1
- data/lib/declare_schema/model.rb +48 -36
- data/lib/declare_schema/version.rb +1 -1
- data/lib/declare_schema.rb +34 -2
- data/lib/generators/declare_schema/migration/migrator.rb +16 -10
- data/spec/lib/declare_schema/field_spec_spec.rb +22 -2
- data/spec/lib/declare_schema/migration_generator_spec.rb +17 -35
- data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +28 -27
- data/spec/lib/declare_schema/model/habtm_model_shim_spec.rb +54 -57
- data/spec/lib/declare_schema/model/index_definition_spec.rb +60 -53
- data/spec/lib/declare_schema/model/table_options_definition_spec.rb +26 -6
- data/spec/lib/declare_schema_spec.rb +62 -8
- data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +3 -1
- data/spec/spec_helper.rb +4 -3
- metadata +2 -2
@@ -11,6 +11,7 @@ require_relative '../../../../lib/declare_schema/model/index_definition'
|
|
11
11
|
|
12
12
|
RSpec.describe DeclareSchema::Model::IndexDefinition do
|
13
13
|
let(:model_class) { IndexDefinitionTestModel }
|
14
|
+
let(:table_name) { model_class.table_name }
|
14
15
|
|
15
16
|
context 'Using declare_schema' do
|
16
17
|
before do
|
@@ -34,23 +35,19 @@ RSpec.describe DeclareSchema::Model::IndexDefinition do
|
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
38
|
+
# TODO: create model_spec.rb and move the Model specs below into it. -Colin
|
37
39
|
describe 'instance methods' do
|
38
40
|
let(:model) { model_class.new }
|
41
|
+
let(:table_name) { "index_definition_test_models" }
|
39
42
|
let(:fields) { ['last_name', 'first_name'] }
|
40
|
-
let(:options) { {} }
|
41
|
-
subject(:instance) { described_class.new(
|
43
|
+
let(:options) { { table_name: table_name } }
|
44
|
+
subject(:instance) { described_class.new(fields, **options) }
|
42
45
|
|
43
46
|
describe 'attr_readers' do
|
44
|
-
describe '#
|
45
|
-
subject { instance.
|
47
|
+
describe '#table_name' do
|
48
|
+
subject { instance.table_name }
|
46
49
|
|
47
|
-
it { is_expected.to eq(
|
48
|
-
|
49
|
-
context 'with table_name option' do
|
50
|
-
let(:options) { { table_name: 'auth_users' } }
|
51
|
-
|
52
|
-
it { is_expected.to eq('auth_users') }
|
53
|
-
end
|
50
|
+
it { is_expected.to eq(table_name) }
|
54
51
|
end
|
55
52
|
|
56
53
|
describe '#fields' do
|
@@ -62,18 +59,22 @@ RSpec.describe DeclareSchema::Model::IndexDefinition do
|
|
62
59
|
describe '#explicit_name' do
|
63
60
|
subject { instance.explicit_name }
|
64
61
|
|
65
|
-
|
62
|
+
context 'with allow_equivalent' do
|
63
|
+
let(:options) { { table_name: table_name, allow_equivalent: true } }
|
64
|
+
|
65
|
+
it { is_expected.to eq(nil) }
|
66
|
+
end
|
66
67
|
|
67
68
|
context 'with name option' do
|
68
|
-
let(:options) { { name: '
|
69
|
+
let(:options) { { table_name: table_name, name: 'index_auth_users_on_names' } }
|
69
70
|
|
70
|
-
it { is_expected.to eq('
|
71
|
+
it { is_expected.to eq('index_auth_users_on_names') }
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
74
75
|
describe '#length' do
|
75
76
|
subject { instance.length }
|
76
|
-
let(:options) { { length: length } }
|
77
|
+
let(:options) { { table_name: table_name, length: length } }
|
77
78
|
|
78
79
|
context 'with integer length' do
|
79
80
|
let(:length) { 2 }
|
@@ -90,9 +91,9 @@ RSpec.describe DeclareSchema::Model::IndexDefinition do
|
|
90
91
|
|
91
92
|
describe '#options' do
|
92
93
|
subject { instance.options }
|
93
|
-
let(:options) { { name: 'my_index', unique: false, where: "(name like 'a%')", length: 10 } }
|
94
|
+
let(:options) { { name: 'my_index', table_name: table_name, unique: false, where: "(name like 'a%')", length: 10 } }
|
94
95
|
|
95
|
-
it { is_expected.to eq(options) }
|
96
|
+
it { is_expected.to eq(options.except(:table_name)) }
|
96
97
|
end
|
97
98
|
|
98
99
|
describe '#with_name' do
|
@@ -105,33 +106,25 @@ RSpec.describe DeclareSchema::Model::IndexDefinition do
|
|
105
106
|
end
|
106
107
|
end
|
107
108
|
|
108
|
-
describe 'class methods' do
|
109
|
-
|
110
|
-
|
111
|
-
describe 'index_definitions' do
|
112
|
-
it do
|
113
|
-
expect(model_class.index_definitions.size).to eq(1)
|
109
|
+
describe 'Model class methods' do
|
110
|
+
describe '.has index_definitions' do
|
111
|
+
subject { model_class.index_definitions }
|
114
112
|
|
115
|
-
|
116
|
-
expect(
|
117
|
-
|
118
|
-
|
113
|
+
it 'returns indexes without primary key' do
|
114
|
+
expect(subject.map(&:to_key)).to eq([
|
115
|
+
['index_index_definition_test_models_on_name', ['name'], { length: nil, unique: false, where: nil }],
|
116
|
+
])
|
119
117
|
end
|
120
118
|
end
|
121
119
|
|
122
|
-
describe 'has index_definitions_with_primary_key' do
|
123
|
-
|
124
|
-
expect(model_class.index_definitions_with_primary_key).to be_kind_of(Set)
|
125
|
-
result = model_class.index_definitions_with_primary_key.sort_by(&:name)
|
126
|
-
expect(result.size).to eq(2)
|
120
|
+
describe '.has index_definitions_with_primary_key' do
|
121
|
+
subject { model_class.index_definitions_with_primary_key }
|
127
122
|
|
128
|
-
|
129
|
-
expect(
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
expect(result[1].fields).to eq(['name'])
|
134
|
-
expect(result[1].unique).to eq(false)
|
123
|
+
it 'returns indexes with primary key' do
|
124
|
+
expect(subject.map(&:to_key)).to eq([
|
125
|
+
['index_index_definition_test_models_on_name', ['name'], { length: nil, unique: false, where: nil }],
|
126
|
+
['PRIMARY', ['id'], { length: nil, unique: true, where: nil }],
|
127
|
+
])
|
135
128
|
end
|
136
129
|
end
|
137
130
|
end
|
@@ -147,6 +140,11 @@ RSpec.describe DeclareSchema::Model::IndexDefinition do
|
|
147
140
|
ActiveRecord::Base.connection.execute <<~EOS
|
148
141
|
CREATE UNIQUE INDEX index_definition_test_models_on_name ON index_definition_test_models(name)
|
149
142
|
EOS
|
143
|
+
if defined?(Mysql2)
|
144
|
+
ActiveRecord::Base.connection.execute <<~EOS
|
145
|
+
CREATE INDEX index_definition_test_models_on_name_partial ON index_definition_test_models(name(10))
|
146
|
+
EOS
|
147
|
+
end
|
150
148
|
ActiveRecord::Base.connection.execute <<~EOS
|
151
149
|
CREATE TABLE index_definition_compound_index_models (
|
152
150
|
fk1_id INTEGER NOT NULL,
|
@@ -157,29 +155,38 @@ RSpec.describe DeclareSchema::Model::IndexDefinition do
|
|
157
155
|
ActiveRecord::Base.connection.schema_cache.clear!
|
158
156
|
end
|
159
157
|
|
160
|
-
describe '
|
161
|
-
|
158
|
+
describe 'for_table' do
|
159
|
+
let(:ignore_indexes) { model_class.ignore_indexes }
|
160
|
+
subject { described_class.for_table(model_class.table_name, ignore_indexes, model_class.connection) }
|
162
161
|
|
163
162
|
context 'with single-column PK' do
|
164
163
|
it 'returns the indexes for the model' do
|
165
|
-
expect(subject.
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
expect(subject[1].columns).to eq(['id'])
|
171
|
-
expect(subject[1].unique).to eq(true)
|
164
|
+
expect(subject.map(&:to_key)).to eq([
|
165
|
+
["index_definition_test_models_on_name", ["name"], { unique: true, where: nil, length: nil }],
|
166
|
+
(["index_definition_test_models_on_name_partial", ["name"], { unique: false, where: nil, length: 10 }] if defined?(Mysql2)),
|
167
|
+
["PRIMARY", ["id"], { unique: true, where: nil, length: nil }]
|
168
|
+
].compact)
|
172
169
|
end
|
173
170
|
end
|
174
171
|
|
175
|
-
context 'with
|
172
|
+
context 'with composite (multi-column) PK' do
|
176
173
|
let(:model_class) { IndexDefinitionCompoundIndexModel }
|
177
174
|
|
178
175
|
it 'returns the indexes for the model' do
|
179
|
-
expect(subject.
|
180
|
-
|
181
|
-
|
182
|
-
|
176
|
+
expect(subject.map(&:to_key)).to eq([
|
177
|
+
["PRIMARY", ["fk1_id", "fk2_id"], { length: nil, unique: true, where: nil }]
|
178
|
+
])
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'with ignored_indexes' do
|
183
|
+
let(:ignore_indexes) { ['index_definition_test_models_on_name'] }
|
184
|
+
|
185
|
+
it 'skips the ignored index' do
|
186
|
+
expect(subject.map(&:to_key)).to eq([
|
187
|
+
(["index_definition_test_models_on_name_partial", ["name"], { unique: false, where: nil, length: 10 }] if defined?(Mysql2)),
|
188
|
+
["PRIMARY", ["id"], { length: nil, unique: true, where: nil }]
|
189
|
+
].compact)
|
183
190
|
end
|
184
191
|
end
|
185
192
|
end
|
@@ -9,6 +9,8 @@ require_relative '../../../../lib/declare_schema/model/table_options_definition'
|
|
9
9
|
|
10
10
|
RSpec.describe DeclareSchema::Model::TableOptionsDefinition do
|
11
11
|
let(:model_class) { TableOptionsDefinitionTestModel }
|
12
|
+
let(:charset) { DeclareSchema.normalize_charset('utf8') }
|
13
|
+
let(:collation) { DeclareSchema.normalize_collation('utf8_general') } # adapt so that tests will pass on MySQL 5.7 or 8+
|
12
14
|
|
13
15
|
context 'Using declare_schema' do
|
14
16
|
before do
|
@@ -27,27 +29,45 @@ RSpec.describe DeclareSchema::Model::TableOptionsDefinition do
|
|
27
29
|
|
28
30
|
describe '#to_key' do
|
29
31
|
subject { model.to_key }
|
30
|
-
it {
|
32
|
+
it { is_expected.to eq(['table_options_definition_test_models', "{:charset=>#{charset.inspect}, :collation=>#{collation.inspect}}"]) }
|
31
33
|
end
|
32
34
|
|
33
35
|
describe '#settings' do
|
34
36
|
subject { model.settings }
|
35
|
-
it {
|
37
|
+
it { is_expected.to eq("CHARACTER SET #{charset} COLLATE #{collation}") }
|
38
|
+
|
39
|
+
if defined?(Mysql2)
|
40
|
+
context 'when running in MySQL 8' do
|
41
|
+
around do |spec|
|
42
|
+
DeclareSchema.mysql_version = Gem::Version.new('8.0.21')
|
43
|
+
spec.run
|
44
|
+
ensure
|
45
|
+
DeclareSchema.remove_instance_variable('@mysql_version') rescue nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it { is_expected.to eq("CHARACTER SET utf8mb3 COLLATE utf8mb3_general") }
|
49
|
+
|
50
|
+
context 'when _ci collation' do
|
51
|
+
let(:table_options) { { charset: "utf8", collation: "utf8_general_ci"} }
|
52
|
+
it { is_expected.to eq("CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci") }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
36
56
|
end
|
37
57
|
|
38
58
|
describe '#hash' do
|
39
59
|
subject { model.hash }
|
40
|
-
it {
|
60
|
+
it { is_expected.to eq(['table_options_definition_test_models', "{:charset=>#{charset.inspect}, :collation=>#{collation.inspect}}"].hash) }
|
41
61
|
end
|
42
62
|
|
43
63
|
describe '#to_s' do
|
44
64
|
subject { model.to_s }
|
45
|
-
it {
|
65
|
+
it { is_expected.to eq("CHARACTER SET #{charset} COLLATE #{collation}") }
|
46
66
|
end
|
47
67
|
|
48
68
|
describe '#alter_table_statement' do
|
49
69
|
subject { model.alter_table_statement }
|
50
|
-
it {
|
70
|
+
it { is_expected.to match(/execute "ALTER TABLE .*table_options_definition_test_models.* CHARACTER SET #{charset} COLLATE #{collation}"/) }
|
51
71
|
end
|
52
72
|
end
|
53
73
|
|
@@ -67,7 +87,7 @@ RSpec.describe DeclareSchema::Model::TableOptionsDefinition do
|
|
67
87
|
generate_migrations '-n', '-m'
|
68
88
|
end
|
69
89
|
|
70
|
-
it {
|
90
|
+
it { is_expected.to eq(described_class.new(model_class.table_name, **options)) }
|
71
91
|
end
|
72
92
|
end
|
73
93
|
end
|
@@ -8,10 +8,34 @@ RSpec.describe DeclareSchema do
|
|
8
8
|
it { is_expected.to eq("utf8mb4") }
|
9
9
|
end
|
10
10
|
|
11
|
-
context 'when
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
context 'when running on MySQL 5.7' do
|
12
|
+
around do |spec|
|
13
|
+
described_class.mysql_version = Gem::Version.new('5.7.48')
|
14
|
+
spec.run
|
15
|
+
ensure
|
16
|
+
described_class.remove_instance_variable('@mysql_version') rescue nil
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when explicitly set' do
|
20
|
+
before { described_class.default_charset = "utf8" }
|
21
|
+
after { described_class.default_charset = "utf8mb4" }
|
22
|
+
it { is_expected.to eq("utf8") }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when running on MySQL 8.0' do
|
27
|
+
around do |spec|
|
28
|
+
described_class.mysql_version = Gem::Version.new('8.0.21')
|
29
|
+
spec.run
|
30
|
+
ensure
|
31
|
+
described_class.remove_instance_variable('@mysql_version') rescue nil
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when explicitly set' do
|
35
|
+
before { described_class.default_charset = "utf8" }
|
36
|
+
after { described_class.default_charset = "utf8mb4" }
|
37
|
+
it { is_expected.to eq("utf8mb3") }
|
38
|
+
end
|
15
39
|
end
|
16
40
|
end
|
17
41
|
|
@@ -22,10 +46,40 @@ RSpec.describe DeclareSchema do
|
|
22
46
|
it { is_expected.to eq("utf8mb4_bin") }
|
23
47
|
end
|
24
48
|
|
25
|
-
context 'when
|
26
|
-
|
27
|
-
|
28
|
-
|
49
|
+
context 'when running on MySQL 5.7' do
|
50
|
+
around do |spec|
|
51
|
+
described_class.mysql_version = Gem::Version.new('5.7.48')
|
52
|
+
spec.run
|
53
|
+
ensure
|
54
|
+
described_class.remove_instance_variable('@mysql_version')
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when explicitly set' do
|
58
|
+
before { described_class.default_collation = "utf8_general_ci" }
|
59
|
+
after { described_class.default_collation = "utf8mb4_bin" }
|
60
|
+
it { is_expected.to eq("utf8_general_ci") }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when running on MySQL 8.0' do
|
65
|
+
around do |spec|
|
66
|
+
described_class.mysql_version = Gem::Version.new('8.0.21')
|
67
|
+
spec.run
|
68
|
+
ensure
|
69
|
+
described_class.remove_instance_variable('@mysql_version')
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when explicitly set without _ci' do
|
73
|
+
before { described_class.default_collation = "utf8_general" }
|
74
|
+
after { described_class.default_collation = "utf8mb4_bin" }
|
75
|
+
it { is_expected.to eq("utf8mb3_general") }
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when explicitly set with _ci' do
|
79
|
+
before { described_class.default_collation = "utf8_general_ci" }
|
80
|
+
after { described_class.default_collation = "utf8mb4_bin" }
|
81
|
+
it { is_expected.to eq("utf8mb3_general_ci") }
|
82
|
+
end
|
29
83
|
end
|
30
84
|
end
|
31
85
|
|
@@ -12,6 +12,8 @@ module Generators
|
|
12
12
|
module Migration
|
13
13
|
RSpec.describe Migrator do
|
14
14
|
subject { described_class.new }
|
15
|
+
let(:charset) { ::DeclareSchema.normalize_charset('utf8') }
|
16
|
+
let(:collation) { ::DeclareSchema.normalize_collation('utf8_general') } # adapt so that tests will pass on MySQL 5.7 or 8+
|
15
17
|
|
16
18
|
describe '#before_generating_migration' do
|
17
19
|
it 'requires a block be passed' do
|
@@ -29,7 +31,7 @@ module Generators
|
|
29
31
|
context 'when explicitly set' do
|
30
32
|
before { described_class.default_charset = "utf8" }
|
31
33
|
after { described_class.default_charset = "utf8mb4" }
|
32
|
-
it { should eq(
|
34
|
+
it { should eq(charset) }
|
33
35
|
end
|
34
36
|
|
35
37
|
it 'should output deprecation warning' do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'declare_schema'
|
5
|
+
require 'climate_control'
|
6
|
+
require 'pry'
|
6
7
|
|
7
8
|
require_relative "./support/acceptance_spec_helpers"
|
8
9
|
|
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: 1.4.0.colin.
|
4
|
+
version: 1.4.0.colin.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Invoca Development adapted from hobo_fields by Tom Locke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|