seamusabshere-conversions 1.2.2 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/conversions.gemspec +1 -1
- data/lib/conversions.rb +19 -2
- data/lib/conversions/active_record_accessors.rb +2 -2
- data/lib/conversions/ext.rb +2 -5
- data/lib/conversions/unit.rb +3 -27
- data/test/accessor_test.rb +8 -0
- data/test/ext_test.rb +11 -7
- data/test/unit_test.rb +8 -8
- metadata +1 -1
data/conversions.gemspec
CHANGED
data/lib/conversions.rb
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
module Conversions
|
2
|
-
|
2
|
+
mattr_accessor :conversions
|
3
|
+
self.conversions = {}
|
4
|
+
|
5
|
+
def self.register(from, to, rate)
|
6
|
+
conversions[from] ||= {}
|
7
|
+
conversions[from][to] ||= {}
|
8
|
+
conversions[from][to] = rate
|
9
|
+
conversions[to] ||= {}
|
10
|
+
conversions[to][from] ||= {}
|
11
|
+
conversions[to][from] = 1 / rate
|
12
|
+
end
|
13
|
+
|
14
|
+
# This is ugly
|
15
|
+
{
|
3
16
|
:miles => {
|
4
17
|
:kilometres => 1.609344
|
5
18
|
},
|
@@ -21,7 +34,11 @@ module Conversions
|
|
21
34
|
:miles_per_gallon => {
|
22
35
|
:kilometres_per_litre => 0.425143707
|
23
36
|
}
|
24
|
-
}
|
37
|
+
}.each do |from_unit, to_units|
|
38
|
+
to_units.each do |to_unit, rate|
|
39
|
+
register(from_unit, to_unit, rate)
|
40
|
+
end
|
41
|
+
end
|
25
42
|
end
|
26
43
|
|
27
44
|
require 'conversions/unit'
|
@@ -39,10 +39,10 @@ module Conversions #:nodoc:
|
|
39
39
|
end
|
40
40
|
define_method "#{attribute}_in_#{options[:external]}" do
|
41
41
|
v = send(attribute)
|
42
|
-
v ? v.send(options[:internal]
|
42
|
+
v ? v.send(:convert, options[:internal], options[:external], :scale => options[:scale]) : nil
|
43
43
|
end
|
44
44
|
define_method "#{attribute}_in_#{options[:external]}=" do |v|
|
45
|
-
send("#{attribute}=", v.to_f.send(options[:external]
|
45
|
+
send("#{attribute}=", v.to_f.send(:convert, options[:external], options[:internal]))
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
data/lib/conversions/ext.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
1
1
|
module Conversions #:nodoc:
|
2
|
-
# Defines all the conversion methods (miles, kilometers, etc…)
|
3
2
|
module Ext
|
4
|
-
|
5
|
-
|
6
|
-
Unit.new self, method
|
7
|
-
end unless respond_to? method
|
3
|
+
def convert(from, to, options={})
|
4
|
+
Unit.new(self, from).to(to, options)
|
8
5
|
end
|
9
6
|
end
|
10
7
|
end
|
data/lib/conversions/unit.rb
CHANGED
@@ -14,43 +14,19 @@ module Conversions #:nodoc
|
|
14
14
|
#
|
15
15
|
# * _to_: The unit to convert to (ie. :kilometers)
|
16
16
|
# * _scale_: The number of digits behind the decimal point to you want to keep (Optional)
|
17
|
-
def to(to,
|
17
|
+
def to(to, options = {})
|
18
|
+
scale = options.delete(:scale)
|
18
19
|
value = @value * self.class.exchange_rate(@from, to)
|
19
20
|
scale.nil? ? value : (value * (10 ** scale)).round / (10 ** scale).to_f
|
20
21
|
end
|
21
22
|
|
22
23
|
def self.exchange_rate(from_unit, to_unit) #:nodoc:
|
23
24
|
return 1 if from_unit == to_unit
|
24
|
-
from =
|
25
|
+
from = Conversions.conversions[from_unit]
|
25
26
|
raise ArgumentError, "Can't convert from `#{from}', unknown unit" if from.nil?
|
26
27
|
to = from[to_unit]
|
27
28
|
raise ArgumentError, "Can't convert from `#{from_unit}' to `#{to_unit}', unknown unit" if to.nil?
|
28
29
|
to
|
29
30
|
end
|
30
|
-
|
31
|
-
def self.conversion #:nodoc:
|
32
|
-
map_conversion if !defined? @@conversion
|
33
|
-
@@conversion
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.register(from, to, value)
|
37
|
-
CONVERSION.merge!(from.to_sym => { to.to_sym => value.to_f })
|
38
|
-
map_conversion
|
39
|
-
Numeric.send :include, Conversions::Ext
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def self.map_conversion
|
45
|
-
@@conversion = {}
|
46
|
-
CONVERSION.each do |from, conversion|
|
47
|
-
conversion.each do |to, value|
|
48
|
-
@@conversion[from] ||= {}
|
49
|
-
@@conversion[from][to] = value
|
50
|
-
@@conversion[to] ||= {}
|
51
|
-
@@conversion[to][from] = 1.0 / value
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
31
|
end
|
56
32
|
end
|
data/test/accessor_test.rb
CHANGED
@@ -5,6 +5,9 @@ class Flight
|
|
5
5
|
attr_accessor :distance, :fuel_consumption
|
6
6
|
conversion_accessor :distance, :internal => :kilometres, :external => :miles
|
7
7
|
conversion_accessor :fuel_consumption, :internal => :litres, :external => :gallons, :scale => 2
|
8
|
+
|
9
|
+
Conversions.register(:kilometres, :leagues, 0.179985601)
|
10
|
+
conversion_accessor :distance, :internal => :kilometres, :external => :leagues, :scale => 2
|
8
11
|
end
|
9
12
|
|
10
13
|
class AccessorTest < Test::Unit::TestCase
|
@@ -27,4 +30,9 @@ class AccessorTest < Test::Unit::TestCase
|
|
27
30
|
@flight.fuel_consumption = 3400
|
28
31
|
assert_equal 898.18, @flight.fuel_consumption_in_gallons, DELTA
|
29
32
|
end
|
33
|
+
|
34
|
+
def test_register
|
35
|
+
@flight.distance = 1200
|
36
|
+
assert_in_delta 215.98, @flight.distance_in_leagues, DELTA
|
37
|
+
end
|
30
38
|
end
|
data/test/ext_test.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
3
|
class ExtTest < Test::Unit::TestCase
|
4
|
-
|
5
4
|
def test_conversions
|
6
|
-
assert_in_delta 1.609344, 1.
|
7
|
-
assert_in_delta 1.609344, 1.0.
|
8
|
-
assert_in_delta 0.45359237, 1.
|
9
|
-
assert_in_delta 0.00110231131092439, 1.
|
10
|
-
assert_in_delta 2.20462262184878, 1.
|
11
|
-
assert_in_delta 1, ( 1.
|
5
|
+
assert_in_delta 1.609344, 1.convert(:miles, :kilometres), DELTA
|
6
|
+
assert_in_delta 1.609344, 1.0.convert(:miles, :kilometres), DELTA
|
7
|
+
assert_in_delta 0.45359237, 1.convert(:pounds, :kilograms), DELTA
|
8
|
+
assert_in_delta 0.00110231131092439, 1.convert(:kilograms, :tons), DELTA
|
9
|
+
assert_in_delta 2.20462262184878, 1.convert(:kilograms, :pounds), DELTA
|
10
|
+
assert_in_delta 1, ( 1.convert(:kilograms, :pounds) * 1.convert(:pounds, :kilograms) ), DELTA
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_register
|
14
|
+
Conversions.register(:dollars, :cents, 100.0)
|
15
|
+
assert_in_delta 1000.0, 10.convert(:dollars, :cents), DELTA
|
12
16
|
end
|
13
17
|
end
|
data/test/unit_test.rb
CHANGED
@@ -11,7 +11,7 @@ class UnitTest < Test::Unit::TestCase
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_exchange_rate_for_identity_transform
|
14
|
-
Conversions
|
14
|
+
Conversions.conversions.keys.each do |unit|
|
15
15
|
assert_equal 1, Conversions::Unit.exchange_rate(unit, unit)
|
16
16
|
end
|
17
17
|
end
|
@@ -21,28 +21,28 @@ class UnitTest < Test::Unit::TestCase
|
|
21
21
|
assert_in_delta 16.09344, amount.to(:kilometres), DELTA
|
22
22
|
|
23
23
|
amount = Conversions::Unit.new(10.0, :miles)
|
24
|
-
assert_equal 16.09, amount.to(:kilometres, 2), DELTA
|
24
|
+
assert_equal 16.09, amount.to(:kilometres, :scale => 2), DELTA
|
25
25
|
|
26
26
|
amount = Conversions::Unit.new(10.0, :kilograms)
|
27
27
|
assert_in_delta 22.0462262184878, amount.to(:pounds), DELTA
|
28
28
|
|
29
29
|
amount = Conversions::Unit.new(10.0, :kilograms)
|
30
|
-
assert_equal 22.05, amount.to(:pounds, 2), DELTA
|
30
|
+
assert_equal 22.05, amount.to(:pounds, :scale => 2), DELTA
|
31
31
|
|
32
32
|
amount = Conversions::Unit.new(10.0, :miles_per_gallon)
|
33
|
-
assert_equal 4.25, amount.to(:kilometres_per_litre, 2), DELTA
|
33
|
+
assert_equal 4.25, amount.to(:kilometres_per_litre, :scale => 2), DELTA
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_identity_transforms
|
37
|
-
Conversions
|
38
|
-
assert_equal 1.0, Conversions::Unit.new(1.0, unit).to(unit, 2)
|
37
|
+
Conversions.conversions.each do |unit|
|
38
|
+
assert_equal 1.0, Conversions::Unit.new(1.0, unit).to(unit, :scale => 2)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
def test_register
|
43
|
-
Conversions
|
43
|
+
Conversions.register(:dollars, :cents, 100.0)
|
44
44
|
assert_in_delta 0.01, Conversions::Unit.exchange_rate(:cents, :dollars), DELTA
|
45
45
|
amount = Conversions::Unit.new(10.0, :dollars)
|
46
|
-
assert_equal 1000.0, amount.to(:cents, 2), DELTA
|
46
|
+
assert_equal 1000.0, amount.to(:cents, :scale => 2), DELTA
|
47
47
|
end
|
48
48
|
end
|