diff options
Diffstat (limited to 'jni/ruby/test/psych/test_parser.rb')
-rw-r--r-- | jni/ruby/test/psych/test_parser.rb | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/jni/ruby/test/psych/test_parser.rb b/jni/ruby/test/psych/test_parser.rb new file mode 100644 index 0000000..0abe0dd --- /dev/null +++ b/jni/ruby/test/psych/test_parser.rb @@ -0,0 +1,339 @@ +# coding: utf-8 + +require_relative 'helper' + +module Psych + class TestParser < TestCase + class EventCatcher < Handler + attr_accessor :parser + attr_reader :calls, :marks + def initialize + @parser = nil + @calls = [] + @marks = [] + end + + (Handler.instance_methods(true) - + Object.instance_methods).each do |m| + class_eval %{ + def #{m} *args + super + @marks << @parser.mark if @parser + @calls << [:#{m}, args] + end + } + end + end + + def setup + super + @handler = EventCatcher.new + @parser = Psych::Parser.new @handler + @handler.parser = @parser + end + + def test_ast_roundtrip + parser = Psych.parser + parser.parse('null') + ast = parser.handler.root + assert_match(/^null/, ast.yaml) + end + + def test_exception_memory_leak + yaml = <<-eoyaml +%YAML 1.1 +%TAG ! tag:tenderlovemaking.com,2009: +--- &ponies +- first element +- *ponies +- foo: bar +... + eoyaml + + [:start_stream, :start_document, :end_document, :alias, :scalar, + :start_sequence, :end_sequence, :start_mapping, :end_mapping, + :end_stream].each do |method| + + klass = Class.new(Psych::Handler) do + define_method(method) do |*args| + raise + end + end + + parser = Psych::Parser.new klass.new + 2.times { + assert_raises(RuntimeError, method.to_s) do + parser.parse yaml + end + } + end + end + + def test_multiparse + 3.times do + @parser.parse '--- foo' + end + end + + def test_filename + ex = assert_raises(Psych::SyntaxError) do + @parser.parse '--- `', 'omg!' + end + assert_match 'omg!', ex.message + end + + def test_line_numbers + assert_equal 0, @parser.mark.line + @parser.parse "---\n- hello\n- world" + line_calls = @handler.marks.map(&:line).zip(@handler.calls.map(&:first)) + assert_equal [[0, :start_stream], + [0, :start_document], + [1, :start_sequence], + [2, :scalar], + [3, :scalar], + [3, :end_sequence], + [3, :end_document], + [3, :end_stream]], line_calls + + assert_equal 3, @parser.mark.line + end + + def test_column_numbers + assert_equal 0, @parser.mark.column + @parser.parse "---\n- hello\n- world" + col_calls = @handler.marks.map(&:column).zip(@handler.calls.map(&:first)) + assert_equal [[0, :start_stream], + [3, :start_document], + [1, :start_sequence], + [0, :scalar], + [0, :scalar], + [0, :end_sequence], + [0, :end_document], + [0, :end_stream]], col_calls + + assert_equal 0, @parser.mark.column + end + + def test_index_numbers + assert_equal 0, @parser.mark.index + @parser.parse "---\n- hello\n- world" + idx_calls = @handler.marks.map(&:index).zip(@handler.calls.map(&:first)) + assert_equal [[0, :start_stream], + [3, :start_document], + [5, :start_sequence], + [12, :scalar], + [19, :scalar], + [19, :end_sequence], + [19, :end_document], + [19, :end_stream]], idx_calls + + assert_equal 19, @parser.mark.index + end + + def test_bom + tadpole = 'おたまじゃくし' + + # BOM + text + yml = "\uFEFF#{tadpole}".encode('UTF-16LE') + @parser.parse yml + assert_equal tadpole, @parser.handler.calls[2][1].first + end + + def test_external_encoding + tadpole = 'おたまじゃくし' + + @parser.external_encoding = Psych::Parser::UTF16LE + @parser.parse tadpole.encode 'UTF-16LE' + assert_equal tadpole, @parser.handler.calls[2][1].first + end + + def test_bogus_io + o = Object.new + def o.external_encoding; nil end + def o.read len; self end + + assert_raises(TypeError) do + @parser.parse o + end + end + + def test_parse_io + @parser.parse StringIO.new("--- a") + assert_called :start_stream + assert_called :scalar + assert_called :end_stream + end + + def test_syntax_error + assert_raises(Psych::SyntaxError) do + @parser.parse("---\n\"foo\"\n\"bar\"\n") + end + end + + def test_syntax_error_twice + assert_raises(Psych::SyntaxError) do + @parser.parse("---\n\"foo\"\n\"bar\"\n") + end + + assert_raises(Psych::SyntaxError) do + @parser.parse("---\n\"foo\"\n\"bar\"\n") + end + end + + def test_syntax_error_has_path_for_string + e = assert_raises(Psych::SyntaxError) do + @parser.parse("---\n\"foo\"\n\"bar\"\n") + end + assert_match '(<unknown>):', e.message + end + + def test_syntax_error_has_path_for_io + io = StringIO.new "---\n\"foo\"\n\"bar\"\n" + def io.path; "hello!"; end + + e = assert_raises(Psych::SyntaxError) do + @parser.parse(io) + end + assert_match "(#{io.path}):", e.message + end + + def test_mapping_end + @parser.parse("---\n!!map { key: value }") + assert_called :end_mapping + end + + def test_mapping_tag + @parser.parse("---\n!!map { key: value }") + assert_called :start_mapping, ["tag:yaml.org,2002:map", false, Nodes::Mapping::FLOW] + end + + def test_mapping_anchor + @parser.parse("---\n&A { key: value }") + assert_called :start_mapping, ['A', true, Nodes::Mapping::FLOW] + end + + def test_mapping_block + @parser.parse("---\n key: value") + assert_called :start_mapping, [true, Nodes::Mapping::BLOCK] + end + + def test_mapping_start + @parser.parse("---\n{ key: value }") + assert_called :start_mapping + assert_called :start_mapping, [true, Nodes::Mapping::FLOW] + end + + def test_sequence_end + @parser.parse("---\n&A [1, 2]") + assert_called :end_sequence + end + + def test_sequence_start_anchor + @parser.parse("---\n&A [1, 2]") + assert_called :start_sequence, ["A", true, Nodes::Sequence::FLOW] + end + + def test_sequence_start_tag + @parser.parse("---\n!!seq [1, 2]") + assert_called :start_sequence, ["tag:yaml.org,2002:seq", false, Nodes::Sequence::FLOW] + end + + def test_sequence_start_flow + @parser.parse("---\n[1, 2]") + assert_called :start_sequence, [true, Nodes::Sequence::FLOW] + end + + def test_sequence_start_block + @parser.parse("---\n - 1\n - 2") + assert_called :start_sequence, [true, Nodes::Sequence::BLOCK] + end + + def test_literal_scalar + @parser.parse(<<-eoyml) +%YAML 1.1 +--- +"literal\n\ + \ttext\n" + eoyml + assert_called :scalar, ['literal text ', false, true, Nodes::Scalar::DOUBLE_QUOTED] + end + + def test_scalar + @parser.parse("--- foo\n") + assert_called :scalar, ['foo', true, false, Nodes::Scalar::PLAIN] + end + + def test_scalar_with_tag + @parser.parse("---\n!!str foo\n") + assert_called :scalar, ['foo', 'tag:yaml.org,2002:str', false, false, Nodes::Scalar::PLAIN] + end + + def test_scalar_with_anchor + @parser.parse("---\n&A foo\n") + assert_called :scalar, ['foo', 'A', true, false, Nodes::Scalar::PLAIN] + end + + def test_scalar_plain_implicit + @parser.parse("---\n&A foo\n") + assert_called :scalar, ['foo', 'A', true, false, Nodes::Scalar::PLAIN] + end + + def test_alias + @parser.parse(<<-eoyml) +%YAML 1.1 +--- +!!seq [ + !!str "Without properties", + &A !!str "Anchored", + !!str "Tagged", + *A, + !!str "", +] + eoyml + assert_called :alias, ['A'] + end + + def test_end_stream + @parser.parse("--- foo\n") + assert_called :end_stream + end + + def test_start_stream + @parser.parse("--- foo\n") + assert_called :start_stream + end + + def test_end_document_implicit + @parser.parse("\"foo\"\n") + assert_called :end_document, [true] + end + + def test_end_document_explicit + @parser.parse("\"foo\"\n...") + assert_called :end_document, [false] + end + + def test_start_document_version + @parser.parse("%YAML 1.1\n---\n\"foo\"\n") + assert_called :start_document, [[1,1], [], false] + end + + def test_start_document_tag + @parser.parse("%TAG !yaml! tag:yaml.org,2002\n---\n!yaml!str \"foo\"\n") + assert_called :start_document, [[], [['!yaml!', 'tag:yaml.org,2002']], false] + end + + def assert_called call, with = nil, parser = @parser + if with + call = parser.handler.calls.find { |x| + x.first == call && x.last.compact == with + } + assert(call, + "#{[call,with].inspect} not in #{parser.handler.calls.inspect}" + ) + else + assert parser.handler.calls.any? { |x| x.first == call } + end + end + end +end |