unit 0.3.0 → 0.4.0
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/.gitignore +1 -0
- data/Rakefile +16 -4
- data/lib/unit/class.rb +140 -59
- data/lib/unit/dsl.rb +5 -4
- data/lib/unit/system.rb +3 -0
- data/lib/unit/systems/si.yml +1 -1
- data/lib/unit/version.rb +1 -1
- data/spec/error_spec.rb +27 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/unit_one.rb +46 -0
- data/{test/system_test.rb → spec/system_spec.rb} +13 -5
- data/spec/unit_spec.rb +225 -0
- data/{test → spec}/yml/filename.yml +0 -0
- data/{test → spec}/yml/io.yml +0 -0
- data/unit.gemspec +2 -2
- metadata +43 -50
- data/test/error_test.rb +0 -16
- data/test/unit_test.rb +0 -144
    
        data/.gitignore
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            Gemfile.lock
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -1,6 +1,18 @@ | |
| 1 | 
            -
            task :default => :test
         | 
| 2 1 |  | 
| 3 | 
            -
             | 
| 4 | 
            -
            task : | 
| 5 | 
            -
             | 
| 2 | 
            +
            require 'rspec/core/rake_task'
         | 
| 3 | 
            +
            task :default => :spec
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            desc "Run specs"
         | 
| 6 | 
            +
            task :spec => ["spec:no_dsl", "spec:dsl"]
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            namespace :spec do
         | 
| 9 | 
            +
              desc "Run specs without DSL"
         | 
| 10 | 
            +
              RSpec::Core::RakeTask.new(:no_dsl) do |t|
         | 
| 11 | 
            +
                t.rspec_opts = "-t ~dsl"
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              desc "Run specs with DSL"
         | 
| 15 | 
            +
              RSpec::Core::RakeTask.new(:dsl) do |t|
         | 
| 16 | 
            +
                # Run all tests
         | 
| 17 | 
            +
              end
         | 
| 6 18 | 
             
            end
         | 
    
        data/lib/unit/class.rb
    CHANGED
    
    | @@ -2,6 +2,8 @@ | |
| 2 2 | 
             
            class Unit < Numeric
         | 
| 3 3 | 
             
              attr_reader :value, :normalized, :unit, :system
         | 
| 4 4 |  | 
| 5 | 
            +
              class IncompatibleUnitError < TypeError; end
         | 
| 6 | 
            +
             | 
| 5 7 | 
             
              def initialize(value, unit, system)
         | 
| 6 8 | 
             
                @system = system
         | 
| 7 9 | 
             
                @value = value
         | 
| @@ -44,21 +46,33 @@ class Unit < Numeric | |
| 44 46 | 
             
              end
         | 
| 45 47 |  | 
| 46 48 | 
             
              def *(other)
         | 
| 47 | 
            -
                 | 
| 48 | 
            -
             | 
| 49 | 
            +
                if Numeric === other
         | 
| 50 | 
            +
                  other = coerce_numeric(other)
         | 
| 51 | 
            +
                  Unit.new(other.value * self.value, other.unit + self.unit, system)
         | 
| 52 | 
            +
                else
         | 
| 53 | 
            +
                  apply_through_coercion(other, __method__)
         | 
| 54 | 
            +
                end
         | 
| 49 55 | 
             
              end
         | 
| 50 56 |  | 
| 51 57 | 
             
              def /(other)
         | 
| 52 | 
            -
                 | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 58 | 
            +
                if Numeric === other
         | 
| 59 | 
            +
                  other = coerce_numeric(other)
         | 
| 60 | 
            +
                  Unit.new(Integer === value && Integer === other.value ?
         | 
| 61 | 
            +
                           Rational(value, other.value) : value / other.value,
         | 
| 62 | 
            +
                           unit + Unit.power_unit(other.unit, -1), system)
         | 
| 63 | 
            +
                else
         | 
| 64 | 
            +
                  apply_through_coercion(other, __method__)
         | 
| 65 | 
            +
                end
         | 
| 55 66 | 
             
              end
         | 
| 56 67 |  | 
| 57 68 | 
             
              def +(other)
         | 
| 58 | 
            -
                 | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 69 | 
            +
                if Numeric === other
         | 
| 70 | 
            +
                  other = coerce_numeric_compatible(other)
         | 
| 71 | 
            +
                  a, b = self.normalize, other.normalize
         | 
| 72 | 
            +
                  Unit.new(a.value + b.value, b.unit, system).in(self)
         | 
| 73 | 
            +
                else
         | 
| 74 | 
            +
                  apply_through_coercion(other, __method__)
         | 
| 75 | 
            +
                end
         | 
| 62 76 | 
             
              end
         | 
| 63 77 |  | 
| 64 78 | 
             
              def **(exp)
         | 
| @@ -67,23 +81,49 @@ class Unit < Numeric | |
| 67 81 | 
             
              end
         | 
| 68 82 |  | 
| 69 83 | 
             
              def -(other)
         | 
| 70 | 
            -
                 | 
| 84 | 
            +
                if Numeric === other
         | 
| 85 | 
            +
                  other = coerce_numeric_compatible(other)
         | 
| 86 | 
            +
                  a, b = self.normalize, other.normalize
         | 
| 87 | 
            +
                  Unit.new(a.value - b.value, b.unit, system).in(self)
         | 
| 88 | 
            +
                else
         | 
| 89 | 
            +
                  apply_through_coercion(other, __method__)
         | 
| 90 | 
            +
                end
         | 
| 71 91 | 
             
              end
         | 
| 72 92 |  | 
| 73 93 | 
             
              def -@
         | 
| 74 94 | 
             
                Unit.new(-value, unit, system)
         | 
| 75 95 | 
             
              end
         | 
| 76 96 |  | 
| 97 | 
            +
              def abs
         | 
| 98 | 
            +
                Unit.new(value.abs, unit, system)
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
              def zero?
         | 
| 102 | 
            +
                value.zero?
         | 
| 103 | 
            +
              end
         | 
| 104 | 
            +
             | 
| 77 105 | 
             
              def ==(other)
         | 
| 78 | 
            -
                 | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 106 | 
            +
                if Numeric === other
         | 
| 107 | 
            +
                  other = coerce_numeric(other)
         | 
| 108 | 
            +
                  a, b = self.normalize, other.normalize
         | 
| 109 | 
            +
                  a.value == b.value && a.unit == b.unit
         | 
| 110 | 
            +
                else
         | 
| 111 | 
            +
                  apply_through_coercion(other, __method__)
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
              end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              def eql?(other)
         | 
| 116 | 
            +
                Unit === other && value.eql?(other.value) && unit == other.unit
         | 
| 81 117 | 
             
              end
         | 
| 82 118 |  | 
| 83 119 | 
             
              def <=>(other)
         | 
| 84 | 
            -
                 | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 120 | 
            +
                if Numeric === other
         | 
| 121 | 
            +
                  other = coerce_numeric_compatible(other)
         | 
| 122 | 
            +
                  a, b = self.normalize, other.normalize
         | 
| 123 | 
            +
                  a.value <=> b.value
         | 
| 124 | 
            +
                else
         | 
| 125 | 
            +
                  apply_through_coercion(other, __method__)
         | 
| 126 | 
            +
                end
         | 
| 87 127 | 
             
              end
         | 
| 88 128 |  | 
| 89 129 | 
             
              # Number without dimension
         | 
| @@ -91,22 +131,28 @@ class Unit < Numeric | |
| 91 131 | 
             
                normalize.unit.empty?
         | 
| 92 132 | 
             
              end
         | 
| 93 133 |  | 
| 94 | 
            -
               | 
| 134 | 
            +
              alias_method :unitless?, :dimensionless?
         | 
| 95 135 |  | 
| 96 136 | 
             
              # Compatible units can be added
         | 
| 97 137 | 
             
              def compatible?(other)
         | 
| 98 | 
            -
                 | 
| 99 | 
            -
                a, b = a.normalize, b.normalize
         | 
| 100 | 
            -
                a.unit == b.unit
         | 
| 138 | 
            +
                self.normalize.unit == Unit.to_unit(other, system).normalize.unit
         | 
| 101 139 | 
             
              end
         | 
| 102 140 |  | 
| 103 | 
            -
               | 
| 141 | 
            +
              alias_method :compatible_with?, :compatible?
         | 
| 104 142 |  | 
| 105 143 | 
             
              # Convert to other unit
         | 
| 106 144 | 
             
              def in(unit)
         | 
| 107 | 
            -
                 | 
| 108 | 
            -
                 | 
| 109 | 
            -
             | 
| 145 | 
            +
                conversion = Unit.new(1, Unit.to_unit(unit, system).unit, system)
         | 
| 146 | 
            +
                (self / conversion).normalize * conversion
         | 
| 147 | 
            +
              end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
              def in!(unit)
         | 
| 150 | 
            +
                unit = coerce_object(unit)
         | 
| 151 | 
            +
                result = self.in(unit)
         | 
| 152 | 
            +
                unless result.unit == unit.unit
         | 
| 153 | 
            +
                  raise TypeError, "Unexpected #{result.inspect}, expected to be in #{other_unit.unit_string}"
         | 
| 154 | 
            +
                end
         | 
| 155 | 
            +
                result
         | 
| 110 156 | 
             
              end
         | 
| 111 157 |  | 
| 112 158 | 
             
              def inspect
         | 
| @@ -114,7 +160,7 @@ class Unit < Numeric | |
| 114 160 | 
             
              end
         | 
| 115 161 |  | 
| 116 162 | 
             
              def to_s
         | 
| 117 | 
            -
                unit.empty? ? value.to_s : "#{value} #{unit_string | 
| 163 | 
            +
                unit.empty? ? value.to_s : "#{value} #{unit_string}"
         | 
| 118 164 | 
             
              end
         | 
| 119 165 |  | 
| 120 166 | 
             
              def to_tex
         | 
| @@ -130,40 +176,20 @@ class Unit < Numeric | |
| 130 176 | 
             
              end
         | 
| 131 177 |  | 
| 132 178 | 
             
              def approx
         | 
| 133 | 
            -
                 | 
| 134 | 
            -
              end
         | 
| 135 | 
            -
             | 
| 136 | 
            -
              def coerce(val)
         | 
| 137 | 
            -
                [self, Unit.to_unit(val, system)]
         | 
| 138 | 
            -
              end
         | 
| 139 | 
            -
             | 
| 140 | 
            -
              def self.to_unit(object, system = nil)
         | 
| 141 | 
            -
                system ||= Unit.default_system
         | 
| 142 | 
            -
                case object
         | 
| 143 | 
            -
                when Unit
         | 
| 144 | 
            -
                  raise TypeError, 'Different unit system' if object.system != system
         | 
| 145 | 
            -
                  object
         | 
| 146 | 
            -
                when Array
         | 
| 147 | 
            -
                  system.validate_unit(object)
         | 
| 148 | 
            -
                  Unit.new(1, object, system)
         | 
| 149 | 
            -
                when String, Symbol
         | 
| 150 | 
            -
                  unit = system.parse_unit(object.to_s)
         | 
| 151 | 
            -
                  system.validate_unit(unit)
         | 
| 152 | 
            -
                  Unit.new(1, unit, system)
         | 
| 153 | 
            -
                when Numeric
         | 
| 154 | 
            -
                  Unit.new(object, [], system)
         | 
| 155 | 
            -
                else
         | 
| 156 | 
            -
                  raise TypeError, "#{object.class} has no unit support"
         | 
| 157 | 
            -
                end
         | 
| 179 | 
            +
                Unit.new(self.to_f, unit, system)
         | 
| 158 180 | 
             
              end
         | 
| 159 181 |  | 
| 160 | 
            -
               | 
| 182 | 
            +
              def coerce(other)
         | 
| 183 | 
            +
                [coerce_numeric(other), self]
         | 
| 184 | 
            +
              end
         | 
| 161 185 |  | 
| 162 | 
            -
              def unit_string(sep)
         | 
| 186 | 
            +
              def unit_string(sep = '·')
         | 
| 163 187 | 
             
                (unit_list(@unit.select {|factor, name, exp| exp >= 0 }) +
         | 
| 164 188 | 
             
                 unit_list(@unit.select {|factor, name, exp| exp < 0 })).join(sep)
         | 
| 165 189 | 
             
              end
         | 
| 166 190 |  | 
| 191 | 
            +
              private
         | 
| 192 | 
            +
             | 
| 167 193 | 
             
              def unit_list(list)
         | 
| 168 194 | 
             
                units = []
         | 
| 169 195 | 
             
                list.each do |factor, name, exp|
         | 
| @@ -176,18 +202,14 @@ class Unit < Numeric | |
| 176 202 | 
             
                units.sort
         | 
| 177 203 | 
             
              end
         | 
| 178 204 |  | 
| 179 | 
            -
              def self.power_unit(unit, pow)
         | 
| 180 | 
            -
                unit.map {|factor, name, exp| [factor, name, exp * pow] }
         | 
| 181 | 
            -
              end
         | 
| 182 | 
            -
             | 
| 183 205 | 
             
              # Reduce units and factors
         | 
| 184 206 | 
             
              def reduce!
         | 
| 185 207 | 
             
                # Remove numbers from units
         | 
| 186 208 | 
             
                numbers = @unit.select {|factor, unit, exp| Numeric === unit }
         | 
| 187 209 | 
             
                @unit -= numbers
         | 
| 188 210 | 
             
                numbers.each do |factor, number, exp|
         | 
| 189 | 
            -
             | 
| 190 | 
            -
             | 
| 211 | 
            +
                  raise RuntimeError, 'Numeric unit with factor' if factor != :one
         | 
| 212 | 
            +
                  @value *= number ** exp
         | 
| 191 213 | 
             
                end
         | 
| 192 214 |  | 
| 193 215 | 
             
                # Reduce units
         | 
| @@ -227,7 +249,66 @@ class Unit < Numeric | |
| 227 249 | 
             
                self
         | 
| 228 250 | 
             
              end
         | 
| 229 251 |  | 
| 230 | 
            -
               | 
| 252 | 
            +
              # Given another object and an operator, use the other object's #coerce method
         | 
| 253 | 
            +
              # to perform the operation.
         | 
| 254 | 
            +
              #
         | 
| 255 | 
            +
              # Based on Matrix#apply_through_coercion
         | 
| 256 | 
            +
              def apply_through_coercion(obj, oper)
         | 
| 257 | 
            +
                coercion = obj.coerce(self)
         | 
| 258 | 
            +
                raise TypeError unless coercion.is_a?(Array) && coercion.length == 2
         | 
| 259 | 
            +
                first, last = coercion
         | 
| 260 | 
            +
                first.send(oper, last)
         | 
| 261 | 
            +
              rescue
         | 
| 262 | 
            +
                raise TypeError, "#{obj.class} can't be coerced into #{self.class}"
         | 
| 263 | 
            +
              end
         | 
| 264 | 
            +
             | 
| 265 | 
            +
              def coerce_numeric_compatible(object)
         | 
| 266 | 
            +
                object = coerce_numeric(object)
         | 
| 267 | 
            +
                raise IncompatibleUnitError, "#{inspect} and #{object.inspect} are incompatible" if !compatible?(object)
         | 
| 268 | 
            +
                object
         | 
| 269 | 
            +
              end
         | 
| 270 | 
            +
             | 
| 271 | 
            +
              def coerce_numeric(object)
         | 
| 272 | 
            +
                Unit.numeric_to_unit(object, system)
         | 
| 273 | 
            +
              end
         | 
| 274 | 
            +
             | 
| 275 | 
            +
              def coerce_object(object)
         | 
| 276 | 
            +
                Unit.to_unit(object, system)
         | 
| 277 | 
            +
              end
         | 
| 278 | 
            +
             | 
| 279 | 
            +
              class << self
         | 
| 231 280 | 
             
                attr_accessor :default_system
         | 
| 281 | 
            +
             | 
| 282 | 
            +
                def power_unit(unit, pow)
         | 
| 283 | 
            +
                  unit.map {|factor, name, exp| [factor, name, exp * pow] }
         | 
| 284 | 
            +
                end
         | 
| 285 | 
            +
             | 
| 286 | 
            +
                def numeric_to_unit(object, system = nil)
         | 
| 287 | 
            +
                  system ||= Unit.default_system
         | 
| 288 | 
            +
                  case object
         | 
| 289 | 
            +
                  when Unit
         | 
| 290 | 
            +
                    raise IncompatibleUnitError, "Unit system of #{object.inspect} is incompatible with #{system.name}" if object.system != system
         | 
| 291 | 
            +
                    object
         | 
| 292 | 
            +
                  when Numeric
         | 
| 293 | 
            +
                    Unit.new(object, [], system)
         | 
| 294 | 
            +
                  else
         | 
| 295 | 
            +
                    raise TypeError, "#{object.class} can't be coerced into Unit"
         | 
| 296 | 
            +
                  end
         | 
| 297 | 
            +
                end
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                def to_unit(object, system = nil)
         | 
| 300 | 
            +
                  system ||= Unit.default_system
         | 
| 301 | 
            +
                  case object
         | 
| 302 | 
            +
                  when String, Symbol
         | 
| 303 | 
            +
                    unit = system.parse_unit(object.to_s)
         | 
| 304 | 
            +
                    system.validate_unit(unit)
         | 
| 305 | 
            +
                    Unit.new(1, unit, system)
         | 
| 306 | 
            +
                  when Array
         | 
| 307 | 
            +
                    system.validate_unit(object)
         | 
| 308 | 
            +
                    Unit.new(1, object, system)
         | 
| 309 | 
            +
                  else
         | 
| 310 | 
            +
                    numeric_to_unit(object, system)
         | 
| 311 | 
            +
                  end
         | 
| 312 | 
            +
                end
         | 
| 232 313 | 
             
              end
         | 
| 233 314 | 
             
            end
         | 
    
        data/lib/unit/dsl.rb
    CHANGED
    
    | @@ -13,11 +13,12 @@ class Unit < Numeric | |
| 13 13 | 
             
                name.to_s.sub(/^per_/, '1/').gsub('_per_', '/').gsub('_', ' ')
         | 
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 | 
            -
              def method_missing(name)
         | 
| 17 | 
            -
                if name.to_s =~ /^in_ | 
| 18 | 
            -
                   | 
| 16 | 
            +
              def method_missing(name, system = nil)
         | 
| 17 | 
            +
                if name.to_s =~ /^in_(.*?)(!?)$/
         | 
| 18 | 
            +
                  unit = Unit.method_name_to_unit($1)
         | 
| 19 | 
            +
                  $2.empty? ? self.in(unit) : self.in!(unit)
         | 
| 19 20 | 
             
                else
         | 
| 20 | 
            -
                   | 
| 21 | 
            +
                  super(name, system || @system)
         | 
| 21 22 | 
             
                end
         | 
| 22 23 | 
             
              end
         | 
| 23 24 | 
             
            end
         | 
    
        data/lib/unit/system.rb
    CHANGED
    
    | @@ -20,6 +20,9 @@ class Unit < Numeric | |
| 20 20 |  | 
| 21 21 | 
             
                def load(input)
         | 
| 22 22 | 
             
                  case input
         | 
| 23 | 
            +
                  when Hash
         | 
| 24 | 
            +
                    raise "Invalid hash format to load system" unless (input["units"] && input["units"].first.last['def']) || input.first.last['def']
         | 
| 25 | 
            +
                    data = input['units'] || input
         | 
| 23 26 | 
             
                  when IO
         | 
| 24 27 | 
             
                    data = YAML.load(input.read)
         | 
| 25 28 | 
             
                  when String
         | 
    
        data/lib/unit/systems/si.yml
    CHANGED
    
    
    
        data/lib/unit/version.rb
    CHANGED
    
    
    
        data/spec/error_spec.rb
    ADDED
    
    | @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
            require 'spec_helper'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            describe "Errors" do
         | 
| 5 | 
            +
              describe "TypeError when adding incompatible units" do
         | 
| 6 | 
            +
                it "should have a nice error message" do
         | 
| 7 | 
            +
                  a = Unit(1, "meter")
         | 
| 8 | 
            +
                  b = Unit(1, "second")
         | 
| 9 | 
            +
                  lambda { a + b }.should raise_error(TypeError, "#{a.inspect} and #{b.inspect} are incompatible")
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              describe "TypeError when trying to convert incompatible unit using #in!" do
         | 
| 14 | 
            +
                it "should have a nice error message" do
         | 
| 15 | 
            +
                  unit = Unit(1000, "m / s")
         | 
| 16 | 
            +
                  lambda { unit.in!("seconds") }.should
         | 
| 17 | 
            +
                    raise_error(TypeError, %{Unexpected Unit("1000/1 m.s^-1"), expected to be in s})
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                it "should have a nice error message using the DSL", :dsl => true do
         | 
| 21 | 
            +
                  unit = Unit(1000, "m / s")
         | 
| 22 | 
            +
                  lambda { unit.in_seconds!  }.should
         | 
| 23 | 
            +
                    raise_error(TypeError, %{Unexpected Unit("1000/1 m.s^-1"), expected to be in s})
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            # Example test class for coercion
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # UnitOne behaves as Unit(1) when added to a Unit, and as 1 when added to anything else.
         | 
| 4 | 
            +
            class UnitOne
         | 
| 5 | 
            +
              def coerce(other)
         | 
| 6 | 
            +
                case other
         | 
| 7 | 
            +
                when Unit
         | 
| 8 | 
            +
                  [other, Unit(1)]
         | 
| 9 | 
            +
                else
         | 
| 10 | 
            +
                  [other, 1]
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              def +(other)
         | 
| 15 | 
            +
                apply_through_coercion(other, __method__)
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def -(other)
         | 
| 19 | 
            +
                apply_through_coercion(other, __method__)
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def /(other)
         | 
| 23 | 
            +
                apply_through_coercion(other, __method__)
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              def *(other)
         | 
| 27 | 
            +
                apply_through_coercion(other, __method__)
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              def ==(other)
         | 
| 31 | 
            +
                apply_through_coercion(other, __method__)
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              private
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              def apply_through_coercion(other, operation)
         | 
| 37 | 
            +
                case other
         | 
| 38 | 
            +
                when Unit
         | 
| 39 | 
            +
                  a, b = other.coerce(Unit(1))
         | 
| 40 | 
            +
                else
         | 
| 41 | 
            +
                  a, b = other.coerce(1)
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                a.send(operation, b)
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            end
         | 
| @@ -1,7 +1,5 @@ | |
| 1 1 | 
             
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            -
            require ' | 
| 3 | 
            -
            require 'unit'
         | 
| 4 | 
            -
            require 'unit/dsl'
         | 
| 2 | 
            +
            require 'spec_helper'
         | 
| 5 3 |  | 
| 6 4 | 
             
            describe "Unit" do
         | 
| 7 5 | 
             
              describe "#default_system" do
         | 
| @@ -11,13 +9,23 @@ describe "Unit" do | |
| 11 9 | 
             
                    File.open(test_file) do |file|
         | 
| 12 10 | 
             
                      Unit.default_system.load(file)
         | 
| 13 11 | 
             
                    end
         | 
| 14 | 
            -
                    Unit(1, "pim").should | 
| 12 | 
            +
                    Unit(1, "pim").should == Unit(3.14159, "m")
         | 
| 15 13 | 
             
                  end
         | 
| 16 14 |  | 
| 17 15 | 
             
                  it "should load a file" do
         | 
| 18 16 | 
             
                    test_file = File.join(File.dirname(__FILE__), "yml", "filename.yml")
         | 
| 19 17 | 
             
                    Unit.default_system.load(test_file)
         | 
| 20 | 
            -
                    Unit(2, "dzm").should | 
| 18 | 
            +
                    Unit(2, "dzm").should == Unit(24, "m")
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  it "should load a hash" do
         | 
| 22 | 
            +
                    Unit.default_system.load({
         | 
| 23 | 
            +
                      'dozen_meter' => {
         | 
| 24 | 
            +
                        'sym' => 'dzm',
         | 
| 25 | 
            +
                        'def' => '12 m'
         | 
| 26 | 
            +
                      }
         | 
| 27 | 
            +
                    })
         | 
| 28 | 
            +
                    Unit(2, "dzm").should == Unit(24, "m")
         | 
| 21 29 | 
             
                  end
         | 
| 22 30 | 
             
                end
         | 
| 23 31 | 
             
              end
         | 
    
        data/spec/unit_spec.rb
    ADDED
    
    | @@ -0,0 +1,225 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
            require 'spec_helper'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            Unit.default_system.load(:scientific)
         | 
| 5 | 
            +
            Unit.default_system.load(:imperial)
         | 
| 6 | 
            +
            Unit.default_system.load(:misc)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            describe 'Unit' do
         | 
| 9 | 
            +
              it 'should support multiplication' do
         | 
| 10 | 
            +
                (Unit(2, 'm') * Unit(3, 'm')).should == Unit(6, 'm^2')
         | 
| 11 | 
            +
                (Unit(2, 'm') * 3).should == Unit(6, 'm')
         | 
| 12 | 
            +
                (Unit(2, 'm') * Rational(3, 4)).should == Unit(3, 2, 'm')
         | 
| 13 | 
            +
                (Unit(2, 'm') * 0.5).should == Unit(1.0, 'm')
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              it 'should support division' do
         | 
| 17 | 
            +
                (Unit(2, 'm') / Unit(3, 'm^2')).should == Unit(2, 3, '1/m')
         | 
| 18 | 
            +
                (Unit(2, 'm') / 3).should == Unit(2, 3, 'm')
         | 
| 19 | 
            +
                (Unit(2, 'm') / Rational(3, 4)).should == Unit(8, 3, 'm')
         | 
| 20 | 
            +
                (Unit(2, 'm') / 0.5).should == Unit(4.0, 'm')
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              it 'should support addition' do
         | 
| 24 | 
            +
                (Unit(42, 'm') + Unit(1, 'km')).should == Unit(1042, 'm')
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              it 'should support subtraction' do
         | 
| 28 | 
            +
                (Unit(1, 'm') - Unit(1, 'cm')).should == Unit(99, 100, 'm')
         | 
| 29 | 
            +
                (Unit(2, 'm') - Unit(1, 'm')).should == Unit(1, 'm')
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              it "should support arithmetic with Integers when appropriate" do
         | 
| 33 | 
            +
                (1 + Unit(1)).should == Unit(2)
         | 
| 34 | 
            +
                (2 - Unit(1)).should == Unit(1)
         | 
| 35 | 
            +
                (Unit(2) - 1).should == Unit(1)
         | 
| 36 | 
            +
                (2 - Unit(-1)).should == Unit(3)
         | 
| 37 | 
            +
                (Unit(2) - -1).should == Unit(3)
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              it "should support arithmetic with other classes using #coerce" do
         | 
| 41 | 
            +
                (Unit(2) + UnitOne.new).should == Unit(3)
         | 
| 42 | 
            +
                (2 + UnitOne.new).should == 3
         | 
| 43 | 
            +
                (Unit(2) - UnitOne.new).should == Unit(1)
         | 
| 44 | 
            +
                (2 - UnitOne.new).should == 1
         | 
| 45 | 
            +
                (Unit(2) * UnitOne.new).should == Unit(2)
         | 
| 46 | 
            +
                (2 * UnitOne.new).should == 2
         | 
| 47 | 
            +
                (Unit(2) / UnitOne.new).should == Unit(2)
         | 
| 48 | 
            +
                (2 / UnitOne.new).should == 2
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                (UnitOne.new + Unit(4)).should == Unit(5)
         | 
| 51 | 
            +
                (UnitOne.new + 4).should == 5
         | 
| 52 | 
            +
                (UnitOne.new - Unit(4)).should == Unit(-3)
         | 
| 53 | 
            +
                (UnitOne.new - 4).should == -3
         | 
| 54 | 
            +
                (UnitOne.new * Unit(4)).should == Unit(4)
         | 
| 55 | 
            +
                (UnitOne.new * 4).should == 4
         | 
| 56 | 
            +
                (UnitOne.new / Unit(4)).should == Unit(1, 4)
         | 
| 57 | 
            +
                (UnitOne.new / 4).should == 0
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              it "should support logic with other classes using #coerce" do
         | 
| 61 | 
            +
                Unit(1).should == UnitOne.new
         | 
| 62 | 
            +
                Unit(2).should > UnitOne.new
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              it "should support eql comparison" do
         | 
| 66 | 
            +
                Unit(1).should eql(Unit(1))
         | 
| 67 | 
            +
                Unit(1.0).should_not eql(Unit(1))
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                Unit(1).should_not eql(UnitOne.new)
         | 
| 70 | 
            +
                Unit(1.0).should_not eql(UnitOne.new)
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              it "should not support adding anything but numeric unless object is coerceable" do
         | 
| 74 | 
            +
                expect { Unit(1) + 'string'}.to raise_error(TypeError)
         | 
| 75 | 
            +
                expect { Unit(1) + []}.to raise_error(TypeError)
         | 
| 76 | 
            +
                expect { Unit(1) + :symbol }.to raise_error(TypeError)
         | 
| 77 | 
            +
                expect { Unit(1) + {}}.to raise_error(TypeError)
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              it "should support adding through zero" do
         | 
| 81 | 
            +
                (Unit(0, "m") + Unit(1, "m")).should == Unit(1, "m")
         | 
| 82 | 
            +
                (Unit(1, "m") + Unit(-1, "m") + Unit(1, "m")).should == Unit(1, "m")
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
              it 'should check unit compatiblity' do
         | 
| 86 | 
            +
                expect {Unit(42, 'm') + Unit(1, 's')}.to raise_error(TypeError)
         | 
| 87 | 
            +
                expect {Unit(42, 'g') + Unit(1, 'm')}.to raise_error(TypeError)
         | 
| 88 | 
            +
                expect {Unit(0, 'g') + Unit(1, 'm')}.to raise_error(TypeError)
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
              it 'should support exponentiation' do
         | 
| 92 | 
            +
                (Unit(2, 'm') ** 3).should == Unit(8, 'm^3')
         | 
| 93 | 
            +
                (Unit(9, 'm^2') ** 0.5).should == Unit(3.0, 'm')
         | 
| 94 | 
            +
                (Unit(9, 'm^2') ** Rational(1, 2)).should == Unit(3, 'm')
         | 
| 95 | 
            +
                (Unit(2, 'm') ** 1.3).should == Unit(2 ** 1.3, 'm^1.3')
         | 
| 96 | 
            +
              end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              it 'should not allow units as exponent' do
         | 
| 99 | 
            +
                expect { Unit(42, 'g') ** Unit(1, 'm') }.to raise_error(TypeError)
         | 
| 100 | 
            +
              end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
              describe "#normalize" do
         | 
| 103 | 
            +
                it "should return a normalized unit" do
         | 
| 104 | 
            +
                  unit = Unit(1, 'joule')
         | 
| 105 | 
            +
                  normalized_unit =  Unit(1000, 'gram meter^2 / second^2')
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  unit.normalize.should eql normalized_unit
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                it "should not modify the receiver" do
         | 
| 111 | 
            +
                  unit = Unit(1, 'joule')
         | 
| 112 | 
            +
                  normalized_unit =  Unit(1000, 'gram meter^2 / second^2')
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                  unit.normalize
         | 
| 115 | 
            +
                  unit.should_not eql normalized_unit
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
              end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
              describe "#normalize!" do
         | 
| 120 | 
            +
                it "should return a normalized unit" do
         | 
| 121 | 
            +
                  unit = Unit(1, 'joule')
         | 
| 122 | 
            +
                  normalized_unit =  Unit(1000, 'gram meter^2 / second^2')
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                  unit.normalize!.should eql normalized_unit
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                it "should modify the receiver" do
         | 
| 128 | 
            +
                  unit = Unit(1, 'joule')
         | 
| 129 | 
            +
                  normalized_unit =  Unit(1000, 'gram meter^2 / second^2')
         | 
| 130 | 
            +
             | 
| 131 | 
            +
                  unit.normalize!
         | 
| 132 | 
            +
                  unit.should eql normalized_unit
         | 
| 133 | 
            +
                end
         | 
| 134 | 
            +
              end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
              it 'should convert units' do
         | 
| 137 | 
            +
                Unit(1, "MeV").in("joule").should == Unit(1.602176487e-13, 'joule')
         | 
| 138 | 
            +
                Unit(1, "kilometer").in("meter").should == Unit(1000, 'meter')
         | 
| 139 | 
            +
                Unit(1, "liter").in('meter^3').should == Unit(1, 1000, 'meter^3')
         | 
| 140 | 
            +
                Unit(1, "kilometer/hour").in("meter/second").should == Unit(5, 18, 'meter/second')
         | 
| 141 | 
            +
              end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
              it 'should have a working compatible? method' do
         | 
| 144 | 
            +
                Unit(7, "meter").compatible?('kilogram').should == false
         | 
| 145 | 
            +
                Unit(3, "parsec").compatible_with?('meter').should == true
         | 
| 146 | 
            +
              end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
              it 'should have a pretty string representation' do
         | 
| 149 | 
            +
                Unit(7, "joule").normalize.to_s.should == '7000 g·m^2·s^-2'
         | 
| 150 | 
            +
              end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
              it 'should parse units' do
         | 
| 153 | 
            +
                Unit(1, 'KiB s^-1').unit.should == [[:kibi, :byte, 1], [:one, :second, -1]].sort
         | 
| 154 | 
            +
                Unit(1, 'KiB/s').unit.should == [[:kibi, :byte, 1], [:one, :second, -1]].sort
         | 
| 155 | 
            +
                Unit(1, 'kilometer^2 / megaelectronvolt^7 * gram centiliter').unit.should == [[:kilo, :meter, 2], [:mega, :electronvolt, -7],
         | 
| 156 | 
            +
                                                                                                 [:one, :gram, 1], [:centi, :liter, 1]].sort
         | 
| 157 | 
            +
              end
         | 
| 158 | 
            +
             | 
| 159 | 
            +
              it 'should reduce units' do
         | 
| 160 | 
            +
                Unit(1, "joule/kilogram").normalize.unit.should == [[:one, :meter, 2], [:one, :second, -2]].sort
         | 
| 161 | 
            +
                Unit(1, "megaton/kilometer").unit.should == [[:kilo, :ton, 1], [:one, :meter, -1]].reverse
         | 
| 162 | 
            +
              end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
              it 'should work with floating point values' do
         | 
| 165 | 
            +
                w = 5.2 * Unit('kilogram')
         | 
| 166 | 
            +
                w.in("pounds").to_int.should == 11
         | 
| 167 | 
            +
              end
         | 
| 168 | 
            +
             | 
| 169 | 
            +
              it 'should have dimensionless? method' do
         | 
| 170 | 
            +
                Unit(100, "m/km").should be_dimensionless
         | 
| 171 | 
            +
                Unit(42, "meter/second").should_not be_unitless
         | 
| 172 | 
            +
                Unit(100, "meter/km").should == Unit(Rational(1, 10))
         | 
| 173 | 
            +
              end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
              it 'should be equal to rational if dimensionless' do
         | 
| 176 | 
            +
                Unit(100, "meter/km").should == Rational(1, 10)
         | 
| 177 | 
            +
                Unit(100, "meter/km").approx.should == 0.1
         | 
| 178 | 
            +
              end
         | 
| 179 | 
            +
             | 
| 180 | 
            +
              it 'should be comparable' do
         | 
| 181 | 
            +
                Unit(1, 'm').should < Unit(2, 'm')
         | 
| 182 | 
            +
                Unit(1, 'm').should <= Unit(2, 'm')
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                Unit(1, 'm').should <= Unit(1, 'm')
         | 
| 185 | 
            +
                Unit(1, 'm').should >= Unit(1, 'm')
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                Unit(1, 'm').should > Unit(0, 'm')
         | 
| 188 | 
            +
                Unit(1, 'm').should >= Unit(0, 'm')
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                Unit(100, "m").should < Unit(1, "km")
         | 
| 191 | 
            +
                Unit(100, "m").should > Unit(0.0001, "km")
         | 
| 192 | 
            +
              end
         | 
| 193 | 
            +
             | 
| 194 | 
            +
              it "should fail comparison on differing units" do
         | 
| 195 | 
            +
                expect { Unit(1, "second") > Unit(1, "meter") }.to raise_error(Unit::IncompatibleUnitError)
         | 
| 196 | 
            +
              end
         | 
| 197 | 
            +
             | 
| 198 | 
            +
              it "should keep units when the value is zero" do
         | 
| 199 | 
            +
                Unit(0, "m").unit.should == [[:one, :meter, 1]]
         | 
| 200 | 
            +
              end
         | 
| 201 | 
            +
             | 
| 202 | 
            +
              it "should support absolute value" do
         | 
| 203 | 
            +
                Unit(1, "m").abs.should == Unit(1, "m")
         | 
| 204 | 
            +
                Unit(-1, "m").abs.should == Unit(1, "m")
         | 
| 205 | 
            +
              end
         | 
| 206 | 
            +
             | 
| 207 | 
            +
              it "should have #zero?" do
         | 
| 208 | 
            +
                Unit(0, "m").zero?.should == true
         | 
| 209 | 
            +
                Unit(1, "m").zero?.should == false
         | 
| 210 | 
            +
              end
         | 
| 211 | 
            +
             | 
| 212 | 
            +
              it "should produce an approximation" do
         | 
| 213 | 
            +
                Unit(Rational(1,3), "m").approx.should == Unit(1.0/3.0, "m")
         | 
| 214 | 
            +
              end
         | 
| 215 | 
            +
             | 
| 216 | 
            +
            end
         | 
| 217 | 
            +
             | 
| 218 | 
            +
            describe "Unit DSL", :dsl => true do
         | 
| 219 | 
            +
              it 'should provide method sugar' do
         | 
| 220 | 
            +
                1.meter.should == Unit('1 meter')
         | 
| 221 | 
            +
                1.meter_per_second.should == Unit('1 m/s')
         | 
| 222 | 
            +
                1.meter.in_kilometer.should == Unit('1 m').in('km')
         | 
| 223 | 
            +
                1.unit('°C').should == Unit(1, '°C')
         | 
| 224 | 
            +
              end
         | 
| 225 | 
            +
            end
         | 
| 
            File without changes
         | 
    
        data/{test → spec}/yml/io.yml
    RENAMED
    
    | 
            File without changes
         | 
    
        data/unit.gemspec
    CHANGED
    
    | @@ -6,7 +6,7 @@ Gem::Specification.new do |s| | |
| 6 6 | 
             
              s.version = Unit::VERSION
         | 
| 7 7 |  | 
| 8 8 | 
             
              s.authors = ["Daniel Mendler"]
         | 
| 9 | 
            -
              s.date | 
| 9 | 
            +
              s.date  = Date.today.to_s
         | 
| 10 10 | 
             
              s.email = ["mail@daniel-mendler.de"]
         | 
| 11 11 |  | 
| 12 12 | 
             
              s.files         = `git ls-files`.split("\n")
         | 
| @@ -19,5 +19,5 @@ Gem::Specification.new do |s| | |
| 19 19 | 
             
              s.homepage = %q{http://github.com/minad/unit}
         | 
| 20 20 |  | 
| 21 21 | 
             
              s.add_development_dependency('rake', ['>= 0.8.7'])
         | 
| 22 | 
            -
              s.add_development_dependency(' | 
| 22 | 
            +
              s.add_development_dependency('rspec')
         | 
| 23 23 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,50 +1,46 @@ | |
| 1 | 
            -
            --- !ruby/object:Gem::Specification | 
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: unit
         | 
| 3 | 
            -
            version: !ruby/object:Gem::Version | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.4.0
         | 
| 4 5 | 
             
              prerelease: 
         | 
| 5 | 
            -
              version: 0.3.0
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 | 
            -
            authors: | 
| 7 | 
            +
            authors:
         | 
| 8 8 | 
             
            - Daniel Mendler
         | 
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
            dependencies: 
         | 
| 16 | 
            -
            - !ruby/object:Gem::Dependency 
         | 
| 12 | 
            +
            date: 2012-01-19 00:00:00.000000000 Z
         | 
| 13 | 
            +
            dependencies:
         | 
| 14 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 17 15 | 
             
              name: rake
         | 
| 18 | 
            -
               | 
| 19 | 
            -
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 16 | 
            +
              requirement: &7079200 !ruby/object:Gem::Requirement
         | 
| 20 17 | 
             
                none: false
         | 
| 21 | 
            -
                requirements: | 
| 22 | 
            -
                - -  | 
| 23 | 
            -
                  - !ruby/object:Gem::Version | 
| 18 | 
            +
                requirements:
         | 
| 19 | 
            +
                - - ! '>='
         | 
| 20 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 24 21 | 
             
                    version: 0.8.7
         | 
| 25 22 | 
             
              type: :development
         | 
| 26 | 
            -
              version_requirements: *id001
         | 
| 27 | 
            -
            - !ruby/object:Gem::Dependency 
         | 
| 28 | 
            -
              name: bacon
         | 
| 29 23 | 
             
              prerelease: false
         | 
| 30 | 
            -
               | 
| 24 | 
            +
              version_requirements: *7079200
         | 
| 25 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 26 | 
            +
              name: rspec
         | 
| 27 | 
            +
              requirement: &7078560 !ruby/object:Gem::Requirement
         | 
| 31 28 | 
             
                none: false
         | 
| 32 | 
            -
                requirements: | 
| 33 | 
            -
                - -  | 
| 34 | 
            -
                  - !ruby/object:Gem::Version | 
| 35 | 
            -
                    version:  | 
| 29 | 
            +
                requirements:
         | 
| 30 | 
            +
                - - ! '>='
         | 
| 31 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 32 | 
            +
                    version: '0'
         | 
| 36 33 | 
             
              type: :development
         | 
| 37 | 
            -
               | 
| 34 | 
            +
              prerelease: false
         | 
| 35 | 
            +
              version_requirements: *7078560
         | 
| 38 36 | 
             
            description: 
         | 
| 39 | 
            -
            email: | 
| 37 | 
            +
            email:
         | 
| 40 38 | 
             
            - mail@daniel-mendler.de
         | 
| 41 39 | 
             
            executables: []
         | 
| 42 | 
            -
             | 
| 43 40 | 
             
            extensions: []
         | 
| 44 | 
            -
             | 
| 45 41 | 
             
            extra_rdoc_files: []
         | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 42 | 
            +
            files:
         | 
| 43 | 
            +
            - .gitignore
         | 
| 48 44 | 
             
            - .travis.yml
         | 
| 49 45 | 
             
            - Gemfile
         | 
| 50 46 | 
             
            - LICENSE
         | 
| @@ -64,39 +60,36 @@ files: | |
| 64 60 | 
             
            - lib/unit/systems/si.yml
         | 
| 65 61 | 
             
            - lib/unit/systems/time.yml
         | 
| 66 62 | 
             
            - lib/unit/version.rb
         | 
| 67 | 
            -
            -  | 
| 68 | 
            -
            -  | 
| 69 | 
            -
            -  | 
| 70 | 
            -
            -  | 
| 71 | 
            -
            -  | 
| 63 | 
            +
            - spec/error_spec.rb
         | 
| 64 | 
            +
            - spec/spec_helper.rb
         | 
| 65 | 
            +
            - spec/support/unit_one.rb
         | 
| 66 | 
            +
            - spec/system_spec.rb
         | 
| 67 | 
            +
            - spec/unit_spec.rb
         | 
| 68 | 
            +
            - spec/yml/filename.yml
         | 
| 69 | 
            +
            - spec/yml/io.yml
         | 
| 72 70 | 
             
            - unit.gemspec
         | 
| 73 | 
            -
            has_rdoc: true
         | 
| 74 71 | 
             
            homepage: http://github.com/minad/unit
         | 
| 75 72 | 
             
            licenses: []
         | 
| 76 | 
            -
             | 
| 77 73 | 
             
            post_install_message: 
         | 
| 78 74 | 
             
            rdoc_options: []
         | 
| 79 | 
            -
             | 
| 80 | 
            -
            require_paths: 
         | 
| 75 | 
            +
            require_paths:
         | 
| 81 76 | 
             
            - lib
         | 
| 82 | 
            -
            required_ruby_version: !ruby/object:Gem::Requirement | 
| 77 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 83 78 | 
             
              none: false
         | 
| 84 | 
            -
              requirements: | 
| 85 | 
            -
              - -  | 
| 86 | 
            -
                - !ruby/object:Gem::Version | 
| 87 | 
            -
                  version:  | 
| 88 | 
            -
            required_rubygems_version: !ruby/object:Gem::Requirement | 
| 79 | 
            +
              requirements:
         | 
| 80 | 
            +
              - - ! '>='
         | 
| 81 | 
            +
                - !ruby/object:Gem::Version
         | 
| 82 | 
            +
                  version: '0'
         | 
| 83 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 89 84 | 
             
              none: false
         | 
| 90 | 
            -
              requirements: | 
| 91 | 
            -
              - -  | 
| 92 | 
            -
                - !ruby/object:Gem::Version | 
| 93 | 
            -
                  version:  | 
| 85 | 
            +
              requirements:
         | 
| 86 | 
            +
              - - ! '>='
         | 
| 87 | 
            +
                - !ruby/object:Gem::Version
         | 
| 88 | 
            +
                  version: '0'
         | 
| 94 89 | 
             
            requirements: []
         | 
| 95 | 
            -
             | 
| 96 90 | 
             
            rubyforge_project: unit
         | 
| 97 | 
            -
            rubygems_version: 1. | 
| 91 | 
            +
            rubygems_version: 1.8.11
         | 
| 98 92 | 
             
            signing_key: 
         | 
| 99 93 | 
             
            specification_version: 3
         | 
| 100 94 | 
             
            summary: Scientific unit support for ruby for calculations
         | 
| 101 95 | 
             
            test_files: []
         | 
| 102 | 
            -
             | 
    
        data/test/error_test.rb
    DELETED
    
    | @@ -1,16 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            -
            require 'bacon'
         | 
| 3 | 
            -
            require 'unit'
         | 
| 4 | 
            -
            require 'unit/dsl'
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            describe "Errors" do
         | 
| 7 | 
            -
              describe "TypeError when adding incompatible units" do
         | 
| 8 | 
            -
                it "should have a nice error message" do
         | 
| 9 | 
            -
                  unit_1 = Unit(1, "meter")
         | 
| 10 | 
            -
                  unit_2 = Unit(1, "second")
         | 
| 11 | 
            -
                  lambda {
         | 
| 12 | 
            -
                    unit_1 + unit_2
         | 
| 13 | 
            -
                  }.should.raise(TypeError).message.should.equal("Incompatible units: #{unit_1.inspect} and #{unit_2.inspect}")
         | 
| 14 | 
            -
                end
         | 
| 15 | 
            -
              end
         | 
| 16 | 
            -
            end
         | 
    
        data/test/unit_test.rb
    DELETED
    
    | @@ -1,144 +0,0 @@ | |
| 1 | 
            -
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            -
            require 'bacon'
         | 
| 3 | 
            -
            require 'unit'
         | 
| 4 | 
            -
            require 'unit/dsl'
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            Unit.default_system.load(:scientific)
         | 
| 7 | 
            -
            Unit.default_system.load(:imperial)
         | 
| 8 | 
            -
            Unit.default_system.load(:misc)
         | 
| 9 | 
            -
             | 
| 10 | 
            -
            describe 'Unit' do
         | 
| 11 | 
            -
              it 'should support multiplication' do
         | 
| 12 | 
            -
                (Unit(2, 'm') * Unit(3, 'm')).should.equal Unit(6, 'm^2')
         | 
| 13 | 
            -
                (Unit(2, 'm') * 3).should.equal Unit(6, 'm')
         | 
| 14 | 
            -
                (Unit(2, 'm') * Rational(3, 4)).should.equal Unit(3, 2, 'm')
         | 
| 15 | 
            -
                (Unit(2, 'm') * 0.5).should.equal Unit(1.0, 'm')
         | 
| 16 | 
            -
              end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
              it 'should support division' do
         | 
| 19 | 
            -
                (Unit(2, 'm') / Unit(3, 'm^2')).should.equal Unit(2, 3, '1/m')
         | 
| 20 | 
            -
                (Unit(2, 'm') / 3).should.equal Unit(2, 3, 'm')
         | 
| 21 | 
            -
                (Unit(2, 'm') / Rational(3, 4)).should.equal Unit(8, 3, 'm')
         | 
| 22 | 
            -
                (Unit(2, 'm') / 0.5).should.equal Unit(4.0, 'm')
         | 
| 23 | 
            -
              end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
              it 'should support addition' do
         | 
| 26 | 
            -
                (Unit(42, 'm') + Unit(1, 'km')).should.equal Unit(1042, 'm')
         | 
| 27 | 
            -
                (Unit(1, 'm') - Unit(1, 'cm')).should.equal Unit(99, 100, 'm')
         | 
| 28 | 
            -
              end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
              it "should support adding through zero" do
         | 
| 31 | 
            -
                (Unit(0, "m") + Unit(1, "m")).should.equal Unit(1, "m")
         | 
| 32 | 
            -
                (Unit(1, "m") + Unit(-1, "m") + Unit(1, "m")).should.equal Unit(1, "m")
         | 
| 33 | 
            -
              end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
              it 'should check unit compatiblity' do
         | 
| 36 | 
            -
                should.raise TypeError do
         | 
| 37 | 
            -
                  (Unit(42, 'm') + Unit(1, 's'))
         | 
| 38 | 
            -
                end
         | 
| 39 | 
            -
                should.raise TypeError do
         | 
| 40 | 
            -
                  (Unit(42, 'g') + Unit(1, 'm'))
         | 
| 41 | 
            -
                end
         | 
| 42 | 
            -
                should.raise TypeError do
         | 
| 43 | 
            -
                  (Unit(0, 'g') + Unit(1, 'm'))
         | 
| 44 | 
            -
                end
         | 
| 45 | 
            -
              end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
              it 'should support exponentiation' do
         | 
| 48 | 
            -
                (Unit(2, 'm') ** 3).should.equal Unit(8, 'm^3')
         | 
| 49 | 
            -
                (Unit(9, 'm^2') ** 0.5).should.equal Unit(3.0, 'm')
         | 
| 50 | 
            -
                (Unit(9, 'm^2') ** Rational(1, 2)).should.equal Unit(3, 'm')
         | 
| 51 | 
            -
                (Unit(2, 'm') ** 1.3).should.equal Unit(2 ** 1.3, 'm^1.3')
         | 
| 52 | 
            -
              end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
              it 'should not allow units as exponent' do
         | 
| 55 | 
            -
                should.raise TypeError do
         | 
| 56 | 
            -
                  Unit(42, 'g') ** Unit(1, 'm')
         | 
| 57 | 
            -
                end
         | 
| 58 | 
            -
              end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
              it 'should provide method sugar' do
         | 
| 61 | 
            -
                1.meter.should.equal Unit('1 meter')
         | 
| 62 | 
            -
                1.meter_per_second.should.equal Unit('1 m/s')
         | 
| 63 | 
            -
                1.meter.in_kilometer.should.equal Unit('1 m').in('km')
         | 
| 64 | 
            -
                1.unit('°C').should.equal Unit(1, '°C')
         | 
| 65 | 
            -
              end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
              it 'should have a normalizer' do
         | 
| 68 | 
            -
                1.joule.normalize.should.equal Unit(1000, 'gram meter^2 / second^2')
         | 
| 69 | 
            -
                unit = 1.joule.normalize!
         | 
| 70 | 
            -
                unit.should.equal unit.normalized
         | 
| 71 | 
            -
              end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
              it 'should convert units' do
         | 
| 74 | 
            -
                1.MeV.in_joule.should.equal Unit(1.602176487e-13, 'joule')
         | 
| 75 | 
            -
                1.kilometer.in_meter.should.equal Unit(1000, 'meter')
         | 
| 76 | 
            -
                1.liter.in('meter^3').should.equal Unit(1, 1000, 'meter^3')
         | 
| 77 | 
            -
                1.kilometer_per_hour.in_meter_per_second.should.equal Unit(5, 18, 'meter/second')
         | 
| 78 | 
            -
              end
         | 
| 79 | 
            -
             | 
| 80 | 
            -
              it 'should have a working compatible? method' do
         | 
| 81 | 
            -
                7.meter.compatible?('kilogram').should.equal false
         | 
| 82 | 
            -
                3.parsec.compatible_with?('meter').should.equal true
         | 
| 83 | 
            -
              end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
              it 'should have a pretty string representation' do
         | 
| 86 | 
            -
                7.joule.normalize.to_s.should.equal '7000 g·m^2·s^-2'
         | 
| 87 | 
            -
              end
         | 
| 88 | 
            -
             | 
| 89 | 
            -
              it 'should parse units' do
         | 
| 90 | 
            -
                Unit(1, 'KiB s^-1').unit.should.equal [[:kibi, :byte, 1], [:one, :second, -1]].sort
         | 
| 91 | 
            -
                Unit(1, 'KiB/s').unit.should.equal [[:kibi, :byte, 1], [:one, :second, -1]].sort
         | 
| 92 | 
            -
                Unit(1, 'kilometer^2 / megaelectronvolt^7 * gram centiliter').unit.should.equal [[:kilo, :meter, 2], [:mega, :electronvolt, -7],
         | 
| 93 | 
            -
                                                                                                 [:one, :gram, 1], [:centi, :liter, 1]].sort
         | 
| 94 | 
            -
              end
         | 
| 95 | 
            -
             | 
| 96 | 
            -
              it 'should reduce units' do
         | 
| 97 | 
            -
                1.joule_per_kilogram.normalize.unit.should.equal [[:one, :meter, 2], [:one, :second, -2]].sort
         | 
| 98 | 
            -
                1.megaton_per_kilometer.unit.should.equal [[:kilo, :ton, 1], [:one, :meter, -1]].sort
         | 
| 99 | 
            -
              end
         | 
| 100 | 
            -
             | 
| 101 | 
            -
              it 'should work with floating point values' do
         | 
| 102 | 
            -
                #w = (5.2).kilogram
         | 
| 103 | 
            -
                w = 5.2 * Unit('kilogram')
         | 
| 104 | 
            -
                w.in_pounds.to_int.should.equal 11
         | 
| 105 | 
            -
              end
         | 
| 106 | 
            -
             | 
| 107 | 
            -
              it 'should have dimensionless? method' do
         | 
| 108 | 
            -
                100.meter_per_km.should.be.dimensionless
         | 
| 109 | 
            -
                100.meter.per_km.should.be.dimensionless
         | 
| 110 | 
            -
                100.meter.per_km.should.be.unitless
         | 
| 111 | 
            -
                42.meter.per_second.should.not.be.unitless
         | 
| 112 | 
            -
                100.meter.per_km.should.equal Unit(Rational(1, 10))
         | 
| 113 | 
            -
              end
         | 
| 114 | 
            -
             | 
| 115 | 
            -
              it 'should be equal to rational if dimensionless' do
         | 
| 116 | 
            -
                100.meter.per_km.should.equal Rational(1, 10)
         | 
| 117 | 
            -
                100.meter.per_km.approx.should.equal 0.1
         | 
| 118 | 
            -
              end
         | 
| 119 | 
            -
             | 
| 120 | 
            -
              it 'should be comparable' do
         | 
| 121 | 
            -
                Unit(1,'m').should < Unit(2,'m')
         | 
| 122 | 
            -
                Unit(1,'m').should <= Unit(2,'m')
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                Unit(1,'m').should <= Unit(1,'m')
         | 
| 125 | 
            -
                Unit(1,'m').should >= Unit(1,'m')
         | 
| 126 | 
            -
             | 
| 127 | 
            -
                Unit(1,'m').should > Unit(0,'m')
         | 
| 128 | 
            -
                Unit(1,'m').should >= Unit(0,'m')
         | 
| 129 | 
            -
             | 
| 130 | 
            -
                Unit(100, "m").should < Unit(1, "km")
         | 
| 131 | 
            -
                Unit(100, "m").should > Unit(0.0001, "km")
         | 
| 132 | 
            -
              end
         | 
| 133 | 
            -
             | 
| 134 | 
            -
              it "should fail comparison on differing units" do
         | 
| 135 | 
            -
                lambda do
         | 
| 136 | 
            -
                  Unit(1, "second") > Unit(1, "meter")
         | 
| 137 | 
            -
                end.should.raise(ArgumentError)
         | 
| 138 | 
            -
              end
         | 
| 139 | 
            -
             | 
| 140 | 
            -
              it "should keep units when the value is zero" do
         | 
| 141 | 
            -
                Unit(0, "m").unit.should.equal [[:one, :meter, 1]]
         | 
| 142 | 
            -
              end
         | 
| 143 | 
            -
            end
         | 
| 144 | 
            -
             |