metamorphosis 0.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/LICENSE.txt +22 -0
- data/README.md +34 -0
- data/lib/metamorphosis.rb +8 -0
- data/lib/metamorphosis/constants.rb +341 -0
- data/lib/metamorphosis/engine.rb +96 -0
- data/lib/metamorphosis/errors.rb +4 -0
- data/lib/metamorphosis/prefix_parser.rb +35 -0
- data/lib/metamorphosis/unit_registry.rb +35 -0
- data/lib/metamorphosis/unit_value.rb +54 -0
- data/lib/metamorphosis/version.rb +3 -0
- data/lib/numeric.rb +9 -0
- data/metamorphosis.gemspec +15 -0
- data/spec/lib/metamorphosis/engine_spec.rb +104 -0
- data/spec/lib/metamorphosis/prefix_parser_spec.rb +43 -0
- data/spec/lib/metamorphosis/unit_registry_spec.rb +38 -0
- data/spec/lib/metamorphosis/unit_value_spec.rb +69 -0
- data/spec/lib/metamorphosis_spec.rb +18 -0
- data/spec/lib/numeric_spec.rb +21 -0
- data/spec/spec_helper.rb +19 -0
- metadata +80 -0
    
        data/LICENSE.txt
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            The MIT LICENSE
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Copyright (c) 2012 Wegowise, Inc.
         | 
| 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.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            Metamorphosis
         | 
| 2 | 
            +
            =============
         | 
| 3 | 
            +
            An engine for allowing numeric values to convert between units.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            [](http://travis-ci.org/wegowise/metamorphosis)
         | 
| 6 | 
            +
            [](https://codeclimate.com/github/wegowise/metamorphosis)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            Usage
         | 
| 9 | 
            +
            ==============
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            Add 'metamorphosis' to your Gemfile,
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            Bundle install
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            Inside your intializer use the predefined units:
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            ````
         | 
| 18 | 
            +
            Metamorphosis.register_predefined_units
         | 
| 19 | 
            +
            ````
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            or register your own:
         | 
| 22 | 
            +
            ````
         | 
| 23 | 
            +
            Metamorphosis.engine.register_unit(:wegowise, :british_thermal_units, 1)
         | 
| 24 | 
            +
            Metamorphosis.engine.register_unit(:wegowise, :therms, 100_000)
         | 
| 25 | 
            +
            ````
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            Once you've defined your units you now have freedom to make your values
         | 
| 28 | 
            +
            more expressive:
         | 
| 29 | 
            +
            ````
         | 
| 30 | 
            +
            value = 200_000.british_thermal_units #200000.0 british_thermal_units
         | 
| 31 | 
            +
            value = value.to.therms
         | 
| 32 | 
            +
            value == 2.therms  #true
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            ````
         | 
| @@ -0,0 +1,341 @@ | |
| 1 | 
            +
            module Metamorphosis
         | 
| 2 | 
            +
              SI_UNITS = %w{m meter metre meters metres liter litre litres liters l L
         | 
| 3 | 
            +
                            farad farads F coulombs C gray grays Gy siemen siemens S
         | 
| 4 | 
            +
                            mhos mho ohm ohms volt volts V joule joules J newton newtons N
         | 
| 5 | 
            +
                            lux lx henry henrys H b B bits bytes bit byte lumen lumens lm
         | 
| 6 | 
            +
                            candela candelas cd tesla teslas T gauss Gs G gram gramme grams
         | 
| 7 | 
            +
                            grammes g watt watts W pascal pascals Pa becquerel becquerels
         | 
| 8 | 
            +
                            Bq curie curies Ci}.map(&:to_sym)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              DEFAULT_PREFIXES = {
         | 
| 11 | 
            +
                  :googol => 1e+100,
         | 
| 12 | 
            +
                  :yotta => 1e+24, :Y => 1e+24,
         | 
| 13 | 
            +
                  :zetta => 1e+21, :Z => 1e+21,
         | 
| 14 | 
            +
                  :exa => 1e+18, :E => 1e+18,
         | 
| 15 | 
            +
                  :peta => 1e+15, :P => 1e+15,
         | 
| 16 | 
            +
                  :tera => 1e+12, :T => 1e+12,
         | 
| 17 | 
            +
                  :giga => 1e+9, :G => 1e+9,
         | 
| 18 | 
            +
                  :mega => 1e+6, :M => 1e+6,
         | 
| 19 | 
            +
                  :kilo => 1e+3, :k => 1e+3,
         | 
| 20 | 
            +
                  :hecto => 1e+2, :h => 1e+2,
         | 
| 21 | 
            +
                  :deca => 10, :da => 10,
         | 
| 22 | 
            +
                  :deci => 1e-1, :d => 1e-1,
         | 
| 23 | 
            +
                  :centi => 1e-2, :c => 1e-2,
         | 
| 24 | 
            +
                  :milli => 1e-3, :m => 1e-3,
         | 
| 25 | 
            +
                  :micro => 1e-6, :u => 1e-6,
         | 
| 26 | 
            +
                  :nano => 1e-9, :n => 1e-9,
         | 
| 27 | 
            +
                  :pico => 1e-12, :p => 1e-12,
         | 
| 28 | 
            +
                  :femto => 1e-15, :f => 1e-15,
         | 
| 29 | 
            +
                  :atto => 1e-18, :a => 1e-18,
         | 
| 30 | 
            +
                  :zepto => 1e-21, :z => 1e-21,
         | 
| 31 | 
            +
                  :yocto => 1e-24, :y => 1e-24,
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  # binary prefixes
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  :kibi => 2.0**10.0, :Ki => 2.0**10.0,
         | 
| 36 | 
            +
                  :mebi => 2.0**20.0, :Mi => 2.0**20.0,
         | 
| 37 | 
            +
                  :gibi => 2.0**30.0, :Gi => 2.0**30.0,
         | 
| 38 | 
            +
                  :tebi => 2.0**40.0, :Ti => 2.0**40.0,
         | 
| 39 | 
            +
                  :pebi => 2.0**50.0, :Pi => 2.0**50.0,
         | 
| 40 | 
            +
                  :exbi => 2.0**60.0, :Ei => 2.0**60.0,
         | 
| 41 | 
            +
                  :zebi => 2.0**70.0, :Zi => 2.0**70.0,
         | 
| 42 | 
            +
                  :yobi => 2.0**80.0, :Yi => 2.0**80.0
         | 
| 43 | 
            +
                }
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              PRE_DEFINED_UNITS =
         | 
| 46 | 
            +
                {
         | 
| 47 | 
            +
                :absorbed_radiation_dose => {
         | 
| 48 | 
            +
                  :gray => 1.0, :grays => 1.0, :Gy => 1.0,
         | 
| 49 | 
            +
                  :rad => 1.0e-2, :rads => 1.0e-2
         | 
| 50 | 
            +
                },
         | 
| 51 | 
            +
                :angles => {
         | 
| 52 | 
            +
                  :radian => 1.0, :radians => 1.0,
         | 
| 53 | 
            +
                  :degree => Math::PI / 180.0, :degrees => Math::PI / 180.0,
         | 
| 54 | 
            +
                  :arcminute => Math::PI / 10800.0, :arcminutes => Math::PI / 10800.0,
         | 
| 55 | 
            +
                  :arcsecond => Math::PI / 648000.0, :arcseconds => Math::PI / 648000.0,
         | 
| 56 | 
            +
                  :mil => 9.817477e-4, :mils => 9.817477e-4,
         | 
| 57 | 
            +
                  :revolution => Math::PI * 2.0, :revolutions => Math::PI * 2.0,
         | 
| 58 | 
            +
                  :circle =>  Math::PI * 2.0, :circles =>  Math::PI * 2.0,
         | 
| 59 | 
            +
                  :right_angle =>  Math::PI / 2.0, :right_angles =>  Math::PI / 2.0,
         | 
| 60 | 
            +
                  :grad => Math::PI / 200.0, :grade => Math::PI / 200.0, :gradian => Math::PI / 200.0, :gon => Math::PI / 200.0, :grads => Math::PI / 200.0, :grades => Math::PI / 200.0, :gradians => Math::PI / 200.0, :gons => Math::PI / 200.0,
         | 
| 61 | 
            +
                  #unusual measurements
         | 
| 62 | 
            +
                  :furman => 9.58737992858887e-5, :furmans => 9.58737992858887e-5
         | 
| 63 | 
            +
                },
         | 
| 64 | 
            +
                :area => {
         | 
| 65 | 
            +
                  :square_meter => 1.0, :square_meters => 1.0, :square_metre => 1.0, :square_metres => 1.0,
         | 
| 66 | 
            +
                  :acre => 4046.85642, :acres => 4046.85642,
         | 
| 67 | 
            +
                  :are => 1.0e+2, :ares => 1.0e+2, :a => 1.0e+2,
         | 
| 68 | 
            +
                  :barn => 1.0e-28, :barns => 1.0e-28, :b => 1.0e-28,
         | 
| 69 | 
            +
                  :circular_mil => 5.067075e-10, :circular_mils => 5.067075e-10,
         | 
| 70 | 
            +
                  :hectare => 1.0e+4, :hectares => 1.0e+4, :ha => 1.0e+4,
         | 
| 71 | 
            +
                  :square_foot => 9.290304e-2, :square_feet => 9.290304e-2,
         | 
| 72 | 
            +
                  :square_inch => 6.4516e-4, :square_inches => 6.4516e-4,
         | 
| 73 | 
            +
                  :square_mile => 2.589988e+6, :square_miles => 2.589988e+6,
         | 
| 74 | 
            +
                  :square_yard => 0.83612736, :square_yards => 0.83612736
         | 
| 75 | 
            +
                },
         | 
| 76 | 
            +
                :capacitance => {
         | 
| 77 | 
            +
                  :farad => 1.0, :farads => 1.0, :F => 1.0,
         | 
| 78 | 
            +
                  :abfarad => 1.0e+9, :emu_of_capacitance => 1.0e+9, :abfarads => 1.0e+9, :emus_of_capacitance => 1.0e+9,
         | 
| 79 | 
            +
                  :statfarad => 1.112650e-12, :esu_of_capacitance => 1.112650e-12, :statfarads => 1.112650e-12, :esus_of_capacitance => 1.112650e-12
         | 
| 80 | 
            +
                },
         | 
| 81 | 
            +
                :density => {
         | 
| 82 | 
            +
                  :specific_gravity => 1, :sg => 1,
         | 
| 83 | 
            +
                  :brix     => [Proc.new{ |d| -261.3 / (d - 261.3) }, Proc.new{ |d| 261.3 - (261.3 / d) }],
         | 
| 84 | 
            +
                  :plato    => [Proc.new{ |d| -260.0 / (d - 260.0) }, Proc.new{ |d| 260.0 - (260.0 / d) }],
         | 
| 85 | 
            +
                  :baume    => [Proc.new{ |d| -145.0 / (d - 145.0) }, Proc.new{ |d| 145.0 - (145.0 / d) }]
         | 
| 86 | 
            +
                },
         | 
| 87 | 
            +
                :distance => {
         | 
| 88 | 
            +
                  :meter => 1.0, :metres => 1.0, :meters => 1.0, :m => 1.0,
         | 
| 89 | 
            +
                  :fermi => 1.0e-15, :fermis => 1.0e-15,
         | 
| 90 | 
            +
                  :micron => 1.0e-6, :microns => 1.0e-6,
         | 
| 91 | 
            +
                  :chain => 20.1168, :chains => 20.1168,
         | 
| 92 | 
            +
                  :inch => 25.4e-3, :inches => 25.4e-3, :in => 25.4e-3,
         | 
| 93 | 
            +
                  :microinch => 2.54e-8, :microinches => 2.54e-8,
         | 
| 94 | 
            +
                  :mil => 2.54e-05, :mils => 2.54e-05,
         | 
| 95 | 
            +
                  :rod => 5.029210, :rods => 5.029210,
         | 
| 96 | 
            +
                  :league => 5556, :leagues => 5556,
         | 
| 97 | 
            +
                  :foot => 0.3048, :feet => 0.3048, :ft => 0.3048,
         | 
| 98 | 
            +
                  :yard => 0.9144, :yards => 0.9144, :yd => 0.9144,
         | 
| 99 | 
            +
                  :mile =>1609.344, :miles =>1609.344, :mi => 1609.344,
         | 
| 100 | 
            +
                  :astronomical_unit => 149.60e+9, :astronomical_units => 149.60e+9, :au => 149.60e+9, :ua => 149.60e+9,
         | 
| 101 | 
            +
                  :light_year => 9.461e+15, :light_years => 9.461e+15, :ly => 9.461e+15,
         | 
| 102 | 
            +
                  :parsec => 30.857e+15, :parsecs => 30.857e+15,
         | 
| 103 | 
            +
                  :nautical_mile => 1852.0, :nautical_miles => 1852.0,
         | 
| 104 | 
            +
                  :admirality_mile => 185.3184, :admirality_miles => 185.3184,
         | 
| 105 | 
            +
                  :fathom => 1.8288, :fathoms => 1.8288,
         | 
| 106 | 
            +
                  :cable_length => 185.2, :cable_lengths => 185.2,
         | 
| 107 | 
            +
                  :angstrom => 100.0e-12, :angstroms => 100.0e-12,
         | 
| 108 | 
            +
                  :pica => 4.233333e-3, :picas => 4.233333e-3,
         | 
| 109 | 
            +
                  :printer_pica => 4.217518e-3, :printer_picas => 4.217518e-3,
         | 
| 110 | 
            +
                  :point => 3.527778e-4, :points => 3.527778e-4,
         | 
| 111 | 
            +
                  :printer_point => 3.514598e-4, :printer_points => 3.514598e-4,
         | 
| 112 | 
            +
                  # unusual mesaurements
         | 
| 113 | 
            +
                  :empire_state_building => 449.0, :empire_state_buildings => 449.0,
         | 
| 114 | 
            +
                  :sears_tower => 519.0, :sears_towers => 519.0,
         | 
| 115 | 
            +
                  :seattle_space_needle => 184.0, :seattle_space_needles => 184.0, :space_needle => 184.0, :space_needles => 184.0,
         | 
| 116 | 
            +
                  :statue_of_liberty => 46.0, :statue_of_liberties => 46.0,
         | 
| 117 | 
            +
                  :washington_monument => 169.294, :washington_monuments => 169.294,
         | 
| 118 | 
            +
                  :eiffel_tower => 324.0, :eiffel_towers => 324.0,
         | 
| 119 | 
            +
                  :nelsons_column => 61.5, :nelsons_columns => 61.5,
         | 
| 120 | 
            +
                  :blackpool_tower => 158.0, :blackpool_towers => 158.0,
         | 
| 121 | 
            +
                  :big_ben => 96.3, :big_bens => 96.3, :clock_tower_of_the_palace_of_westminster => 96.3, :clock_towers_of_the_palace_of_westminster => 96.3,
         | 
| 122 | 
            +
                  :st_pauls_cathedral => 108.0, :st_pauls_cathedrals => 108.0,
         | 
| 123 | 
            +
                  :toronto_cn_tower => 553.0, :toronto_cn_towers => 553.0, :cn_tower => 553.0, :cn_towers => 553.0,
         | 
| 124 | 
            +
                  :circle_of_the_earth => 40075016.686, :equator => 40075016.686, :circles_of_the_earth => 40075016.686, :equators => 40075016.686,
         | 
| 125 | 
            +
                  :siriometer => 1.494838e+17, :siriometers => 1.494838e+17,
         | 
| 126 | 
            +
                  :football_field => 91.0, :football_fields => 91.0,
         | 
| 127 | 
            +
                  :length_of_a_double_decker_bus => 8.4, :height_of_a_double_decker_bus => 4.4,
         | 
| 128 | 
            +
                  :smoot => 1.7018, :smoots => 1.7018
         | 
| 129 | 
            +
                },
         | 
| 130 | 
            +
                :dose_equivalent => {
         | 
| 131 | 
            +
                  :sievert => 1.0, :sieverts => 1.0, :Si => 1.0,
         | 
| 132 | 
            +
                  :rem => 1.0e-2, :rems => 1.0e-2
         | 
| 133 | 
            +
                },
         | 
| 134 | 
            +
                :electric_charge => {
         | 
| 135 | 
            +
                  :coulomb => 1.0, :coulombs => 1.0, :C => 1.0,
         | 
| 136 | 
            +
                  :abcoulomb => 10.0, :abcoulombs => 10.0,
         | 
| 137 | 
            +
                  :ampere_hour => 3.6e+3, :ampere_hours => 3.6e+3,
         | 
| 138 | 
            +
                  :faraday => 9.648534e+4, :faradays => 9.648534e+4,
         | 
| 139 | 
            +
                  :franklin => 3.335641e-10, :franklins => 3.335641e-10, :Fr => 3.335641e-10,
         | 
| 140 | 
            +
                  :statcoulomb => 3.335641e-10, :statcoulombs => 3.335641e-10
         | 
| 141 | 
            +
                },
         | 
| 142 | 
            +
                :electric_conductance => {
         | 
| 143 | 
            +
                  :siemen => 1.0, :siemens => 1.0, :S => 1.0, :mho => 1.0,
         | 
| 144 | 
            +
                  :abmho => 1.0e+9, :absiemen => 1.0e+9, :absiemens => 1.0e+9,
         | 
| 145 | 
            +
                  :statmho => 1.112650e-12, :statsiemen => 1.112650e-12, :statsiemens => 1.112650e-12
         | 
| 146 | 
            +
                },
         | 
| 147 | 
            +
                :electrical_impedance => {
         | 
| 148 | 
            +
                  :ohm => 1.0, :ohms => 1.0,
         | 
| 149 | 
            +
                  :abohm => 1.0e-9, :emu_of_resistance => 1.0e-9, :abohms => 1.0e-9, :emus_of_resistance => 1.0e-9,
         | 
| 150 | 
            +
                  :statohm => 8.987552e+11, :esu_of_resistance => 8.987552e+11, :statohms => 8.987552e+11, :esus_of_resistance => 8.987552e+11
         | 
| 151 | 
            +
                },
         | 
| 152 | 
            +
                :electromotive_force => {
         | 
| 153 | 
            +
                  :volt => 1.0, :volts => 1.0, :V => 1.0,
         | 
| 154 | 
            +
                  :abvolt => 1.0e-8, :emu_of_electric_potential => 1.0e-8, :abvolts => 1.0e-8, :emus_of_electric_potential => 1.0e-8,
         | 
| 155 | 
            +
                  :statvolt => 2.997925e+2, :esu_of_electric_potential => 2.997925e+2, :statvolts => 2.997925e+2, :esus_of_electric_potential => 2.997925e+2
         | 
| 156 | 
            +
                },
         | 
| 157 | 
            +
                :energy => {
         | 
| 158 | 
            +
                  :joule => 1.0, :joules => 1.0, :J => 1.0, :watt_second => 1.0, :watt_seconds => 1.0,
         | 
| 159 | 
            +
                  :watt_hour => 3.6e+3, :watt_hours => 3.6e+3,
         | 
| 160 | 
            +
                  :ton_of_tnt => 4.184e+9, :tons_of_tnt => 4.184e+9,
         | 
| 161 | 
            +
                  :therm => 1.05506e+8, :therms => 1.05506e+8,
         | 
| 162 | 
            +
                  :us_therm => 1.054804e+8, :us_therms => 1.054804e+8,
         | 
| 163 | 
            +
                  :kilowatt_hour => 3.6e+6, :kilowatt_hours => 3.6e+6,
         | 
| 164 | 
            +
                  :kilocalorie => 4184.0, :kilocalories => 4184.0,
         | 
| 165 | 
            +
                  :calorie => 4.184, :calories => 4.184,
         | 
| 166 | 
            +
                  :mean_kilocalorie => 4190, :mean_kilocalories => 4190,
         | 
| 167 | 
            +
                  :mean_calorie => 4.190, :mean_calories => 4.190,
         | 
| 168 | 
            +
                  :it_kilocalorie => 4186.8, :it_kilocalories => 4186.8,
         | 
| 169 | 
            +
                  :it_calorie => 4.1868, :it_calories => 4.1868,
         | 
| 170 | 
            +
                  :foot_poundal => 4.214011e-2, :foot_poundals => 4.214011e-2,
         | 
| 171 | 
            +
                  :foot_pound_force => 1.355818,
         | 
| 172 | 
            +
                  :erg =>  1.0e-7, :ergs =>  1.0e-7,
         | 
| 173 | 
            +
                  :electronvolt => 1.602176e-19, :electronvolts => 1.602176e-19, :eV => 1.602176e-19,
         | 
| 174 | 
            +
                  :british_thermal_unit => 1.054350e+3, :british_thermal_units => 1.054350e+3,
         | 
| 175 | 
            +
                  :mean_british_thermal_unit => 1.05587e+3, :mean_british_thermal_units => 1.05587e+3,
         | 
| 176 | 
            +
                  :it_british_thermal_unit => 1.055056e+3, :it_british_thermal_units => 1.055056e+3,
         | 
| 177 | 
            +
                  #unusual measurements
         | 
| 178 | 
            +
                  :foe => 1e+44, :foes => 1e+44
         | 
| 179 | 
            +
                },
         | 
| 180 | 
            +
                :frequency => {
         | 
| 181 | 
            +
                  :hertz => 1.0, :hz => 1.0, :'Hz' => 1.0,
         | 
| 182 | 
            +
                  :revolutions_per_minute => 1/60.0, :rpm => 1/60.0,
         | 
| 183 | 
            +
                  :beats_per_minute => 1/60.0, :bpm => 1/60.0
         | 
| 184 | 
            +
                },
         | 
| 185 | 
            +
                :force => {
         | 
| 186 | 
            +
                  :newton => 1.0, :newtons => 1.0, :N => 1.0,
         | 
| 187 | 
            +
                  :dyne => 1.0e-5, :dynes => 1.0e-5, :dyn => 1.0e-5,
         | 
| 188 | 
            +
                  :kilogram_force => 9.80665, :kgf => 9.80665, :kilopond => 9.80665, :kiloponds => 9.80665, :kp => 9.80665,
         | 
| 189 | 
            +
                  :kip => 4.448222e+3, :kips => 4.448222e+3,
         | 
| 190 | 
            +
                  :ounce_force => 2.780139e-1, :ozf => 2.780139e-1,
         | 
| 191 | 
            +
                  :poundal => 1.382550e-1, :poundals => 1.382550e-1,
         | 
| 192 | 
            +
                  :pound_force => 4.448222, :lbf => 4.448222,
         | 
| 193 | 
            +
                  :ton_force => 8.896443e+3
         | 
| 194 | 
            +
                },
         | 
| 195 | 
            +
                :illuminance => {
         | 
| 196 | 
            +
                  :lux => 1.0, :lx => 1.0, :lumens_per_square_metre => 1.0, :lumens_per_square_meter => 1.0, :lumen_per_square_metre => 1.0, :lumen_per_square_meter => 1.0,
         | 
| 197 | 
            +
                  :phot => 1.0e+4, :phots => 1.0e+4, :ph => 1.0e+4,
         | 
| 198 | 
            +
                  :lumens_per_square_foot => 10.76391, :footcandle => 10.76391, :lumen_per_square_foot => 10.76391, :footcandles => 10.76391
         | 
| 199 | 
            +
                },
         | 
| 200 | 
            +
               :inductance => {
         | 
| 201 | 
            +
                  :henry => 1.0, :henrys => 1.0, :H => 1.0,
         | 
| 202 | 
            +
                  :abhenrys => 1.0e-9, :emus_of_inductance => 1.0e-9, :abhenry => 1.0e-9, :emu_of_inductance => 1.0e-9,
         | 
| 203 | 
            +
                  :stathenrys => 8.987552e+11, :esus_of_inductance => 8.987552e+11, :stathenry => 8.987552e+11, :esu_of_inductance => 8.987552e+11
         | 
| 204 | 
            +
                },
         | 
| 205 | 
            +
                :information_storage => {
         | 
| 206 | 
            +
                  :bit => 1.0, :bits => 1.0, :b => 1.0,
         | 
| 207 | 
            +
                  :byte => 8.0, :bytes => 8.0, :B => 8.0,
         | 
| 208 | 
            +
                  :nibbles => 4.0, :nybbles => 4.0
         | 
| 209 | 
            +
                },
         | 
| 210 | 
            +
                :luminous_flux => {
         | 
| 211 | 
            +
                  :lumen => 1.0, :lumens => 1.0, :lm => 1.0
         | 
| 212 | 
            +
                },
         | 
| 213 | 
            +
                :luminous_intensity => {
         | 
| 214 | 
            +
                  :candela => 1.0, :candelas => 1.0, :cd => 1.0
         | 
| 215 | 
            +
                },
         | 
| 216 | 
            +
                :magnetic_flux => {
         | 
| 217 | 
            +
                  :webers => 1.0, :Wb => 1.0,
         | 
| 218 | 
            +
                  :maxwells => 1.0e-8, :Mx => 1.0e-8,
         | 
| 219 | 
            +
                  :unit_poles => 1.256637e-7
         | 
| 220 | 
            +
                },
         | 
| 221 | 
            +
                :magnetic_inductance => {
         | 
| 222 | 
            +
                  :tesla => 1.0, :teslas => 1.0, :T => 1.0,
         | 
| 223 | 
            +
                  :gamma => 1.0e-9, :gammas => 1.0e-9,
         | 
| 224 | 
            +
                  :gauss => 1.0e-4, :Gs => 1.0e-4, :G => 1.0e-4
         | 
| 225 | 
            +
                },
         | 
| 226 | 
            +
                :mass => {
         | 
| 227 | 
            +
                  :gram => 1.0, :gramme => 1.0, :grams => 1.0, :grammes => 1.0, :g => 1.0,
         | 
| 228 | 
            +
                  :carat => 2.0e-1, :carats => 2.0e-1,
         | 
| 229 | 
            +
                  :ounce => 2.834952e+1, :ounces => 2.834952e+1, :oz => 2.834952e+1,
         | 
| 230 | 
            +
                  :pennyweight => 1.555174, :pennyweights => 1.555174, :dwt => 1.555174,
         | 
| 231 | 
            +
                  :pound => 453.59237, :pounds => 453.59237, :lb => 453.59237, :lbs => 453.59237,
         | 
| 232 | 
            +
                  :troy_pound => 373.2417, :apothecary_pound => 373.2417, :troy_pounds => 373.2417, :apothecary_pounds => 373.2417,
         | 
| 233 | 
            +
                  :slug => 14593.9029, :slugs => 14593.9029,
         | 
| 234 | 
            +
                  :assay_ton => 29.1667, :assay_tons => 29.1667, :AT => 29.1667,
         | 
| 235 | 
            +
                  :metric_ton => 1000000, :metric_tons => 1000000,
         | 
| 236 | 
            +
                  :ton => 907184.74, :tons => 907184.74, :short_tons => 907184.74,
         | 
| 237 | 
            +
                  #unusual measurements
         | 
| 238 | 
            +
                  :elephant => 5443108.44, :elephants => 5443108.44
         | 
| 239 | 
            +
                },
         | 
| 240 | 
            +
                :power => {
         | 
| 241 | 
            +
                  :watt => 1.0, :watts => 1.0, :W => 1.0,
         | 
| 242 | 
            +
                  :british_thermal_unit_per_hour => 2.928751e-1, :british_thermal_units_per_hour => 2.928751e-1,
         | 
| 243 | 
            +
                  :it_british_thermal_unit_per_hour => 2.930711e-1, :it_british_thermal_units_per_hour => 2.930711e-1,
         | 
| 244 | 
            +
                  :british_thermal_unit_per_second => 1.054350e+3, :british_thermal_units_per_second => 1.054350e+3,
         | 
| 245 | 
            +
                  :it_british_thermal_unit_per_second => 1.055056e+3, :it_british_thermal_units_per_second => 1.055056e+3,
         | 
| 246 | 
            +
                  :calorie_per_minute => 6.973333e-2, :calories_per_minute => 6.973333e-2,
         | 
| 247 | 
            +
                  :calorie_per_second => 4.184, :calories_per_second => 4.184,
         | 
| 248 | 
            +
                  :erg_per_second => 1.0e-7, :ergs_per_second => 1.0e-7,
         | 
| 249 | 
            +
                  :foot_pound_force_per_hour => 3.766161e-4,
         | 
| 250 | 
            +
                  :foot_pound_force_per_minute => 2.259697e-2,
         | 
| 251 | 
            +
                  :foot_pound_force_per_second => 1.355818,
         | 
| 252 | 
            +
                  :horsepower => 7.456999e+2,
         | 
| 253 | 
            +
                  :boiler_horsepower => 9.80950e+3,
         | 
| 254 | 
            +
                  :electric_horsepower => 7.46e+2,
         | 
| 255 | 
            +
                  :metric_horsepower => 7.354988e+2,
         | 
| 256 | 
            +
                  :uk_horsepower => 7.4570e+2,
         | 
| 257 | 
            +
                  :water_horsepower => 7.46043e+2,
         | 
| 258 | 
            +
                  :kilocalorie_per_minute => 6.973333*10, :kilocalories_per_minute => 6.973333*10,
         | 
| 259 | 
            +
                  :kilocalorie_per_second => 4.184e+3, :kilocalories_per_second => 4.184e+3,
         | 
| 260 | 
            +
                  :ton_of_refrigeration => 3.516853e+3, :tons_of_refrigeration => 3.516853e+3
         | 
| 261 | 
            +
                },
         | 
| 262 | 
            +
                :pressure => {
         | 
| 263 | 
            +
                  :pascal => 1.0, :pascals => 1.0, :Pa => 1.0,
         | 
| 264 | 
            +
                  :atmosphere => 1.01325e+5, :atmospheres => 1.01325e+5,
         | 
| 265 | 
            +
                  :technical_atmosphere => 9.80665e+4, :technical_atmospheres => 9.80665e+4,
         | 
| 266 | 
            +
                  :bar => 1.0e+5, :bars => 1.0e+5,
         | 
| 267 | 
            +
                  :centimeter_of_mercury => 1.333224e+3, :centimeters_of_mercury => 1.333224e+3,
         | 
| 268 | 
            +
                  :centimeter_of_water => 98.0665, :centimeters_of_water => 98.0665, :gram_force_per_square_centimeter => 98.0665,
         | 
| 269 | 
            +
                  :dyne_per_square_centimeter => 1.0e-1, :dynes_per_square_centimeter => 1.0e-1,
         | 
| 270 | 
            +
                  :foot_of_mercury => 4.063666e+4, :feet_of_mercury => 4.063666e+4,
         | 
| 271 | 
            +
                  :foot_of_water => 2.989067e+3, :feet_of_water => 2.989067e+3,
         | 
| 272 | 
            +
                  :inch_of_mercury => 3.386389e+3, :inches_of_mercury => 3.386389e+3,
         | 
| 273 | 
            +
                  :inch_of_water =>  2.490889e+2, :inches_of_water =>  2.490889e+2,
         | 
| 274 | 
            +
                  :kilogram_force_per_square_centimeter => 9.80665e+4,
         | 
| 275 | 
            +
                  :kilogram_force_per_square_meter => 9.80665,
         | 
| 276 | 
            +
                  :kilogram_force_per_square_millimeter =>  9.80665e+6,
         | 
| 277 | 
            +
                  :kip_per_square_inch => 6.894757e+6, :kips_per_square_inch => 6.894757e+6, :ksi => 6.894757e+6,
         | 
| 278 | 
            +
                  :millibar => 1.0e+2, :mbar => 1.0e+2, :millibars => 1.0e+2, :mbars => 1.0e+2,
         | 
| 279 | 
            +
                  :millimeter_of_mercury => 1.333224e+2, :millimeters_of_mercury => 1.333224e+2,
         | 
| 280 | 
            +
                  :millimeter_of_water => 9.80665, :millimeters_of_water => 9.80665,
         | 
| 281 | 
            +
                  :poundal_per_square_foot => 1.488164, :poundals_per_square_foot => 1.488164,
         | 
| 282 | 
            +
                  :pound_force_per_square_foot => 47.88026,
         | 
| 283 | 
            +
                  :pound_force_per_square_inch => 6.894757e+3, :psi => 6.894757e+3,
         | 
| 284 | 
            +
                  :torr => 1.333224e+2, :torrs => 1.333224e+2
         | 
| 285 | 
            +
                },
         | 
| 286 | 
            +
                :radioactivity => {
         | 
| 287 | 
            +
                  :becquerel => 1.0, :becquerels => 1.0, :Bq => 1.0,
         | 
| 288 | 
            +
                  :curie => 3.7e+10, :curies => 3.7e+10, :Ci => 3.7e+10
         | 
| 289 | 
            +
                },
         | 
| 290 | 
            +
                :temperature => {
         | 
| 291 | 
            +
                  :kelvin => 1.0, :K => 1.0,
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                  :celsius => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }], :centrigrade => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }],
         | 
| 294 | 
            +
                  :degree_celsius => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }], :degree_centrigrade => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }],
         | 
| 295 | 
            +
                  :degrees_celsius => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }], :degrees_centrigrade => [Proc.new{ |t| t + 273.15 }, Proc.new{ |t| t - 273.15 }],
         | 
| 296 | 
            +
                  :fahrenheit => [Proc.new{ |t| (t + 459.67) * (5.0/9.0) }, Proc.new{ |t| t * (9.0/5.0) - 459.67 }],
         | 
| 297 | 
            +
                  :degree_fahrenheit => [Proc.new{ |t| (t + 459.67) * (5.0/9.0) }, Proc.new{ |t| t * (9.0/5.0) - 459.67 }],
         | 
| 298 | 
            +
                  :degrees_fahrenheit => [Proc.new{ |t| (t + 459.67) * (5.0/9.0) }, Proc.new{ |t| t * (9.0/5.0) - 459.67 }],
         | 
| 299 | 
            +
                  :rankine => 1.8, :rankines => 1.8
         | 
| 300 | 
            +
                },
         | 
| 301 | 
            +
                :time => {
         | 
| 302 | 
            +
                  :second => 1.0, :seconds => 1.0, :s => 1.0,
         | 
| 303 | 
            +
                  :minute => 60.0, :minutes => 60.0, :min => 60.0,
         | 
| 304 | 
            +
                  :sidereal_minute => 5.983617, :sidereal_minutes => 5.983617,
         | 
| 305 | 
            +
                  :hour => 3600.0, :hours => 3600.0, :hr => 3600.0, :h => 3600.0,
         | 
| 306 | 
            +
                  :sidereal_hour => 3.590170e+3, :sidereal_hours => 3.590170e+3,
         | 
| 307 | 
            +
                  :day => 86400.0, :days => 86400.0,
         | 
| 308 | 
            +
                  :sidereal_day => 8.616409e+4, :sidereal_days => 8.616409e+4,
         | 
| 309 | 
            +
                  :shake => 1.0e-8, :shakes => 1.0e-8,
         | 
| 310 | 
            +
                  :year => 3.1536e+7, :years => 3.1536e+7,
         | 
| 311 | 
            +
                  :sidereal_year => 3.155815e+7, :sidereal_years => 3.155815e+7,
         | 
| 312 | 
            +
                  :tropical_year => 3.155693e+7, :tropical_years => 3.155693e+7,
         | 
| 313 | 
            +
                  #unusual measurements
         | 
| 314 | 
            +
                  :jiffy => 0.01, :jiffies => 0.01,
         | 
| 315 | 
            +
                  :microfortnight => 1.2096, :microfortnights => 1.2096,
         | 
| 316 | 
            +
                  :megaannum => 3.1536e+16, :Ma => 3.1536e+16, :megaannums => 3.1536e+16,
         | 
| 317 | 
            +
                  :galactic_year => 7.884e+18, :galactic_years => 7.884e+18, :GY => 7.884e+18
         | 
| 318 | 
            +
                },
         | 
| 319 | 
            +
                :volume => {
         | 
| 320 | 
            +
                  :litre => 1.0, :liter => 1.0, :litres => 1.0, :liters => 1.0, :l => 1.0, :L => 1.0,
         | 
| 321 | 
            +
                  :barrel => 1.589873e+2, :barrels => 1.589873e+2,
         | 
| 322 | 
            +
                  :bushel => 3.523907e+1, :bushels => 3.523907e+1,
         | 
| 323 | 
            +
                  :cubic_meter => 1000.0, :cubic_meters => 1000.0,
         | 
| 324 | 
            +
                  :cup => 2.365882e-1, :cups => 2.365882e-1,
         | 
| 325 | 
            +
                  :imperial_fluid_ounce => 0.0284130742, :imperial_fluid_ounces => 0.0284130742,
         | 
| 326 | 
            +
                  :ounce => 0.0295735296, :ounces => 0.0295735296, :fluid_ounce => 0.0295735296, :fluid_ounces => 0.0295735296,
         | 
| 327 | 
            +
                  :imperial_gallon => 4.54609, :imperial_gallons => 4.54609,
         | 
| 328 | 
            +
                  :gallon => 3.785412, :gallons => 3.785412, :gals => 3.785412, :Gals => 3.785412,
         | 
| 329 | 
            +
                  :imperial_gill => 1.420653e-1, :imperial_gills => 1.420653e-1,
         | 
| 330 | 
            +
                  :gill => 1.182941e-1, :gills => 1.182941e-1, :gi => 1.182941e-1,
         | 
| 331 | 
            +
                  :pint => 5.506105e-1, :pints => 5.506105e-1,
         | 
| 332 | 
            +
                  :liquid_pint => 4.731765e-1, :liquid_pints => 4.731765e-1,
         | 
| 333 | 
            +
                  :quart => 1.101221, :quarts => 1.101221,
         | 
| 334 | 
            +
                  :liquid_quart => 9.463529e-1, :liquid_quarts => 9.463529e-1,
         | 
| 335 | 
            +
                  :tablespoon => 0.0147867648, :tablespoons => 0.0147867648,
         | 
| 336 | 
            +
                  :teaspoon => 0.00492892159, :teaspoons => 0.00492892159,
         | 
| 337 | 
            +
                  #unusual measurements
         | 
| 338 | 
            +
                  :sydharb => 5.0e+11, :sydharbs => 5.0e+11
         | 
| 339 | 
            +
                }
         | 
| 340 | 
            +
              }
         | 
| 341 | 
            +
            end
         | 
| @@ -0,0 +1,96 @@ | |
| 1 | 
            +
            require 'singleton'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Metamorphosis
         | 
| 4 | 
            +
              class Engine
         | 
| 5 | 
            +
                include Singleton
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                attr_reader :registry
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def numeric_to_unit_value(numeric, unit_name)
         | 
| 10 | 
            +
                  exponent, unit_symbol = @parser.parse(unit_name)
         | 
| 11 | 
            +
                  return nil unless @registry.include?(unit_symbol)
         | 
| 12 | 
            +
                  UnitValue.new(unit_symbol, numeric, exponent)
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def initialize
         | 
| 16 | 
            +
                  reset!
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def reset!
         | 
| 20 | 
            +
                  @registry = UnitRegistry.new
         | 
| 21 | 
            +
                  @parser = PrefixParser.new(DEFAULT_PREFIXES, @registry)
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def common_unit_category(source, dest)
         | 
| 25 | 
            +
                  source_categories = @registry.unit_categories(source)
         | 
| 26 | 
            +
                  dest_categories   = @registry.unit_categories(dest)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  category = (source_categories & dest_categories).first
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def convert_to(dest_unit_name, source)
         | 
| 32 | 
            +
                  return source if dest_unit_name.to_sym == source.unit_symbol
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  exponent, dest_unit_symbol = @parser.parse(dest_unit_name)
         | 
| 35 | 
            +
                  return unless @registry.include?(dest_unit_symbol)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  category = common_unit_category(source.unit_symbol, dest_unit_symbol)
         | 
| 38 | 
            +
                  unless category
         | 
| 39 | 
            +
                    raise IncompatibleUnitsError,
         | 
| 40 | 
            +
                      "Cannot convert from #{source.unit_symbol} to #{dest_unit_symbol}"
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  value = to_base_value(category, source)
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  from_base_value(category, dest_unit_symbol, value, exponent)
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def from_base_value(category, dest_unit_symbol, value, exponent)
         | 
| 49 | 
            +
                  conversion_factor = @registry.conversion_factor(category, dest_unit_symbol)
         | 
| 50 | 
            +
                  if conversion_factor.is_a?(Array)
         | 
| 51 | 
            +
                    new_unit_value = conversion_factor[1].call(value)
         | 
| 52 | 
            +
                  else
         | 
| 53 | 
            +
                    new_unit_value = value / (exponent * conversion_factor)
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                  UnitValue.new(dest_unit_symbol, new_unit_value)
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                def to_base_value(category, source_unit)
         | 
| 59 | 
            +
                  conversion_factor = @registry.conversion_factor(category, source_unit.unit_symbol)
         | 
| 60 | 
            +
                  if(conversion_factor.is_a?(Array))
         | 
| 61 | 
            +
                    conversion_factor[0].call(source_unit.value) * source_unit.exponent
         | 
| 62 | 
            +
                  else
         | 
| 63 | 
            +
                    source_unit.to_f * conversion_factor
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def register_unit(category, symbols, value)
         | 
| 68 | 
            +
                  value = value.is_a?(UnitValue) ? to_base_value(category, value) : value
         | 
| 69 | 
            +
                  symbols = Array(symbols)
         | 
| 70 | 
            +
                  symbols.each do |unit_symbol|
         | 
| 71 | 
            +
                    @registry.register(category, unit_symbol, value)
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              def self.engine
         | 
| 78 | 
            +
                Engine.instance
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              def self.register_predefined_units
         | 
| 82 | 
            +
                PRE_DEFINED_UNITS.each do |category, units|
         | 
| 83 | 
            +
                  units.each do |unit_symbol, value|
         | 
| 84 | 
            +
                    engine.register_unit(category, unit_symbol, value)
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
              def self.reset!
         | 
| 90 | 
            +
                engine.reset!
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              def self.register_unit(category, symbols, value)
         | 
| 94 | 
            +
                engine.register_unit(category, symbols, value)
         | 
| 95 | 
            +
              end
         | 
| 96 | 
            +
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            module Metamorphosis
         | 
| 2 | 
            +
              class PrefixParser
         | 
| 3 | 
            +
                attr_reader :prefixes
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(prefixes, available_units)
         | 
| 6 | 
            +
                  @prefixes = prefixes
         | 
| 7 | 
            +
                  @available_units = available_units
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                # Given a known set of unit names, returns the prefix value,
         | 
| 11 | 
            +
                # and the base unit name
         | 
| 12 | 
            +
                def parse(unit_text)
         | 
| 13 | 
            +
                  unit_text = unit_text.to_s
         | 
| 14 | 
            +
                  @prefixes.each do |prefix, value|
         | 
| 15 | 
            +
                    unit = parse_unit(unit_text, prefix)
         | 
| 16 | 
            +
                    next unless unit
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    return [value, unit]
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                  [1.0, unit_text.to_sym]
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
             | 
| 24 | 
            +
                #############################################
         | 
| 25 | 
            +
                private
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def parse_unit(unit_text, prefix)
         | 
| 28 | 
            +
                  md = /^#{prefix}(.+)/.match(unit_text)
         | 
| 29 | 
            +
                  return unless md
         | 
| 30 | 
            +
                  unit = md[1].to_sym
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  @available_units.include?(unit) ? unit : nil
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            module Metamorphosis
         | 
| 2 | 
            +
              class UnitRegistry
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                def initialize
         | 
| 5 | 
            +
                  @categories = Hash.new{|h,k| h[k] = {} }
         | 
| 6 | 
            +
                  @unit_category_lookup = Hash.new{|h,k| h[k] = Set.new }
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def register(category, unit, conversion)
         | 
| 10 | 
            +
                  category_symbol = category.to_sym
         | 
| 11 | 
            +
                  unit_symbol = unit.to_sym
         | 
| 12 | 
            +
                  @categories[category_symbol][unit_symbol] = conversion
         | 
| 13 | 
            +
                  @unit_category_lookup[unit_symbol] << category_symbol
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def category_names
         | 
| 17 | 
            +
                  @categories.keys
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def unit_categories(unit)
         | 
| 21 | 
            +
                  unit_symbol = unit.is_a?(UnitValue) ? unit.unit_symbol : unit.to_sym
         | 
| 22 | 
            +
                  @unit_category_lookup[unit_symbol]
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
             | 
| 26 | 
            +
                def conversion_factor(category, unit)
         | 
| 27 | 
            +
                  @categories[category.to_sym][unit]
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def include?(unit)
         | 
| 31 | 
            +
                  @unit_category_lookup.include?(unit.to_sym)
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
| @@ -0,0 +1,54 @@ | |
| 1 | 
            +
            module Metamorphosis
         | 
| 2 | 
            +
              class UnitValue
         | 
| 3 | 
            +
                include Comparable
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                attr_reader :unit_symbol, :value, :exponent
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(unit_symbol, value, exponent = 1.0)
         | 
| 8 | 
            +
                  @unit_symbol = unit_symbol.to_sym
         | 
| 9 | 
            +
                  @value = value
         | 
| 10 | 
            +
                  @exponent = exponent.to_f
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def to_s
         | 
| 14 | 
            +
                  "#{self.to_f} #{unit_symbol}"
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def to_f
         | 
| 18 | 
            +
                  @exponent * @value
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def to_i
         | 
| 22 | 
            +
                  to_f.to_i
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def <=>(other_unit)
         | 
| 26 | 
            +
                  unless other_unit.is_a?(UnitValue) || other_unit.is_a?(Numeric)
         | 
| 27 | 
            +
                    raise ArgumentError,
         | 
| 28 | 
            +
                          "Unable to compare #{self.to_s} with #{other_unit.class}"
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  # Assume numeric values are of the same unit type
         | 
| 32 | 
            +
                  return self.to_f <=> other_unit if other_unit.is_a?(Numeric)
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  # Convert the unit if they're not the same unit already
         | 
| 35 | 
            +
                  unless @unit_symbol == other_unit.unit_symbol
         | 
| 36 | 
            +
                    other_unit = other_unit.to(@unit_symbol)
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  self.to_f <=> other_unit.to_f
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def to(unit_symbol = nil)
         | 
| 43 | 
            +
                  return self unless unit_symbol
         | 
| 44 | 
            +
                  Metamorphosis.engine.convert_to(unit_symbol, self)
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
                alias_method :as, :to
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def method_missing method_name, *args, &block
         | 
| 49 | 
            +
                  self.to(method_name) ||
         | 
| 50 | 
            +
                    super( method_name, *args, &block )
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
            end
         | 
    
        data/lib/numeric.rb
    ADDED
    
    
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            require 'rubygems' unless defined? Gem
         | 
| 2 | 
            +
            require File.dirname(__FILE__) + "/lib/metamorphosis/version"
         | 
| 3 | 
            +
            Gem::Specification.new do |s|
         | 
| 4 | 
            +
              s.name        = "metamorphosis"
         | 
| 5 | 
            +
              s.version     = Metamorphosis::VERSION
         | 
| 6 | 
            +
              s.authors     = ["Ryan Stawarz"]
         | 
| 7 | 
            +
              s.email       = "rstawarz@wegowise.com"
         | 
| 8 | 
            +
              s.homepage    = "http://github.com/wegowise/metamorphosis"
         | 
| 9 | 
            +
              s.summary     = "A library for enabling conversions between units"
         | 
| 10 | 
            +
              s.description = "A library for enabling conversions between units"
         | 
| 11 | 
            +
              s.add_development_dependency('rspec')
         | 
| 12 | 
            +
              s.required_rubygems_version = ">= 1.3.6"
         | 
| 13 | 
            +
              s.files = Dir.glob(%w[{lib,spec}/**/*.rb bin/* [A-Z]*.{txt,rdoc,md} ext/**/*.{rb,c}]) + %w{metamorphosis.gemspec}
         | 
| 14 | 
            +
              s.license = 'MIT'
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,104 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Metamorphosis::Engine do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              let!(:engine){ Metamorphosis::Engine.instance }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              before{ Metamorphosis.register_predefined_units }
         | 
| 8 | 
            +
              after { Metamorphosis.reset! }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              describe "#numeric_to_unit_value" do
         | 
| 11 | 
            +
                it "Creates a UnitValue from a numeric value and a unit name" do
         | 
| 12 | 
            +
                  engine.numeric_to_unit_value(42.0, 'J').
         | 
| 13 | 
            +
                    should == Metamorphosis::UnitValue.new(:J, 42.0)
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                it "Creates a UnitValue from a numeric value and a unit name with a prefix" do
         | 
| 17 | 
            +
                  val = engine.numeric_to_unit_value(42.0, 'kJ')
         | 
| 18 | 
            +
                  val.should == Metamorphosis::UnitValue.new(:J, 42.0, 1_000)
         | 
| 19 | 
            +
                  val.to_f.should == 42_000
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                it "returns nil when the unit_name is not recognized" do
         | 
| 23 | 
            +
                  engine.numeric_to_unit_value(1.0, 'junk').should be_nil
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              describe "#convert_to" do
         | 
| 28 | 
            +
                it "converts 16 ounces to cups" do
         | 
| 29 | 
            +
                  engine.convert_to(:cups, 16.ounces).to_f.
         | 
| 30 | 
            +
                    should be_within(0.000001).of(2)
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                it "converts 73 degress F to celsius" do
         | 
| 34 | 
            +
                  engine.convert_to(:celsius, 73.degree_fahrenheit).to_f.
         | 
| 35 | 
            +
                    should be_within(0.0001).of(22.7778)
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                it "converts btu's to kilowatt_hour" do
         | 
| 39 | 
            +
                  engine.convert_to(:kilowatt_hours, 1054.350.british_thermal_units).
         | 
| 40 | 
            +
                    to_f.should be_within(0.000001).of(0.3087927)
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                it "convert joules's to therms" do
         | 
| 44 | 
            +
                  engine.convert_to(:therms, 1.J).to_f.
         | 
| 45 | 
            +
                    should be_within(0.0001).of(1/1.05506e+8)
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                it "converts to the same unit" do
         | 
| 49 | 
            +
                  engine.convert_to(:therms, 44.therms).to_f.
         | 
| 50 | 
            +
                    should == 44
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              describe "#to_base_value" do
         | 
| 55 | 
            +
                it "converts units into base unit values" do
         | 
| 56 | 
            +
                  engine.to_base_value(:energy, 1.british_thermal_units).
         | 
| 57 | 
            +
                    should == 1_054.35
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                it "uses the first proc to convert to the base value when provided" do
         | 
| 61 | 
            +
                  engine.to_base_value(:temperature, 1.3.celsius).
         | 
| 62 | 
            +
                    should == 274.45
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
              describe "#from_base_values" do
         | 
| 67 | 
            +
                it "converts from base values" do
         | 
| 68 | 
            +
                  engine.from_base_value(:energy, :british_thermal_units, 1_054.35, 1.0).
         | 
| 69 | 
            +
                    should == 1.british_thermal_units
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                it "converts from base values using the last proc when provided" do
         | 
| 73 | 
            +
                  engine.from_base_value(:temperature, :celsius, 274.45, 1.0).to_f.
         | 
| 74 | 
            +
                    should be_within(0.00000000001).of(1.3)
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              # Incompatible type checking (i.e. area to volume
         | 
| 79 | 
            +
              it "raises an Error when the unit types are not compatible" do
         | 
| 80 | 
            +
                expect{ engine.convert_to(:square_meter, 16.ounces) }.
         | 
| 81 | 
            +
                  to raise_error(Metamorphosis::IncompatibleUnitsError)
         | 
| 82 | 
            +
              end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
              it "will register multiple units symbosl to the same value" do
         | 
| 85 | 
            +
                engine.register_unit(:stuff, [:value1a, :value1b], 1.0)
         | 
| 86 | 
            +
                engine.register_unit(:stuff, [:value2c, :value2d], 2.0)
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                1.value1b.value1a.to_f.should == 1.value1a.to_f
         | 
| 89 | 
            +
                1.value1a.should == 1.value1b
         | 
| 90 | 
            +
                1.value2c.value1a.to_f.should == 2.0
         | 
| 91 | 
            +
                1.value2c.should == 2.value1a
         | 
| 92 | 
            +
                1.value2c.should == 1.value2d
         | 
| 93 | 
            +
                1.value2d.should == 2.value1b
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
              it "#register_units allows units to be defined based on other units" do
         | 
| 97 | 
            +
                Metamorphosis.reset!
         | 
| 98 | 
            +
                Metamorphosis.register_unit(:energy, :btu, 1.0)
         | 
| 99 | 
            +
                Metamorphosis.register_unit(:energy, :therms, 100_000.btu)
         | 
| 100 | 
            +
                Metamorphosis.register_unit(:energy, :kwh, 0.03413.therms)
         | 
| 101 | 
            +
                1.kwh.to.btu.to_f.should == 3413.0
         | 
| 102 | 
            +
              end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
            end
         | 
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Metamorphosis::PrefixParser do
         | 
| 4 | 
            +
              let!(:available_units) {Metamorphosis::SI_UNITS }
         | 
| 5 | 
            +
              let!(:prefixes) { Metamorphosis::DEFAULT_PREFIXES }
         | 
| 6 | 
            +
              let!(:parser) {Metamorphosis::PrefixParser.new(prefixes, available_units)}
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              [:meter, :joule].each do |unit|
         | 
| 9 | 
            +
                Metamorphosis::DEFAULT_PREFIXES.each do |prefix, value|
         | 
| 10 | 
            +
                  new_unit = "#{prefix}#{unit}"
         | 
| 11 | 
            +
                  it "parses #{new_unit}as [#{value}, #{unit}]" do
         | 
| 12 | 
            +
                    parser.parse(new_unit).should == [value, unit.to_sym]
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              it "should parse kJ" do
         | 
| 18 | 
            +
                parser.parse("kJ").should == [1000.0, :J]
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              it "should return the unit with value of 1.0 for unknown prefix" do
         | 
| 22 | 
            +
                parser.parse("crazystuff").should == [1.0, :crazystuff]
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              it "should return the unit with value of 1.0 for unknown unit" do
         | 
| 26 | 
            +
                parser.parse("kilojunk").should == [1.0, :kilojunk]
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              it "should allow prefixes to be overridden" do
         | 
| 30 | 
            +
                prefixes = { :yotta => 2**80, :Y => 2**80,
         | 
| 31 | 
            +
                             :zetta => 2**70, :Z => 2**70,
         | 
| 32 | 
            +
                             :exa   => 2**60, :E => 2**60,
         | 
| 33 | 
            +
                             :peta  => 2**50, :P => 2**50,
         | 
| 34 | 
            +
                             :tera  => 2**40, :T => 2**40,
         | 
| 35 | 
            +
                             :giga  => 2**30, :G => 2**30,
         | 
| 36 | 
            +
                             :mega  => 2**20, :M => 2**20,
         | 
| 37 | 
            +
                             :kilo  => 2**10, :k => 2**10 }
         | 
| 38 | 
            +
                parser = Metamorphosis::PrefixParser.new(prefixes, [:byte])
         | 
| 39 | 
            +
                parser.parse("kbyte").should == [1024, :byte]
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                parser.parse("Mbyte").should == [1048576, :byte]
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Metamorphosis::UnitRegistry do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              let!(:registry) { Metamorphosis::UnitRegistry.new }
         | 
| 6 | 
            +
              let!(:subject)  { registry }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              before do
         | 
| 9 | 
            +
                registry.register(:wegowise, :btu, 1)
         | 
| 10 | 
            +
                registry.register(:wegowise, :therms, 100_000)
         | 
| 11 | 
            +
                registry.register(:other, :btu, 22)
         | 
| 12 | 
            +
                registry.register(:junk, :whatchamakalit, 0.0000001)
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              its(:category_names) { should match_array [:wegowise, :other, :junk] }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              it "keeps different conversion factors for units across categories" do
         | 
| 18 | 
            +
                registry.conversion_factor(:wegowise, :btu).
         | 
| 19 | 
            +
                  should_not == registry.conversion_factor(:other, :btu)
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              it "returns the set of categories a unit belongs to" do
         | 
| 23 | 
            +
                registry.unit_categories(:btu).to_a.should match_array [:wegowise, :other]
         | 
| 24 | 
            +
                registry.unit_categories(:therms).to_a.should == [:wegowise]
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              it "tracks conversion factors for units" do
         | 
| 28 | 
            +
                registry.conversion_factor(:wegowise, :btu).should == 1
         | 
| 29 | 
            +
                registry.conversion_factor(:wegowise, :therms).should == 100_000
         | 
| 30 | 
            +
                registry.conversion_factor(:other, :btu).should == 22
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              it "tracks which units have been registered" do
         | 
| 34 | 
            +
                registry.include?(:btu).should be_true
         | 
| 35 | 
            +
                registry.include?(:therms).should be_true
         | 
| 36 | 
            +
                registry.include?(:joules).should be_false
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
            end
         | 
| @@ -0,0 +1,69 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Metamorphosis::UnitValue do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              before{ Metamorphosis.register_predefined_units }
         | 
| 6 | 
            +
              after { Metamorphosis.reset! }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              let!(:unit) { Metamorphosis::UnitValue.new('therms', 1.3, 1_000) }
         | 
| 9 | 
            +
              subject{ unit }
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              its(:unit_symbol){ should == :therms }
         | 
| 12 | 
            +
              its(:exponent){ should == 1_000 }
         | 
| 13 | 
            +
              its(:value){ should == 1.3 }
         | 
| 14 | 
            +
              its(:to_s){ should == '1300.0 therms' }
         | 
| 15 | 
            +
              its(:to_f){ should == 1300.0 }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              # Comparisons between the same unit
         | 
| 18 | 
            +
              it{ should be == Metamorphosis::UnitValue.new(:therms, 1_300)  }
         | 
| 19 | 
            +
              it{ should be >  Metamorphosis::UnitValue.new(:therms, 1_290) }
         | 
| 20 | 
            +
              it{ should be <  Metamorphosis::UnitValue.new(:therms, 1_310)  }
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              # Comparisons between different units
         | 
| 23 | 
            +
              it{ should be >  Metamorphosis::UnitValue.new(:J, 1_000)  }
         | 
| 24 | 
            +
              it{ should be ==  Metamorphosis::UnitValue.new(:J, 1.05506e+8 * 1_300)  }
         | 
| 25 | 
            +
              it{ should be <  Metamorphosis::UnitValue.new(:J, 1.05506e+8 * 1_400)  }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              # Should not compare units that are not alike (i.e. energy vs. distance)
         | 
| 28 | 
            +
              it{ should_not eq(Metamorphosis::UnitValue.new(:meters, 100))  }
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              it "compares like units" do
         | 
| 31 | 
            +
                Metamorphosis::UnitValue.new('therms', 85.30320550490019).should ==
         | 
| 32 | 
            +
                  Metamorphosis::UnitValue.new('kilowatt_hour', 2_500)
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              # Don't compare non unit like things
         | 
| 36 | 
            +
              it{ should_not be ==  :x }
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              it "raises ArgumentError comparing non numeric/UnitValues with UnitValue" do
         | 
| 39 | 
            +
                expect{ unit <=>  :x }.to raise_error(ArgumentError)
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              # Assume numeric values are of the same unit
         | 
| 43 | 
            +
              it { should be == 1_300 }
         | 
| 44 | 
            +
             | 
| 45 | 
            +
             | 
| 46 | 
            +
              it "returns itself when to/as method receives no parameters" do
         | 
| 47 | 
            +
                unit.to.should === unit
         | 
| 48 | 
            +
                unit.as.should === unit
         | 
| 49 | 
            +
              end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              it "delegates conversion to the Metamorphosis::Engine" do
         | 
| 52 | 
            +
                Metamorphosis.engine.should_receive(:convert_to).with(:J, unit)
         | 
| 53 | 
            +
                unit.to(:J)
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              it "delegates missing methods to the Metamorphosis::Engine" do
         | 
| 57 | 
            +
                Metamorphosis.engine.should_receive(:convert_to).with(:J, unit).
         | 
| 58 | 
            +
                  and_return("cooking with fire!")
         | 
| 59 | 
            +
                unit.to(:J).should == "cooking with fire!"
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
              it "is a good method_missing citizen when Metamorphosis doesn't know how
         | 
| 63 | 
            +
                  to convert to the given unit" do
         | 
| 64 | 
            +
                Metamorphosis.engine.should_receive(:convert_to).with(:J, unit).
         | 
| 65 | 
            +
                  and_return(nil)
         | 
| 66 | 
            +
                expect{ unit.J }.to raise_error(NoMethodError)
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            require "spec_helper"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Metamorphosis do
         | 
| 4 | 
            +
               it "Exposes Metamorphosis::Engine as 'engine'" do
         | 
| 5 | 
            +
                 Metamorphosis.engine.should === Metamorphosis::Engine.instance
         | 
| 6 | 
            +
               end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
               it "registers the units defined as constants" do
         | 
| 9 | 
            +
                 Metamorphosis.register_predefined_units
         | 
| 10 | 
            +
                 1.respond_to?(:kwh)
         | 
| 11 | 
            +
                 1.respond_to?(:kilowatt_hour)
         | 
| 12 | 
            +
               end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
               it "exposes 'register_unit' from engine" do
         | 
| 15 | 
            +
                 Metamorphosis.engine.should_receive(:register_unit).with(:a, :b, :c)
         | 
| 16 | 
            +
                 Metamorphosis.register_unit(:a, :b, :c)
         | 
| 17 | 
            +
               end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Numeric do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              it "delegates missing method calls to the Metamorphosis::Engine" do
         | 
| 6 | 
            +
                engine = Metamorphosis::Engine.instance
         | 
| 7 | 
            +
                engine.should_receive(:numeric_to_unit_value).with(1.3, :J).
         | 
| 8 | 
            +
                  and_return('eureka!')
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                1.3.J.should == 'eureka!'
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              it "raises a method not found exception when the engine returns an empty result" do
         | 
| 14 | 
            +
                engine = Metamorphosis::Engine.instance
         | 
| 15 | 
            +
                engine.should_receive(:numeric_to_unit_value).with(1.3, :J).
         | 
| 16 | 
            +
                  and_return(nil)
         | 
| 17 | 
            +
                expect{ 1.3.J }.to raise_error(NoMethodError)
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            # This file was generated by the `rspec --init` command. Conventionally, all
         | 
| 2 | 
            +
            # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
         | 
| 3 | 
            +
            # Require this file using `require "spec_helper"` to ensure that it is only
         | 
| 4 | 
            +
            # loaded once.
         | 
| 5 | 
            +
            #
         | 
| 6 | 
            +
            # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
         | 
| 7 | 
            +
            RSpec.configure do |config|
         | 
| 8 | 
            +
              config.treat_symbols_as_metadata_keys_with_true_values = true
         | 
| 9 | 
            +
              config.run_all_when_everything_filtered = true
         | 
| 10 | 
            +
              config.filter_run :focus
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              # Run specs in random order to surface order dependencies. If you find an
         | 
| 13 | 
            +
              # order dependency and want to debug it, you can fix the order by providing
         | 
| 14 | 
            +
              # the seed, which is printed after each run.
         | 
| 15 | 
            +
              #     --seed 1234
         | 
| 16 | 
            +
              config.order = 'random'
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            require 'metamorphosis'
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,80 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: metamorphosis
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: '0.1'
         | 
| 5 | 
            +
              prerelease: 
         | 
| 6 | 
            +
            platform: ruby
         | 
| 7 | 
            +
            authors:
         | 
| 8 | 
            +
            - Ryan Stawarz
         | 
| 9 | 
            +
            autorequire: 
         | 
| 10 | 
            +
            bindir: bin
         | 
| 11 | 
            +
            cert_chain: []
         | 
| 12 | 
            +
            date: 2012-11-13 00:00:00.000000000 Z
         | 
| 13 | 
            +
            dependencies:
         | 
| 14 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 15 | 
            +
              name: rspec
         | 
| 16 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 17 | 
            +
                none: false
         | 
| 18 | 
            +
                requirements:
         | 
| 19 | 
            +
                - - ! '>='
         | 
| 20 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 21 | 
            +
                    version: '0'
         | 
| 22 | 
            +
              type: :development
         | 
| 23 | 
            +
              prerelease: false
         | 
| 24 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 25 | 
            +
                none: false
         | 
| 26 | 
            +
                requirements:
         | 
| 27 | 
            +
                - - ! '>='
         | 
| 28 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 29 | 
            +
                    version: '0'
         | 
| 30 | 
            +
            description: A library for enabling conversions between units
         | 
| 31 | 
            +
            email: rstawarz@wegowise.com
         | 
| 32 | 
            +
            executables: []
         | 
| 33 | 
            +
            extensions: []
         | 
| 34 | 
            +
            extra_rdoc_files: []
         | 
| 35 | 
            +
            files:
         | 
| 36 | 
            +
            - lib/metamorphosis/constants.rb
         | 
| 37 | 
            +
            - lib/metamorphosis/engine.rb
         | 
| 38 | 
            +
            - lib/metamorphosis/errors.rb
         | 
| 39 | 
            +
            - lib/metamorphosis/prefix_parser.rb
         | 
| 40 | 
            +
            - lib/metamorphosis/unit_registry.rb
         | 
| 41 | 
            +
            - lib/metamorphosis/unit_value.rb
         | 
| 42 | 
            +
            - lib/metamorphosis/version.rb
         | 
| 43 | 
            +
            - lib/metamorphosis.rb
         | 
| 44 | 
            +
            - lib/numeric.rb
         | 
| 45 | 
            +
            - spec/lib/metamorphosis/engine_spec.rb
         | 
| 46 | 
            +
            - spec/lib/metamorphosis/prefix_parser_spec.rb
         | 
| 47 | 
            +
            - spec/lib/metamorphosis/unit_registry_spec.rb
         | 
| 48 | 
            +
            - spec/lib/metamorphosis/unit_value_spec.rb
         | 
| 49 | 
            +
            - spec/lib/metamorphosis_spec.rb
         | 
| 50 | 
            +
            - spec/lib/numeric_spec.rb
         | 
| 51 | 
            +
            - spec/spec_helper.rb
         | 
| 52 | 
            +
            - LICENSE.txt
         | 
| 53 | 
            +
            - README.md
         | 
| 54 | 
            +
            - metamorphosis.gemspec
         | 
| 55 | 
            +
            homepage: http://github.com/wegowise/metamorphosis
         | 
| 56 | 
            +
            licenses:
         | 
| 57 | 
            +
            - MIT
         | 
| 58 | 
            +
            post_install_message: 
         | 
| 59 | 
            +
            rdoc_options: []
         | 
| 60 | 
            +
            require_paths:
         | 
| 61 | 
            +
            - lib
         | 
| 62 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 63 | 
            +
              none: false
         | 
| 64 | 
            +
              requirements:
         | 
| 65 | 
            +
              - - ! '>='
         | 
| 66 | 
            +
                - !ruby/object:Gem::Version
         | 
| 67 | 
            +
                  version: '0'
         | 
| 68 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 69 | 
            +
              none: false
         | 
| 70 | 
            +
              requirements:
         | 
| 71 | 
            +
              - - ! '>='
         | 
| 72 | 
            +
                - !ruby/object:Gem::Version
         | 
| 73 | 
            +
                  version: 1.3.6
         | 
| 74 | 
            +
            requirements: []
         | 
| 75 | 
            +
            rubyforge_project: 
         | 
| 76 | 
            +
            rubygems_version: 1.8.24
         | 
| 77 | 
            +
            signing_key: 
         | 
| 78 | 
            +
            specification_version: 3
         | 
| 79 | 
            +
            summary: A library for enabling conversions between units
         | 
| 80 | 
            +
            test_files: []
         |