require 'rails_helper' RSpec.describe UnitConversion do describe '.get_value' do it 'returns rationals' do expect(UnitConversion.get_value('1/2')).to eq Rational(1, 2) expect(UnitConversion.get_value('1 1/2')).to eq Rational(3, 2) expect(UnitConversion.get_value('-1/2')).to eq Rational(-1, 2) expect(UnitConversion.get_value('-1 1/2')).to eq Rational(-3, 2) end it 'returns decimals' do expect(UnitConversion.get_value('-1')).to eq -1.to_d expect(UnitConversion.get_value('1.0')).to eq 1.to_d expect(UnitConversion.get_value('5.56')).to eq "5.56".to_d end end describe '.convert' do it 'scales decimal numbers' do expect(UnitConversion.convert('1', '2', 'cup', 'cup')).to eq '2' expect(UnitConversion.convert('1.5', '2', 'cup', 'cup')).to eq '3' expect(UnitConversion.convert('4', '.5', 'cup', 'cup')).to eq '2' expect(UnitConversion.convert('4', '1/2', 'cup', 'cup')).to eq '2' end it 'scales rational numbers' do expect(UnitConversion.convert('1/2', '2', 'cup', 'cup')).to eq '1' expect(UnitConversion.convert('1 1/2', '2', 'cup', 'cup')).to eq '3' expect(UnitConversion.convert('4', '.5', 'cup', 'cup')).to eq '2' expect(UnitConversion.convert('4', '1/2', 'cup', 'cup')).to eq '2' expect(UnitConversion.convert('2', '1/3', 'cup', 'cup')).to eq '2/3' end it 'converts units' do expect(UnitConversion.convert('1/2', '1', 'cup', 'tbsp')).to eq '8' expect(UnitConversion.convert('8', '1', 'tablespoon', 'cup')).to eq '1/2' expect(UnitConversion.convert('1', '1', 'tablespoon', 'cup')).to eq '1/16' expect(UnitConversion.convert('2.0', '1', 'tablespoon', 'cup')).to eq '0.125' end it 'converts and scales' do expect(UnitConversion.convert('1/2', '2', 'cup', 'tbsp')).to eq '16' expect(UnitConversion.convert('2.0', '1 1/2', 'tablespoon', 'cup')).to eq '0.188' expect(UnitConversion.convert('2', '1 1/2', 'tablespoon', 'cup')).to eq '3/16' end end describe '.parse' do it 'correctly parses strings to Units' do data = { '4 c' => Unitwise(4, 'cup'), '5.5 oz' => Unitwise(5.5, 'ounce'), '-4 tbsp' => Unitwise(-4, 'tablespoon'), '223 g/c' => Unitwise(223, 'gram/cup'), '1/3 c' => Unitwise("1/3".to_r, 'cup'), '-5/16 g' => Unitwise("-5/16".to_r, 'gram') } data.each do |input, output| expect(UnitConversion.parse(input)).to eq output end end it 'raises UnknownUnitError with bad units' do data = [ '5 cats', '33 gulps/thinking', '9.2 meeters/s2', '5/8 floor' ] data.each do |input| expect { UnitConversion.parse(input) }.to raise_error(UnitConversion::UnknownUnitError), "'#{input}' didn't raise" end end it 'raises UnparseableUnitError on malformed string' do data = [ '55', '55.5', '-55', '-55.55', '5.5/2 cups', '2/3.0 cups', 'ounce', '-.4 cups', 'gallons 6', '5,5 tsp' ] data.each do |input| expect { UnitConversion.parse(input) }.to raise_error(UnitConversion::UnparseableUnitError), "'#{input}' didn't raise" end end end describe '.density?' do it 'returns true for any mass over volume unit' do data = [ Unitwise(1, 'gram/cup'), Unitwise(1, 'pound/gallon'), Unitwise(1, 'ounce/tablespoon'), Unitwise(1, 'ounce/centimeter3') ] data.each do |input| expect(UnitConversion.density?(input)).to be_truthy end end it 'returns false for any non density unit' do data = [ Unitwise(1, 'cup'), Unitwise(1, 'gram'), Unitwise(1, 'gram/hour'), Unitwise(1, 'centimeter3/ounce') ] data.each do |input| expect(UnitConversion.density?(input)).to be_falsey end end end describe '.normalize_unit_name' do it 'converts simple units' do data = { 'c' => 'cup', 'cups' => 'cup', 'pints' => 'pint', 'g' => 'gram', 'grams' => 'gram' } data.each do |input, output| expect(UnitConversion.normalize_unit_names(input)).to eq output end end it 'converts mixed units' do data = { 'oz/c' => 'ounce/cup', 'kg/cups' => 'kilogram/cup', 'pints/junk' => 'pint/junk' } data.each do |input, output| expect(UnitConversion.normalize_unit_names(input)).to eq output end end end end