numbers_in_words 0.2.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|