cousin_roman 0.0.2 → 1.0.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: d721d30a8c9bfff8692b8be996a4b10697fb2d60
4
- data.tar.gz: 9134a9f70a990f750a4c904daaa90878aefd6552
3
+ metadata.gz: f16dc19c0864ea51d64a45d94b4a0acf07cea72b
4
+ data.tar.gz: d0bd841b1ab1c55cb9ed88ef4671a9d9a134820c
5
5
  SHA512:
6
- metadata.gz: 6fd61fa7907ce017e491be441e96f00c51e94cb67ac1407965dc15bb3d41caf118f4b4898fe3a885cd0d117b911182aa4a5ce363bb674f0c13d1ca25ae76c919
7
- data.tar.gz: fa39c4136a8b29e9d7d7408a37716ed423f1144cf6422b98368838a640ae1b82ee9b2056db4b7de2cc86f7166cb919184cf609d4122708b27db556092a488321
6
+ metadata.gz: ec7600e60f73656ed7aefa6c1bdaf6a36e70d29943becb1f2d9115cf20f43eb7cc052228d85ad08d74c85e2d996ef5a82bfb395efe46bbadcfaecd7720643ea6
7
+ data.tar.gz: 9e41c6a9c0f41a90d47258623b6e8088dff534add7ff06ef8d69f2303cbf01c8c00de59bf5f31f4162d513a434eee36838ce7ebeafc6d56817746333c5727283
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # CousinRoman
2
2
 
3
- `CousinRoman` is a `String` extension which allows you to convert
4
- Roman numerals (following modern subtractive notation)
5
- to Arabic numbers (i.e. Integers).
3
+ `CousinRoman` provides functionality to convert between Roman and Arabian numerals.
4
+
5
+ The functionality provided via String and Integer extensions.
6
6
 
7
7
  ## Installation
8
8
 
@@ -20,14 +20,22 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- Just use `String#to_arabic` or `String#to_arabic!` method.
23
+ Just use `String#to_arabian` or `String#to_arabian!` methods
24
+ if you want to convert from Roman to Arabian
25
+ and
26
+ `Integer#to_roman` or `Integer#to_roman!`
27
+ if you want to convert from Arabian to Roman.
24
28
 
25
29
  For example:
26
30
 
27
31
  ```ruby
28
- 'MMXIII'.to_arabic # => 2013
29
- 'MMYUOX'.to_arabic # => nil
30
- 'MMYOUX'.to_arabic! # => TypeError: not a valid roman number
32
+ 'MMXIII'.to_arabian # => 2013
33
+ 'MMYUOX'.to_arabian # => nil
34
+ 'MMYOUX'.to_arabian! # => TypeError: not a valid roman number
35
+
36
+ 2013.to_roman # => 'MMXIII'
37
+ '0'.to_roman # => nil
38
+ '100500'.to_roman # => TypeError: not a valid roman number
31
39
  ```
32
40
 
33
41
  ## Testing
@@ -36,7 +44,7 @@ Just run
36
44
 
37
45
  $ rake
38
46
 
39
- under gem folder.
47
+ under gem folder (be prepared for massive output).
40
48
 
41
49
  ## Contributing
42
50
 
data/cousin_roman.gemspec CHANGED
@@ -8,14 +8,14 @@ Gem::Specification.new do |spec|
8
8
  spec.version = CousinRoman::VERSION
9
9
  spec.authors = ["Artem Pyanykh"]
10
10
  spec.email = ["artem.pyanykh@gmail.com"]
11
- spec.description = %q{Easily convert Roman numerals to Integers. Functionality provided via String extension}
12
- spec.summary = %q{Convert Roman numerals to Integers}
11
+ spec.description = %q{Easily convert Roman and Arabian number. Functionality provided via String and extensions}
12
+ spec.summary = %q{Convert Roman numerals to Integers and vice versa}
13
13
  spec.homepage = "https://github.com/ArtemPyanykh/cousin_roman"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)*/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
@@ -0,0 +1,69 @@
1
+ require 'cousin_roman'
2
+
3
+ module CousinRoman
4
+ module Arabian
5
+ extend self
6
+
7
+ def valid?(number)
8
+ number.is_a? Integer and number >= 1 and number <= 3999
9
+ end
10
+
11
+ def to_roman(arabian)
12
+ convert arabian if valid? arabian
13
+ end
14
+
15
+ def to_roman!(arabian)
16
+ if valid? arabian
17
+ convert arabian
18
+ else
19
+ raise TypeError, 'not a valid roman number'
20
+ end
21
+ end
22
+
23
+ def convert(number)
24
+ thousands = number / 1000
25
+ hundreds = number / 100 % 10
26
+ tens = number / 10 % 10
27
+ ones = number % 10
28
+
29
+ build_roman(thousands, hundreds, tens, ones).upcase
30
+ end
31
+
32
+ def build_roman(thousands, hundreds, tens, ones)
33
+ build_pow(thousands, 4) +
34
+ build_pow(hundreds, 3) +
35
+ build_pow(tens, 2) +
36
+ build_pow(ones, 1)
37
+ end
38
+
39
+ def build_pow(number, pow)
40
+ literals = pow_literals(pow)
41
+
42
+ case number
43
+ when 1..3 then literals[:one]*number
44
+ when 4 then literals[:subtractives][4]
45
+ when 5..8 then literals[:five] + (literals[:one]*(number - 5))
46
+ when 9 then literals[:subtractives][9]
47
+ else ""
48
+ end
49
+ end
50
+
51
+ def pow_literals(pow)
52
+ one_literal, _ = ONES.find do |literal, value|
53
+ value >= 10 ** (pow - 1) and value < 10 ** pow
54
+ end
55
+ five_literal, _ = FIVES.find do |literal, value|
56
+ value >= 10 ** (pow - 1) and value < 10 ** pow
57
+ end
58
+ subtractive_literals = {}
59
+ SUBTRACTIVES.select do |literal, value|
60
+ value >= 10 ** (pow - 1) and value < 10 ** pow
61
+ end.each do |literal, number|
62
+ order = number / (10 ** (pow - 1))
63
+ subtractive_literals[order] = literal
64
+ end
65
+
66
+ {one: one_literal, five: five_literal, subtractives: subtractive_literals}
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,11 @@
1
+ require "cousin_roman/roman"
2
+
3
+ class Integer
4
+ def to_roman
5
+ CousinRoman::Arabian.to_roman(self)
6
+ end
7
+
8
+ def to_roman!
9
+ CousinRoman::Arabian.to_roman!(self)
10
+ end
11
+ end
@@ -1,39 +1,9 @@
1
- module CousinRoman
2
- LITERALS = [
3
- 'i', 'I',
4
- 'v', 'V',
5
- 'x', 'X',
6
- 'l', 'L',
7
- 'c', 'C',
8
- 'd', 'D',
9
- 'm', 'M'
10
- ]
11
-
12
- ONES = {
13
- 'i' => 1,
14
- 'x' => 10,
15
- 'c' => 100,
16
- 'm' => 1000
17
- }
18
-
19
- FIVES = {
20
- 'v' => 5,
21
- 'l' => 50,
22
- 'd' => 500,
23
- }
1
+ require 'cousin_roman'
24
2
 
25
- SUBTRACTIVE = {
26
- 'iv' => 4,
27
- 'ix' => 9,
28
- 'xl' => 40,
29
- 'xc' => 90,
30
- 'cd' => 400,
31
- 'cm' => 900,
32
- }
33
-
34
- FACTORS = ONES.merge(FIVES).merge(SUBTRACTIVE)
3
+ module CousinRoman
4
+ module Roman
5
+ extend self
35
6
 
36
- class << self
37
7
  def valid?(number)
38
8
  matches = number.match roman_regex
39
9
  matches and !matches[0].empty?
@@ -50,7 +20,7 @@ module CousinRoman
50
20
  # 2. Sum this numeric values to get the final answer
51
21
  def convert(number)
52
22
  intermediate = number.dup.downcase
53
- SUBTRACTIVE.each do |factor, value|
23
+ SUBTRACTIVES.each do |factor, value|
54
24
  intermediate.gsub!(factor, "(#{value})")
55
25
  end
56
26
  ONES.merge(FIVES).each do |factor, value|
@@ -62,12 +32,12 @@ module CousinRoman
62
32
  end
63
33
  end
64
34
 
65
- def to_arabic(number)
35
+ def to_arabian(number)
66
36
  clean = number.strip
67
37
  convert clean if valid? clean
68
38
  end
69
39
 
70
- def to_arabic!(number)
40
+ def to_arabian!(number)
71
41
  clean = number.strip
72
42
  if valid? clean
73
43
  convert clean
@@ -1,11 +1,11 @@
1
- require "cousin_roman/conversion"
1
+ require "cousin_roman/roman"
2
2
 
3
3
  class String
4
- def to_arabic
5
- CousinRoman.to_arabic(self)
4
+ def to_arabian
5
+ CousinRoman::Roman.to_arabian(self)
6
6
  end
7
7
 
8
- def to_arabic!
9
- CousinRoman.to_arabic!(self)
8
+ def to_arabian!
9
+ CousinRoman::Roman.to_arabian!(self)
10
10
  end
11
11
  end
@@ -1,3 +1,3 @@
1
1
  module CousinRoman
2
- VERSION = "0.0.2"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/cousin_roman.rb CHANGED
@@ -1,3 +1,41 @@
1
1
  require "cousin_roman/version"
2
- require "cousin_roman/conversion"
2
+ require "cousin_roman/roman"
3
+ require "cousin_roman/arabian"
3
4
  require "cousin_roman/string_extension"
5
+ require "cousin_roman/integer_extension"
6
+
7
+ module CousinRoman
8
+ LITERALS = [
9
+ 'i', 'I',
10
+ 'v', 'V',
11
+ 'x', 'X',
12
+ 'l', 'L',
13
+ 'c', 'C',
14
+ 'd', 'D',
15
+ 'm', 'M'
16
+ ]
17
+
18
+ ONES = {
19
+ 'i' => 1,
20
+ 'x' => 10,
21
+ 'c' => 100,
22
+ 'm' => 1000
23
+ }
24
+
25
+ FIVES = {
26
+ 'v' => 5,
27
+ 'l' => 50,
28
+ 'd' => 500,
29
+ }
30
+
31
+ SUBTRACTIVES = {
32
+ 'iv' => 4,
33
+ 'ix' => 9,
34
+ 'xl' => 40,
35
+ 'xc' => 90,
36
+ 'cd' => 400,
37
+ 'cm' => 900,
38
+ }
39
+
40
+ FACTORS = ONES.merge(FIVES).merge(SUBTRACTIVES)
41
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe CousinRoman::Arabian do
4
+ describe 'valid?' do
5
+ it 'should consider invalid numbers <= 0' do
6
+ (-10..0).each do |number|
7
+ CousinRoman::Arabian.valid?(number).should be_false
8
+ end
9
+ end
10
+
11
+ it 'should consider valid numbers > 1 and <= 3999' do
12
+ CousinRoman::Arabian.valid?(1).should be_true
13
+ CousinRoman::Arabian.valid?(3999).should be_true
14
+ end
15
+
16
+ it 'should consider invalid numbers > 3999' do
17
+ CousinRoman::Arabian.valid?(4000).should be_false
18
+ end
19
+ end
20
+
21
+
22
+ describe 'convert' do
23
+ 1.upto(3999).each do |arabian|
24
+ it "should succeed on #{arabian}", slow: true do
25
+ roman = CousinRoman::Arabian.convert(arabian)
26
+ CousinRoman::Roman.valid?(roman).should be_true
27
+ CousinRoman::Roman.convert(roman).should == arabian
28
+ end
29
+ end
30
+ end
31
+
32
+ describe 'to_roman' do
33
+ it 'should call convert on valid number' do
34
+ CousinRoman::Arabian.should_receive(:convert).and_call_original
35
+ CousinRoman::Arabian.to_roman(1).should == 'I'
36
+ end
37
+
38
+ it 'should return nil on invalid number' do
39
+ CousinRoman::Arabian.to_roman(100500).should be_nil
40
+ end
41
+ end
42
+
43
+ describe 'to_roman!' do
44
+ it 'should call convert on valid number' do
45
+ CousinRoman::Arabian.should_receive(:convert).and_call_original
46
+ CousinRoman::Arabian.to_roman!(1).should == 'I'
47
+ end
48
+
49
+ it 'should throw TypeError on invalid number' do
50
+ expect { CousinRoman::Arabian.to_roman!(100500) }.to raise_error(TypeError)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,182 @@
1
+ require 'spec_helper'
2
+
3
+ describe CousinRoman::Roman do
4
+ describe 'valid?' do
5
+ describe 'literals validation' do
6
+ ASCII = 0.upto(127).map(&:chr)
7
+ NON_ROMAN_LITERALS = ASCII - CousinRoman::LITERALS
8
+
9
+ CousinRoman::LITERALS.each do |l|
10
+ it "should allow #{l}" do
11
+ CousinRoman::Roman.valid?(l).should be_true
12
+ end
13
+ end
14
+
15
+ NON_ROMAN_LITERALS.each do |l|
16
+ it "should not allow #{l}" do
17
+ CousinRoman::Roman.valid?(l).should be_false
18
+ end
19
+ end
20
+
21
+ it 'should not allow mix of allowed and disallowed literals' do
22
+ CousinRoman::Roman.valid?('MYCXI').should be_false
23
+ end
24
+
25
+ it 'should not allow empty string' do
26
+ CousinRoman::Roman.valid?('').should be_false
27
+ end
28
+ end
29
+
30
+ describe 'factors validation' do
31
+ CousinRoman::ONES.keys.each do |factor|
32
+ 1.upto(3).each do |reps|
33
+ it "should allow #{reps} repetitions of #{factor}" do
34
+ CousinRoman::Roman.valid?(factor*reps).should be_true
35
+ end
36
+ end
37
+
38
+ it "should not allow more than 3 repetitions of #{factor}" do
39
+ CousinRoman::Roman.valid?(factor*4).should be_false
40
+ end
41
+ end
42
+
43
+ CousinRoman::FIVES.merge(CousinRoman::SUBTRACTIVES).keys.each do |factor|
44
+ it "should not allow repetition of #{factor}" do
45
+ CousinRoman::Roman.valid?(factor*2).should be_false
46
+ end
47
+ end
48
+
49
+ it 'should allow ones and fives of the same power' do
50
+ CousinRoman::FIVES.keys.each_with_index do |five, index|
51
+ 1.upto(3).each do |reps|
52
+ corresponding_one = CousinRoman::ONES.keys[index]
53
+ CousinRoman::Roman.valid?(five + (corresponding_one * reps)).should be_true
54
+ end
55
+ end
56
+ end
57
+
58
+ it 'should not allow subtractives and ones or fives of the same power' do
59
+ CousinRoman::Roman.valid?('ivi').should be_false
60
+ CousinRoman::Roman.valid?('ixi').should be_false
61
+ CousinRoman::Roman.valid?('xlx').should be_false
62
+ CousinRoman::Roman.valid?('xcx').should be_false
63
+ CousinRoman::Roman.valid?('cdc').should be_false
64
+ CousinRoman::Roman.valid?('cmc').should be_false
65
+
66
+ CousinRoman::Roman.valid?('ivv').should be_false
67
+ CousinRoman::Roman.valid?('ixv').should be_false
68
+ CousinRoman::Roman.valid?('xll').should be_false
69
+ CousinRoman::Roman.valid?('xcl').should be_false
70
+ CousinRoman::Roman.valid?('cdd').should be_false
71
+ CousinRoman::Roman.valid?('cmd').should be_false
72
+ end
73
+ end
74
+
75
+ describe 'ordering validation' do
76
+ context 'when validating that factors are ordered by descreasing of power' do
77
+ ORDERINGS_RIGHT = [
78
+ 'md', 'mc',
79
+ 'cl', 'cx',
80
+ 'xv', 'xi',
81
+ 'mcm', 'mcd',
82
+ 'cxc', 'cxl',
83
+ 'xix', 'xiv'
84
+ ]
85
+ ORDERINGS_WRONG = [
86
+ 'dm', 'lc', 'vx',
87
+ 'cmm', 'cdm',
88
+ 'xcc', 'xlc',
89
+ 'ixx', 'ivx'
90
+ ]
91
+
92
+ ORDERINGS_RIGHT.each do |pair|
93
+ high, low = pair.split('', 2)
94
+ it "should allow #{high}#{low}" do
95
+ CousinRoman::Roman.valid?(high + low).should be_true
96
+ end
97
+ end
98
+
99
+ ORDERINGS_WRONG.each do |pair|
100
+ low, high = pair.split('', 2)
101
+ it "should not allow #{low}#{high}" do
102
+ CousinRoman::Roman.valid?(low + high).should be_false
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ describe 'convert' do
110
+ context 'singular factors' do
111
+ CousinRoman::FACTORS.each do |factor, number|
112
+ it "should convert #{factor} to #{number}" do
113
+ CousinRoman::Roman.convert(factor).should == number
114
+ end
115
+ end
116
+ end
117
+
118
+ context 'repetitive factors' do
119
+ CousinRoman::ONES.each do |factor, number|
120
+ 1.upto(3).each do |reps|
121
+ it "should convert #{factor*reps} to #{number*reps}" do
122
+ CousinRoman::Roman.convert(factor*reps).should == (number*reps)
123
+ end
124
+ end
125
+ end
126
+ end
127
+
128
+ context 'different power factors' do
129
+ it 'should honor ones' do
130
+ CousinRoman::Roman.convert('mcxi').should == 1111
131
+ end
132
+
133
+ it 'should honor fives' do
134
+ CousinRoman::Roman.convert('dlv').should == 555
135
+ end
136
+
137
+ it 'should honor ones and fives together' do
138
+ CousinRoman::Roman.convert('mdclxvi').should == 1666
139
+ end
140
+
141
+ it 'should honor subtractives ones and fives together' do
142
+ CousinRoman::Roman.convert('mcmlxxxix').should == 1989
143
+ end
144
+
145
+ it 'should honor max number' do
146
+ CousinRoman::Roman.convert('mmmcmxcix').should == 3999
147
+ end
148
+
149
+ it 'should honor the longest number' do
150
+ CousinRoman::Roman.convert('dccclxxxviii').should == 888
151
+ end
152
+
153
+ it 'should be case insensitive' do
154
+ number = 'MCXI'
155
+ CousinRoman::Roman.convert(number).should == CousinRoman::Roman.convert(number.downcase)
156
+ end
157
+ end
158
+ end
159
+
160
+ describe 'to_arabian' do
161
+ it 'should call convert on valid number' do
162
+ CousinRoman::Roman.should_receive(:convert).and_call_original
163
+ CousinRoman::Roman.to_arabian('MMM').should == 3000
164
+ end
165
+
166
+ it 'should return nil on invalid number' do
167
+ CousinRoman::Roman.to_arabian('YRU?!').should be_nil
168
+ end
169
+ end
170
+
171
+ describe 'to_arabian!' do
172
+ it 'should call convert on valid number' do
173
+ CousinRoman::Roman.should_receive(:convert).and_call_original
174
+ CousinRoman::Roman.to_arabian!('MMM').should == 3000
175
+ end
176
+
177
+ it 'should throw TypeError on invalid number' do
178
+ expect { CousinRoman::Roman.to_arabian!('YRU?!') }.to raise_error(TypeError)
179
+ end
180
+ end
181
+
182
+ end
@@ -4,195 +4,26 @@ describe CousinRoman do
4
4
  it 'should have a version number' do
5
5
  CousinRoman::VERSION.should_not be_nil
6
6
  end
7
-
8
- describe 'valid?' do
9
- describe 'literals validation' do
10
- ASCII = 0.upto(127).map(&:chr)
11
- NON_ROMAN_LITERALS = ASCII - CousinRoman::LITERALS
12
-
13
- CousinRoman::LITERALS.each do |l|
14
- it "should allow #{l}" do
15
- CousinRoman.valid?(l).should be_true
16
- end
17
- end
18
-
19
- NON_ROMAN_LITERALS.each do |l|
20
- it "should not allow #{l}" do
21
- CousinRoman.valid?(l).should be_false
22
- end
23
- end
24
-
25
- it 'should not allow mix of allowed and disallowed literals' do
26
- CousinRoman.valid?('MYCXI').should be_false
27
- end
28
-
29
- it 'should not allow empty string' do
30
- CousinRoman.valid?('').should be_false
31
- end
32
- end
33
-
34
- describe 'factors validation' do
35
- CousinRoman::ONES.keys.each do |factor|
36
- 1.upto(3).each do |reps|
37
- it "should allow #{reps} repetitions of #{factor}" do
38
- CousinRoman.valid?(factor*reps).should be_true
39
- end
40
- end
41
-
42
- it "should not allow more than 3 repetitions of #{factor}" do
43
- CousinRoman.valid?(factor*4).should be_false
44
- end
45
- end
46
-
47
- CousinRoman::FIVES.merge(CousinRoman::SUBTRACTIVE).keys.each do |factor|
48
- it "should not allow repetition of #{factor}" do
49
- CousinRoman.valid?(factor*2).should be_false
50
- end
51
- end
52
-
53
- it 'should allow ones and fives of the same power' do
54
- CousinRoman::FIVES.keys.each_with_index do |five, index|
55
- 1.upto(3).each do |reps|
56
- corresponding_one = CousinRoman::ONES.keys[index]
57
- CousinRoman.valid?(five + (corresponding_one * reps)).should be_true
58
- end
59
- end
60
- end
61
-
62
- it 'should not allow subtractives and ones or fives of the same power' do
63
- CousinRoman.valid?('ivi').should be_false
64
- CousinRoman.valid?('ixi').should be_false
65
- CousinRoman.valid?('xlx').should be_false
66
- CousinRoman.valid?('xcx').should be_false
67
- CousinRoman.valid?('cdc').should be_false
68
- CousinRoman.valid?('cmc').should be_false
69
-
70
- CousinRoman.valid?('ivv').should be_false
71
- CousinRoman.valid?('ixv').should be_false
72
- CousinRoman.valid?('xll').should be_false
73
- CousinRoman.valid?('xcl').should be_false
74
- CousinRoman.valid?('cdd').should be_false
75
- CousinRoman.valid?('cmd').should be_false
76
- end
77
- end
78
-
79
- describe 'ordering validation' do
80
- context 'when validating that factors are ordered by descreasing of power' do
81
- ORDERINGS_RIGHT = [
82
- 'md', 'mc',
83
- 'cl', 'cx',
84
- 'xv', 'xi',
85
- 'mcm', 'mcd',
86
- 'cxc', 'cxl',
87
- 'xix', 'xiv'
88
- ]
89
- ORDERINGS_WRONG = [
90
- 'dm', 'lc', 'vx',
91
- 'cmm', 'cdm',
92
- 'xcc', 'xlc',
93
- 'ixx', 'ivx'
94
- ]
95
-
96
- ORDERINGS_RIGHT.each do |pair|
97
- high, low = pair.split('', 2)
98
- it "should allow #{high}#{low}" do
99
- CousinRoman.valid?(high + low).should be_true
100
- end
101
- end
102
-
103
- ORDERINGS_WRONG.each do |pair|
104
- low, high = pair.split('', 2)
105
- it "should not allow #{low}#{high}" do
106
- CousinRoman.valid?(low + high).should be_false
107
- end
108
- end
109
- end
110
- end
111
- end
112
-
113
- describe 'convert' do
114
- context 'singular factors' do
115
- CousinRoman::FACTORS.each do |factor, number|
116
- it "should convert #{factor} to #{number}" do
117
- CousinRoman.convert(factor).should == number
118
- end
119
- end
120
- end
121
-
122
- context 'repetitive factors' do
123
- CousinRoman::ONES.each do |factor, number|
124
- 1.upto(3).each do |reps|
125
- it "should convert #{factor*reps} to #{number*reps}" do
126
- CousinRoman.convert(factor*reps).should == (number*reps)
127
- end
128
- end
129
- end
130
- end
131
-
132
- context 'different power factors' do
133
- it 'should honor ones' do
134
- CousinRoman.convert('mcxi').should == 1111
135
- end
136
-
137
- it 'should honor fives' do
138
- CousinRoman.convert('dlv').should == 555
139
- end
140
-
141
- it 'should honor ones and fives together' do
142
- CousinRoman.convert('mdclxvi').should == 1666
143
- end
144
-
145
- it 'should honor subtractives ones and fives together' do
146
- CousinRoman.convert('mcmlxxxix').should == 1989
147
- end
148
-
149
- it 'should honor max number' do
150
- CousinRoman.convert('mmmcmxcix').should == 3999
151
- end
152
-
153
- it 'should honor the longest number' do
154
- CousinRoman.convert('dccclxxxviii').should == 888
155
- end
156
-
157
- it 'should be case insensitive' do
158
- number = 'MCXI'
159
- CousinRoman.convert(number).should == CousinRoman.convert(number.downcase)
160
- end
161
- end
162
- end
163
-
164
- describe 'to_arabic' do
165
- it 'should call convert on valid number' do
166
- CousinRoman.should_receive(:convert).and_call_original
167
- CousinRoman.to_arabic('MMM').should == 3000
168
- end
169
-
170
- it 'should return nil on invalid number' do
171
- CousinRoman.to_arabic('YRU?!').should be_nil
172
- end
173
- end
174
-
175
- describe 'to_arabic!' do
176
- it 'should call convert on valid number' do
177
- CousinRoman.should_receive(:convert).and_call_original
178
- CousinRoman.to_arabic!('MMM').should == 3000
179
- end
180
-
181
- it 'should throw TypeError on invalid number' do
182
- expect { CousinRoman.to_arabic!('YRU?!') }.to raise_error(TypeError)
183
- end
184
- end
185
-
186
7
  end
187
8
 
188
9
  describe String do
189
- [:to_arabic, :to_arabic!].each do |meth|
10
+ [:to_arabian, :to_arabian!].each do |meth|
190
11
  it { should respond_to(meth) }
191
12
 
192
- it "should call CousinRoman.#{meth} on String##{meth}" do
13
+ it "should call CousinRoman::Roman.#{meth} on String##{meth}" do
193
14
  roman = 'i'
194
- CousinRoman.should_receive(meth).with(roman).and_call_original
15
+ CousinRoman::Roman.should_receive(meth).with(roman).and_call_original
195
16
  roman.send(meth).should == 1
196
17
  end
197
18
  end
198
19
  end
20
+
21
+ describe Integer do
22
+ [:to_roman, :to_roman!].each do |meth|
23
+ it "should call CousinRoman::Arabian.#{meth} on Fixnum##{meth}" do
24
+ arabian = 1
25
+ CousinRoman::Arabian.should_receive(meth).with(arabian).and_call_original
26
+ arabian.send(meth).should == 'I'
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cousin_roman
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Pyanykh
@@ -52,8 +52,8 @@ dependencies:
52
52
  - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- description: Easily convert Roman numerals to Integers. Functionality provided via
56
- String extension
55
+ description: Easily convert Roman and Arabian number. Functionality provided via String
56
+ and extensions
57
57
  email:
58
58
  - artem.pyanykh@gmail.com
59
59
  executables: []
@@ -69,9 +69,13 @@ files:
69
69
  - Rakefile
70
70
  - cousin_roman.gemspec
71
71
  - lib/cousin_roman.rb
72
- - lib/cousin_roman/conversion.rb
72
+ - lib/cousin_roman/arabian.rb
73
+ - lib/cousin_roman/integer_extension.rb
74
+ - lib/cousin_roman/roman.rb
73
75
  - lib/cousin_roman/string_extension.rb
74
76
  - lib/cousin_roman/version.rb
77
+ - spec/cousin_roman/arabian_spec.rb
78
+ - spec/cousin_roman/roman_spec.rb
75
79
  - spec/cousin_roman_spec.rb
76
80
  - spec/spec_helper.rb
77
81
  homepage: https://github.com/ArtemPyanykh/cousin_roman
@@ -97,7 +101,9 @@ rubyforge_project:
97
101
  rubygems_version: 2.1.8
98
102
  signing_key:
99
103
  specification_version: 4
100
- summary: Convert Roman numerals to Integers
104
+ summary: Convert Roman numerals to Integers and vice versa
101
105
  test_files:
106
+ - spec/cousin_roman/arabian_spec.rb
107
+ - spec/cousin_roman/roman_spec.rb
102
108
  - spec/cousin_roman_spec.rb
103
109
  - spec/spec_helper.rb