dimensional 0.0.2
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/CHANGELOG +0 -0
- data/LICENSE +20 -0
- data/README +11 -0
- data/Rakefile +38 -0
- data/lib/dimensional.rb +8 -0
- data/lib/dimensional/configurator.rb +118 -0
- data/lib/dimensional/dimension.rb +56 -0
- data/lib/dimensional/measure.rb +98 -0
- data/lib/dimensional/metric.rb +59 -0
- data/lib/dimensional/system.rb +51 -0
- data/lib/dimensional/unit.rb +90 -0
- data/test/configurator_test.rb +144 -0
- data/test/demo.rb +140 -0
- data/test/dimension_test.rb +55 -0
- data/test/dimensional_test.rb +27 -0
- data/test/measure_test.rb +185 -0
- data/test/metric_test.rb +90 -0
- data/test/system_test.rb +40 -0
- data/test/unit_test.rb +102 -0
- metadata +80 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'dimensional/dimension'
|
2
|
+
require 'dimensional/system'
|
3
|
+
require 'set'
|
4
|
+
require 'enumerator'
|
5
|
+
|
6
|
+
module Dimensional
|
7
|
+
# A standard scale unit for measuring physical quantities. In addition to the Dimension and System attribute
|
8
|
+
# that are well-defined by classes above, the user-defined metric attribute is available to identify units as
|
9
|
+
# belonging to an arbitrary metric like length, draft or property size. Effective use of the metric attribute
|
10
|
+
# can simplify presentation of Measures and make parsing of user input more accurate.
|
11
|
+
# Reference: http://en.wikipedia.org/wiki/Units_of_measurement
|
12
|
+
class Unit
|
13
|
+
@store = Set.new
|
14
|
+
|
15
|
+
def self.register(*args)
|
16
|
+
u = new(*args)
|
17
|
+
raise "Namespace collision: #{u.dimension}:#{u.system}:#{u.name}" if self[u.dimension, u.system, u.name.to_sym]
|
18
|
+
raise "Namespace collision: #{u.dimension}:#{u.system}:#{u.abbreviation}" if self[u.dimension, u.system, u.abbreviation.to_sym]
|
19
|
+
@store << u
|
20
|
+
u
|
21
|
+
end
|
22
|
+
|
23
|
+
# Lookup the unit by name or abbreviation, scoped by dimension and system
|
24
|
+
def self.[](dim, sys, sym)
|
25
|
+
dim = Dimension[dim] unless dim.kind_of?(Dimension)
|
26
|
+
sys = System[sys] unless sys.kind_of?(System)
|
27
|
+
sym = sym.to_sym
|
28
|
+
@store.select{|u| u.dimension == dim}.select{|u| u.system == sys}.detect{|u| sym == u.abbreviation.to_sym || sym == u.name.to_sym}
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.reset!
|
32
|
+
@store.clear
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_reader :name, :abbreviation, :format
|
36
|
+
attr_reader :system, :dimension
|
37
|
+
attr_reader :reference_factor, :reference_unit
|
38
|
+
|
39
|
+
def initialize(name, system, dimension, options = {})
|
40
|
+
@name = name.to_s
|
41
|
+
@system = system
|
42
|
+
@dimension = dimension
|
43
|
+
@reference_factor = options[:reference_factor]
|
44
|
+
@reference_unit = options[:reference_unit]
|
45
|
+
@detector = options[:detector] || /\A#{self.name}\Z/
|
46
|
+
@abbreviation = (options[:abbreviation] || self.name).to_s
|
47
|
+
@format = options[:format] || dimension.nil? ? "%s %U" : "%s%U"
|
48
|
+
end
|
49
|
+
|
50
|
+
def match(s)
|
51
|
+
@detector.match(s)
|
52
|
+
end
|
53
|
+
|
54
|
+
# If no reference was provided during initialization, this unit must itself be a base unit.
|
55
|
+
def base?
|
56
|
+
!reference_unit
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns the unit or array of units on which this unit's scale is ultimately based.
|
60
|
+
def base
|
61
|
+
return self if base?
|
62
|
+
@base ||= reference_unit.kind_of?(Enumerable) ? reference_unit.map{|ru| ru.base} : reference_unit.base
|
63
|
+
end
|
64
|
+
|
65
|
+
# The conversion factor relative to the base unit.
|
66
|
+
def factor
|
67
|
+
return 1 if base?
|
68
|
+
@factor ||= reference_factor * (reference_unit.kind_of?(Enumerable) ? reference_unit.inject(1){|f, ru| f * ru.factor} : reference_unit.factor)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns the conversion factor to convert to the other unit
|
72
|
+
def convert(other)
|
73
|
+
raise "Units #{self} and #{other} are not commensurable" unless commensurable?(other)
|
74
|
+
return 1 if self == other
|
75
|
+
self.factor / other.factor
|
76
|
+
end
|
77
|
+
|
78
|
+
def commensurable?(other)
|
79
|
+
dimension == other.dimension
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_s
|
83
|
+
name rescue super
|
84
|
+
end
|
85
|
+
|
86
|
+
def inspect
|
87
|
+
"#<#{self.class.inspect}: #{dimension.to_s}:#{system.to_s}:#{to_s}>"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'dimensional/configurator'
|
3
|
+
|
4
|
+
class ConfiguratorTest < Test::Unit::TestCase
|
5
|
+
include Dimensional
|
6
|
+
|
7
|
+
def setup
|
8
|
+
System.register('International System', 'SI')
|
9
|
+
System.register('United States Customary', 'US')
|
10
|
+
System.register('British Admiralty', 'BA')
|
11
|
+
Dimension.register('Length')
|
12
|
+
Dimension.register('Area', 'A', {Dimension::L => 2})
|
13
|
+
Dimension.register('Mass')
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
Dimension.reset!
|
18
|
+
System.reset!
|
19
|
+
Unit.reset!
|
20
|
+
Metric.reset!
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_create_configurator
|
24
|
+
assert_instance_of Configurator, c = Configurator.new
|
25
|
+
assert_nil c.context.dimension
|
26
|
+
assert_nil c.context.system
|
27
|
+
assert_nil c.context.unit
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_start_configurator
|
31
|
+
assert Configurator.start
|
32
|
+
assert Configurator.start {true}
|
33
|
+
assert !Configurator.start {false}
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_start_configurator_with_context_args
|
37
|
+
assert_same Dimension::L, Configurator.start(:dimension => Dimension::L){context.dimension}
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_change_dimension_context_for_duration_of_block
|
41
|
+
test_context = self
|
42
|
+
Configurator.start do
|
43
|
+
dimension(Dimension::L) do
|
44
|
+
test_context.assert_equal Dimension::L, context.dimension
|
45
|
+
true
|
46
|
+
end
|
47
|
+
test_context.assert_nil context.dimension
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_change_system_context_for_duration_of_block
|
52
|
+
test_context = self
|
53
|
+
Configurator.start do
|
54
|
+
system(System::SI) do
|
55
|
+
test_context.assert_equal System::SI, context.system
|
56
|
+
true
|
57
|
+
end
|
58
|
+
test_context.assert_nil context.system
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_build_base_unit
|
63
|
+
Configurator.start(:system => System::SI, :dimension => Dimension::L) do
|
64
|
+
base('meter', :detector => /\A(meters?|m)\Z/, :abbreviation => 'm')
|
65
|
+
end
|
66
|
+
assert_instance_of Unit, u = Unit[Dimension::L, System::SI, 'meter']
|
67
|
+
assert_same System::SI, u.system
|
68
|
+
assert_same Dimension::L, u.dimension
|
69
|
+
assert u.base?
|
70
|
+
assert_instance_of Metric, Metric[:L]
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_build_derived_unit
|
74
|
+
Configurator.start(:system => System::SI, :dimension => Dimension::L) do
|
75
|
+
base('meter', :detector => /\A(meters?|m)\Z/, :abbreviation => 'm') do
|
76
|
+
derive('centimeter', 1e-2, :detector => /\A(centimeters?|cm)\Z/, :abbreviation => 'cm')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
u0 = Unit[Dimension::L, System::SI, 'meter']
|
80
|
+
assert_instance_of Unit, u = Unit[Dimension::L, System::SI, 'centimeter']
|
81
|
+
assert_same System::SI, u.system
|
82
|
+
assert_same Dimension::L, u.dimension
|
83
|
+
assert_same u0, u.base
|
84
|
+
assert_equal 1E-2, u.factor
|
85
|
+
assert_equal 'cm', u.abbreviation
|
86
|
+
assert u.match("centimeters")
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_build_aliased_unit
|
90
|
+
Configurator.start(:system => System::SI, :dimension => Dimension::L) do
|
91
|
+
base('meter', :detector => /\A(meters?|m)\Z/, :abbreviation => 'm') do
|
92
|
+
self.alias('decadecimeter')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
u0 = Unit[Dimension::L, System::SI, 'meter']
|
96
|
+
assert_instance_of Unit, u = Unit[Dimension::L, System::SI, 'decadecimeter']
|
97
|
+
assert_same System::SI, u.system
|
98
|
+
assert_same Dimension::L, u.dimension
|
99
|
+
assert_same u0, u.base
|
100
|
+
assert_equal 1, u.factor
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_build_referenced_unit
|
104
|
+
Configurator.start(:system => System::SI, :dimension => Dimension::L) do
|
105
|
+
base('meter', :detector => /\A(meters?|m)\Z/, :abbreviation => 'm')
|
106
|
+
system(:US) do
|
107
|
+
reference('yard', Unit[:L, :SI, 'meter'], 0.9144, :detector => /\A(yards?|yds?)\Z/, :abbreviation => 'yd')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
u0 = Unit[Dimension::L, System::SI, 'meter']
|
111
|
+
assert_instance_of Unit, u = Unit[Dimension::L, System::US, 'yard']
|
112
|
+
assert_equal 0.9144, u.factor
|
113
|
+
assert_same u0, u.base
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_build_combined_unit
|
117
|
+
Configurator.start(:system => System::SI, :dimension => Dimension::L) do
|
118
|
+
base('meter', :detector => /\A(meters?|m)\Z/, :abbreviation => 'm')
|
119
|
+
system(:US) do
|
120
|
+
reference('yard', Unit[:L, :SI, 'meter'], 0.9144, :detector => /\A(yards?|yds?)\Z/, :abbreviation => 'yd')
|
121
|
+
dimension(:A) do
|
122
|
+
combine('square yard', [Unit[:L, :US, 'yard'], Unit[:L, :US, 'yard']], :detector => //, :abbreviation => 'yd2')
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
u1 = Unit[Dimension::L, System::US, 'yard']
|
127
|
+
assert_instance_of Unit, u = Unit[:A, :US, 'square yard']
|
128
|
+
assert_equal Dimension::A, u.dimension
|
129
|
+
assert_equal 0.83612736, u.factor
|
130
|
+
assert_equal [u1.base, u1.base], u.base
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_register_metric_options
|
134
|
+
Configurator.start(:system => System::SI, :dimension => Dimension::L) do
|
135
|
+
base('meter', :detector => /\A(meters?|m)\Z/, :abbreviation => 'm') do
|
136
|
+
prefer(:length_over_all, :precision => 0.01)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
u = Unit[:L, :SI, 'm']
|
140
|
+
assert_instance_of Metric, m = Metric[:length_over_all]
|
141
|
+
assert_same Metric[:L], m.parent
|
142
|
+
assert_equal 0.01, m.preferences(u)[:precision]
|
143
|
+
end
|
144
|
+
end
|
data/test/demo.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'dimensional/configurator'
|
2
|
+
require 'rational'
|
3
|
+
|
4
|
+
# Define fundamental dimensions and composite dimensions
|
5
|
+
# Reference: http://en.wikipedia.org/wiki/Dimensional_Analysis
|
6
|
+
Dimensional::Dimension.register('Length')
|
7
|
+
Dimensional::Dimension.register('Mass')
|
8
|
+
Dimensional::Dimension.register('Time')
|
9
|
+
Dimensional::Dimension.register('Temperature', 'Temp') # Θ is the proper symbol, but it can't be represented in US ASCII
|
10
|
+
Dimensional::Dimension.register('Electric Charge', 'Q')
|
11
|
+
Dimensional::Dimension.register('Area', 'A', {Dimensional::Dimension[:L] => 2})
|
12
|
+
Dimensional::Dimension.register('Volume', 'V', {Dimensional::Dimension[:L] => 3})
|
13
|
+
|
14
|
+
# Define common Systems of Measurement
|
15
|
+
Dimensional::System.register('SI - International System (kg, tonne, m)', 'SI')
|
16
|
+
Dimensional::System.register('US Customary (lbs, ton, ft)', 'US') # http://en.wikipedia.org/wiki/United_States_customary_units
|
17
|
+
Dimensional::System.register('US Customary Troy (oz)', 'USt') # http://en.wikipedia.org/wiki/United_States_customary_units
|
18
|
+
Dimensional::System.register('British Imperial (lbs, ton, ft)', 'Imp') # http://en.wikipedia.org/wiki/Imperial_units
|
19
|
+
|
20
|
+
Dimensional::Configurator.start do
|
21
|
+
dimension(:L) do
|
22
|
+
system(:SI) do
|
23
|
+
base('meter', :detector => /\A(meters?|m)\Z/, :abbreviation => 'm') do
|
24
|
+
derive('centimeter', 1e-2, :detector => /\A(centimeters?|cm)\Z/, :abbreviation => 'cm')
|
25
|
+
derive('kilometer', 1e3, :detector => /\A(kilometers?|km)\Z/, :abbreviation => 'km')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
system(:US) do # As of 1 July 1959 (http://en.wikipedia.org/wiki/United_States_customary_units#Units_of_length)
|
29
|
+
reference('yard', Dimensional::Unit[:L, :SI, 'meter'], 0.9144, :detector => /\A(yards?|yds?)\Z/, :abbreviation => 'yd') do
|
30
|
+
derive('foot', Rational(1,3), :detector => /\A(foot|feet|ft|')\Z/, :abbreviation => "ft", :format => "%p'") do
|
31
|
+
prefer(:hull)
|
32
|
+
derive('inch', Rational(1,12), :detector => /\A(inch|inches|in|")\Z/, :abbreviation =>"in", :format => "%p\"")
|
33
|
+
end
|
34
|
+
derive('furlong', 220, :detector => /\A(furlongs?)\Z/) do
|
35
|
+
derive('mile', 8, :detector => /\Amiles?\Z/, :abbreviation => 'mi')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
dimension(:M) do
|
41
|
+
system(:SI) do
|
42
|
+
base('kilogram', :detector => /\A(kilograms?|kg)\Z/, :abbreviation => 'kg') do
|
43
|
+
derive('tonne', 1e3, :detector => /\A(tonnes?)\Z/, :abbreviation => 't') do # metric ton
|
44
|
+
prefer(:displacement)
|
45
|
+
end
|
46
|
+
derive('gram', 1e-3, :detector => /\A(grams?|g)\Z/, :abbreviation => 'g')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
system(:US) do # Common units for mass and, occasionally, force/weight (http://en.wikipedia.org/wiki/United_States_customary_units#Units_of_mass)
|
50
|
+
reference('pound', Dimensional::Unit[:M, :SI, 'gram'], 453.59237, :detector => /\A(pounds?|lbs?|#)\Z/, :abbreviation => 'lb') do # avoirdupois
|
51
|
+
derive('hundredweight', 100, :detector => /\A(hundredweights?|cwt)\Z/, :abbreviation => 'cwt') do
|
52
|
+
derive('ton', 20, :detector => /\A(tons?|t)\Z/, :abbreviation => 't') do # short ton
|
53
|
+
prefer(:displacement)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
derive('grain', 7000**-1, :detector => /\A(grains?|gr)\Z/, :abbreviation => 'gr') do
|
57
|
+
derive('dram', 27 + Rational(11, 32), :detector => /\A(drams?|dr)\Z/, :abbreviation => 'dr') do
|
58
|
+
derive('ounce', :detector => /\A(ounces?|ozs?)\Z/, :conversion => [437.5, :grain], :abbreviation => 'oz')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
system(:Imp) do
|
64
|
+
reference('pound', Dimensional::Unit[:M, :SI, 'gram'], 453.59237, :detector => /\A(pounds?|lbs?|#)\Z/, :abbreviation => 'lb') do
|
65
|
+
derive('grain', 7000**-1, :detector => /\A(grains?|gr)\Z/, :abbreviation => 'gr')
|
66
|
+
derive('drachm', 256**-1, :detector => /\A(drachms?|dr)\Z/, :abbreviation => 'dr')
|
67
|
+
derive('ounce', 16**-1, :detector => /\A(ounces?|ozs?)\Z/, :abbreviation => 'oz')
|
68
|
+
derive('stone', 14, :detector => /\A(stones?)\Z/)
|
69
|
+
derive('quarter', 28, :detector => /\A(quarters?)\Z/)
|
70
|
+
derive('hundredweight', 112, :detector => /\A(hundredweights?|cwt)\Z/, :abbreviation => 'cwt')
|
71
|
+
derive('ton', 2240, :detector => /\A(tons?|t)\Z/, :abbreviation => 't') do # long ton
|
72
|
+
prefer(:displacement)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
dimension(:A) do
|
78
|
+
system(:SI) do
|
79
|
+
combine('square meter', %w(meter meter).map{|name| Dimensional::Unit[:L, :SI, name]}, :detector => /\A(sq\.?\s?meters?|m2)\Z/, :abbreviation => 'm2') do
|
80
|
+
derive('hectare', 10000, :format => "%.4f%U", :abbreviation => 'ha') do
|
81
|
+
prefer(:forestry, :precision => -4, :format => "%s%U")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
system(:US) do # All measures below are approximations due to the difference between a survey foot and an international foot.
|
86
|
+
combine('square yard', %w(yard yard).map{|name| Dimensional::Unit[:L, :US, name]}, :detector => /yd2/, :abbreviation => 'yd2') do
|
87
|
+
derive('acre', 4840.0)
|
88
|
+
end
|
89
|
+
combine('square mile', %w(mile mile).map{|name| Dimensional::Unit[:L, :US, name]}, :detector => /\A(sq(uare|\.)?\s?miles?)\Z/) do
|
90
|
+
self.alias('section', :detector => /\Asections?\Z/) do
|
91
|
+
derive('township', 36, :detector => /\Atownships?\Z/)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
dimension(:V) do
|
98
|
+
system(:SI) do
|
99
|
+
combine('cubic meter', %w(meter meter meter).map{|name| Dimensional::Unit[:L, :SI, name]}, :detector => /\A(cubic meters?|m3)\Z/, :abbreviation => "m3") do
|
100
|
+
derive('cubic decimeter', 1e-3, :detector => /\A(cubic decimeters?|dm3)\Z/, :abbreviation => "dm3") do
|
101
|
+
self.alias('liter', :detector => /\A(liters?|l|L)\Z/, :abbreviation => "l") do
|
102
|
+
derive('milliliter', 1E-3, :detector => /\A(milliliters?|ml|mL)\Z/, :abbreviation => "ml")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
system(:Imp) do
|
108
|
+
reference('ounce', Dimensional::Unit[:V, :SI, 'milliliter'], 28.4130625, :detector => /\A((fluid )?ounces?|oz)\Z/, :abbreviation => "fl oz")
|
109
|
+
# register :ounce, :conversion => [28.4130625, :milliliter], :detector => /\A(imperial\s(fluid )?imp\.\sounces?|imp\.\soz)\Z/, :abbreviation => "imp. oz"
|
110
|
+
# register :gill, :conversion => [5, :ounce], :detector => /\A(gills?|gi)\Z/, :abbreviation => "gi"
|
111
|
+
# register :cup, :conversion => [2, :gill], :detector => /\A(cups?)\Z/, :abbreviation => "cp"
|
112
|
+
# register :pint, :conversion => [2, :cup], :detector => /\A(pints?|pt)\Z/, :abbreviation => "pt"
|
113
|
+
# register :quart, :conversion => [2, :pint], :detector => /\A(quarts?|qt)\Z/, :abbreviation => "qt"
|
114
|
+
# register :gallon, :conversion => [4, :quart], :detector => /\A(gallons?|gal)\Z/, :abbreviation => "gal"
|
115
|
+
end
|
116
|
+
system(:US) do
|
117
|
+
# # Common US Customary units for volume, based on the SI Base Unit 'liter'
|
118
|
+
# register :minim, :conversion => [0.00006161152, :liter], :abbreviation => "min" # Base Unit
|
119
|
+
# register :dram, :conversion => [60, :minim], :abbreviation => "fl dr"
|
120
|
+
# register :ounce, :conversion => [8, :dram], :detector => /\A((fluid )?ounces?|oz)\Z/, :abbreviation => "fl oz"
|
121
|
+
# register :gill, :conversion => [4, :ounce], :detector => /\A(gills?|gi)\Z/, :abbreviation => "gi"
|
122
|
+
# register :cup, :conversion => [2, :gill], :detector => /\A(cups?)\Z/, :abbreviation => "cp"
|
123
|
+
# register :pint, :conversion => [2, :cup], :detector => /\A(pints?|pt)\Z/, :abbreviation => "pt"
|
124
|
+
# register :quart, :conversion => [2, :pint], :detector => /\A(quarts?|qt)\Z/, :abbreviation => "qt"
|
125
|
+
# register :gallon, :conversion => [4, :quart], :detector => /\A(gallons?|gal)\Z/, :abbreviation => "gal"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
dimension(nil) do
|
130
|
+
system(:US) do
|
131
|
+
base('each', :detector => /\Aea(ch)?\Z/, :abbreviation => 'ea') do
|
132
|
+
derive('pair', 2, :detector => /\A(pr|pair)\Z/, :abbreviation => 'pr')
|
133
|
+
derive('dozen', 12, :detector => /\A(dz|dozen)\Z/, :abbreviation => 'dz') do
|
134
|
+
derive('gross', 12)
|
135
|
+
end
|
136
|
+
derive('score', 20)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'dimensional/dimension'
|
3
|
+
|
4
|
+
class DimensionTest < Test::Unit::TestCase
|
5
|
+
include Dimensional
|
6
|
+
|
7
|
+
def teardown
|
8
|
+
Dimension.reset!
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_create_new_fundamental_dimension
|
12
|
+
assert_instance_of Dimension, d = Dimension.new('Mass')
|
13
|
+
assert d.fundamental?
|
14
|
+
assert_equal 'Mass', d.name
|
15
|
+
assert_equal 'M', d.symbol
|
16
|
+
assert_equal Hash.new, d.exponents
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_create_new_composite_dimension
|
20
|
+
l = Dimension.new('Length')
|
21
|
+
assert_instance_of Dimension, a = Dimension.new('Hyperspace', 'H4', {l => 4})
|
22
|
+
assert !a.fundamental?
|
23
|
+
assert a.exponents.has_key?(l)
|
24
|
+
assert_equal 4, a.exponents[l]
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_register_new_dimension
|
28
|
+
assert d = Dimension.register('Length')
|
29
|
+
assert_instance_of Dimension, d
|
30
|
+
assert_same d, Dimension['Length']
|
31
|
+
assert_same d, Dimension['L']
|
32
|
+
assert defined?(Dimension::L)
|
33
|
+
assert_same d, Dimension::L
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_register_new_dimension_with_alternate_symbol
|
37
|
+
assert d = Dimension.register('Electric Charge', 'Q')
|
38
|
+
assert_instance_of Dimension, d
|
39
|
+
assert_same d, Dimension['Electric Charge']
|
40
|
+
assert_same d, Dimension['Q']
|
41
|
+
assert defined?(Dimension::Q)
|
42
|
+
assert_same d, Dimension::Q
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_register_new_dimension_with_symbol_that_is_not_a_valid_constant
|
46
|
+
assert d = Dimension.register('Temperature', 'Θ')
|
47
|
+
assert_instance_of Dimension, d
|
48
|
+
assert_same d, Dimension['Temperature']
|
49
|
+
assert_same d, Dimension['Θ']
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_return_nil_on_nil_lookup
|
53
|
+
assert_nil Dimension[nil]
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'dimensional'
|
3
|
+
|
4
|
+
class DimensionalTest < Test::Unit::TestCase
|
5
|
+
include Dimensional
|
6
|
+
|
7
|
+
def setup
|
8
|
+
load 'test/demo.rb'
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
Dimension.reset!
|
13
|
+
System.reset!
|
14
|
+
Unit.reset!
|
15
|
+
Metric.reset!
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_a_lot
|
19
|
+
100.times do
|
20
|
+
assert m0 = Measure.parse("1 acre", Metric[:forestry])
|
21
|
+
assert u2 = Unit[:A, :SI, 'hectare']
|
22
|
+
assert m2 = m0.convert(u2)
|
23
|
+
assert_in_delta 0.40468564224, m2, 0.00001
|
24
|
+
assert_equal "0.4047ha", m2.to_s
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|