quantify 2.0.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/quantify/config.rb +2 -0
- data/lib/quantify/core_extensions/string.rb +4 -0
- data/lib/quantify/parser.rb +7 -0
- data/lib/quantify/quantity.rb +32 -15
- data/lib/quantify/unit/base_unit.rb +1 -0
- data/lib/quantify/unit/unit.rb +81 -30
- data/quantify.gemspec +4 -3
- data/spec/quantity_spec.rb +142 -20
- data/spec/unit_spec.rb +11 -3
- metadata +37 -36
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
3.0.0
|
data/lib/quantify/config.rb
CHANGED
data/lib/quantify/quantity.rb
CHANGED
@@ -44,13 +44,23 @@ module Quantify
|
|
44
44
|
|
45
45
|
|
46
46
|
# Parse a string and return a Quantity object based upon the value and
|
47
|
-
# subseqent unit name, symbol or JScience label
|
47
|
+
# subseqent unit name, symbol or JScience label. Returns an array containing
|
48
|
+
# quantity objects for each quantity recognised.
|
48
49
|
def self.parse(string)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
words = string.words
|
51
|
+
quantities = words.each_with_index.map do |word,index|
|
52
|
+
if word.starts_with_number?
|
53
|
+
# Isolate number from subsequent string
|
54
|
+
value, string = word, words[index+1..-1].join(" ")
|
55
|
+
# Shift any trailing non-numeric characters to start of string.
|
56
|
+
value, string = $1, "#{$2} #{string}" if (/([\d\s.,]+)([^\d\s.,\^]+(\^[\d\.-]*)?)/i).match(word)
|
57
|
+
# Parse string for unit references
|
58
|
+
unit = Unit.parse(string, :iterative => true) || Unit.dimensionless
|
59
|
+
# Instantiate quantity using value and unit
|
60
|
+
Quantity.new(value,unit)
|
61
|
+
end
|
62
|
+
end.compact
|
63
|
+
return quantities
|
54
64
|
rescue Quantify::Exceptions::InvalidArgumentError
|
55
65
|
raise Quantify::Exceptions::QuantityParseError, "Cannot parse string into value and unit"
|
56
66
|
end
|
@@ -58,6 +68,17 @@ module Quantify
|
|
58
68
|
def self.configure(&block)
|
59
69
|
self.class_eval(&block) if block
|
60
70
|
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
|
74
|
+
def self.is_basic_conversion_with_scalings?(quantity,new_unit)
|
75
|
+
return true if (quantity.unit.has_scaling? || new_unit.has_scaling?) &&
|
76
|
+
!quantity.unit.is_compound_unit? &&
|
77
|
+
!new_unit.is_compound_unit?
|
78
|
+
return false
|
79
|
+
end
|
80
|
+
|
81
|
+
public
|
61
82
|
|
62
83
|
attr_accessor :value, :unit
|
63
84
|
|
@@ -74,7 +95,7 @@ module Quantify
|
|
74
95
|
# quantity which is represented by the Dimensions object in the Quantity unit.
|
75
96
|
# e.g.
|
76
97
|
#
|
77
|
-
# Quantity.parse(
|
98
|
+
# Quantity.parse("25 yr").represents #=> :time
|
78
99
|
#
|
79
100
|
# 1.foot.represents #=> :length
|
80
101
|
#
|
@@ -119,7 +140,7 @@ module Quantify
|
|
119
140
|
#
|
120
141
|
def to(new_unit)
|
121
142
|
new_unit = Unit.for new_unit
|
122
|
-
if is_basic_conversion_with_scalings?
|
143
|
+
if Quantity.is_basic_conversion_with_scalings?(self,new_unit)
|
123
144
|
Quantity.new(@value,@unit).conversion_with_scalings! new_unit
|
124
145
|
elsif self.unit.is_alternative_for? new_unit
|
125
146
|
Quantity.new(@value,@unit).convert_to_equivalent_unit! new_unit
|
@@ -130,13 +151,6 @@ module Quantify
|
|
130
151
|
end
|
131
152
|
end
|
132
153
|
|
133
|
-
def is_basic_conversion_with_scalings?(new_unit)
|
134
|
-
return true if (@unit.has_scaling? || new_unit.has_scaling?) &&
|
135
|
-
!@unit.is_compound_unit? &&
|
136
|
-
!new_unit.is_compound_unit?
|
137
|
-
return false
|
138
|
-
end
|
139
|
-
|
140
154
|
# Conversion where both units (including compound units) are of precisely
|
141
155
|
# equivalent dimensions, i.e. direct alternatives for one another. Where
|
142
156
|
# previous unit is a compound unit, new unit must be cancelled by all original
|
@@ -317,6 +331,9 @@ module Quantify
|
|
317
331
|
range.include? self
|
318
332
|
end
|
319
333
|
|
334
|
+
protected :convert_compound_unit_to_si!, :add_or_subtract!, :multiply_or_divide!
|
335
|
+
|
336
|
+
|
320
337
|
# Enables shorthand for reciprocal of quantity, e.g.
|
321
338
|
#
|
322
339
|
# quantity = 2.m
|
data/lib/quantify/unit/unit.rb
CHANGED
@@ -173,6 +173,12 @@ module Quantify
|
|
173
173
|
Quantity.new(value, new_unit)
|
174
174
|
end
|
175
175
|
|
176
|
+
def self.dimensionless
|
177
|
+
Unit::Base.new(:dimensions => 'dimensionless') do |unit|
|
178
|
+
unit.acts_as_alternative_unit = false
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
176
182
|
# Retrieve an object representing the specified unit.
|
177
183
|
#
|
178
184
|
# Argument can be the unit name, symbol or JScience label and provided as
|
@@ -204,9 +210,12 @@ module Quantify
|
|
204
210
|
end
|
205
211
|
if unit = Unit.match(name_symbol_or_label)
|
206
212
|
return unit
|
207
|
-
|
208
|
-
if unit = Unit.parse(name_symbol_or_label)
|
213
|
+
elsif unit = Unit.parse(name_symbol_or_label)
|
209
214
|
return unit
|
215
|
+
elsif unit = Unit.parse(name_symbol_or_label, :iterative => true)
|
216
|
+
return unit
|
217
|
+
else
|
218
|
+
return nil
|
210
219
|
end
|
211
220
|
rescue Exceptions::InvalidUnitError
|
212
221
|
return nil
|
@@ -214,21 +223,12 @@ module Quantify
|
|
214
223
|
|
215
224
|
# Parse complex strings into unit.
|
216
225
|
#
|
217
|
-
def self.parse(string)
|
226
|
+
def self.parse(string, options={})
|
218
227
|
string = string.remove_underscores.without_superscript_characters
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
units = []
|
224
|
-
numerator, per, denominator = string.split(/(\/|per)/)
|
225
|
-
units += Unit.parse_numerator_units(numerator)
|
226
|
-
units += Unit.parse_denominator_units(denominator) unless denominator.nil?
|
227
|
-
if units.size == 1 && units.first.index == 1
|
228
|
-
return units.first.unit
|
229
|
-
else
|
230
|
-
return Unit::Compound.new(*units)
|
231
|
-
end
|
228
|
+
units = options[:iterative] == true ? Unit.iterative_parse(string) : Unit.simple_parse(string)
|
229
|
+
return nil if units.empty?
|
230
|
+
return units.first.unit if units.size == 1 && units.first.index == 1
|
231
|
+
return Unit::Compound.new(*units)
|
232
232
|
end
|
233
233
|
|
234
234
|
def self.match(name_symbol_or_label)
|
@@ -266,23 +266,43 @@ module Quantify
|
|
266
266
|
return nil
|
267
267
|
end
|
268
268
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
def self.format_unit_attribute(attribute, string_or_symbol)
|
273
|
-
string_or_symbol = case attribute
|
274
|
-
when :symbol then string_or_symbol.remove_underscores
|
275
|
-
when :name then string_or_symbol.remove_underscores.singularize.downcase
|
276
|
-
else string_or_symbol.to_s
|
269
|
+
def self.simple_parse(string)
|
270
|
+
if string.scan(/(\/|per)/).size > 1
|
271
|
+
raise Exceptions::InvalidArgumentError, "Malformed unit: multiple uses of '/' or 'per'"
|
277
272
|
end
|
278
|
-
|
279
|
-
|
273
|
+
units = []
|
274
|
+
numerator, per, denominator = string.split(/(\/|per)/)
|
275
|
+
units += Unit.parse_numerator_units(numerator)
|
276
|
+
units += Unit.parse_denominator_units(denominator) unless denominator.nil?
|
277
|
+
return units
|
278
|
+
end
|
279
|
+
|
280
|
+
def self.iterative_parse(string)
|
281
|
+
units=[]
|
282
|
+
current_set = "numerator_units"
|
283
|
+
while unit = Unit.unit_label_regex.match(string) || unit = Unit.unit_symbol_regex.match(string) ||
|
284
|
+
unit = Unit.unit_name_regex.match(string) || unit = Unit.unit_denominator_regex.match(string) do
|
285
|
+
if unit[0] =~ Unit.unit_denominator_regex
|
286
|
+
current_set = "denominator_units"
|
287
|
+
else
|
288
|
+
units += Unit.send("parse_#{current_set}".to_sym, unit[0])
|
289
|
+
end
|
290
|
+
# Remove matched pattern from string for next iteration
|
291
|
+
match_length = unit[0].size
|
292
|
+
string = string[match_length, string.length-match_length].strip
|
293
|
+
end
|
294
|
+
return units
|
280
295
|
end
|
281
296
|
|
282
297
|
def self.parse_unit_and_index(string)
|
283
298
|
string.scan(/([^0-9\^]+)\^?([\d\.-]*)?/i)
|
284
299
|
index = ($2.nil? || $2.empty? ? 1 : $2.to_i)
|
285
|
-
|
300
|
+
unit = Unit.match($1.to_s)
|
301
|
+
if unit.is_a? Compound
|
302
|
+
return unit.base_units.each {|base_unit| base_unit.index = base_unit.index * index}
|
303
|
+
else
|
304
|
+
return CompoundBaseUnit.new($1.to_s, index)
|
305
|
+
end
|
286
306
|
end
|
287
307
|
|
288
308
|
def self.parse_numerator_units(string)
|
@@ -294,7 +314,7 @@ module Quantify
|
|
294
314
|
end
|
295
315
|
num_units.map! do |substring|
|
296
316
|
Unit.parse_unit_and_index(substring)
|
297
|
-
end
|
317
|
+
end.flatten
|
298
318
|
end
|
299
319
|
|
300
320
|
def self.parse_denominator_units(string)
|
@@ -304,6 +324,19 @@ module Quantify
|
|
304
324
|
end
|
305
325
|
end
|
306
326
|
|
327
|
+
# standardize query strings or symbols into canonical form for unit names,
|
328
|
+
# symbols and labels
|
329
|
+
#
|
330
|
+
def self.format_unit_attribute(attribute, string_or_symbol)
|
331
|
+
string_or_symbol = case attribute
|
332
|
+
when :symbol then string_or_symbol.remove_underscores
|
333
|
+
when :name then string_or_symbol.remove_underscores.singularize.downcase
|
334
|
+
else string_or_symbol.to_s
|
335
|
+
end
|
336
|
+
Unit.use_superscript_characters? ?
|
337
|
+
string_or_symbol.with_superscript_characters : string_or_symbol.without_superscript_characters
|
338
|
+
end
|
339
|
+
|
307
340
|
# This returns the suite of units which represents THE SI units for each of
|
308
341
|
# the base dimensions, i.e. metre, kilogram, second, etc. but not prefixed
|
309
342
|
# versions of the same unit
|
@@ -341,6 +374,24 @@ module Quantify
|
|
341
374
|
@units.map {|unit| unit.symbol if unit.symbol.word_count > 1 }.compact
|
342
375
|
end
|
343
376
|
|
377
|
+
# might want to try atomic groupings, but must get units in size order perhaps first
|
378
|
+
def self.unit_label_regex
|
379
|
+
/\A((#{Unit.units_for_regex(Unit::Prefix,:non_si_prefixes,:label)})?((#{Unit.units_for_regex(Unit,:non_si_non_prefixed_units,:label)})\b)|(#{Unit.units_for_regex(Unit::Prefix,:si_prefixes,:label)})?((#{Unit.units_for_regex(Unit,:si_non_prefixed_units,:label)})\b))(\^[\d\.-]*)?/
|
380
|
+
end
|
381
|
+
|
382
|
+
def self.unit_symbol_regex
|
383
|
+
/\A((#{Unit.units_for_regex(Unit::Prefix,:si_prefixes,:symbol)})?((#{Unit.units_for_regex(Unit,:si_non_prefixed_units,:symbol)})\b)|(#{Unit.units_for_regex(Unit::Prefix,:non_si_prefixes,:symbol)})?((#{Unit.units_for_regex(Unit,:non_si_non_prefixed_units,:symbol)})\b))(\^[\d\.-]*)?/
|
384
|
+
end
|
385
|
+
|
386
|
+
def self.unit_name_regex
|
387
|
+
# Specifically case insensitive
|
388
|
+
/\A((#{Unit.units_for_regex(Unit::Prefix,:non_si_prefixes,:name)})?((#{Unit.units_for_regex(Unit,:non_si_non_prefixed_units,:pluralized_name)}|#{Unit.units_for_regex(Unit,:non_si_non_prefixed_units,:name)})\b)|(#{Unit.units_for_regex(Unit::Prefix,:si_prefixes,:name)})?((#{Unit.units_for_regex(Unit,:si_non_prefixed_units,:pluralized_name)}|#{Unit.units_for_regex(Unit,:si_non_prefixed_units,:name)})\b))(\^[\d\.-]*)?/i
|
389
|
+
end
|
390
|
+
|
391
|
+
def self.unit_denominator_regex
|
392
|
+
/\A(\/|per)/i
|
393
|
+
end
|
394
|
+
|
344
395
|
# Underscore any parts of string which represent multi-word unit identifiers
|
345
396
|
# so that units can be parsed on whitespace
|
346
397
|
#
|
@@ -354,9 +405,9 @@ module Quantify
|
|
354
405
|
# Returns a list of "|" separated unit identifiers for use as regex
|
355
406
|
# alternatives. Lists are constructed by calling
|
356
407
|
def self.units_for_regex(klass,method,attribute)
|
357
|
-
list = klass.send(method).map { |item| item.send(attribute)
|
408
|
+
list = klass.send(method).map { |item| item.send(attribute).gsub("/","\\/").gsub("^","\\^") }
|
358
409
|
list.map! { |item| item.downcase } if attribute == :name
|
359
|
-
list.join("|")
|
410
|
+
list.sort {|x, y| y.size <=> x.size }.join("|")
|
360
411
|
end
|
361
412
|
|
362
413
|
end
|
data/quantify.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{quantify}
|
8
|
-
s.version = "
|
8
|
+
s.version = "3.0.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Andrew Berkeley"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-11-08}
|
13
13
|
s.description = %q{A gem to support physical quantities and unit conversions}
|
14
14
|
s.email = %q{andrew.berkeley.is@googlemail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
"lib/quantify/dimensions.rb",
|
31
31
|
"lib/quantify/exception.rb",
|
32
32
|
"lib/quantify/inflections.rb",
|
33
|
+
"lib/quantify/parser.rb",
|
33
34
|
"lib/quantify/quantify.rb",
|
34
35
|
"lib/quantify/quantity.rb",
|
35
36
|
"lib/quantify/unit/base_unit.rb",
|
@@ -54,7 +55,7 @@ Gem::Specification.new do |s|
|
|
54
55
|
s.homepage = %q{https://github.com/spatchcock/quantify}
|
55
56
|
s.licenses = ["MIT"]
|
56
57
|
s.require_paths = ["lib"]
|
57
|
-
s.rubygems_version = %q{1.
|
58
|
+
s.rubygems_version = %q{1.5.3}
|
58
59
|
s.summary = %q{Support for handling physical quantities, unit conversions, etc}
|
59
60
|
|
60
61
|
if s.respond_to? :specification_version then
|
data/spec/quantity_spec.rb
CHANGED
@@ -34,33 +34,162 @@ describe Quantity do
|
|
34
34
|
quantity.unit.name.should == 'kilometre'
|
35
35
|
end
|
36
36
|
|
37
|
+
it "should create valid instances with class parse method" do
|
38
|
+
quantities = Quantity.parse "10m driving and 5 tonnes carried"
|
39
|
+
quantities.should be_a Array
|
40
|
+
quantities.first.value.should == 10
|
41
|
+
quantities.first.unit.symbol.should == 'm'
|
42
|
+
quantities.last.value.should == 5
|
43
|
+
quantities.last.unit.symbol.should == 't'
|
44
|
+
end
|
45
|
+
|
37
46
|
it "should create a valid instance with class parse method" do
|
38
|
-
|
39
|
-
|
40
|
-
|
47
|
+
quantities = Quantity.parse "10 m"
|
48
|
+
quantities.first.value.should == 10
|
49
|
+
quantities.first.unit.symbol.should == 'm'
|
41
50
|
end
|
42
51
|
|
43
52
|
it "should create a valid instance with class parse method" do
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
53
|
+
quantities = Quantity.parse "155.6789 ly"
|
54
|
+
quantities.first.value.should == 155.6789
|
55
|
+
quantities.first.unit.name.should == 'light year'
|
56
|
+
quantities.first.represents.should == 'length'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should create a valid instance with class parse method and per unit with symbols" do
|
60
|
+
quantities = Quantity.parse "10 m / h"
|
61
|
+
quantities.first.value.should == 10
|
62
|
+
quantities.first.unit.symbol.should == 'm/h'
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should create a valid instance with class parse method and per unit with names" do
|
66
|
+
quantities = Quantity.parse "10 miles / hour"
|
67
|
+
quantities.first.value.should == 10
|
68
|
+
quantities.first.unit.symbol.should == 'mi/h'
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should create a valid instance with class parse method and compound per unit with names" do
|
72
|
+
quantities = Quantity.parse "10 kilograms / tonne kilometre"
|
73
|
+
quantities.first.value.should == 10
|
74
|
+
quantities.first.unit.symbol.should == 'kg/t km'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should create a valid instance with class parse method and compound per unit with symbols" do
|
78
|
+
quantities = Quantity.parse "10 kg / t km"
|
79
|
+
quantities.first.value.should == 10
|
80
|
+
quantities.first.unit.symbol.should == 'kg/t km'
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should create a valid instance from complex string with compound per unit" do
|
84
|
+
quantities = Quantity.parse "We sent some freight 6000 nautical miles by ship and the emissions rate was 10 kg / t km"
|
85
|
+
quantities.first.value.should == 6000
|
86
|
+
quantities.first.unit.name.should == 'nautical mile'
|
87
|
+
quantities.first.unit.symbol.should == 'nmi'
|
88
|
+
quantities[1].value.should == 10
|
89
|
+
quantities[1].unit.pluralized_name.should == 'kilograms per tonne kilometre'
|
90
|
+
quantities[1].unit.symbol.should == 'kg/t km'
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should create valid instances from complex string" do
|
94
|
+
quantities = Quantity.parse "I travelled 220 miles driving my car and using 0.13 UK gallons per mile of diesel"
|
95
|
+
quantities.first.value.should == 220
|
96
|
+
quantities.first.unit.name.should == 'mile'
|
97
|
+
quantities.first.unit.symbol.should == 'mi'
|
98
|
+
quantities[1].value.should == 0.13
|
99
|
+
quantities[1].unit.pluralized_name.should == 'UK gallons per mile'
|
100
|
+
quantities[1].unit.symbol.should == 'gal/mi'
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should create valid instances from easy string" do
|
104
|
+
quantities = Quantity.parse "100km"
|
105
|
+
quantities.first.value.should == 100
|
106
|
+
quantities.first.unit.name.should == 'kilometre'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should create valid instances from complex string, no space and two-digit symbol" do
|
110
|
+
quantities = Quantity.parse "100km driving cars"
|
111
|
+
quantities.first.value.should == 100
|
112
|
+
quantities.first.unit.name.should == 'kilometre'
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should create valid instances from complex string with punctuation" do
|
116
|
+
quantities = Quantity.parse "66666 kg; 5 lb; 86 gigagrams per kelvin and some more words"
|
117
|
+
quantities.first.value.should == 66666
|
118
|
+
quantities.first.unit.name.should == 'kilogram'
|
119
|
+
quantities[1].value.should == 5
|
120
|
+
quantities[1].unit.pluralized_name.should == 'pounds'
|
121
|
+
quantities[1].unit.symbol.should == 'lb'
|
122
|
+
quantities[2].value.should == 86
|
123
|
+
quantities[2].unit.pluralized_name.should == 'gigagrams per kelvin'
|
124
|
+
quantities[2].unit.symbol.should == 'Gg/K'
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should create valid instances from complex string with punctuation" do
|
128
|
+
quantities = Quantity.parse "6 kilogram square metre per second^2"
|
129
|
+
quantities.first.value.should == 6
|
130
|
+
quantities.first.unit.name.should == 'kilogram square metre per square second'
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should create valid instances from complex string with punctuation" do
|
134
|
+
quantities = Quantity.parse "I make 1 cup of tea with 1 tea bag, 0.3 litres of water, 10 g of sugar and 1 dram of milk"
|
135
|
+
quantities.first.value.should == 1
|
136
|
+
quantities.first.unit.name.should == 'cup'
|
137
|
+
quantities[1].value.should == 1
|
138
|
+
quantities[1].unit.name.should == ''
|
139
|
+
quantities[2].value.should == 0.3
|
140
|
+
quantities[2].unit.name.should == 'litre'
|
141
|
+
quantities[3].value.should == 10
|
142
|
+
quantities[3].unit.name.should == 'gram'
|
143
|
+
quantities[4].value.should == 1
|
144
|
+
quantities[4].unit.name.should == 'dram'
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should create valid instances from complex string with indices" do
|
148
|
+
quantities = Quantity.parse "I sprayed 500 litres of fertilizer across 6000 m^2 of farmland"
|
149
|
+
quantities.first.value.should == 500
|
150
|
+
quantities.first.unit.name.should == 'litre'
|
151
|
+
quantities.first.unit.symbol.should == 'L'
|
152
|
+
quantities[1].value.should == 6000
|
153
|
+
quantities[1].unit.pluralized_name.should == 'square metres'
|
154
|
+
quantities[1].unit.symbol.should == 'm²'
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should create valid instances from complex string with no spaces" do
|
158
|
+
quantities = Quantity.parse "I sprayed 500L of fertilizer across 6000m^2 of farmland"
|
159
|
+
quantities.first.value.should == 500
|
160
|
+
quantities.first.unit.name.should == 'litre'
|
161
|
+
quantities.first.unit.symbol.should == 'L'
|
162
|
+
quantities[1].value.should == 6000
|
163
|
+
quantities[1].unit.pluralized_name.should == 'square metres'
|
164
|
+
quantities[1].unit.symbol.should == 'm²'
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should create a valid instance with class parse method and per unit" do
|
168
|
+
quantities = Quantity.parse "10 miles / hour"
|
169
|
+
quantities.first.value.should == 10
|
170
|
+
quantities.first.unit.symbol.should == 'mi/h'
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should parse using string method" do
|
174
|
+
"20 m".to_q.first.value.should == 20.0
|
175
|
+
"45.45 BTU".to_q.first.class.should == Quantity
|
176
|
+
"65 kilometres per hour".to_q.first.unit.class.should == Unit::Compound
|
48
177
|
end
|
49
178
|
|
50
179
|
it "should create a valid instance with class parse method based on to_string method" do
|
51
180
|
quantity_1 = Quantity.new 15, :watt
|
52
181
|
quantity_2 = Quantity.parse quantity_1.to_s
|
53
|
-
quantity_2.value.should == 15
|
54
|
-
quantity_2.unit.name.should == 'watt'
|
55
|
-
quantity_2.represents.should == 'power'
|
182
|
+
quantity_2.first.value.should == 15
|
183
|
+
quantity_2.first.unit.name.should == 'watt'
|
184
|
+
quantity_2.first.represents.should == 'power'
|
56
185
|
end
|
57
186
|
|
58
187
|
it "should create a valid instance with class parse method and unit prefix based on to_string method" do
|
59
188
|
quantity_1 = Quantity.new 15, :watt
|
60
189
|
quantity_2 = Quantity.parse quantity_1.to_s
|
61
|
-
quantity_2.value.should == 15
|
62
|
-
quantity_2.unit.name.should == 'watt'
|
63
|
-
quantity_2.represents.should == 'power'
|
190
|
+
quantity_2.first.value.should == 15
|
191
|
+
quantity_2.first.unit.name.should == 'watt'
|
192
|
+
quantity_2.first.represents.should == 'power'
|
64
193
|
end
|
65
194
|
|
66
195
|
it "should convert quantity correctly" do
|
@@ -243,13 +372,6 @@ describe Quantity do
|
|
243
372
|
lambda{ ((10.m/1.s).pow! 0.5) }.should raise_error
|
244
373
|
end
|
245
374
|
|
246
|
-
it "should parse using string method" do
|
247
|
-
"20 m".to_q.value.should == 20.0
|
248
|
-
"45.45 BTU".to_q.class.should == Quantity
|
249
|
-
"65 kilometres per hour".to_q.unit.class.should == Unit::Compound
|
250
|
-
"65 kilometre per hour".to_q.unit.class.should == Unit::Compound
|
251
|
-
end
|
252
|
-
|
253
375
|
it "should cancel by base units of original compound unit if necessary" do
|
254
376
|
quantity = Quantity.new(20, Unit.psi).to(Unit.inches_of_mercury)
|
255
377
|
quantity.unit.base_units.size.should == 1
|
data/spec/unit_spec.rb
CHANGED
@@ -239,6 +239,7 @@ describe Unit do
|
|
239
239
|
it "should NOT ignore case when initialising units by symbol" do
|
240
240
|
Unit.m.label.should eql 'm'
|
241
241
|
lambda{Unit.M}.should raise_error
|
242
|
+
|
242
243
|
Unit.Gg.name.should eql 'gigagram'
|
243
244
|
lambda{Unit.GG}.should raise_error
|
244
245
|
end
|
@@ -325,8 +326,8 @@ describe Unit do
|
|
325
326
|
it "dynamic unit retrieval with symbol should be successful" do
|
326
327
|
Unit.m.name.should == 'metre'
|
327
328
|
Unit.ft.symbol.should == 'ft'
|
328
|
-
#
|
329
|
-
#
|
329
|
+
#Unit.μm.factor.should == 0.000001
|
330
|
+
#Unit.°C.name.should == 'degree celsius'
|
330
331
|
end
|
331
332
|
|
332
333
|
it "dynamic unit retrieval with symbol and prefix should be successful" do
|
@@ -455,10 +456,17 @@ describe Unit do
|
|
455
456
|
unit.symbol.should == 'Mpd'
|
456
457
|
end
|
457
458
|
|
458
|
-
it "should raise with block initialize and no name" do
|
459
|
+
it "should not raise with block initialize and no name if dimensionless" do
|
459
460
|
lambda{unit = Unit::Base.new do |unit|
|
460
461
|
unit.symbol = 'Mpd'
|
461
462
|
unit.dimensions = Dimensions.dimensionless
|
463
|
+
end}.should_not raise_error
|
464
|
+
end
|
465
|
+
|
466
|
+
it "should raise with block initialize and no name" do
|
467
|
+
lambda{unit = Unit::Base.new do |unit|
|
468
|
+
unit.symbol = 'Mpd'
|
469
|
+
unit.dimensions = Dimensions.mass
|
462
470
|
end}.should raise_error
|
463
471
|
end
|
464
472
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quantify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
|
-
-
|
7
|
+
- 3
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version:
|
9
|
+
- 0
|
10
|
+
version: 3.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andrew Berkeley
|
@@ -15,13 +15,12 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-11-08 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
-
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
22
|
+
name: activesupport
|
23
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
25
|
requirements:
|
27
26
|
- - ~>
|
@@ -31,12 +30,12 @@ dependencies:
|
|
31
30
|
- 3
|
32
31
|
- 0
|
33
32
|
version: "3.0"
|
34
|
-
name: activesupport
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
33
|
prerelease: false
|
38
34
|
type: :runtime
|
39
|
-
requirement:
|
35
|
+
requirement: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: i18n
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
40
39
|
none: false
|
41
40
|
requirements:
|
42
41
|
- - ">="
|
@@ -45,12 +44,12 @@ dependencies:
|
|
45
44
|
segments:
|
46
45
|
- 0
|
47
46
|
version: "0"
|
48
|
-
name: i18n
|
49
|
-
version_requirements: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
47
|
prerelease: false
|
52
|
-
type: :
|
53
|
-
requirement:
|
48
|
+
type: :runtime
|
49
|
+
requirement: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: bundler
|
52
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
54
53
|
none: false
|
55
54
|
requirements:
|
56
55
|
- - ~>
|
@@ -61,12 +60,12 @@ dependencies:
|
|
61
60
|
- 0
|
62
61
|
- 0
|
63
62
|
version: 1.0.0
|
64
|
-
name: bundler
|
65
|
-
version_requirements: *id003
|
66
|
-
- !ruby/object:Gem::Dependency
|
67
63
|
prerelease: false
|
68
64
|
type: :development
|
69
|
-
requirement:
|
65
|
+
requirement: *id003
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: jeweler
|
68
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
70
69
|
none: false
|
71
70
|
requirements:
|
72
71
|
- - ~>
|
@@ -77,12 +76,12 @@ dependencies:
|
|
77
76
|
- 6
|
78
77
|
- 4
|
79
78
|
version: 1.6.4
|
80
|
-
name: jeweler
|
81
|
-
version_requirements: *id004
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
79
|
prerelease: false
|
84
80
|
type: :development
|
85
|
-
requirement:
|
81
|
+
requirement: *id004
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rspec
|
84
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
86
85
|
none: false
|
87
86
|
requirements:
|
88
87
|
- - ~>
|
@@ -93,12 +92,12 @@ dependencies:
|
|
93
92
|
- 6
|
94
93
|
- 0
|
95
94
|
version: 2.6.0
|
96
|
-
name: rspec
|
97
|
-
version_requirements: *id005
|
98
|
-
- !ruby/object:Gem::Dependency
|
99
95
|
prerelease: false
|
100
96
|
type: :development
|
101
|
-
requirement:
|
97
|
+
requirement: *id005
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rcov
|
100
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
102
101
|
none: false
|
103
102
|
requirements:
|
104
103
|
- - ">="
|
@@ -107,12 +106,12 @@ dependencies:
|
|
107
106
|
segments:
|
108
107
|
- 0
|
109
108
|
version: "0"
|
110
|
-
name: rcov
|
111
|
-
version_requirements: *id006
|
112
|
-
- !ruby/object:Gem::Dependency
|
113
109
|
prerelease: false
|
114
110
|
type: :development
|
115
|
-
requirement:
|
111
|
+
requirement: *id006
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: rdoc
|
114
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
116
115
|
none: false
|
117
116
|
requirements:
|
118
117
|
- - ">="
|
@@ -121,8 +120,9 @@ dependencies:
|
|
121
120
|
segments:
|
122
121
|
- 0
|
123
122
|
version: "0"
|
124
|
-
|
125
|
-
|
123
|
+
prerelease: false
|
124
|
+
type: :development
|
125
|
+
requirement: *id007
|
126
126
|
description: A gem to support physical quantities and unit conversions
|
127
127
|
email: andrew.berkeley.is@googlemail.com
|
128
128
|
executables: []
|
@@ -146,6 +146,7 @@ files:
|
|
146
146
|
- lib/quantify/dimensions.rb
|
147
147
|
- lib/quantify/exception.rb
|
148
148
|
- lib/quantify/inflections.rb
|
149
|
+
- lib/quantify/parser.rb
|
149
150
|
- lib/quantify/quantify.rb
|
150
151
|
- lib/quantify/quantity.rb
|
151
152
|
- lib/quantify/unit/base_unit.rb
|
@@ -196,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
196
197
|
requirements: []
|
197
198
|
|
198
199
|
rubyforge_project:
|
199
|
-
rubygems_version: 1.
|
200
|
+
rubygems_version: 1.5.3
|
200
201
|
signing_key:
|
201
202
|
specification_version: 3
|
202
203
|
summary: Support for handling physical quantities, unit conversions, etc
|