to_decimal 1.0.2 → 2.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
  SHA256:
3
- metadata.gz: 8f2107e719ece63eefe7d9a46e2731ad6fa69989d860bcfc716b73564814bd04
4
- data.tar.gz: 3f079c1a415277cbdc01e65d8400d596b065197727b88ce2cdd90cc30489ecd8
3
+ metadata.gz: 3b6653d23069ad770aaea5c3c964526f4af9d834d55b011ffdb0b3ea78077340
4
+ data.tar.gz: e0c1d4c94a2db2d31b1a46cc32a5b26842832aab4aa992a53a594d557fc55ca9
5
5
  SHA512:
6
- metadata.gz: 9ef794b8ea307148bf1979d0f1e7045b535db7028e6bc81985983416e6671b7ee110d80e7684a5793347f2c6fbb61263f10b7cc1ee71f265f96e02d6f727664d
7
- data.tar.gz: 446e43db18be25ba8f05232ff590e536ac9dd3eb254aa1c874f0061310eed0546918f666997fd969b76f33868a57afcb985d21c663667b1cd4f9343ddd7ea9d1
6
+ metadata.gz: 67c5be620307348487f0e492a41ba7b81427fa4b5b880a8cd3b14859d4f9cc3432ec4fcdfb1b84d84d431e73c923ad3cf2eb6d68df32da3f5d88339483da6130
7
+ data.tar.gz: 1e80bec78c78e43922f6a7372f796d76135fc8515be84ac6b85d73a8974eb5db81f7bb6db32ba57fb6bdfc540001cda78b476b62d579be4b27001a6f7adcef59
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # to_decimal 2.0.0 (2022-10-02)
2
+ ---
3
+ New Features :
4
+ - Allow instantiation of new base objects
5
+ - Allow usage of bases up to 36
6
+
7
+ Breaking Changes :
8
+
9
+ - `WrongBaseInputError` is renamed `WrongInputBaseError`
10
+ - The `Base2`, `Base3`, ... `Base10` constants are no longer provided, you need to instantiate Base object yourself
11
+
12
+ Other :
13
+ - Change Convertor class name to Base
14
+ - Update development dependecies and use Standard instead of Rubocop for linting
15
+
1
16
  # to_decimal 1.0.2 (2019-12-20)
2
17
  ---
3
18
  - fix a bug by removing the require statements at the top of `lib/to_decimal.rb`
data/README.md CHANGED
@@ -1,16 +1,15 @@
1
- # to_decimal (Version 1.0.2)
1
+ # to_decimal (Version 2.0.0)
2
2
 
3
- A simple gem to convert an integer expressed in bases
4
- ranging from 2 to 10 into a decimal integer.
3
+ A simple gem to convert an integer or string representation of an integer expressed in bases
4
+ ranging from 2 to 36 into a decimal integer.
5
5
 
6
- Ruby comes with useful built-in methods to convert integers and string
6
+ Ruby comes with built-in methods to convert integers and string
7
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
8
  [`Kernel#Integer(arg, base=0)`](https://ruby-doc.com/core-2.5.2/Kernel.html#method-i-Integer) and
9
9
  [`Integer#to_s(base=10)`](http://ruby-doc.org/core-2.5.3/Integer.html#method-i-to_s).
10
10
 
11
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):
12
+ for binary, octal, decimal and hexadecimal notation :
14
13
 
15
14
  ```ruby
16
15
  # binary
@@ -26,31 +25,39 @@ the most usecases):
26
25
  0x17 # => 23
27
26
  ```
28
27
 
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):
28
+ For other bases ranging from 2 to 36, you can proceed like this :
31
29
 
32
30
  ```ruby
33
31
  12.to_s.to_i(6) # => 8
32
+ # OR
33
+ Integer("12", 6) # => 8)
34
34
  ```
35
35
 
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.
36
+ The `Kernel#Integer` method raises useful error messages when using invalid arguments.
40
37
 
41
- I've looked in the core API and in the Standard Library, but I didn't find
42
- anything.
38
+ ```
39
+ Integer "17", 6 # => `Integer': invalid value for Integer(): "17" (ArgumentError)
40
+
41
+ Integer "17, 37 # => `Integer': invalid radix 37 (ArgumentError)
42
+ ```
43
43
 
44
- I found the following two gems :
44
+ The `String#to_i` method on the other hand also raises an ArgumentError when trying to use an invalid radix, _but_ if the string value does not represent a valid integer, or an integer that doesn't match the provided base, the method silently stop the conversion process when it encounters an invalid character, and returns the result of the conversion so far :
45
+
46
+ ```
47
+ "17".to_i(37) # => invalid radix 37 (ArgumentError)
48
+ "17".to_i(6) # => 1
49
+ "12378".to_i(6) # => 51
50
+ ```
51
+
52
+ This gem is simply a wrapper around the `String#to_i` and `Kernel#Integer` methods, with some argument validations and useful error messages.
53
+
54
+ If you need more features, checkout these twp gems :
45
55
  - [bases](https://github.com/whatyouhide/bases) ;
46
56
  - [radix](https://github.com/rubyworks/radix) ;
47
57
 
48
58
  They are very comprehensive, go both behind the base 36, which is the limit
49
59
  of Ruby, and allow to convert form bases back and forth.
50
60
 
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.
54
61
 
55
62
  # Installation
56
63
  ```shell
@@ -77,42 +84,35 @@ This project is tested under minitest.
77
84
 
78
85
  # Usage
79
86
 
80
- The gem gives you access to 9 objects under the namespace `ToDecimal` called :
81
- `Base2`, `Base3`,... `Base10`.
87
+ You can create a `ToDecimal::Base` object with the required base as an integer argument :
82
88
 
83
- Each object has a `[]` method, which takes as parameter an integer OR a string
84
- representation of the corresponding base and returns this integer expressed
89
+ ```ruby
90
+ b8 = ToDecimal::Base.new(8)
91
+ ```
92
+
93
+ Each object is frozen after initialisation and exposes a `[]` method, which takes as argument an integer OR a string
94
+ representation of an integer of the corresponding base and returns this integer expressed
85
95
  in base 10 :
86
96
 
87
97
  ```ruby
88
- base2 = ToDecimal::Base2
98
+ base2 = ToDecimal::Base.new(2)
89
99
  base2[10] # => 2
100
+ base2["10"] # => 2
101
+ base2["010"] # => 2
90
102
 
91
- b8 = ToDecimal::Base8
103
+ b8 = ToDecimal::Base.new(8)
92
104
  b8[12] # => 10
93
-
94
105
  b8['12'] # => 10
95
106
  b8['012'] # => 10
96
- ```
97
107
 
98
- These objects and their associated `[]` method are basically wrappers for the
99
- `Integer.to_s.to_i(original_base)` or `String.to_i(original_base)` methods,
100
- with a custom error when the input is not of the excpected base, or not a valid
101
- string representation of an integer. In this case, you will get
102
- a `WrongBaseInputError` instead of the default results of the previous methods, which can lead to unexpected results if drown into some other computations.
108
+ b8["99"]
109
+ # => raises : A number of base 8 cannot have a digit greater or equal to '7'. Check your argument: '99'. (ToDecimal::WrongInputBaseError)
103
110
 
104
- The objects are frozen and no new `Convertor` object can be instantiated.
105
-
106
- The benefit you may find using this gem are:
107
-
108
- - **argument validation** : you avoid the standard behavior of the different built-in
109
- methods, which sometimes throw an error (`Kernel#Integer(arg, base)`) or worse,
110
- silently stop the conversion process when they encounter an invalid character, returning the result of the conversion so far. Instead, you have a consistent
111
- behavior, and you are free to decide what to do with the error.
112
-
113
- - **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
114
- base 8, which is, most of the time, not what you want ;
111
+ b36 = ToDecimal::Base.new(36)
112
+ b36[12] # => 38
113
+ b36["ruby"] # => 1299022
115
114
 
115
+ ```
116
116
 
117
117
  # Contribute
118
118
 
@@ -133,5 +133,4 @@ Laurent Guinotte
133
133
 
134
134
  # Licence
135
135
 
136
- to_decimal is released under the MIT Licence. See LICENCE.txt
137
- for further details.
136
+ MIT
@@ -0,0 +1,73 @@
1
+ module ToDecimal
2
+ class WrongInputBaseError < ArgumentError; end
3
+
4
+ NUMBERS = %w[0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z].freeze
5
+
6
+ class Base
7
+ attr_reader :base
8
+
9
+ def initialize(base)
10
+ validate_base(base)
11
+ @base = base
12
+ freeze
13
+ end
14
+
15
+ def [](input)
16
+ validate_input(input)
17
+
18
+ convert(input)
19
+ end
20
+
21
+ private
22
+
23
+ def convert(input)
24
+ if input.is_a?(Integer)
25
+ input.to_s.to_i(base)
26
+ else
27
+ Integer(input, base)
28
+ end
29
+ end
30
+
31
+ def validate_base(base)
32
+ raise ArgumentError, "Base must be an Integer" unless base.is_a?(Integer)
33
+ raise ArgumentError, "Base must be 2..36" unless \
34
+ (2..36) === base
35
+ end
36
+
37
+ def validate_input(input)
38
+ err_value = "Argument must be an integer or a valid string\
39
+ representation of an integer. You input : #{input}, of class #{input.class}."
40
+ raise ArgumentError, err_value unless valid_integer_string_or_integer?(input)
41
+
42
+ err_base = "A number of base #{base} cannot have a\
43
+ digit greater than '#{NUMBERS[base - 1]}'. Check your argument: '#{input}'."
44
+ raise WrongInputBaseError, err_base unless valid_input_base?(input)
45
+ end
46
+
47
+ def valid_integer_string_or_integer?(input)
48
+ valid_integer?(input) || valid_integer_string?(input)
49
+ end
50
+
51
+ def valid_integer?(input)
52
+ input.is_a?(Integer)
53
+ end
54
+
55
+ def valid_integer_string?(input)
56
+ return false unless input.is_a?(String)
57
+ input = remove_leading_zeros(input)
58
+
59
+ return false unless input.match?(/\A[a-z0-9]+\z/i)
60
+ true
61
+ end
62
+
63
+ def valid_input_base?(input)
64
+ input = input.to_s
65
+ digitized_input = input.chars.map(&:downcase)
66
+ digitized_input.none? { |digit| NUMBERS.index(digit) > base - 1 }
67
+ end
68
+
69
+ def remove_leading_zeros(input)
70
+ input.sub(/\A0+/, "")
71
+ end
72
+ end
73
+ end
data/lib/to_decimal.rb CHANGED
@@ -1,22 +1 @@
1
- require_relative 'to_decimal/validator_class'
2
- require_relative 'to_decimal/convertor_class'
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
- # Ensure no other convertor object will be created
17
- class Convertor
18
- class << self
19
- private :new
20
- end
21
- end
22
- end
1
+ require_relative "to_decimal/base_class"
@@ -1,221 +1,62 @@
1
- require 'minitest/autorun'
2
- require 'minitest/reporters'
1
+ require "minitest/autorun"
2
+ require "minitest/reporters"
3
3
  Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
4
4
 
5
- require_relative '../lib/to_decimal'
5
+ require_relative "../lib/to_decimal"
6
6
 
7
- class ToDecimalBaseValidationTest < Minitest::Test
8
-
9
- # ======== Testing error is raised if input is not of the correct base =======
10
-
11
- def test_raises_error_if_input_is_not_from_base_2
12
- base2 = ToDecimal::Base2
13
- assert_raises(ToDecimal::WrongBaseInputError) { base2[2] }
14
- assert_raises(ToDecimal::WrongBaseInputError) { base2[9] }
15
- end
16
-
17
- def test_raises_error_if_input_is_not_from_base_3
18
- base3 = ToDecimal::Base3
19
- assert_raises(ToDecimal::WrongBaseInputError) { base3[3] }
20
- assert_raises(ToDecimal::WrongBaseInputError) { base3[9] }
21
- end
22
-
23
- def test_raises_error_if_input_is_not_from_base_4
24
- base4 = ToDecimal::Base4
25
- assert_raises(ToDecimal::WrongBaseInputError) { base4[4] }
26
- assert_raises(ToDecimal::WrongBaseInputError) { base4[9] }
27
- end
28
-
29
- def test_raises_error_if_input_is_not_from_base_5
30
- base5 = ToDecimal::Base5
31
- assert_raises(ToDecimal::WrongBaseInputError) { base5[5] }
32
- assert_raises(ToDecimal::WrongBaseInputError) { base5[9] }
33
- end
34
-
35
- def test_raises_error_if_input_is_not_from_base_6
36
- base6 = ToDecimal::Base6
37
- assert_raises(ToDecimal::WrongBaseInputError) { base6[6] }
38
- assert_raises(ToDecimal::WrongBaseInputError) { base6[9] }
39
- end
40
-
41
- def test_raises_error_if_input_is_not_from_base_7
42
- base7 = ToDecimal::Base7
43
- assert_raises(ToDecimal::WrongBaseInputError) { base7[7] }
44
- assert_raises(ToDecimal::WrongBaseInputError) { base7[9] }
45
- end
46
-
47
- def test_raises_error_if_input_is_not_from_base_8
48
- base8 = ToDecimal::Base8
49
- assert_raises(ToDecimal::WrongBaseInputError) { base8[8] }
50
- assert_raises(ToDecimal::WrongBaseInputError) { base8[9] }
51
- end
52
-
53
- def test_raises_error_if_input_is_not_from_base_9
54
- base9 = ToDecimal::Base9
55
- assert_raises(ToDecimal::WrongBaseInputError) { base9[9] }
56
- end
57
- end
58
-
59
- # ========= Testing return values of [] method =================================
60
-
61
- # ========= Test helper method
62
-
63
- def execute_test_with(test_values, base_convertor)
64
- test_values.each do |data_set|
65
- assert_equal data_set[1], base_convertor[data_set[0]]
66
- end
67
- end
68
-
69
- # ========= Test class
70
-
71
- class ToDecimalConvserionFromIntegerTest < Minitest::Test
72
-
73
- # Test data
74
- TEST_VALUES_BASE_2 = [[101, 5], [100_000_000, 256]].freeze
75
- TEST_VALUES_BASE_3 = [[1_122_111, 1201], [12, 5]].freeze
76
- TEST_VALUES_BASE_4 = [[11_001, 321], [322, 58]].freeze
77
- TEST_VALUES_BASE_5 = [[14, 9], [10_011_302, 78_952]].freeze
78
- TEST_VALUES_BASE_6 = [[13, 9], [1_405_304, 78_952]].freeze
79
- TEST_VALUES_BASE_7 = [[12, 9], [446_116, 78_952]].freeze
80
- TEST_VALUES_BASE_8 = [[11, 9], [232_150, 78_952]].freeze
81
- TEST_VALUES_BASE_9 = [[10, 9], [130_264, 78_952]].freeze
82
- TEST_VALUES_BASE_10 = [[9, 9], [78_952, 78_952]].freeze
83
-
84
- def test_returns_decimal_value_of_integer_of_base_2
85
- execute_test_with(TEST_VALUES_BASE_2, ToDecimal::Base2)
86
- end
87
-
88
- def test_returns_decimal_value_of_integer_of_base_3
89
- execute_test_with(TEST_VALUES_BASE_3, ToDecimal::Base3)
90
- end
91
-
92
- def test_returns_decimal_value_of_integer_of_base_4
93
- execute_test_with(TEST_VALUES_BASE_4, ToDecimal::Base4)
94
- end
95
-
96
- def test_returns_decimal_value_of_integer_of_base_5
97
- execute_test_with(TEST_VALUES_BASE_5, ToDecimal::Base5)
98
- end
99
-
100
- def test_returns_decimal_value_of_integer_of_base_6
101
- execute_test_with(TEST_VALUES_BASE_6, ToDecimal::Base6)
102
- end
103
-
104
- def test_returns_decimal_value_of_integer_of_base_7
105
- execute_test_with(TEST_VALUES_BASE_7, ToDecimal::Base7)
106
- end
107
-
108
- def test_returns_decimal_value_of_integer_of_base_8
109
- execute_test_with(TEST_VALUES_BASE_8, ToDecimal::Base8)
110
- end
111
-
112
- def test_returns_decimal_value_of_integer_of_base_9
113
- execute_test_with(TEST_VALUES_BASE_9, ToDecimal::Base9)
114
- end
115
-
116
- def test_returns_decimal_value_of_integer_of_base_10
117
- execute_test_with(TEST_VALUES_BASE_10, ToDecimal::Base10)
118
- end
119
- end
120
-
121
- class ToDecimalConvserionFromStringTest < Minitest::Test
122
- TEST_VALUES_BASE_2 = [['101', 5], ['100000000', 256]].freeze
123
- TEST_VALUES_BASE_3 = [['1122111', 1_201], ['12', 5]].freeze
124
- TEST_VALUES_BASE_4 = [['11001', 321], ['322', 58]].freeze
125
- TEST_VALUES_BASE_5 = [['14', 9], ['10011302', 78_952]].freeze
126
- TEST_VALUES_BASE_6 = [['13', 9], ['1405304', 78_952]].freeze
127
- TEST_VALUES_BASE_7 = [['12', 9], ['446116', 78_952]].freeze
128
- TEST_VALUES_BASE_8 = [['11', 9], ['232150', 78_952]].freeze
129
- TEST_VALUES_BASE_9 = [['10', 9], ['130264', 78_952]].freeze
130
- TEST_VALUES_BASE_10 = [['9', 9], ['78952', 78_952]].freeze
131
-
132
- def test_returns_decimal_value_of_string_of_base_2
133
- execute_test_with(TEST_VALUES_BASE_2, ToDecimal::Base2)
134
- end
135
-
136
- def test_returns_decimal_value_of_string_of_base_3
137
- execute_test_with(TEST_VALUES_BASE_3, ToDecimal::Base3)
138
- end
139
-
140
- def test_returns_decimal_value_of_string_of_base_4
141
- execute_test_with(TEST_VALUES_BASE_4, ToDecimal::Base4)
142
- end
143
-
144
- def test_returns_decimal_value_of_string_of_base_5
145
- execute_test_with(TEST_VALUES_BASE_5, ToDecimal::Base5)
146
- end
147
-
148
- def test_returns_decimal_value_of_string_of_base_6
149
- execute_test_with(TEST_VALUES_BASE_6, ToDecimal::Base6)
150
- end
151
-
152
- def test_returns_decimal_value_of_string_of_base_7
153
- execute_test_with(TEST_VALUES_BASE_7, ToDecimal::Base7)
154
- end
155
-
156
- def test_returns_decimal_value_of_string_of_base_8
157
- execute_test_with(TEST_VALUES_BASE_8, ToDecimal::Base8)
158
- end
159
-
160
- def test_returns_decimal_value_of_string_of_base_9
161
- execute_test_with(TEST_VALUES_BASE_9, ToDecimal::Base9)
162
- end
163
-
164
- def test_returns_decimal_value_of_string_of_base_10
165
- execute_test_with(TEST_VALUES_BASE_10, ToDecimal::Base10)
7
+ class ToDecimalTest < Minitest::Test
8
+ def test_base_object_can_be_initialized_with_correct_argument
9
+ (2..36).to_a.each do |valid_base|
10
+ assert_silent { ToDecimal::Base.new(valid_base) }
11
+ end
166
12
  end
167
- end
168
-
169
- class RemoveLeadingZeroesFromStringsTest < Minitest::Test
170
- TEST_VALUES_BASE_2 = [['00101', 5], ['0100000000', 256]].freeze
171
- TEST_VALUES_BASE_3 = [['001122111', 1_201], ['012', 5]].freeze
172
- TEST_VALUES_BASE_4 = [['0011001', 321], ['322', 58]].freeze
173
- TEST_VALUES_BASE_5 = [['0014', 9], ['010011302', 78_952]].freeze
174
- TEST_VALUES_BASE_6 = [['0013', 9], ['01405304', 78_952]].freeze
175
- TEST_VALUES_BASE_7 = [['0012', 9], ['0446116', 78_952]].freeze
176
- TEST_VALUES_BASE_8 = [['0011', 9], ['0232150', 78_952]].freeze
177
- TEST_VALUES_BASE_9 = [['0010', 9], ['0130264', 78_952]].freeze
178
- TEST_VALUES_BASE_10 = [['009', 9], ['078952', 78_952]].freeze
179
13
 
180
- def test_removes_leading_zeros_from_string_with_base2
181
- execute_test_with(TEST_VALUES_BASE_2, ToDecimal::Base2)
14
+ def test_base_object_initialisation_raises_if_incorrect_argument
15
+ [1, 37, "10", "a", :a].each do |invalid_base|
16
+ assert_raises(ArgumentError) { ToDecimal::Base.new(invalid_base) }
17
+ end
182
18
  end
183
19
 
184
- def test_removes_leading_zeros_from_string_with_base3
185
- execute_test_with(TEST_VALUES_BASE_3, ToDecimal::Base3)
186
- end
20
+ def test_raises_wrong_input_base_error_if_input_is_not_of_the_correct_base
21
+ base2 = ToDecimal::Base.new(2)
22
+ assert_raises(ToDecimal::WrongInputBaseError) { base2[2] }
23
+ assert_raises(ToDecimal::WrongInputBaseError) { base2["2"] }
24
+ assert_raises(ToDecimal::WrongInputBaseError) { base2["02"] }
187
25
 
188
- def test_removes_leading_zeros_from_string_with_base4
189
- execute_test_with(TEST_VALUES_BASE_4, ToDecimal::Base4)
190
- end
26
+ base10 = ToDecimal::Base.new(10)
27
+ assert_raises(ToDecimal::WrongInputBaseError) { base10["a"] }
28
+ assert_raises(ToDecimal::WrongInputBaseError) { base10["0a"] }
29
+ assert_raises(ToDecimal::WrongInputBaseError) { base10["A"] }
191
30
 
192
- def test_removes_leading_zeros_from_string_with_base5
193
- execute_test_with(TEST_VALUES_BASE_5, ToDecimal::Base5)
31
+ base35 = ToDecimal::Base.new(35)
32
+ assert_raises(ToDecimal::WrongInputBaseError) { base35["z"] }
33
+ assert_raises(ToDecimal::WrongInputBaseError) { base35["0z"] }
194
34
  end
195
35
 
196
- def test_removes_leading_zeros_from_string_with_base6
197
- execute_test_with(TEST_VALUES_BASE_6, ToDecimal::Base6)
198
- end
36
+ def test_returns_correct_value_as_integer
37
+ base2 = ToDecimal::Base.new(2)
38
+ assert_equal 2, base2[10]
39
+ assert_equal 2, base2["10"]
40
+ assert_equal 2, base2["010"]
199
41
 
200
- def test_removes_leading_zeros_from_string_with_base7
201
- execute_test_with(TEST_VALUES_BASE_7, ToDecimal::Base7)
42
+ base36 = ToDecimal::Base.new(36)
43
+ assert_equal 1, base36[1]
44
+ assert_equal 146, base36["42"]
202
45
  end
203
46
 
204
- def test_removes_leading_zeros_from_string_with_base8
205
- execute_test_with(TEST_VALUES_BASE_8, ToDecimal::Base8)
206
- end
207
-
208
- def test_removes_leading_zeros_from_string_with_base9
209
- execute_test_with(TEST_VALUES_BASE_9, ToDecimal::Base9)
210
- end
47
+ def test_is_case_insensitive
48
+ base16 = ToDecimal::Base.new(16)
49
+ assert_equal 15, base16["f"]
50
+ assert_equal 15, base16["F"]
211
51
 
212
- def test_removes_leading_zeros_from_string_with_base10
213
- execute_test_with(TEST_VALUES_BASE_10, ToDecimal::Base10)
52
+ assert_equal 255, base16["ff"]
53
+ assert_equal 255, base16["FF"]
214
54
  end
215
- end
216
55
 
217
- class ConvertorCannotBeInstantiatedTest < Minitest::Test
218
- def test_raises_error_if_user_tries_to_instantiate_new_convertor
219
- assert_raises(NoMethodError) { ToDecimal::Convertor.new }
56
+ def test_handles_leading_zeros_in_strings
57
+ base8 = ToDecimal::Base.new(8)
58
+ assert_equal 34, base8["42"]
59
+ assert_equal 34, base8["042"]
60
+ assert_equal 34, base8["0000042"]
220
61
  end
221
62
  end
metadata CHANGED
@@ -1,123 +1,108 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: to_decimal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 2.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: 2019-12-20 00:00:00.000000000 Z
11
+ date: 2022-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
19
+ version: '13.0'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 2.0.1
22
+ version: 13.0.6
23
23
  type: :development
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '2.0'
29
+ version: '13.0'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 2.0.1
33
- - !ruby/object:Gem::Dependency
34
- name: rake
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '12.3'
40
- type: :development
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: '12.3'
32
+ version: 13.0.6
47
33
  - !ruby/object:Gem::Dependency
48
34
  name: minitest
49
35
  requirement: !ruby/object:Gem::Requirement
50
36
  requirements:
51
37
  - - "~>"
52
38
  - !ruby/object:Gem::Version
53
- version: '5.11'
39
+ version: '5.16'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 5.16.3
54
43
  type: :development
55
44
  prerelease: false
56
45
  version_requirements: !ruby/object:Gem::Requirement
57
46
  requirements:
58
47
  - - "~>"
59
48
  - !ruby/object:Gem::Version
60
- version: '5.11'
49
+ version: '5.16'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 5.16.3
61
53
  - !ruby/object:Gem::Dependency
62
54
  name: minitest-reporters
63
55
  requirement: !ruby/object:Gem::Requirement
64
56
  requirements:
65
57
  - - "~>"
66
58
  - !ruby/object:Gem::Version
67
- version: '1.1'
68
- type: :development
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '1.1'
75
- - !ruby/object:Gem::Dependency
76
- name: pry
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
59
+ version: '1.5'
60
+ - - ">="
80
61
  - !ruby/object:Gem::Version
81
- version: 0.12.2
62
+ version: 1.5.0
82
63
  type: :development
83
64
  prerelease: false
84
65
  version_requirements: !ruby/object:Gem::Requirement
85
66
  requirements:
86
67
  - - "~>"
87
68
  - !ruby/object:Gem::Version
88
- version: 0.12.2
69
+ version: '1.5'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 1.5.0
89
73
  - !ruby/object:Gem::Dependency
90
- name: rubocop
74
+ name: standard
91
75
  requirement: !ruby/object:Gem::Requirement
92
76
  requirements:
93
77
  - - "~>"
94
78
  - !ruby/object:Gem::Version
95
- version: 0.65.0
79
+ version: '1.16'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.16.1
96
83
  type: :development
97
84
  prerelease: false
98
85
  version_requirements: !ruby/object:Gem::Requirement
99
86
  requirements:
100
87
  - - "~>"
101
88
  - !ruby/object:Gem::Version
102
- version: 0.65.0
89
+ version: '1.16'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 1.16.1
103
93
  description: |
104
94
  Provides a simple way to convert an integer expressed in bases
105
- 2 up to 10 to a decimal integer
95
+ 2 up to 36 to a decimal integer
106
96
  email: laurentguinotte@icloud.com
107
97
  executables: []
108
98
  extensions: []
109
99
  extra_rdoc_files: []
110
100
  files:
111
101
  - CHANGELOG.md
112
- - Gemfile
113
- - Gemfile.lock
114
102
  - LICENCE.txt
115
103
  - README.md
116
- - Rakefile
117
104
  - lib/to_decimal.rb
118
- - lib/to_decimal/convertor_class.rb
119
- - lib/to_decimal/validator_class.rb
120
- - lib/to_decimal/wrong_base_input_error.rb
105
+ - lib/to_decimal/base_class.rb
121
106
  - test/to_decimal_test.rb
122
107
  homepage: https://github.com/loranger32/to_decimal
123
108
  licenses:
@@ -140,8 +125,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
125
  - !ruby/object:Gem::Version
141
126
  version: '0'
142
127
  requirements: []
143
- rubygems_version: 3.0.3
128
+ rubygems_version: 3.3.7
144
129
  signing_key:
145
130
  specification_version: 4
146
- summary: A small gem to convert integers from bases 2..10 to decimal integers
131
+ summary: A small gem to convert integers from bases 2..36 to decimal integers
147
132
  test_files: []
data/Gemfile DELETED
@@ -1,15 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- ruby '>= 2.4'
4
-
5
- source 'https://rubygems.org'
6
-
7
- gem 'bundler', '~> 2.0', '>= 2.0.1'
8
- gem 'rake', '~> 12.3', '>= 12.3.2'
9
-
10
- group :development do
11
- gem 'minitest', '~> 5.11', '>= 5.11.3'
12
- gem 'minitest-reporters', '~> 1.3', '>= 1.3.6'
13
- gem 'pry', '~> 0.12.2'
14
- gem 'rubocop', '~> 0.65.0'
15
- end
data/Gemfile.lock DELETED
@@ -1,53 +0,0 @@
1
- GEM
2
- remote: https://rubygems.org/
3
- specs:
4
- ansi (1.5.0)
5
- ast (2.4.0)
6
- builder (3.2.4)
7
- coderay (1.1.2)
8
- jaro_winkler (1.5.4)
9
- method_source (0.9.2)
10
- minitest (5.13.0)
11
- minitest-reporters (1.4.2)
12
- ansi
13
- builder
14
- minitest (>= 5.0)
15
- ruby-progressbar
16
- parallel (1.19.1)
17
- parser (2.6.5.0)
18
- ast (~> 2.4.0)
19
- powerpack (0.1.2)
20
- pry (0.12.2)
21
- coderay (~> 1.1.0)
22
- method_source (~> 0.9.0)
23
- psych (3.1.0)
24
- rainbow (3.0.0)
25
- rake (12.3.3)
26
- rubocop (0.65.0)
27
- jaro_winkler (~> 1.5.1)
28
- parallel (~> 1.10)
29
- parser (>= 2.5, != 2.5.1.1)
30
- powerpack (~> 0.1)
31
- psych (>= 3.1.0)
32
- rainbow (>= 2.2.2, < 4.0)
33
- ruby-progressbar (~> 1.7)
34
- unicode-display_width (~> 1.4.0)
35
- ruby-progressbar (1.10.1)
36
- unicode-display_width (1.4.1)
37
-
38
- PLATFORMS
39
- ruby
40
-
41
- DEPENDENCIES
42
- bundler (~> 2.0, >= 2.0.1)
43
- minitest (~> 5.11, >= 5.11.3)
44
- minitest-reporters (~> 1.3, >= 1.3.6)
45
- pry (~> 0.12.2)
46
- rake (~> 12.3, >= 12.3.2)
47
- rubocop (~> 0.65.0)
48
-
49
- RUBY VERSION
50
- ruby 2.6.5p114
51
-
52
- BUNDLED WITH
53
- 2.0.2
data/Rakefile DELETED
@@ -1,25 +0,0 @@
1
- require 'rake/testtask'
2
- require 'find'
3
-
4
- desc 'Run tests'
5
- Rake::TestTask.new(:test) do |t|
6
- t.libs << 'lib'
7
- t.libs << 'test'
8
- t.test_files = FileList['test/**/*_test.rb']
9
- end
10
-
11
- desc 'Run tests'
12
- task :default => :test
13
-
14
- desc 'Display inventory of all files'
15
- task :inventory do
16
- Find.find('.') do |name|
17
- next if name.include?('/.') # Excludes files and directories with . names
18
- puts name if File.file?(name)
19
- end
20
- end
21
-
22
- desc 'Run rubocop'
23
- task :rub do
24
- sh 'rubocop'
25
- end
@@ -1,40 +0,0 @@
1
- module ToDecimal
2
- # The main class that performs the actual conversion
3
- class Convertor
4
- attr_reader :base
5
-
6
- def initialize(base)
7
- validate_base(base)
8
- @base = base
9
- freeze
10
- end
11
-
12
- def [](input)
13
- input = remove_leading_zeros_of(input)
14
- Validator.new(input, base).validate
15
-
16
- input_as_integer = integerize(input)
17
- convert(input_as_integer)
18
- end
19
-
20
- private
21
-
22
- def remove_leading_zeros_of(input)
23
- input.is_a?(String) ? input.sub(/\A0+/, '') : input
24
- end
25
-
26
- def convert(integer)
27
- integer.to_s.to_i(base)
28
- end
29
-
30
- def integerize(input)
31
- input.is_a?(String) ? input.to_i : input
32
- end
33
-
34
- def validate_base(base)
35
- raise ArgumentError, 'Base must be an Integer' unless base.is_a?(Integer)
36
- raise ArgumentError, 'Base must be 1..10' unless \
37
- base.positive? && base <= 10
38
- end
39
- end
40
- end
@@ -1,38 +0,0 @@
1
- module ToDecimal
2
- # Class to validate arguments
3
- class Validator
4
- def initialize(input, base)
5
- @input = input
6
- @base = base
7
- end
8
-
9
- def validate
10
- err_value = "Argument must be an integer or a valid string\
11
- representation of an integer. You input : #{@input}, of class #{@input.class}."
12
- raise ArgumentError, err_value unless valid_integer_string_or_integer?
13
-
14
- err_base = "A number of base #{@base} cannot have a\
15
- digit greater or equal to #{@base}. Check your argument: #{@input}."
16
- raise WrongBaseInputError, err_base unless valid_input_base?
17
- end
18
-
19
- private
20
-
21
- def valid_integer_string_or_integer?
22
- valid_integer_string? || valid_integer?
23
- end
24
-
25
- def valid_integer?
26
- @input.is_a?(Integer)
27
- end
28
-
29
- def valid_integer_string?
30
- (@input.is_a?(String) && @input.to_i.to_s == @input)
31
- end
32
-
33
- def valid_input_base?
34
- digitized_input = @input.to_i.digits
35
- digitized_input.none? { |digit| digit >= @base }
36
- end
37
- end
38
- end
@@ -1,3 +0,0 @@
1
- module ToDecimal
2
- class WrongBaseInputError < ArgumentError; end
3
- end