enum_kit 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +46 -0
- data/.rspec +2 -0
- data/.rubocop.yml +21 -0
- data/.travis.yml +13 -0
- data/Gemfile +5 -0
- data/Guardfile +17 -0
- data/LICENSE +21 -0
- data/README.md +82 -0
- data/Rakefile +8 -0
- data/bin/console +7 -0
- data/bin/setup +6 -0
- data/config.ru +9 -0
- data/enum_kit.gemspec +35 -0
- data/lib/enum_kit/active_record_extensions/connection_adapters/postgresql/column_dumper.rb +29 -0
- data/lib/enum_kit/active_record_extensions/connection_adapters/postgresql/schema_dumper.rb +29 -0
- data/lib/enum_kit/active_record_extensions/connection_adapters/postgresql_adapter.rb +74 -0
- data/lib/enum_kit/active_record_extensions/migration/command_recorder.rb +45 -0
- data/lib/enum_kit/active_record_extensions/schema_dumper.rb +31 -0
- data/lib/enum_kit/active_record_patches/connection_adapters/postgresql/column_methods.rb +32 -0
- data/lib/enum_kit/active_record_patches/connection_adapters/postgresql/oid/enum.rb +32 -0
- data/lib/enum_kit/active_record_patches/connection_adapters/postgresql/oid/type_map_initializer.rb +27 -0
- data/lib/enum_kit/active_record_patches/enum/enum_type.rb +25 -0
- data/lib/enum_kit/active_record_patches/enum.rb +39 -0
- data/lib/enum_kit/active_record_patches/validations/pg_enum_validator.rb +31 -0
- data/lib/enum_kit/constants.rb +7 -0
- data/lib/enum_kit/helpers.rb +84 -0
- data/lib/enum_kit.rb +62 -0
- data/spec/active_record/base_spec.rb +15 -0
- data/spec/active_record/connection_adapters/postgresql_adapter_spec.rb +62 -0
- data/spec/active_record/validations/pg_enum_validator_spec.rb +19 -0
- data/spec/enum_kit/constants_spec.rb +11 -0
- data/spec/enum_kit/helpers_spec.rb +106 -0
- data/spec/internal/app/models/shirt.rb +7 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/db/schema.rb +10 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/spec_helper.rb +96 -0
- metadata +231 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nodoc:
|
4
|
+
#
|
5
|
+
module ActiveRecord
|
6
|
+
# :nodoc:
|
7
|
+
#
|
8
|
+
module Validations
|
9
|
+
# Validates whether an enum's value is acceptable by comparing with the acceptable values defined in the PostgreSQL
|
10
|
+
# database.
|
11
|
+
#
|
12
|
+
class PgEnumValidator < ActiveModel::EachValidator
|
13
|
+
# Validate the given value is acceptable for the enum.
|
14
|
+
#
|
15
|
+
# @param record [ActiveRecord::Base] The record being validated.
|
16
|
+
# @param attribute [Symbol] The enum attribute being validated.
|
17
|
+
# @param value [String, Symbol, nil] The current value of the enum.
|
18
|
+
#
|
19
|
+
def validate_each(record, attribute, value)
|
20
|
+
values = record.class.pg_enum_values(attribute)
|
21
|
+
|
22
|
+
return if values.include?(value)
|
23
|
+
|
24
|
+
record.errors.add(attribute, options[:message] || :invalid, **options.except(:message).merge!(
|
25
|
+
attribute: record.class.human_attribute_name(attribute),
|
26
|
+
values: values.join(', ')
|
27
|
+
))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EnumKit
|
4
|
+
# Makes an underscored, lowercase form from the expression in the string.
|
5
|
+
#
|
6
|
+
# Changes '::' to '/' to convert namespaces to paths.
|
7
|
+
# This method is based on the `ActiveSupport::Inflector.underscore` method.
|
8
|
+
#
|
9
|
+
# @param value [String] A value to transform.
|
10
|
+
# @return [String] The underscored, lowercase form of the expression.
|
11
|
+
#
|
12
|
+
def self.underscore(value)
|
13
|
+
return value unless /[A-Z-]|::/.match?(value)
|
14
|
+
|
15
|
+
value = value.to_s.gsub('::', '/')
|
16
|
+
value.gsub!('PostgreSQL', 'Postgresql')
|
17
|
+
value.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
18
|
+
value.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
19
|
+
value.tr!('-', '_')
|
20
|
+
value.downcase!
|
21
|
+
value
|
22
|
+
end
|
23
|
+
|
24
|
+
# Convert a value into a String that can be used in SQL.
|
25
|
+
#
|
26
|
+
# @param value [Array|String|Symbol] A value to convert into SQL format.
|
27
|
+
# @return [String] The SQL representation of the value.
|
28
|
+
#
|
29
|
+
def self.sqlize(value)
|
30
|
+
case value
|
31
|
+
when Array
|
32
|
+
'(' + value.map { |v| sqlize(v) }.join(', ') + ')'
|
33
|
+
when String
|
34
|
+
ActiveRecord::Base.connection.quote(value)
|
35
|
+
when Symbol
|
36
|
+
sqlize(value.to_s)
|
37
|
+
else
|
38
|
+
raise ArgumentError, "Unable to convert value of type #{value.class} into SQL format."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Sanitize the name of the enum.
|
43
|
+
#
|
44
|
+
# @param name [String|Symbol] An enum name.
|
45
|
+
# @return [String] The sanitized name.
|
46
|
+
#
|
47
|
+
def self.sanitize_name!(name)
|
48
|
+
raise ArgumentError, 'Enum names must be a String or a Symbol.' unless name.is_a?(String) || name.is_a?(Symbol)
|
49
|
+
|
50
|
+
name = name.to_s
|
51
|
+
|
52
|
+
return name if name =~ /^[a-z0-9_]+$/
|
53
|
+
|
54
|
+
raise ArgumentError, 'Enum names may contain only lowercase letters, numbers and underscores.'
|
55
|
+
end
|
56
|
+
|
57
|
+
# Sanitize a single value of an enum.
|
58
|
+
#
|
59
|
+
# @param value [String|Symbol] An enum value.
|
60
|
+
# @return [Array] The sanitized value.
|
61
|
+
#
|
62
|
+
def self.sanitize_value!(value)
|
63
|
+
raise ArgumentError, 'Enum values must be a String or a Symbol.' unless value.is_a?(String) || value.is_a?(Symbol)
|
64
|
+
|
65
|
+
value = value.to_s
|
66
|
+
|
67
|
+
return value if value =~ /^[a-z0-9_ ]+$/
|
68
|
+
|
69
|
+
raise ArgumentError, 'Enum values may contain only lowercase letters, numbers, underscores and spaces.'
|
70
|
+
end
|
71
|
+
|
72
|
+
# Sanitize the values of an enum.
|
73
|
+
#
|
74
|
+
# @param values [Array] An Array of String or Symbol values.
|
75
|
+
# @return [Array] A sanitized Array of String values.
|
76
|
+
#
|
77
|
+
def self.sanitize_values!(values)
|
78
|
+
return nil if values.nil?
|
79
|
+
|
80
|
+
raise ArgumentError, 'Enum values must be an Array of String and/or Symbol objects.' unless values.is_a?(Array)
|
81
|
+
|
82
|
+
values.map { |value| sanitize_value!(value) }
|
83
|
+
end
|
84
|
+
end
|
data/lib/enum_kit.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'enum_kit/constants'
|
4
|
+
require 'enum_kit/helpers'
|
5
|
+
|
6
|
+
# Used as a namespace to encapsulate the logic for the EnumKit gem.
|
7
|
+
#
|
8
|
+
module EnumKit
|
9
|
+
# Queue loading of the patches/extensions and database type registration for when `ActiveRecord` has loaded.
|
10
|
+
#
|
11
|
+
def self.load!
|
12
|
+
require 'active_record'
|
13
|
+
require 'active_record/connection_adapters/postgresql_adapter'
|
14
|
+
require 'active_support/lazy_load_hooks'
|
15
|
+
|
16
|
+
ActiveSupport.on_load(:active_record) do
|
17
|
+
EnumKit.load_patches!
|
18
|
+
EnumKit.load_extensions!
|
19
|
+
EnumKit.register_database_type!
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Load the `ActiveRecord` monkey patches.
|
24
|
+
#
|
25
|
+
def self.load_patches!
|
26
|
+
require 'enum_kit/active_record_patches/connection_adapters/postgresql/column_methods'
|
27
|
+
require 'enum_kit/active_record_patches/connection_adapters/postgresql/oid/enum'
|
28
|
+
require 'enum_kit/active_record_patches/connection_adapters/postgresql/oid/type_map_initializer'
|
29
|
+
require 'enum_kit/active_record_patches/enum'
|
30
|
+
require 'enum_kit/active_record_patches/enum/enum_type'
|
31
|
+
require 'enum_kit/active_record_patches/validations/pg_enum_validator'
|
32
|
+
end
|
33
|
+
|
34
|
+
# Load the `ActiveRecord` extensions.
|
35
|
+
#
|
36
|
+
def self.load_extensions!
|
37
|
+
%w[
|
38
|
+
ConnectionAdapters::PostgreSQL::ColumnDumper
|
39
|
+
ConnectionAdapters::PostgreSQL::SchemaDumper
|
40
|
+
ConnectionAdapters::PostgreSQLAdapter
|
41
|
+
Migration::CommandRecorder
|
42
|
+
SchemaDumper
|
43
|
+
].each do |extension|
|
44
|
+
next unless Object.const_defined?("ActiveRecord::#{extension}")
|
45
|
+
|
46
|
+
require File.join('enum_kit', 'active_record_extensions', EnumKit.underscore(extension))
|
47
|
+
|
48
|
+
target_constant = Object.const_get("ActiveRecord::#{extension}")
|
49
|
+
extension_constant = Object.const_get("EnumKit::ActiveRecordExtensions::#{extension}")
|
50
|
+
|
51
|
+
target_constant.prepend(extension_constant)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Register `:enum` as a native database type.
|
56
|
+
#
|
57
|
+
def self.register_database_type!
|
58
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:enum] = { name: 'enum' }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
EnumKit.load!
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe ActiveRecord::Base do
|
4
|
+
describe '.pg_enum' do
|
5
|
+
it 'is defined' do
|
6
|
+
expect(described_class).to respond_to(:pg_enum)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '.pg_enum_values' do
|
11
|
+
it 'is defined' do
|
12
|
+
expect(described_class).to respond_to(:pg_enum_values)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe ActiveRecord::ConnectionAdapters::PostgreSQLAdapter do
|
4
|
+
subject(:connection) { ActiveRecord::Base.connection }
|
5
|
+
|
6
|
+
describe '#create_enum' do
|
7
|
+
after { connection.execute 'DROP TYPE IF EXISTS an_enum' }
|
8
|
+
|
9
|
+
it 'is defined' do
|
10
|
+
expect(connection).to respond_to(:create_enum)
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when called with valid arguments' do
|
14
|
+
subject { connection.create_enum(:an_enum, [:first_value, 'second value']) }
|
15
|
+
|
16
|
+
it 'creates an enum' do
|
17
|
+
expect(subject.result_status).to eq(PG::PGRES_COMMAND_OK)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when called with a malformed name' do
|
22
|
+
subject { connection.create_enum('an enum', [:first_value, 'second value']) }
|
23
|
+
|
24
|
+
it 'raises an ArgumentError' do
|
25
|
+
expect { subject }.to raise_exception(ArgumentError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when called with malformed values' do
|
30
|
+
subject { connection.create_enum(:an_enum, [:good_value, 'bad$value']) }
|
31
|
+
|
32
|
+
it 'raises an ArgumentError' do
|
33
|
+
expect { subject }.to raise_exception(ArgumentError)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#drop_enum' do
|
39
|
+
before { connection.execute "CREATE TYPE an_enum AS ENUM ('first', 'second')" }
|
40
|
+
after { connection.execute 'DROP TYPE IF EXISTS an_enum' }
|
41
|
+
|
42
|
+
it 'is defined' do
|
43
|
+
expect(connection).to respond_to(:drop_enum)
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when called with an existing enum' do
|
47
|
+
subject { connection.drop_enum(:an_enum) }
|
48
|
+
|
49
|
+
it 'drops the enum' do
|
50
|
+
expect(subject.result_status).to eq(PG::PGRES_COMMAND_OK)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when called with a non-existent enum' do
|
55
|
+
subject { connection.drop_enum(:non_existent_enum) }
|
56
|
+
|
57
|
+
it 'raises ActiveRecord::StatementInvalid' do
|
58
|
+
expect { subject }.to raise_exception(ActiveRecord::StatementInvalid)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe ActiveRecord::Validations::PgEnumValidator do
|
4
|
+
subject { Shirt.create(name: 'Plain Shirt', size: :small) }
|
5
|
+
|
6
|
+
it 'permits known values' do
|
7
|
+
expect { subject.update!(size: :large) }.not_to raise_exception
|
8
|
+
expect { subject.update!(size: :medium) }.not_to raise_exception
|
9
|
+
expect { subject.update!(size: :small) }.not_to raise_exception
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'rejects unknown values' do
|
13
|
+
expect { subject.update!(size: :other) }.to raise_exception(ActiveRecord::RecordInvalid)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'rejects nil values' do
|
17
|
+
expect { subject.update!(size: nil) }.to raise_exception(ActiveRecord::RecordInvalid)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe EnumKit do
|
4
|
+
describe '.underscore' do
|
5
|
+
it 'converts camel case into snake case' do
|
6
|
+
expect(described_class.underscore('EnumKit')).to eq('enum_kit')
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'converts namespaces into paths' do
|
10
|
+
expect(described_class.underscore('EnumKit::Example')).to eq('enum_kit/example')
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'treats PostgreSQL as an acronym' do
|
14
|
+
expect(described_class.underscore('PostgreSQL')).to eq('postgresql')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.sqlize' do
|
19
|
+
context 'with a String' do
|
20
|
+
subject { described_class.sqlize('value') }
|
21
|
+
|
22
|
+
it 'returns a quoted String' do
|
23
|
+
expect(subject).to eq("'value'")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with a Symbol' do
|
28
|
+
subject { described_class.sqlize(:value) }
|
29
|
+
|
30
|
+
it 'returns a quoted String' do
|
31
|
+
expect(subject).to eq("'value'")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with an Array' do
|
36
|
+
subject { described_class.sqlize(%i[one two three]) }
|
37
|
+
|
38
|
+
it 'returns a SQL array representation' do
|
39
|
+
expect(subject).to eq("('one', 'two', 'three')")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.sanitize_name!' do
|
45
|
+
it 'permits lowercase letters' do
|
46
|
+
expect(described_class.sanitize_name!('abc')).to eq('abc')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'permits numbers' do
|
50
|
+
expect(described_class.sanitize_name!('123')).to eq('123')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'permits underscores' do
|
54
|
+
expect(described_class.sanitize_name!('_')).to eq('_')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'rejects hyphens' do
|
58
|
+
expect { described_class.sanitize_name!('-') }.to raise_exception(ArgumentError)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'rejects spaces' do
|
62
|
+
expect { described_class.sanitize_name!(' ') }.to raise_exception(ArgumentError)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'rejects uppercase letters' do
|
66
|
+
expect { described_class.sanitize_name!('ABC') }.to raise_exception(ArgumentError)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '.sanitize_value!' do
|
71
|
+
it 'permits lowercase letters' do
|
72
|
+
expect(described_class.sanitize_value!('abc')).to eq('abc')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'permits numbers' do
|
76
|
+
expect(described_class.sanitize_value!('123')).to eq('123')
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'permits spaces' do
|
80
|
+
expect(described_class.sanitize_value!(' ')).to eq(' ')
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'permits underscores' do
|
84
|
+
expect(described_class.sanitize_value!('_')).to eq('_')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'rejects hyphens' do
|
88
|
+
expect { described_class.sanitize_value!('-') }.to raise_exception(ArgumentError)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'rejects uppercase letters' do
|
92
|
+
expect { described_class.sanitize_value!('ABC') }.to raise_exception(ArgumentError)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '.sanitize_values!' do
|
97
|
+
subject { described_class.sanitize_values!(%i[one two three]) }
|
98
|
+
|
99
|
+
it 'calls .sanitize_value! for each of the inputs' do
|
100
|
+
expect(described_class).to receive(:sanitize_value!).with(:one).once
|
101
|
+
expect(described_class).to receive(:sanitize_value!).with(:two).once
|
102
|
+
expect(described_class).to receive(:sanitize_value!).with(:three).once
|
103
|
+
subject
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
*.log
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Conventionally, all specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
4
|
+
# The `.rspec` file contains `--require spec_helper` which will cause this file to always be loaded,
|
5
|
+
# without a need to explicitly require it in any files.
|
6
|
+
#
|
7
|
+
# Given that it is always loaded, you are encouraged to keep this file as light-weight as possible.
|
8
|
+
# Requiring heavyweight dependencies from this file will add to the boot time of your test suite on EVERY test run,
|
9
|
+
# even for an individual file that may not need all of that loaded. Instead, consider making a separate helper file
|
10
|
+
# that requires the additional dependencies and performs the additional setup, and require it from the spec files
|
11
|
+
# that actually need it.
|
12
|
+
#
|
13
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
14
|
+
|
15
|
+
# Bundler
|
16
|
+
require 'bundler'
|
17
|
+
|
18
|
+
Bundler.require :default, :test
|
19
|
+
|
20
|
+
# Combustion
|
21
|
+
require 'combustion'
|
22
|
+
|
23
|
+
Combustion.initialize! :active_record
|
24
|
+
|
25
|
+
# Rails
|
26
|
+
require 'rspec/rails'
|
27
|
+
|
28
|
+
# RSpec
|
29
|
+
RSpec.configure do |config|
|
30
|
+
# rspec-expectations config goes here. You can use an alternate assertion/expectation library such as wrong or the
|
31
|
+
# stdlib/minitest assertions if you prefer.
|
32
|
+
config.expect_with :rspec do |expectations|
|
33
|
+
# This option will default to `true` in RSpec 4.
|
34
|
+
# It makes the `description` and `failure_message` of custom matchers include text for helper methods defined using
|
35
|
+
# `chain`, e.g.:
|
36
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
37
|
+
# # => "be bigger than 2 and smaller than 4"
|
38
|
+
# ...rather than:
|
39
|
+
# # => "be bigger than 2"
|
40
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
41
|
+
end
|
42
|
+
|
43
|
+
# rspec-mocks config goes here. You can use an alternate test double library (such as bogus or mocha) by changing the
|
44
|
+
# `mock_with` option here.
|
45
|
+
config.mock_with :rspec do |mocks|
|
46
|
+
# Prevents you from mocking or stubbing a method that does not exist on a real object.
|
47
|
+
# This is generally recommended, and will default to `true` in RSpec 4.
|
48
|
+
mocks.verify_partial_doubles = true
|
49
|
+
end
|
50
|
+
|
51
|
+
# This option will default to `:apply_to_host_groups` in RSpec 4 (and will have no way to turn it off -- the option
|
52
|
+
# exists only for backwards compatibility in RSpec 3).
|
53
|
+
# It causes shared context metadata to be inherited by the metadata hash of host groups and examples, rather than
|
54
|
+
# triggering implicit auto-inclusion in groups with matching metadata.
|
55
|
+
config.shared_context_metadata_behavior = :apply_to_host_groups
|
56
|
+
|
57
|
+
# This allows you to limit a spec run to individual examples or groups you care about by tagging them with `:focus`
|
58
|
+
# metadata. When nothing is tagged with `:focus`, all examples get run.
|
59
|
+
# RSpec also provides aliases for `it`, `describe`, and `context` that include `:focus` metadata: `fit`, `fdescribe`
|
60
|
+
# and `fcontext`, respectively.
|
61
|
+
config.filter_run_when_matching :focus
|
62
|
+
|
63
|
+
# Allows RSpec to persist some state between runs in order to support the `--only-failures` and `--next-failure` CLI
|
64
|
+
# options. We recommend you configure your source control system to ignore this file.
|
65
|
+
config.example_status_persistence_file_path = 'spec/examples.txt'
|
66
|
+
|
67
|
+
# Limits the available syntax to the non-monkey patched syntax that is recommended. For more details, see:
|
68
|
+
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
69
|
+
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
70
|
+
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
71
|
+
config.disable_monkey_patching!
|
72
|
+
|
73
|
+
# Many RSpec users commonly either run the entire suite or an individual file, and it's useful to allow more verbose
|
74
|
+
# output when running an individual spec file.
|
75
|
+
if config.files_to_run.one?
|
76
|
+
# Use the documentation formatter for detailed output, unless a formatter has already been configured (e.g. via a
|
77
|
+
# command-line flag).
|
78
|
+
config.default_formatter = 'doc'
|
79
|
+
end
|
80
|
+
|
81
|
+
# Print the 10 slowest examples and example groups at the end of the spec run, to help surface which specs are
|
82
|
+
# running particularly slow.
|
83
|
+
# config.profile_examples = 10
|
84
|
+
|
85
|
+
# Run specs in random order to surface order dependencies. If you find an order dependency and want to debug it, you
|
86
|
+
# can fix the order by providing the seed, which is printed after each run.
|
87
|
+
# --seed 1234
|
88
|
+
config.order = :random
|
89
|
+
|
90
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
91
|
+
# Setting this allows you to use `--seed` to deterministically reproduce test failures related to randomization by
|
92
|
+
# passing the same `--seed` value as the one that triggered the failure.
|
93
|
+
Kernel.srand config.seed
|
94
|
+
end
|
95
|
+
|
96
|
+
Dir[File.expand_path('support/**/*.rb', __dir__)].each { |path| require(path) }
|