unite 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/Guardfile +3 -1
- data/lib/unite/arithmetic.rb +1 -1
- data/lib/unite/comparison.rb +6 -2
- data/lib/unite/conversion.rb +6 -6
- data/lib/unite/dimension/integer.rb +1 -1
- data/lib/unite/dimension/vector.rb +5 -5
- data/lib/unite/dimension.rb +16 -10
- data/lib/unite/fraction.rb +7 -7
- data/lib/unite/lookup/definitions.rb +28 -2
- data/lib/unite/lookup/property.rb +5 -3
- data/lib/unite/lookup/simple_unit.rb +3 -3
- data/lib/unite/quantity.rb +8 -0
- data/lib/unite/version.rb +1 -1
- data/lib/unite.rb +11 -0
- data/spec/dimension_spec.rb +22 -1
- data/spec/lookup/property_spec.rb +7 -0
- data/spec/lookup/simple_unit_spec.rb +9 -2
- data/spec/lookup_spec.rb +1 -1
- data/spec/quantity_spec.rb +47 -1
- data/spec/spec_helper.rb +10 -0
- data/spec/support/shared_examples/units/comparison.rb +8 -1
- data/spec/support/shared_examples/units/conversion.rb +9 -2
- data/spec/support/shared_examples/units/dimension/integer.rb +40 -28
- data/spec/support/shared_examples/units/dimension/vector.rb +20 -3
- data/spec/support/shared_examples/units/fractions.rb +19 -2
- metadata +6 -6
data/Gemfile.lock
CHANGED
data/Guardfile
CHANGED
@@ -9,7 +9,9 @@ end
|
|
9
9
|
|
10
10
|
guard 'rspec', :cli => '--backtrace', :version => 2 do
|
11
11
|
watch(%r{^spec/.+_spec\.rb$})
|
12
|
-
watch(%r{^
|
12
|
+
watch(%r{^spec/support/shared_examples/.+\.rb$}) { 'spec' }
|
13
|
+
# watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
14
|
+
watch(%r{^lib/(.+)\.rb$}) { 'spec' }
|
13
15
|
watch('spec/spec_helper.rb') { "spec" }
|
14
16
|
end
|
15
17
|
|
data/lib/unite/arithmetic.rb
CHANGED
@@ -41,7 +41,7 @@ module Unite
|
|
41
41
|
new_denominator = self.denominator + other.denominator
|
42
42
|
self.class.new(:value => (self.value * other.value), :numerator => new_numerator, :denominator => new_denominator).tap(&:reduce)
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
def coerce(other)
|
46
46
|
case other
|
47
47
|
when Numeric
|
data/lib/unite/comparison.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
module Unite
|
3
3
|
class IncompatibleError < RuntimeError
|
4
4
|
end
|
5
|
-
|
5
|
+
|
6
6
|
module Comparison
|
7
7
|
|
8
8
|
extend ::ActiveSupport::Concern
|
@@ -27,7 +27,11 @@ module Unite
|
|
27
27
|
def == other
|
28
28
|
self.compatible?(other) && self.convert_to(other).value == other.value
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
|
+
def compatible_units
|
32
|
+
Lookup.compatible_units self.dimension_int
|
33
|
+
end
|
34
|
+
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
data/lib/unite/conversion.rb
CHANGED
@@ -8,7 +8,7 @@ module Unite
|
|
8
8
|
extend ::ActiveSupport::Concern
|
9
9
|
include Comparison
|
10
10
|
include Fraction
|
11
|
-
|
11
|
+
|
12
12
|
included do
|
13
13
|
|
14
14
|
end
|
@@ -18,15 +18,15 @@ module Unite
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def convert_to other
|
21
|
-
other = other.clone.tap{|o| o.value = 1
|
21
|
+
other = other.clone.tap{|o| o.value = BigDecimal.new(1) } #this is so that only the unit is used for the conversion
|
22
22
|
new_value = self.converted_value(other)
|
23
23
|
return nil if new_value.nil?
|
24
24
|
self.class.new :value => new_value, :numerator => other.numerator, :denominator => other.denominator
|
25
25
|
end
|
26
26
|
|
27
|
-
protected
|
27
|
+
protected
|
28
28
|
|
29
|
-
def converted_value other
|
29
|
+
def converted_value other
|
30
30
|
return nil unless self.compatible?(other)
|
31
31
|
self.si_factor / other.si_factor
|
32
32
|
end
|
@@ -37,8 +37,8 @@ module Unite
|
|
37
37
|
|
38
38
|
def get_si_factor unit_array
|
39
39
|
expand_unit_array(unit_array).map do |element|
|
40
|
-
|
41
|
-
end.inject(1
|
40
|
+
Lookup.find!(element).si_factor
|
41
|
+
end.inject(BigDecimal.new(1)) {|product, factor| product*factor}
|
42
42
|
end
|
43
43
|
|
44
44
|
end
|
@@ -9,7 +9,7 @@ module Unite
|
|
9
9
|
end
|
10
10
|
|
11
11
|
module ClassMethods
|
12
|
-
|
12
|
+
|
13
13
|
end
|
14
14
|
|
15
15
|
def dimension_vector
|
@@ -17,7 +17,7 @@ module Unite
|
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
20
|
-
|
20
|
+
|
21
21
|
def generate_dimension_vector
|
22
22
|
subtract_vectors numerator_dimension_vector, denominator_dimension_vector
|
23
23
|
end
|
@@ -31,13 +31,13 @@ module Unite
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def add_vectors v1, v2
|
34
|
-
|
34
|
+
VECTOR_LIST.length.times.map{|i| v1[i] + v2[i]}
|
35
35
|
end
|
36
36
|
|
37
37
|
def subtract_vectors v1, v2
|
38
|
-
|
38
|
+
VECTOR_LIST.length.times.map{|i| v1[i] - v2[i]}
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
data/lib/unite/dimension.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
module Unite
|
3
3
|
module Dimension
|
4
4
|
extend self
|
5
|
-
|
5
|
+
|
6
6
|
#for a description of this algorithm refer to http://www.cs.utexas.edu/users/novak/units95.html
|
7
|
-
|
7
|
+
|
8
8
|
# 0 length meter
|
9
9
|
# 1 time second
|
10
10
|
# 2 temperature kelvin
|
@@ -13,20 +13,26 @@ module Unite
|
|
13
13
|
# 5 substance mole
|
14
14
|
# 6 luminosity candela
|
15
15
|
# 7 money pound
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
#
|
17
|
+
|
18
|
+
VECTOR_LIST = [:length, :time, :temperature, :mass, :current, :substance, :luminosity, :money]
|
19
|
+
|
21
20
|
DIMSIZES = [20, 20, 20, 10, 10, 10, 10, 10]
|
22
21
|
DIMVALS = [1, 20, 400, 8000, 80000, 800000, 8000000, 80000000]
|
23
|
-
|
22
|
+
|
23
|
+
|
24
|
+
# also include the dimensionless dimension "none"
|
25
|
+
LIST = VECTOR_LIST + [:none]
|
26
|
+
UNITS = ['meter', 'second', 'kelvin', 'kilogram', 'ampere', 'mole', 'candela', 'GBP', '']
|
27
|
+
INDICIES = Hash[*LIST.each_with_index.map{|d,i| [d,i]}.flatten]
|
28
|
+
|
29
|
+
|
24
30
|
def si_unit dimension
|
25
31
|
UNITS[INDICIES[dimension.to_sym]]
|
26
32
|
end
|
27
|
-
|
33
|
+
|
28
34
|
def blank_dimension_vector
|
29
|
-
Array.new(
|
35
|
+
Array.new(VECTOR_LIST.length, 0)
|
30
36
|
end
|
31
37
|
|
32
38
|
end
|
data/lib/unite/fraction.rb
CHANGED
@@ -15,22 +15,22 @@ module Unite
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def initialize *args
|
18
|
-
self.value ||=
|
18
|
+
self.value ||= BigDecimal.new(0)
|
19
19
|
self.numerator ||= []
|
20
20
|
self.denominator ||= []
|
21
21
|
end
|
22
22
|
|
23
23
|
|
24
24
|
def expression=string
|
25
|
-
unless string.blank?
|
25
|
+
unless string.blank? || string.strip == '/'
|
26
26
|
num_denom = string.split('/')
|
27
|
-
raise(InvalidFormat, string) if num_denom.length > 2
|
27
|
+
raise(InvalidFormat, string) if num_denom.length > 2 || num_denom.empty?
|
28
28
|
self.numerator = num_denom[0].split('*').map(&:strip)
|
29
29
|
self.denominator = (num_denom[1].nil? ? [] : num_denom[1].split('*')).map(&:strip)
|
30
30
|
self.value = extract_value!(:numerator) / extract_value!(:denominator)
|
31
31
|
reduce
|
32
32
|
else
|
33
|
-
self.value =
|
33
|
+
self.value = BigDecimal.new(0)
|
34
34
|
self.numerator = []
|
35
35
|
self.denominator = []
|
36
36
|
end
|
@@ -55,7 +55,7 @@ module Unite
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def inverse
|
58
|
-
new_value = value ==
|
58
|
+
new_value = value == BigDecimal.new(0) ? BigDecimal.new(0) : BigDecimal.new(1) / value
|
59
59
|
self.class.new :value => new_value, :numerator => denominator, :denominator => numerator
|
60
60
|
end
|
61
61
|
|
@@ -86,8 +86,8 @@ module Unite
|
|
86
86
|
|
87
87
|
def extract_value! method
|
88
88
|
number_regex = /\A[-+]?\d*\.?\d+([eE][-+]?\d+)?\Z/
|
89
|
-
seperate!(self.send(method)){|x| number_regex =~ x }.map(
|
90
|
-
inject(1
|
89
|
+
seperate!(self.send(method)){|x| number_regex =~ x }.map{|n| BigDecimal.new(n)}.
|
90
|
+
inject(BigDecimal.new(1)){|product, number| product*number }
|
91
91
|
end
|
92
92
|
|
93
93
|
def reduce_unit_array array
|
@@ -1,11 +1,16 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
3
|
module Unite
|
4
|
-
|
4
|
+
|
5
5
|
Lookup.clear!
|
6
6
|
|
7
7
|
#SIMPLE UNITS
|
8
8
|
|
9
|
+
#DIMENSIONLESS
|
10
|
+
Lookup.add SimpleUnit.new(:name => "", :si_factor => 1, :dimension => :none)
|
11
|
+
|
12
|
+
Lookup.add_property Property.new(:name => :none, :expression => '')
|
13
|
+
|
9
14
|
#TIME
|
10
15
|
Lookup.add SimpleUnit.new(:name => "s", :si_factor => 1, :dimension => :time)
|
11
16
|
Lookup.add SimpleUnit.new(:name => "h", :si_factor => 3600, :dimension => :time)
|
@@ -14,6 +19,7 @@ module Unite
|
|
14
19
|
|
15
20
|
#LENGTH
|
16
21
|
Lookup.add SimpleUnit.new(:name => "m", :si_factor => 1, :dimension => :length)
|
22
|
+
Lookup.add SimpleUnit.new(:name => "dm", :si_factor => 0.1, :dimension => :length)
|
17
23
|
Lookup.add SimpleUnit.new(:name => "km", :si_factor => 1000, :dimension => :length)
|
18
24
|
|
19
25
|
Lookup.add_property Property.new(:name => :distance, :expression => 'km')
|
@@ -27,6 +33,19 @@ module Unite
|
|
27
33
|
Lookup.add_property Property.new(:name => :mass, :expression => 'tonne')
|
28
34
|
|
29
35
|
|
36
|
+
#DIMENSIONLESS
|
37
|
+
Lookup.add SimpleUnit.new(:name => "GBP", :si_factor => 1, :dimension => :money)
|
38
|
+
|
39
|
+
#Right now only one currency is supported. It is too difficult to be able to convert them.
|
40
|
+
|
41
|
+
# Lookup.add SimpleUnit.new(:name => "EUR", :si_factor => nil, :dimension => :money)
|
42
|
+
# Lookup.add SimpleUnit.new(:name => "USD", :si_factor => nil, :dimension => :money)
|
43
|
+
# Lookup.add SimpleUnit.new(:name => "CAD", :si_factor => nil, :dimension => :money)
|
44
|
+
|
45
|
+
|
46
|
+
Lookup.add_property Property.new(:name => :money, :expression => 'GBP')
|
47
|
+
|
48
|
+
|
30
49
|
#DERIVED UNITS
|
31
50
|
|
32
51
|
#ENERGY
|
@@ -36,12 +55,19 @@ module Unite
|
|
36
55
|
Lookup.add_property Property.new(:name => :energy, :expression => 'kWh')
|
37
56
|
|
38
57
|
#AREA
|
39
|
-
|
58
|
+
Lookup.add DerivedUnit.new(:name => "square_meter", :expression => 'm^2')
|
40
59
|
Lookup.add DerivedUnit.new(:name => "hectare", :expression => '10000*m^2')
|
41
60
|
Lookup.add DerivedUnit.new(:name => "acre", :expression => '4046.85642*m^2')
|
42
61
|
|
43
62
|
Lookup.add_property Property.new(:name => :area, :expression => 'hectare')
|
44
63
|
|
64
|
+
#Volume
|
65
|
+
Lookup.add DerivedUnit.new(:name => "cubic_meter", :expression => 'm^3')
|
66
|
+
Lookup.add DerivedUnit.new(:name => "L", :expression => 'dm^3')
|
67
|
+
Lookup.add DerivedUnit.new(:name => "gallon", :expression => '3.785411784*L')
|
68
|
+
|
69
|
+
Lookup.add_property Property.new(:name => :volume, :expression => 'cubic_meter')
|
70
|
+
|
45
71
|
end
|
46
72
|
|
47
73
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
module Unite
|
3
3
|
class Property
|
4
|
-
|
4
|
+
|
5
5
|
include ActiveModel::Validations
|
6
6
|
include Dimension::Vector
|
7
7
|
include Conversion
|
@@ -9,13 +9,15 @@ module Unite
|
|
9
9
|
attr_accessor :name, :numerator, :denominator, :value
|
10
10
|
|
11
11
|
validates_presence_of :name
|
12
|
-
|
13
|
-
|
12
|
+
|
13
|
+
def initialize(attributes = {})
|
14
14
|
attributes.each do |name, value|
|
15
15
|
send("#{name}=", value)
|
16
16
|
end
|
17
17
|
super
|
18
18
|
end
|
19
19
|
|
20
|
+
delegate :to_s, :to_sym, :to => :name
|
21
|
+
|
20
22
|
end
|
21
23
|
end
|
@@ -9,11 +9,11 @@ module Unite
|
|
9
9
|
alias :to_s :name
|
10
10
|
|
11
11
|
validates_inclusion_of :dimension, :in => Dimension::LIST
|
12
|
-
validates_presence_of :si_factor, :dimension
|
13
|
-
validates_format_of :name, :with => /\A[^\s*\/\^]+\Z/, :message => "cannot contain *, / or ^"
|
12
|
+
validates_presence_of :si_factor, :dimension
|
13
|
+
validates_format_of :name, :with => /\A[^\s*\/\^]+\Z/, :allow_blank => true, :message => "cannot contain *, / or ^"
|
14
14
|
|
15
15
|
def dimension_vector
|
16
|
-
@dimension_vector ||= Dimension::
|
16
|
+
@dimension_vector ||= Dimension::VECTOR_LIST.map{|d| d == dimension ? 1 : 0 }
|
17
17
|
end
|
18
18
|
|
19
19
|
def initialize(attributes = {})
|
data/lib/unite/quantity.rb
CHANGED
@@ -13,6 +13,14 @@ module Unite
|
|
13
13
|
super
|
14
14
|
end
|
15
15
|
|
16
|
+
|
17
|
+
#Initialize the quantity,
|
18
|
+
#
|
19
|
+
#A nil value is treated as 0.0
|
20
|
+
def self.init value, unit = ""
|
21
|
+
new :expression => [value || 0.0, unit].reject(&:blank?).join('*')
|
22
|
+
end
|
23
|
+
|
16
24
|
attr_accessor :name, :numerator, :denominator, :cached_expression, :value
|
17
25
|
alias :to_s :expression
|
18
26
|
|
data/lib/unite/version.rb
CHANGED
data/lib/unite.rb
CHANGED
@@ -6,6 +6,17 @@ end
|
|
6
6
|
|
7
7
|
|
8
8
|
require 'active_support'
|
9
|
+
require 'bigdecimal'
|
10
|
+
|
11
|
+
class BigDecimal
|
12
|
+
|
13
|
+
alias :old_to_s :to_s
|
14
|
+
def to_s format = 'F'
|
15
|
+
self.old_to_s(format)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
9
20
|
|
10
21
|
# Dir["#{Rails.root.to_s}/lib/units/**/*.rb"].each {|file| require file }
|
11
22
|
require 'unite/fraction'
|
data/spec/dimension_spec.rb
CHANGED
@@ -2,6 +2,27 @@
|
|
2
2
|
require 'spec_helper'
|
3
3
|
|
4
4
|
describe Unite::Dimension do
|
5
|
+
subject { Unite::Dimension }
|
6
|
+
|
7
|
+
|
8
|
+
it "should have the correct VECTOR_LIST" do
|
9
|
+
Unite::Dimension::VECTOR_LIST.should ==
|
10
|
+
[:length, :time, :temperature, :mass, :current, :substance, :luminosity, :money]
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
it "should have the correct LIST" do
|
15
|
+
Unite::Dimension::LIST.should ==
|
16
|
+
[:length, :time, :temperature, :mass, :current, :substance, :luminosity, :money, :none]
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
it "should return the correct si unit" do
|
21
|
+
Unite::Dimension::LIST.map{|d| Unite::Dimension.si_unit(d)}.should ==
|
22
|
+
['meter', 'second', 'kelvin', 'kilogram', 'ampere', 'mole', 'candela', 'GBP', '']
|
23
|
+
end
|
24
|
+
|
25
|
+
its(:blank_dimension_vector) { should == [0,0,0,0,0,0,0,0] }
|
26
|
+
|
5
27
|
|
6
|
-
|
7
28
|
end
|
@@ -14,5 +14,12 @@ module Unite
|
|
14
14
|
include_examples "unit fractions"
|
15
15
|
|
16
16
|
end
|
17
|
+
|
18
|
+
describe "to_s and to_sym" do
|
19
|
+
subject { Property.new :name => name }
|
20
|
+
let(:name) { "mass" }
|
21
|
+
its(:to_s) { should == name }
|
22
|
+
its(:to_sym) { should == name.to_sym }
|
23
|
+
end
|
17
24
|
end
|
18
25
|
|
@@ -6,7 +6,6 @@ module Unite
|
|
6
6
|
describe SimpleUnit do
|
7
7
|
it { should ensure_inclusion_of(:dimension).in_array(Dimension::LIST) }
|
8
8
|
it { should validate_presence_of(:si_factor)}
|
9
|
-
it { should validate_presence_of(:name)}
|
10
9
|
it { should validate_presence_of(:dimension)}
|
11
10
|
|
12
11
|
%w{ $ £ € m }.each do |unit|
|
@@ -21,11 +20,19 @@ module Unite
|
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
23
|
+
describe "no dimension" do
|
24
|
+
subject { SimpleUnit.new(:name => "", :si_factor => 1, :dimension => :none) }
|
25
|
+
|
26
|
+
it { should be_valid }
|
27
|
+
its(:property_name) { should == :none }
|
28
|
+
|
29
|
+
end
|
30
|
+
|
24
31
|
describe "instance methods" do
|
25
32
|
let(:dimension) { :length }
|
26
33
|
subject { Fabricate.build :simple_unit, :name => "m", :si_factor => 1, :dimension => :length }
|
27
34
|
|
28
|
-
its(:dimension_vector) { should == Dimension::
|
35
|
+
its(:dimension_vector) { should == Dimension::VECTOR_LIST.map{|d| d == dimension ? 1 : 0}}
|
29
36
|
its(:property_name) { should == :distance }
|
30
37
|
|
31
38
|
end
|
data/spec/lookup_spec.rb
CHANGED
data/spec/quantity_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'spec_helper'
|
|
4
4
|
module Unite
|
5
5
|
describe Quantity do
|
6
6
|
|
7
|
-
subject { Quantity.new :expression => expression }
|
7
|
+
subject { Quantity.new :expression => expression }
|
8
8
|
|
9
9
|
include_examples "unit arithmetic"
|
10
10
|
include_examples "comparable unit"
|
@@ -12,5 +12,51 @@ module Unite
|
|
12
12
|
include_examples "convertable value"
|
13
13
|
include_examples "dimension vectors"
|
14
14
|
include_examples "unit fractions"
|
15
|
+
|
16
|
+
|
17
|
+
describe ".init" do
|
18
|
+
let(:quantity) { Quantity.new :expression => expression }
|
19
|
+
|
20
|
+
context "with unit" do
|
21
|
+
|
22
|
+
let(:expression) { "#{value}*#{unit}" }
|
23
|
+
let(:value) { 200.0 }
|
24
|
+
let(:unit) { "km" }
|
25
|
+
|
26
|
+
it "should initalize via expression" do
|
27
|
+
Quantity.init(value,unit).should == quantity
|
28
|
+
end
|
29
|
+
end
|
30
|
+
context "without unit" do
|
31
|
+
let(:expression) { "#{value}" }
|
32
|
+
let(:value) { 200.0 }
|
33
|
+
|
34
|
+
it "should initalize via expression" do
|
35
|
+
Quantity.init(value).should == quantity
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "with only unit" do
|
40
|
+
let(:expression) { "#{unit}" }
|
41
|
+
let(:unit) { 'L' }
|
42
|
+
|
43
|
+
it "should initalize via expression" do
|
44
|
+
Quantity.init(unit).should == quantity
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
context "with only unit" do
|
50
|
+
let(:expression) { "0.0*#{unit}" }
|
51
|
+
let(:unit) { 'L' }
|
52
|
+
let(:value) { nil }
|
53
|
+
|
54
|
+
it "should initalize via expression" do
|
55
|
+
Quantity.init(value,unit).should == quantity
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
15
60
|
end
|
16
61
|
end
|
62
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -4,12 +4,22 @@
|
|
4
4
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
5
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
6
|
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'ruby-debug'
|
10
|
+
puts "USING DEBUGGER"
|
11
|
+
rescue
|
12
|
+
puts "NOT USING DEBUGGER"
|
13
|
+
end
|
14
|
+
|
15
|
+
|
7
16
|
require 'rspec'
|
8
17
|
require 'shoulda/matchers/active_model'
|
9
18
|
require 'mocha'
|
10
19
|
require 'unite'
|
11
20
|
require 'fabrication'
|
12
21
|
|
22
|
+
|
13
23
|
# Requires supporting files with custom matchers and macros, etc,
|
14
24
|
# in ./support/ and its subdirectories.
|
15
25
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
@@ -60,10 +60,17 @@ shared_examples_for "comparable unit" do
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
context "with non
|
63
|
+
context "with non compatible units" do
|
64
64
|
let(:expression1) { "1*m" }
|
65
65
|
let(:expression2) { "1*g" }
|
66
66
|
it { should be_false }
|
67
67
|
end
|
68
68
|
end
|
69
|
+
|
70
|
+
|
71
|
+
describe "compatible_units" do
|
72
|
+
subject { described_class.new :expression => '1*m' }
|
73
|
+
its(:compatible_units) { subject.map(&:to_s).should include('km', 'm') }
|
74
|
+
end
|
75
|
+
|
69
76
|
end
|
@@ -14,6 +14,14 @@ shared_examples "convertable value" do
|
|
14
14
|
its(:unit) { should == 'm' }
|
15
15
|
end
|
16
16
|
|
17
|
+
context "with no unit" do
|
18
|
+
let(:from) { '1.0' }
|
19
|
+
let(:to) { '' }
|
20
|
+
|
21
|
+
its(:value) { should == 1.0 }
|
22
|
+
its(:unit) { should == '' }
|
23
|
+
end
|
24
|
+
|
17
25
|
context "with exponents on units" do
|
18
26
|
let(:from) { '1000000*m^2' }
|
19
27
|
let(:to) { 'km^2' }
|
@@ -39,11 +47,10 @@ shared_examples "convertable value" do
|
|
39
47
|
context "with value on the to" do
|
40
48
|
let(:from) { '2*km' }
|
41
49
|
let(:to) { '10*m' }
|
42
|
-
|
50
|
+
|
43
51
|
its(:value) { should == 2000.0 }
|
44
52
|
its(:unit) { should == 'm' }
|
45
53
|
end
|
46
54
|
end
|
47
55
|
|
48
|
-
|
49
56
|
end
|
@@ -1,41 +1,53 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
shared_examples "dimension integer" do
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
context "" do
|
4
|
+
subject { described_class.new }
|
5
|
+
describe "#dimension_int" do
|
6
|
+
before do
|
7
|
+
subject.stubs(:dimension_vector).returns(dimension_vector)
|
8
|
+
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
context "with a dimension" do
|
11
|
+
let(:dimension_vector) { [1,-2,0,0,0,0,0,0] }
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
Unite::Lookup.stubs(:find_property).with(dimension_int).returns(property_stub)
|
19
|
-
end
|
20
|
-
its(:property) { should == property_stub }
|
21
|
-
end
|
13
|
+
its(:dimension_int) { should == -39 }
|
14
|
+
end
|
15
|
+
context "without a dimension" do
|
16
|
+
|
17
|
+
let(:dimension_vector) { [0,0,0,0,0,0,0,0] }
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
context "with existing property" do
|
28
|
-
let(:property_name) { :yo }
|
29
|
-
let(:property_stub) { stub(:name => property_name) }
|
19
|
+
its(:dimension_int) { should == 0 }
|
20
|
+
end
|
21
|
+
end
|
30
22
|
|
31
|
-
|
23
|
+
describe "#property" do
|
24
|
+
let(:dimension_int) { 10 }
|
25
|
+
let(:property_stub) { stub }
|
26
|
+
before do
|
27
|
+
subject.stubs(:dimension_int => dimension_int)
|
28
|
+
Unite::Lookup.stubs(:find_property).with(dimension_int).returns(property_stub)
|
29
|
+
end
|
30
|
+
its(:property) { should == property_stub }
|
32
31
|
end
|
33
32
|
|
34
|
-
|
35
|
-
|
33
|
+
describe "#property_name" do
|
34
|
+
before do
|
35
|
+
subject.stubs(:property => property_stub)
|
36
|
+
end
|
37
|
+
context "with existing property" do
|
38
|
+
let(:property_name) { :yo }
|
39
|
+
let(:property_stub) { stub(:name => property_name) }
|
40
|
+
|
41
|
+
its(:property_name) { should == property_name }
|
42
|
+
end
|
36
43
|
|
37
|
-
|
44
|
+
context "with non existing property" do
|
45
|
+
let(:property_stub) { nil }
|
46
|
+
|
47
|
+
its(:property_name) { should == nil }
|
48
|
+
end
|
38
49
|
end
|
50
|
+
|
39
51
|
end
|
40
52
|
|
41
53
|
end
|
@@ -1,10 +1,27 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
|
-
|
2
|
+
shared_examples "dimension vectors" do
|
3
|
+
|
4
|
+
describe "generating" do
|
5
|
+
|
6
|
+
subject { described_class.new :expression => expression }
|
7
|
+
|
8
|
+
describe "something" do
|
4
9
|
|
5
10
|
let(:expression) { "m/s^2" }
|
6
11
|
its(:dimension_vector) { should == [1,-2,0,0,0,0,0,0] }
|
7
12
|
|
8
|
-
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
describe "when there is no unit" do
|
17
|
+
|
18
|
+
let(:expression) { "" }
|
19
|
+
its(:dimension_vector) { should == [0,0,0,0,0,0,0,0] }
|
20
|
+
|
21
|
+
end
|
9
22
|
|
10
23
|
end
|
24
|
+
|
25
|
+
it "should limit the powers of the vector to the max"
|
26
|
+
|
27
|
+
end
|
@@ -4,7 +4,8 @@ shared_examples_for "unit fractions" do
|
|
4
4
|
|
5
5
|
subject { described_class.new :expression => expression }
|
6
6
|
|
7
|
-
describe "required methods" do
|
7
|
+
describe "required methods" do
|
8
|
+
subject { described_class.new }
|
8
9
|
it { should respond_to(:value) }
|
9
10
|
it { should respond_to(:value=) }
|
10
11
|
it { should respond_to(:numerator) }
|
@@ -13,6 +14,14 @@ shared_examples_for "unit fractions" do
|
|
13
14
|
it { should respond_to(:denominator=) }
|
14
15
|
end
|
15
16
|
|
17
|
+
describe "big decimal" do
|
18
|
+
let(:expression) { '100.12345' }
|
19
|
+
let(:big_decimal) { BigDecimal(expression) }
|
20
|
+
|
21
|
+
its(:value) { should be_instance_of(BigDecimal) }
|
22
|
+
its(:value) {should == big_decimal }
|
23
|
+
end
|
24
|
+
|
16
25
|
describe "#expression" do
|
17
26
|
|
18
27
|
context "with blank string" do
|
@@ -55,13 +64,21 @@ shared_examples_for "unit fractions" do
|
|
55
64
|
its(:expression) { should == '10.0/s' }
|
56
65
|
end
|
57
66
|
|
58
|
-
context 'with
|
67
|
+
context 'with too many /' do
|
59
68
|
let(:expression) { 'km/kg/s' }
|
60
69
|
it "should raise exception" do
|
61
70
|
lambda { subject }.should raise_exception Unite::InvalidFormat
|
62
71
|
end
|
63
72
|
end
|
64
73
|
|
74
|
+
context 'with only / ' do
|
75
|
+
let(:expression) { '/' }
|
76
|
+
its(:unit) { should == '' }
|
77
|
+
its(:value) { should == 0.0 }
|
78
|
+
its(:expression) { should == '0.0' }
|
79
|
+
end
|
80
|
+
|
81
|
+
|
65
82
|
context "with spaces" do
|
66
83
|
let(:expression) { '10 * km / 5 *h ' }
|
67
84
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05
|
12
|
+
date: 2012-07-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
|
-
requirement: &
|
16
|
+
requirement: &70241757471700 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70241757471700
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activemodel
|
27
|
-
requirement: &
|
27
|
+
requirement: &70241757471120 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 3.0.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70241757471120
|
36
36
|
description: Unite provides extensions to your objects to support values with units
|
37
37
|
email:
|
38
38
|
- scott.ellard@gmail.com
|