1
0
mirror of https://github.com/meineerde/rackstash.git synced 2026-01-31 17:27:13 +00:00

Add Tags field class to hold tags on a Buffer

This commit is contained in:
Holger Just 2017-02-02 21:48:17 +01:00
parent 0a011efc32
commit e69818dd01
4 changed files with 189 additions and 1 deletions

View File

@ -6,3 +6,4 @@
require 'rackstash/fields/abstract_collection'
require 'rackstash/fields/hash'
require 'rackstash/fields/array'
require 'rackstash/fields/tags'

View File

@ -89,7 +89,7 @@ module Rackstash
hash_field.raw = hash
end if wrap
return hash
when ::Array, ::Enumerator
when ::Array, ::Set, ::Enumerator
array = value.map { |e| normalize(e, scope: scope, resolve: resolve) }
array = Rackstash::Fields::Array.new.tap do |array_field|
array_field.raw = array

View File

@ -0,0 +1,69 @@
# 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 'set'
require 'rackstash/fields/abstract_collection'
module Rackstash
module Fields
class Tags < AbstractCollection
def initialize
@raw = Set.new
end
def <<(tag)
merge!(tag)
end
def as_json(*)
@raw.to_a
end
alias :to_ary :as_json
alias :to_a :as_json
def clear
@raw.clear
self
end
def empty?
@raw.empty?
end
def merge(*tags, scope: nil)
dup.merge!(*tags, scope: scope)
end
def merge!(*tags, scope: nil)
@raw.merge normalize_tags(tags.to_ary)
self
end
def tagged?(tag)
@raw.include? utf8_encode(tag)
end
def to_set
@raw.dup
end
protected
def normalize_tags(value, scope: nil)
value = resolve_value(value, scope: scope)
if value.respond_to?(:to_ary)
value = value.to_ary.map { |tag| normalize_tags(tag) }
value.flatten!
value
else
utf8_encode(value).freeze
end
end
end
end
end

View File

@ -0,0 +1,118 @@
# 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 'rackstash/fields/tags'
describe Rackstash::Fields::Tags do
let(:tags) { Rackstash::Fields::Tags.new }
describe '#<<' do
it 'calls merge!' do
expect(tags).to receive(:merge!).with('tag').and_call_original
tags << 'tag'
expect(tags.tagged?('tag')).to be true
end
end
describe '#as_json' do
before do
tags.merge!(123, 'tag', true)
end
it 'returns a simple array' do
expect(tags.as_json).to be_a ::Array
expect(tags.as_json).to eql ['123', 'tag', 'true']
end
it 'returns a new copy each time' do
expect(tags.as_json).to eql tags.as_json
expect(tags.as_json).not_to equal tags.as_json
end
it 'can use to_ary as an alias' do
expect(tags.to_ary).to eql tags.as_json
end
it 'can use to_a as an alias' do
expect(tags.to_a).to eql tags.as_json
end
end
describe '#clear' do
it 'clears all tags' do
tags << 'beep'
tags.clear
expect(tags.to_a).to be_empty
end
it 'returns the tags' do
tags << 'beep'
expect(tags.clear).to equal tags
end
end
describe '#empty?' do
it 'returns true of there are any tags' do
expect(tags.empty?).to be true
tags << 'foo'
expect(tags.empty?).to be false
tags.clear
expect(tags.empty?).to be true
end
end
describe '#merge' do
it 'returns a new object' do
new_tags = tags.merge('hello')
expect(new_tags).to be_a Rackstash::Fields::Tags
expect(new_tags.tagged?('hello')).to be true
expect(new_tags).not_to equal tags
# The original hash is not changed
expect(tags.tagged?('hello')).to be false
end
end
describe '#merge!' do
it 'merges multiple tags as strings' do
tags.merge! 'foo', 'bar'
expect(tags.to_a).to eql ['foo', 'bar']
tags.merge! 123, 'foo', nil
expect(tags.to_a).to eql ['foo', 'bar', '123', '']
expect(tags.to_a).to all be_frozen
end
end
describe '#tagged?' do
it 'checks is the argument is tagged' do
tags.merge! 'foo', '123'
expect(tags.tagged?('foo')).to be true
expect(tags.tagged?(:foo)).to be true
expect(tags.tagged?(123)).to be true
expect(tags.tagged?('123')).to be true
expect(tags.tagged?(nil)).to be false
expect(tags.tagged?('bar')).to be false
end
end
describe 'to_set' do
it 'returns a copy of the internal set' do
expect(tags.to_set).to be_a Set
tags.merge! 'foo', nil
expect(tags.to_set.include?('foo')).to be true
expect(tags.to_set.include?(nil)).to be false
expect(tags.to_set.include?('')).to be true
end
end
end