alchemist 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 09cdd7bc72d33ef49f70bfa21e7a6b98bc56ca35
4
- data.tar.gz: 5930f598e0adec3f2a8b3e3e2030fd61b9c48234
3
+ metadata.gz: f47215664aef5b08025bbf14fcb971c7b3d8d726
4
+ data.tar.gz: 92dcc4243340af6f1e4cacfb9593f292a8fdf16c
5
5
  SHA512:
6
- metadata.gz: 72133a2fa6b707b2e52e6cb5354506d364b176aaab25383b9db8f341be847fa2622a89e888fc3adeb8021f2e347b210961a2fca687d4278a5807da5d41827bc0
7
- data.tar.gz: b6ded515a9ebd212ace47ba64a91a9f44619f757457f27a8ae384edf380b327312e5223c444122ae5e3a2552c9d1330964c99e115f88c2e66ac6315f31fc8b3d
6
+ metadata.gz: 6f38ec388bac7cea190f0ace7bca99c2d5da955f4fa6ce4719cbca2cd4df603ccdfb53bc33e8125ff87169d77bb63873fe927c5e42be43b02549802cf163cd39
7
+ data.tar.gz: 085ddcae66c574428f71b8c9c2a2b149144ba80debc5585c88d82723e2bd0c0b96bd2fc71166d1920e2815adc242c989d4e49f59c852093d1bed281153ffb5e2
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- alchemist (0.1.5)
4
+ alchemist (0.1.6)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -2,132 +2,21 @@ require "alchemist/conversion_table"
2
2
  require "alchemist/measurement"
3
3
  require "alchemist/compound_measurement"
4
4
  require "alchemist/module_builder"
5
+ require "alchemist/configuration"
6
+ require "alchemist/library"
5
7
 
6
8
  module Alchemist
7
9
  autoload :Earth, "alchemist/objects/planets/earth"
8
10
 
9
- DATA_DIR = File.join(File.dirname(__FILE__), "alchemist", "data")
10
-
11
- DEFAULT_UNITS_FILE = File.join(DATA_DIR, "units.yml")
12
- DEFAULT_BINARY_PREFIXES_FILE = File.join(DATA_DIR, "binary_prefixes.yml")
13
- DEFAULT_SI_UNITS_FILE = File.join(DATA_DIR, "si_units.yml")
14
- DEFAULT_UNIT_PREFIXES_FILE = File.join(DATA_DIR, "unit_prefixes.yml")
15
-
16
11
  def self.setup category = nil
17
12
  if category
18
13
  Numeric.send(:include, ModuleBuilder.new(category).build)
19
14
  else
20
- conversion_table.keys.each { |category| Numeric.send(:include, ModuleBuilder.new(category).build) }
15
+ library.categories.each { |category| Numeric.send(:include, ModuleBuilder.new(category).build) }
21
16
  end
22
17
  end
23
18
 
24
19
  def self.measure value, unit, exponent = 1.0
25
20
  Measurement.new value, unit, exponent
26
21
  end
27
-
28
- def self.has_measurement? name
29
- conversions.keys.include? name.to_sym
30
- end
31
-
32
- def self.measurement_for name
33
- conversions[ name.to_sym ]
34
- end
35
-
36
- def self.register(type, names, value)
37
- names = Array(names)
38
- value = value.is_a?(Measurement) ? value.base(type) : value
39
- Alchemist.conversion_table[type] ||= {}
40
-
41
- names.each do |name|
42
- conversions[name] ||= []
43
- conversions[name] << type
44
- Alchemist.conversion_table[type][name] = value
45
- end
46
- end
47
-
48
- def self.parse_prefix(unit)
49
- matches = unit.to_s.match(prefix_matcher)
50
- prefix, parsed_unit = matches.captures
51
-
52
- if prefix && si_units.include?(parsed_unit)
53
- value = prefixed_value_for(prefix.to_sym, parsed_unit)
54
- [value, parsed_unit.to_sym]
55
- else
56
- [1, unit]
57
- end
58
- end
59
-
60
- def self.register_operation_conversions type, other_type, operation, converted_type
61
- operator_actions[operation] ||= []
62
- operator_actions[operation] << [type, other_type, converted_type]
63
- end
64
-
65
- def self.operator_actions
66
- @operator_actions ||= {}
67
- end
68
-
69
- def self.binary_prefixes
70
- @binary_prefixes ||= YAML.load_file(DEFAULT_BINARY_PREFIXES_FILE)
71
- end
72
-
73
- def self.si_units
74
- @si_units ||= YAML.load_file(DEFAULT_SI_UNITS_FILE)
75
- end
76
-
77
- def self.unit_prefixes
78
- @unit_prefixes ||= YAML.load_file(DEFAULT_UNIT_PREFIXES_FILE)
79
- end
80
-
81
- def self.use_si
82
- @use_si ||= false
83
- end
84
-
85
- def self.use_si= use_si
86
- @use_si = use_si
87
- end
88
-
89
- def self.load_conversion_table(filename=DEFAULT_UNITS_FILE)
90
- @conversion_table = ConversionTable.new.load_all(filename)
91
- end
92
-
93
- def self.conversion_table
94
- @conversion_table ||= load_conversion_table
95
- end
96
-
97
- def self.conversions
98
- @conversions ||= load_conversions
99
- end
100
-
101
-
102
- private
103
-
104
- def self.use_binary_prefix? unit
105
- !use_si && measurement_for(unit).include?(:information_storage)
106
- end
107
-
108
- def self.prefix_matcher
109
- @prefix_matcher ||= begin
110
- prefix_keys = unit_prefixes.keys.map(&:to_s).sort{ |a,b| b.length <=> a.length }
111
- %r{^(#{prefix_keys.join('|')})?(.+)}
112
- end
113
- end
114
-
115
- def self.prefixed_value_for prefix, unit
116
- if use_binary_prefix? unit
117
- binary_prefixes[prefix]
118
- else
119
- unit_prefixes[prefix]
120
- end
121
- end
122
-
123
- def self.load_conversions
124
- conversions = {}
125
- conversion_table.each do |type, table_conversions|
126
- table_conversions.each do |name, value|
127
- conversions[name] ||= []
128
- conversions[name] << type
129
- end
130
- end
131
- conversions
132
- end
133
22
  end
@@ -42,7 +42,7 @@ module Alchemist
42
42
 
43
43
  def should_remove_units? numerator, denominator
44
44
  return false if numerator.is_a?(Numeric) || denominator.is_a?(Numeric)
45
- (Alchemist.measurement_for(numerator.unit_name) & Alchemist.measurement_for(denominator.unit_name)).length > 0
45
+ (Alchemist.library.measurement_for(numerator.unit_name) & Alchemist.library.measurement_for(denominator.unit_name)).length > 0
46
46
  end
47
47
 
48
48
  def set_coefficients
@@ -56,7 +56,7 @@ module Alchemist
56
56
  end
57
57
 
58
58
  def method_missing(method, *attrs, &block)
59
- if Alchemist.measurement_for(method)
59
+ if Alchemist.library.measurement_for(method)
60
60
  @denominators << Alchemist.measure(1, method)
61
61
  consolidate
62
62
  end
@@ -0,0 +1,26 @@
1
+ require 'singleton'
2
+
3
+ module Alchemist
4
+ def self.config
5
+ Configuration.instance
6
+ end
7
+
8
+ class Configuration
9
+ DATA_DIR = File.join(File.dirname(__FILE__), "data")
10
+ DEFAULT_UNITS_FILE = File.join(DATA_DIR, "units.yml")
11
+ DEFAULT_SI_UNITS_FILE = File.join(DATA_DIR, "si_units.yml")
12
+ DEFAULT_BINARY_PREFIXES_FILE = File.join(DATA_DIR, "binary_prefixes.yml")
13
+ DEFAULT_UNIT_PREFIXES_FILE = File.join(DATA_DIR, "unit_prefixes.yml")
14
+
15
+ include Singleton
16
+
17
+ attr_accessor :use_si
18
+ def initialize
19
+ @use_si = false
20
+ end
21
+
22
+ def use_si?
23
+ @use_si
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,86 @@
1
+ require 'singleton'
2
+
3
+ module Alchemist
4
+ def self.library
5
+ Library.instance
6
+ end
7
+
8
+ class Library
9
+ include Singleton
10
+
11
+ attr_reader :si_units, :unit_prefixes, :conversion_table, :binary_prefixes
12
+
13
+ def initialize
14
+ @conversion_table = load_conversion_table
15
+ @si_units = YAML.load_file(Configuration::DEFAULT_SI_UNITS_FILE)
16
+ @unit_prefixes = YAML.load_file(Configuration::DEFAULT_UNIT_PREFIXES_FILE)
17
+ @binary_prefixes = YAML.load_file(Configuration::DEFAULT_BINARY_PREFIXES_FILE)
18
+ end
19
+
20
+ def categories
21
+ @conversion_table.keys
22
+ end
23
+
24
+ def unit_names category
25
+ @conversion_table[category.to_sym].map { |values| values[0] }
26
+ end
27
+
28
+ def measurement_for unit_name
29
+ conversions[ unit_name.to_sym ]
30
+ end
31
+
32
+ def conversions
33
+ @conversions ||= load_conversions
34
+ end
35
+
36
+ def conversion_base_for(unit_type, unit_name)
37
+ @conversion_table[unit_type][unit_name]
38
+ end
39
+
40
+ def has_measurement? name
41
+ conversions.keys.include? name.to_sym
42
+ end
43
+
44
+ def register_operation_conversions type, other_type, operation, converted_type
45
+ operator_actions[operation] ||= []
46
+ operator_actions[operation] << [type, other_type, converted_type]
47
+ end
48
+
49
+ def operator_actions
50
+ @operator_actions ||= {}
51
+ end
52
+
53
+ def load_conversion_table(filename=Configuration::DEFAULT_UNITS_FILE)
54
+ if new_table = ConversionTable.new.load_all(filename)
55
+ @conversion_table = new_table
56
+ else
57
+ @conversion_table ||= load_conversion_table
58
+ end
59
+ end
60
+
61
+ def register(type, names, value)
62
+ names = Array(names)
63
+ value = value.is_a?(Measurement) ? value.base(type) : value
64
+ conversion_table[type] ||= {}
65
+
66
+ names.each do |name|
67
+ conversions[name] ||= []
68
+ conversions[name] << type
69
+ conversion_table[type][name] = value
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def load_conversions
76
+ conversions = {}
77
+ conversion_table.each do |type, table_conversions|
78
+ table_conversions.each do |name, value|
79
+ conversions[name] ||= []
80
+ conversions[name] << type
81
+ end
82
+ end
83
+ conversions
84
+ end
85
+ end
86
+ end
@@ -18,7 +18,7 @@ module Alchemist
18
18
 
19
19
  def to type = nil
20
20
  if type
21
- convertor.send(type)
21
+ convertor.send(type, exponent)
22
22
  else
23
23
  convertor
24
24
  end
@@ -27,24 +27,28 @@ module Alchemist
27
27
  def + measurement
28
28
  ensure_shared_type!(measurement)
29
29
  converted = measurement.to(unit_name)
30
- Measurement.new(value + converted.value, unit_name, exponent)
30
+ remeasure(value + converted.value)
31
31
  end
32
32
 
33
33
  def - measurement
34
34
  ensure_shared_type!(measurement)
35
35
  converted = measurement.to(unit_name)
36
- Measurement.new(value - converted.value, unit_name, exponent)
36
+ remeasure(value - converted.value)
37
37
  end
38
38
 
39
39
  def / measurement
40
- ensure_shared_type!(measurement)
41
- dividend = measurement.is_a?(Measurement) ? measurement.to(unit_name).to_f / exponent : measurement
42
- Measurement.new(value / dividend, unit_name, exponent).value
40
+ converted = remeasure(value / dividend(measurement))
41
+
42
+ if measurement.is_a?(Measurement)
43
+ converted.value
44
+ else
45
+ converted
46
+ end
43
47
  end
44
48
 
45
49
  def * multiplicand
46
50
  if multiplicand.is_a?(Numeric)
47
- Measurement.new(value * multiplicand, unit_name, exponent)
51
+ remeasure(value * multiplicand)
48
52
  else
49
53
  try_raising_dimension(multiplicand)
50
54
  end
@@ -52,39 +56,68 @@ module Alchemist
52
56
 
53
57
  def base unit_type
54
58
  conversion_base = conversion_base_for(unit_type)
55
- convert_to_base conversion_base
59
+ convert_to_base(conversion_base)
56
60
  end
57
61
 
58
62
  def to_s
59
- value.to_s
63
+ to_f.to_s
60
64
  end
61
65
 
62
66
  def to_i
63
- value.to_i
67
+ to_f.to_i
64
68
  end
65
69
 
66
70
  def to_f
67
- @value
71
+ @value * exponent
68
72
  end
69
73
 
70
74
  def <=>(other)
71
- (self.to_f * exponent).to_f <=> other.to(unit_name).to_f
75
+ self.to_f <=> other.to(unit_name).to_f
72
76
  end
73
77
 
74
78
  def types
75
- Alchemist.measurement_for(unit_name)
79
+ library.measurement_for(unit_name)
76
80
  end
77
81
 
78
82
  def shared_types other_unit_name
79
- types & Alchemist.measurement_for(other_unit_name)
83
+ types & library.measurement_for(other_unit_name)
80
84
  end
81
85
 
82
86
  def coerce(number)
83
87
  [self, number]
84
88
  end
85
89
 
90
+ def round(*args)
91
+ remeasure(value.round(*args))
92
+ end
93
+
94
+ def ceil(*args)
95
+ remeasure(value.ceil(*args))
96
+ end
97
+
98
+ def floor(*args)
99
+ remeasure(value.floor(*args))
100
+ end
101
+
86
102
  private
87
103
 
104
+ def dividend measurement
105
+ if measurement.is_a?(Measurement)
106
+ ensure_shared_type!(measurement)
107
+ measurement.to(unit_name).to_f / exponent
108
+ else
109
+ measurement
110
+ end
111
+ end
112
+
113
+ def remeasure value
114
+ Measurement.new(value, unit_name, exponent)
115
+ end
116
+
117
+ def library
118
+ Library.instance
119
+ end
120
+
88
121
  def ensure_shared_type! measurement
89
122
  if !has_shared_types?(measurement.unit_name)
90
123
  incompatible_types
@@ -100,7 +133,7 @@ module Alchemist
100
133
  end
101
134
 
102
135
  def conversion_base_for unit_type
103
- Alchemist.conversion_table[unit_type][unit_name]
136
+ library.conversion_base_for(unit_type, unit_name)
104
137
  end
105
138
 
106
139
  def has_shared_types? other_unit_name
@@ -109,7 +142,7 @@ module Alchemist
109
142
 
110
143
  def try_raising_dimension(measurement)
111
144
  valid_types = shared_types(measurement.unit_name)
112
- Alchemist.operator_actions[:*].each do |s1, s2, new_type|
145
+ library.operator_actions[:*].each do |s1, s2, new_type|
113
146
  if (valid_types & [s1, s2]).any?
114
147
  return Alchemist.measure(value * measurement.to_f, new_type)
115
148
  end
@@ -1,4 +1,5 @@
1
1
  require 'bigdecimal'
2
+ require 'alchemist/prefix_parser'
2
3
 
3
4
  module Alchemist
4
5
  class MeasurementConvertor
@@ -7,27 +8,42 @@ module Alchemist
7
8
  end
8
9
 
9
10
  def method_missing method, *args, &block
10
- exponent, unit_name = Alchemist.parse_prefix(method)
11
- convert(from.shared_types(unit_name), unit_name, exponent)
11
+ exponent, unit_name = PrefixParser.new.parse(method)
12
+ convert(from.shared_types(unit_name), unit_name, args.first || exponent)
12
13
  end
13
14
 
14
15
  private
15
16
  attr_reader :from
16
17
 
18
+ def library
19
+ Library.instance
20
+ end
21
+
17
22
  def convert types, unit_name, exponent
18
23
  if type = types[0]
19
- conversion_base = BigDecimal.new(from.base(type).to_s)
20
- conversion_factor = Alchemist.conversion_table[type][unit_name]
21
- if proc_based?(conversion_factor)
22
- Measurement.new(conversion_factor[1].call(conversion_base), unit_name, exponent)
23
- else
24
- Measurement.new(conversion_base / BigDecimal.new(conversion_factor.to_s), unit_name, exponent)
25
- end
24
+ convert_from_type(type, unit_name, exponent)
26
25
  else
27
26
  raise Exception, "Incompatible Types"
28
27
  end
29
28
  end
30
29
 
30
+ def convert_from_type(type, unit_name, exponent)
31
+ conversion_base = BigDecimal.new(from.base(type).to_s)
32
+ conversion_factor = library.conversion_base_for(type, unit_name)
33
+
34
+ value = value_from(conversion_base, conversion_factor)
35
+ Measurement.new(value / exponent, unit_name, exponent)
36
+ end
37
+
38
+ def value_from(base, factor)
39
+ if proc_based?(factor)
40
+ factor[1].call(base)
41
+ else
42
+ base / BigDecimal.new(factor.to_s)
43
+ end
44
+
45
+ end
46
+
31
47
  def proc_based? conversion_factor
32
48
  conversion_factor.is_a? Array
33
49
  end
@@ -21,12 +21,12 @@ module Alchemist
21
21
  end
22
22
 
23
23
  def unit_names
24
- Alchemist.conversion_table[category.to_sym].map { |values| values[0] }
24
+ Library.instance.unit_names(category)
25
25
  end
26
26
 
27
27
  def prefixes_with_value(name)
28
- if Alchemist.si_units.include?(name.to_s)
29
- Alchemist.unit_prefixes
28
+ if Library.instance.si_units.include?(name.to_s)
29
+ Library.instance.unit_prefixes
30
30
  else
31
31
  []
32
32
  end
@@ -0,0 +1,42 @@
1
+ module Alchemist
2
+ class PrefixParser
3
+ def parse(unit)
4
+ matches = unit.to_s.match(prefix_matcher)
5
+ prefix, parsed_unit = matches.captures
6
+
7
+ if prefix && library.si_units.include?(parsed_unit)
8
+ value = prefixed_value_for(prefix.to_sym, parsed_unit)
9
+ [value, parsed_unit.to_sym]
10
+ else
11
+ [1, unit]
12
+ end
13
+ end
14
+
15
+ def prefix_matcher
16
+ @prefix_matcher ||= generate_prefix_matcher
17
+ end
18
+
19
+ private
20
+
21
+ def library
22
+ Alchemist.library
23
+ end
24
+
25
+ def generate_prefix_matcher
26
+ prefix_keys = library.unit_prefixes.keys.map(&:to_s).sort{ |a,b| b.length <=> a.length }
27
+ %r{^(#{prefix_keys.join('|')})?(.+)}
28
+ end
29
+
30
+ def prefixed_value_for prefix, unit
31
+ if use_binary_prefix? unit
32
+ library.binary_prefixes[prefix]
33
+ else
34
+ library.unit_prefixes[prefix]
35
+ end
36
+ end
37
+
38
+ def use_binary_prefix? unit
39
+ !Alchemist.config.use_si? && library.measurement_for(unit).include?(:information_storage)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ require 'alchemist'
2
+
3
+ Alchemist.setup
@@ -1,3 +1,3 @@
1
1
  module Alchemist
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.7"
3
3
  end
@@ -3,14 +3,11 @@ require 'spec_helper'
3
3
  describe Alchemist do
4
4
 
5
5
  it "sets up Numeric" do
6
- category_module = double()
7
- module_builder = double()
8
- module_builder.should_receive(:build).and_return(category_module)
9
- fake_module = double()
10
- fake_module.should_receive(:include).with(category_module)
11
- Alchemist::ModuleBuilder.should_receive(:new).with('distance').and_return(module_builder)
12
- stub_const("Numeric", fake_module)
6
+ category_module = build_category_module
7
+ fake_numeric = build_fake_numeric
13
8
  Alchemist.setup('distance')
9
+ expect(Alchemist::ModuleBuilder).to have_received(:new).with('distance')
10
+ expect(fake_numeric).to have_received(:include).with(category_module)
14
11
  end
15
12
 
16
13
  it "creates a measurement" do
@@ -18,34 +15,18 @@ describe Alchemist do
18
15
  expect(unit).to eq(1.meter)
19
16
  end
20
17
 
21
- it "knows if it has a measurement" do
22
- expect(Alchemist.has_measurement?(:meter)).to be_true
18
+ def build_category_module
19
+ double.tap do |category_module|
20
+ module_builder = double()
21
+ allow(module_builder).to receive(:build) { category_module }
22
+ Alchemist::ModuleBuilder.stub(:new).and_return(module_builder)
23
+ end
23
24
  end
24
25
 
25
- it "knows if it doesn't have a measurement" do
26
- expect(Alchemist.has_measurement?(:wombat)).to be_false
27
- end
28
-
29
- it "can register units" do
30
- Alchemist.register :quux, :qaat, 1.0
31
- Alchemist.register :quux, :quut, 3.0
32
- expect(Alchemist.conversion_table[:quux]).to eq({:qaat=>1.0, :quut=>3.0})
33
- end
34
-
35
- it "can register units with plural names" do
36
- Alchemist.register(:beards, [:beard_second, :beard_seconds], 1.0)
37
- expect(Alchemist.conversion_table[:beards]).to eq({:beard_second=>1.0, :beard_seconds=>1.0})
38
- end
39
-
40
- it "can register units with formulas" do
41
- to = lambda { |t| t + 1 }
42
- from = lambda { |t| t - 1 }
43
- Alchemist.register(:yetis, :yeti, [to, from])
44
- expect(Alchemist.conversion_table[:yetis]).to eq({:yeti => [to, from]})
45
- end
46
-
47
- it "can parse a prefix" do
48
- parsed = Alchemist.parse_prefix(:kilometer)
49
- expect(parsed).to eq([1000.0, :meter])
26
+ def build_fake_numeric
27
+ double.tap do |fake_module|
28
+ allow(fake_module).to receive(:include)
29
+ stub_const("Numeric", fake_module)
30
+ end
50
31
  end
51
32
  end
@@ -17,11 +17,11 @@ module Alchemist
17
17
  end
18
18
 
19
19
  def conversion_table
20
- Alchemist::conversion_table
20
+ Alchemist.library.conversion_table
21
21
  end
22
22
 
23
23
  def load_file file
24
- Alchemist::load_conversion_table file
24
+ Alchemist.library.load_conversion_table file
25
25
  end
26
26
 
27
27
  def good_file
@@ -33,7 +33,7 @@ module Alchemist
33
33
  end
34
34
 
35
35
  def default_file
36
- File.join(File.dirname(__FILE__), "..", "lib", "alchemist", "units.yml")
36
+ Configuration::DEFAULT_UNITS_FILE
37
37
  end
38
38
  end
39
39
  end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ module Alchemist
4
+ describe Library do
5
+ it "returns a list of the binary prefixes" do
6
+ expect(library.binary_prefixes[:kilo]).to eq(1024.0)
7
+ end
8
+
9
+ it "can register units with formulas" do
10
+ to = lambda { |t| t + 1 }
11
+ from = lambda { |t| t - 1 }
12
+ library.register(:yetis, :yeti, [to, from])
13
+ expect(library.conversion_table[:yetis]).to eq({:yeti => [to, from]})
14
+ end
15
+
16
+ it "can register units with plural names" do
17
+ library.register(:beards, [:beard_second, :beard_seconds], 1.0)
18
+ expect(library.conversion_table[:beards]).to eq({:beard_second=>1.0, :beard_seconds=>1.0})
19
+ end
20
+
21
+ it "can register units" do
22
+ library.register :quux, :qaat, 1.0
23
+ library.register :quux, :quut, 3.0
24
+ expect(library.conversion_table[:quux]).to eq({:qaat=>1.0, :quut=>3.0})
25
+ end
26
+
27
+ it "knows if it has a measurement" do
28
+ expect(library.has_measurement?(:meter)).to be_true
29
+ end
30
+
31
+ it "knows if it doesn't have a measurement" do
32
+ expect(library.has_measurement?(:wombat)).to be_false
33
+ end
34
+
35
+ def library
36
+ Library.instance
37
+ end
38
+ end
39
+ end
@@ -15,12 +15,13 @@ module Alchemist
15
15
  end
16
16
 
17
17
  it "can be multiplied" do
18
- Alchemist.register_operation_conversions(:distance, :distance, :*, :square_meters)
18
+ Alchemist.library.register_operation_conversions(:distance, :distance, :*, :square_meters)
19
19
  expect(1.meter * 1.meter).to eq(1.square_meter)
20
20
  end
21
21
 
22
22
  it "can be divided" do
23
23
  expect(2.meters / 1.meter).to eq(2.0)
24
+ expect(4.meters / 2).to eq(2.meters)
24
25
  end
25
26
 
26
27
  it "can be added" do
@@ -55,6 +56,25 @@ module Alchemist
55
56
  expect(1.meter.coerce(10)).to eq([1.meter, 10])
56
57
  end
57
58
 
59
+ it "can round measurements" do
60
+ expect(1.5.meters.round).to eq(2.meters)
61
+ end
62
+
63
+ it "can ceil measurements" do
64
+ expect(1.4.meters.ceil).to eq(2.meters)
65
+ end
66
+
67
+ it "can floor measurments" do
68
+ expect(1.6.meters.floor).to eq(1.meter)
69
+ end
70
+
71
+ it "handles exponents correctly" do
72
+ expect(1.kg.to.kg).to eq(1.kg)
73
+ expect(1.kg.to(:kg)).to eq(1.kg)
74
+ expect(1.kg.to.kg.to.g).to eq(1000.g)
75
+ expect(1.kg.to.g.to.kg).to eq(1.kg)
76
+ end
77
+
58
78
  describe '#geospatial' do
59
79
 
60
80
  it 'should convert angles to meters' do
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ module Alchemist
4
+ describe PrefixParser do
5
+ it "can parse a prefix" do
6
+ parsed = PrefixParser.new.parse(:kilometer)
7
+ expect(parsed).to eq([1000.0, :meter])
8
+ end
9
+ end
10
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemist
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Mongeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-02 00:00:00.000000000 Z
11
+ date: 2013-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -53,23 +53,29 @@ files:
53
53
  - alchemist.gemspec
54
54
  - lib/alchemist.rb
55
55
  - lib/alchemist/compound_measurement.rb
56
+ - lib/alchemist/configuration.rb
56
57
  - lib/alchemist/conversion_table.rb
57
58
  - lib/alchemist/data/binary_prefixes.yml
58
59
  - lib/alchemist/data/si_units.yml
59
60
  - lib/alchemist/data/unit_prefixes.yml
60
61
  - lib/alchemist/data/units.yml
61
62
  - lib/alchemist/geospatial.rb
63
+ - lib/alchemist/library.rb
62
64
  - lib/alchemist/measurement.rb
63
65
  - lib/alchemist/measurement_convertor.rb
64
66
  - lib/alchemist/module_builder.rb
65
67
  - lib/alchemist/objects/planets/earth.rb
68
+ - lib/alchemist/prefix_parser.rb
69
+ - lib/alchemist/setup.rb
66
70
  - lib/alchemist/version.rb
67
71
  - spec/alchemist_spec.rb
68
72
  - spec/compound_measurement_spec.rb
69
73
  - spec/conversion_table_spec.rb
70
74
  - spec/fixtures/bad_test.yml
71
75
  - spec/fixtures/good_test.yml
76
+ - spec/library_spec.rb
72
77
  - spec/measurement_spec.rb
78
+ - spec/prefix_parser_spec.rb
73
79
  - spec/spec_helper.rb
74
80
  homepage: http://github.com/halogenandtoast/alchemist
75
81
  licenses:
@@ -101,6 +107,8 @@ test_files:
101
107
  - spec/conversion_table_spec.rb
102
108
  - spec/fixtures/bad_test.yml
103
109
  - spec/fixtures/good_test.yml
110
+ - spec/library_spec.rb
104
111
  - spec/measurement_spec.rb
112
+ - spec/prefix_parser_spec.rb
105
113
  - spec/spec_helper.rb
106
114
  has_rdoc: