mirror of
https://github.com/meineerde/rackstash.git
synced 2026-02-01 01:37:12 +00:00
Build a new Filter from a String or Symbol
This commit is contained in:
parent
9e23267c76
commit
f0c65524a7
@ -23,5 +23,54 @@ module Rackstash
|
||||
# A filter can be any object responding to `call`, e.g. a Proc or a concrete
|
||||
# class inside this module.
|
||||
module Filters
|
||||
# Create a new filter instance from the specified class and the given
|
||||
# arguments. The class can be given as an actual class or as the name of a
|
||||
# filter in which case we are resolving it to a class defined inside the
|
||||
# {Rackstash::Filters} namespace.
|
||||
#
|
||||
# @param klass [Class, Symbol, String] a description of the class from which
|
||||
# we are creating a new filter object. When giving a `Class`, we are using
|
||||
# it as is. When giving a `String` or `Symbol`, we are determining the
|
||||
# associated class from the {Rackstash::Filters} module and create an
|
||||
# instance of that.
|
||||
# @param args [Array] an optional list of arguments which is passed to the
|
||||
# initializer for the new filter object.
|
||||
# @raise [TypeError] if we can not create a new Filter object from `class`
|
||||
# @raise [NameError] if we could not find a filter class for the specified
|
||||
# class name
|
||||
# @return [Object] a new filter object
|
||||
def self.build(klass, *args, &block)
|
||||
case klass
|
||||
when Class
|
||||
klass.new(*args, &block)
|
||||
when Symbol, String
|
||||
filter_class_name = klass.to_s
|
||||
.sub(/^[a-z\d]*/) { $&.capitalize }
|
||||
.gsub(/(?:_)([a-z\d]*)/) { $1.capitalize }
|
||||
.to_sym
|
||||
filter_class = const_get(filter_class_name, false)
|
||||
filter_class.new(*args, &block)
|
||||
else
|
||||
raise TypeError, "Can not build filter for #{klass.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Hash<Symbol => Class>] a Hash with names of filters and their
|
||||
# respective classes which can be used with {Filters.build} to create a
|
||||
# new filter object
|
||||
def self.known
|
||||
constants.each_with_object({}) do |const, known|
|
||||
filter_class = const_get(const, false)
|
||||
next unless filter_class.is_a?(Class)
|
||||
|
||||
filter_class_name = const.to_s
|
||||
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
||||
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
||||
.downcase
|
||||
.to_sym
|
||||
|
||||
known[filter_class_name] = filter_class
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
68
spec/rackstash/filters_spec.rb
Normal file
68
spec/rackstash/filters_spec.rb
Normal file
@ -0,0 +1,68 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Copyright 2017 Holger Just
|
||||
#
|
||||
# This software may be modified and distributed under the terms
|
||||
# of the MIT license. See the LICENSE.txt file for details.
|
||||
|
||||
require 'spec_helper'
|
||||
require 'securerandom'
|
||||
|
||||
require 'rackstash/filters'
|
||||
|
||||
describe Rackstash::Filters do
|
||||
let(:filter_class) { Class.new }
|
||||
let(:random) { SecureRandom.hex(6) }
|
||||
let(:filter_class_name) { :"FilterClass#{random}" }
|
||||
|
||||
around(:each) do |example|
|
||||
described_class.const_set(filter_class_name, filter_class)
|
||||
example.run
|
||||
described_class.send(:remove_const, filter_class_name)
|
||||
end
|
||||
|
||||
describe '.build' do
|
||||
it 'builds a filter from a class' do
|
||||
args = ['arg1', foo: 'bar']
|
||||
expect(filter_class).to receive(:new).with(*args)
|
||||
|
||||
described_class.build(filter_class, *args)
|
||||
end
|
||||
|
||||
it 'builds a filter from a Symbol' do
|
||||
args = ['arg1', foo: 'bar']
|
||||
expect(filter_class).to receive(:new).with(*args)
|
||||
|
||||
described_class.build(:"filter_class#{random}", *args)
|
||||
end
|
||||
|
||||
it 'builds a filter from a String' do
|
||||
args = ['arg1', foo: 'bar']
|
||||
expect(filter_class).to receive(:new).with(*args)
|
||||
|
||||
described_class.build("filter_class#{random}", *args)
|
||||
end
|
||||
|
||||
it 'raises a TypeError with different arguments' do
|
||||
expect { described_class.build(123) }.to raise_error(TypeError)
|
||||
expect { described_class.build(nil) }.to raise_error(TypeError)
|
||||
expect { described_class.build(true) }.to raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.known' do
|
||||
it 'returns a Hash with known Filters' do
|
||||
expect(described_class.known).not_to be_empty
|
||||
|
||||
expect(described_class.known.keys).to all(
|
||||
be_a(Symbol)
|
||||
.and match(/\A[a-z0-9_]+\z/)
|
||||
)
|
||||
expect(described_class.known.values).to all be_a(Class)
|
||||
end
|
||||
|
||||
it 'includes Filter classes' do
|
||||
expect(described_class.known[:"filter_class#{random}"]).to equal filter_class
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user