ruby-changes:21916
From: tenderlove <ko1@a...>
Date: Wed, 7 Dec 2011 08:12:48 +0900 (JST)
Subject: [ruby-changes:21916] tenderlove:r33965 (trunk): * ext/psych/lib/psych.rb (module Psych): parse and load methods take
tenderlove 2011-12-07 08:12:37 +0900 (Wed, 07 Dec 2011) New Revision: 33965 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33965 Log: * ext/psych/lib/psych.rb (module Psych): parse and load methods take an optional file name that is used when raising Psych::SyntaxError exceptions * ext/psych/lib/psych/syntax_error.rb (module Psych): allow nil file names and handle nil file names in the exception message * test/psych/test_exception.rb (module Psych): Tests for changes. Modified files: trunk/ChangeLog trunk/ext/psych/lib/psych/syntax_error.rb trunk/ext/psych/lib/psych.rb trunk/test/psych/test_exception.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 33964) +++ ChangeLog (revision 33965) @@ -1,3 +1,12 @@ +Wed Dec 7 08:04:31 2011 Aaron Patterson <aaron@t...> + + * ext/psych/lib/psych.rb (module Psych): parse and load methods take + an optional file name that is used when raising Psych::SyntaxError + exceptions + * ext/psych/lib/psych/syntax_error.rb (module Psych): allow nil file + names and handle nil file names in the exception message + * test/psych/test_exception.rb (module Psych): Tests for changes. + Tue Dec 6 18:26:33 2011 Tanaka Akira <akr@f...> * ext/dbm/dbm.c: use db_version() instead of DB_VERSION_STRING to Index: ext/psych/lib/psych/syntax_error.rb =================================================================== --- ext/psych/lib/psych/syntax_error.rb (revision 33964) +++ ext/psych/lib/psych/syntax_error.rb (revision 33965) @@ -3,8 +3,9 @@ attr_reader :file, :line, :column, :offset, :problem, :context def initialize file, line, col, offset, problem, context - err = [problem, context].compact.join ' ' - message = "(%s): %s at line %d column %d" % [file, err, line, col] + err = [problem, context].compact.join ' ' + filename = file || '<unknown>' + message = "(%s): %s at line %d column %d" % [filename, err, line, col] @file = file @line = line Index: ext/psych/lib/psych.rb =================================================================== --- ext/psych/lib/psych.rb (revision 33964) +++ ext/psych/lib/psych.rb (revision 33965) @@ -106,34 +106,58 @@ ### # Load +yaml+ in to a Ruby data structure. If multiple documents are # provided, the object contained in the first document will be returned. + # +filename+ will be used in the exception message if any exception is raised + # while parsing. # + # Raises a Psych::SyntaxError when a YAML syntax error is detected. + # # Example: # - # Psych.load("--- a") # => 'a' - # Psych.load("---\n - a\n - b") # => ['a', 'b'] - def self.load yaml - result = parse(yaml) + # Psych.load("--- a") # => 'a' + # Psych.load("---\n - a\n - b") # => ['a', 'b'] + # + # begin + # Psych.load("--- `", "file.txt") + # rescue Psych::SyntaxError => ex + # ex.file # => 'file.txt' + # ex.message # => "(foo.txt): found character that cannot start any token" + # end + def self.load yaml, filename = nil + result = parse(yaml, filename) result ? result.to_ruby : result end ### # Parse a YAML string in +yaml+. Returns the first object of a YAML AST. + # +filename+ is used in the exception message if a Psych::SyntaxError is + # raised. # + # Raises a Psych::SyntaxError when a YAML syntax error is detected. + # # Example: # # Psych.parse("---\n - a\n - b") # => #<Psych::Nodes::Sequence:0x00> # + # begin + # Psych.parse("--- `", "file.txt") + # rescue Psych::SyntaxError => ex + # ex.file # => 'file.txt' + # ex.message # => "(foo.txt): found character that cannot start any token" + # end + # # See Psych::Nodes for more information about YAML AST. - def self.parse yaml - children = parse_stream(yaml).children + def self.parse yaml, filename = nil + children = parse_stream(yaml, filename).children children.empty? ? false : children.first.children.first end ### # Parse a file at +filename+. Returns the YAML AST. + # + # Raises a Psych::SyntaxError when a YAML syntax error is detected. def self.parse_file filename File.open filename do |f| - parse f + parse f, filename end end @@ -146,15 +170,26 @@ ### # Parse a YAML string in +yaml+. Returns the full AST for the YAML document. # This method can handle multiple YAML documents contained in +yaml+. + # +filename+ is used in the exception message if a Psych::SyntaxError is + # raised. # + # Raises a Psych::SyntaxError when a YAML syntax error is detected. + # # Example: # # Psych.parse_stream("---\n - a\n - b") # => #<Psych::Nodes::Stream:0x00> # + # begin + # Psych.parse_stream("--- `", "file.txt") + # rescue Psych::SyntaxError => ex + # ex.file # => 'file.txt' + # ex.message # => "(foo.txt): found character that cannot start any token" + # end + # # See Psych::Nodes for more information about YAML AST. - def self.parse_stream yaml + def self.parse_stream yaml, filename = nil parser = self.parser - parser.parse yaml + parser.parse yaml, filename parser.handler.root end @@ -221,15 +256,15 @@ # # Psych.load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar'] # - def self.load_stream yaml - parse_stream(yaml).children.map { |child| child.to_ruby } + def self.load_stream yaml, filename = nil + parse_stream(yaml, filename).children.map { |child| child.to_ruby } end ### # Load the document contained in +filename+. Returns the yaml contained in # +filename+ as a ruby object def self.load_file filename - File.open(filename) { |f| self.load f } + File.open(filename) { |f| self.load f, filename } end # :stopdoc: Index: test/psych/test_exception.rb =================================================================== --- test/psych/test_exception.rb (revision 33964) +++ test/psych/test_exception.rb (revision 33965) @@ -16,12 +16,88 @@ @wups = Wups.new end + def test_load_takes_file + ex = assert_raises(Psych::SyntaxError) do + Psych.load '--- `' + end + assert_nil ex.file + + ex = assert_raises(Psych::SyntaxError) do + Psych.load '--- `', 'meow' + end + assert_equal 'meow', ex.file + end + + def test_psych_parse_stream_takes_file + ex = assert_raises(Psych::SyntaxError) do + Psych.parse_stream '--- `' + end + assert_nil ex.file + assert_match '(<unknown>)', ex.message + + ex = assert_raises(Psych::SyntaxError) do + Psych.parse_stream '--- `', 'omg!' + end + assert_equal 'omg!', ex.file + assert_match 'omg!', ex.message + end + + def test_load_stream_takes_file + ex = assert_raises(Psych::SyntaxError) do + Psych.load_stream '--- `' + end + assert_nil ex.file + assert_match '(<unknown>)', ex.message + + ex = assert_raises(Psych::SyntaxError) do + Psych.load_stream '--- `', 'omg!' + end + assert_equal 'omg!', ex.file + end + + def test_parse_file_exception + t = Tempfile.new(['parsefile', 'yml']) + t.binmode + t.write '--- `' + t.close + ex = assert_raises(Psych::SyntaxError) do + Psych.parse_file t.path + end + assert_equal t.path, ex.file + t.close(true) + end + + def test_load_file_exception + t = Tempfile.new(['loadfile', 'yml']) + t.binmode + t.write '--- `' + t.close + ex = assert_raises(Psych::SyntaxError) do + Psych.load_file t.path + end + assert_equal t.path, ex.file + t.close(true) + end + + def test_psych_parse_takes_file + ex = assert_raises(Psych::SyntaxError) do + Psych.parse '--- `' + end + assert_match '(<unknown>)', ex.message + assert_nil ex.file + + ex = assert_raises(Psych::SyntaxError) do + Psych.parse '--- `', 'omg!' + end + assert_match 'omg!', ex.message + end + def test_attributes e = assert_raises(Psych::SyntaxError) { Psych.load '--- `foo' } - assert_equal '<unknown>', e.file + assert_nil e.file assert_equal 1, e.line assert_equal 5, e.column # FIXME: offset isn't being set correctly by libyaml -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/