unitwise 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +6 -10
- data/CHANGELOG.md +18 -0
- data/Gemfile +2 -2
- data/README.md +33 -3
- data/data/base_unit.yaml +2 -2
- data/data/derived_unit.yaml +60 -22
- data/data/prefix.yaml +1 -1
- data/lib/unitwise.rb +13 -1
- data/lib/unitwise/atom.rb +31 -2
- data/lib/unitwise/errors.rb +5 -2
- data/lib/unitwise/expression/decomposer.rb +21 -9
- data/lib/unitwise/expression/matcher.rb +3 -8
- data/lib/unitwise/expression/parser.rb +11 -4
- data/lib/unitwise/version.rb +1 -1
- data/test/test_helper.rb +1 -2
- data/test/unitwise/atom_test.rb +38 -2
- data/test/unitwise/expression/matcher_test.rb +3 -3
- data/test/unitwise_test.rb +21 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb8605b862b95bff79423e03fabf502e89a39440
|
4
|
+
data.tar.gz: 83bf9041753023411557a9f9b22d84d6d61cecfc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c202998427bdbd04aef777b310afbca4bbfd1866bc2d5405054864f28b17d9e723ea0885eba6bed4ee981b9078ed99c3ab10c6f0f98ebc6ef73fe5eac94713d6
|
7
|
+
data.tar.gz: 806a06c5c4fcd80cd2ec3be0c6e723b2e7ce1b9b621340d9db194a782f08356594ea7816b8dec3d024245283404555559c5635b4c8fe05633a71aa0d043fd4e3
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.4.0
|
data/.travis.yml
CHANGED
@@ -3,18 +3,14 @@ cache: bundler
|
|
3
3
|
bundler_args: --without yard pry
|
4
4
|
sudo: false
|
5
5
|
rvm:
|
6
|
-
- 1.
|
7
|
-
- 2.
|
8
|
-
- 2.
|
9
|
-
- 2.
|
6
|
+
- 2.1.10
|
7
|
+
- 2.2.7
|
8
|
+
- 2.3.4
|
9
|
+
- 2.4.1
|
10
|
+
- jruby-9.1.8.0
|
10
11
|
- ruby-head
|
11
|
-
-
|
12
|
+
- jruby-head
|
12
13
|
matrix:
|
13
|
-
include:
|
14
|
-
- rvm: jruby-19mode
|
15
|
-
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
|
16
|
-
- rvm: jruby-head
|
17
|
-
env: JRUBY_OPTS="$JRUBY_OPTS --debug"
|
18
14
|
allow_failures:
|
19
15
|
- rvm: ruby-head
|
20
16
|
- rvm: jruby-head
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,24 @@ version 1.0.0.
|
|
5
5
|
|
6
6
|
Unitwise uses semantic versioning.
|
7
7
|
|
8
|
+
## Unreleased
|
9
|
+
|
10
|
+
## 2.1.0 - 2017-04-28
|
11
|
+
|
12
|
+
### Removed
|
13
|
+
|
14
|
+
- Support for Ruby MRI 1.9.3, MRI 2.0, and Rubinius
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
- `Unitwise.register` is a new method that allows user defined units
|
19
|
+
- Support for MRI 2.3 and 2.4
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
|
23
|
+
- Unit data refreshed from latest UCUM spec. Most notably, some metric atoms
|
24
|
+
names have seen case changes.
|
25
|
+
|
8
26
|
## 2.0.0 - 2015-09-13
|
9
27
|
|
10
28
|
### Fixed
|
data/Gemfile
CHANGED
@@ -2,9 +2,9 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
gem 'coveralls', '~> 0.7'
|
4
4
|
if RUBY_VERSION >= '2.2.0'
|
5
|
-
gem 'bigdecimal', '
|
5
|
+
gem 'bigdecimal', '>= 1.2.6', :platform => :mri
|
6
6
|
else
|
7
|
-
gem 'bigdecimal', '
|
7
|
+
gem 'bigdecimal', '<= 1.2.5', :platform => :mri
|
8
8
|
end
|
9
9
|
|
10
10
|
gemspec
|
data/README.md
CHANGED
@@ -237,17 +237,47 @@ Unitwise(1, "meter/s") # Does not work, mixed designations (name and primar
|
|
237
237
|
Unitwise(1, "meter") / Unitwise(1, "s") # Also works
|
238
238
|
```
|
239
239
|
|
240
|
+
|
241
|
+
### Adding custom units
|
242
|
+
|
243
|
+
While UCUM's list of units is rather exhaustive, there may still be occasions
|
244
|
+
where you need custom or uncommon measurements. You can add them yourself
|
245
|
+
with `Unitwise.register`, which will allow you to convert to or from the new
|
246
|
+
unit.
|
247
|
+
|
248
|
+
For example, if your app needed to pour "3 fingers" of bourbon, you could
|
249
|
+
register an atom for that:
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
Unitwise.register(
|
253
|
+
names: ["finger", "fingers"],
|
254
|
+
symbol: "🥃",
|
255
|
+
primary_code: "fng",
|
256
|
+
secondary_code: "fng",
|
257
|
+
scale: {
|
258
|
+
value: 1.0,
|
259
|
+
unit_code: '[foz_us]'
|
260
|
+
},
|
261
|
+
property: 'fluid volume'
|
262
|
+
)
|
263
|
+
|
264
|
+
Unitwise(1, "gallon").to_fingers
|
265
|
+
# => #<Unitwise::Measurement value=0.153721590464621430998E3 unit=fingers>
|
266
|
+
|
267
|
+
Unitwise(1, "🥃").to_cup
|
268
|
+
# => #<Unitwise::Measurement value=0.125 unit=cup>
|
269
|
+
```
|
270
|
+
|
240
271
|
## Supported Ruby Versions
|
241
272
|
|
242
273
|
This library aims to support and is tested against the following Ruby
|
243
274
|
implementations:
|
244
275
|
|
245
|
-
* Ruby 1.9.3
|
246
|
-
* Ruby 2.0.0
|
247
276
|
* Ruby 2.1
|
248
277
|
* Ruby 2.2
|
278
|
+
* Ruby 2.3
|
279
|
+
* Ruby 2.4
|
249
280
|
* [JRuby](http://jruby.org/)
|
250
|
-
* [Rubinius](http://rubini.us/)
|
251
281
|
|
252
282
|
If something doesn't work on one of these versions, it's a bug.
|
253
283
|
|
data/data/base_unit.yaml
CHANGED
@@ -23,13 +23,13 @@
|
|
23
23
|
:secondary_code: RAD
|
24
24
|
:property: plane angle
|
25
25
|
:dim: A
|
26
|
-
- :names:
|
26
|
+
- :names: kelvin
|
27
27
|
:symbol: K
|
28
28
|
:primary_code: K
|
29
29
|
:secondary_code: K
|
30
30
|
:property: temperature
|
31
31
|
:dim: C
|
32
|
-
- :names:
|
32
|
+
- :names: coulomb
|
33
33
|
:symbol: C
|
34
34
|
:primary_code: C
|
35
35
|
:secondary_code: C
|
data/data/derived_unit.yaml
CHANGED
@@ -24,7 +24,7 @@
|
|
24
24
|
:special: false
|
25
25
|
:arbitrary: false
|
26
26
|
- :names: the number pi
|
27
|
-
:symbol:
|
27
|
+
:symbol: π
|
28
28
|
:primary_code: "[pi]"
|
29
29
|
:secondary_code: "[PI]"
|
30
30
|
:scale:
|
@@ -119,7 +119,7 @@
|
|
119
119
|
:metric: true
|
120
120
|
:special: false
|
121
121
|
:arbitrary: false
|
122
|
-
- :names:
|
122
|
+
- :names: hertz
|
123
123
|
:symbol: Hz
|
124
124
|
:primary_code: Hz
|
125
125
|
:secondary_code: HZ
|
@@ -131,7 +131,7 @@
|
|
131
131
|
:metric: true
|
132
132
|
:special: false
|
133
133
|
:arbitrary: false
|
134
|
-
- :names:
|
134
|
+
- :names: newton
|
135
135
|
:symbol: N
|
136
136
|
:primary_code: N
|
137
137
|
:secondary_code: N
|
@@ -143,7 +143,7 @@
|
|
143
143
|
:metric: true
|
144
144
|
:special: false
|
145
145
|
:arbitrary: false
|
146
|
-
- :names:
|
146
|
+
- :names: pascal
|
147
147
|
:symbol: Pa
|
148
148
|
:primary_code: Pa
|
149
149
|
:secondary_code: PAL
|
@@ -155,7 +155,7 @@
|
|
155
155
|
:metric: true
|
156
156
|
:special: false
|
157
157
|
:arbitrary: false
|
158
|
-
- :names:
|
158
|
+
- :names: joule
|
159
159
|
:symbol: J
|
160
160
|
:primary_code: J
|
161
161
|
:secondary_code: J
|
@@ -167,7 +167,7 @@
|
|
167
167
|
:metric: true
|
168
168
|
:special: false
|
169
169
|
:arbitrary: false
|
170
|
-
- :names:
|
170
|
+
- :names: watt
|
171
171
|
:symbol: W
|
172
172
|
:primary_code: W
|
173
173
|
:secondary_code: W
|
@@ -179,7 +179,7 @@
|
|
179
179
|
:metric: true
|
180
180
|
:special: false
|
181
181
|
:arbitrary: false
|
182
|
-
- :names:
|
182
|
+
- :names: ampère
|
183
183
|
:symbol: A
|
184
184
|
:primary_code: A
|
185
185
|
:secondary_code: A
|
@@ -191,7 +191,7 @@
|
|
191
191
|
:metric: true
|
192
192
|
:special: false
|
193
193
|
:arbitrary: false
|
194
|
-
- :names:
|
194
|
+
- :names: volt
|
195
195
|
:symbol: V
|
196
196
|
:primary_code: V
|
197
197
|
:secondary_code: V
|
@@ -203,7 +203,7 @@
|
|
203
203
|
:metric: true
|
204
204
|
:special: false
|
205
205
|
:arbitrary: false
|
206
|
-
- :names:
|
206
|
+
- :names: farad
|
207
207
|
:symbol: F
|
208
208
|
:primary_code: F
|
209
209
|
:secondary_code: F
|
@@ -215,8 +215,8 @@
|
|
215
215
|
:metric: true
|
216
216
|
:special: false
|
217
217
|
:arbitrary: false
|
218
|
-
- :names:
|
219
|
-
:symbol:
|
218
|
+
- :names: ohm
|
219
|
+
:symbol: Ω
|
220
220
|
:primary_code: Ohm
|
221
221
|
:secondary_code: OHM
|
222
222
|
:scale:
|
@@ -227,7 +227,7 @@
|
|
227
227
|
:metric: true
|
228
228
|
:special: false
|
229
229
|
:arbitrary: false
|
230
|
-
- :names:
|
230
|
+
- :names: siemens
|
231
231
|
:symbol: S
|
232
232
|
:primary_code: S
|
233
233
|
:secondary_code: SIE
|
@@ -239,7 +239,7 @@
|
|
239
239
|
:metric: true
|
240
240
|
:special: false
|
241
241
|
:arbitrary: false
|
242
|
-
- :names:
|
242
|
+
- :names: weber
|
243
243
|
:symbol: Wb
|
244
244
|
:primary_code: Wb
|
245
245
|
:secondary_code: WB
|
@@ -264,7 +264,7 @@
|
|
264
264
|
:metric: true
|
265
265
|
:special: true
|
266
266
|
:arbitrary: false
|
267
|
-
- :names:
|
267
|
+
- :names: tesla
|
268
268
|
:symbol: T
|
269
269
|
:primary_code: T
|
270
270
|
:secondary_code: T
|
@@ -276,7 +276,7 @@
|
|
276
276
|
:metric: true
|
277
277
|
:special: false
|
278
278
|
:arbitrary: false
|
279
|
-
- :names:
|
279
|
+
- :names: henry
|
280
280
|
:symbol: H
|
281
281
|
:primary_code: H
|
282
282
|
:secondary_code: H
|
@@ -312,7 +312,7 @@
|
|
312
312
|
:metric: true
|
313
313
|
:special: false
|
314
314
|
:arbitrary: false
|
315
|
-
- :names:
|
315
|
+
- :names: becquerel
|
316
316
|
:symbol: Bq
|
317
317
|
:primary_code: Bq
|
318
318
|
:secondary_code: BQ
|
@@ -324,7 +324,7 @@
|
|
324
324
|
:metric: true
|
325
325
|
:special: false
|
326
326
|
:arbitrary: false
|
327
|
-
- :names:
|
327
|
+
- :names: gray
|
328
328
|
:symbol: Gy
|
329
329
|
:primary_code: Gy
|
330
330
|
:secondary_code: GY
|
@@ -336,7 +336,7 @@
|
|
336
336
|
:metric: true
|
337
337
|
:special: false
|
338
338
|
:arbitrary: false
|
339
|
-
- :names:
|
339
|
+
- :names: sievert
|
340
340
|
:symbol: Sv
|
341
341
|
:primary_code: Sv
|
342
342
|
:secondary_code: SV
|
@@ -666,7 +666,7 @@
|
|
666
666
|
:primary_code: "[h]"
|
667
667
|
:secondary_code: "[H]"
|
668
668
|
:scale:
|
669
|
-
:value: 6.6260755e-
|
669
|
+
:value: 6.6260755e-34
|
670
670
|
:unit_code: J.s
|
671
671
|
:classification: const
|
672
672
|
:property: action
|
@@ -1069,7 +1069,7 @@
|
|
1069
1069
|
:metric: false
|
1070
1070
|
:special: false
|
1071
1071
|
:arbitrary: false
|
1072
|
-
- :names:
|
1072
|
+
- :names: mile
|
1073
1073
|
:symbol: mi
|
1074
1074
|
:primary_code: "[mi_i]"
|
1075
1075
|
:secondary_code: "[MI_I]"
|
@@ -2244,6 +2244,19 @@
|
|
2244
2244
|
:metric: false
|
2245
2245
|
:special: false
|
2246
2246
|
:arbitrary: false
|
2247
|
+
- :names: degree Réaumur
|
2248
|
+
:symbol: "°Ré"
|
2249
|
+
:primary_code: "[degRe]"
|
2250
|
+
:secondary_code: "[degRe]"
|
2251
|
+
:scale:
|
2252
|
+
:function_code: degre
|
2253
|
+
:value: 5.0
|
2254
|
+
:unit_code: K/4
|
2255
|
+
:classification: heat
|
2256
|
+
:property: temperature
|
2257
|
+
:metric: false
|
2258
|
+
:special: true
|
2259
|
+
:arbitrary: false
|
2247
2260
|
- :names: calorie at 15 °C
|
2248
2261
|
:symbol: cal<sub>15°C</sub>
|
2249
2262
|
:primary_code: cal_[15]
|
@@ -3138,6 +3151,19 @@
|
|
3138
3151
|
:metric: false
|
3139
3152
|
:special: false
|
3140
3153
|
:arbitrary: true
|
3154
|
+
- :names: index of reactivity
|
3155
|
+
:symbol: IR
|
3156
|
+
:primary_code: "[IR]"
|
3157
|
+
:secondary_code: "[IR]"
|
3158
|
+
:scale:
|
3159
|
+
:value: 1.0
|
3160
|
+
:unit_code: '1'
|
3161
|
+
:classification: chemical
|
3162
|
+
:property: amount of an allergen callibrated through in-vivo testing using the Stallergenes®
|
3163
|
+
method.
|
3164
|
+
:metric: false
|
3165
|
+
:special: false
|
3166
|
+
:arbitrary: true
|
3141
3167
|
- :names: bioequivalent allergen unit
|
3142
3168
|
:symbol: BAU
|
3143
3169
|
:primary_code: "[BAU]"
|
@@ -3372,8 +3398,8 @@
|
|
3372
3398
|
:metric: true
|
3373
3399
|
:special: false
|
3374
3400
|
:arbitrary: false
|
3375
|
-
- :names:
|
3376
|
-
:symbol:
|
3401
|
+
- :names: Ångström
|
3402
|
+
:symbol: Å
|
3377
3403
|
:primary_code: Ao
|
3378
3404
|
:secondary_code: AO
|
3379
3405
|
:scale:
|
@@ -3491,6 +3517,18 @@
|
|
3491
3517
|
:metric: false
|
3492
3518
|
:special: false
|
3493
3519
|
:arbitrary: false
|
3520
|
+
- :names: meter per square seconds per square root of hertz
|
3521
|
+
:primary_code: "[m/s2/Hz^(1/2)]"
|
3522
|
+
:secondary_code: "[M/S2/HZ^(1/2)]"
|
3523
|
+
:scale:
|
3524
|
+
:function_code: sqrt
|
3525
|
+
:value: 1.0
|
3526
|
+
:unit_code: m2/s4/Hz
|
3527
|
+
:classification: misc
|
3528
|
+
:property: amplitude spectral density
|
3529
|
+
:metric: false
|
3530
|
+
:special: true
|
3531
|
+
:arbitrary: false
|
3494
3532
|
- :names: bit
|
3495
3533
|
:symbol: bit<sub>s</sub>
|
3496
3534
|
:primary_code: bit_s
|
data/data/prefix.yaml
CHANGED
data/lib/unitwise.rb
CHANGED
@@ -43,7 +43,19 @@ module Unitwise
|
|
43
43
|
false
|
44
44
|
end
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
|
+
# Add additional atoms. Useful for registering uncommon or custom units.
|
48
|
+
# @param properties [Hash] Properties of the atom
|
49
|
+
# @return [Unitwise::Atom] The newly created atom
|
50
|
+
# @raise [Unitwise::DefinitionError]
|
51
|
+
def self.register(atom_hash)
|
52
|
+
atom = Unitwise::Atom.new(atom_hash)
|
53
|
+
atom.validate!
|
54
|
+
Unitwise::Atom.all.push(atom)
|
55
|
+
Unitwise::Expression::Decomposer.send(:reset)
|
56
|
+
atom
|
57
|
+
end
|
58
|
+
|
47
59
|
# The system path for the installed gem
|
48
60
|
# @api private
|
49
61
|
def self.path
|
data/lib/unitwise/atom.rb
CHANGED
@@ -7,13 +7,13 @@ module Unitwise
|
|
7
7
|
include Compatible
|
8
8
|
|
9
9
|
class << self
|
10
|
-
# Array of hashes representing atom properties.
|
10
|
+
# Array of hashes representing default atom properties.
|
11
11
|
# @api private
|
12
12
|
def data
|
13
13
|
@data ||= data_files.map { |file| YAML.load(File.open file) }.flatten
|
14
14
|
end
|
15
15
|
|
16
|
-
# Data files containing atom data
|
16
|
+
# Data files containing default atom data
|
17
17
|
# @api private
|
18
18
|
def data_files
|
19
19
|
%w(base_unit derived_unit).map { |type| Unitwise.data_file type }
|
@@ -117,5 +117,34 @@ module Unitwise
|
|
117
117
|
base? ? [Term.new(:atom_code => primary_code)] : scale.root_terms
|
118
118
|
end
|
119
119
|
memoize :root_terms
|
120
|
+
|
121
|
+
|
122
|
+
# A basic validator for atoms. It checks for the bare minimum properties
|
123
|
+
# and that it's scalar and magnitude can be resolved. Note that this method
|
124
|
+
# requires the units it depends on to already exist, so it is not used
|
125
|
+
# when loading the initial data from UCUM.
|
126
|
+
# @return [true] returns true if the atom is valid
|
127
|
+
# @raise [Unitwise::DefinitionError]
|
128
|
+
def validate!
|
129
|
+
missing_properties = %i{primary_code names scale}.select do |prop|
|
130
|
+
val = liner_get(prop)
|
131
|
+
val.nil? || (val.respond_to?(:empty) && val.empty?)
|
132
|
+
end
|
133
|
+
|
134
|
+
if !missing_properties.empty?
|
135
|
+
missing_list = missing_properties.join(',')
|
136
|
+
raise Unitwise::DefinitionError,
|
137
|
+
"Atom has missing properties: #{missing_list}."
|
138
|
+
end
|
139
|
+
|
140
|
+
msg = "Atom definition could not be resolved. Ensure that it is a base " \
|
141
|
+
"unit or is defined relative to existing units."
|
142
|
+
|
143
|
+
begin
|
144
|
+
!scalar.nil? && !magnitude.nil? || raise(Unitwise::DefinitionError, msg)
|
145
|
+
rescue Unitwise::ExpressionError
|
146
|
+
raise Unitwise::DefinitionError, msg
|
147
|
+
end
|
148
|
+
end
|
120
149
|
end
|
121
150
|
end
|
data/lib/unitwise/errors.rb
CHANGED
@@ -5,13 +5,7 @@ module Unitwise
|
|
5
5
|
# of a string, as well as caching the results.
|
6
6
|
class Decomposer
|
7
7
|
|
8
|
-
MODES = [:primary_code, :secondary_code, :names, :slugs, :symbol]
|
9
|
-
|
10
|
-
PARSERS = MODES.reduce({}) do |hash, mode|
|
11
|
-
hash[mode] = Parser.new(mode); hash
|
12
|
-
end
|
13
|
-
|
14
|
-
TRANSFORMER = Transformer.new
|
8
|
+
MODES = [:primary_code, :secondary_code, :names, :slugs, :symbol].freeze
|
15
9
|
|
16
10
|
class << self
|
17
11
|
|
@@ -25,6 +19,16 @@ module Unitwise
|
|
25
19
|
end
|
26
20
|
end
|
27
21
|
|
22
|
+
def parsers
|
23
|
+
@parsers ||= MODES.reduce({}) do |hash, mode|
|
24
|
+
hash[mode] = Parser.new(mode); hash
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def transformer
|
29
|
+
@transformer = Transformer.new
|
30
|
+
end
|
31
|
+
|
28
32
|
private
|
29
33
|
|
30
34
|
# A simple cache to prevent re-decomposing the same units
|
@@ -32,6 +36,14 @@ module Unitwise
|
|
32
36
|
def cache
|
33
37
|
@cache ||= {}
|
34
38
|
end
|
39
|
+
|
40
|
+
# Reset memoized data. Allows rebuilding of parsers, transformers, and
|
41
|
+
# the cache after list of atoms has been modified.
|
42
|
+
def reset
|
43
|
+
@parsers = nil
|
44
|
+
@transformer = nil
|
45
|
+
@cache = nil
|
46
|
+
end
|
35
47
|
end
|
36
48
|
|
37
49
|
attr_reader :expression, :mode
|
@@ -44,7 +56,7 @@ module Unitwise
|
|
44
56
|
end
|
45
57
|
|
46
58
|
def parse
|
47
|
-
|
59
|
+
self.class.parsers.reduce(nil) do |_, (mode, parser)|
|
48
60
|
parsed = parser.parse(expression) rescue next
|
49
61
|
@mode = mode
|
50
62
|
break parsed
|
@@ -52,7 +64,7 @@ module Unitwise
|
|
52
64
|
end
|
53
65
|
|
54
66
|
def transform
|
55
|
-
@transform ||=
|
67
|
+
@transform ||= self.class.transformer.apply(parse, :mode => mode)
|
56
68
|
end
|
57
69
|
|
58
70
|
def terms
|
@@ -5,19 +5,15 @@ module Unitwise
|
|
5
5
|
class Matcher
|
6
6
|
class << self
|
7
7
|
def atom(mode)
|
8
|
-
|
9
|
-
@atom[mode] ||= new(Atom.all, mode).alternative
|
8
|
+
new(Atom.all, mode).alternative
|
10
9
|
end
|
11
10
|
|
12
11
|
def metric_atom(mode)
|
13
|
-
|
14
|
-
@metric_atom[mode] ||=
|
15
|
-
new(Atom.all.select(&:metric?), mode).alternative
|
12
|
+
new(Atom.all.select(&:metric?), mode).alternative
|
16
13
|
end
|
17
14
|
|
18
15
|
def prefix(mode)
|
19
|
-
|
20
|
-
@prefix[mode] ||= new(Prefix.all, mode).alternative
|
16
|
+
new(Prefix.all, mode).alternative
|
21
17
|
end
|
22
18
|
end
|
23
19
|
|
@@ -41,7 +37,6 @@ module Unitwise
|
|
41
37
|
def alternative
|
42
38
|
Parslet::Atoms::Alternative.new(*matchers)
|
43
39
|
end
|
44
|
-
|
45
40
|
end
|
46
41
|
end
|
47
42
|
end
|
@@ -5,14 +5,21 @@ module Unitwise
|
|
5
5
|
class Parser < Parslet::Parser
|
6
6
|
attr_reader :key
|
7
7
|
def initialize(key = :primary_code)
|
8
|
-
@key
|
8
|
+
@key = key
|
9
|
+
@atom_matcher = Matcher.atom(key)
|
10
|
+
@metric_atom_matcher = Matcher.metric_atom(key)
|
11
|
+
@prefix_matcher = Matcher.prefix(key)
|
9
12
|
end
|
10
13
|
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :atom_matcher, :metric_atom_matcher, :prefix_matcher
|
17
|
+
|
11
18
|
root :expression
|
12
19
|
|
13
|
-
rule (:atom) {
|
14
|
-
rule (:metric_atom) {
|
15
|
-
rule (:prefix) {
|
20
|
+
rule (:atom) { atom_matcher.as(:atom_code) }
|
21
|
+
rule (:metric_atom) { metric_atom_matcher.as(:atom_code) }
|
22
|
+
rule (:prefix) { prefix_matcher.as(:prefix_code) }
|
16
23
|
|
17
24
|
rule (:simpleton) do
|
18
25
|
(prefix.as(:prefix) >> metric_atom.as(:atom) | atom.as(:atom))
|
data/lib/unitwise/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -9,9 +9,8 @@ require 'minitest/pride'
|
|
9
9
|
require 'unitwise'
|
10
10
|
|
11
11
|
module Minitest::Assertions
|
12
|
-
def assert_almost_equal(expected, actual)
|
12
|
+
def assert_almost_equal(expected, actual, range=0.0001)
|
13
13
|
message = "Expected #{actual} to be almost equal to #{expected}"
|
14
|
-
range = 0.00001
|
15
14
|
assert expected + range > actual && expected - range < actual, message
|
16
15
|
end
|
17
16
|
end
|
data/test/unitwise/atom_test.rb
CHANGED
@@ -31,7 +31,7 @@ describe Unitwise::Atom do
|
|
31
31
|
let(:joule) { Unitwise::Atom.find("J")}
|
32
32
|
describe "#scale" do
|
33
33
|
it "must be nil for base atoms" do
|
34
|
-
second.scale.
|
34
|
+
second.scale.must_be_nil
|
35
35
|
end
|
36
36
|
it "sould be a Scale object for derived atoms" do
|
37
37
|
yard.scale.must_be_instance_of Unitwise::Scale
|
@@ -126,4 +126,40 @@ describe Unitwise::Atom do
|
|
126
126
|
second.frozen?.must_equal true
|
127
127
|
end
|
128
128
|
end
|
129
|
-
|
129
|
+
|
130
|
+
describe "validate!" do
|
131
|
+
it "returns true for a valid atom" do
|
132
|
+
atom = Unitwise::Atom.new(
|
133
|
+
primary_code: "warp",
|
134
|
+
secondary_code: "[warp]",
|
135
|
+
names: ["Warp", "Warp Factor"],
|
136
|
+
scale: {
|
137
|
+
value: 1,
|
138
|
+
unit_code: "[c]"
|
139
|
+
}
|
140
|
+
)
|
141
|
+
|
142
|
+
atom.validate!.must_equal true
|
143
|
+
end
|
144
|
+
|
145
|
+
it "returns an error for an atom with missing properties" do
|
146
|
+
atom = Unitwise::Atom.new(names: "hot dog")
|
147
|
+
|
148
|
+
assert_raises { atom.validate! }
|
149
|
+
end
|
150
|
+
|
151
|
+
it "returns an error for an atom that doesn't resolve" do
|
152
|
+
atom = Unitwise::Atom.new(
|
153
|
+
primary_code: "feels",
|
154
|
+
secondary_code: "FEELS",
|
155
|
+
names: ["feels"],
|
156
|
+
scale: {
|
157
|
+
value: 1,
|
158
|
+
unit_code: "hearts"
|
159
|
+
}
|
160
|
+
)
|
161
|
+
|
162
|
+
assert_raises { atom.validate! }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -15,8 +15,8 @@ describe Unitwise::Expression::Matcher do
|
|
15
15
|
it "must be an Alternative list of names" do
|
16
16
|
subject.must_be_instance_of Parslet::Atoms::Alternative
|
17
17
|
end
|
18
|
-
it "must parse '
|
19
|
-
subject.parse('
|
18
|
+
it "must parse 'joule'" do
|
19
|
+
subject.parse('joule').must_equal('joule')
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -39,4 +39,4 @@ describe Unitwise::Expression::Matcher do
|
|
39
39
|
subject.parse('h').must_equal('h')
|
40
40
|
end
|
41
41
|
end
|
42
|
-
end
|
42
|
+
end
|
data/test/unitwise_test.rb
CHANGED
@@ -28,8 +28,28 @@ describe Unitwise do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
describe 'register' do
|
32
|
+
it 'should allow custom units to be registered' do
|
33
|
+
josh = {
|
34
|
+
names: ["Josh W Lewis", "joshwlewis"],
|
35
|
+
symbol: "JWL",
|
36
|
+
primary_code: "jwl",
|
37
|
+
secondary_code: "jwl",
|
38
|
+
scale: {
|
39
|
+
value: 71.875,
|
40
|
+
unit_code: "[in_i]"
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
Unitwise.register(josh)
|
45
|
+
|
46
|
+
joshes = Unitwise(1, 'mile').to_jwl
|
47
|
+
|
48
|
+
joshes.to_i.must_equal(881)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
31
52
|
it "should have a path" do
|
32
53
|
Unitwise.path.must_match(/unitwise$/)
|
33
54
|
end
|
34
|
-
|
35
55
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unitwise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Lewis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: liner
|
@@ -217,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
217
217
|
version: '0'
|
218
218
|
requirements: []
|
219
219
|
rubyforge_project:
|
220
|
-
rubygems_version: 2.
|
220
|
+
rubygems_version: 2.6.8
|
221
221
|
signing_key:
|
222
222
|
specification_version: 4
|
223
223
|
summary: Convert between and perform mathematical operations on physical quantities
|