dimensional 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,185 @@
1
+ require 'test/unit'
2
+ require 'dimensional/measure'
3
+ require 'dimensional/configurator'
4
+ require 'rational'
5
+
6
+ class MeasureTest < Test::Unit::TestCase
7
+ include Dimensional
8
+
9
+ def setup
10
+ System.register('International System of Units', 'SI')
11
+ System.register('United States Customary Units', 'US')
12
+ System.register('British Admiralty', 'BA')
13
+
14
+ Dimension.register('Length')
15
+ Dimension.register('Mass')
16
+
17
+ Metric.register('length', :L)
18
+
19
+ Configurator.start do
20
+ dimension(:L) do
21
+ system(:SI) do
22
+ base('meter', :detector => /\A(meters?|m)\Z/, :abbreviation => 'm') do
23
+ prefer(:length_over_all, :precision => 0.01)
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', 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(:length_over_all, :precision => Rational(1, 12))
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
+ system(:BA) do
40
+ base('mile', :detector => /\A(miles?|nm|nmi)\Z/, :abbreviation => 'nm') do
41
+ prefer(:distance, :precision => -2)
42
+ derive('cable', Rational(1,10), :detector => /\A(cables?|cbls?)\Z/) do
43
+ derive('fathom', Rational(1,10), :detector => /\A(fathoms?|fms?)\Z/, :abbreviation => 'fm') do
44
+ derive('yard', Rational(1,6), :detector => /\A(yards?|yds?)\Z/, :abbreviation => 'yd') do
45
+ derive('foot', Rational(1,3), :detector => /\A(foot|feet|ft|')\Z/, :abbreviation => "ft") do
46
+ prefer(:length_over_all, :precision => Rational(1, 12))
47
+ derive('inch', Rational(1,12), :detector => /\A(inch|inches|in|")\Z/, :abbreviation => "in")
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ dimension(:M) do
56
+ system(:SI) do
57
+ base('kilogram', :detector => /\A(kilograms?|kg)\Z/, :abbreviation => 'kg') do
58
+ derive('tonne', 1000, :detector => /\A(tonnes?)\Z/, :abbreviation => 't') # metric ton
59
+ derive('gram', Rational(1, 1000), :detector => /\A(grams?|g)\Z/, :abbreviation => 'g')
60
+ end
61
+ end
62
+ end
63
+ # Dimensionless Units
64
+ base('each', :abbreviation => 'ea') do
65
+ derive('dozen', 12, :abbreviation => 'dz')
66
+ end
67
+ end
68
+ end
69
+
70
+ def teardown
71
+ Dimension.reset!
72
+ System.reset!
73
+ Unit.reset!
74
+ Metric.reset!
75
+ end
76
+
77
+ def test_create_new_measure
78
+ u = Unit[:L, :BA, 'mile']
79
+ assert m = Measure.new(3000, u, :length)
80
+ assert_equal 3000, m
81
+ assert_equal u, m.unit
82
+ assert_same Metric[:length], m.metric
83
+ end
84
+
85
+ def test_to_f
86
+ d = Measure.parse("1.85m", :L, :SI)
87
+ assert_instance_of Float, d.to_f
88
+ end
89
+
90
+ def test_to_i
91
+ d = Measure.parse("1 each", Metric[nil])
92
+ assert_instance_of Fixnum, d.to_i
93
+ end
94
+
95
+ def test_to_native
96
+ d = Measure.parse("1 each", Metric[nil])
97
+ assert_instance_of Fixnum, d.native
98
+ end
99
+
100
+ def test_convert
101
+ old_unit = Unit[:L, :BA, 'cable']
102
+ new_unit = Unit[:L, :BA, 'fathom']
103
+ new = Measure.new(1, old_unit).convert(new_unit)
104
+ assert_in_delta(10, new, 0.000001)
105
+ assert_same new_unit, new.unit
106
+ end
107
+
108
+ def test_do_identity_conversion
109
+ old_unit = Unit[:L, :BA, 'cable']
110
+ new_unit = old_unit
111
+ old_value = Measure.new(12, old_unit)
112
+ new_value = old_value.convert(new_unit)
113
+ assert_equal old_value, new_value
114
+ end
115
+
116
+ def test_return_base
117
+ u = Unit[:L, :BA, 'fathom']
118
+ b = Measure.new(1, u).base
119
+ assert_in_delta(1e-2, b, 0.000001)
120
+ assert_same u.base, b.unit
121
+ end
122
+
123
+ def test_parse
124
+ assert m = Measure.parse("15'", :L, :BA)
125
+ assert_same Unit[:L, :BA, 'foot'], m.unit
126
+ assert_equal 15, m
127
+ end
128
+
129
+ def test_parse_with_whitespace
130
+ m = Measure.parse("15 feet", :L, :BA)
131
+ assert_same Unit[:L, :BA, 'foot'], m.unit
132
+ assert_equal 15, m
133
+ end
134
+
135
+ def test_parse_compound
136
+ d = Measure.parse("15'11\"", :L, :US)
137
+ assert_in_delta(15 + Rational(11, 12), d, 0.000001)
138
+ end
139
+
140
+ def test_parse_compound_with_whitespace
141
+ d = Measure.parse("1 foot 11 inches", :L, :US)
142
+ assert_same d.unit, Unit[:L, :US, 'foot']
143
+ assert_in_delta(1 + Rational(11, 12).to_f, d, 0.000001)
144
+ end
145
+
146
+ def test_raise_on_parse_of_mixed_compound
147
+ assert_raises ArgumentError do
148
+ Measure.parse("1 foot 11cm", :L)
149
+ end
150
+ end
151
+
152
+ def test_parse_with_default_unit
153
+ metric = Metric[:L]
154
+ du = metric.units.first
155
+ assert_instance_of Measure, m = Measure.parse("10", :L)
156
+ assert_equal du, m.unit
157
+ end
158
+
159
+ def test_parse_dimensionless_units
160
+ assert m = Measure.parse('2 dozen', nil)
161
+ assert_instance_of Measure, m
162
+ assert_equal 2, m
163
+ assert_equal Unit[nil, nil, 'dozen'], m.unit
164
+ assert_equal 12, m.unit.factor
165
+ assert_nil m.unit.dimension
166
+ end
167
+
168
+ def test_stringify_with_abbreviation
169
+ assert_equal "1.85nm", Measure.parse('1.85 miles', :L, :BA).to_s
170
+ end
171
+
172
+ def test_parse_gibberish_as_nil
173
+ assert_nil Measure.parse("gibberish", :L)
174
+ end
175
+
176
+ def test_format_output
177
+ m = Measure.parse("15'3\"", :L, :BA)
178
+ assert_equal "15.25 (ft)", m.strfmeasure("%4.2f (%U)")
179
+ end
180
+
181
+ def test_precision_recognition
182
+ assert_equal "1.8600nm", Measure.parse('1.8565454 miles', :distance, :BA).strfmeasure("%.4f%U")
183
+ assert_equal "1.86", Measure.parse('1.8565454 miles', :distance, :BA).strfmeasure("%s")
184
+ end
185
+ end
@@ -0,0 +1,90 @@
1
+ require 'test/unit'
2
+ require 'dimensional/metric'
3
+ require 'dimensional/unit'
4
+ require 'rational'
5
+
6
+ class MetricTest < Test::Unit::TestCase
7
+ include Dimensional
8
+
9
+ def setup
10
+ Dimension.register('Length')
11
+ Dimension.register('Mass')
12
+ Dimension.register('Force')
13
+ System.register('British Admiralty', 'BA')
14
+ System.register('United States Customary', 'US')
15
+ cable = Unit.register('cable', System::BA, Dimension::L, {})
16
+ fathom = Unit.register('fathom', System::BA, Dimension::L, {:reference_unit => cable, :reference_factor => Rational(1,10)})
17
+ yard = Unit.register('yard', System::BA, Dimension::L, {:reference_unit => fathom, :reference_factor => Rational(1,6)})
18
+ Unit.register('foot', System::BA, Dimension::L, {:reference_unit => yard, :reference_factor => Rational(1,3)})
19
+ Unit.register('foot', System::US, Dimension::L, {:reference_unit => yard, :reference_factor => Rational(1,3)})
20
+ Unit.register('pound', System::US, Dimension::M)
21
+ Unit.register('pound', System::US, Dimension::F)
22
+ end
23
+
24
+ def teardown
25
+ Dimension.reset!
26
+ System.reset!
27
+ Unit.reset!
28
+ Metric.reset!
29
+ end
30
+
31
+ def test_create
32
+ assert_instance_of Metric, m = Metric.new('draft', Dimension::L)
33
+ assert_same Dimension::L, m.dimension
34
+ assert_equal 'draft', m.name
35
+ end
36
+
37
+ def test_register
38
+ assert_instance_of Metric, m = Metric.register('draft', Dimension::L)
39
+ assert_same m, Metric[:draft]
40
+ end
41
+
42
+ def test_register_metric_with_parent
43
+ parent = Metric.register('L', Dimension::L)
44
+ child = Metric.register('depth', nil, parent)
45
+ assert_same parent, child.parent
46
+ end
47
+
48
+ def test_register_dimensionless_metric
49
+ assert_instance_of Metric, m = Metric.register('population', nil)
50
+ assert_same m, Metric[:population]
51
+ end
52
+
53
+ def test_register_default_dimensionless_metric
54
+ assert_instance_of Metric, m = Metric.register(nil, nil)
55
+ assert_same m, Metric[nil]
56
+ end
57
+
58
+ def test_unit_preferences
59
+ length = Metric.register('L', Dimension::L)
60
+ draft = Metric.register('draft', Dimension::L, length)
61
+ foot = Unit[Dimension::L, System::BA, 'foot']
62
+ length.prefer(foot, {:detector => /(foot|ft)?s/})
63
+ draft.prefer(foot, {:precision => Rational(1, 12)})
64
+ assert_instance_of Hash, draft.preferences(foot)
65
+ assert_equal Rational(1,12), draft.preferences(foot)[:precision]
66
+ assert_equal /(foot|ft)?s/, draft.preferences(foot)[:detector]
67
+ end
68
+
69
+ def test_unit_membership
70
+ length = Metric.register('L', Dimension::L)
71
+ mass = Metric.register('M', Dimension::M)
72
+ depth = Metric.register('depth', Dimension::L, length)
73
+ foot = Unit[:L, :BA, 'foot']
74
+ fathom = Unit[:L, :BA, 'fathom']
75
+ pound = Unit[:M, :US, 'pound']
76
+ length.prefer(foot)
77
+ length.prefer(fathom)
78
+ depth.prefer(fathom)
79
+ mass.prefer(pound)
80
+ assert_same fathom, depth.units.first # Units should be ordered with preferred units first...
81
+ assert_same foot, depth.units.last # ...followed by remaining units from parent.
82
+ assert_equal 2, depth.units.size # Units should be de-duped with parent
83
+ end
84
+
85
+ def test_enumerate
86
+ length = Metric.register('L', Dimension::L)
87
+ assert length.to_enum.kind_of?(Enumerable::Enumerator)
88
+ assert_respond_to length, :map
89
+ end
90
+ end
@@ -0,0 +1,40 @@
1
+ require 'test/unit'
2
+ require 'dimensional/system'
3
+
4
+ class SystemTest < Test::Unit::TestCase
5
+ include Dimensional
6
+
7
+ def teardown
8
+ System.reset!
9
+ end
10
+
11
+ def test_create_new_measurement_system
12
+ assert_instance_of System, s = System.new('British Admiralty')
13
+ assert_equal 'British Admiralty', s.name
14
+ assert_nil s.abbreviation
15
+ end
16
+
17
+ def test_create_new_measurement_system_with_abbreviation
18
+ assert_instance_of System, s = System.new('British Admiralty', 'BA')
19
+ assert_equal 'British Admiralty', s.name
20
+ assert_equal 'BA', s.abbreviation
21
+ end
22
+
23
+ def test_register_new_measurement_system
24
+ assert_instance_of System, s = System.register('British Admiralty')
25
+ assert_same s, System['British Admiralty']
26
+ end
27
+
28
+ def test_register_new_measurement_system_with_abbreviation
29
+ assert_instance_of System, s = System.register('British Admiralty', 'BA')
30
+ assert_same s, System['BA']
31
+ assert defined?(System::BA)
32
+ assert_same s, System::BA
33
+ end
34
+
35
+ def test_not_raise_exception_when_system_not_found
36
+ assert_nothing_raised do
37
+ System['British Admiralty']
38
+ end
39
+ end
40
+ end
data/test/unit_test.rb ADDED
@@ -0,0 +1,102 @@
1
+ require 'test/unit'
2
+ require 'dimensional/unit'
3
+
4
+ class UnitTest < Test::Unit::TestCase
5
+ include Dimensional
6
+
7
+ def setup
8
+ System.register('International System of Units', 'SI')
9
+ System.register('United States Customary', 'US')
10
+ System.register('British Admiralty', 'BA')
11
+ Dimension.register('Length')
12
+ Dimension.register('Mass')
13
+ Dimension.register('Force')
14
+ end
15
+
16
+ def teardown
17
+ Dimension.reset!
18
+ System.reset!
19
+ Unit.reset!
20
+ end
21
+
22
+ def test_create_new_base_unit
23
+ assert_instance_of Unit, u = Unit.new('cable', System::BA, Dimension::L, {})
24
+ assert_same System::BA, u.system
25
+ assert_same Dimension::L, u.dimension
26
+ assert u.base?
27
+ assert_same u, u.base
28
+ assert_same 1, u.factor
29
+ end
30
+
31
+ def test_create_new_dimensionless_unit
32
+ assert_instance_of Unit, u = Unit.new('each', System::BA, nil, {})
33
+ assert_nil u.dimension
34
+ end
35
+
36
+ def test_create_new_derived_unit
37
+ cable = Unit.new('cable', System::BA, Dimension::L, {})
38
+ assert_instance_of Unit, u = Unit.new('fathom', System['BA'], Dimension['L'], :reference_factor => 1E-1, :reference_unit => cable)
39
+ assert !u.base?
40
+ assert_same cable, u.base
41
+ assert_equal 1E-1, u.factor
42
+ end
43
+
44
+ def test_create_new_combined_unit
45
+ meter = Unit.new('meter', System::SI, Dimension::L, {})
46
+ assert_instance_of Unit, u = Unit.new('square meter', System::SI, Dimension::L, :reference_factor => 1, :reference_unit => [meter, meter])
47
+ assert !u.base?
48
+ assert_equal [meter, meter], u.base
49
+ assert_equal 1, u.factor
50
+ end
51
+
52
+ def test_regsiter_new_unit
53
+ assert_instance_of Unit, u = Unit.register('fathom', System::BA, Dimension::L, {:abbreviation => 'fm'})
54
+ assert_same u, Unit[Dimension::L, System::BA, 'fathom']
55
+ assert_same u, Unit[Dimension::L, System::BA, 'fm']
56
+ end
57
+
58
+ def test_regsiter_new_dimensionless_unit
59
+ assert_instance_of Unit, u = Unit.register('each', System::BA, nil, {:abbreviation => 'ea'})
60
+ assert_same u, Unit[nil, System::BA, 'each']
61
+ assert_same u, Unit[nil, System::BA, 'ea']
62
+ end
63
+
64
+ def test_lookup_unit_with_symbols
65
+ u = Unit.register('fathom', System::BA, Dimension::L, {:abbreviation => 'fm'})
66
+ assert_nil Unit[:L, :SI, 'fathom']
67
+ assert_nil Unit[:M, :BA, 'fathom']
68
+ assert_nil Unit[:L, :BA, 'somethingelse']
69
+ assert_same u, Unit[:L, :BA, 'fathom']
70
+ end
71
+
72
+ def test_convert
73
+ cable = Unit.new('cable', System::BA, Dimension::L, {})
74
+ fathom = Unit.new('fathom', System::BA, Dimension::L, :reference_factor => 1E-1, :reference_unit => cable)
75
+ assert_equal 10, cable.convert(fathom)
76
+ assert_equal 1E-1, fathom.convert(cable)
77
+ assert_equal 1, fathom.convert(fathom)
78
+ end
79
+
80
+ def test_match_per_unit
81
+ u = Unit.new('mile', System::BA, Dimension::L, :detector => /\A(nm|nmi)\Z/)
82
+ md = u.match('nmi')
83
+ assert_instance_of MatchData, md
84
+ assert_equal 'nmi', md[0]
85
+ end
86
+
87
+ def test_identify_commensurable_units
88
+ u0 = Unit.new('mile', System::BA, Dimension::L, :detector => /\A(nm|nmi)\Z/, :abbreviation => 'nm')
89
+ u1 = Unit.new('cable', System::BA, Dimension::L, :detector => /\A(cables?|cbls?)\Z/, :reference_factor => 1E-1, :reference_unit => u0)
90
+ u2 = Unit.new('ton', System::BA, Dimension::M, :abbreviation => 't')
91
+ assert u0.commensurable?(u1)
92
+ assert !u0.commensurable?(u2)
93
+ end
94
+
95
+ def test_identify_commensurable_composed_units
96
+ u0 = Unit.new('mile', System::BA, Dimension::L, :detector => /\A(nm|nmi)\Z/, :abbreviation => 'nm')
97
+ u1 = Unit.new('cable', System::BA, Dimension::L, :detector => /\A(cables?|cbls?)\Z/, :reference_factor => 1E-1, :reference_unit => u0)
98
+ u2 = Unit.new('ton', System::BA, Dimension::M, :abbreviation => 't')
99
+ assert u0.commensurable?(u1)
100
+ assert !u0.commensurable?(u2)
101
+ end
102
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dimensional
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Chris Hapgood
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-09 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: " Dimensional provides handling for dimensional values (numbers with units). Dimensional values\n can be parsed, stored, converted and formatted for output.\n"
17
+ email: cch1@hapgoods.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/dimensional/configurator.rb
26
+ - lib/dimensional/dimension.rb
27
+ - lib/dimensional/measure.rb
28
+ - lib/dimensional/metric.rb
29
+ - lib/dimensional/system.rb
30
+ - lib/dimensional/unit.rb
31
+ - lib/dimensional.rb
32
+ - test/configurator_test.rb
33
+ - test/demo.rb
34
+ - test/dimension_test.rb
35
+ - test/dimensional_test.rb
36
+ - test/measure_test.rb
37
+ - test/metric_test.rb
38
+ - test/system_test.rb
39
+ - test/unit_test.rb
40
+ - README
41
+ - CHANGELOG
42
+ - LICENSE
43
+ - Rakefile
44
+ has_rdoc: true
45
+ homepage: http://cho.hapgoods.com/dimensional
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options: []
50
+
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: 1.6.8
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project:
68
+ rubygems_version: 1.3.5
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Dimensional provides handling for numbers with units.
72
+ test_files:
73
+ - test/configurator_test.rb
74
+ - test/demo.rb
75
+ - test/dimension_test.rb
76
+ - test/dimensional_test.rb
77
+ - test/measure_test.rb
78
+ - test/metric_test.rb
79
+ - test/system_test.rb
80
+ - test/unit_test.rb