declare_schema 0.6.2 → 0.8.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+
5
+ begin
6
+ require 'mysql2'
7
+ rescue LoadError
8
+ end
9
+
10
+ require_relative '../../../../lib/declare_schema/model/column'
11
+
12
+ RSpec.describe DeclareSchema::Model::Column do
13
+ before do
14
+ load File.expand_path('../prepare_testapp.rb', __dir__)
15
+ end
16
+
17
+ describe 'class methods' do
18
+ describe '.native_type?' do
19
+ if Rails::VERSION::MAJOR >= 5
20
+ let(:native_types) { [:string, :text, :integer, :float, :decimal, :datetime, :time, :date, :binary, :boolean, :json] }
21
+ else
22
+ let(:native_types) { [:string, :text, :integer, :float, :decimal, :datetime, :time, :date, :binary, :boolean] }
23
+ end
24
+
25
+ it 'is falsey for :primary_key' do
26
+ expect(described_class.native_type?(:primary_key)).to be_falsey
27
+ end
28
+
29
+ it 'is truthy for native types' do
30
+ native_types.each do |type|
31
+ expect(described_class.native_type?(type)).to be_truthy, type.inspect
32
+ end
33
+ end
34
+
35
+ it 'is falsey for other types' do
36
+ [:email, :url].each do |type|
37
+ expect(described_class.native_type?(type)).to be_falsey
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '.native_types' do
43
+ subject { described_class.native_types }
44
+
45
+ it 'returns the native type for :primary_key' do
46
+ expect(subject[:primary_key]).to match(/auto_increment PRIMARY KEY|PRIMARY KEY AUTOINCREMENT NOT NULL/)
47
+ end
48
+
49
+ it 'returns the native type for :string' do
50
+ expect(subject.dig(:string, :name)).to eq('varchar')
51
+ end
52
+
53
+ it 'returns the native type for :integer' do
54
+ expect(subject.dig(:integer, :name)).to match(/int/)
55
+ end
56
+
57
+ it 'returns the native type for :datetime' do
58
+ expect(subject.dig(:datetime, :name)).to eq('datetime')
59
+ end
60
+ end
61
+
62
+ describe '.deserialize_default_value' do
63
+ require 'rails'
64
+
65
+ if ::Rails::VERSION::MAJOR >= 5
66
+ it 'deserializes :boolean' do
67
+ expect(described_class.deserialize_default_value(nil, :boolean, 'true')).to eq(true)
68
+ expect(described_class.deserialize_default_value(nil, :boolean, 'false')).to eq(false)
69
+ end
70
+
71
+ it 'deserializes :integer' do
72
+ expect(described_class.deserialize_default_value(nil, :integer, '12')).to eq(12)
73
+ end
74
+
75
+ it 'deserializes :json' do
76
+ expect(described_class.deserialize_default_value(nil, :json, '{}')).to eq({})
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ describe 'instance methods' do
83
+ before do
84
+ class ColumnTestModel < ActiveRecord::Base
85
+ fields do
86
+ title :string, limit: 127, null: false
87
+ count :integer, null: false
88
+ end
89
+ end
90
+ end
91
+ let(:model) { ColumnTestModel }
92
+ let(:type) { :integer }
93
+ let(:current_table_name) { model.table_name }
94
+ let(:column) { double("ActiveRecord Column",
95
+ name: 'count',
96
+ type: type,
97
+ limit: nil,
98
+ precision: nil,
99
+ scale: nil,
100
+ type_cast_from_database: nil,
101
+ null: false,
102
+ default: nil,
103
+ sql_type_metadata: {}) }
104
+ subject { described_class.new(model, current_table_name, column) }
105
+
106
+ describe '#type' do
107
+ it 'returns type' do
108
+ expect(subject.type).to eq(type)
109
+ end
110
+ end
111
+
112
+ describe '#schema_attributes' do
113
+ it 'returns a hash with relevant key/values' do
114
+ if defined?(Mysql2)
115
+ expect(subject.schema_attributes).to eq(type: :integer, null: false, limit: 4)
116
+ else
117
+ expect(subject.schema_attributes).to eq(type: :integer, null: false)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../../lib/declare_schema/model/foreign_key_definition'
4
+
5
+ RSpec.describe DeclareSchema::Model::ForeignKeyDefinition do
6
+ before do
7
+ load File.expand_path('../prepare_testapp.rb', __dir__)
8
+
9
+ class Network < ActiveRecord::Base
10
+ fields do
11
+ name :string, limit: 127, index: true
12
+
13
+ timestamps
14
+ end
15
+ end
16
+ end
17
+
18
+ let(:model_class) { Network }
19
+
20
+ describe 'instance methods' do
21
+ let(:connection) { instance_double(ActiveRecord::Base.connection.class) }
22
+ let(:model) { instance_double('Model', table_name: 'models', connection: connection) }
23
+ let(:foreign_key) { :network_id }
24
+ let(:options) { {} }
25
+ subject { described_class.new(model, foreign_key, options)}
26
+
27
+ before do
28
+ allow(connection).to receive(:index_name).with('models', column: 'network_id') { 'on_network_id' }
29
+ end
30
+
31
+ describe '#initialize' do
32
+ it 'normalizes symbols to strings' do
33
+ expect(subject.foreign_key).to eq('network_id')
34
+ expect(subject.parent_table_name).to eq('networks')
35
+ end
36
+
37
+ context 'when most options passed' do
38
+ let(:options) { { parent_table: :networks, foreign_key: :the_network_id, index_name: :index_on_network_id } }
39
+
40
+ it 'normalizes symbols to strings' do
41
+ expect(subject.foreign_key).to eq('network_id')
42
+ expect(subject.foreign_key_name).to eq('the_network_id')
43
+ expect(subject.parent_table_name).to eq('networks')
44
+ expect(subject.foreign_key).to eq('network_id')
45
+ expect(subject.constraint_name).to eq('index_on_network_id')
46
+ expect(subject.on_delete_cascade).to be_falsey
47
+ end
48
+ end
49
+
50
+ context 'when all options passed' do
51
+ let(:foreign_key) { nil }
52
+ let(:options) { { parent_table: :networks, foreign_key: :the_network_id, index_name: :index_on_network_id,
53
+ constraint_name: :constraint_1, dependent: :delete } }
54
+
55
+ it 'normalizes symbols to strings' do
56
+ expect(subject.foreign_key).to be_nil
57
+ expect(subject.foreign_key_name).to eq('the_network_id')
58
+ expect(subject.parent_table_name).to eq('networks')
59
+ expect(subject.constraint_name).to eq('constraint_1')
60
+ expect(subject.on_delete_cascade).to be_truthy
61
+ end
62
+ end
63
+ end
64
+
65
+ describe '#to_add_statement' do
66
+ it 'returns add_foreign_key command' do
67
+ expect(subject.to_add_statement).to eq('add_foreign_key("models", "networks", column: "network_id", name: "on_network_id")')
68
+ end
69
+ end
70
+ end
71
+
72
+ describe 'class << self' do
73
+ let(:connection) { instance_double(ActiveRecord::Base.connection.class) }
74
+ let(:model) { instance_double('Model', table_name: 'models', connection: connection) }
75
+ let(:old_table_name) { 'networks' }
76
+ before do
77
+ allow(connection).to receive(:quote_table_name).with('networks') { 'networks' }
78
+ allow(connection).to receive(:select_rows) { [['CONSTRAINT `constraint` FOREIGN KEY (`network_id`) REFERENCES `networks` (`id`)']] }
79
+ allow(connection).to receive(:index_name).with('models', column: 'network_id') { }
80
+ end
81
+
82
+ describe '.for_model' do
83
+ subject { described_class.for_model(model, old_table_name) }
84
+
85
+ it 'returns new object' do
86
+ expect(subject.size).to eq(1), subject.inspect
87
+ expect(subject.first).to be_kind_of(described_class)
88
+ expect(subject.first.foreign_key).to eq('network_id')
89
+ end
90
+ end
91
+ end
92
+ # TODO: fill out remaining tests
93
+ end
@@ -18,17 +18,8 @@ module Generators
18
18
  subject { described_class.new }
19
19
 
20
20
  describe 'format_options' do
21
- let(:mysql_longtext_limit) { 0xffff_ffff }
22
- let(:limit_option) do
23
- if defined?(Mysql2)
24
- ["limit: #{mysql_longtext_limit}"]
25
- else
26
- []
27
- end
28
- end
29
-
30
- it 'returns text limits if supported' do
31
- expect(subject.format_options({ limit: mysql_longtext_limit }, :text)).to eq(limit_option)
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\""'])
32
23
  end
33
24
  end
34
25
 
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.6.2
4
+ version: 0.8.0.pre.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-01-14 00:00:00.000000000 Z
11
+ date: 2021-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -61,6 +61,7 @@ files:
61
61
  - lib/declare_schema/extensions/module.rb
62
62
  - lib/declare_schema/field_declaration_dsl.rb
63
63
  - lib/declare_schema/model.rb
64
+ - lib/declare_schema/model/column.rb
64
65
  - lib/declare_schema/model/field_spec.rb
65
66
  - lib/declare_schema/model/foreign_key_definition.rb
66
67
  - lib/declare_schema/model/index_definition.rb
@@ -82,6 +83,8 @@ files:
82
83
  - spec/lib/declare_schema/generator_spec.rb
83
84
  - spec/lib/declare_schema/interactive_primary_key_spec.rb
84
85
  - spec/lib/declare_schema/migration_generator_spec.rb
86
+ - spec/lib/declare_schema/model/column_spec.rb
87
+ - spec/lib/declare_schema/model/foreign_key_definition_spec.rb
85
88
  - spec/lib/declare_schema/model/index_definition_spec.rb
86
89
  - spec/lib/declare_schema/model/table_options_definition_spec.rb
87
90
  - spec/lib/declare_schema/prepare_testapp.rb
@@ -93,7 +96,7 @@ homepage: https://github.com/Invoca/declare_schema
93
96
  licenses: []
94
97
  metadata:
95
98
  allowed_push_host: https://rubygems.org
96
- post_install_message:
99
+ post_install_message:
97
100
  rdoc_options: []
98
101
  require_paths:
99
102
  - lib
@@ -109,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
112
  version: 1.3.6
110
113
  requirements: []
111
114
  rubygems_version: 3.0.3
112
- signing_key:
115
+ signing_key:
113
116
  specification_version: 4
114
117
  summary: Database schema declaration and migration generator for Rails
115
118
  test_files: []