Fix breakage in XmlMini

- Boolean parsing breaks on non strings (i.e. integer 1|0)
- Symbol parsing breaks on non strings.
- BigDecimal parsing breaks due to missing require.
- Update changelog.
This commit is contained in:
Birkir A. Barkarson 2013-11-13 12:31:02 +09:00
parent 5542dff88a
commit 8dd4aca485
3 changed files with 136 additions and 2 deletions

View File

@ -1,3 +1,10 @@
* Fix parsing bugs in `XmlMini`
Symbols or boolean parsing would raise an error for non string values (e.g.
integers). Decimal parsing would fail due to a missing requirement.
*Birkir A. Barkarson*
* Add `ActiveSupport::Testing::TimeHelpers#travel` and `#travel_to`. These methods change current
time to the given time or time difference by stubbing `Time.now` and `Date.today` to return the
time or date after the difference calculation, or the time or date that got passed into the

View File

@ -1,7 +1,9 @@
require 'time'
require 'base64'
require 'bigdecimal'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/string/inflections'
require 'active_support/core_ext/date_time/calculations'
module ActiveSupport
# = XmlMini
@ -56,13 +58,13 @@ module ActiveSupport
# TODO use regexp instead of Date.parse
unless defined?(PARSING)
PARSING = {
"symbol" => Proc.new { |symbol| symbol.to_sym },
"symbol" => Proc.new { |symbol| symbol.to_s.to_sym },
"date" => Proc.new { |date| ::Date.parse(date) },
"datetime" => Proc.new { |time| Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc },
"integer" => Proc.new { |integer| integer.to_i },
"float" => Proc.new { |float| float.to_f },
"decimal" => Proc.new { |number| BigDecimal(number) },
"boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.strip) },
"boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.to_s.strip) },
"string" => Proc.new { |string| string.to_s },
"yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
"base64Binary" => Proc.new { |bin| ::Base64.decode64(bin) },

View File

@ -169,4 +169,129 @@ module XmlMiniTest
end
end
end
class ParsingTest < ActiveSupport::TestCase
def setup
@parsing = ActiveSupport::XmlMini::PARSING
end
def test_symbol
parser = @parsing['symbol']
assert_equal :symbol, parser.call('symbol')
assert_equal :symbol, parser.call(:symbol)
assert_equal :'123', parser.call(123)
assert_raises(ArgumentError) { parser.call(Date.new(2013,11,12,02,11)) }
end
def test_date
parser = @parsing['date']
assert_equal Date.new(2013,11,12), parser.call("2013-11-12T0211Z")
assert_raises(TypeError) { parser.call(1384190018) }
assert_raises(ArgumentError) { parser.call("not really a date") }
end
def test_datetime
parser = @parsing['datetime']
assert_equal Time.new(2013,11,12,02,11,00,0), parser.call("2013-11-12T02:11:00Z")
assert_equal DateTime.new(2013,11,12), parser.call("2013-11-12T0211Z")
assert_equal DateTime.new(2013,11,12,02,11), parser.call("2013-11-12T02:11Z")
assert_equal DateTime.new(2013,11,12,02,11), parser.call("2013-11-12T11:11+9")
assert_raises(ArgumentError) { parser.call("1384190018") }
end
def test_integer
parser = @parsing['integer']
assert_equal 123, parser.call(123)
assert_equal 123, parser.call(123.003)
assert_equal 123, parser.call("123")
assert_equal 0, parser.call("")
assert_raises(ArgumentError) { parser.call(Date.new(2013,11,12,02,11)) }
end
def test_float
parser = @parsing['float']
assert_equal 123, parser.call("123")
assert_equal 123.003, parser.call("123.003")
assert_equal 123.0, parser.call("123,003")
assert_equal 0.0, parser.call("")
assert_equal 123, parser.call(123)
assert_equal 123.05, parser.call(123.05)
assert_raises(ArgumentError) { parser.call(Date.new(2013,11,12,02,11)) }
end
def test_decimal
parser = @parsing['decimal']
assert_equal 123, parser.call("123")
assert_equal 123.003, parser.call("123.003")
assert_equal 123.0, parser.call("123,003")
assert_equal 0.0, parser.call("")
assert_equal 123, parser.call(123)
assert_raises(ArgumentError) { parser.call(123.04) }
assert_raises(ArgumentError) { parser.call(Date.new(2013,11,12,02,11)) }
end
def test_boolean
parser = @parsing['boolean']
[1, true, "1"].each do |value|
assert parser.call(value)
end
[0, false, "0"].each do |value|
assert_not parser.call(value)
end
end
def test_string
parser = @parsing['string']
assert_equal "123", parser.call(123)
assert_equal "123", parser.call("123")
assert_equal "[]", parser.call("[]")
assert_equal "[]", parser.call([])
assert_equal "{}", parser.call({})
assert_raises(ArgumentError) { parser.call(Date.new(2013,11,12,02,11)) }
end
def test_yaml
yaml = <<YAML
product:
- sku : BL394D
quantity : 4
description : Basketball
YAML
expected = {
"product"=> [
{"sku"=>"BL394D", "quantity"=>4, "description"=>"Basketball"}
]
}
parser = @parsing['yaml']
assert_equal(expected, parser.call(yaml))
assert_equal({1 => 'test'}, parser.call({1 => 'test'}))
assert_equal({"1 => 'test'"=>nil}, parser.call("{1 => 'test'}"))
end
def test_base64Binary_and_binary
base64 = <<BASE64
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
BASE64
expected_base64 = <<EXPECTED
Man is distinguished, not only by his reason, but by this singular passion from
other animals, which is a lust of the mind, that by a perseverance of delight
in the continued and indefatigable generation of knowledge, exceeds the short
vehemence of any carnal pleasure.
EXPECTED
parser = @parsing['base64Binary']
assert_equal expected_base64.gsub(/\n/," ").strip, parser.call(base64)
parser.call("NON BASE64 INPUT")
parser = @parsing['binary']
assert_equal expected_base64.gsub(/\n/," ").strip, parser.call(base64, 'encoding' => 'base64')
assert_equal "IGNORED INPUT", parser.call("IGNORED INPUT", {})
end
end
end