to_decimal 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 +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +60 -56
- data/lib/to_decimal.rb +20 -1
- data/lib/to_decimal/convertor_class.rb +38 -0
- data/lib/to_decimal/validator_class.rb +27 -0
- data/lib/to_decimal/wrong_base_input_error.rb +3 -1
- data/test/to_decimal_test.rb +131 -166
- metadata +5 -4
- data/lib/to_decimal/to_decimal_class.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 536d4add05473007155d6508a38be3c2edc844c8b2ca055c284d66b610156218
|
4
|
+
data.tar.gz: 99c02b0b97440add3b06f8b3e81e4c3695bb3dff8725cce9e89ebed2caf1cc3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d3c17dd84adcdfd27018bf9c39a57f716e67a925ba92af4520b7872d816dea34075258bee82478ee1e28ef63e1ad941629640bda53cde12d176568cb7eb6014
|
7
|
+
data.tar.gz: 8ee66486d089201851a3dcd2502cdd2ffc26685a6bccbc69e7dcff294c150615dbe561306a82225f56fbdc369233ab6a19eb3b2a40278230e0da1b2e69796bd6
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
# to_decimal 0.0.3 (2018-11-27)
|
2
|
+
---
|
3
|
+
|
4
|
+
**Breaking changes !!!**
|
5
|
+
|
6
|
+
- Provides a namespace `ToDecimal` to the gem
|
7
|
+
- Renames the main class from `ToDecimal` to `Convertor`
|
8
|
+
- Provides constants `ToDecimal::Base2` to `ToDecimal::Base10` as convenience.
|
9
|
+
- Remove all other class and instance methods, except the getter for the `base`
|
10
|
+
attribute of the `Convertor` class
|
11
|
+
- Make the `ToDecimal::Convertor.new` class method private
|
12
|
+
- Update tests accordingly
|
13
|
+
|
14
|
+
|
1
15
|
# to_decimal 0.0.2 (2018-05-08)
|
2
16
|
---
|
3
17
|
|
data/README.md
CHANGED
@@ -4,40 +4,53 @@ A simple gem to convert an integer expressed in bases
|
|
4
4
|
ranging from 2 to 10 into a decimal integer.
|
5
5
|
|
6
6
|
Ruby comes with useful built-in methods to convert integers and string
|
7
|
-
|
8
|
-
|
7
|
+
representations of integers to another base ([`String#to_i(base=10)`](http://ruby-doc.org/core-2.5.3/String.html#method-i-to_i),
|
8
|
+
[`Kernel#Integer(arg, base=0)`](https://ruby-doc.com/core-2.5.2/Kernel.html#method-i-Integer) and
|
9
|
+
[`Integer#to_s(base=10)`](http://ruby-doc.org/core-2.5.3/Integer.html#method-i-to_s).
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
You can also use prefixes with [litteral numeric constant](https://ruby-doc.com/core-2.5.2/doc/syntax/literals_rdoc.html#label-Numbers),
|
12
|
+
but it only works for binary, octal, decimal and hexadecimal notation (which cover
|
13
|
+
the most usecases):
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
```ruby
|
16
|
+
# binary
|
17
|
+
0b10111 # => 23
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
# octal
|
20
|
+
0o27 # => 23
|
20
21
|
|
21
|
-
|
22
|
+
# decimal
|
23
|
+
0d23 # => 23
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
+
# hexadecimal
|
26
|
+
0x17 # => 23
|
27
|
+
```
|
25
28
|
|
26
|
-
|
29
|
+
But if you want to convert an integer of say, base 6, to an integer of base 10,
|
30
|
+
you need to proceed like this (AFAIK):
|
27
31
|
|
28
|
-
|
32
|
+
```ruby
|
33
|
+
12.to_s.to_i(6) # => 8
|
34
|
+
```
|
29
35
|
|
30
|
-
|
36
|
+
It's not a concern if you need to do this occasionally, or if you can easily
|
37
|
+
manage using prefixes, but I thought there could be a more straightforward,
|
38
|
+
consise and explicit way to perform this, showing more clearly what your intent
|
39
|
+
is.
|
31
40
|
|
32
|
-
|
33
|
-
|
41
|
+
I've looked in the core API and in the Standard Library, but I didn't find
|
42
|
+
anything.
|
34
43
|
|
35
|
-
|
36
|
-
|
44
|
+
I found the following two gems :
|
45
|
+
- [bases](https://github.com/whatyouhide/bases) ;
|
46
|
+
- [radix](https://github.com/rubyworks/radix) ;
|
37
47
|
|
38
|
-
|
39
|
-
|
48
|
+
They are very comprehensive, go both behind the base 36, which is the limit
|
49
|
+
of Ruby, and allow to convert form bases back and forth.
|
40
50
|
|
51
|
+
But they were a little too heavy for my purpose, which was simply
|
52
|
+
converting from a base lesser or equal than 10 and to return an integer
|
53
|
+
expressed in base 10. So I decided to write my own gem.
|
41
54
|
|
42
55
|
# Installation
|
43
56
|
```shell
|
@@ -55,55 +68,46 @@ This project is tested under minitest.
|
|
55
68
|
|
56
69
|
### Instance methods
|
57
70
|
|
58
|
-
|
71
|
+
The gem gives you access to 9 objects under the namespace `ToDecimal` called :
|
72
|
+
`Base2`, `Base3`,... `Base10`.
|
59
73
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
# or
|
65
|
-
base8 = ToDecimal.new(8)
|
66
|
-
# or
|
67
|
-
base8 = ToDecimal.new('8')
|
68
|
-
# => a new object with base set to 8
|
69
|
-
```
|
70
|
-
|
71
|
-
The base attribute can be updated simply :
|
74
|
+
Each object has a `[]` instance method, which takes as parameter an integer OR a string
|
75
|
+
representation of the corresponding base and returns this integer expressed
|
76
|
+
in base 10 :
|
72
77
|
|
73
78
|
```ruby
|
74
|
-
|
79
|
+
base2 = ToDecimal::Base2
|
80
|
+
base2[10] # => 2
|
75
81
|
|
76
|
-
|
82
|
+
b8 = ToDecimal::Base8
|
83
|
+
b8[12] # => 10
|
77
84
|
|
78
|
-
|
85
|
+
b8['12'] # => 10
|
86
|
+
b8['012'] # => 10
|
79
87
|
```
|
80
88
|
|
81
|
-
|
82
|
-
|
89
|
+
These objects and their associated `[]` method are basically wrappers for the
|
90
|
+
`Integer.to_s.to_i(original_base)` or `String.to_i(original_base)` methods,
|
91
|
+
with a custom error when the input is not of the excpected base, or not a valid
|
92
|
+
string representation of an integer. In this case, you will get
|
93
|
+
a `WrongBaseInputError` instead of the default results of the previous methods, which can lead to unexpected results if drown into some other computations.
|
83
94
|
|
84
|
-
|
85
|
-
base8.to_d(12) # => 10
|
95
|
+
The objects are frozen and no new `Convertor` object can be instantiated.
|
86
96
|
|
87
|
-
|
97
|
+
The benefit you may find using this gem are:
|
88
98
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
### Class method
|
99
|
+
- **argument validation** : you avoid the standard behavior of the different built-in
|
100
|
+
methods, which sometimes throw an error (`Kernel#Integer(arg, base)`) or worse,
|
101
|
+
silently stop the conversion process when they encounter an invalid character, returning the result of the conversion so far. Instead, you have a consistent
|
102
|
+
behavior, and you are free to decide what to do with the error.
|
94
103
|
|
95
|
-
|
96
|
-
the
|
104
|
+
- **allow you to work with strings with leading zeros** : in this case, zeros are removed form the beginning of the string, avoiding the implict conversion in
|
105
|
+
base 8, which is, most of the time, not what you want ;
|
97
106
|
|
98
|
-
```ruby
|
99
|
-
ToDecimal.to_d(1231, base: 4)
|
100
|
-
# => 109
|
101
|
-
```
|
102
107
|
|
103
108
|
# Contribute
|
104
109
|
|
105
|
-
|
106
|
-
I would be happy to learn. And if you want to contribute, I would be happy too !
|
110
|
+
Think it could be better ? Great !
|
107
111
|
|
108
112
|
- Fork it ;
|
109
113
|
- Create your own branch (`git checkout -b my-new-feature`) ;
|
data/lib/to_decimal.rb
CHANGED
@@ -1,2 +1,21 @@
|
|
1
|
-
require_relative 'to_decimal/
|
1
|
+
require_relative 'to_decimal/validator_class'
|
2
|
+
require_relative 'to_decimal/convertor_class'
|
2
3
|
require_relative 'to_decimal/wrong_base_input_error'
|
4
|
+
|
5
|
+
module ToDecimal
|
6
|
+
Base2 = Convertor.new(2)
|
7
|
+
Base3 = Convertor.new(3)
|
8
|
+
Base4 = Convertor.new(4)
|
9
|
+
Base5 = Convertor.new(5)
|
10
|
+
Base6 = Convertor.new(6)
|
11
|
+
Base7 = Convertor.new(7)
|
12
|
+
Base8 = Convertor.new(8)
|
13
|
+
Base9 = Convertor.new(9)
|
14
|
+
Base10 = Convertor.new(10)
|
15
|
+
|
16
|
+
class Convertor
|
17
|
+
class << self
|
18
|
+
private :new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module ToDecimal
|
2
|
+
class Convertor
|
3
|
+
attr_reader :base
|
4
|
+
|
5
|
+
def initialize(base)
|
6
|
+
validate_base(base)
|
7
|
+
@base = base
|
8
|
+
self.freeze
|
9
|
+
end
|
10
|
+
|
11
|
+
def [](input)
|
12
|
+
input = remove_leading_zeros_of(input)
|
13
|
+
Validator.new(input, base).validate
|
14
|
+
|
15
|
+
input_as_integer = integerize(input)
|
16
|
+
convert(input_as_integer)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def remove_leading_zeros_of(input)
|
22
|
+
input.is_a?(String) ? input.sub(/\A0+/, '') : input
|
23
|
+
end
|
24
|
+
|
25
|
+
def convert(integer)
|
26
|
+
integer.to_s.to_i(base)
|
27
|
+
end
|
28
|
+
|
29
|
+
def integerize(input)
|
30
|
+
input.is_a?(String) ? input.to_i : input
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_base(base)
|
34
|
+
raise ArgumentError, "Base must be an Integer" unless base.is_a?(Integer)
|
35
|
+
raise ArgumentError, "Base must be 1..10" unless base > 0 && base <= 10
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ToDecimal
|
2
|
+
class Validator
|
3
|
+
def initialize(input, base)
|
4
|
+
@input = input
|
5
|
+
@base = base
|
6
|
+
end
|
7
|
+
|
8
|
+
def validate
|
9
|
+
raise ArgumentError, "Argument must be an integer or a valid string\
|
10
|
+
representation of an integer. You input : #{@input}" unless valid_integer_string_or_integer?
|
11
|
+
|
12
|
+
raise WrongBaseInputError, "A number of base #{@base} cannot have a digit\
|
13
|
+
greater or equal to #{@base}. Check your argument: #{@input}" unless valid_input_base?
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def valid_integer_string_or_integer?
|
19
|
+
@input.is_a?(Integer) || (@input.is_a?(String) && @input.to_i.to_s == @input)
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_input_base?
|
23
|
+
digitized_input = @input.to_i.digits
|
24
|
+
digitized_input.none? { |digit| digit >= @base }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/test/to_decimal_test.rb
CHANGED
@@ -4,251 +4,216 @@ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
|
4
4
|
|
5
5
|
require_relative '../lib/to_decimal'
|
6
6
|
|
7
|
-
# ==========
|
7
|
+
# ========== Test helper method ================================================
|
8
8
|
|
9
|
-
|
10
|
-
TEST_VALUES_BASE_3 = [[1122111, 3, 1201], [12, 3, 5]]
|
11
|
-
TEST_VALUES_BASE_4 = [[11001, 4, 321], [322, 4, 58]]
|
12
|
-
TEST_VALUES_BASE_5 = [[14, 5, 9], [10011302, 5, 78952]]
|
13
|
-
TEST_VALUES_BASE_6 = [[13, 6, 9], [1405304, 6, 78952]]
|
14
|
-
TEST_VALUES_BASE_7 = [[12, 7, 9], [446116, 7, 78952]]
|
15
|
-
TEST_VALUES_BASE_8 = [[11, 8, 9], [232150, 8, 78952]]
|
16
|
-
TEST_VALUES_BASE_9 = [[10, 9, 9], [130264, 9, 78952]]
|
17
|
-
TEST_VALUES_BASE_10 = [[9, 10, 9], [78952, 10, 78952]]
|
18
|
-
|
19
|
-
# ========== Test helper methods ===============================================
|
20
|
-
|
21
|
-
def execute_test_of_to_d(test_values)
|
22
|
-
test_values.each do |data_set|
|
23
|
-
@convertor.base = data_set[1]
|
24
|
-
assert_equal data_set[2], @convertor.to_d(data_set[0])
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def execute_test_of_to_d_class_method(test_values)
|
9
|
+
def execute_test_with(test_values, base_convertor)
|
29
10
|
test_values.each do |data_set|
|
30
|
-
assert_equal data_set[
|
11
|
+
assert_equal data_set[1], base_convertor[data_set[0]]
|
31
12
|
end
|
32
13
|
end
|
33
14
|
|
34
|
-
class
|
35
|
-
# ======== Setup =============================================================
|
36
|
-
|
37
|
-
def setup
|
38
|
-
@convertor = ToDecimal.new
|
39
|
-
end
|
15
|
+
class ToDecimalBaseValidationTest < Minitest::Test
|
40
16
|
|
41
|
-
|
42
|
-
|
43
|
-
def
|
44
|
-
|
17
|
+
# ======== Testing error is raises if input is not of the correct base =========
|
18
|
+
|
19
|
+
def test_raises_error_if_input_is_not_from_base_2
|
20
|
+
base2 = ToDecimal::Base2
|
21
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base2[2] }
|
22
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base2[9] }
|
45
23
|
end
|
46
24
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
25
|
+
def test_raises_error_if_input_is_not_from_base_3
|
26
|
+
base3 = ToDecimal::Base3
|
27
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base3[3] }
|
28
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base3[9] }
|
50
29
|
end
|
51
30
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
31
|
+
def test_raises_error_if_input_is_not_from_base_4
|
32
|
+
base4 = ToDecimal::Base4
|
33
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base4[4] }
|
34
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base4[9] }
|
55
35
|
end
|
56
36
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
assert_equal(2, @convertor.base)
|
62
|
-
@convertor.base = 8
|
63
|
-
assert_equal(8, @convertor.base)
|
37
|
+
def test_raises_error_if_input_is_not_from_base_5
|
38
|
+
base5 = ToDecimal::Base5
|
39
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base5[5] }
|
40
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base5[9] }
|
64
41
|
end
|
65
42
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
43
|
+
def test_raises_error_if_input_is_not_from_base_6
|
44
|
+
base6 = ToDecimal::Base6
|
45
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base6[6] }
|
46
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base6[9] }
|
69
47
|
end
|
70
48
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
assert_raises(
|
75
|
-
assert_raises(ArgumentError) { @convertor.base = :sym }
|
49
|
+
def test_raises_error_if_input_is_not_from_base_7
|
50
|
+
base7 = ToDecimal::Base7
|
51
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base7[7] }
|
52
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base7[9] }
|
76
53
|
end
|
77
54
|
|
78
|
-
def
|
79
|
-
|
55
|
+
def test_raises_error_if_input_is_not_from_base_8
|
56
|
+
base8 = ToDecimal::Base8
|
57
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base8[8] }
|
58
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base8[9] }
|
80
59
|
end
|
81
60
|
|
82
|
-
def
|
83
|
-
|
84
|
-
assert_raises(
|
61
|
+
def test_raises_error_if_input_is_not_from_base_9
|
62
|
+
base9 = ToDecimal::Base9
|
63
|
+
assert_raises(ToDecimal::WrongBaseInputError) { base9[9] }
|
85
64
|
end
|
65
|
+
end
|
86
66
|
|
87
|
-
|
88
|
-
|
89
|
-
def test_to_d_raises_error_if_input_is_not_from_base_2
|
90
|
-
@convertor.base = 2
|
91
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(2) }
|
92
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(9) }
|
93
|
-
end
|
67
|
+
# ========= Testing return values of [] instance method ========================
|
94
68
|
|
95
|
-
|
96
|
-
@convertor.base = 3
|
97
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(3) }
|
98
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(9) }
|
99
|
-
end
|
69
|
+
class ToDecimalConvserionFromIntegerTest < Minitest::Test
|
100
70
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
71
|
+
# Test data
|
72
|
+
TEST_VALUES_BASE_2 = [[101, 5], [100_000_000, 256]]
|
73
|
+
TEST_VALUES_BASE_3 = [[1122111, 1201], [12, 5]]
|
74
|
+
TEST_VALUES_BASE_4 = [[11001, 321], [322, 58]]
|
75
|
+
TEST_VALUES_BASE_5 = [[14, 9], [10011302, 78952]]
|
76
|
+
TEST_VALUES_BASE_6 = [[13, 9], [1405304, 78952]]
|
77
|
+
TEST_VALUES_BASE_7 = [[12, 9], [446116, 78952]]
|
78
|
+
TEST_VALUES_BASE_8 = [[11, 9], [232150, 78952]]
|
79
|
+
TEST_VALUES_BASE_9 = [[10, 9], [130264, 78952]]
|
80
|
+
TEST_VALUES_BASE_10 = [[9, 9], [78952, 78952]]
|
106
81
|
|
107
|
-
def
|
108
|
-
|
109
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(5) }
|
110
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(9) }
|
82
|
+
def test_returns_decimal_value_of_integer_of_base_2
|
83
|
+
execute_test_with(TEST_VALUES_BASE_2, ToDecimal::Base2)
|
111
84
|
end
|
112
85
|
|
113
|
-
def
|
114
|
-
|
115
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(6) }
|
116
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(9) }
|
86
|
+
def test_returns_decimal_value_of_integer_of_base_3
|
87
|
+
execute_test_with(TEST_VALUES_BASE_3, ToDecimal::Base3)
|
117
88
|
end
|
118
89
|
|
119
|
-
def
|
120
|
-
|
121
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(7) }
|
122
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(9) }
|
90
|
+
def test_returns_decimal_value_of_integer_of_base_4
|
91
|
+
execute_test_with(TEST_VALUES_BASE_4, ToDecimal::Base4)
|
123
92
|
end
|
124
93
|
|
125
|
-
def
|
126
|
-
|
127
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(8) }
|
128
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(9) }
|
94
|
+
def test_returns_decimal_value_of_integer_of_base_5
|
95
|
+
execute_test_with(TEST_VALUES_BASE_5, ToDecimal::Base5)
|
129
96
|
end
|
130
97
|
|
131
|
-
def
|
132
|
-
|
133
|
-
assert_raises(WrongBaseInputError) { @convertor.to_d(9) }
|
98
|
+
def test_returns_decimal_value_of_integer_of_base_6
|
99
|
+
execute_test_with(TEST_VALUES_BASE_6, ToDecimal::Base6)
|
134
100
|
end
|
135
101
|
|
136
|
-
|
137
|
-
|
138
|
-
def test_to_d_returns_decimal_value_of_number_of_base_2
|
139
|
-
execute_test_of_to_d(TEST_VALUES_BASE_2)
|
102
|
+
def test_returns_decimal_value_of_integer_of_base_7
|
103
|
+
execute_test_with(TEST_VALUES_BASE_7, ToDecimal::Base7)
|
140
104
|
end
|
141
105
|
|
142
|
-
def
|
143
|
-
|
106
|
+
def test_returns_decimal_value_of_integer_of_base_8
|
107
|
+
execute_test_with(TEST_VALUES_BASE_8, ToDecimal::Base8)
|
144
108
|
end
|
145
109
|
|
146
|
-
def
|
147
|
-
|
110
|
+
def test_returns_decimal_value_of_integer_of_base_9
|
111
|
+
execute_test_with(TEST_VALUES_BASE_9, ToDecimal::Base9)
|
148
112
|
end
|
149
113
|
|
150
|
-
def
|
151
|
-
|
114
|
+
def test_returns_decimal_value_of_integer_of_base_10
|
115
|
+
execute_test_with(TEST_VALUES_BASE_10, ToDecimal::Base10)
|
152
116
|
end
|
117
|
+
end
|
153
118
|
|
154
|
-
|
155
|
-
|
156
|
-
|
119
|
+
class ToDecimalConvserionFromStringTest < Minitest::Test
|
120
|
+
TEST_VALUES_BASE_2 = [['101', 5], ['100000000', 256]]
|
121
|
+
TEST_VALUES_BASE_3 = [['1122111', 1201], ['12', 5]]
|
122
|
+
TEST_VALUES_BASE_4 = [['11001', 321], ['322', 58]]
|
123
|
+
TEST_VALUES_BASE_5 = [['14', 9], ['10011302', 78952]]
|
124
|
+
TEST_VALUES_BASE_6 = [['13', 9], ['1405304', 78952]]
|
125
|
+
TEST_VALUES_BASE_7 = [['12', 9], ['446116', 78952]]
|
126
|
+
TEST_VALUES_BASE_8 = [['11', 9], ['232150', 78952]]
|
127
|
+
TEST_VALUES_BASE_9 = [['10', 9], ['130264', 78952]]
|
128
|
+
TEST_VALUES_BASE_10 = [['9', 9], ['78952', 78952]]
|
157
129
|
|
158
|
-
def
|
159
|
-
|
130
|
+
def test_returns_decimal_value_of_string_of_base_2
|
131
|
+
execute_test_with(TEST_VALUES_BASE_2, ToDecimal::Base2)
|
160
132
|
end
|
161
133
|
|
162
|
-
def
|
163
|
-
|
134
|
+
def test_returns_decimal_value_of_string_of_base_3
|
135
|
+
execute_test_with(TEST_VALUES_BASE_3, ToDecimal::Base3)
|
164
136
|
end
|
165
137
|
|
166
|
-
def
|
167
|
-
|
138
|
+
def test_returns_decimal_value_of_string_of_base_4
|
139
|
+
execute_test_with(TEST_VALUES_BASE_4, ToDecimal::Base4)
|
168
140
|
end
|
169
141
|
|
170
|
-
def
|
171
|
-
|
142
|
+
def test_returns_decimal_value_of_string_of_base_5
|
143
|
+
execute_test_with(TEST_VALUES_BASE_5, ToDecimal::Base5)
|
172
144
|
end
|
173
145
|
|
174
|
-
|
175
|
-
|
176
|
-
def test_square_brackets_is_alias_for_to_d
|
177
|
-
convertor = ToDecimal.new(10)
|
178
|
-
assert_equal(200, convertor[200])
|
146
|
+
def test_returns_decimal_value_of_string_of_base_6
|
147
|
+
execute_test_with(TEST_VALUES_BASE_6, ToDecimal::Base6)
|
179
148
|
end
|
180
149
|
|
181
|
-
|
182
|
-
|
183
|
-
def test_to_d_class_method_accepts_integers_for_both_parameters
|
184
|
-
assert_silent { ToDecimal.to_d(101, base: 2) }
|
150
|
+
def test_returns_decimal_value_of_string_of_base_7
|
151
|
+
execute_test_with(TEST_VALUES_BASE_7, ToDecimal::Base7)
|
185
152
|
end
|
186
153
|
|
187
|
-
def
|
188
|
-
|
154
|
+
def test_returns_decimal_value_of_string_of_base_8
|
155
|
+
execute_test_with(TEST_VALUES_BASE_8, ToDecimal::Base8)
|
189
156
|
end
|
190
|
-
|
191
|
-
def test_to_d_class_method_accepts_mixed_strings_and_integers_as_args
|
192
|
-
assert_silent { ToDecimal.to_d('101', base: 2) }
|
193
|
-
assert_silent { ToDecimal.to_d(101, base: '2') }
|
194
|
-
end
|
195
|
-
|
196
|
-
# ======== Testing to_d class method raises error with invalid parameters ====
|
197
157
|
|
198
|
-
def
|
199
|
-
|
200
|
-
assert_raises(ArgumentError) { ToDecimal.to_d([4], base: 5) }
|
158
|
+
def test_returns_decimal_value_of_string_of_base_9
|
159
|
+
execute_test_with(TEST_VALUES_BASE_9, ToDecimal::Base9)
|
201
160
|
end
|
202
161
|
|
203
|
-
def
|
204
|
-
|
205
|
-
assert_raises(ArgumentError) { ToDecimal.to_d(45, base: :sym) }
|
162
|
+
def test_returns_decimal_value_of_string_of_base_10
|
163
|
+
execute_test_with(TEST_VALUES_BASE_10, ToDecimal::Base10)
|
206
164
|
end
|
165
|
+
end
|
207
166
|
|
208
|
-
|
209
|
-
|
210
|
-
|
167
|
+
class RemoveLeadingZeroesFromStringsTest < Minitest::Test
|
168
|
+
TEST_VALUES_BASE_2 = [['00101', 5], ['0100000000', 256]]
|
169
|
+
TEST_VALUES_BASE_3 = [['001122111', 1201], ['012', 5]]
|
170
|
+
TEST_VALUES_BASE_4 = [['0011001', 321], ['322', 58]]
|
171
|
+
TEST_VALUES_BASE_5 = [['0014', 9], ['010011302', 78952]]
|
172
|
+
TEST_VALUES_BASE_6 = [['0013', 9], ['01405304', 78952]]
|
173
|
+
TEST_VALUES_BASE_7 = [['0012', 9], ['0446116', 78952]]
|
174
|
+
TEST_VALUES_BASE_8 = [['0011', 9], ['0232150', 78952]]
|
175
|
+
TEST_VALUES_BASE_9 = [['0010', 9], ['0130264', 78952]]
|
176
|
+
TEST_VALUES_BASE_10 = [['009', 9], ['078952', 78952]]
|
211
177
|
|
212
|
-
def
|
213
|
-
|
214
|
-
assert_raises(ArgumentError) { ToDecimal.to_d(456, base: -8) }
|
178
|
+
def test_removes_leading_zeros_from_string_with_base2
|
179
|
+
execute_test_with(TEST_VALUES_BASE_2, ToDecimal::Base2)
|
215
180
|
end
|
216
181
|
|
217
|
-
|
218
|
-
|
219
|
-
def test_to_d_class_method_returns_decimal_value_of_number_of_base_2
|
220
|
-
execute_test_of_to_d_class_method(TEST_VALUES_BASE_2)
|
182
|
+
def test_removes_leading_zeros_from_string_with_base3
|
183
|
+
execute_test_with(TEST_VALUES_BASE_3, ToDecimal::Base3)
|
221
184
|
end
|
222
185
|
|
223
|
-
def
|
224
|
-
|
186
|
+
def test_removes_leading_zeros_from_string_with_base4
|
187
|
+
execute_test_with(TEST_VALUES_BASE_4, ToDecimal::Base4)
|
225
188
|
end
|
226
189
|
|
227
|
-
def
|
228
|
-
|
190
|
+
def test_removes_leading_zeros_from_string_with_base5
|
191
|
+
execute_test_with(TEST_VALUES_BASE_5, ToDecimal::Base5)
|
229
192
|
end
|
230
193
|
|
231
|
-
def
|
232
|
-
|
194
|
+
def test_removes_leading_zeros_from_string_with_base6
|
195
|
+
execute_test_with(TEST_VALUES_BASE_6, ToDecimal::Base6)
|
233
196
|
end
|
234
197
|
|
235
|
-
def
|
236
|
-
|
198
|
+
def test_removes_leading_zeros_from_string_with_base7
|
199
|
+
execute_test_with(TEST_VALUES_BASE_7, ToDecimal::Base7)
|
237
200
|
end
|
238
201
|
|
239
|
-
def
|
240
|
-
|
202
|
+
def test_removes_leading_zeros_from_string_with_base8
|
203
|
+
execute_test_with(TEST_VALUES_BASE_8, ToDecimal::Base8)
|
241
204
|
end
|
242
205
|
|
243
|
-
def
|
244
|
-
|
206
|
+
def test_removes_leading_zeros_from_string_with_base9
|
207
|
+
execute_test_with(TEST_VALUES_BASE_9, ToDecimal::Base9)
|
245
208
|
end
|
246
209
|
|
247
|
-
def
|
248
|
-
|
210
|
+
def test_removes_leading_zeros_from_string_with_base10
|
211
|
+
execute_test_with(TEST_VALUES_BASE_10, ToDecimal::Base10)
|
249
212
|
end
|
213
|
+
end
|
250
214
|
|
251
|
-
|
252
|
-
|
215
|
+
class ConvertorCannotBeInstantiatedTest < Minitest::Test
|
216
|
+
def test_raises_error_if_user_tries_to_instantiate_new_convertor
|
217
|
+
assert_raises(NoMethodError) { ToDecimal::Convertor.new }
|
253
218
|
end
|
254
|
-
end
|
219
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: to_decimal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laurent Guinotte
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -81,7 +81,8 @@ files:
|
|
81
81
|
- README.md
|
82
82
|
- Rakefile
|
83
83
|
- lib/to_decimal.rb
|
84
|
-
- lib/to_decimal/
|
84
|
+
- lib/to_decimal/convertor_class.rb
|
85
|
+
- lib/to_decimal/validator_class.rb
|
85
86
|
- lib/to_decimal/wrong_base_input_error.rb
|
86
87
|
- test/to_decimal_test.rb
|
87
88
|
homepage: https://github.com/loranger32/to_decimal
|
@@ -89,7 +90,7 @@ licenses:
|
|
89
90
|
- MIT
|
90
91
|
metadata:
|
91
92
|
source_code_uri: https://github.com/loranger32/to_decimal
|
92
|
-
changelog_uri: https://github.com/blob/master/CHANGELOG.md
|
93
|
+
changelog_uri: https://github.com/loranger32/blob/master/CHANGELOG.md
|
93
94
|
post_install_message:
|
94
95
|
rdoc_options: []
|
95
96
|
require_paths:
|
@@ -1,60 +0,0 @@
|
|
1
|
-
class ToDecimal
|
2
|
-
attr_reader :base
|
3
|
-
|
4
|
-
def self.to_d(digit, base: 10)
|
5
|
-
self.new(base).to_d(digit)
|
6
|
-
end
|
7
|
-
|
8
|
-
def initialize(base=10)
|
9
|
-
@base = format_and_validate(base)
|
10
|
-
end
|
11
|
-
|
12
|
-
def base=(new_base)
|
13
|
-
@base = format_and_validate(new_base)
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_d(input)
|
17
|
-
formatted_input = format(input).digits
|
18
|
-
validate_input(formatted_input)
|
19
|
-
decimal = 0
|
20
|
-
formatted_input.each_with_index do |digit, power|
|
21
|
-
decimal += digit * (base**power)
|
22
|
-
end
|
23
|
-
decimal
|
24
|
-
end
|
25
|
-
|
26
|
-
alias_method :[], :to_d
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def format(input)
|
31
|
-
if input.is_a?(String) || input.is_a?(Integer)
|
32
|
-
if input.is_a?(String)
|
33
|
-
input.to_i
|
34
|
-
else
|
35
|
-
input
|
36
|
-
end
|
37
|
-
else
|
38
|
-
raise ArgumentError, "Integer or String representation of an Integer\
|
39
|
-
expected as input or base"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def validate_base(base)
|
44
|
-
raise ArgumentError, "Base must be an Integer" unless base.is_a?(Integer)
|
45
|
-
raise ArgumentError, "Base must be 1..10" unless base > 0 && base <= 10
|
46
|
-
end
|
47
|
-
|
48
|
-
def format_and_validate(base)
|
49
|
-
formatted_base = format(base)
|
50
|
-
validate_base(formatted_base)
|
51
|
-
formatted_base
|
52
|
-
end
|
53
|
-
|
54
|
-
def validate_input(formatted_input)
|
55
|
-
if formatted_input.any? { |digit| digit >= base }
|
56
|
-
raise WrongBaseInputError, "A number of base #{base} cannot have a digit\
|
57
|
-
greater or equal to #{base}. Check your input: #{formatted_input.reverse.join}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|