Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions lib/net/imap/data_encoding.rb
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ def self.format_datetime(time)

# Common validators of number and nz_number types
module NumValidator # :nodoc
NUMBER_RE = /\A(?:0|[1-9]\d*)\z/
NUMBER_RE = /\A\d+\z/
NZ_NUMBER_RE = /\A[1-9]\d*\z/
module_function

# Check if argument is a valid 'number' according to RFC 3501
Expand Down Expand Up @@ -251,7 +252,7 @@ def ensure_mod_sequence_valzer(num)
def coerce_number(num)
case num
when Integer then ensure_number num
when NUMBER_RE then ensure_number Integer num
when NUMBER_RE then ensure_number num.to_i
else
raise DataFormatError, "%p is not a valid number" % [num]
end
Expand All @@ -260,8 +261,8 @@ def coerce_number(num)
# Like #ensure_nz_number, but usable with numeric String input.
def coerce_nz_number(num)
case num
when Integer then ensure_nz_number num
when NUMBER_RE then ensure_nz_number Integer num
when Integer then ensure_nz_number num
when NZ_NUMBER_RE then ensure_nz_number num.to_i
else
raise DataFormatError, "%p is not a valid nz-number" % [num]
end
Expand All @@ -271,7 +272,7 @@ def coerce_nz_number(num)
def coerce_number64(num)
case num
when Integer then ensure_number64 num
when NUMBER_RE then ensure_number64 Integer num
when NUMBER_RE then ensure_number64 num.to_i
else
raise DataFormatError, "%p is not a valid number64" % [num]
end
Expand All @@ -280,8 +281,8 @@ def coerce_number64(num)
# Like #ensure_nz_number64, but usable with numeric String input.
def coerce_nz_number64(num)
case num
when Integer then ensure_nz_number64 num
when NUMBER_RE then ensure_nz_number64 Integer num
when Integer then ensure_nz_number64 num
when NZ_NUMBER_RE then ensure_nz_number64 num.to_i
else
raise DataFormatError, "%p is not a valid nz-number64" % [num]
end
Expand All @@ -291,7 +292,7 @@ def coerce_nz_number64(num)
def coerce_mod_sequence_value(num)
case num
when Integer then ensure_mod_sequence_value num
when NUMBER_RE then ensure_mod_sequence_value Integer num
when NUMBER_RE then ensure_mod_sequence_value num.to_i
else
raise DataFormatError, "%p is not a valid mod-sequence-value" % [num]
end
Expand All @@ -301,7 +302,7 @@ def coerce_mod_sequence_value(num)
def coerce_mod_sequence_valzer(num)
case num
when Integer then ensure_mod_sequence_valzer num
when NUMBER_RE then ensure_mod_sequence_valzer Integer num
when NUMBER_RE then ensure_mod_sequence_valzer num.to_i
else
raise DataFormatError, "%p is not a valid mod-sequence-valzer" % [num]
end
Expand Down
222 changes: 59 additions & 163 deletions test/net/imap/test_num_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ class NumValidatorTest < Net::IMAP::TestCase
TEST_VALUES = {
-1 => %i[invalid],

{"000"=> 0} => %i[number number64 mod-sequence-valzer],
{"011"=>11} => %i[number number64 mod-sequence-value mod-sequence-valzer],

0 => %i[number number64 mod-sequence-valzer],
1 => %i[number nz-number number64 nz-number64 mod-sequence-value mod-sequence-valzer],
0x0000_ffff => %i[number nz-number number64 nz-number64 mod-sequence-value mod-sequence-valzer],
Expand All @@ -22,196 +25,89 @@ class NumValidatorTest < Net::IMAP::TestCase
0xffff_ffff_ffff_ffff => %i[invalid],
}

def self.using_test_values_for(type)
TEST_VALUES.each do |value, types|
label = value if value < 1
label ||= "0x" + ("%016x" % value).chars.each_slice(4).map(&:join).join(?_)
yield label, value, types.include?(type)
end
end
TYPES = TEST_VALUES.values.flatten.uniq - [:invalid]

using_test_values_for :number do |label, value, valid|
test "#valid_number?(%s) => %p" % [label, valid] do
assert_equal valid, NumValidator.valid_number?(value)
end
end

using_test_values_for :"nz-number" do |label, value, valid|
test "#valid_nz_number?(%s) => %p" % [label, valid] do
assert_equal valid, NumValidator.valid_nz_number?(value)
end
end

using_test_values_for :number64 do |label, value, valid|
test "#valid_number64?(%s) => %p" % [label, valid] do
assert_equal valid, NumValidator.valid_number64?(value)
end
end

using_test_values_for :"nz-number64" do |label, value, valid|
test "#valid_nz_number64?(%s) => %p" % [label, valid] do
assert_equal valid, NumValidator.valid_nz_number64?(value)
end
end

using_test_values_for :"mod-sequence-value" do |label, value, valid|
test "#valid_mod_sequence_value?(%s) => %p" % [label, valid] do
assert_equal valid, NumValidator.valid_mod_sequence_value?(value)
def self.each_integer_test_value_for(type)
TEST_VALUES.each do |value, types|
yield value, types.include?(type) if Integer === value
end
end

using_test_values_for :"mod-sequence-valzer" do |label, value, valid|
test "#valid_mod_sequence_valzer?(%s) => %p" % [label, valid] do
assert_equal valid, NumValidator.valid_mod_sequence_valzer?(value)
def self.each_coercible_test_value_for(type)
TEST_VALUES.each do |value, types|
valid = types.include?(type)
case value
in Integer
[value, value.to_s].each do |input|
yield input, valid, value
end
in Hash if value.to_a in [[String => input, Integer => coerced]]
yield input, valid, coerced
end
end
end

def assert_format_error
assert_raise Net::IMAP::DataFormatError do
yield
def self.each_num_validator_type_method(prefix, suffix = "")
TYPES.each do |type|
method_name = "#{prefix}_#{type}#{suffix}".tr(?-, ?_)
yield type, method_name
end
end

using_test_values_for :number do |label, value, valid|
result = valid ? "=> #{label}" : "raises DataFormatError"
test "#ensure_number(%s) %s" % [label, result] do
if valid
assert_equal value, NumValidator.ensure_number(value)
else
assert_format_error do NumValidator.ensure_number(value) end
def self.test_method_invocation(method, input, result: nil, error: nil)
label = ->(value) {
case value
in String then value.dump
in true | false | nil then value.to_s
in Integer if value.negative? then value.to_s
in Integer
"0x" + ("%016x" % value).chars.each_slice(4).map(&:join).join(?_)
end
end
end

using_test_values_for :"nz-number" do |label, value, valid|
result = valid ? "=> #{label}" : "raises DataFormatError"
test "#ensure_nz_number(%s) %s" % [label, result] do
if valid
assert_equal value, NumValidator.ensure_nz_number(value)
else
assert_format_error do NumValidator.ensure_nz_number(value) end
}
if error
test "#%s(%s) raises %s" % [method, label[input], error.name] do
assert_raise error do NumValidator.public_send(method, input) end
end
end
end

using_test_values_for :number64 do |label, value, valid|
result = valid ? "=> #{label}" : "raises DataFormatError"
test "#ensure_number64(%s) %s" % [label, result] do
if valid
assert_equal value, NumValidator.ensure_number64(value)
else
assert_format_error do NumValidator.ensure_number64(value) end
else
test "#%s(%s) => %s" % [method, label[input], label.(result)] do
assert_equal result, NumValidator.public_send(method, input)
end
end
end

using_test_values_for :"nz-number64" do |label, value, valid|
result = valid ? "=> #{label}" : "raises DataFormatError"
test "#ensure_nz_number64(%s) %s" % [label, result] do
if valid
assert_equal value, NumValidator.ensure_nz_number64(value)
else
assert_format_error do NumValidator.ensure_nz_number64(value) end
end
# Test valid_{type}?(input), e.g:
# #ensure_nz_number(0x0000_0000_ffff_ffff) => true
# #ensure_nz_number(0x0000_0001_0000_0000) => false
each_num_validator_type_method(:valid, "?") do |type, method|
each_integer_test_value_for type do |value, valid|
test_method_invocation(method, value, result: valid)
end
end

using_test_values_for :"mod-sequence-value" do |label, value, valid|
result = valid ? "=> #{label}" : "raises DataFormatError"
test "#ensure_mod_sequence_value(%s) %s" % [label, result] do
# Test ensure_{type}(input), e.g:
# #ensure_nz_number(0x0000_0000_ffff_ffff) => 0x0000_0000_ffff_ffff
# #ensure_nz_number(0x0000_0001_0000_0000) raises DataFormatError
each_num_validator_type_method(:ensure) do |type, method|
each_integer_test_value_for type do |value, valid|
if valid
assert_equal value, NumValidator.ensure_mod_sequence_value(value)
test_method_invocation(method, value, result: value)
else
assert_format_error do NumValidator.ensure_mod_sequence_value(value) end
test_method_invocation(method, value, error: Net::IMAP::DataFormatError)
end
end
end

using_test_values_for :"mod-sequence-valzer" do |label, value, valid|
result = valid ? "=> #{label}" : "raises DataFormatError"
test "#ensure_mod_sequence_valzer(%s) %s" % [label, result] do
# Test coerce_{type}(input), e.g:
# #coerce_number64("9223372036854775807") => 9223372036854775807
# #coerce_number64("9223372036854775808") raises DataFormatError
# #coerce_number64(0x7fff_ffff_ffff_ffff) => 9223372036854775807
# #coerce_number64(0x8000_0000_0000_0000) raises DataFormatError
each_num_validator_type_method(:coerce) do |type, method|
each_coercible_test_value_for type do |value, valid, coerced|
if valid
assert_equal value, NumValidator.ensure_mod_sequence_valzer(value)
test_method_invocation(method, value, result: coerced)
else
assert_format_error do NumValidator.ensure_mod_sequence_valzer(value) end
end
end
end

using_test_values_for :number do |label, value, valid|
result = valid ? "=> #{value}" : "raises DataFormatError"
[value, value.to_s].each do |input|
test "#coerce_number(%p) %s" % [input, result] do
if valid
assert_equal value, NumValidator.coerce_number(input)
else
assert_format_error do NumValidator.coerce_number(input) end
end
end
end
end

using_test_values_for :"nz-number" do |label, value, valid|
result = valid ? "=> #{value}" : "raises DataFormatError"
[value, value.to_s].each do |input|
test "#coerce_nz_number(%p) %s" % [input, result] do
if valid
assert_equal value, NumValidator.coerce_nz_number(input)
else
assert_format_error do NumValidator.coerce_nz_number(input) end
end
end
end
end

using_test_values_for :number64 do |label, value, valid|
result = valid ? "=> #{value}" : "raises DataFormatError"
[value, value.to_s].each do |input|
test "#coerce_number64(%p) %s" % [input, result] do
if valid
assert_equal value, NumValidator.coerce_number64(input)
else
assert_format_error do NumValidator.coerce_number64(input) end
end
end
end
end

using_test_values_for :"nz-number64" do |label, value, valid|
result = valid ? "=> #{value}" : "raises DataFormatError"
[value, value.to_s].each do |input|
test "#coerce_nz_number64(%p) %s" % [input, result] do
if valid
assert_equal value, NumValidator.coerce_nz_number64(input)
else
assert_format_error do NumValidator.coerce_nz_number64(input) end
end
end
end
end

using_test_values_for :"mod-sequence-value" do |label, value, valid|
result = valid ? "=> #{value}" : "raises DataFormatError"
[value, value.to_s].each do |input|
test "#coerce_mod_sequence_value(%p) %s" % [input, result] do
if valid
assert_equal value, NumValidator.coerce_mod_sequence_value(input)
else
assert_format_error do NumValidator.coerce_mod_sequence_value(input) end
end
end
end
end

using_test_values_for :"mod-sequence-valzer" do |label, value, valid|
result = valid ? "=> #{value}" : "raises DataFormatError"
[value, value.to_s].each do |input|
test "#coerce_mod_sequence_valzer(%p) %s" % [input, result] do
if valid
assert_equal value, NumValidator.coerce_mod_sequence_valzer(input)
else
assert_format_error do NumValidator.coerce_mod_sequence_valzer(input) end
end
test_method_invocation(method, value, error: Net::IMAP::DataFormatError)
end
end
end
Expand Down
Loading