Skip to content

Instantly share code, notes, and snippets.

@georgiybykov
Last active September 5, 2022 22:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save georgiybykov/c809cdcf35cc2a4e02146501697dbd26 to your computer and use it in GitHub Desktop.
Save georgiybykov/c809cdcf35cc2a4e02146501697dbd26 to your computer and use it in GitHub Desktop.
Eager Load configuration
# EagerLoad.configure.enabled = true
#
# EagerLoad.configure_for_environments do |env|
# env.development = false
# env.staging = true
# env.production = true
# end
#
# EagerLoad.enabled?
class EagerLoad
class << self
def config
@_config ||= Configuration.new
end
def configure
yield config if block_given?
config
end
alias configure_for_environments configure
def enabled?
return config.enabled if config.for_environments.empty?
validate_environment!(config.for_environments.keys)
config.for_environments.fetch($env, false)
end
def validate_environment!(envs)
raise Configuration::ConfigurationError.new unless envs.include?($env)
end
end
private_class_method :validate_environment!
class Configuration
attr_accessor :enabled
attr_accessor :env_config
alias for_environments env_config
def initialize
@enabled = false
@env_config = {}
end
private
def method_missing(symbol, arg)
if symbol.end_with?('=') && (arg.is_a?(TrueClass) || arg.is_a?(FalseClass))
env_config[symbol.to_s.chop.to_sym] = arg
else
raise ConfigurationError.new
end
end
def respond_to_missing?(_method_name, _include_private = false)
false
end
# move to common errors list
class ConfigurationError < StandardError
def initialize
super with_message
end
private
def with_message
<<~MSG
Eager load for environments is not configured correctly.
You need to specify a block with boolean values set to each
of your project environments. For example:
Resque::Railtie::EagerLoad.configure_for_environments do |env|
env.development = false
env.staging = true
env.production = true
end
MSG
end
end
end
end
module Environment
def self.set_global(env = :development)
$env = env
end
end
# rspec
require 'rspec/autorun'
RSpec.describe EagerLoad do
let(:error_message) do
<<~MSG
Eager load for environments is not configured correctly.
You need to specify a block with boolean values set to each
of your project environments. For example:
Resque::Railtie::EagerLoad.configure_for_environments do |env|
env.development = false
env.staging = true
env.production = true
end
MSG
end
describe '.enabled?' do
subject(:result) { described_class.enabled? }
let(:reset_config!) { EagerLoad.instance_variable_set(:@_config, nil) }
before do
reset_config!
Environment.set_global :development
end
context 'when configuration has not been set' do
it 'returns eager load config value set to false by default' do
expect(result).to eq(false)
end
end
context 'when configuration has been set for all environments' do
before { EagerLoad.configure.enabled = true }
it 'returns eager load config value' do
expect(result).to eq(true)
end
end
context 'when configuration has been set' do
before do
EagerLoad.configure_for_environments do |env|
env.development = false
env.staging = true
env.production = true
end
end
context 'and it is development environment' do
it { is_expected.to eq(false) }
end
context 'and it is staging environment' do
before { Environment.set_global :staging }
it { is_expected.to eq(true) }
end
context 'and it is production environment' do
before { Environment.set_global :production }
it { is_expected.to eq(true) }
end
end
context 'when invalid configuration has been set' do
before do
EagerLoad.configure_for_environments do |env|
env.invalid = true
end
end
it 'raises a ConfigurationError with the explanation ' do
expect { result }
.to raise_error(EagerLoad::Configuration::ConfigurationError, error_message)
end
end
end
context 'when the configuration value for environments is not correct' do
subject(:configure!) do
EagerLoad.configure_for_environments do |env|
env.development = 'invalid'
end
end
it 'raises a ConfigurationError with the explanation' do
expect { configure! }
.to raise_error(EagerLoad::Configuration::ConfigurationError, error_message)
end
end
end
# EagerLoad.configure.enabled = true
#
# EagerLoad.configure do |config|
# config.for_environments do |env|
# env.development = false
# env.staging = true
# env.production = true
# end
# end
#
# EagerLoad.enabled?
class EagerLoad
class << self
def config
@_config ||= Configuration.new
end
def configure
yield config if block_given?
config
end
def enabled?
return config.enabled if config.with_environments.empty?
validate_environment!(config.with_environments.keys)
config.with_environments.fetch($env, false)
end
def validate_environment!(envs)
raise Configuration::ForEnvironments::ConfigurationError.new unless envs.include?($env)
end
end
private_class_method :validate_environment!
class Configuration
attr_accessor :enabled
attr_reader :env_config
alias with_environments env_config
def initialize
@enabled = false
@env_config = {}
end
def for_environments
raise ForEnvironments::ConfigurationError.new unless block_given?
yield environments_config
@env_config = environments_config.env_config
end
def environments_config
@_environments_config ||= ForEnvironments.new
end
private :environments_config
class ForEnvironments
attr_reader :env_config
def initialize
@env_config = {}
end
private
def method_missing(symbol, arg)
if symbol.end_with?('=') && (arg.is_a?(TrueClass) || arg.is_a?(FalseClass))
env_config[symbol.to_s.chop.to_sym] = arg
else
raise ConfigurationError.new
end
end
def respond_to_missing?(_method_name, _include_private = false)
false
end
# move to common errors list
class ConfigurationError < StandardError
def initialize
super with_message
end
private
def with_message
<<~MSG
Eager load for environments is not configured correctly.
You need to specify a block with boolean values set to each
of your project environments. For example:
EagerLoad.configure do |config|
config.for_environments do |env|
env.development = false
env.staging = true
env.production = true
end
end
MSG
end
end
end
end
end
module Environment
def self.set_global(env = :development)
$env = env
end
end
# rspec
require 'rspec/autorun'
RSpec.describe EagerLoad do
let(:error_message) do
<<~MSG
Eager load for environments is not configured correctly.
You need to specify a block with boolean values set to each
of your project environments. For example:
EagerLoad.configure do |config|
config.for_environments do |env|
env.development = false
env.staging = true
env.production = true
end
end
MSG
end
describe '.enabled?' do
subject(:result) { described_class.enabled? }
let(:reset_config!) { EagerLoad.instance_variable_set(:@_config, nil) }
before do
reset_config!
Environment.set_global :development
end
context 'when configuration has not been set' do
it 'returns eager load config value set to false by default' do
expect(result).to eq(false)
end
end
context 'when one configuration value has been set for all environments' do
before { EagerLoad.configure.enabled = true }
it { is_expected.to eq(true) }
end
context 'when different configuration values has been set depends on environment' do
before do
EagerLoad.configure do |config|
config.for_environments do |env|
env.development = false
env.staging = true
env.production = true
end
end
end
context 'and the environment is development' do
it { is_expected.to eq(false) }
end
context 'and the environment is staging' do
before { Environment.set_global :staging }
it { is_expected.to eq(true) }
end
context 'and the environment is production' do
before { Environment.set_global :production }
it { is_expected.to eq(true) }
end
end
context 'when invalid configuration has been set' do
before do
EagerLoad.configure do |config|
config.for_environments do |env|
env.invalid = true
end
end
end
it 'raises a ConfigurationError with the explanation ' do
expect { result }
.to raise_error(
EagerLoad::Configuration::ForEnvironments::ConfigurationError,
error_message
)
end
end
end
context 'when the configuration for environments is not correct' do
context 'and the configuration block has not been passed' do
subject(:configure!) do
EagerLoad.configure { |config| config.for_environments }
end
it 'raises a ConfigurationError with the explanation ' do
expect { configure! }
.to raise_error(
EagerLoad::Configuration::ForEnvironments::ConfigurationError,
error_message
)
end
end
context 'and the configuration value for environment is not correct' do
subject(:configure!) do
EagerLoad.configure do |config|
config.for_environments do |env|
env.development = 'invalid_value'
end
end
end
it 'raises a ConfigurationError with the explanation ' do
expect { configure! }
.to raise_error(
EagerLoad::Configuration::ForEnvironments::ConfigurationError,
error_message
)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment