auom 0.1.0 → 0.2.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.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/.rubocop.yml +2 -6
- data/.travis.yml +5 -2
- data/Changelog.md +5 -1
- data/Gemfile +0 -5
- data/README.md +17 -22
- data/TODO +1 -1
- data/auom.gemspec +14 -14
- data/circle.yml +3 -0
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/reek.yml +2 -1
- data/config/rubocop.yml +130 -34
- data/lib/auom.rb +0 -2
- data/lib/auom/algebra.rb +5 -7
- data/lib/auom/equalization.rb +0 -2
- data/lib/auom/inspection.rb +26 -23
- data/lib/auom/relational.rb +2 -4
- data/lib/auom/unit.rb +15 -17
- data/spec/shared/incompatible_operation_behavior.rb +0 -2
- data/spec/shared/operation_behavior.rb +5 -4
- data/spec/shared/sunits_shared.rb +0 -2
- data/spec/spec_helper.rb +1 -4
- data/spec/unit/auom/algebra/add_spec.rb +12 -16
- data/spec/unit/auom/algebra/divide_spec.rb +50 -52
- data/spec/unit/auom/algebra/multiply_spec.rb +17 -21
- data/spec/unit/auom/algebra/substract_spec.rb +4 -8
- data/spec/unit/auom/equalization/equality_operator_spec.rb +3 -7
- data/spec/unit/auom/inspection/class_methods/prettify_unit_part_spec.rb +7 -7
- data/spec/unit/auom/inspection/inspect_spec.rb +1 -5
- data/spec/unit/auom/relational/greater_than_or_equal_to_predicate_spec.rb +0 -4
- data/spec/unit/auom/relational/greater_than_predicate_spec.rb +0 -4
- data/spec/unit/auom/relational/less_than_or_equal_to_predicate_spec.rb +0 -4
- data/spec/unit/auom/relational/less_than_predicate_spec.rb +0 -4
- data/spec/unit/auom/unit/assert_same_unit_spec.rb +2 -6
- data/spec/unit/auom/unit/class_methods/convert_spec.rb +0 -4
- data/spec/unit/auom/unit/class_methods/lookup_spec.rb +2 -6
- data/spec/unit/auom/unit/class_methods/new_spec.rb +16 -21
- data/spec/unit/auom/unit/class_methods/try_convert_spec.rb +0 -4
- data/spec/unit/auom/unit/class_methods/units_spec.rb +0 -4
- data/spec/unit/auom/unit/denominators_spec.rb +0 -4
- data/spec/unit/auom/unit/numerators_spec.rb +0 -4
- data/spec/unit/auom/unit/same_unit_predicate_spec.rb +1 -5
- data/spec/unit/auom/unit/scalar_spec.rb +0 -4
- data/spec/unit/auom/unit/unit_spec.rb +0 -4
- data/spec/unit/auom/unit/unitless_predicate_spec.rb +0 -4
- metadata +29 -22
- data/Gemfile.devtools +0 -71
- data/Guardfile +0 -8
data/lib/auom/equalization.rb
CHANGED
data/lib/auom/inspection.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
1
|
module AUOM
|
4
2
|
# Inspection module for auom units
|
5
3
|
module Inspection
|
4
|
+
|
5
|
+
INSPECT_FORMAT = '<%s @scalar=%s%s>'.freeze
|
6
|
+
SCALAR_FORMAT = '~%0.4f'.freeze
|
7
|
+
UNIT_FORMAT = ' %s/%s'.freeze
|
8
|
+
|
6
9
|
# Return inspectable representation
|
7
10
|
#
|
8
11
|
# @return [String]
|
@@ -10,12 +13,24 @@ module AUOM
|
|
10
13
|
# @api private
|
11
14
|
#
|
12
15
|
def inspect
|
13
|
-
|
16
|
+
format(INSPECT_FORMAT, self.class, pretty_scalar, pretty_unit)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return prettified units
|
20
|
+
#
|
21
|
+
# @param [Array] base
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
#
|
27
|
+
def self.prettify_unit_part(base)
|
28
|
+
counts(base).map { |unit, length| length > 1 ? "#{unit}^#{length}" : unit }.join('*')
|
14
29
|
end
|
15
30
|
|
16
31
|
private
|
17
32
|
|
18
|
-
# Return
|
33
|
+
# Return prettified scalar
|
19
34
|
#
|
20
35
|
# @return [String]
|
21
36
|
#
|
@@ -23,13 +38,13 @@ module AUOM
|
|
23
38
|
#
|
24
39
|
def pretty_scalar
|
25
40
|
if reminder?
|
26
|
-
|
41
|
+
format(SCALAR_FORMAT, scalar)
|
27
42
|
else
|
28
|
-
scalar.
|
43
|
+
scalar.to_int
|
29
44
|
end
|
30
45
|
end
|
31
46
|
|
32
|
-
# Return
|
47
|
+
# Return prettified unit part
|
33
48
|
#
|
34
49
|
# @return [String]
|
35
50
|
# if there is a prettifiable unit part
|
@@ -42,15 +57,15 @@ module AUOM
|
|
42
57
|
def pretty_unit
|
43
58
|
return if unitless?
|
44
59
|
|
45
|
-
numerator = Inspection.prettify_unit_part(
|
46
|
-
denominator = Inspection.prettify_unit_part(
|
60
|
+
numerator = Inspection.prettify_unit_part(numerators)
|
61
|
+
denominator = Inspection.prettify_unit_part(denominators)
|
47
62
|
|
48
63
|
numerator = '1' if numerator.empty?
|
49
64
|
if denominator.empty?
|
50
65
|
return " #{numerator}"
|
51
66
|
end
|
52
67
|
|
53
|
-
|
68
|
+
format(UNIT_FORMAT, numerator, denominator)
|
54
69
|
end
|
55
70
|
|
56
71
|
# Test if scalar has and reminder in decimal representation
|
@@ -67,18 +82,6 @@ module AUOM
|
|
67
82
|
!(scalar % scalar.denominator).zero?
|
68
83
|
end
|
69
84
|
|
70
|
-
# Return prettified units
|
71
|
-
#
|
72
|
-
# @param [Array] base
|
73
|
-
#
|
74
|
-
# @return [String]
|
75
|
-
#
|
76
|
-
# @api private
|
77
|
-
#
|
78
|
-
def self.prettify_unit_part(base)
|
79
|
-
counts(base).map { |unit, length| length > 1 ? "#{unit}^#{length}" : unit }.join('*')
|
80
|
-
end
|
81
|
-
|
82
85
|
# Return unit counts
|
83
86
|
#
|
84
87
|
# @param [Array] base
|
@@ -91,7 +94,7 @@ module AUOM
|
|
91
94
|
counts = base.each_with_object(Hash.new(0)) { |unit, hash| hash[unit] += 1 }
|
92
95
|
counts.sort do |left, right|
|
93
96
|
result = right.last <=> left.last
|
94
|
-
if result
|
97
|
+
if result.equal?(0)
|
95
98
|
left.first <=> right.first
|
96
99
|
else
|
97
100
|
result
|
data/lib/auom/relational.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
1
|
module AUOM
|
4
2
|
# Mixin to add relational operators
|
5
3
|
module Relational
|
@@ -21,7 +19,7 @@ module AUOM
|
|
21
19
|
end
|
22
20
|
alias_method :<=, :less_than_or_equal_to?
|
23
21
|
|
24
|
-
# Test if unit is greater than or equal
|
22
|
+
# Test if unit is greater than or equal to other
|
25
23
|
#
|
26
24
|
# @param [Unit] other
|
27
25
|
#
|
@@ -74,7 +72,7 @@ module AUOM
|
|
74
72
|
|
75
73
|
private
|
76
74
|
|
77
|
-
#
|
75
|
+
# Perform relational operation
|
78
76
|
#
|
79
77
|
# @param [Unit] other
|
80
78
|
# @param [Symbol] operation
|
data/lib/auom/unit.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
1
|
module AUOM
|
4
2
|
# A scalar with units
|
5
3
|
class Unit
|
@@ -43,7 +41,7 @@ module AUOM
|
|
43
41
|
#
|
44
42
|
# include AUOM
|
45
43
|
# m = Unit.new(1, :meter)
|
46
|
-
# m.
|
44
|
+
# m.denominators # => []
|
47
45
|
#
|
48
46
|
# @return [Rational]
|
49
47
|
#
|
@@ -78,7 +76,7 @@ module AUOM
|
|
78
76
|
kilometer: [1000, :meter]
|
79
77
|
}.freeze
|
80
78
|
|
81
|
-
# Return
|
79
|
+
# Return built-in units symbols
|
82
80
|
#
|
83
81
|
# @return [Hash]
|
84
82
|
#
|
@@ -115,7 +113,7 @@ module AUOM
|
|
115
113
|
# if units are the same
|
116
114
|
#
|
117
115
|
# @return [false]
|
118
|
-
#
|
116
|
+
# otherwise
|
119
117
|
#
|
120
118
|
# @example
|
121
119
|
#
|
@@ -132,7 +130,7 @@ module AUOM
|
|
132
130
|
other.unit.eql?(unit)
|
133
131
|
end
|
134
132
|
|
135
|
-
#
|
133
|
+
# Instantiate a new unit
|
136
134
|
#
|
137
135
|
# @param [Rational] scalar
|
138
136
|
# @param [Enumerable] numerators
|
@@ -161,7 +159,7 @@ module AUOM
|
|
161
159
|
# # A complex unit
|
162
160
|
# u = Unit.new(Rational(1, 3), :euro, :meter)
|
163
161
|
# u.fractions? # => true
|
164
|
-
# u.
|
162
|
+
# u.scalar # => Rational(1, 3)
|
165
163
|
# u.inspect # => <AUOM::Unit @scalar=~0.3333 euro/meter>
|
166
164
|
# u.unit # => [[:euro], [:meter]]
|
167
165
|
#
|
@@ -189,7 +187,7 @@ module AUOM
|
|
189
187
|
#
|
190
188
|
def assert_same_unit(other)
|
191
189
|
unless same_unit?(other)
|
192
|
-
|
190
|
+
fail ArgumentError, 'Incompatible units'
|
193
191
|
end
|
194
192
|
|
195
193
|
self
|
@@ -209,7 +207,7 @@ module AUOM
|
|
209
207
|
def self.convert(operand)
|
210
208
|
converted = try_convert(operand)
|
211
209
|
unless converted
|
212
|
-
|
210
|
+
fail ArgumentError, "Cannot convert #{operand.inspect} to #{self}"
|
213
211
|
end
|
214
212
|
converted
|
215
213
|
end
|
@@ -230,7 +228,7 @@ module AUOM
|
|
230
228
|
case operand
|
231
229
|
when self
|
232
230
|
operand
|
233
|
-
when
|
231
|
+
when Integer, Rational
|
234
232
|
new(operand)
|
235
233
|
end
|
236
234
|
end
|
@@ -252,18 +250,18 @@ module AUOM
|
|
252
250
|
left.delete_if { |item| right.delete_at(right.index(item) || right.length) }
|
253
251
|
end
|
254
252
|
|
255
|
-
@numerators
|
253
|
+
@numerators = numerators.freeze
|
256
254
|
@denominators = denominators.freeze
|
257
255
|
|
258
|
-
@unit = [
|
259
|
-
|
256
|
+
@unit = [numerators, denominators].freeze
|
257
|
+
scalar.freeze
|
260
258
|
end
|
261
259
|
|
262
260
|
# Return rational converted from value
|
263
261
|
#
|
264
262
|
# @param [Object] value
|
265
263
|
#
|
266
|
-
# @return [
|
264
|
+
# @return [Rational]
|
267
265
|
#
|
268
266
|
# @raise [ArgumentError]
|
269
267
|
# raises argument error when cannot be converted to a rational
|
@@ -274,10 +272,10 @@ module AUOM
|
|
274
272
|
case value
|
275
273
|
when Rational
|
276
274
|
value
|
277
|
-
when
|
275
|
+
when Integer
|
278
276
|
Rational(value)
|
279
277
|
else
|
280
|
-
|
278
|
+
fail ArgumentError, "#{value.inspect} cannot be converted to rational"
|
281
279
|
end
|
282
280
|
end
|
283
281
|
|
@@ -314,7 +312,7 @@ module AUOM
|
|
314
312
|
#
|
315
313
|
def self.lookup(value)
|
316
314
|
units.fetch(value) do
|
317
|
-
|
315
|
+
fail ArgumentError, "Unknown unit #{value.inspect}"
|
318
316
|
end
|
319
317
|
end
|
320
318
|
|
@@ -1,13 +1,14 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
1
|
shared_examples_for 'an operation' do
|
4
2
|
it 'returns a new object' do
|
5
|
-
object.
|
3
|
+
expect(object).to_not equal(subject)
|
6
4
|
end
|
7
5
|
|
8
6
|
it 'is idempotent on equivalency' do
|
9
7
|
first = subject
|
10
|
-
|
8
|
+
fail unless RSpec.configuration.threadsafe?
|
9
|
+
mutex = __memoized.instance_variable_get(:@mutex)
|
10
|
+
memoized = __memoized.instance_variable_get(:@memoized)
|
11
|
+
mutex.synchronize { memoized.delete(:subject) }
|
11
12
|
should eql(first)
|
12
13
|
end
|
13
14
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
1
|
describe AUOM::Algebra, '#add' do
|
6
2
|
subject { object.add(operand) }
|
7
3
|
|
@@ -10,22 +6,22 @@ describe AUOM::Algebra, '#add' do
|
|
10
6
|
context 'when unit is unitless' do
|
11
7
|
let(:arguments) { [1] }
|
12
8
|
|
13
|
-
context 'and operand is
|
14
|
-
let(:operand) {
|
9
|
+
context 'and operand is an Integer' do
|
10
|
+
let(:operand) { 2 }
|
15
11
|
|
16
12
|
it_should_behave_like 'an operation'
|
17
13
|
|
18
|
-
it { should eql(AUOM::Unit.new(
|
14
|
+
it { should eql(AUOM::Unit.new(3)) }
|
19
15
|
end
|
20
16
|
|
21
17
|
context 'and operand is a unitless unit' do
|
22
|
-
let(:operand) { AUOM::Unit.new(
|
18
|
+
let(:operand) { AUOM::Unit.new(2) }
|
23
19
|
|
24
|
-
it { should eql(AUOM::Unit.new(
|
20
|
+
it { should eql(AUOM::Unit.new(3)) }
|
25
21
|
end
|
26
22
|
|
27
23
|
context 'and operand is a unitful unit' do
|
28
|
-
let(:operand) { AUOM::Unit.new(
|
24
|
+
let(:operand) { AUOM::Unit.new(2, :meter) }
|
29
25
|
|
30
26
|
it_should_behave_like 'an incompatible operation'
|
31
27
|
end
|
@@ -34,28 +30,28 @@ describe AUOM::Algebra, '#add' do
|
|
34
30
|
context 'when unit is unitful' do
|
35
31
|
let(:arguments) { [1, :meter, :euro] }
|
36
32
|
|
37
|
-
context 'and operand is
|
38
|
-
let(:operand) {
|
33
|
+
context 'and operand is an Integer' do
|
34
|
+
let(:operand) { 2 }
|
39
35
|
|
40
36
|
it_should_behave_like 'an incompatible operation'
|
41
37
|
end
|
42
38
|
|
43
39
|
context 'and operand is a unitless unit' do
|
44
|
-
let(:operand) { AUOM::Unit.new(
|
40
|
+
let(:operand) { AUOM::Unit.new(2) }
|
45
41
|
|
46
42
|
it_should_behave_like 'an incompatible operation'
|
47
43
|
end
|
48
44
|
|
49
45
|
context 'and operand is a incompatible unit' do
|
50
|
-
let(:operand) { AUOM::Unit.new(
|
46
|
+
let(:operand) { AUOM::Unit.new(2, :euro) }
|
51
47
|
|
52
48
|
it_should_behave_like 'an incompatible operation'
|
53
49
|
end
|
54
50
|
|
55
51
|
context 'and operand is a compatible unit' do
|
56
|
-
let(:operand) { AUOM::Unit.new(
|
52
|
+
let(:operand) { AUOM::Unit.new(2, :meter, :euro) }
|
57
53
|
|
58
|
-
it { should eql(AUOM::Unit.new(
|
54
|
+
it { should eql(AUOM::Unit.new(3, :meter, :euro)) }
|
59
55
|
end
|
60
56
|
end
|
61
57
|
end
|
@@ -1,85 +1,83 @@
|
|
1
|
-
|
1
|
+
describe AUOM::Algebra do
|
2
|
+
describe '#divide' do
|
3
|
+
subject { object.divide(operand) }
|
2
4
|
|
3
|
-
|
5
|
+
let(:object) { AUOM::Unit.new(*arguments) }
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
+
context 'with unitless unit' do
|
8
|
+
let(:arguments) { [4] }
|
7
9
|
|
8
|
-
|
10
|
+
context 'when operand is a fixnum' do
|
11
|
+
let(:operand) { 2 }
|
9
12
|
|
10
|
-
|
11
|
-
let(:arguments) { [4] }
|
12
|
-
|
13
|
-
context 'when operand is a fixnum' do
|
14
|
-
let(:operand) { 2 }
|
15
|
-
|
16
|
-
it_should_behave_like 'an operation'
|
13
|
+
it_should_behave_like 'an operation'
|
17
14
|
|
18
|
-
|
19
|
-
|
15
|
+
it { should eql(AUOM::Unit.new(2)) }
|
16
|
+
end
|
20
17
|
|
21
|
-
|
22
|
-
|
18
|
+
context 'when operand is a unitless unit' do
|
19
|
+
let(:operand) { AUOM::Unit.new(2) }
|
23
20
|
|
24
|
-
|
21
|
+
it_should_behave_like 'an operation'
|
25
22
|
|
26
|
-
|
27
|
-
|
23
|
+
it { should eql(AUOM::Unit.new(2)) }
|
24
|
+
end
|
28
25
|
|
29
|
-
|
30
|
-
|
26
|
+
context 'when operand is a unitful unit' do
|
27
|
+
let(:operand) { AUOM::Unit.new(2, :meter) }
|
31
28
|
|
32
|
-
|
29
|
+
it_should_behave_like 'an operation'
|
33
30
|
|
34
|
-
|
31
|
+
it { should eql(AUOM::Unit.new(2, [], :meter)) }
|
32
|
+
end
|
35
33
|
end
|
36
|
-
end
|
37
34
|
|
38
|
-
|
39
|
-
|
35
|
+
context 'with unitful unit' do
|
36
|
+
let(:arguments) { [2, :meter] }
|
40
37
|
|
41
|
-
|
42
|
-
|
38
|
+
context 'when operand is a fixnum' do
|
39
|
+
let(:operand) { 1 }
|
43
40
|
|
44
|
-
|
41
|
+
it_should_behave_like 'an operation'
|
45
42
|
|
46
|
-
|
47
|
-
|
43
|
+
it { should eql(AUOM::Unit.new(2, :meter)) }
|
44
|
+
end
|
48
45
|
|
49
|
-
|
50
|
-
|
46
|
+
context 'when operand is a unitless unit' do
|
47
|
+
let(:operand) { AUOM::Unit.new(1) }
|
51
48
|
|
52
|
-
|
49
|
+
it_should_behave_like 'an operation'
|
53
50
|
|
54
|
-
|
55
|
-
|
51
|
+
it { should eql(AUOM::Unit.new(2, :meter)) }
|
52
|
+
end
|
56
53
|
|
57
|
-
|
54
|
+
context 'when operand is a unitful unit' do
|
58
55
|
|
59
|
-
|
60
|
-
|
56
|
+
context 'and units get added to denominator' do
|
57
|
+
let(:operand) { AUOM::Unit.new(1, :euro) }
|
61
58
|
|
62
|
-
|
59
|
+
it_should_behave_like 'an operation'
|
63
60
|
|
64
|
-
|
65
|
-
|
61
|
+
it { should eql(AUOM::Unit.new(2, :meter, :euro)) }
|
62
|
+
end
|
66
63
|
|
67
|
-
|
68
|
-
|
64
|
+
context 'and units get added to numerator' do
|
65
|
+
let(:operand) { AUOM::Unit.new(1, nil, :euro) }
|
69
66
|
|
70
|
-
|
67
|
+
it_should_behave_like 'an operation'
|
71
68
|
|
72
|
-
|
73
|
-
|
69
|
+
it { should eql(AUOM::Unit.new(2, %i[euro meter])) }
|
70
|
+
end
|
74
71
|
|
75
|
-
|
76
|
-
|
72
|
+
context 'and units cancel each other' do
|
73
|
+
let(:operand) { AUOM::Unit.new(1, :meter) }
|
77
74
|
|
78
|
-
|
75
|
+
it_should_behave_like 'an operation'
|
79
76
|
|
80
|
-
|
81
|
-
|
77
|
+
it { should eql(AUOM::Unit.new(2)) }
|
78
|
+
end
|
82
79
|
|
80
|
+
end
|
83
81
|
end
|
84
82
|
end
|
85
83
|
end
|