mirror of
https://github.com/meineerde/rackstash.git
synced 2026-03-20 15:19:51 +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
|
# A filter can be any object responding to `call`, e.g. a Proc or a concrete
|
||||||
# class inside this module.
|
# class inside this module.
|
||||||
module Filters
|
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
|
||||||
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