parsley/spec/models/unit_conversion_spec.rb

253 lines
8.9 KiB
Ruby
Raw Normal View History

2016-01-15 13:49:08 -06:00
require 'rails_helper'
RSpec.describe UnitConversion do
2016-01-20 18:37:28 -06:00
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
2016-01-15 13:49:08 -06:00
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)
2016-01-20 15:07:37 -06:00
expect(UnitConversion.get_value('18 9/10')).to eq Rational(189, 10)
2016-01-15 13:49:08 -06:00
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'
2016-01-15 16:15:50 -06:00
expect(UnitConversion.convert('2/3', '1', 'tablespoon', 'teaspoons')).to eq '2'
2016-01-20 15:07:37 -06:00
expect(UnitConversion.convert('2', '4', 'teaspoons', 'tablespoons')).to eq '2 2/3'
2016-01-15 13:49:08 -06:00
end
2016-01-15 16:09:34 -06:00
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'
2016-01-18 12:58:54 -06:00
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'
2016-01-15 16:09:34 -06:00
end
2016-01-15 13:49:08 -06:00
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
2016-01-15 16:09:34 -06:00
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
2016-01-15 13:49:08 -06:00
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'),
2016-01-15 13:50:51 -06:00
'-5/16 g' => Unitwise("-5/16".to_r, 'gram'),
2016-01-18 20:50:19 -06:00
'2 1/2 c' => Unitwise("5/2".to_r, 'cup'),
'1.03 gram/ml' => Unitwise(1.03, 'gram/milliliter')
2016-01-15 13:49:08 -06:00
}
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
2016-01-20 18:37:28 -06:00
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
2016-01-15 13:49:08 -06:00
describe '.normalize_unit_name' do
it 'converts simple units' do
data = {
2016-01-20 18:37:28 -06:00
'c' => '[cup_us]',
'cups' => '[cup_us]',
'pints' => '[pt_us]',
'gram' => 'g',
'grams' => 'g',
'Grams' => 'g',
'Tbsp' => '[tbs_us]'
2016-01-15 13:49:08 -06:00
}
data.each do |input, output|
expect(UnitConversion.normalize_unit_names(input)).to eq output
end
end
it 'converts mixed units' do
data = {
2016-01-20 18:37:28 -06:00
'oz/c' => '[oz_av]/[cup_us]',
'kilograms/cups' => 'kg/[cup_us]',
'pints/junk' => '[pt_us]/junk'
2016-01-15 13:49:08 -06:00
}
data.each do |input, output|
expect(UnitConversion.normalize_unit_names(input)).to eq output
end
end
end
end