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 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