to_decimal 0.0.2 → 1.0.0
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 +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
|