diff --git a/lib/oga.rb b/lib/oga.rb index 8eee85b..414dc2a 100644 --- a/lib/oga.rb +++ b/lib/oga.rb @@ -8,6 +8,8 @@ require_relative 'oga/oga' require_relative 'oga/lru' require_relative 'oga/entity_decoder' require_relative 'oga/node_name_set' +require_relative 'oga/blacklist' +require_relative 'oga/whitelist' # Load these first so that the native extensions don't have to define the # Oga::XML namespace. diff --git a/lib/oga/blacklist.rb b/lib/oga/blacklist.rb new file mode 100644 index 0000000..f6013bb --- /dev/null +++ b/lib/oga/blacklist.rb @@ -0,0 +1,40 @@ +module Oga + ## + # @api private + # + class Blacklist + # @return [Set] + attr_reader :names + + ## + # @param [Array] names + # + def initialize(names) + @names = Set.new(names + names.map(&:upcase)) + end + + ## + # @yieldparam [String] + # + def each + names.each do |value| + yield value + end + end + + ## + # @return [TrueClass|FalseClass] + # + def allow?(name) + return !names.include?(name) + end + + ## + # @param [Oga::Blacklist] other + # @return [Oga::Blacklist] + # + def +(other) + return self.class.new(names + other.names) + end + end # Blacklist +end # Oga diff --git a/lib/oga/whitelist.rb b/lib/oga/whitelist.rb new file mode 100644 index 0000000..8a76670 --- /dev/null +++ b/lib/oga/whitelist.rb @@ -0,0 +1,20 @@ +module Oga + ## + # @api private + # + class Whitelist < Blacklist + ## + # @return [TrueClass|FalseClass] + # + def allow?(name) + return names.include?(name) + end + + ## + # @return [Oga::Blacklist] + # + def to_blacklist + return Blacklist.new(names) + end + end # Whitelist +end # Oga diff --git a/spec/oga/blacklist_spec.rb b/spec/oga/blacklist_spec.rb new file mode 100644 index 0000000..759b519 --- /dev/null +++ b/spec/oga/blacklist_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +describe Oga::Blacklist do + describe '#each' do + it 'yields each value in the list' do + list = described_class.new(%w{foo bar}) + + expect { |block| list.each(&block) } + .to yield_successive_args('foo', 'bar', 'FOO', 'BAR') + end + end + + describe '#allow?' do + it 'returns true for a name not in the list' do + list = described_class.new(%w{foo}) + + list.allow?('bar').should == true + list.allow?('BAR').should == true + end + + it 'returns false for a name in the list' do + list = described_class.new(%w{foo}) + + list.allow?('foo').should == false + list.allow?('FOO').should == false + end + end + + describe '#+' do + it 'returns a new Blacklist' do + list1 = described_class.new(%w{foo}) + list2 = described_class.new(%w{bar}) + list3 = list1 + list2 + + list3.should be_an_instance_of(described_class) + list3.names.to_a.should == %w{foo FOO bar BAR} + end + end +end diff --git a/spec/oga/whitelist_spec.rb b/spec/oga/whitelist_spec.rb new file mode 100644 index 0000000..85d5e45 --- /dev/null +++ b/spec/oga/whitelist_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +describe Oga::Whitelist do + describe '#each' do + it 'yields each value in the list' do + list = described_class.new(%w{foo bar}) + + expect { |block| list.each(&block) } + .to yield_successive_args('foo', 'bar', 'FOO', 'BAR') + end + end + + describe '#allow?' do + it 'returns false for a name not in the list' do + list = described_class.new(%w{foo}) + + list.allow?('bar').should == false + list.allow?('BAR').should == false + end + + it 'returns true for a name in the list' do + list = described_class.new(%w{foo}) + + list.allow?('foo').should == true + list.allow?('FOO').should == true + end + end + + describe '#+' do + it 'returns a new Blacklist' do + list1 = described_class.new(%w{foo}) + list2 = described_class.new(%w{bar}) + list3 = list1 + list2 + + list3.should be_an_instance_of(described_class) + list3.names.to_a.should == %w{foo FOO bar BAR} + end + end + + describe '#to_blacklist' do + it 'returns a Blacklist containing the same values' do + whitelist = described_class.new(%w{foo}) + blacklist = whitelist.to_blacklist + + blacklist.should be_an_instance_of(Oga::Blacklist) + blacklist.names.should == whitelist.names + end + end +end