253 lines
8.9 KiB
Ruby
253 lines
8.9 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe UnitConversion do
|
|
|
|
describe '.auto_unit' do
|
|
it 'leaves units alone if reasonable' do
|
|
expect(UnitConversion.auto_unit('1/2', 'tbsp')).to eq ['1/2', 'tbsp']
|
|
expect(UnitConversion.auto_unit('2', 'cups')).to eq ['2', 'cups']
|
|
expect(UnitConversion.auto_unit('1', 'c')).to eq ['1', 'c']
|
|
end
|
|
|
|
it 'leaves units alone if unknown' do
|
|
expect(UnitConversion.auto_unit('1/16', 'splat')).to eq ['1/16', 'splat']
|
|
expect(UnitConversion.auto_unit('4.5', 'dogs')).to eq ['4.5', 'dogs']
|
|
expect(UnitConversion.auto_unit('0', '')).to eq ['0', '']
|
|
end
|
|
|
|
it 'converts standard volume units correctly' do
|
|
expect(UnitConversion.auto_unit('6', 'tsp')).to eq ['2', 'tablespoon']
|
|
expect(UnitConversion.auto_unit('24', 'tsp')).to eq ['1/2', 'cup']
|
|
expect(UnitConversion.auto_unit('1/16', 'cup')).to eq ['1', 'tablespoon']
|
|
expect(UnitConversion.auto_unit('1/48', 'cup')).to eq ['1', 'teaspoon']
|
|
expect(UnitConversion.auto_unit('768', 'tsp')).to eq ['1', 'gallon']
|
|
end
|
|
|
|
it 'converts standard mass units correctly' do
|
|
expect(UnitConversion.auto_unit('32', 'oz')).to eq ['2', 'pound']
|
|
expect(UnitConversion.auto_unit('40', 'oz')).to eq ['2 1/2', 'pound']
|
|
expect(UnitConversion.auto_unit('3/4', 'lb')).to eq ['12', 'ounce']
|
|
expect(UnitConversion.auto_unit('0.0625', 'lb')).to eq ['1', 'ounce']
|
|
end
|
|
end
|
|
|
|
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)
|
|
expect(UnitConversion.get_value('18 9/10')).to eq Rational(189, 10)
|
|
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 '.rationalize' do
|
|
it 'leaves integers alone' do
|
|
expect(UnitConversion.rationalize(1)).to eq 1
|
|
expect(UnitConversion.rationalize(15)).to eq 15
|
|
expect(UnitConversion.rationalize(-1)).to eq -1
|
|
expect(UnitConversion.rationalize(0)).to eq 0
|
|
end
|
|
|
|
it 'leaves non-fractional numbers alone' do
|
|
expect(UnitConversion.rationalize(1.0)).to eq 1.0
|
|
expect(UnitConversion.rationalize(-1.0)).to eq -1.0
|
|
expect(UnitConversion.rationalize(0.0)).to eq 0.0
|
|
expect(UnitConversion.rationalize(35.0)).to eq 35.0
|
|
end
|
|
|
|
it 'leaves already nice rationals alone' do
|
|
expect(UnitConversion.rationalize(Rational(1,2))).to eq Rational(1,2)
|
|
expect(UnitConversion.rationalize(Rational(5,2))).to eq Rational(5,2)
|
|
expect(UnitConversion.rationalize(Rational(3,16))).to eq Rational(3,16)
|
|
expect(UnitConversion.rationalize(Rational(3,4))).to eq Rational(3,4)
|
|
end
|
|
|
|
it 'converts neat decimals to rationals' do
|
|
expect(UnitConversion.rationalize(1.5)).to eq Rational(3,2)
|
|
expect(UnitConversion.rationalize(0.125)).to eq Rational(1,8)
|
|
expect(UnitConversion.rationalize(5.0625)).to eq Rational(81, 16)
|
|
expect(UnitConversion.rationalize(0.75)).to eq Rational(3,4)
|
|
end
|
|
|
|
it 'rounds weird rationals to nice rationals' do
|
|
expect(UnitConversion.rationalize(Rational(3,7))).to eq Rational(7,16)
|
|
expect(UnitConversion.rationalize(Rational(2,5))).to eq Rational(3,8)
|
|
expect(UnitConversion.rationalize(Rational(2,5))).to eq Rational(3,8)
|
|
end
|
|
|
|
it 'rounds weird decimals to nice rationals' do
|
|
expect(UnitConversion.rationalize(0.24)).to eq Rational(1,4)
|
|
expect(UnitConversion.rationalize(1.24)).to eq Rational(5,4)
|
|
expect(UnitConversion.rationalize(1.13)).to eq Rational(9,8)
|
|
end
|
|
end
|
|
|
|
describe '.normalize_unit_name' do
|
|
|
|
it 'converts simple units' do
|
|
data = {
|
|
'c' => '[cup_us]',
|
|
'cups' => '[cup_us]',
|
|
'pints' => '[pt_us]',
|
|
'gram' => 'g',
|
|
'grams' => 'g',
|
|
'Grams' => 'g',
|
|
'Tbsp' => '[tbs_us]'
|
|
}
|
|
|
|
data.each do |input, output|
|
|
expect(UnitConversion.normalize_unit_names(input)).to eq output
|
|
end
|
|
end
|
|
|
|
it 'converts mixed units' do
|
|
data = {
|
|
'oz/c' => '[oz_av]/[cup_us]',
|
|
'kilograms/cups' => 'kg/[cup_us]',
|
|
'pints/junk' => '[pt_us]/junk'
|
|
}
|
|
|
|
data.each do |input, output|
|
|
expect(UnitConversion.normalize_unit_names(input)).to eq output
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
end
|