numbers_in_words 0.2.0 → 0.5.1
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/.codeclimate.yml +14 -0
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.rubocop.yml +58 -0
- data/.travis.yml +15 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +50 -26
- data/README.md +20 -70
- data/Rakefile +3 -1
- data/bin/spec +2 -0
- data/lib/numbers_in_words.rb +49 -15
- data/lib/numbers_in_words/duck_punch.rb +12 -8
- data/lib/numbers_in_words/exceptional_numbers.rb +115 -0
- data/lib/numbers_in_words/fraction.rb +136 -0
- data/lib/numbers_in_words/number_group.rb +34 -25
- data/lib/numbers_in_words/parsing/fraction_parsing.rb +34 -0
- data/lib/numbers_in_words/parsing/number_parser.rb +98 -0
- data/lib/numbers_in_words/parsing/pair_parsing.rb +64 -0
- data/lib/numbers_in_words/parsing/parse_fractions.rb +45 -0
- data/lib/numbers_in_words/parsing/parse_individual_number.rb +68 -0
- data/lib/numbers_in_words/parsing/parse_status.rb +17 -0
- data/lib/numbers_in_words/parsing/special.rb +67 -0
- data/lib/numbers_in_words/parsing/to_number.rb +77 -0
- data/lib/numbers_in_words/powers_of_ten.rb +49 -0
- data/lib/numbers_in_words/to_word.rb +78 -13
- data/lib/numbers_in_words/version.rb +3 -1
- data/lib/numbers_in_words/writer.rb +69 -0
- data/numbers_in_words.gemspec +15 -14
- data/spec/exceptional_numbers_spec.rb +26 -0
- data/spec/fraction_spec.rb +152 -0
- data/spec/fractions_spec.rb +31 -0
- data/spec/non_monkey_patch_spec.rb +51 -0
- data/spec/number_group_spec.rb +12 -12
- data/spec/number_parser_spec.rb +31 -0
- data/spec/numbers_in_words_spec.rb +74 -54
- data/spec/numerical_strings_spec.rb +35 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/to_word_spec.rb +18 -0
- data/spec/words_in_numbers_spec.rb +135 -117
- data/spec/writer_spec.rb +26 -0
- data/spec/years_spec.rb +27 -0
- metadata +61 -59
- data/lib/numbers_in_words/english/constants.rb +0 -93
- data/lib/numbers_in_words/english/language_writer_english.rb +0 -107
- data/lib/numbers_in_words/language_writer.rb +0 -31
- data/lib/numbers_in_words/number_parser.rb +0 -81
- data/lib/numbers_in_words/to_number.rb +0 -82
- data/spec/language_writer_spec.rb +0 -23
data/numbers_in_words.gemspec
CHANGED
@@ -1,24 +1,25 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'numbers_in_words/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |gem|
|
7
|
-
gem.name =
|
8
|
-
gem.description =
|
9
|
-
gem.summary =
|
8
|
+
gem.name = 'numbers_in_words'
|
9
|
+
gem.description = 'convert written numbers into Integers and vice-versa'
|
10
|
+
gem.summary = 'Example: NumbersInWords.in_words(123) # => ' \
|
11
|
+
'"one hundred and twenty three", NumbersInWords.in_numbers("seventy-five point eight") # = > 75.8'
|
10
12
|
|
11
13
|
gem.version = NumbersInWords::VERSION
|
12
|
-
gem.authors = [
|
13
|
-
gem.email = [
|
14
|
-
gem.homepage =
|
14
|
+
gem.authors = ['Mark Burns', 'Dimid Duchovny']
|
15
|
+
gem.email = ['markthedeveloper@gmail.com', 'dimidd@gmail.com']
|
16
|
+
gem.homepage = 'http://github.com/markburns/numbers_in_words'
|
15
17
|
|
16
|
-
gem.
|
17
|
-
gem.add_development_dependency
|
18
|
-
gem.add_development_dependency "debugger"
|
18
|
+
gem.add_development_dependency 'rspec', '~> 3.4.0'
|
19
|
+
gem.add_development_dependency 'rubocop'
|
19
20
|
|
20
|
-
gem.files = `git ls-files`.split(
|
21
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
21
|
+
gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
22
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
22
23
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
23
|
-
gem.require_paths = [
|
24
|
+
gem.require_paths = ['lib']
|
24
25
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require './spec/spec_helper'
|
4
|
+
|
5
|
+
describe NumbersInWords::ExceptionalNumbers do
|
6
|
+
describe '#fraction' do
|
7
|
+
FRACTIONS = {
|
8
|
+
[1, 2] => 'one half',
|
9
|
+
[2, 2] => 'two halves',
|
10
|
+
[3, 2] => 'three halves',
|
11
|
+
[1, 3] => 'one third',
|
12
|
+
[1, 4] => 'one quarter',
|
13
|
+
[2, 17] => 'two seventeenths',
|
14
|
+
[1, 1_000] => 'one one thousandth',
|
15
|
+
[74, 101] => 'seventy-four hundred and firsts',
|
16
|
+
[13, 97] => 'thirteen ninety-sevenths',
|
17
|
+
[131, 1_000] => 'one hundred and thirty-one thousandths'
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
FRACTIONS.each do |(numerator, denominator), string|
|
21
|
+
it "#{numerator}/#{denominator} == #{string}" do
|
22
|
+
expect(subject.fraction(denominator: denominator, numerator: numerator).in_words).to eql(string)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe NumbersInWords::Fraction do # rubocop: disable Metrics/BlockLength
|
4
|
+
subject do
|
5
|
+
described_class.new(numerator: numerator, denominator: denominator, attributes: attributes)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:numerator) { 1 }
|
9
|
+
|
10
|
+
context 'halves' do
|
11
|
+
let(:denominator) { 2 }
|
12
|
+
let(:attributes) do
|
13
|
+
{ number: 'two',
|
14
|
+
ordinal: 'second',
|
15
|
+
fraction: { singular: 'half', plural: 'halves' } }
|
16
|
+
end
|
17
|
+
|
18
|
+
it do
|
19
|
+
expect(subject.in_words).to eq 'one half'
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with plural' do
|
23
|
+
let(:numerator) { 2 }
|
24
|
+
|
25
|
+
it do
|
26
|
+
expect(subject.in_words).to eq 'two halves'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'quarters' do
|
32
|
+
let(:denominator) { 4 }
|
33
|
+
let(:attributes) do
|
34
|
+
{
|
35
|
+
number: 'four',
|
36
|
+
ordinal: 'fourth',
|
37
|
+
fraction: { singular: 'quarter' }
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
it do
|
42
|
+
expect(subject.in_words).to eq 'one quarter'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'fifths' do
|
47
|
+
let(:denominator) { 5 }
|
48
|
+
let(:attributes) do
|
49
|
+
{ number: 'five', ordinal: 'fifth' }
|
50
|
+
end
|
51
|
+
|
52
|
+
it do
|
53
|
+
expect(subject.in_words).to eq 'one fifth'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'sixths' do
|
58
|
+
let(:denominator) { 6 }
|
59
|
+
let(:attributes) { {} }
|
60
|
+
|
61
|
+
it do
|
62
|
+
expect(subject.in_words).to eq 'one sixth'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'nineteenths' do
|
67
|
+
let(:denominator) { 19 }
|
68
|
+
let(:attributes) { {} }
|
69
|
+
|
70
|
+
it do
|
71
|
+
expect(subject.in_words).to eq 'one nineteenth'
|
72
|
+
expect(subject.fraction).to eq 'nineteenth'
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'plural' do
|
76
|
+
let(:numerator) { 763 }
|
77
|
+
|
78
|
+
it do
|
79
|
+
expect(subject.in_words).to eq 'seven hundred and sixty-three nineteenths'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'one hundred and seconds' do
|
85
|
+
let(:denominator) { 102 }
|
86
|
+
let(:attributes) { {} }
|
87
|
+
|
88
|
+
it do
|
89
|
+
expect(subject.in_words).to eq 'one one hundred and second'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'one hundred and sixth' do
|
94
|
+
let(:denominator) { 106 }
|
95
|
+
let(:attributes) { {} }
|
96
|
+
|
97
|
+
it do
|
98
|
+
expect(subject.in_words).to eq 'one one hundred and sixth'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'one hundred and nineteenth' do
|
103
|
+
let(:denominator) { 119 }
|
104
|
+
let(:attributes) { {} }
|
105
|
+
|
106
|
+
it do
|
107
|
+
expect(subject.ordinal).to eq 'one hundred and nineteenth'
|
108
|
+
expect(subject.in_words).to eq 'one one hundred and nineteenth'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'one thousandth' do
|
113
|
+
let(:denominator) { 1000 }
|
114
|
+
let(:attributes) { {} }
|
115
|
+
|
116
|
+
it do
|
117
|
+
expect(subject.ordinal).to eq 'one thousandth'
|
118
|
+
expect(subject.in_words).to eq 'one one thousandth'
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'plural' do
|
122
|
+
let(:numerator) { 2 }
|
123
|
+
let(:denominator) { 1000 }
|
124
|
+
|
125
|
+
it do
|
126
|
+
expect(subject.in_words).to eq 'two thousandths'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'googolplexths' do
|
132
|
+
let(:denominator) { Kernel.silence_warnings { 10**(10**100) } }
|
133
|
+
|
134
|
+
let(:attributes) do
|
135
|
+
{ number: 'googolplex',
|
136
|
+
ordinal: 'googolplexth',
|
137
|
+
fraction: { singular: 'googolplexth', plural: 'googolplexths' } }
|
138
|
+
end
|
139
|
+
|
140
|
+
it do
|
141
|
+
expect(subject.in_words).to eq 'one infinitieth'
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'with plural' do
|
145
|
+
let(:numerator) { 2 }
|
146
|
+
|
147
|
+
it do
|
148
|
+
expect(subject.in_words).to eq 'two infinitieths'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe NumbersInWords do
|
4
|
+
FRACTION_EXAMPLES = {
|
5
|
+
'half' => 0.5,
|
6
|
+
'a half' => 0.5,
|
7
|
+
'one half' => 0.5,
|
8
|
+
'two halves' => 1.0,
|
9
|
+
'three halves' => 1.5,
|
10
|
+
'three quarters' => 0.75,
|
11
|
+
'three fifths' => 3 / 5.0,
|
12
|
+
'seven fifteenths' => 7 / 15.0
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
PENDING = {
|
16
|
+
'twenty and three fifteenths' => 20 + 3 / 15.0,
|
17
|
+
'three ninety-sevenths' => 3 / 97.0
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
FRACTION_EXAMPLES.each do |string, float|
|
21
|
+
it "#{string} == #{float}" do
|
22
|
+
expect(string.in_numbers).to eql(float)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
PENDING.each do |string, float|
|
27
|
+
pending "#{string} == #{float}" do
|
28
|
+
expect(string.in_numbers).to eql(float)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'NumbersInWords' do # rubocop: disable Metrics/BlockLength
|
6
|
+
describe '.in_words' do
|
7
|
+
it do
|
8
|
+
expect(NumbersInWords.in_words(100)).to eq 'one hundred'
|
9
|
+
expect(NumbersInWords.in_words(-100)).to eq 'minus one hundred'
|
10
|
+
expect(NumbersInWords.in_words(24)).to eq 'twenty-four'
|
11
|
+
expect(NumbersInWords.in_words(1.2)).to eq 'one point two'
|
12
|
+
expect(NumbersInWords.in_words(100 * 10**100)).to eq 'one hundred googol'
|
13
|
+
expect(NumbersInWords.in_words(30 + 100 * 10**100)).to eq 'one hundred googol and thirty'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
FRACTION_TO_WORDS = {
|
18
|
+
[1, 2] => 'one half',
|
19
|
+
[3, 2] => 'three halves',
|
20
|
+
[1, 3] => 'one third',
|
21
|
+
[1, 4] => 'one quarter',
|
22
|
+
[1, 5] => 'one fifth',
|
23
|
+
[1, 19] => 'one nineteenth',
|
24
|
+
[2, 17] => 'two seventeenths',
|
25
|
+
[1, 21] => 'one twenty-first',
|
26
|
+
[1, 32] => 'one thirty-second',
|
27
|
+
[1, 101] => 'one one hundred and first',
|
28
|
+
[3, 101] => 'three hundred and firsts',
|
29
|
+
[73, 102] => 'seventy-three hundred and seconds',
|
30
|
+
[13, 97] => 'thirteen ninety-sevenths'
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
FRACTION_TO_WORDS.each do |(numerator, denominator), string|
|
34
|
+
it "#{numerator}/#{denominator} == #{string}" do
|
35
|
+
expect(NumbersInWords.in_words(numerator.to_f / denominator, fraction: true)).to eql(string)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '.in_numbers' do
|
40
|
+
it do
|
41
|
+
expect(NumbersInWords.in_numbers('hundred')).to eq 100
|
42
|
+
expect(NumbersInWords.in_numbers('one hundred')).to eq 100
|
43
|
+
|
44
|
+
expect(NumbersInWords.in_numbers('minus one hundred')).to eq(-100)
|
45
|
+
expect(NumbersInWords.in_numbers('twenty four')).to eq 24
|
46
|
+
expect(NumbersInWords.in_numbers('one point two')).to eq 1.2
|
47
|
+
expect(NumbersInWords.in_numbers('one hundred googol')).to eq 100 * 10**100
|
48
|
+
expect(NumbersInWords.in_numbers('one hundred googol and thirty')).to eq 30 + 100 * 10**100
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/number_group_spec.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require './spec/spec_helper'
|
4
|
+
require 'numbers_in_words/number_group'
|
2
5
|
|
3
6
|
describe NumbersInWords::NumberGroup do
|
4
|
-
it
|
5
|
-
g =
|
6
|
-
|
7
|
-
g.groups_of(
|
8
|
-
g.groups_of(
|
9
|
-
g.groups_of(
|
10
|
-
g.groups_of(
|
11
|
-
g.groups_of(
|
12
|
-
g.groups_of(
|
13
|
-
g.groups_of(123_456_789_101_112 ,3 ).should == {12=>123 , 9=>456 , 6=>789 , 3=>101 , 0=>112 }
|
7
|
+
it 'should split into group of three digit numbers' do
|
8
|
+
g = described_class
|
9
|
+
expect(g.groups_of(1, 3)).to eq({ 0 => 1 })
|
10
|
+
expect(g.groups_of(12, 3)).to eq({ 0 => 12 })
|
11
|
+
expect(g.groups_of(123, 3)).to eq({ 0 => 123 })
|
12
|
+
expect(g.groups_of(1111, 3)).to eq({ 3 => 1, 0 => 111 })
|
13
|
+
expect(g.groups_of(87_654, 3)).to eq({ 3 => 87, 0 => 654 })
|
14
|
+
expect(g.groups_of(1_234_567, 3)).to eq({ 6 => 1, 3 => 234, 0 => 567 })
|
15
|
+
expect(g.groups_of(123_456_789_101_112, 3)).to eq({ 12 => 123, 9 => 456, 6 => 789, 3 => 101, 0 => 112 })
|
14
16
|
end
|
15
17
|
end
|
16
|
-
|
17
|
-
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require './spec/spec_helper'
|
4
|
+
require 'numbers_in_words/parsing/number_parser'
|
5
|
+
|
6
|
+
describe NumbersInWords::NumberParser do
|
7
|
+
subject do
|
8
|
+
super().parse(number)
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'with single digit' do
|
12
|
+
let(:number) { [9] }
|
13
|
+
it { expect(subject).to eq 9 }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with thousands' do
|
17
|
+
let(:number) { [20, 1000] }
|
18
|
+
it { expect(subject).to eq 20_000 }
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with thousands with a leading one' do
|
22
|
+
let(:number) { [1, 1000, 6, 100] }
|
23
|
+
it { expect(subject).to eq 1600 }
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with hundreds' do
|
27
|
+
let(:number) { [2, 100, 45] }
|
28
|
+
|
29
|
+
it { expect(subject).to eq 245 }
|
30
|
+
end
|
31
|
+
end
|
@@ -1,79 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require './spec/spec_helper'
|
2
4
|
|
3
|
-
describe NumbersInWords do
|
4
|
-
|
5
|
+
describe NumbersInWords do # rubocop: disable Metrics/BlockLength
|
6
|
+
describe '.in_words' do
|
7
|
+
it do
|
8
|
+
expect(NumbersInWords.in_words(100)).to eq 'one hundred'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.in_numbers' do
|
13
|
+
it do
|
14
|
+
expect(NumbersInWords.in_numbers('one-hundred')).to eq 100
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should print the digits 0-9 correctly' do
|
5
19
|
numbers = %w[zero one two three four five six seven eight nine]
|
6
20
|
|
7
|
-
10.times { |i| i.in_words.
|
21
|
+
10.times { |i| expect(i.in_words).to eq(numbers[i]) }
|
8
22
|
end
|
9
23
|
|
10
|
-
it
|
24
|
+
it 'should print the digits 11-19 correctly' do
|
11
25
|
words = %w[eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen]
|
12
|
-
numbers = [11,12,13,14,15,16,17,18,19]
|
26
|
+
numbers = [11, 12, 13, 14, 15, 16, 17, 18, 19]
|
13
27
|
numbers.each_with_index do |number, index|
|
14
|
-
number.in_words.
|
15
|
-
|
28
|
+
expect(number.in_words).to eq(words[index])
|
16
29
|
end
|
17
30
|
end
|
18
31
|
|
19
|
-
it
|
20
|
-
21.in_words.
|
32
|
+
it 'should handle two digit numbers' do
|
33
|
+
expect(21.in_words).to eq('twenty-one')
|
21
34
|
end
|
22
35
|
|
23
|
-
it
|
24
|
-
113.in_words.
|
25
|
-
299.in_words.
|
26
|
-
300.in_words.
|
27
|
-
101.in_words.
|
36
|
+
it 'should handle three digit numbers' do
|
37
|
+
expect(113.in_words).to eq('one hundred and thirteen')
|
38
|
+
expect(299.in_words).to eq('two hundred and ninety-nine')
|
39
|
+
expect(300.in_words).to eq('three hundred')
|
40
|
+
expect(101.in_words).to eq('one hundred and one')
|
28
41
|
end
|
29
42
|
|
30
|
-
it
|
31
|
-
2999
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
+
it 'should print out some random examples correctly' do
|
44
|
+
expect(2999.in_words).to eq('two thousand nine hundred and ninety-nine')
|
45
|
+
expect(99_999.in_words).to eq('ninety-nine thousand nine hundred and ninety-nine')
|
46
|
+
expect(999_999.in_words).to eq('nine hundred and ninety-nine thousand nine hundred and ninety-nine')
|
47
|
+
expect(123_456.in_words).to eq('one hundred and twenty-three thousand four hundred and fifty-six')
|
48
|
+
expect(24_056.in_words).to eq('twenty-four thousand and fifty-six')
|
49
|
+
expect(17_054.in_words).to eq('seventeen thousand and fifty-four')
|
50
|
+
expect(11_004.in_words).to eq('eleven thousand and four')
|
51
|
+
expect(470_154.in_words).to eq('four hundred and seventy thousand one hundred and fifty-four')
|
52
|
+
expect(417_155.in_words).to eq('four hundred and seventeen thousand one hundred and fifty-five')
|
53
|
+
expect(999_999.in_words).to eq('nine hundred and ninety-nine thousand nine hundred and ninety-nine')
|
54
|
+
expect(1_000_000.in_words).to eq('one million')
|
55
|
+
expect(1_000_001.in_words).to eq('one million and one')
|
56
|
+
expect(112.in_words).to eq('one hundred and twelve')
|
43
57
|
end
|
44
58
|
|
45
|
-
it
|
46
|
-
|
47
|
-
(10*10**12 + 10**6 +1)
|
48
|
-
(10**75)
|
49
|
-
|
59
|
+
it 'should handle edge cases' do
|
60
|
+
expect(1_000_001.in_words).to eq('one million and one')
|
61
|
+
expect((10 * 10**12 + 10**6 + 1).in_words).to eq('ten trillion one million and one')
|
62
|
+
expect((10**75).in_words).to eq('one quattuorvigintillion')
|
63
|
+
expect(10_001_001.in_words).to eq('ten million one thousand and one')
|
50
64
|
end
|
51
65
|
|
52
|
-
it
|
53
|
-
|
54
|
-
(
|
55
|
-
(42*
|
56
|
-
|
66
|
+
it 'should handle a googol and larger' do
|
67
|
+
googol = 10**100
|
68
|
+
expect((googol + 1).in_words).to eq('one googol and one')
|
69
|
+
expect((42 * googol + 16_777_216).in_words)
|
70
|
+
.to eq('forty-two googol sixteen million seven hundred and seventy-seven thousand two hundred and sixteen')
|
71
|
+
expect((42 * googol * googol).in_words).to eq('forty-two googol googol')
|
57
72
|
end
|
58
73
|
|
59
|
-
it
|
60
|
-
-1
|
61
|
-
-9
|
62
|
-
-10
|
63
|
-
-15
|
64
|
-
-100
|
65
|
-
(-1*(10**100)).in_words.
|
66
|
-
|
74
|
+
it 'should handle negative numbers' do
|
75
|
+
expect(-1.in_words).to eq('minus one')
|
76
|
+
expect(-9.in_words).to eq('minus nine')
|
77
|
+
expect(-10.in_words).to eq('minus ten')
|
78
|
+
expect(-15.in_words).to eq('minus fifteen')
|
79
|
+
expect(-100.in_words).to eq('minus one hundred')
|
80
|
+
expect((-1 * (10**100)).in_words).to eq('minus one googol')
|
81
|
+
|
82
|
+
expect(-123_456_789.in_words)
|
83
|
+
.to eq('minus one hundred and twenty-three million four hundred and ' \
|
84
|
+
'fifty-six thousand seven hundred and eighty-nine')
|
67
85
|
end
|
68
86
|
|
69
|
-
it
|
70
|
-
#because of lack of absolute accuracy with floats
|
71
|
-
#the output won't be exactly as you might expect
|
72
|
-
#so we will match rather than find equivalents
|
73
|
-
1.1
|
74
|
-
1.2345678
|
75
|
-
1000.2345678
|
76
|
-
|
77
|
-
|
87
|
+
it 'should handle decimals' do
|
88
|
+
# because of lack of absolute accuracy with floats
|
89
|
+
# the output won't be exactly as you might expect
|
90
|
+
# so we will match rather than find equivalents
|
91
|
+
expect(1.1.in_words).to match(/one point one/)
|
92
|
+
expect(1.2345678.in_words).to match(/one point two three four five six seven eight/)
|
93
|
+
expect(1000.2345678.in_words).to match(/one thousand point two three four five six seven eight/)
|
94
|
+
expect(12_345.2345678.in_words)
|
95
|
+
.to match(/twelve thousand three hundred and forty-five point two three four five six seven eight/)
|
96
|
+
|
97
|
+
expect((10**9 + 0.1).in_words).to match(/one billion point one/)
|
78
98
|
end
|
79
99
|
end
|