1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33965 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tenderlove 2011-12-06 23:12:37 +00:00
parent c5fada686d
commit 54b214cc23
4 changed files with 136 additions and 15 deletions

View file

@ -1,3 +1,12 @@
Wed Dec 7 08:04:31 2011 Aaron Patterson <aaron@tenderlovemaking.com>
* 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@fsij.org> Tue Dec 6 18:26:33 2011 Tanaka Akira <akr@fsij.org>
* ext/dbm/dbm.c: use db_version() instead of DB_VERSION_STRING to * ext/dbm/dbm.c: use db_version() instead of DB_VERSION_STRING to

View file

@ -106,34 +106,58 @@ module Psych
### ###
# Load +yaml+ in to a Ruby data structure. If multiple documents are # Load +yaml+ in to a Ruby data structure. If multiple documents are
# provided, the object contained in the first document will be returned. # 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: # Example:
# #
# Psych.load("--- a") # => 'a' # Psych.load("--- a") # => 'a'
# Psych.load("---\n - a\n - b") # => ['a', 'b'] # Psych.load("---\n - a\n - b") # => ['a', 'b']
def self.load yaml #
result = parse(yaml) # 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 result ? result.to_ruby : result
end end
### ###
# Parse a YAML string in +yaml+. Returns the first object of a YAML AST. # 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: # Example:
# #
# Psych.parse("---\n - a\n - b") # => #<Psych::Nodes::Sequence:0x00> # 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. # See Psych::Nodes for more information about YAML AST.
def self.parse yaml def self.parse yaml, filename = nil
children = parse_stream(yaml).children children = parse_stream(yaml, filename).children
children.empty? ? false : children.first.children.first children.empty? ? false : children.first.children.first
end end
### ###
# Parse a file at +filename+. Returns the YAML AST. # 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 def self.parse_file filename
File.open filename do |f| File.open filename do |f|
parse f parse f, filename
end end
end end
@ -146,15 +170,26 @@ module Psych
### ###
# Parse a YAML string in +yaml+. Returns the full AST for the YAML document. # Parse a YAML string in +yaml+. Returns the full AST for the YAML document.
# This method can handle multiple YAML documents contained in +yaml+. # 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: # Example:
# #
# Psych.parse_stream("---\n - a\n - b") # => #<Psych::Nodes::Stream:0x00> # 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. # 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 = self.parser
parser.parse yaml parser.parse yaml, filename
parser.handler.root parser.handler.root
end end
@ -221,15 +256,15 @@ module Psych
# #
# Psych.load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar'] # Psych.load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar']
# #
def self.load_stream yaml def self.load_stream yaml, filename = nil
parse_stream(yaml).children.map { |child| child.to_ruby } parse_stream(yaml, filename).children.map { |child| child.to_ruby }
end end
### ###
# Load the document contained in +filename+. Returns the yaml contained in # Load the document contained in +filename+. Returns the yaml contained in
# +filename+ as a ruby object # +filename+ as a ruby object
def self.load_file filename def self.load_file filename
File.open(filename) { |f| self.load f } File.open(filename) { |f| self.load f, filename }
end end
# :stopdoc: # :stopdoc:

View file

@ -3,8 +3,9 @@ module Psych
attr_reader :file, :line, :column, :offset, :problem, :context attr_reader :file, :line, :column, :offset, :problem, :context
def initialize file, line, col, offset, problem, context def initialize file, line, col, offset, problem, context
err = [problem, context].compact.join ' ' err = [problem, context].compact.join ' '
message = "(%s): %s at line %d column %d" % [file, err, line, col] filename = file || '<unknown>'
message = "(%s): %s at line %d column %d" % [filename, err, line, col]
@file = file @file = file
@line = line @line = line

View file

@ -16,12 +16,88 @@ module Psych
@wups = Wups.new @wups = Wups.new
end 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 def test_attributes
e = assert_raises(Psych::SyntaxError) { e = assert_raises(Psych::SyntaxError) {
Psych.load '--- `foo' Psych.load '--- `foo'
} }
assert_equal '<unknown>', e.file assert_nil e.file
assert_equal 1, e.line assert_equal 1, e.line
assert_equal 5, e.column assert_equal 5, e.column
# FIXME: offset isn't being set correctly by libyaml # FIXME: offset isn't being set correctly by libyaml