Skip to content

Commit

Permalink
Merge pull request #19 from lyrasis/prepend-field-with-field
Browse files Browse the repository at this point in the history
add Prepend::FieldToFieldValue transform
  • Loading branch information
kspurgin authored Jul 16, 2021
2 parents ad2c48b + cf29dc6 commit 7fc8899
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 5 deletions.
117 changes: 115 additions & 2 deletions lib/kiba/extend/transforms/prepend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,129 @@ module Extend
module Transforms
module Prepend
::Prepend = Kiba::Extend::Transforms::Prepend

# Adds the value of prepended_field to the beginning of the value(s) of the target_field
#
# If target field value is blank, it is left blank, even if there is a prepended field value. If there is no value in prepended field, target field is left as-is
#
# == Examples
# Input table:
#
# | a | b |
# -----------
# | c | d |
# | e;f | g |
# | | h |
# | i | |
#
# Used in pipeline as:
# transform Prepend::FieldToFieldValue, target_field: :a, prepended_field: :b, sep: ': '
#
# Results in:
#
# | a | b |
# --------------
# | d: c | d |
# | d: e;f | g |
# | | h |
# | i | |
#
# Used in pipeline as:
# transform Prepend::FieldToFieldValue, target_field: :a, prepended_field: :b, sep: ': ',
# delete_prepended: true, mvdelim: ';'
#
# Results in:
#
# | a |
# -------------
# | d: c |
# | d: e;d: f |
# | |
# | i |
class FieldToFieldValue
# @param target_field [Symbol] Name of field to prepend to
# @param prepended_field [Symbol] Name of field whose value should be prepended
# @param sep [String] Text inserted between prepended field value and target field value
# @param delete_prepended [Boolean] Whether or not to delete the prepended_field column after prepending
# @param mvdelim [String] Character(s) on which to split multiple values in target field before prepending. If empty string, behaves as a single value field
def initialize(target_field:, prepended_field:, sep: '', delete_prepended: false, mvdelim: '')
@field = target_field
@prepend = prepended_field
@sep = sep
@delete = delete_prepended
@mvdelim = mvdelim
end

# @private
def process(row)
fv = row.fetch(@field, nil)
prepend_val = row.fetch(@prepend, nil)
row.delete(@prepend) if @delete
return row if fv.blank?
return row if prepend_val.blank?

values = @mvdelim.blank? ? [fv] : fv.split(@mvdelim)
row[@field] = values.map{ |val| "#{prepend_val}#{@sep}#{val}"}
.join(@mvdelim)
row.delete(@prepend) if @delete
row
end
end

# Adds the specified value to the specified field
#
# If target field value is blank, it is left blank
#
# == Examples
# Input table:
#
# | a | b |
# -----------
# | c | d |
# | e;f | g |
# | | h |
# | i | |
#
# Used in pipeline as:
# transform Prepend::ToFieldValue, field: :a, value: 'pre: '
#
# Results in:
#
# | a | b |
# --------------
# | pre: c | d |
# | pre: e;f | g |
# | | h |
# | pre: i | |
#
# Used in pipeline as:
# transform Prepend::ToFieldValue, field: :a, value: 'pre: ', mvdelim: ';'
#
# Results in:
#
# | a | b |
# ---------------------
# | pre: c | d |
# | pre: e;pre: f | g |
# | | h |
# | pre: i | |
class ToFieldValue
def initialize(field:, value:)
# @param field [Symbol] The field to prepend to
# @param value [String] The value to be prepended
# @param mvdelim [String] Character(s) on which to split multiple values in field before prepending. If empty string, behaves as a single value field
def initialize(field:, value:, mvdelim: '')
@field = field
@value = value
@mvdelim = mvdelim
end

# @private
def process(row)
fv = row.fetch(@field, nil)
return row if fv.blank?
row[@field] = "#{@value}#{fv}"

fieldvals = @mvdelim.blank? ? [fv] : fv.split(@mvdelim)
row[@field] = fieldvals.map{ |fv| "#{@value}#{fv}" }.join(@mvdelim)
row
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/kiba/extend/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Kiba
module Extend
VERSION = "1.13.0"
VERSION = "1.14.0"
end
end
75 changes: 73 additions & 2 deletions spec/kiba/extend/transforms/prepend_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,77 @@
require 'spec_helper'

RSpec.describe Kiba::Extend::Transforms::Prepend do
describe 'FieldToFieldValue' do
test_csv = 'tmp/test.csv'
rows = [
['name', 'prependval'],
['Weddy', 'm'],
[nil, 'u'],
['', 'u'],
['Kernel', nil],
['Divebomber|Hunter', 'm']
]

context 'when delete_prepended = false' do
before do
generate_csv(test_csv, rows)
@result = execute_job(filename: test_csv,
xform: Prepend::FieldToFieldValue,
xformopt: {target_field: :name, prepended_field: :prependval, sep: ': ',
mvdelim: '|'})
end
it 'prepends value of given field to existing field values' do
expected = {name: 'm: Weddy', prependval: 'm'}
expect(@result[0]).to eq(expected)
end
it 'leaves nil values alone' do
expected = {name: nil, prependval: 'u'}
expect(@result[1]).to eq(expected)
end
it 'leaves blank values alone' do
expected = {name: '', prependval: 'u'}
expect(@result[2]).to eq(expected)
end
it 'does not prepend blank field' do
expected = {name: 'Kernel', prependval: nil}
expect(@result[3]).to eq(expected)
end
it 'prepends to each multivalue in target field' do
expected = {name: 'm: Divebomber|m: Hunter', prependval: 'm'}
expect(@result[4]).to eq(expected)
end
end
context 'when delete_prepended = true' do
before do
generate_csv(test_csv, rows)
@result = execute_job(filename: test_csv,
xform: Prepend::FieldToFieldValue,
xformopt: {target_field: :name, prepended_field: :prependval, sep: ': ', delete_prepended: true,
mvdelim: '|'})
end
it 'prepends value of given field to existing field values' do
expected = {name: 'm: Weddy'}
expect(@result[0]).to eq(expected)
end
it 'leaves nil values alone' do
expected = {name: nil}
expect(@result[1]).to eq(expected)
end
it 'leaves blank values alone' do
expected = {name: ''}
expect(@result[2]).to eq(expected)
end
it 'does not prepend blank field' do
expected = {name: 'Kernel'}
expect(@result[3]).to eq(expected)
end
it 'prepends to each multivalue in target field' do
expected = {name: 'm: Divebomber|m: Hunter'}
expect(@result[4]).to eq(expected)
end
end
end

describe 'ToFieldValue' do
test_csv = 'tmp/test.csv'
rows = [
Expand All @@ -13,8 +84,8 @@
before do
generate_csv(test_csv, rows)
@result = execute_job(filename: test_csv,
xform: Prepend::ToFieldValue,
xformopt: {field: :name, value: 'name: '})
xform: Prepend::ToFieldValue,
xformopt: {field: :name, value: 'name: '})
end
it 'prepends given value to existing field values' do
expected = {id: '1', name: 'name: Weddy'}
Expand Down

0 comments on commit 7fc8899

Please sign in to comment.