schema_expectations 0.0.1 → 0.2.0

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +19 -5
  4. data/Appraisals +33 -0
  5. data/CHANGELOG.md +17 -1
  6. data/README.md +4 -0
  7. data/Rakefile +12 -0
  8. data/gemfiles/activerecord_3.1.gemfile +7 -0
  9. data/gemfiles/activerecord_3.2.gemfile +7 -0
  10. data/gemfiles/activerecord_4.0.gemfile +7 -0
  11. data/gemfiles/activerecord_4.1.gemfile +7 -0
  12. data/gemfiles/activerecord_4.2.gemfile +7 -0
  13. data/gemfiles/default.gemfile +5 -0
  14. data/gemfiles/rspec_3.0.gemfile +7 -0
  15. data/gemfiles/rspec_3.1.gemfile +7 -0
  16. data/gemfiles/rspec_3.2.gemfile +7 -0
  17. data/lib/schema_expectations/active_record/column_reflector.rb +92 -0
  18. data/lib/schema_expectations/active_record/validation_reflector.rb +59 -0
  19. data/lib/schema_expectations/config.rb +25 -0
  20. data/lib/schema_expectations/rspec_matchers/validate_schema_nullable.rb +49 -58
  21. data/lib/schema_expectations/util.rb +9 -0
  22. data/lib/schema_expectations/version.rb +1 -1
  23. data/lib/schema_expectations.rb +1 -0
  24. data/schema_expectations.gemspec +12 -3
  25. data/spec/db/database.yml +13 -0
  26. data/spec/lib/schema_expectations/active_record/column_reflector_spec.rb +150 -0
  27. data/spec/lib/schema_expectations/active_record/validation_reflector_spec.rb +62 -0
  28. data/spec/lib/schema_expectations/config_spec.rb +22 -0
  29. data/spec/lib/schema_expectations/rspec_matchers/validate_schema_nullable_spec.rb +260 -77
  30. data/spec/lib/schema_expectations/util_spec.rb +16 -0
  31. data/spec/meta_spec.rb +44 -0
  32. data/spec/spec_helper.rb +11 -2
  33. data/spec/support/active_record.rb +34 -12
  34. data/spec/support/active_record_helpers.rb +51 -0
  35. data/spec/support/gem_filters.rb +6 -0
  36. metadata +162 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d089e8270a688859724aea6d9e3a117f0cc32154
4
- data.tar.gz: bc468ef7199c0960ca1ad33c8f20ea18ec5431bb
3
+ metadata.gz: 18218491d35e976cf13367e3d30d60e952886de6
4
+ data.tar.gz: fa58281615fdda22fefb031a987f85001c8fe672
5
5
  SHA512:
6
- metadata.gz: 7be6b68419758bbb28a87033904c4721d42bb0db70d2029ac52ffcb3e284aa2794621c351cdb481f8dd40c9d64e4c2be9ad22eefe51dfbb9bccdac30485d2379
7
- data.tar.gz: 56ec7dd5e2b85c9d05f02131c9603bfb59b5ef8f814922d4406ba2149a916a725bec39c0c1546b9916110418a989907a9c3e6c3a4764b38bc4ef1433a1595301
6
+ metadata.gz: 1eb5dc8161b1b91c08d40225bbd03d58e4153a6ea51af88420afbb91549837ca861849e486bb8e41f703097e5566ff6a344785829ac772a24c5a36995aa3992d
7
+ data.tar.gz: 8cc5ba8420797a7d5b10e8c25ca2ca309b2b8ecd7204f804296960988d7b835fc99ced2ff607f8b32c384ab5f407de6cf1d37cd3b103cc53fc1c23e0ba2052a9
data/.gitignore CHANGED
@@ -1,4 +1,7 @@
1
1
  Gemfile.lock
2
+ *.gemfile.lock
2
3
  /pkg
3
4
  /.yardoc
4
5
  /doc
6
+ /coverage
7
+ /tmp
data/.travis.yml CHANGED
@@ -1,7 +1,21 @@
1
+ ---
1
2
  language: ruby
2
3
  rvm:
3
- - 2.0.0
4
- - 2.1.5
5
- - 2.2.0
6
- - ruby-head
7
- script: 'bundle exec rake'
4
+ - 2.0.0
5
+ - 2.1.5
6
+ - 2.2.0
7
+ env:
8
+ - DB=sqlite3
9
+ - DB=postgresql
10
+ - DB=mysql2
11
+ script: bundle exec rake
12
+ gemfile:
13
+ - gemfiles/activerecord_3.1.gemfile
14
+ - gemfiles/activerecord_3.2.gemfile
15
+ - gemfiles/activerecord_4.0.gemfile
16
+ - gemfiles/activerecord_4.1.gemfile
17
+ - gemfiles/activerecord_4.2.gemfile
18
+ - gemfiles/default.gemfile
19
+ - gemfiles/rspec_3.0.gemfile
20
+ - gemfiles/rspec_3.1.gemfile
21
+ - gemfiles/rspec_3.2.gemfile
data/Appraisals ADDED
@@ -0,0 +1,33 @@
1
+ appraise 'activerecord-3.1' do
2
+ gem 'activerecord', '~> 3.1'
3
+ end
4
+
5
+ appraise 'activerecord-3.2' do
6
+ gem 'activerecord', '~> 3.2'
7
+ end
8
+
9
+ appraise 'activerecord-4.0' do
10
+ gem 'activerecord', '~> 4.0'
11
+ end
12
+
13
+ appraise 'activerecord-4.1' do
14
+ gem 'activerecord', '~> 4.1'
15
+ end
16
+
17
+ appraise 'activerecord-4.2' do
18
+ gem 'activerecord', '~> 4.2'
19
+ end
20
+
21
+ appraise 'rspec-3.0' do
22
+ gem 'rspec', '~> 3.0'
23
+ end
24
+
25
+ appraise 'rspec-3.1' do
26
+ gem 'rspec', '~> 3.1'
27
+ end
28
+
29
+ appraise 'rspec-3.2' do
30
+ gem 'rspec', '~> 3.2'
31
+ end
32
+
33
+ appraise('default') {}
data/CHANGELOG.md CHANGED
@@ -1,6 +1,22 @@
1
1
  # Schema Expectations Changelog
2
2
 
3
- # git master
3
+ ### git master
4
+
5
+ ### 0.2.0 (Febuary 18, 2015)
6
+
7
+ - support activerecord 3.1 to 4.2
8
+ - support rspec 3.0 to 3.2
9
+ - `validate_schema_nullable` #failure_message_when_negated works
10
+ - `validate_schema_nullable` #description works
11
+ - `validate_schema_nullable` supports belongs_to association validators
12
+ - `validate_schema_nullable` supports polymorphic belongs_to association validators
13
+ - `validate_schema_nullable` skips primary key and timestamps
14
+ - `validate_schema_nullable` is aware of columns with default values
15
+ - `validate_schema_nullable` is aware of columns with default functions
16
+ - postgres support
17
+ - mysql support
18
+
19
+ ### 0.0.1 (February 12, 2015)
4
20
 
5
21
  - `validate_schema_nullable` supports being called on AR instances
6
22
  - documented `validate_schema_nullable`
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
+ [![Gem Version](https://badge.fury.io/rb/schema_expectations.svg)](https://rubygems.org/gems/schema_expectations)
1
2
  [![Build Status](https://travis-ci.org/emma-borhanian/schema_expectations.svg?branch=master)](https://travis-ci.org/emma-borhanian/schema_expectations)
3
+ [![Code Climate](https://codeclimate.com/github/emma-borhanian/schema_expectations/badges/gpa.svg)](https://codeclimate.com/github/emma-borhanian/schema_expectations)
4
+ [![Test Coverage](https://codeclimate.com/github/emma-borhanian/schema_expectations/badges/coverage.svg)](https://codeclimate.com/github/emma-borhanian/schema_expectations)
5
+ [![Dependency Status](https://gemnasium.com/emma-borhanian/schema_expectations.svg)](https://gemnasium.com/emma-borhanian/schema_expectations)
2
6
 
3
7
  # Work in progress
4
8
 
data/Rakefile CHANGED
@@ -10,3 +10,15 @@ begin
10
10
  rescue LoadError
11
11
  # no rspec available
12
12
  end
13
+
14
+ task :refresh do
15
+ require 'yaml'
16
+
17
+ `appraisal install`
18
+
19
+ travis_file = File.expand_path('../.travis.yml', __FILE__)
20
+ travis_config = YAML.load(File.read(travis_file))
21
+ travis_config['gemfile'] = Dir.glob("#{File.dirname(__FILE__)}/gemfiles/*.gemfile").
22
+ map { |path| "gemfiles/#{File.basename(path)}" }
23
+ File.open(travis_file, 'w') { |f| f.write YAML.dump(travis_config) }
24
+ end
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord", "~> 3.1"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord", "~> 3.2"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord", "~> 4.0"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord", "~> 4.1"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activerecord", "~> 4.2"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,5 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rspec", "~> 3.0"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rspec", "~> 3.1"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "rspec", "~> 3.2"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,92 @@
1
+ require 'active_support/core_ext/object/blank'
2
+
3
+ module SchemaExpectations
4
+ module ActiveRecord
5
+ class ColumnReflector # :nodoc:
6
+ def initialize(model, columns = nil)
7
+ @model = model
8
+ @columns = columns || model.columns
9
+ end
10
+
11
+ def column_names
12
+ @columns.map { |column| column.name.to_sym }
13
+ end
14
+
15
+ def not_null
16
+ new_with_columns @columns.reject(&:null)
17
+ end
18
+
19
+ def for_attributes(*attributes)
20
+ new_with_columns attributes_to_columns(*attributes)
21
+ end
22
+
23
+ def without_present_default
24
+ new_with_columns @columns.reject(&method(:present_default_column?))
25
+ end
26
+
27
+ private
28
+
29
+ def new_with_columns(columns)
30
+ ColumnReflector.new(@model, columns)
31
+ end
32
+
33
+ def attributes_to_columns(*attributes)
34
+ column_names = attributes.flat_map(&method(:attribute_to_column_names))
35
+ @columns.select do |column|
36
+ column_names.include? column.name.to_sym
37
+ end
38
+ end
39
+
40
+ def attribute_to_column_names(attribute)
41
+ association = @model.reflect_on_association(attribute)
42
+
43
+ if association && association.belongs_to? && association.options.key?(:polymorphic)
44
+ [association.foreign_key.to_sym, association.foreign_type.to_sym]
45
+ elsif association && association.belongs_to?
46
+ [association.foreign_key.to_sym]
47
+ else
48
+ [attribute]
49
+ end
50
+ end
51
+
52
+ def present_default_column?(column)
53
+ column.default.present? ||
54
+ primary_key?(column) ||
55
+ default_timestamp?(column) ||
56
+ default_function?(column)
57
+ end
58
+
59
+ def primary_key?(column)
60
+ column.name.to_s == @model.primary_key.to_s
61
+ end
62
+
63
+ def default_timestamp?(column)
64
+ @model.record_timestamps && all_timestamp_attributes.include?(column.name.to_sym)
65
+ end
66
+
67
+ def default_function?(column)
68
+ column.respond_to?(:default_function) &&
69
+ column.default_function &&
70
+ function_produces_present_value?(column.default_function)
71
+ end
72
+
73
+ def function_produces_present_value?(function)
74
+ query = "SELECT #{function}"
75
+ begin
76
+ result = @model.connection.execute query
77
+ result.first.values.first.present?
78
+ rescue => e
79
+ message = "SchemaExpectations: encountered error running #{query}"
80
+ message << "\n" << e.message
81
+ message << "\n" << e.backtrace.join('\n')
82
+ SchemaExpectations.error_logger.error message
83
+ false
84
+ end
85
+ end
86
+
87
+ def all_timestamp_attributes
88
+ @all_timestamp_attributes ||= Record.new.send(:all_timestamp_attributes).map(&:to_sym)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,59 @@
1
+ require 'schema_expectations/util'
2
+
3
+ module SchemaExpectations
4
+ module ActiveRecord
5
+ class ValidationReflector # :nodoc:
6
+ CONDITIONAL_OPTIONS = %i(on if unless allow_nil allow_blank)
7
+
8
+ def initialize(model, validators = nil)
9
+ @model = model
10
+ @validators = validators || model.validators
11
+ end
12
+
13
+ def attributes
14
+ @validators.flat_map(&:attributes).uniq
15
+ end
16
+
17
+ def conditions_for_attribute(attribute)
18
+ validators = validators_for_attribute(attribute)
19
+ validators -= validators_without_options CONDITIONAL_OPTIONS
20
+ Util.slice_hash(validators.first.options, *CONDITIONAL_OPTIONS) if validators.first
21
+ end
22
+
23
+ def presence
24
+ new_with_validators validators_with_kind :presence
25
+ end
26
+
27
+ def unconditional
28
+ new_with_validators validators_without_options CONDITIONAL_OPTIONS
29
+ end
30
+
31
+ private
32
+
33
+ def new_with_validators(validators)
34
+ ValidationReflector.new(@model, validators)
35
+ end
36
+
37
+ def validators_with_kind(kind)
38
+ @validators.select do |validator|
39
+ validator.kind == kind
40
+ end
41
+ end
42
+
43
+ def validators_without_options(options)
44
+ @validators.select do |validator|
45
+ options.all? do |option_key|
46
+ !validator.options[option_key] ||
47
+ Array(validator.options[option_key]).empty?
48
+ end
49
+ end
50
+ end
51
+
52
+ def validators_for_attribute(attribute)
53
+ @validators.select do |validator|
54
+ validator.attributes.include? attribute
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,25 @@
1
+ require 'logger'
2
+
3
+ module SchemaExpectations
4
+ def self.configure(&block)
5
+ @config.instance_eval(&block)
6
+ end
7
+
8
+ def self.error_logger
9
+ @config.error_logger
10
+ end
11
+
12
+ class Config
13
+ attr_accessor :error_logger
14
+
15
+ def initialize
16
+ reset!
17
+ end
18
+
19
+ def reset!
20
+ @error_logger = Logger.new($stderr)
21
+ end
22
+ end
23
+
24
+ @config = Config.new
25
+ end
@@ -1,8 +1,10 @@
1
1
  require 'rspec/expectations'
2
+ require 'schema_expectations/active_record/validation_reflector'
3
+ require 'schema_expectations/active_record/column_reflector'
2
4
 
3
5
  module SchemaExpectations
4
6
  module RSpecMatchers
5
- # The `validate_schema_nullable` matcher test that an ActiveRecord model
7
+ # The `validate_schema_nullable` matcher tests that an ActiveRecord model
6
8
  # has unconditional presence validation on columns with `NOT NULL` constraints,
7
9
  # and vice versa.
8
10
  #
@@ -30,7 +32,7 @@ module SchemaExpectations
30
32
  # it { should validate_schema_nullable.except(:name) }
31
33
  # end
32
34
  #
33
- # The `id` column is automatically skipped.
35
+ # The primary key and timestamp columns are automatically skipped.
34
36
  #
35
37
  # @return [ValidateSchemaNullableMatcher]
36
38
  def validate_schema_nullable
@@ -39,36 +41,40 @@ module SchemaExpectations
39
41
 
40
42
  class ValidateSchemaNullableMatcher
41
43
  def matches?(model)
42
- model = model.class if model.is_a?(ActiveRecord::Base)
43
- fail "#{model.inspect} does not inherit from ActiveRecord::Base" unless model.ancestors.include?(ActiveRecord::Base)
44
-
45
- @model = model
46
- @not_null_columns = filter_attributes(not_null_columns(model))
47
- @present_attributes = filter_attributes(present_attributes(model))
48
- @not_null_columns == @present_attributes
44
+ @model = cast_model model
45
+ @validation_reflector = ActiveRecord::ValidationReflector.new(@model)
46
+ @column_reflector = ActiveRecord::ColumnReflector.new(@model)
47
+ @not_null_column_names = filter_column_names(not_null_column_names).sort
48
+ @present_column_names = filter_column_names(present_column_names).sort
49
+ @not_null_column_names == @present_column_names
49
50
  end
50
51
 
51
52
  def failure_message
52
- @not_null_columns.sort!
53
- @present_attributes.sort!
54
-
55
53
  errors = []
56
54
 
57
- (@present_attributes - @not_null_columns).each do |attribute|
58
- errors << "#{attribute} has unconditional presence validation but is missing NOT NULL"
55
+ (@present_column_names - @not_null_column_names).each do |column_name|
56
+ errors << "#{column_name} has unconditional presence validation but is missing NOT NULL"
59
57
  end
60
58
 
61
- (@not_null_columns - @present_attributes).each do |attribute|
62
- if condition = validator_condition(@model, attribute)
63
- errors << "#{attribute} is NOT NULL but its presence validator was conditional: #{condition.inspect}"
59
+ (@not_null_column_names - @present_column_names).each do |column_name|
60
+ if conditions = validator_conditions_for_column_name(column_name)
61
+ errors << "#{column_name} is NOT NULL but its presence validator was conditional: #{conditions.inspect}"
64
62
  else
65
- errors << "#{attribute} is NOT NULL but has no presence validation"
63
+ errors << "#{column_name} is NOT NULL but has no presence validation"
66
64
  end
67
65
  end
68
66
 
69
67
  errors.join(', ')
70
68
  end
71
69
 
70
+ def failure_message_when_negated
71
+ 'should not match NOT NULL with its presence validation but does'
72
+ end
73
+
74
+ def description
75
+ 'validate NOT NULL columns are present'
76
+ end
77
+
72
78
  # Specifies a list of columns to restrict matcher
73
79
  #
74
80
  # @return [ValidateSchemaNullableMatcher] self
@@ -91,58 +97,43 @@ module SchemaExpectations
91
97
 
92
98
  private
93
99
 
94
- def presence_validators(model)
95
- presence_validators = model.validators.select do |validator|
96
- validator.kind == :presence
100
+ def cast_model(model)
101
+ model = model.class if model.is_a?(::ActiveRecord::Base)
102
+ unless model.is_a?(Class) && model.ancestors.include?(::ActiveRecord::Base)
103
+ fail "#{model.inspect} does not inherit from ActiveRecord::Base"
97
104
  end
105
+ model
98
106
  end
99
107
 
100
- def unconditional_presence_validators(model)
101
- presence_validators(model).select do |validator|
102
- keep = %i(on if unless).all? do |option_key|
103
- Array(validator.options[option_key]).empty?
104
- end
105
-
106
- keep && !validator.options[:allow_nil] && !validator.options[:allow_blank]
107
- end
108
+ def present_attributes
109
+ @validation_reflector.presence.unconditional.attributes
108
110
  end
109
111
 
110
- def present_attributes(model)
111
- present_attributes = unconditional_presence_validators(model).
112
- flat_map(&:attributes).uniq
113
- present_attributes &= model.columns.map(&:name).map(&:to_sym)
114
- present_attributes
112
+ def present_column_names
113
+ @column_reflector.for_attributes(*present_attributes).
114
+ without_present_default.column_names
115
115
  end
116
116
 
117
- def not_null_columns(model)
118
- model.columns.select { |column| !column.null }.map(&:name).map(&:to_sym)
117
+ def column_name_to_attribute(column_name)
118
+ @validation_reflector.attributes.detect do |attribute|
119
+ @column_reflector.for_attributes(attribute).column_names.
120
+ include? column_name
121
+ end
119
122
  end
120
123
 
121
- def filter_attributes(attributes)
122
- attributes &= @only if @only
123
- attributes -= @except if @except
124
- attributes -= [:id]
125
- attributes
124
+ def not_null_column_names
125
+ @column_reflector.not_null.
126
+ without_present_default.column_names
126
127
  end
127
128
 
128
- def validator_condition(model, attribute)
129
- validators = presence_validators(model).select do |validator|
130
- validator.attributes.include? attribute
131
- end
132
-
133
- validators.each do |validator|
134
- condition = [:on, :if, :unless].detect do |option_key|
135
- !Array(validator.options[option_key]).empty?
136
- end
137
-
138
- condition ||= [:allow_nil, :allow_blank].detect do |option_key|
139
- validator.options[option_key]
140
- end
141
-
142
- return { condition => validator.options[condition] } if condition
143
- end
129
+ def filter_column_names(column_names)
130
+ column_names &= @only if @only
131
+ column_names -= @except if @except
132
+ column_names
133
+ end
144
134
 
145
- nil
135
+ def validator_conditions_for_column_name(column_name)
136
+ @validation_reflector.conditions_for_attribute column_name_to_attribute column_name
146
137
  end
147
138
  end
148
139
  end
@@ -0,0 +1,9 @@
1
+ module SchemaExpectations
2
+ module Util # :nodoc:
3
+ def self.slice_hash(hash, *keys)
4
+ keys.each_with_object(hash.class.new) do |key, memo|
5
+ memo[key] = hash[key] if hash.has_key?(key)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module SchemaExpectations
2
- VERSION = '0.0.1'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require 'schema_expectations/version'
2
+ require 'schema_expectations/config'
2
3
 
3
4
  begin
4
5
  require 'rspec/core'
@@ -22,15 +22,24 @@ Gem::Specification.new do |gem|
22
22
 
23
23
  gem.required_ruby_version = '>= 2.0.0'
24
24
 
25
- gem.add_dependency 'activerecord', '~> 4.2'
25
+ gem.add_dependency 'activerecord', '>= 3.1', '< 4.3'
26
+ gem.add_dependency 'activesupport', '>= 3.1', '< 4.3'
27
+
28
+ # optional dependency
29
+ gem.add_development_dependency 'rspec', '>= 3.0', '< 3.3'
26
30
 
27
31
  gem.add_development_dependency 'pry'
28
32
  gem.add_development_dependency 'rake', '~> 10.4'
29
33
  gem.add_development_dependency 'yard', '~> 0.8.7'
30
34
 
31
35
  # tests
32
- gem.add_development_dependency 'codeclimate-test-reporter'
33
- gem.add_development_dependency 'rspec', '~> 3.2'
36
+ gem.add_development_dependency 'wwtd'
37
+ gem.add_development_dependency 'appraisal', '~> 1.0'
38
+ gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4', '>= 0.4.6'
39
+ gem.add_development_dependency 'simplecov'
34
40
  gem.add_development_dependency 'guard-rspec', '~> 4.5'
35
41
  gem.add_development_dependency 'sqlite3', '~> 1.3'
42
+ gem.add_development_dependency 'pg', '~> 0.18'
43
+ gem.add_development_dependency 'mysql2', '~> 0.3.18'
44
+ gem.add_development_dependency 'database_cleaner', '~> 1.4'
36
45
  end
@@ -0,0 +1,13 @@
1
+ sqlite3:
2
+ adapter: sqlite3
3
+ database: ':memory:'
4
+ postgresql:
5
+ adapter: postgresql
6
+ encoding: unicode
7
+ database: schema_expectations_test
8
+ username: postgres
9
+ mysql2:
10
+ adapter: mysql2
11
+ encoding: utf8
12
+ database: schema_expectations_test
13
+ username: root