quantify 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +20 -0
- data/Examples.rb +104 -0
- data/README +7 -0
- data/lib/quantify/config.rb +379 -0
- data/lib/quantify/core_extensions.rb +63 -0
- data/lib/quantify/dimensions.rb +523 -0
- data/lib/quantify/exception.rb +21 -0
- data/lib/quantify/inflections.rb +63 -0
- data/lib/quantify/quantify.rb +37 -0
- data/lib/quantify/quantity.rb +325 -0
- data/lib/quantify/unit/base_unit.rb +518 -0
- data/lib/quantify/unit/compound_base_unit.rb +91 -0
- data/lib/quantify/unit/compound_unit.rb +321 -0
- data/lib/quantify/unit/non_si_unit.rb +20 -0
- data/lib/quantify/unit/prefix/base_prefix.rb +42 -0
- data/lib/quantify/unit/prefix/non_si_prefix.rb +10 -0
- data/lib/quantify/unit/prefix/prefix.rb +73 -0
- data/lib/quantify/unit/prefix/si_prefix.rb +10 -0
- data/lib/quantify/unit/si_unit.rb +10 -0
- data/lib/quantify/unit/unit.rb +217 -0
- data/lib/quantify.rb +26 -0
- data/spec/dimension_spec.rb +294 -0
- data/spec/quantity_spec.rb +250 -0
- data/spec/unit_spec.rb +687 -0
- metadata +103 -0
@@ -0,0 +1,217 @@
|
|
1
|
+
#! usr/bin/ruby
|
2
|
+
|
3
|
+
module Quantify
|
4
|
+
module Unit
|
5
|
+
|
6
|
+
extend ExtendedMethods
|
7
|
+
|
8
|
+
# The Unit module contains functionality for defining and handling
|
9
|
+
# representations of physical units.
|
10
|
+
#
|
11
|
+
# All units are defined using the Unit::SI and Unit::NonSI classes, both of
|
12
|
+
# which inherit from Unit::Base.
|
13
|
+
#
|
14
|
+
# New units can be defined to represent whatever is required. However a
|
15
|
+
# system of known units is stored in the Unit module instance variable
|
16
|
+
# @units, accessible using Unit.units. These known units can be configured
|
17
|
+
# to represent which ever units are required. The Unit module will handle
|
18
|
+
# any combinations of units and prefixes according to the known units and
|
19
|
+
# prefixes specified in config.rb. New units can be defined (with or without
|
20
|
+
# prefixes) at any time and either used in place or loaded into the known
|
21
|
+
# system.
|
22
|
+
|
23
|
+
# Make the @units instance array readable
|
24
|
+
class << self
|
25
|
+
attr_reader :units
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.configure &block
|
29
|
+
self.class_eval &block if block
|
30
|
+
end
|
31
|
+
|
32
|
+
# Instance variable containing system of known units
|
33
|
+
@units = []
|
34
|
+
|
35
|
+
# Load a new unit into they system of known units
|
36
|
+
def self.load(unit)
|
37
|
+
@units << unit if unit.is_a? Unit::Base
|
38
|
+
end
|
39
|
+
|
40
|
+
# Remove a unit from the system of known units
|
41
|
+
def self.unload(*unloaded_units)
|
42
|
+
[unloaded_units].flatten.each do |unloaded_unit|
|
43
|
+
unloaded_unit = Unit.for(unloaded_unit)
|
44
|
+
@units.delete_if { |unit| unit.label == unloaded_unit.label }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns an instance of the class Quantity which represents the ratio of two
|
49
|
+
# units. For example, the ratio of miles to kilometers is 1.609355, or there
|
50
|
+
# are 1.609355 km in 1 mile.
|
51
|
+
#
|
52
|
+
# ratio = Unit.ratio :km, :mi #=> <Quantify::Quantity:0xj9ab878a7>
|
53
|
+
#
|
54
|
+
# ratio.to_s :name #=> "1.609344 kilometres per mile"
|
55
|
+
#
|
56
|
+
# In other words the quantity represents the definition of one unit in terms
|
57
|
+
# of the other.
|
58
|
+
#
|
59
|
+
def self.ratio(unit,other_unit)
|
60
|
+
unit = Unit.for unit
|
61
|
+
other_unit = Unit.for other_unit
|
62
|
+
unless unit.is_alternative_for? other_unit
|
63
|
+
raise InvalidUnitError, "Units do not represent the same physical quantity"
|
64
|
+
end
|
65
|
+
new_unit = (unit / other_unit)
|
66
|
+
value = 1/new_unit.factor
|
67
|
+
Quantity.new(value, new_unit)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Retrieve an object representing the specified unit.
|
71
|
+
#
|
72
|
+
# Argument can be the unit name, symbol or JScience label and provided as
|
73
|
+
# a string or a symbol, e.g.
|
74
|
+
#
|
75
|
+
# Unit.for :metre
|
76
|
+
#
|
77
|
+
# Unit.for 'kilogram'
|
78
|
+
#
|
79
|
+
# This can be shortened to, for example, Unit.metre by virtue of the
|
80
|
+
# #method_missing method (see below)
|
81
|
+
#
|
82
|
+
# This method will recognise valid combinations of known units and prefixes,
|
83
|
+
# irrespective of whether the prefixed unit has been initialized into the
|
84
|
+
# system of known units in it's own right. For example,
|
85
|
+
#
|
86
|
+
# Unit.centimetre ... or, alternatively ... Unit.cm
|
87
|
+
#
|
88
|
+
# will return a Unit::SI object with attributes representing a centimetre
|
89
|
+
# based on the initialized Unit for :metre and Prefix :centi.
|
90
|
+
#
|
91
|
+
def self.for(name_symbol_label_or_object)
|
92
|
+
return name_symbol_label_or_object.clone if name_symbol_label_or_object.is_a? Unit::Base
|
93
|
+
return nil if name_symbol_label_or_object.nil? or
|
94
|
+
( name_symbol_label_or_object.is_a?(String) and name_symbol_label_or_object.empty? )
|
95
|
+
name_symbol_or_label = name_symbol_label_or_object
|
96
|
+
unless name_symbol_or_label.is_a? String or name_symbol_or_label.is_a? Symbol
|
97
|
+
raise InvalidArgumentError, "Argument must be a Symbol or String"
|
98
|
+
end
|
99
|
+
if unit = Unit.match(name_symbol_or_label)
|
100
|
+
return unit
|
101
|
+
end
|
102
|
+
if unit = Unit.parse(name_symbol_or_label)
|
103
|
+
return unit
|
104
|
+
end
|
105
|
+
rescue InvalidUnitError
|
106
|
+
return nil
|
107
|
+
end
|
108
|
+
|
109
|
+
# Parse complex strings into unit.
|
110
|
+
#
|
111
|
+
def self.parse(string)
|
112
|
+
string = string.standardize
|
113
|
+
if string.scan(/(\/|per)/).size > 1
|
114
|
+
raise InvalidArgumentError, "Malformed unit: multiple uses of '/' or 'per'"
|
115
|
+
end
|
116
|
+
|
117
|
+
units = []
|
118
|
+
numerator, per, denominator = string.split(/(\/|per)/)
|
119
|
+
units += Unit.parse_numerator_units(numerator)
|
120
|
+
units += Unit.parse_denominator_units(denominator) unless denominator.nil?
|
121
|
+
if units.size == 1 and units.first.index == 1
|
122
|
+
return units.first.unit
|
123
|
+
else
|
124
|
+
return Unit::Compound.new(*units)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.match(name_symbol_or_label)
|
129
|
+
return name_symbol_or_label.clone if name_symbol_or_label.is_a? Unit::Base
|
130
|
+
Unit.match_known_unit_or_prefixed_variant(:label, name_symbol_or_label) or
|
131
|
+
Unit.match_known_unit_or_prefixed_variant(:name, name_symbol_or_label) or
|
132
|
+
Unit.match_known_unit_or_prefixed_variant(:symbol, name_symbol_or_label)
|
133
|
+
end
|
134
|
+
|
135
|
+
protected
|
136
|
+
|
137
|
+
def self.match_known_unit_or_prefixed_variant(attribute, string_or_symbol)
|
138
|
+
Unit.match_known_unit(attribute, string_or_symbol) or
|
139
|
+
Unit.match_prefixed_variant(attribute, string_or_symbol)
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.match_known_unit(attribute, string_or_symbol)
|
143
|
+
string_or_symbol = Unit.format_unit_attribute(attribute, string_or_symbol)
|
144
|
+
unit = @units.find { |unit| unit.send(attribute) == string_or_symbol }
|
145
|
+
return unit.clone rescue nil
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.match_prefixed_variant(attribute, string_or_symbol)
|
149
|
+
string_or_symbol = Unit.format_unit_attribute(attribute, string_or_symbol)
|
150
|
+
if string_or_symbol =~ /\A(#{Unit::Prefix.si_prefixes.map(&attribute).join("|")})(#{Unit.si_non_prefixed_units.map(&attribute).join("|")})\z/ or
|
151
|
+
string_or_symbol =~ /\A(#{Unit::Prefix.non_si_prefixes.map(&attribute).join("|")})(#{Unit.non_si_non_prefixed_units.map(&attribute).join("|")})\z/
|
152
|
+
return Unit.for($2).with_prefix($1).clone
|
153
|
+
end
|
154
|
+
return nil
|
155
|
+
end
|
156
|
+
|
157
|
+
# Standardizes query strings or symbols into canonical form for unit names,
|
158
|
+
# symbols and labels
|
159
|
+
#
|
160
|
+
def self.format_unit_attribute(attribute, string_or_symbol)
|
161
|
+
string_or_symbol = case attribute
|
162
|
+
when :symbol then string_or_symbol.standardize
|
163
|
+
when :name then string_or_symbol.standardize.singularize.downcase
|
164
|
+
else string_or_symbol.to_s
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.parse_unit_and_index(string)
|
169
|
+
string.scan(/([^0-9\^]+)\^?([\d\.-]*)?/i)
|
170
|
+
index = ($2.nil? or $2.empty? ? 1 : $2.to_i)
|
171
|
+
CompoundBaseUnit.new($1.to_s, index)
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.parse_numerator_units(string)
|
175
|
+
# If no middot then names parsed by whitespace
|
176
|
+
# Need to consider multi word unit names
|
177
|
+
num_units = ( string =~ /·/ ? string.split("·") : string.split(" ") )
|
178
|
+
num_units.map! do |substring|
|
179
|
+
Unit.parse_unit_and_index(substring)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.parse_denominator_units(string)
|
184
|
+
Unit.parse_numerator_units(string).map do |unit|
|
185
|
+
unit.index *= -1
|
186
|
+
unit
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# This can be replicated by method missing approach, but explicit method provided
|
191
|
+
# given importance in #match (and #for) methods regexen
|
192
|
+
#
|
193
|
+
def self.si_non_prefixed_units
|
194
|
+
@units.select {|unit| unit.is_si_unit? and not unit.is_prefixed_unit? }
|
195
|
+
end
|
196
|
+
|
197
|
+
# This can be replicated by method missing approach, but explicit method provided
|
198
|
+
# given importance in #match (and #for) methods regexen
|
199
|
+
#
|
200
|
+
def self.non_si_non_prefixed_units
|
201
|
+
@units.select {|unit| unit.is_non_si_unit? and not unit.is_prefixed_unit? }
|
202
|
+
end
|
203
|
+
|
204
|
+
def self.multi_word_unit_names
|
205
|
+
@units.map(&:name).compact.select {|name| name.word_count > 1 }
|
206
|
+
end
|
207
|
+
|
208
|
+
def self.multi_word_unit_pluralized_names
|
209
|
+
multi_word_unit_names.map(&:pluralize)
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.multi_word_unit_symbols
|
213
|
+
@units.map(&:symbol).compact.select {|symbol| symbol.word_count > 1 }
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|
data/lib/quantify.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
# The Quantify library provides a system for handling physical quantities. Physical
|
3
|
+
# quantities are represented by a value and a unit. Quantities can be added,
|
4
|
+
# subtracted, multiplied, etc. or converted into alternative units
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'pp'
|
8
|
+
require 'rubygems'
|
9
|
+
require 'active_support/inflector'
|
10
|
+
require 'quantify/quantify'
|
11
|
+
require 'quantify/core_extensions'
|
12
|
+
require 'quantify/inflections'
|
13
|
+
require 'quantify/exception'
|
14
|
+
require 'quantify/dimensions'
|
15
|
+
require 'quantify/unit/prefix/prefix'
|
16
|
+
require 'quantify/unit/prefix/base_prefix'
|
17
|
+
require 'quantify/unit/prefix/si_prefix'
|
18
|
+
require 'quantify/unit/prefix/non_si_prefix'
|
19
|
+
require 'quantify/unit/unit'
|
20
|
+
require 'quantify/unit/base_unit'
|
21
|
+
require 'quantify/unit/si_unit'
|
22
|
+
require 'quantify/unit/non_si_unit'
|
23
|
+
require 'quantify/unit/compound_base_unit'
|
24
|
+
require 'quantify/unit/compound_unit'
|
25
|
+
require 'quantify/quantity'
|
26
|
+
require 'quantify/config'
|
@@ -0,0 +1,294 @@
|
|
1
|
+
require 'quantify'
|
2
|
+
include Quantify
|
3
|
+
|
4
|
+
describe Dimensions do
|
5
|
+
|
6
|
+
it "should hold array of recignised base quantities" do
|
7
|
+
Dimensions::BASE_QUANTITIES. should == [
|
8
|
+
:mass, :length, :time, :electric_current, :temperature,
|
9
|
+
:luminous_intensity, :amount_of_substance, :information,
|
10
|
+
:currency, :item ]
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return an array class variable" do
|
14
|
+
Dimensions.dimensions.class.should == Array
|
15
|
+
end
|
16
|
+
|
17
|
+
it "class variable should contain dimension objects" do
|
18
|
+
Dimensions.dimensions[0].class.should == Dimensions
|
19
|
+
Dimensions.dimensions[1].class.should == Dimensions
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should list all physical quantities as strings" do
|
23
|
+
list = Dimensions.physical_quantities
|
24
|
+
list.should include "acceleration"
|
25
|
+
list.should include "force"
|
26
|
+
list.should_not include "effort"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should return correct dimension object with symbol :length" do
|
30
|
+
dimensions = Dimensions.for(:length)
|
31
|
+
dimensions.class.should == Dimensions
|
32
|
+
dimensions.length.should == 1
|
33
|
+
dimensions.mass.should == nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return correct dimension object with symbol :energy" do
|
37
|
+
dimensions = Dimensions.for(:energy)
|
38
|
+
dimensions.class.should == Dimensions
|
39
|
+
dimensions.length.should == 2
|
40
|
+
dimensions.mass.should == 1
|
41
|
+
dimensions.time.should == -2
|
42
|
+
dimensions.luminous_intensity.should == nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return correct dimension object with string 'energy'" do
|
46
|
+
dimensions = Dimensions.for('ENERGY')
|
47
|
+
dimensions.class.should == Dimensions
|
48
|
+
dimensions.length.should == 2
|
49
|
+
dimensions.mass.should == 1
|
50
|
+
dimensions.time.should == -2
|
51
|
+
dimensions.luminous_intensity.should == nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return correct dimension object with string 'length'" do
|
55
|
+
dimensions = Dimensions.for('length')
|
56
|
+
dimensions.class.should == Dimensions
|
57
|
+
dimensions.length.should == 1
|
58
|
+
dimensions.mass.should == nil
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should raise error with invalid integer argument" do
|
62
|
+
lambda{dimensions = Dimensions.for(1)}.should raise_error
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should raise error with unknown dimension" do
|
66
|
+
lambda{dimensions = Dimensions.for(:effort)}.should raise_error
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should initialize a new object in @@dimensions class variable" do
|
70
|
+
Dimensions.load :physical_quantity => :some_dimensions, :length => 12
|
71
|
+
dimensions = Dimensions.for :some_dimensions
|
72
|
+
dimensions.class.should == Dimensions
|
73
|
+
dimensions.length.should == 12
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should refuse to load new object in class array if no physical quantity" do
|
77
|
+
lambda{Dimensions.load :mass => 1}.should raise_error
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should refuse to load new object in class array if no physical quantity" do
|
81
|
+
lambda{Dimensions.load :physical_quantity => nil, :mass => 1}.should raise_error
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should create a new object with valid arguments" do
|
85
|
+
dimensions = Dimensions.new :mass => 1, :length => -2
|
86
|
+
dimensions.class.should == Dimensions
|
87
|
+
dimensions.mass.should == 1
|
88
|
+
dimensions.length.should == -2
|
89
|
+
dimensions.time.should == nil
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should raise error with invalid arguments" do
|
93
|
+
lambda{dimension = Dimensions.new :acceleration => 1}.should raise_error
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should identify the physical quantity and set ivar if known" do
|
97
|
+
dimensions = Dimensions.new :mass => 1
|
98
|
+
dimensions.describe.should == 'mass'
|
99
|
+
dimensions.physical_quantity.should == 'mass'
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should identify the physical quantity if known" do
|
103
|
+
dimensions = Dimensions.new :mass => 1, :length => 2, :time => -2
|
104
|
+
dimensions.describe.should == 'energy'
|
105
|
+
dimensions.is_known?.should == true
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should return nil if physical quantity not known" do
|
109
|
+
dimensions = Dimensions.new :mass => 81, :length => 2, :time => -2
|
110
|
+
dimensions.describe.should == nil
|
111
|
+
dimensions.is_known?.should == false
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should return the correct dimensions representation on multiplying" do
|
115
|
+
dimensions_1 = Dimensions.for :length
|
116
|
+
dimensions_2 = Dimensions.for :length
|
117
|
+
dimensions_3 = dimensions_1 * dimensions_2
|
118
|
+
dimensions_3.class.should == Dimensions
|
119
|
+
dimensions_3.length.should == 2
|
120
|
+
dimensions_3.physical_quantity.should == 'area'
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should return the correct dimensions representation on dividing" do
|
124
|
+
dimensions_1 = Dimensions.for :area
|
125
|
+
dimensions_2 = Dimensions.for :length
|
126
|
+
dimensions_3 = dimensions_1 / dimensions_2
|
127
|
+
dimensions_3.class.should == Dimensions
|
128
|
+
dimensions_3.length.should == 1
|
129
|
+
dimensions_3.physical_quantity.should == 'length'
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should return the correct dimensions representation on raising to power" do
|
133
|
+
dimensions_1 = Dimensions.for :length
|
134
|
+
dimensions_2 = dimensions_1 ** 2
|
135
|
+
dimensions_2.class.should == Dimensions
|
136
|
+
dimensions_2.length.should == 2
|
137
|
+
dimensions_2.physical_quantity.should == 'area'
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should return the correct dimensions representation on reciprocalize" do
|
141
|
+
dimensions_1 = Dimensions.for :time
|
142
|
+
dimensions_2 = dimensions_1.reciprocalize
|
143
|
+
dimensions_2.class.should == Dimensions
|
144
|
+
dimensions_2.time.should == -1
|
145
|
+
dimensions_2.physical_quantity.should == 'frequency'
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should retrieve the correct dimension with dynamic method" do
|
149
|
+
Dimensions.acceleration.physical_quantity.should == 'acceleration'
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should recognise length as a base quantity" do
|
153
|
+
dimension = Dimensions.length
|
154
|
+
dimension.is_base?.should == true
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should recognise mass as a base quantity" do
|
158
|
+
dimension = Dimensions.mass
|
159
|
+
dimension.is_base?.should == true
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should not recognise force as a base quantity" do
|
163
|
+
dimension = Dimensions.force
|
164
|
+
dimension.is_base?.should == false
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should recognise plane angle as dimensionless" do
|
168
|
+
dimension = Dimensions.plane_angle
|
169
|
+
dimension.is_dimensionless?.should == true
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should not recognise power as dimensionless" do
|
173
|
+
dimension = Dimensions.power
|
174
|
+
dimension.is_dimensionless?.should == false
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should make an instance dimensionless" do
|
178
|
+
dimension = Dimensions.power
|
179
|
+
dimension.is_dimensionless?.should == false
|
180
|
+
dimension
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should return appropriate associated units" do
|
184
|
+
dimension = Dimensions.power
|
185
|
+
units = dimension.units :name
|
186
|
+
units.class.should == Array
|
187
|
+
units.include?('watt').should == true
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should return appropriate associated units" do
|
191
|
+
dimension = Dimensions.length
|
192
|
+
units = dimension.units :name
|
193
|
+
units.class.should == Array
|
194
|
+
units.include?('yard').should == true
|
195
|
+
units.include?('siemens').should == false
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should return appropriate associated units" do
|
199
|
+
dimension = Dimensions.energy
|
200
|
+
units = dimension.units :symbol
|
201
|
+
units.class.should == Array
|
202
|
+
units.include?('J').should == true
|
203
|
+
units.include?('ft').should == false
|
204
|
+
units.include?('kWh').should == true
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should return appropriate associated units" do
|
208
|
+
dimension = Dimensions.temperature
|
209
|
+
units = dimension.units :symbol
|
210
|
+
units.class.should == Array
|
211
|
+
units.include?('K').should == true
|
212
|
+
units.include?('°C').should == true
|
213
|
+
units.include?('L').should == false
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should return correct SI unit" do
|
217
|
+
dimension = Dimensions.temperature
|
218
|
+
dimension.si_unit.symbol.should == 'K'
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should return correct SI unit" do
|
222
|
+
dimension = Dimensions.power
|
223
|
+
dimension.si_unit.symbol.should == 'W'
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should return correct SI unit" do
|
227
|
+
dimension = Dimensions.kinematic_viscosity
|
228
|
+
dimension.si_unit.name.should == 'square metre per second'
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should return correct SI unit" do
|
232
|
+
dimension = Dimensions.mass
|
233
|
+
dimension.si_unit.symbol.should == 'kg'
|
234
|
+
dimension.si_unit.symbol.should_not == 'd'
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should return correct SI unit" do
|
238
|
+
dimension = Dimensions.plane_angle
|
239
|
+
dimension.si_unit.symbol.should == 'rad'
|
240
|
+
dimension.si_unit.symbol.should_not == 'W'
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should return the correct SI base units" do
|
244
|
+
units = Dimensions.mass.si_base_units :name
|
245
|
+
units.class.should == Array
|
246
|
+
units.include?('kilogram').should == true
|
247
|
+
units.include?('gram').should == false
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should return the correct SI base units" do
|
251
|
+
units = Dimensions.energy.si_base_units :name
|
252
|
+
units.class.should == Array
|
253
|
+
units.include?('kilogram').should == true
|
254
|
+
units.include?('square metre').should == true
|
255
|
+
units.include?('per square second').should == true
|
256
|
+
units.include?('kelvin').should == false
|
257
|
+
units.size.should == 3
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should return the correct SI base units" do
|
261
|
+
units = Dimensions.force.si_base_units :name
|
262
|
+
units.class.should == Array
|
263
|
+
units.include?('kilogram').should == true
|
264
|
+
units.include?('metre').should == true
|
265
|
+
units.include?('second').should == false
|
266
|
+
units.size.should == 3
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should return the correct SI base units" do
|
270
|
+
units = Dimensions.mass.si_base_units :symbol
|
271
|
+
units.class.should == Array
|
272
|
+
units.include?('kg').should == true
|
273
|
+
units.size.should == 1
|
274
|
+
end
|
275
|
+
|
276
|
+
it "should return the correct SI base units" do
|
277
|
+
units = Dimensions.area.si_base_units :symbol
|
278
|
+
units.class.should == Array
|
279
|
+
units.include?('m^2').should == true
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should recognise molar quantity" do
|
283
|
+
dimension = Dimensions.mass/Dimensions.amount_of_substance
|
284
|
+
dimension.is_molar_quantity?.should == true
|
285
|
+
dimension.is_specific_quantity?.should == false
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should recognise specific quantity" do
|
289
|
+
dimension = Dimensions.volume/Dimensions.mass
|
290
|
+
dimension.is_molar_quantity?.should == false
|
291
|
+
dimension.is_specific_quantity?.should == true
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|