Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Commit

Permalink
fix special char conflict with regexp & refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
kachick committed Sep 11, 2012
1 parent 3ed2b72 commit 220a6a8
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 76 deletions.
9 changes: 9 additions & 0 deletions History.rdoc
@@ -1,3 +1,12 @@
=== 0.0.6 2012-9-12

* modify:
* remove obsoluite API "convert_[foo]_[bar]"
* integer/base/ext -> integer/base/core_ext

* fix:
* specific character conflict with inner regexp

=== 0.0.5 2012-5-18

* add:
Expand Down
10 changes: 6 additions & 4 deletions Manifest.txt
Expand Up @@ -5,10 +5,12 @@ Manifest.txt
Rakefile
Gemfile
integer-base.gemspec

lib/integer/base.rb
lib/integer/base/singletonclass.rb
lib/integer/base/standard_chars.rb
lib/integer/base/requirements.rb
lib/integer/base/singleton_class.rb
lib/integer/base/version.rb
lib/integer/base/ext.rb
test/test_helper.rb
lib/integer/base/core_ext.rb

test/helper.rb
test/test_integer-base.rb
29 changes: 24 additions & 5 deletions lib/integer/base.rb
@@ -1,17 +1,36 @@
# Copyright (C) 2011 Kenichi Kamiya
# Copyright (C) 2011 Kenichi Kamiya

class Integer

module Base

class InvalidCharacter < TypeError; end
class InvalidCharacterError < TypeError; end

SPECIAL_CHAR_PATTERN = /[\x00-\x20\-\+]/

# @return [Hash]
# @example
# { 1 => [:"0"],
# 2 => [:"0", :"1"],
# 36 => [:"0", :"1", ... , :Z] }
STANDARD_CHARS = Hash.new{|*|raise KeyError}.tap {|standards|
1.upto 10 do |n|
standards[n] = ('0'..((n - 1).to_s)).map(&:to_sym).freeze
end

alphabets = ('A'..'Z').map(&:to_sym)

11.upto 36 do |n|
standards[n] = [
*standards[10], *alphabets.slice(0, n - 10)
].freeze
end

standards[:BINARY] = standards[2]
}.freeze

end

end

require_relative 'base/version'
require_relative 'base/singletonclass'
require_relative 'base/standard_chars'
require_relative 'base/requirements'
5 changes: 2 additions & 3 deletions lib/integer/base/ext.rb → lib/integer/base/core_ext.rb
@@ -1,9 +1,8 @@
# Copyright (C) 2011 Kenichi Kamiya
require_relative '../base'

class String

alias_method :original_to_i, :to_i

remove_method :to_i

# @overload to_i(base_number)
Expand Down Expand Up @@ -33,7 +32,7 @@ class Integer
def to_s(base=10)
case base
when Enumerable
::Integer::Base.convert_to_string self, base
::Integer::Base.string_for self, base
else
original_to_s base
end
Expand Down
2 changes: 2 additions & 0 deletions lib/integer/base/requirements.rb
@@ -0,0 +1,2 @@
require_relative 'singleton_class'
require_relative 'version'
@@ -1,5 +1,3 @@
# Copyright (C) 2011 Kenichi Kamiya

class Integer; module Base

class << self
Expand Down Expand Up @@ -29,13 +27,11 @@ def parse(str, chars)
def string_for(num, chars)
case chars.length
when 1
convert_to_string_unary num, chars.first
string_unary_for num, chars.first
else
convert_to_string_positional num, chars
string_positional_for num, chars
end
end

alias_method :convert_to_string, :string_for

private

Expand All @@ -45,7 +41,7 @@ def parse_sign!(str)

if sign
if str.empty?
raise InvalidCharacter
raise InvalidCharacterError
else
sign.to_sym
end
Expand All @@ -63,30 +59,34 @@ def base_chars_for(chars)
when chars.length < 2
raise TypeError, 'use 2 or more than characters'
when chars.dup.uniq!
raise InvalidCharacter, 'dupulicated characters'
raise InvalidCharacterError, 'dupulicated characters'
when chars.any?{|s|s.length != 1}
raise InvalidCharacter, 'chars must be Array<Char> (Char: length 1)'
raise InvalidCharacterError,
'chars must be Array<Char> (Char: length 1)'
when chars.any?{|c|SPECIAL_CHAR_PATTERN =~ c}
raise InvalidCharacter, 'included Special Characters (-, +, space, control-char)'
raise InvalidCharacterError,
'included Special Characters (-, +, space, control-char)'
else
chars
end
end

# @return [Symbol]
def unary_char_for(char)
raise InvalidCharacter unless (char.length == 1) and char.respond_to?(:to_sym)
unless (char.length == 1) and char.respond_to?(:to_sym)
raise InvalidCharacterError, char
end

char.to_sym
end

def trim_positional_paddings!(str, pad_char)
str.slice!(/\A#{pad_char}+/)
str.slice!(/\A#{Regexp.escape pad_char}+/)
end

# @return [Integer]
def parse_positional_abs(str, chars)
raise InvalidCharacter if str.empty?
raise InvalidCharacterError if str.empty?
base = chars.length
chars = base_chars_for chars

Expand All @@ -99,7 +99,7 @@ def parse_positional_abs(str, chars)
if radix = chars.index(char.to_sym)
sum + (radix * (base ** index))
else
raise InvalidCharacter
raise InvalidCharacterError
end
}
end
Expand All @@ -110,11 +110,16 @@ def parse_unary_abs(str, char)
return 0 if str.empty?

chars = str.chars.to_a

atoms = chars.uniq
raise InvalidCharacter, 'contain multiple chars' unless atoms.length == 1

unless atoms.length == 1
raise InvalidCharacterError, 'contain multiple chars'
end

atom = atoms.first.to_sym
raise InvalidCharacter, 'not match the char and atom' unless atom == char
unless atom == char
raise InvalidCharacterError, 'not match the char and atom'
end

chars.length
end
Expand All @@ -138,9 +143,7 @@ def string_positional_for(num, chars)
s.insert 0, '-' if int < 0
}
end

alias_method :convert_to_string_positional, :string_positional_for


# @return [String]
def string_unary_for(num, char)
char = unary_char_for char
Expand All @@ -150,9 +153,7 @@ def string_unary_for(num, char)
s.insert 0, '-' if int < 0
}
end

alias_method :convert_to_string_unary, :string_unary_for

end

end; end
end; end
23 changes: 0 additions & 23 deletions lib/integer/base/standard_chars.rb

This file was deleted.

2 changes: 1 addition & 1 deletion lib/integer/base/version.rb
@@ -1,5 +1,5 @@
class Integer; module Base

VERSION = '0.0.5'.freeze
VERSION = '0.0.6'.freeze

end; end
5 changes: 5 additions & 0 deletions test/helper.rb
@@ -0,0 +1,5 @@
require 'test/unit'

$VERBOSE = true

require_relative '../lib/integer/base/core_ext'
3 changes: 0 additions & 3 deletions test/test_helper.rb

This file was deleted.

34 changes: 20 additions & 14 deletions test/test_integer-base.rb
@@ -1,26 +1,26 @@
$VERBOSE = true
require_relative 'test_helper'
require_relative 'helper'

class TestIntegerBase < Test::Unit::TestCase

def test_parse
assert_equal(1, '0a'.to_i(['0', *'A'..'I']))

assert_equal(0, ''.to_i(['0']))
assert_equal(1, '0'.to_i(['0']))
assert_equal(2, '00'.to_i(['0']))

assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
'01'.to_i(['0'])
end

assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
'9a'.to_i(['0', *'A'..'I'])
end

assert_equal(1, '9a'.to_i(['9', *'A'..'I']))
assert_equal(10, '9a9'.to_i(['9', *'A'..'I']))

assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
'9a'.to_i(['9', *'A'..'I', 'B'])
end

Expand All @@ -36,21 +36,21 @@ def test_parse
assert_equal(-10, '-a0'.to_i(['0', *'A'..'I']))
assert_equal(-192, '-aib'.to_i(['0', *'A'..'I']))

assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
'a-ib'.to_i(['0', *'A'..'I'])
end

assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
'a+ib'.to_i(['0', *'A'..'I'])
end

assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
'~aib'.to_i(['0', *'A'..'I'])
end
end

def test_characterable
assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
'210'.to_i(('1'..'2').to_a)
end

Expand Down Expand Up @@ -91,25 +91,25 @@ def test_binary
end

def test_standards_to_i
assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
Integer::Base.parse('', Integer::Base::STANDARD_CHARS[2])
end

assert_equal(0, Integer::Base.parse('', Integer::Base::STANDARD_CHARS[1]))

assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
Integer::Base.parse('-', Integer::Base::STANDARD_CHARS[2])
end

assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
Integer::Base.parse('-', Integer::Base::STANDARD_CHARS[1])
end

assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
Integer::Base.parse('+', Integer::Base::STANDARD_CHARS[2])
end

assert_raises Integer::Base::InvalidCharacter do
assert_raises Integer::Base::InvalidCharacterError do
Integer::Base.parse('+', Integer::Base::STANDARD_CHARS[1])
end

Expand All @@ -127,6 +127,11 @@ def test_standards_to_i
end
end

def test_irregular_regexp
assert_equal(2, ':)'.to_i(%w[) :]))
assert_equal(':)', 2.to_s(%w[) :]))
end

def test_implements
assert_raises ArgumentError do
'00'.to_i 1
Expand All @@ -136,4 +141,5 @@ def test_implements
def test_upper36
assert_equal(73, '1!'.to_i([*Integer::Base::STANDARD_CHARS[36], '!']))
end

end

0 comments on commit 220a6a8

Please sign in to comment.