alchemist 0.1.5 → 0.1.6

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.
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ module Alchemist
4
+ describe CompoundMeasurement do
5
+ it "can handle compound units" do
6
+ expect(30.miles).to eq(10.miles.per.second * 3.seconds)
7
+ end
8
+
9
+ it "can handle elimination of a unit" do
10
+ expect(4.m.per.m).to eq(4)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ module Alchemist
4
+ describe ConversionTable do
5
+ after(:each) do
6
+ load_file default_file
7
+ end
8
+
9
+ it "should use the new file" do
10
+ load_file good_file
11
+ expect(conversion_table[:volume]).to eq({ litre: 1.0, swallow: 0.006, pint: 0.5506105 })
12
+ end
13
+
14
+ it "should use the defaults when it fails to load" do
15
+ load_file bad_file
16
+ expect(5280.feet).to eq(1.mile.to.feet)
17
+ end
18
+
19
+ def conversion_table
20
+ Alchemist::conversion_table
21
+ end
22
+
23
+ def load_file file
24
+ Alchemist::load_conversion_table file
25
+ end
26
+
27
+ def good_file
28
+ File.join(File.dirname(__FILE__), "fixtures", "good_test.yml")
29
+ end
30
+
31
+ def bad_file
32
+ File.join(File.dirname(__FILE__), "fixtures", "bad_test.yml")
33
+ end
34
+
35
+ def default_file
36
+ File.join(File.dirname(__FILE__), "..", "lib", "alchemist", "units.yml")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,11 @@
1
+ ---
2
+ :time:
3
+ :second: 1.0
4
+ :GY: 7884000000000000000.0
5
+ :cow:
6
+ :goat: 1.0
7
+ :dog
8
+ :volume:
9
+ :litre: 1.0
10
+ :swallow: 0.006
11
+ :pint: 0.5506105
@@ -0,0 +1,11 @@
1
+ ---
2
+ :time:
3
+ :second: 1.0
4
+ :GY: 7884000000000000000.0
5
+ :cow:
6
+ :goat: 1.0
7
+ :dog: 5.6
8
+ :volume:
9
+ :litre: 1.0
10
+ :swallow: 0.006
11
+ :pint: 0.5506105
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ module Alchemist
4
+ describe Measurement do
5
+ it "is comparable" do
6
+ expect(1.m).to eq(1.meter)
7
+ end
8
+
9
+ it "can be converted" do
10
+ expect(5.grams).to eq(0.005.kilograms)
11
+ end
12
+
13
+ it "can be converted with a formula" do
14
+ expect(222.5.celsius.to.fahrenheit).to eq(432.5.fahrenheit)
15
+ end
16
+
17
+ it "can be multiplied" do
18
+ Alchemist.register_operation_conversions(:distance, :distance, :*, :square_meters)
19
+ expect(1.meter * 1.meter).to eq(1.square_meter)
20
+ end
21
+
22
+ it "can be divided" do
23
+ expect(2.meters / 1.meter).to eq(2.0)
24
+ end
25
+
26
+ it "can be added" do
27
+ expect(2.meters + 1.meter).to eq(3.meters)
28
+ end
29
+
30
+ it "can add different measurements" do
31
+ expect(5.meters + 2.inches).to eq(5.0508.meters)
32
+ end
33
+
34
+ it "can be subtracted" do
35
+ expect(3.meters - 2.meters).to eq(1.meter)
36
+ end
37
+
38
+ it "can subtract different measurements" do
39
+ expect(5.meters - 2.inches).to eq(4.9492.meters)
40
+ end
41
+
42
+ it "can provide an integer value" do
43
+ expect(10.meters.to_i).to eq(10)
44
+ end
45
+
46
+ it "can provide a float value" do
47
+ expect(10.meters.to_f).to eq(10.0)
48
+ end
49
+
50
+ it "can provide a string value" do
51
+ expect(10.meters.to_s).to eq("10.0")
52
+ end
53
+
54
+ it "can coerce correctly" do
55
+ expect(1.meter.coerce(10)).to eq([1.meter, 10])
56
+ end
57
+
58
+ describe '#geospatial' do
59
+
60
+ it 'should convert angles to meters' do
61
+ expect(1.degree.geospatial).to eq(111318.84502145034.meters)
62
+ end
63
+
64
+ it 'should convert distances to radians' do
65
+ expect(1.mile.geospatial).to eq(0.00025232341920007525.radians)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..", "lib")
2
+
3
+ require 'alchemist'
4
+ require 'alchemist/geospatial'
5
+
6
+ Alchemist.setup
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.5
4
+ version: 0.1.6
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-03-14 00:00:00.000000000 Z
11
+ date: 2013-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description: Conversions... like you've never seen them before!!
28
42
  email:
29
43
  - halogenandtoast@gmail.com
@@ -34,26 +48,32 @@ files:
34
48
  - .gitignore
35
49
  - Gemfile
36
50
  - Gemfile.lock
37
- - LICENSE.txt
38
51
  - README.md
39
52
  - Rakefile
40
53
  - alchemist.gemspec
41
54
  - lib/alchemist.rb
42
- - lib/alchemist/binary_prefixes.rb
43
- - lib/alchemist/compound.rb
44
- - lib/alchemist/compound_numeric_conversion.rb
45
- - lib/alchemist/numeric_conversion.rb
46
- - lib/alchemist/numeric_ext.rb
47
- - lib/alchemist/si_units.rb
48
- - lib/alchemist/unit_prefixes.rb
49
- - lib/alchemist/units.rb
50
- - lib/alchemist/units.yml
55
+ - lib/alchemist/compound_measurement.rb
56
+ - lib/alchemist/conversion_table.rb
57
+ - lib/alchemist/data/binary_prefixes.yml
58
+ - lib/alchemist/data/si_units.yml
59
+ - lib/alchemist/data/unit_prefixes.yml
60
+ - lib/alchemist/data/units.yml
61
+ - lib/alchemist/geospatial.rb
62
+ - lib/alchemist/measurement.rb
63
+ - lib/alchemist/measurement_convertor.rb
64
+ - lib/alchemist/module_builder.rb
65
+ - lib/alchemist/objects/planets/earth.rb
51
66
  - lib/alchemist/version.rb
52
- - test/alchemist_compound_test.rb
53
- - test/alchemist_measurement_test.rb
54
- - test/alchemist_test.rb
67
+ - spec/alchemist_spec.rb
68
+ - spec/compound_measurement_spec.rb
69
+ - spec/conversion_table_spec.rb
70
+ - spec/fixtures/bad_test.yml
71
+ - spec/fixtures/good_test.yml
72
+ - spec/measurement_spec.rb
73
+ - spec/spec_helper.rb
55
74
  homepage: http://github.com/halogenandtoast/alchemist
56
- licenses: []
75
+ licenses:
76
+ - MIT
57
77
  metadata: {}
58
78
  post_install_message:
59
79
  rdoc_options: []
@@ -76,6 +96,11 @@ signing_key:
76
96
  specification_version: 4
77
97
  summary: Conversions... like you've never seen them before!
78
98
  test_files:
79
- - test/alchemist_compound_test.rb
80
- - test/alchemist_measurement_test.rb
81
- - test/alchemist_test.rb
99
+ - spec/alchemist_spec.rb
100
+ - spec/compound_measurement_spec.rb
101
+ - spec/conversion_table_spec.rb
102
+ - spec/fixtures/bad_test.yml
103
+ - spec/fixtures/good_test.yml
104
+ - spec/measurement_spec.rb
105
+ - spec/spec_helper.rb
106
+ has_rdoc:
@@ -1,22 +0,0 @@
1
- Copyright (c) 2013 halogenandtoast
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,25 +0,0 @@
1
- module Alchemist
2
- def self.binary_prefixes
3
- {
4
- :yotta => 2.0**80.0, :Y => 2.0**80,
5
- :zetta => 2.0**70.0, :Z => 2.0**70.0,
6
- :exa => 2.0**60.0, :E => 2.0**60.0,
7
- :peta => 2.0**50.0, :P => 2.0**50.0,
8
- :tera => 2.0**40.0, :T => 2.0**40.0,
9
- :giga => 2.0**30.0, :G => 2.0**30.0,
10
- :mega => 2.0**20.0, :M => 2.0**20.0,
11
- :kilo => 2.0**10.0, :k => 2.0**10.0,
12
-
13
- # binary prefixes
14
-
15
- :kibi => 2.0**10.0, :Ki => 2.0**10.0,
16
- :mebi => 2.0**20.0, :Mi => 2.0**20.0,
17
- :gibi => 2.0**30.0, :Gi => 2.0**30.0,
18
- :tebi => 2.0**40.0, :Ti => 2.0**40.0,
19
- :pebi => 2.0**50.0, :Pi => 2.0**50.0,
20
- :exbi => 2.0**60.0, :Ei => 2.0**60.0,
21
- :zebi => 2.0**70.0, :Zi => 2.0**70.0,
22
- :yobi => 2.0**80.0, :Yi => 2.0**80.0
23
- }
24
- end
25
- end
@@ -1,7 +0,0 @@
1
- # TODO: remove all of this
2
- Alchemist.register_operation_conversions(:distance, :distance, :*, :square_meters)
3
- Alchemist.register_operation_conversions(:area, :distance, :*, :cubic_meters)
4
- Alchemist.register_operation_conversions(:distance, :area, :*, :cubic_meters)
5
- Alchemist.register_operation_conversions(:area, :distance, :/, :meters)
6
- Alchemist.register_operation_conversions(:volume, :distance, :/, :square_meters)
7
- Alchemist.register_operation_conversions(:volume, :area, :/, :meters)
@@ -1,146 +0,0 @@
1
- module Alchemist
2
- class NumericConversion
3
- attr_reader :unit_name, :exponent, :value
4
- include Comparable
5
-
6
- def per
7
- CompoundNumericConversion.new self
8
- end
9
- alias_method :p, :per # TODO: deprecate p
10
-
11
- def to type = nil
12
- unless type
13
- self
14
- else
15
- send type
16
- end
17
- end
18
- alias_method :as, :to # TODO: deprecate as
19
-
20
- def base unit_type
21
- conversion_base = conversion_base_for(unit_type)
22
- convert_to_base conversion_base
23
- end
24
-
25
- def to_s
26
- value.to_s
27
- end
28
-
29
- def to_i
30
- value.to_i
31
- end
32
-
33
- def to_f
34
- @value
35
- end
36
-
37
- def <=>(other)
38
- (self.to_f * exponent).to_f <=> other.to(unit_name).to_f
39
- end
40
-
41
- private
42
-
43
- def initialize value, unit_name, exponent = 1.0
44
- @value = value.to_f
45
- @unit_name = unit_name
46
- @exponent = exponent
47
- end
48
-
49
- def convert_to_base conversion_base
50
- if conversion_base.is_a?(Array)
51
- exponent * conversion_base.first.call(value)
52
- else
53
- exponent * value * conversion_base
54
- end
55
- end
56
-
57
- def conversion_base_for unit_type
58
- Alchemist.conversion_table[unit_type][unit_name]
59
- end
60
-
61
- def convert_from_type type, unit_name, exponent
62
- if(Alchemist.conversion_table[type][unit_name].is_a?(Array))
63
- Alchemist.conversion_table[type][unit_name][1].call(base(type))
64
- else
65
- NumericConversion.new(base(type) / (exponent * Alchemist.conversion_table[type][unit_name]), unit_name)
66
- end
67
- end
68
-
69
- def convert types, unit_name, exponent
70
- if type = types[0]
71
- convert_from_type type, unit_name, exponent
72
- else
73
- raise Exception, "Incompatible Types"
74
- end
75
- end
76
-
77
- def multiply multiplicand
78
- if multiplicand.is_a?(Numeric)
79
- @value *= multiplicand
80
- return self
81
- else
82
- raise Exception, "Incompatible Types"
83
- end
84
- end
85
-
86
- def check_operator_conversion arg, unit_name
87
- t1 = Alchemist.measurement_for(self.unit_name)[0]
88
- t2 = Alchemist.measurement_for(arg.unit_name)[0]
89
- Alchemist.operator_actions[unit_name].each do |s1, s2, new_type|
90
- if t1 == s1 && t2 == s2
91
- return ConversionWrap.new((value * arg.to_f).send(new_type))
92
- end
93
- end
94
- end
95
-
96
- def can_perform_conversion? arg, unit_name
97
- arg.is_a?(NumericConversion) && Alchemist.operator_actions[unit_name]
98
- end
99
-
100
- def types
101
- Alchemist.measurement_for(unit_name)
102
- end
103
-
104
- def shared_types other_unit_name
105
- types & Alchemist.measurement_for(other_unit_name)
106
- end
107
-
108
- def has_shared_types? other_unit_name
109
- shared_types(other_unit_name).length > 0
110
- end
111
-
112
- class ConversionWrap < Struct.new(:value)
113
- end
114
-
115
- def method_missing unit_name, *args, &block
116
- exponent, unit_name = Alchemist.parse_prefix(unit_name)
117
- arg = args.first
118
-
119
- if Alchemist.measurement_for(unit_name)
120
- convert shared_types(unit_name), unit_name, exponent
121
- else
122
- perform_conversion_method args, unit_name, exponent, &block
123
- end
124
- end
125
-
126
- def perform_conversion_method args, unit_name, exponent, &block
127
- arg = args.first
128
- if can_perform_conversion?(arg, unit_name)
129
- wrap = check_operator_conversion(arg, unit_name)
130
- if wrap.is_a?(ConversionWrap)
131
- return wrap.value
132
- end
133
- end
134
- if unit_name == :*
135
- return multiply(arg)
136
- end
137
- if unit_name == :/ && arg.is_a?(NumericConversion)
138
- raise Exception, "Incompatible Types" unless has_shared_types?(arg.unit_name)
139
- end
140
- args.map!{|a| a.is_a?(NumericConversion) ? a.send(self.unit_name).to_f / exponent : a }
141
- @value = value.send( unit_name, *args, &block )
142
- unit_name == :/ ? value : self
143
- end
144
- end
145
-
146
- end