From 890b1932348610f5ec018f40edd842e28c0034d0 Mon Sep 17 00:00:00 2001 From: Holger Just Date: Thu, 16 Feb 2017 01:00:52 +0100 Subject: [PATCH] Add basic array operations to Rackstash::Fields::Array --- lib/rackstash/fields/array.rb | 47 ++++++++++++++++++++++++++ spec/rackstash/fields/array_spec.rb | 52 +++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/lib/rackstash/fields/array.rb b/lib/rackstash/fields/array.rb index 3d27401..519f9b8 100644 --- a/lib/rackstash/fields/array.rb +++ b/lib/rackstash/fields/array.rb @@ -12,6 +12,46 @@ module Rackstash @raw = Concurrent::Array.new end + # @!method +(array) + # Concatenation — Returns a new {Rackstash::Fields::Array} built by + # concatenating `self` and the given `array` together to produce a + # third array. + # + # @param array [::Array, Rackstash::Fields::Array] + # @return [Rackstash::Fields::Array] + + # @!method -(array) + # Array Difference — Returns a new {Rackstash::Fields::Array} that is a + # copy of `self`, removing any items that also appear in the given + # `array`. The order is preserved from `self`. + # + # @param array [::Array, Rackstash::Fields::Array] + # @return [Rackstash::Fields::Array] + + # @!method |(array) + # Set Union — Returns a new {Rackstash::Fields::Array} by joining `self` + # with the given `array`, excluding any duplicates and preserving the + # order from `self`. + # + # @param array [::Array, Rackstash::Fields::Array] + # @return [Rackstash::Fields::Array] + + # @!method &(array) + # Set Intersection — Returns a new {Rackstash::Fields::Array} containing + # elements common to `self` and the given `array`, excluding any + # duplicates. The order is preserved from `self`. + # + # @param array [::Array, Rackstash::Fields::Array] + # @return [Rackstash::Fields::Array] + + %i[+ - | &].each do |op| + class_eval <<-RUBY, __FILE__ , __LINE__ + 1 + def #{op}(array) + new(@raw #{op} normalize(array, wrap: false)) + end + RUBY + end + # Retrieve a stored value from a given `index` # # @param index [Integer] the index in the array where we fetch the value @@ -92,6 +132,13 @@ module Rackstash return obj.to_ary if obj.respond_to?(:to_ary) raise TypeError, "no implicit conversion of #{obj.class} into Array" end + + def new(raw) + self.class.new.tap do |array| + array.raw = raw + end + end + end def self.Array(array) diff --git a/spec/rackstash/fields/array_spec.rb b/spec/rackstash/fields/array_spec.rb index d193bea..111160c 100644 --- a/spec/rackstash/fields/array_spec.rb +++ b/spec/rackstash/fields/array_spec.rb @@ -10,6 +10,58 @@ require 'rackstash/fields/array' describe Rackstash::Fields::Array do let(:array) { Rackstash::Fields::Array.new } + describe '#+' do + it 'returns the addition of elements' do + array[0] = 'existing' + expect(array + ['existing', -> { 'new' }, [:nested]]) + .to contain_exactly 'existing', 'existing', 'new', ['nested'] + end + + it 'returns a new Array' do + expect(array + [:foo]).to be_a(Rackstash::Fields::Array) + expect(array + [:foo]).not_to equal array + end + end + + describe '#-' do + it 'returns the subtraction of elements' do + array[0] = 'foo' + array[1] = 'bar' + expect(array - [-> { :bar }, ['foo']]).to contain_exactly 'foo' + end + + it 'returns a new Array' do + expect(array - [:foo]).to be_a(Rackstash::Fields::Array).and be_empty + expect(array - [:foo]).not_to equal array + end + end + + describe '#|' do + it 'returns the union of elements' do + array[0] = 'existing' + expect(array | ['new', :existing, -> { 123 }]) + .to contain_exactly 'existing', 'new', 123 + end + + it 'returns a new Array' do + expect(array | [:foo]).to be_a(Rackstash::Fields::Array) + expect(array | [:foo]).not_to equal array + end + end + + describe '#&' do + it 'returns the intersection of elements' do + array[0] = 'existing' + expect(array & [:existing, 'new']) + .to contain_exactly 'existing' + end + + it 'returns a new Array' do + expect(array & [:foo]).to be_a(Rackstash::Fields::Array).and be_empty + expect(array & [:foo]).not_to equal array + end + end + describe '#[]' do it 'returns nil if a value was not set' do expect(array[1]).to be_nil