From c2dbc35d7a5fa87dc38d49ac9669f392bd125fce Mon Sep 17 00:00:00 2001 From: Piotr Murach Date: Mon, 13 Jul 2020 20:06:27 +0100 Subject: [PATCH] Add string to array of integers conversion --- lib/necromancer/converters/array.rb | 26 +++++++++++++++++++++ spec/unit/conversions/to_hash_spec.rb | 2 ++ spec/unit/convert_spec.rb | 7 +++++- spec/unit/converters/array_spec.rb | 33 +++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/lib/necromancer/converters/array.rb b/lib/necromancer/converters/array.rb index 64404f7..a71b972 100644 --- a/lib/necromancer/converters/array.rb +++ b/lib/necromancer/converters/array.rb @@ -47,6 +47,30 @@ def call(value, strict: config.strict) end end + class StringToIntegerArrayConverter < Converter + # @example + # converter.call("1,2,3") # => [1, 2, 3] + # + # @api public + def call(string, strict: config.strict) + array_converter = StringToArrayConverter.new(:string, :array) + array = array_converter.(string, strict: strict) + int_converter = ArrayToIntegerArrayConverter.new(:array, :integers) + int_converter.(array, strict: strict) + end + end + + class ArrayToIntegerArrayConverter < Converter + # @example + # converter.call(["1", "2", "3"]) # => [1, 2, 3] + # + # @api public + def call(array, strict: config.strict) + int_converter = NumericConverters::StringToIntegerConverter.new(:string, :integer) + array.map { |val| int_converter.(val, strict: strict) } + end + end + # An object that converts an array to an array with numeric values class ArrayToNumericConverter < Converter # Convert an array to an array of numeric values @@ -121,6 +145,8 @@ def self.load(conversions) conversions.register StringToArrayConverter.new(:string, :array) conversions.register StringToBoolArrayConverter.new(:string, :bools) conversions.register StringToBoolArrayConverter.new(:string, :booleans) + conversions.register StringToIntegerArrayConverter.new(:string, :integers) + conversions.register StringToIntegerArrayConverter.new(:string, :ints) conversions.register ArrayToNumericConverter.new(:array, :numeric) conversions.register ArrayToBooleanConverter.new(:array, :boolean) conversions.register ObjectToArrayConverter.new(:object, :array) diff --git a/spec/unit/conversions/to_hash_spec.rb b/spec/unit/conversions/to_hash_spec.rb index bf37483..24a6d63 100644 --- a/spec/unit/conversions/to_hash_spec.rb +++ b/spec/unit/conversions/to_hash_spec.rb @@ -32,6 +32,8 @@ 'string->float', 'string->hash', 'string->integer', + 'string->integers', + 'string->ints', 'string->numeric', 'string->range', 'string->time', diff --git a/spec/unit/convert_spec.rb b/spec/unit/convert_spec.rb index e5f1943..09687af 100644 --- a/spec/unit/convert_spec.rb +++ b/spec/unit/convert_spec.rb @@ -16,7 +16,7 @@ end it "allows replacing #to with #>> call" do - expect(converter.convert("1,2,3") >> :array).to eq(%w[1 2 3]) + expect(converter.convert("1,2,3") >> :integers).to eq([1,2,3]) end it "allows to specify object as conversion target" do @@ -37,6 +37,11 @@ expect(converter.convert("t,f,t").to(:bools)).to eq([true,false,true]) end + it "converts string to array of integers" do + expect(converter.convert("1,2,3").to(:integers)).to eq([1,2,3]) + expect(converter.convert("1,2,3").to(:ints)).to eq([1,2,3]) + end + it "converts array to numeric " do expect(converter.convert(['1','2.3','3.0']).to(:numeric)).to eq([1,2.3,3.0]) end diff --git a/spec/unit/converters/array_spec.rb b/spec/unit/converters/array_spec.rb index 1751485..efa2dd6 100644 --- a/spec/unit/converters/array_spec.rb +++ b/spec/unit/converters/array_spec.rb @@ -20,4 +20,37 @@ "'unknown' could not be converted from `string` into `boolean`") end end + + describe ":string -> :integers/:ints" do + subject(:converter) { described_class::StringToIntegerArrayConverter.new } + + { + "1,2,3" => [1, 2, 3], + "1.2, 2.3, 3.4" => [1, 2, 3] + }.each do |input, obj| + it "converts #{input.inspect} to #{obj.inspect}" do + expect(converter.(input)).to eq(obj) + end + end + + it "fails to convert in strict mode" do + expect { + converter.("1,unknown", strict: true) + }.to raise_error(Necromancer::ConversionTypeError, + "'unknown' could not be converted from `string` into `integer`") + end + end + + describe ":array -> :integers" do + subject(:converter) { described_class::ArrayToIntegerArrayConverter.new } + + { + %w[1 2 3] => [1, 2, 3], + %w[1.2 2.3 3.4] => [1, 2, 3] + }.each do |input, obj| + it "converts #{input.inspect} to #{obj.inspect}" do + expect(converter.(input)).to eq(obj) + end + end + end end