-
Notifications
You must be signed in to change notification settings - Fork 109
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow for underscores in unit names and aliases. (#331)
Fixes #330
- Loading branch information
Showing
3 changed files
with
112 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,47 @@ | ||
require File.dirname(__FILE__) + '/../spec_helper' | ||
require_relative '../spec_helper' | ||
|
||
describe "Unit::Definition('eV')" do | ||
subject do | ||
Unit::Definition.new('eV') do |ev| | ||
ev.aliases = ['eV', 'electron-volt'] | ||
ev.aliases = %w[eV electron-volt electron_volt] | ||
ev.definition = RubyUnits::Unit.new('1.602E-19 joule') | ||
ev.display_name = 'electron-volt' | ||
end | ||
end | ||
|
||
describe '#name' do | ||
subject { super().name } | ||
|
||
it { is_expected.to eq('<eV>') } | ||
end | ||
|
||
describe '#aliases' do | ||
subject { super().aliases } | ||
it { is_expected.to eq(%w[eV electron-volt]) } | ||
|
||
it { is_expected.to eq(%w[eV electron-volt electron_volt]) } | ||
end | ||
|
||
describe '#scalar' do | ||
subject { super().scalar } | ||
|
||
it { is_expected.to eq(1.602E-19) } | ||
end | ||
|
||
describe '#numerator' do | ||
subject { super().numerator } | ||
|
||
it { is_expected.to include('<kilogram>', '<meter>', '<meter>') } | ||
end | ||
|
||
describe '#denominator' do | ||
subject { super().denominator } | ||
|
||
it { is_expected.to include('<second>', '<second>') } | ||
end | ||
|
||
describe '#display_name' do | ||
subject { super().display_name } | ||
|
||
it { is_expected.to eq('electron-volt') } | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,92 +1,113 @@ | ||
require 'spec_helper' | ||
|
||
RSpec.describe 'Number parsing' do | ||
context 'with Integers' do | ||
it { expect(RubyUnits::Unit.new('1')).to have_attributes(scalar: 1) } | ||
it { expect(RubyUnits::Unit.new('-1')).to have_attributes(scalar: -1) } | ||
it { expect(RubyUnits::Unit.new('+1')).to have_attributes(scalar: 1) } | ||
it { expect(RubyUnits::Unit.new('01')).to have_attributes(scalar: 1) } | ||
it { expect(RubyUnits::Unit.new('1,000')).to have_attributes(scalar: 1000) } | ||
it { expect(RubyUnits::Unit.new('1_000')).to have_attributes(scalar: 1000) } | ||
end | ||
RSpec.describe 'Parsing' do | ||
describe 'Parsing numbers' do | ||
context 'with Integers' do | ||
it { expect(RubyUnits::Unit.new('1')).to have_attributes(scalar: 1) } | ||
it { expect(RubyUnits::Unit.new('-1')).to have_attributes(scalar: -1) } | ||
it { expect(RubyUnits::Unit.new('+1')).to have_attributes(scalar: 1) } | ||
it { expect(RubyUnits::Unit.new('01')).to have_attributes(scalar: 1) } | ||
it { expect(RubyUnits::Unit.new('1,000')).to have_attributes(scalar: 1000) } | ||
it { expect(RubyUnits::Unit.new('1_000')).to have_attributes(scalar: 1000) } | ||
end | ||
|
||
context 'with Decimals' do | ||
# NOTE: that since this float is the same as an integer, the integer is returned | ||
it { expect(RubyUnits::Unit.new('1.0').scalar).to be(1) } | ||
it { expect(RubyUnits::Unit.new('-1.0').scalar).to be(-1) } | ||
context 'with Decimals' do | ||
# NOTE: that since this float is the same as an integer, the integer is returned | ||
it { expect(RubyUnits::Unit.new('1.0').scalar).to be(1) } | ||
it { expect(RubyUnits::Unit.new('-1.0').scalar).to be(-1) } | ||
|
||
it { expect(RubyUnits::Unit.new('1.1').scalar).to be(1.1) } | ||
it { expect(RubyUnits::Unit.new('-1.1').scalar).to be(-1.1) } | ||
it { expect(RubyUnits::Unit.new('+1.1').scalar).to be(1.1) } | ||
it { expect(RubyUnits::Unit.new('0.1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('-0.1').scalar).to be(-0.1) } | ||
it { expect(RubyUnits::Unit.new('+0.1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('.1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('-.1').scalar).to be(-0.1) } | ||
it { expect(RubyUnits::Unit.new('+.1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('1.1').scalar).to be(1.1) } | ||
it { expect(RubyUnits::Unit.new('-1.1').scalar).to be(-1.1) } | ||
it { expect(RubyUnits::Unit.new('+1.1').scalar).to be(1.1) } | ||
it { expect(RubyUnits::Unit.new('0.1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('-0.1').scalar).to be(-0.1) } | ||
it { expect(RubyUnits::Unit.new('+0.1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('.1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('-.1').scalar).to be(-0.1) } | ||
it { expect(RubyUnits::Unit.new('+.1').scalar).to be(0.1) } | ||
|
||
it { expect { RubyUnits::Unit.new('0.1.') }.to raise_error(ArgumentError) } | ||
it { expect { RubyUnits::Unit.new('-0.1.') }.to raise_error(ArgumentError) } | ||
it { expect { RubyUnits::Unit.new('+0.1.') }.to raise_error(ArgumentError) } | ||
end | ||
it { expect { RubyUnits::Unit.new('0.1.') }.to raise_error(ArgumentError) } | ||
it { expect { RubyUnits::Unit.new('-0.1.') }.to raise_error(ArgumentError) } | ||
it { expect { RubyUnits::Unit.new('+0.1.') }.to raise_error(ArgumentError) } | ||
end | ||
|
||
context 'with Fractions' do | ||
it { expect(RubyUnits::Unit.new('1/1').scalar).to be(1) } | ||
it { expect(RubyUnits::Unit.new('-1/1').scalar).to be(-1) } | ||
it { expect(RubyUnits::Unit.new('+1/1').scalar).to be(1) } | ||
context 'with Fractions' do | ||
it { expect(RubyUnits::Unit.new('1/1').scalar).to be(1) } | ||
it { expect(RubyUnits::Unit.new('-1/1').scalar).to be(-1) } | ||
it { expect(RubyUnits::Unit.new('+1/1').scalar).to be(1) } | ||
|
||
# NOTE: eql? is used here because two equivalent Rational objects are not the same object, unlike Integers | ||
it { expect(RubyUnits::Unit.new('1/2').scalar).to eql(1/2r) } | ||
it { expect(RubyUnits::Unit.new('-1/2').scalar).to eql(-1/2r) } | ||
it { expect(RubyUnits::Unit.new('+1/2').scalar).to eql(1/2r) } | ||
it { expect(RubyUnits::Unit.new('(1/2)').scalar).to eql(1/2r) } | ||
it { expect(RubyUnits::Unit.new('(-1/2)').scalar).to eql(-1/2r) } | ||
it { expect(RubyUnits::Unit.new('(+1/2)').scalar).to eql(1/2r) } | ||
# NOTE: eql? is used here because two equivalent Rational objects are not the same object, unlike Integers | ||
it { expect(RubyUnits::Unit.new('1/2').scalar).to eql(1/2r) } | ||
it { expect(RubyUnits::Unit.new('-1/2').scalar).to eql(-1/2r) } | ||
it { expect(RubyUnits::Unit.new('+1/2').scalar).to eql(1/2r) } | ||
it { expect(RubyUnits::Unit.new('(1/2)').scalar).to eql(1/2r) } | ||
it { expect(RubyUnits::Unit.new('(-1/2)').scalar).to eql(-1/2r) } | ||
it { expect(RubyUnits::Unit.new('(+1/2)').scalar).to eql(1/2r) } | ||
|
||
# improper fractions | ||
it { expect(RubyUnits::Unit.new('1 1/2').scalar).to eql(3/2r) } | ||
it { expect(RubyUnits::Unit.new('-1 1/2').scalar).to eql(-3/2r) } | ||
it { expect(RubyUnits::Unit.new('+1 1/2').scalar).to eql(3/2r) } | ||
it { expect(RubyUnits::Unit.new('1-1/2').scalar).to eql(3/2r) } | ||
it { expect(RubyUnits::Unit.new('-1-1/2').scalar).to eql(-3/2r) } | ||
it { expect(RubyUnits::Unit.new('+1-1/2').scalar).to eql(3/2r) } | ||
it { expect(RubyUnits::Unit.new('1 2/2').scalar).to be(2) } # weird, but not wrong | ||
it { expect(RubyUnits::Unit.new('1 3/2').scalar).to eql(5/2r) } # weird, but not wrong | ||
it { expect { RubyUnits::Unit.new('1.5 1/2') }.to raise_error(ArgumentError, 'Improper fractions must have a whole number part') } | ||
it { expect { RubyUnits::Unit.new('1.5/2') }.to raise_error(ArgumentError, 'invalid value for Integer(): "1.5"') } | ||
it { expect { RubyUnits::Unit.new('1/2.5') }.to raise_error(ArgumentError, 'invalid value for Integer(): "2.5"') } | ||
end | ||
# improper fractions | ||
it { expect(RubyUnits::Unit.new('1 1/2').scalar).to eql(3/2r) } | ||
it { expect(RubyUnits::Unit.new('-1 1/2').scalar).to eql(-3/2r) } | ||
it { expect(RubyUnits::Unit.new('+1 1/2').scalar).to eql(3/2r) } | ||
it { expect(RubyUnits::Unit.new('1-1/2').scalar).to eql(3/2r) } | ||
it { expect(RubyUnits::Unit.new('-1-1/2').scalar).to eql(-3/2r) } | ||
it { expect(RubyUnits::Unit.new('+1-1/2').scalar).to eql(3/2r) } | ||
it { expect(RubyUnits::Unit.new('1 2/2').scalar).to be(2) } # weird, but not wrong | ||
it { expect(RubyUnits::Unit.new('1 3/2').scalar).to eql(5/2r) } # weird, but not wrong | ||
it { expect { RubyUnits::Unit.new('1.5 1/2') }.to raise_error(ArgumentError, 'Improper fractions must have a whole number part') } | ||
it { expect { RubyUnits::Unit.new('1.5/2') }.to raise_error(ArgumentError, 'invalid value for Integer(): "1.5"') } | ||
it { expect { RubyUnits::Unit.new('1/2.5') }.to raise_error(ArgumentError, 'invalid value for Integer(): "2.5"') } | ||
end | ||
|
||
context 'with Scientific Notation' do | ||
it { expect(RubyUnits::Unit.new('1e0').scalar).to be(1) } | ||
it { expect(RubyUnits::Unit.new('-1e0').scalar).to be(-1) } | ||
it { expect(RubyUnits::Unit.new('+1e0').scalar).to be(1) } | ||
it { expect(RubyUnits::Unit.new('1e1').scalar).to be(10) } | ||
it { expect(RubyUnits::Unit.new('-1e1').scalar).to be(-10) } | ||
it { expect(RubyUnits::Unit.new('+1e1').scalar).to be(10) } | ||
it { expect(RubyUnits::Unit.new('1e-1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('-1e-1').scalar).to be(-0.1) } | ||
it { expect(RubyUnits::Unit.new('+1e-1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('1E+1').scalar).to be(10) } | ||
it { expect(RubyUnits::Unit.new('-1E+1').scalar).to be(-10) } | ||
it { expect(RubyUnits::Unit.new('+1E+1').scalar).to be(10) } | ||
it { expect(RubyUnits::Unit.new('1E-1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('-1E-1').scalar).to be(-0.1) } | ||
it { expect(RubyUnits::Unit.new('+1E-1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('1.0e2').scalar).to be(100) } | ||
it { expect(RubyUnits::Unit.new('.1e2').scalar).to be(10) } | ||
it { expect(RubyUnits::Unit.new('0.1e2').scalar).to be(10) } | ||
it { expect { RubyUnits::Unit.new('0.1e2.5') }.to raise_error(ArgumentError) } | ||
context 'with Scientific Notation' do | ||
it { expect(RubyUnits::Unit.new('1e0').scalar).to be(1) } | ||
it { expect(RubyUnits::Unit.new('-1e0').scalar).to be(-1) } | ||
it { expect(RubyUnits::Unit.new('+1e0').scalar).to be(1) } | ||
it { expect(RubyUnits::Unit.new('1e1').scalar).to be(10) } | ||
it { expect(RubyUnits::Unit.new('-1e1').scalar).to be(-10) } | ||
it { expect(RubyUnits::Unit.new('+1e1').scalar).to be(10) } | ||
it { expect(RubyUnits::Unit.new('1e-1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('-1e-1').scalar).to be(-0.1) } | ||
it { expect(RubyUnits::Unit.new('+1e-1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('1E+1').scalar).to be(10) } | ||
it { expect(RubyUnits::Unit.new('-1E+1').scalar).to be(-10) } | ||
it { expect(RubyUnits::Unit.new('+1E+1').scalar).to be(10) } | ||
it { expect(RubyUnits::Unit.new('1E-1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('-1E-1').scalar).to be(-0.1) } | ||
it { expect(RubyUnits::Unit.new('+1E-1').scalar).to be(0.1) } | ||
it { expect(RubyUnits::Unit.new('1.0e2').scalar).to be(100) } | ||
it { expect(RubyUnits::Unit.new('.1e2').scalar).to be(10) } | ||
it { expect(RubyUnits::Unit.new('0.1e2').scalar).to be(10) } | ||
it { expect { RubyUnits::Unit.new('0.1e2.5') }.to raise_error(ArgumentError) } | ||
end | ||
|
||
context 'with Complex numbers' do | ||
it { expect(RubyUnits::Unit.new('1+1i').scalar).to eql(Complex(1, 1)) } | ||
it { expect(RubyUnits::Unit.new('1i').scalar).to eql(Complex(0, 1)) } | ||
it { expect(RubyUnits::Unit.new('-1i').scalar).to eql(Complex(0, -1)) } | ||
it { expect(RubyUnits::Unit.new('-1+1i').scalar).to eql(Complex(-1, 1)) } | ||
it { expect(RubyUnits::Unit.new('+1+1i').scalar).to eql(Complex(1, 1)) } | ||
it { expect(RubyUnits::Unit.new('1-1i').scalar).to eql(Complex(1, -1)) } | ||
it { expect(RubyUnits::Unit.new('-1.23-4.5i').scalar).to eql(Complex(-1.23, -4.5)) } | ||
it { expect(RubyUnits::Unit.new('1+0i').scalar).to be(1) } | ||
end | ||
end | ||
|
||
context 'with Complex numbers' do | ||
it { expect(RubyUnits::Unit.new('1+1i').scalar).to eql(Complex(1, 1)) } | ||
it { expect(RubyUnits::Unit.new('1i').scalar).to eql(Complex(0, 1)) } | ||
it { expect(RubyUnits::Unit.new('-1i').scalar).to eql(Complex(0, -1)) } | ||
it { expect(RubyUnits::Unit.new('-1+1i').scalar).to eql(Complex(-1, 1)) } | ||
it { expect(RubyUnits::Unit.new('+1+1i').scalar).to eql(Complex(1, 1)) } | ||
it { expect(RubyUnits::Unit.new('1-1i').scalar).to eql(Complex(1, -1)) } | ||
it { expect(RubyUnits::Unit.new('-1.23-4.5i').scalar).to eql(Complex(-1.23, -4.5)) } | ||
it { expect(RubyUnits::Unit.new('1+0i').scalar).to be(1) } | ||
describe 'Unit parsing' do | ||
before do | ||
RubyUnits::Unit.define('m2') do |m2| | ||
m2.definition = RubyUnits::Unit.new('meter^2') | ||
m2.aliases = %w[m2 meter2 square_meter square-meter] | ||
end | ||
end | ||
|
||
it { | ||
expect(RubyUnits::Unit.new('m2')).to have_attributes(scalar: 1, | ||
numerator: %w[<m2>], | ||
denominator: ['<1>'], | ||
kind: :area) | ||
} | ||
|
||
# make sure that underscores in the unit name are handled correctly | ||
it { expect(RubyUnits::Unit.new('1_000 square_meter')).to eq(RubyUnits::Unit.new('1000 m^2')) } | ||
end | ||
end |