unite 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|