# frozen_string_literal: true RSpec.describe Necromancer, '.convert' do subject(:converter) { described_class.new } it "indicates inability to perform the requested conversion" do expect { converter.convert(:foo).to(:float) }.to raise_error(Necromancer::NoTypeConversionAvailableError, /Conversion 'symbol->float' unavailable/) end it "allows for module level convert call" do expect(Necromancer.convert('1,2,3').to(:array)).to eq([1,2,3]) end it "allows replacing #to with #>> call" do expect(converter.convert('1,2,3') >> :array).to eq([1,2,3]) end it "allows to specify object as conversion target" do expect(converter.convert('1,2,3') >> []).to eq([1,2,3]) end it "allows to specify class as conversion target" do expect(converter.convert('1,2,3') >> Array).to eq([1,2,3]) end context 'when array' do it "converts string to array" do expect(converter.convert("1,2,3").to(:array)).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 it "converts array to boolean" do expect(converter.convert(['t', 'no']).to(:boolean)).to eq([true, false]) end it "converts object to array" do expect(converter.convert({x: 1}).to(:array)).to eq([[:x, 1]]) end it "fails to convert in strict mode" do expect { converter.convert(['1', '2.3', false]).to(:numeric, strict: true) }.to raise_error(Necromancer::ConversionTypeError) end end context 'when numeric' do it "converts string to integer" do expect(converter.convert('1').to(:integer)).to eq(1) end it "allows for block for conversion method" do expect(converter.convert { '1' }.to(:integer)).to eq(1) end it "convers integer to string" do expect(converter.convert(1).to(:string)).to eq('1') end it "allows for null type conversion" do expect(converter.convert(1).to(:integer)).to eq(1) end it "raises error when in strict mode" do expect { converter.convert('1a').to(:integer, strict: true) }.to raise_error(Necromancer::ConversionTypeError) end it "doesn't raise error when in non-strict mode" do expect(converter.convert('1').to(:integer, strict: false)).to eql(1) end it "converts string to float" do expect(converter.convert('1.0').to(:float)).to eql(1.0) end it "converts string to numeric" do expect(converter.convert('1.0').to(:numeric)).to eql(1.0) end end context 'when boolean' do it "converts boolean to boolean" do expect(converter.convert(true).to(:boolean)).to eq(true) end it "converts string to boolean" do expect(converter.convert('yes').to(:boolean)).to eq(true) end it "converts integer to boolean" do expect(converter.convert(0).to(:boolean)).to eq(false) end it "converts boolean to integer" do expect(converter.convert(true).to(:integer)).to eq(1) end end context 'when range' do it "converts string to range" do expect(converter.convert('1-10').to(:range)).to eq(1..10) end end context 'when datetime' do it "converts string to date" do expect(converter.convert('2014-12-07').to(:date)). to eq(Date.parse('2014-12-07')) end it "converts string to datetime" do expect(converter.convert('2014-12-07 17:35:44').to(:datetime)). to eq(DateTime.parse('2014-12-07 17:35:44')) end it "converts string to time" do expect(converter.convert('12:30').to(:time)). to eq(Time.parse('12:30')) end end end