spicerack 0.16.3 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/spicerack/configurable.rb +23 -1
- data/lib/spicerack/configurable/config_builder.rb +17 -5
- data/lib/spicerack/configurable/config_delegation.rb +47 -0
- data/lib/spicerack/configurable/config_object.rb +63 -0
- data/lib/spicerack/configurable/evaluator.rb +22 -0
- data/lib/spicerack/configurable/reader.rb +15 -2
- data/lib/spicerack/objects/defaults.rb +3 -1
- data/lib/spicerack/rspec/configurable/dsl.rb +62 -0
- data/lib/spicerack/rspec/configurable/matchers.rb +13 -0
- data/lib/spicerack/rspec/configurable/matchers/define_config_option.rb +43 -0
- data/lib/spicerack/rspec/configurable/spec_helper.rb +9 -0
- data/lib/spicerack/rspec/custom_matchers.rb +0 -1
- data/lib/spicerack/spec_helper.rb +2 -0
- data/lib/spicerack/version.rb +1 -1
- metadata +27 -21
- data/lib/spicerack/rspec/custom_matchers/define_config_option.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c92116412b94f90920f84dd05d8419d0bc7a4c2ffa3b33482ee6b53e32ad2032
|
4
|
+
data.tar.gz: 432943870f985ad4301e95b7f40bf936696c73d3f7d60eefaea27f85fb20bbe6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cccd7de009826d22e34d5de0534ac5d7543e7873db5e72e6c2951814b56089d4dc30ec47076fc91bc40b6329c0c99d97a6f061426dbb6b031c6e80ec3ae3093
|
7
|
+
data.tar.gz: bad53b799446ca49f068ca3931be811d225b1681d3b141de3bbd21dd314c49ffc61d4f5d1ef48c7ac6e36a7394abd2c475958db8033bd06bdacadaaa885b81c5
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "configurable/config_builder"
|
4
|
+
require_relative "configurable/config_delegation"
|
5
|
+
require_relative "configurable/config_object"
|
6
|
+
require_relative "configurable/evaluator"
|
4
7
|
require_relative "configurable/reader"
|
5
8
|
|
6
9
|
# NOTE: This is still a pre-release feature! Use at your own risk - it may change before being released.
|
@@ -16,6 +19,12 @@ require_relative "configurable/reader"
|
|
16
19
|
# configuration_options do
|
17
20
|
# option :some_config_option
|
18
21
|
# option :some_option_with_a_default, default: "I probably know what's best"
|
22
|
+
#
|
23
|
+
# nested :whats_behind do
|
24
|
+
# option :door_one, default: "It's a goat"
|
25
|
+
# option :door_two, default: "Another goat"
|
26
|
+
# option :door_three, default: "It's a car!"
|
27
|
+
# end
|
19
28
|
# end
|
20
29
|
# end
|
21
30
|
# end
|
@@ -24,14 +33,27 @@ require_relative "configurable/reader"
|
|
24
33
|
# SomeGem::Configuration.configure do |config|
|
25
34
|
# config.some_config_option = 12345
|
26
35
|
# config.some_option_with_a_default = "Nope, you really don't"
|
36
|
+
#
|
37
|
+
# config.whats_behind do |nested|
|
38
|
+
# nested.door_one = "It's a boat!"
|
39
|
+
# nested.door_three = "The teletubbies on repeat 😱"
|
40
|
+
# end
|
27
41
|
# end
|
28
42
|
#
|
29
43
|
# # Then, back in your gem code:
|
30
44
|
# puts Configuration.config.some_config_option
|
31
45
|
# => 12345
|
46
|
+
# puts Configuration.config.whats_behind.door_one
|
47
|
+
# => "It's a boat!"
|
48
|
+
#
|
49
|
+
# # Or, if you want to select dynamically:
|
50
|
+
# doors = %i[door_one door_two door_three]
|
51
|
+
# Configuration.config.config_eval(whats_behind, doors.sample).read
|
52
|
+
# => "The teletubbies on repeat 😱"
|
53
|
+
#
|
32
54
|
module Spicerack
|
33
55
|
module Configurable
|
34
|
-
delegate :configure, to: :_config_builder
|
56
|
+
delegate :configure, :config_eval, to: :_config_builder
|
35
57
|
|
36
58
|
def config
|
37
59
|
_config_builder.reader
|
@@ -3,27 +3,39 @@
|
|
3
3
|
module Spicerack
|
4
4
|
module Configurable
|
5
5
|
class ConfigBuilder
|
6
|
+
delegate :config_eval, to: :reader
|
7
|
+
|
6
8
|
def reader
|
7
9
|
@reader ||= Reader.new(configuration)
|
8
10
|
end
|
9
11
|
|
10
12
|
def configure
|
11
|
-
|
13
|
+
mutex.synchronize do
|
14
|
+
yield configuration
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
# NOTE: options must be set up before {#configure} is called
|
15
|
-
def option(*args)
|
16
|
-
config_class.__send__(:option, *args)
|
19
|
+
def option(*args, &block)
|
20
|
+
config_class.__send__(:option, *args, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def nested(*args, &block)
|
24
|
+
config_class.__send__(:nested, *args, &block)
|
17
25
|
end
|
18
26
|
|
19
27
|
private
|
20
28
|
|
21
29
|
def configuration
|
22
|
-
|
30
|
+
config_class.instance
|
23
31
|
end
|
24
32
|
|
25
33
|
def config_class
|
26
|
-
@config_class ||= Class.new(
|
34
|
+
@config_class ||= Class.new(ConfigObject)
|
35
|
+
end
|
36
|
+
|
37
|
+
def mutex
|
38
|
+
@mutex = Mutex.new
|
27
39
|
end
|
28
40
|
end
|
29
41
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Spicerack
|
6
|
+
module Configurable
|
7
|
+
module ConfigDelegation
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
DEFAULT_CONFIGURATION_MODULE_NAME = "Configuration"
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
delegate :config, :configure, to: :_configuration_module
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# Sets up delegation from a top-level class to a nested Configuration module.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# class SomeClass
|
21
|
+
# include Spicerack::Configurable::ConfigDelegation
|
22
|
+
#
|
23
|
+
# delegates_to_configuration
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# module SomeClass::Configuration
|
27
|
+
# include Spicerack::Configurable
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# SomeClass.config
|
31
|
+
# => returns SomeClass::Configuration.config
|
32
|
+
# SomeClass.configure do { |config| # config is the yielded config object from SomeClass::Configuration.configure }
|
33
|
+
#
|
34
|
+
# @param config_class [Spicerack::Configurable] A module that extends Spicerack::Configurable. Defaults to the module +YourGem::Configuration+
|
35
|
+
def delegates_to_configuration(config_class = nil)
|
36
|
+
@_configuration_module = config_class || "#{self}::#{DEFAULT_CONFIGURATION_MODULE_NAME}".constantize
|
37
|
+
end
|
38
|
+
|
39
|
+
def _configuration_module
|
40
|
+
raise NoMethodError, "Configuration not set up for #{self}. Did you forget to call delegates_to_configuration?" if @_configuration_module.nil?
|
41
|
+
|
42
|
+
@_configuration_module
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spicerack
|
4
|
+
module Configurable
|
5
|
+
class ConfigObject < InputObject
|
6
|
+
include Singleton
|
7
|
+
include ActiveModel::AttributeAssignment
|
8
|
+
|
9
|
+
alias_method :assign, :assign_attributes
|
10
|
+
|
11
|
+
RESERVED_WORDS = %i[config_eval].freeze
|
12
|
+
|
13
|
+
class_attribute :_nested_options, instance_writer: false, default: []
|
14
|
+
class_attribute :_nested_builders, instance_writer: false, default: {}
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def name
|
18
|
+
super.presence || "#{superclass}:0x#{object_id.to_s(16)}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def inspect
|
22
|
+
"#<#{name}>"
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def option(name, *)
|
28
|
+
_ensure_safe_option_name(name)
|
29
|
+
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def nested(namespace, &block)
|
34
|
+
_ensure_safe_option_name(namespace)
|
35
|
+
|
36
|
+
nested_config_builder_for(namespace).tap do |builder|
|
37
|
+
builder.instance_exec(&block)
|
38
|
+
|
39
|
+
_nested_options << namespace.to_sym
|
40
|
+
define_method(namespace) { builder.__send__ :configuration }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def nested_config_builder_for(namespace)
|
45
|
+
_nested_builders[namespace.to_sym] ||= ConfigBuilder.new
|
46
|
+
end
|
47
|
+
|
48
|
+
def _ensure_safe_option_name(name)
|
49
|
+
raise ArgumentError, "#{name.inspect} is reserved and cannot be used at a config option" if name.to_sym.in? RESERVED_WORDS
|
50
|
+
raise ArgumentError, "#{name.inspect} is already in use" if _nested_options.include?(name.to_sym)
|
51
|
+
|
52
|
+
puts "Warning: the config option #{name} is already defined" if _options.include?(name.to_sym) # rubocop:disable Rails/Output
|
53
|
+
end
|
54
|
+
|
55
|
+
def inherited(base)
|
56
|
+
base._nested_options = _nested_options.dup
|
57
|
+
base._nested_builders = _nested_builders.dup
|
58
|
+
super
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spicerack
|
4
|
+
module Configurable
|
5
|
+
class Evaluator
|
6
|
+
# @param path [Array<Symbol, String>] A message path for the desired config
|
7
|
+
# @param configuration [Spicerack::Configurable::Reader]
|
8
|
+
def initialize(path, configuration)
|
9
|
+
@path = path
|
10
|
+
@configuration = configuration
|
11
|
+
end
|
12
|
+
|
13
|
+
def read
|
14
|
+
path.inject(configuration, &:public_send)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :path, :configuration
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -7,18 +7,31 @@ module Spicerack
|
|
7
7
|
@config = config
|
8
8
|
end
|
9
9
|
|
10
|
+
def config_eval(*path)
|
11
|
+
Evaluator.new(path, self)
|
12
|
+
end
|
13
|
+
|
10
14
|
private
|
11
15
|
|
12
16
|
attr_reader :config
|
13
17
|
|
14
18
|
def method_missing(method_name, *)
|
15
|
-
|
19
|
+
name = method_name.to_sym
|
20
|
+
|
21
|
+
return mutex.synchronize { config.public_send(name) } if config._options.map(&:to_sym).include?(name)
|
22
|
+
return config._nested_builders[name].reader if config._nested_builders.key?(name)
|
16
23
|
|
17
24
|
super
|
18
25
|
end
|
19
26
|
|
20
27
|
def respond_to_missing?(method_name, *)
|
21
|
-
config._options.map(&:to_sym).include?(method_name.to_sym) ||
|
28
|
+
config._options.map(&:to_sym).include?(method_name.to_sym) ||
|
29
|
+
config._nested_builders.key?(name) ||
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def mutex
|
34
|
+
@mutex ||= Mutex.new
|
22
35
|
end
|
23
36
|
end
|
24
37
|
end
|
@@ -25,12 +25,14 @@ module Spicerack
|
|
25
25
|
end
|
26
26
|
|
27
27
|
class Value
|
28
|
+
include Tablesalt::Isolation
|
29
|
+
|
28
30
|
def initialize(static: nil, &block)
|
29
31
|
@value = (static.nil? && block_given?) ? block : static
|
30
32
|
end
|
31
33
|
|
32
34
|
def value
|
33
|
-
(@value.respond_to?(:call) ? instance_eval(&@value) : @value)
|
35
|
+
isolate(@value.respond_to?(:call) ? instance_eval(&@value) : @value)
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "matchers"
|
4
|
+
|
5
|
+
module Spicerack
|
6
|
+
module RSpec
|
7
|
+
module Configurable
|
8
|
+
module DSL
|
9
|
+
def nested_config_option(config_name, &block)
|
10
|
+
in_nested_config_stack(config_name) do |nested_stack|
|
11
|
+
describe(config_name.to_s, caller: caller) do
|
12
|
+
subject { nested_config }
|
13
|
+
|
14
|
+
let(:parent_config) { parent_config_for_nested(nested_stack) }
|
15
|
+
let(:nested_config) { parent_config.public_send(nested_stack.last) }
|
16
|
+
|
17
|
+
it "defines nested config object #{config_name}" do
|
18
|
+
expect(parent_config).to respond_to config_name
|
19
|
+
expect(parent_config._nested_options).to include config_name.to_sym
|
20
|
+
expect(parent_config.public_send(config_name)).to be_a Spicerack::Configurable::ConfigObject
|
21
|
+
end
|
22
|
+
|
23
|
+
instance_eval(&block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.included(base)
|
29
|
+
base.extend DSL
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def parent_config_for_nested(nested_stack)
|
36
|
+
@parent_config ||= {}
|
37
|
+
|
38
|
+
@parent_config[nested_stack] ||= described_class.
|
39
|
+
__send__(:_config_builder).
|
40
|
+
__send__(:configuration).
|
41
|
+
yield_self do |config|
|
42
|
+
nested_stack[0..-2].inject(config) do |conf, nested_name|
|
43
|
+
conf.public_send(nested_name)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def in_nested_config_stack(name)
|
49
|
+
_nested_config_stack << name.to_sym
|
50
|
+
|
51
|
+
yield _nested_config_stack.dup
|
52
|
+
|
53
|
+
_nested_config_stack.pop
|
54
|
+
end
|
55
|
+
|
56
|
+
def _nested_config_stack
|
57
|
+
Thread.current[:nested_config_stack] ||= []
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Spicerack
|
4
|
+
module RSpec
|
5
|
+
module Configurable
|
6
|
+
module Matchers
|
7
|
+
# RSpec matcher to test options of a Configurable class
|
8
|
+
#
|
9
|
+
# class ExampleConfiguration
|
10
|
+
# include Spicerack::Configurable
|
11
|
+
#
|
12
|
+
# option :foo
|
13
|
+
# option :bar, default: :baz
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# RSpec.describe ExampleConfiguration, type: :configuration do
|
17
|
+
# subject { described_class.new }
|
18
|
+
#
|
19
|
+
# it { is_expected.to define_config_option :foo }
|
20
|
+
# it { is_expected.to define_config_option :bar, default: :baz }
|
21
|
+
# end
|
22
|
+
define :define_config_option do |option, default: nil|
|
23
|
+
description { "define config option #{option}" }
|
24
|
+
failure_message { "expected #{subject} to define config option #{option} #{with_default(default)}".strip }
|
25
|
+
|
26
|
+
match do |obj|
|
27
|
+
if obj.is_a? Spicerack::Configurable::ConfigObject
|
28
|
+
expect(obj).to define_option option, default: default
|
29
|
+
else
|
30
|
+
expect(obj).to respond_to :config
|
31
|
+
expect(obj.config.instance_variable_get(:@config)).to be_present
|
32
|
+
expect(obj.config.instance_variable_get(:@config)).to define_option option, default: default
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def with_default(default)
|
37
|
+
"with default #{default}" unless default.nil?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "matchers"
|
4
|
+
require_relative "dsl"
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.include(Spicerack::RSpec::Configurable::Matchers, type: :configuration)
|
8
|
+
config.include(Spicerack::RSpec::Configurable::DSL, type: :configuration)
|
9
|
+
end
|
@@ -3,7 +3,9 @@
|
|
3
3
|
require "rspice"
|
4
4
|
require "redis_hash/spec_helper"
|
5
5
|
require "technologic/spec_helper"
|
6
|
+
require "tablesalt/spec_helper"
|
6
7
|
|
7
8
|
require_relative "rspec/custom_matchers"
|
8
9
|
require_relative "rspec/shared_examples"
|
9
10
|
require_relative "rspec/shoulda_matcher_helper"
|
11
|
+
require_relative "rspec/configurable/spec_helper"
|
data/lib/spicerack/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spicerack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Garside
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2019-
|
14
|
+
date: 2019-10-01 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: around_the_world
|
@@ -19,98 +19,98 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - '='
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: 0.17.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - '='
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.
|
29
|
+
version: 0.17.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: collectible
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
34
|
- - '='
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: 0.
|
36
|
+
version: 0.17.0
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - '='
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.
|
43
|
+
version: 0.17.0
|
44
44
|
- !ruby/object:Gem::Dependency
|
45
45
|
name: facet
|
46
46
|
requirement: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
48
|
- - '='
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: 0.
|
50
|
+
version: 0.17.0
|
51
51
|
type: :runtime
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
54
|
requirements:
|
55
55
|
- - '='
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version: 0.
|
57
|
+
version: 0.17.0
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: redis_hash
|
60
60
|
requirement: !ruby/object:Gem::Requirement
|
61
61
|
requirements:
|
62
62
|
- - '='
|
63
63
|
- !ruby/object:Gem::Version
|
64
|
-
version: 0.
|
64
|
+
version: 0.17.0
|
65
65
|
type: :runtime
|
66
66
|
prerelease: false
|
67
67
|
version_requirements: !ruby/object:Gem::Requirement
|
68
68
|
requirements:
|
69
69
|
- - '='
|
70
70
|
- !ruby/object:Gem::Version
|
71
|
-
version: 0.
|
71
|
+
version: 0.17.0
|
72
72
|
- !ruby/object:Gem::Dependency
|
73
73
|
name: short_circu_it
|
74
74
|
requirement: !ruby/object:Gem::Requirement
|
75
75
|
requirements:
|
76
76
|
- - '='
|
77
77
|
- !ruby/object:Gem::Version
|
78
|
-
version: 0.
|
78
|
+
version: 0.17.0
|
79
79
|
type: :runtime
|
80
80
|
prerelease: false
|
81
81
|
version_requirements: !ruby/object:Gem::Requirement
|
82
82
|
requirements:
|
83
83
|
- - '='
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version: 0.
|
85
|
+
version: 0.17.0
|
86
86
|
- !ruby/object:Gem::Dependency
|
87
87
|
name: technologic
|
88
88
|
requirement: !ruby/object:Gem::Requirement
|
89
89
|
requirements:
|
90
90
|
- - '='
|
91
91
|
- !ruby/object:Gem::Version
|
92
|
-
version: 0.
|
92
|
+
version: 0.17.0
|
93
93
|
type: :runtime
|
94
94
|
prerelease: false
|
95
95
|
version_requirements: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
97
|
- - '='
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version: 0.
|
99
|
+
version: 0.17.0
|
100
100
|
- !ruby/object:Gem::Dependency
|
101
101
|
name: tablesalt
|
102
102
|
requirement: !ruby/object:Gem::Requirement
|
103
103
|
requirements:
|
104
104
|
- - '='
|
105
105
|
- !ruby/object:Gem::Version
|
106
|
-
version: 0.
|
106
|
+
version: 0.17.0
|
107
107
|
type: :runtime
|
108
108
|
prerelease: false
|
109
109
|
version_requirements: !ruby/object:Gem::Requirement
|
110
110
|
requirements:
|
111
111
|
- - '='
|
112
112
|
- !ruby/object:Gem::Version
|
113
|
-
version: 0.
|
113
|
+
version: 0.17.0
|
114
114
|
- !ruby/object:Gem::Dependency
|
115
115
|
name: bundler
|
116
116
|
requirement: !ruby/object:Gem::Requirement
|
@@ -235,28 +235,28 @@ dependencies:
|
|
235
235
|
requirements:
|
236
236
|
- - '='
|
237
237
|
- !ruby/object:Gem::Version
|
238
|
-
version: 0.
|
238
|
+
version: 0.17.0
|
239
239
|
type: :development
|
240
240
|
prerelease: false
|
241
241
|
version_requirements: !ruby/object:Gem::Requirement
|
242
242
|
requirements:
|
243
243
|
- - '='
|
244
244
|
- !ruby/object:Gem::Version
|
245
|
-
version: 0.
|
245
|
+
version: 0.17.0
|
246
246
|
- !ruby/object:Gem::Dependency
|
247
247
|
name: spicerack-styleguide
|
248
248
|
requirement: !ruby/object:Gem::Requirement
|
249
249
|
requirements:
|
250
250
|
- - '='
|
251
251
|
- !ruby/object:Gem::Version
|
252
|
-
version: 0.
|
252
|
+
version: 0.17.0
|
253
253
|
type: :development
|
254
254
|
prerelease: false
|
255
255
|
version_requirements: !ruby/object:Gem::Requirement
|
256
256
|
requirements:
|
257
257
|
- - '='
|
258
258
|
- !ruby/object:Gem::Version
|
259
|
-
version: 0.
|
259
|
+
version: 0.17.0
|
260
260
|
- !ruby/object:Gem::Dependency
|
261
261
|
name: will_paginate
|
262
262
|
requirement: !ruby/object:Gem::Requirement
|
@@ -323,6 +323,9 @@ files:
|
|
323
323
|
- lib/spicerack/attribute_object.rb
|
324
324
|
- lib/spicerack/configurable.rb
|
325
325
|
- lib/spicerack/configurable/config_builder.rb
|
326
|
+
- lib/spicerack/configurable/config_delegation.rb
|
327
|
+
- lib/spicerack/configurable/config_object.rb
|
328
|
+
- lib/spicerack/configurable/evaluator.rb
|
326
329
|
- lib/spicerack/configurable/reader.rb
|
327
330
|
- lib/spicerack/hash_model.rb
|
328
331
|
- lib/spicerack/input_model.rb
|
@@ -333,10 +336,13 @@ files:
|
|
333
336
|
- lib/spicerack/objects/options.rb
|
334
337
|
- lib/spicerack/redis_model.rb
|
335
338
|
- lib/spicerack/root_object.rb
|
339
|
+
- lib/spicerack/rspec/configurable/dsl.rb
|
340
|
+
- lib/spicerack/rspec/configurable/matchers.rb
|
341
|
+
- lib/spicerack/rspec/configurable/matchers/define_config_option.rb
|
342
|
+
- lib/spicerack/rspec/configurable/spec_helper.rb
|
336
343
|
- lib/spicerack/rspec/custom_matchers.rb
|
337
344
|
- lib/spicerack/rspec/custom_matchers/define_argument.rb
|
338
345
|
- lib/spicerack/rspec/custom_matchers/define_attribute.rb
|
339
|
-
- lib/spicerack/rspec/custom_matchers/define_config_option.rb
|
340
346
|
- lib/spicerack/rspec/custom_matchers/define_field.rb
|
341
347
|
- lib/spicerack/rspec/custom_matchers/define_option.rb
|
342
348
|
- lib/spicerack/rspec/shared_examples.rb
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# RSpec matcher to test options of a Configurable class
|
4
|
-
#
|
5
|
-
# class ExampleConfiguration
|
6
|
-
# include Spicerack::Configurable
|
7
|
-
#
|
8
|
-
# option :foo
|
9
|
-
# option :bar, default: :baz
|
10
|
-
# end
|
11
|
-
#
|
12
|
-
# RSpec.describe ExampleConfiguration, type: :configuration do
|
13
|
-
# subject { described_class.new }
|
14
|
-
#
|
15
|
-
# it { is_expected.to define_config_option :foo }
|
16
|
-
# it { is_expected.to define_config_option :bar, default: :baz }
|
17
|
-
# end
|
18
|
-
|
19
|
-
RSpec::Matchers.define :define_config_option do |option, default: nil|
|
20
|
-
description { "define config option #{option}" }
|
21
|
-
failure_message { "expected #{subject} to define config option #{option} #{with_default(default)}".strip }
|
22
|
-
|
23
|
-
match do |obj|
|
24
|
-
expect(obj).to respond_to :config
|
25
|
-
expect(obj.config.instance_variable_get(:@config)).to be_present
|
26
|
-
expect(obj.config.instance_variable_get(:@config)).to define_option option, default: default
|
27
|
-
end
|
28
|
-
|
29
|
-
def with_default(default)
|
30
|
-
"with default #{default}" unless default.nil?
|
31
|
-
end
|
32
|
-
end
|