unitwise 2.0.0 → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dfd97b3dc7b4fbee73653902232de8df74d79967
4
- data.tar.gz: 25837b28be1ab4e3fbb71100bf6221986419fd65
3
+ metadata.gz: fb8605b862b95bff79423e03fabf502e89a39440
4
+ data.tar.gz: 83bf9041753023411557a9f9b22d84d6d61cecfc
5
5
  SHA512:
6
- metadata.gz: bd81647b67a9ca56b420b6cf47d4c60e2f6311a1d7aef97d6a41309fd4e6a4ba43b746d9c4f776d9dd8dd0d82c95ec69d2e53ba0a211aee7dc49a2045092384e
7
- data.tar.gz: 7fda14718114a1430b56873b68336e5eb92636f97597dce3e743ca72346499d2d3cdfcb4bb61eeedcd6162bfa3b90318f9eec0cc025e19f234f3e0eab7bc73a6
6
+ metadata.gz: c202998427bdbd04aef777b310afbca4bbfd1866bc2d5405054864f28b17d9e723ea0885eba6bed4ee981b9078ed99c3ab10c6f0f98ebc6ef73fe5eac94713d6
7
+ data.tar.gz: 806a06c5c4fcd80cd2ec3be0c6e723b2e7ce1b9b621340d9db194a782f08356594ea7816b8dec3d024245283404555559c5635b4c8fe05633a71aa0d043fd4e3
@@ -1 +1 @@
1
- 2.2.0
1
+ 2.4.0
@@ -3,18 +3,14 @@ cache: bundler
3
3
  bundler_args: --without yard pry
4
4
  sudo: false
5
5
  rvm:
6
- - 1.9.3
7
- - 2.0.0
8
- - 2.1
9
- - 2.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
- - rbx-2
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
@@ -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', '~> 1.2.6', :platform => :mri
5
+ gem 'bigdecimal', '>= 1.2.6', :platform => :mri
6
6
  else
7
- gem 'bigdecimal', '~> 1.2.5', :platform => :mri
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
 
@@ -23,13 +23,13 @@
23
23
  :secondary_code: RAD
24
24
  :property: plane angle
25
25
  :dim: A
26
- - :names: Kelvin
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: Coulomb
32
+ - :names: coulomb
33
33
  :symbol: C
34
34
  :primary_code: C
35
35
  :secondary_code: C
@@ -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: Hertz
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: Newton
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: Pascal
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: Joule
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: Watt
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: Ampère
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: Volt
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: Farad
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: Ohm
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: Siemens
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: Weber
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: Tesla
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: Henry
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: Becquerel
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: Gray
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: Sievert
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-24
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: statute mile
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: "Ångström"
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
@@ -65,7 +65,7 @@
65
65
  :secondary_code: M
66
66
  :scalar: 1e-3
67
67
  - :names: micro
68
- :symbol: "μ"
68
+ :symbol: μ
69
69
  :primary_code: u
70
70
  :secondary_code: U
71
71
  :scalar: 1e-6
@@ -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
@@ -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
@@ -1,7 +1,10 @@
1
1
  module Unitwise
2
- class ExpressionError < Exception
2
+ class ExpressionError < StandardError
3
3
  end
4
4
 
5
- class ConversionError < Exception
5
+ class ConversionError < StandardError
6
+ end
7
+
8
+ class DefinitionError < StandardError
6
9
  end
7
10
  end
@@ -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
- PARSERS.reduce(nil) do |_, (mode, parser)|
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 ||= TRANSFORMER.apply(parse, :mode => mode)
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
- @atom ||= {}
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
- @metric_atom ||= {}
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
- @prefix ||= {}
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 = 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) { Matcher.atom(key).as(:atom_code) }
14
- rule (:metric_atom) { Matcher.metric_atom(key).as(:atom_code) }
15
- rule (:prefix) { Matcher.prefix(key).as(:prefix_code) }
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))
@@ -1,3 +1,3 @@
1
1
  module Unitwise
2
- VERSION = '2.0.0'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -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
@@ -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.must_equal nil
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
- end
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 'Joule'" do
19
- subject.parse('Joule').must_equal('Joule')
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
@@ -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.0.0
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: 2015-09-13 00:00:00.000000000 Z
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.4.5
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