Skip to content

Commit

Permalink
Create Configurable module
Browse files Browse the repository at this point in the history
  • Loading branch information
p-lambert committed Sep 29, 2017
1 parent 3140549 commit cd31a3c
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
52 changes: 52 additions & 0 deletions lib/ddtrace/configurable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
module Datadog
InvalidOptionError = Class.new(StandardError)
# Configuratble provides configuration methods for a given class/module
module Configurable
IDENTITY = ->(x) { x }

def self.included(base)
base.singleton_class.include(ClassMethods)
end

# ClassMethods
module ClassMethods
def set_option(name, value)
name = name.to_sym

invalid!(name) unless options.key?(name)

options[name] = setters[name].call(value)
end

def get_option(name)
invalid!(name) unless options.key?(name)

options[name]
end

def configure_pin(pin)
pin.config = Hash(pin.config).merge(options)
end

private

def option(name, opts = {})
name = name.to_sym
setters[name] = opts.fetch(:setter, IDENTITY)
options[name] = opts[:default]
end

def options
@options ||= {}
end

def setters
@setters ||= {}
end

def invalid!(name)
raise(InvalidOptionError, "#{self} doesn't have the option: #{name}")
end
end
end
end
2 changes: 2 additions & 0 deletions lib/ddtrace/contrib/base.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
require 'ddtrace/registry'
require 'ddtrace/configurable'

module Datadog
module Contrib
# Base provides features that are shared across all integrations
module Base
def self.included(base)
base.include(Registry::Registerable)
base.include(Configurable)
end
end
end
Expand Down
63 changes: 63 additions & 0 deletions test/configurable_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
require 'ddtrace/configurable'

module Datadog
class ConfigurableTest < Minitest::Test
def setup
@module = Module.new { include(Configurable) }
end

def test_option_methods
assert_respond_to(@module, :set_option)
assert_respond_to(@module, :get_option)
assert_respond_to(@module, :configure_pin)
end

def test_option_default
@module.class_eval do
option :foo, default: :bar
end

assert_equal(:bar, @module.get_option(:foo))
end

def test_setting_an_option
@module.class_eval do
option :foo, default: :bar
end

@module.set_option(:foo, 'baz!')
assert_equal('baz!', @module.get_option(:foo))
end

def test_custom_setter
@module.class_eval do
option :shout, setter: ->(v) { v.upcase }
end

@module.set_option(:shout, 'loud')
assert_equal('LOUD', @module.get_option(:shout))
end

def test_pin_configuration
@module.class_eval do
option :foo
end

pin = Pin.new(:test_service)
@module.set_option(:foo, :bar)
@module.configure_pin(pin)

assert_equal(:bar, pin.config[:foo])
end

def test_invalid_option
assert_raises(InvalidOptionError) do
@module.set_option(:bad_option, 'foo')
end

assert_raises(InvalidOptionError) do
@module.get_option(:bad_option)
end
end
end
end

0 comments on commit cd31a3c

Please sign in to comment.