humanize_fraction 0.1.1 → 0.1.2

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: 71e2420b7a27230601ab8ae89e38f3097908f13f
4
- data.tar.gz: 80455bea8b7ae37f41a686570ced33c3ffa78914
3
+ metadata.gz: 48b87152720622914c2118dd643e7ae53757892a
4
+ data.tar.gz: f4a156d8e3f0c5274544d7dc6c84b9f96c6aa22b
5
5
  SHA512:
6
- metadata.gz: 47ecefd1c758ef9de3c81505d16f6312ff3d339f42929feb7c5f4a992c4056ff430d05c30f599b7b85bc784a9bab666fd75250306ee77d624f75c71b119bf942
7
- data.tar.gz: 8a3d6b9e0fd2337dadbf331ad8d17f386d46adc450ca0c4bee112810e458b2acc497fce5cbc300dc47a2b7d4fe50cce8166979283b065bcf218a073aab5ae9da
6
+ metadata.gz: 0bec3257ee12d4158d8b61de48500614486f6685224299e21101701fbad654c165a9beee9b465ad87c835c3994a238b325a4f510c7ea90b7b4571b4f8962a3a5
7
+ data.tar.gz: 25155b9bd6c6c63df47e2cd205c1e126e40464a0c082c00c909b81df270fc1b9caa80bc44d2ad846b32136fe5d0bbd7d115b389901ad45881b2b3300e48301ff
data/README.md CHANGED
@@ -7,10 +7,10 @@ Rubygem to convert fraction to words, like 1 ⅓ => one and a third. Examples:
7
7
  #=> "one eighth"
8
8
  "1/8".humanize_fraction(shorthand: true)
9
9
  #=> "an eighth"
10
- "2 3/4".humanize_fraction
11
- #=> "two and three fourths"
12
- "2 3/4".humanize_fraction(quarter: true)
13
- #=> "two and three quarters"
10
+ "-2 3/4".humanize_fraction
11
+ #=> "negative two and three fourths"
12
+ "-2 3/4".humanize_fraction(quarter: true)
13
+ #=> "negative two and three quarters"
14
14
  "1/1000000".humanize_fraction(shorthand: true)
15
15
  #=> "a millionth"
16
16
  "222/333".humanize_fraction
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_runtime_dependency "activesupport", ">= 4"
26
26
  spec.add_runtime_dependency "humanize", "~> 1.4"
27
27
  spec.add_runtime_dependency "numbers_and_words", "~> 0.11"
28
+ spec.add_runtime_dependency "sig", "~> 1.0"
28
29
 
29
30
  spec.add_development_dependency "bundler", "~> 1.14"
30
31
  spec.add_development_dependency "rake", "~> 10.0"
@@ -2,8 +2,10 @@ require "active_support/inflector"
2
2
  require "humanize"
3
3
  # TODO: figure out how to use this library without the monkey patching it does.
4
4
  require "numbers_and_words"
5
+ require "sig"
5
6
 
6
7
  require "humanize_fraction/humanizer"
8
+ require "humanize_fraction/fraction_string_parser"
7
9
  require "humanize_fraction/version"
8
10
  require "core_extensions/string/humanize_fraction"
9
11
 
@@ -0,0 +1,57 @@
1
+ # This class takes a fraction string (e.g. "1 3/4") and parses it into the
2
+ # individual fraction components of whole_part, numerator, and denominator.
3
+ module HumanizeFraction
4
+ class FractionStringParser
5
+ # From: https://github.com/thechrisoshow/fractional/blob/master/lib/fractional.rb
6
+ SINGLE_FRACTION = /\A\s*(\-?\d+)\s*\/\s*(\-?\d+)\s*\z/
7
+ MIXED_FRACTION = /\A\s*(\-?\d*)\s+(\d+)\s*\/\s*(\d+)\s*\z/
8
+
9
+ attr_reader :string
10
+ sig String,
11
+ def initialize(string)
12
+ @string = string
13
+ end
14
+
15
+ def fraction_components
16
+ @fraction_components ||= begin
17
+ if string_is_mixed_fraction?
18
+ mixed_fraction_components
19
+ elsif string_is_single_fraction?
20
+ single_fraction_components
21
+ else
22
+ raise ArgumentError, "Unable to extract fraction from string #{string}"
23
+ end
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def mixed_fraction_components
30
+ whole_part, numerator, denominator = string.scan(MIXED_FRACTION).flatten.map(&:to_i)
31
+ components = {whole_part: whole_part, numerator: numerator, denominator: denominator}
32
+ validate_fraction_components(components)
33
+ components
34
+ end
35
+
36
+ def single_fraction_components
37
+ numerator, denominator = string.split("/").map(&:to_i)
38
+ components = {whole_part: nil, numerator: numerator, denominator: denominator}
39
+ validate_fraction_components(components)
40
+ components
41
+ end
42
+
43
+ def string_is_mixed_fraction?
44
+ string.match(MIXED_FRACTION)
45
+ end
46
+
47
+ def string_is_single_fraction?
48
+ string.match(SINGLE_FRACTION)
49
+ end
50
+
51
+ def validate_fraction_components(components)
52
+ if components[:denominator].zero?
53
+ raise ArgumentError, "Unable to parse fraction with zero denominator"
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,9 +1,5 @@
1
1
  module HumanizeFraction
2
2
  class Humanizer
3
- # From: https://github.com/thechrisoshow/fractional/blob/master/lib/fractional.rb
4
- SINGLE_FRACTION = /\A\s*(\-?\d+)\/(\-?\d+)\s*\z/
5
- MIXED_FRACTION = /\A\s*(\-?\d*)\s+(\d+)\/(\d+)\s*\z/
6
-
7
3
  # Numbers that should be prefixed with `a` instead of `an` even though they
8
4
  # start with a vowel.
9
5
  NUMBERS_STARTING_WITH_SILENT_VOWEL = [
@@ -12,15 +8,8 @@ module HumanizeFraction
12
8
 
13
9
  attr_reader :numerator, :denominator, :whole_part
14
10
 
11
+ sig [{numerator: Integer, denominator: Integer, whole_part: [NilClass, Integer]}],
15
12
  def initialize(numerator:, denominator:, whole_part: nil)
16
- [numerator, denominator].each do |number|
17
- if !number.is_a?(Integer)
18
- raise ArgumentError, "Expected Integers for numerator/denominator but got #{number.class.name}"
19
- end
20
- end
21
- if !whole_part.nil? && !whole_part.is_a?(Integer)
22
- raise ArgumentError, "Expected Integer or NilClass for whole_part but got #{whole_part.class.name}"
23
- end
24
13
  @whole_part = whole_part
25
14
  @numerator = numerator
26
15
  @denominator = denominator
@@ -35,19 +24,10 @@ module HumanizeFraction
35
24
  words.join(" ")
36
25
  end
37
26
 
27
+ sig_self [String, Hash],
38
28
  def self.from_string(string, options = {})
39
- if !string.is_a?(String)
40
- raise ArgumentError, "Expected String but got #{string.class.name}"
41
- end
42
- if string_is_mixed_fraction?(string)
43
- whole, numerator, denominator = string.scan(MIXED_FRACTION).flatten.map(&:to_i)
44
- new(whole_part: whole, numerator: numerator, denominator: denominator, **options)
45
- elsif string_is_single_fraction?(string)
46
- numerator, denominator = string.split("/").map(&:to_i)
47
- new(numerator: numerator, denominator: denominator, **options)
48
- else
49
- raise ArgumentError, "Unable to extract fraction from string #{string}"
50
- end
29
+ parser = FractionStringParser.new(string)
30
+ new(**parser.fraction_components, **options)
51
31
  end
52
32
 
53
33
  private
@@ -100,13 +80,5 @@ module HumanizeFraction
100
80
  "a"
101
81
  end
102
82
  end
103
-
104
- def self.string_is_mixed_fraction?(value)
105
- value&.match(MIXED_FRACTION)
106
- end
107
-
108
- def self.string_is_single_fraction?(value)
109
- value&.match(SINGLE_FRACTION)
110
- end
111
83
  end
112
84
  end
@@ -1,3 +1,3 @@
1
1
  module HumanizeFraction
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: humanize_fraction
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Graham
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0.11'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sig
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -126,6 +140,7 @@ files:
126
140
  - humanize_fraction.gemspec
127
141
  - lib/core_extensions/string/humanize_fraction.rb
128
142
  - lib/humanize_fraction.rb
143
+ - lib/humanize_fraction/fraction_string_parser.rb
129
144
  - lib/humanize_fraction/humanizer.rb
130
145
  - lib/humanize_fraction/version.rb
131
146
  homepage: https://github.com/6/humanize_fraction