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' expect(UnitConversion.convert('2/3', '1', 'tablespoon', 'teaspoons')).to eq '2' expect(UnitConversion.convert('2', '4', 'teaspoons', 'tablespoons')).to eq '2 2 /3' end it 'scales odd units without conversion' do expect(UnitConversion.convert('1/2', '2', 'slices', 'slices')).to eq '1' expect(UnitConversion.convert('4', '1/8', nil, nil)).to eq '1/2' expect(UnitConversion.convert('4', '1/8', 'slices', nil)).to eq '1/2' expect(UnitConversion.convert('4', '1/8', nil, 'slices')).to eq '1/2' expect(UnitConversion.convert('4', '1/8', 'slices', '')).to eq '1/2' expect(UnitConversion.convert('4', '1/8', '', 'slices')).to eq '1/2' 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 it 'converts from volume to mass' do expect(UnitConversion.convert('5', '1', 'cup', 'ounce', '5 oz/c')).to eq '25' end it 'converts from mass to volume' do expect(UnitConversion.convert('25', '1', 'ounce', 'cup', '5 oz/c')).to eq '5' 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'), '2 1/2 c' => Unitwise("5/2".to_r, 'cup'), '1.03 gram/ml' => Unitwise(1.03, 'gram/milliliter') } 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', 'Grams' => 'gram', 'Tbsp' => 'tablespoon' } 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