summaryrefslogtreecommitdiff
path: root/test/ruby/test_ast.rb
diff options
context:
space:
mode:
authoryui-knk <yui-knk@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-05 00:18:29 +0000
committeryui-knk <yui-knk@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-05 00:18:29 +0000
commit9e1bb6ed5a5efb3726fdbfb1f3331989b27f0b1d (patch)
treeccfe794932594465571419cebbf1d27d5f2d1af7 /test/ruby/test_ast.rb
parentfa0e55707c2e3b9680eb0e82be491762c4db6aaa (diff)
Move a test file
* test/-ext-/ast/test_ast.rb: This test file has not depended C extension since r63534, so move to 'test/ruby/'. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63568 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/ruby/test_ast.rb')
-rw-r--r--test/ruby/test_ast.rb141
1 files changed, 141 insertions, 0 deletions
diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb
new file mode 100644
index 0000000000..7a60811ec0
--- /dev/null
+++ b/test/ruby/test_ast.rb
@@ -0,0 +1,141 @@
+# frozen_string_literal: false
+require 'test/unit'
+
+class RubyVM
+ module AST
+ class Node
+ class CodePosition
+ include Comparable
+ attr_reader :lineno, :column
+ def initialize(lineno, column)
+ @lineno = lineno
+ @column = column
+ end
+
+ def <=>(other)
+ case
+ when lineno < other.lineno
+ -1
+ when lineno == other.lineno
+ column <=> other.column
+ when lineno > other.lineno
+ 1
+ end
+ end
+ end
+
+ def beg_pos
+ CodePosition.new(first_lineno, first_column)
+ end
+
+ def end_pos
+ CodePosition.new(last_lineno, last_column)
+ end
+
+ alias to_s inspect
+ end
+ end
+end
+
+class TestAst < Test::Unit::TestCase
+ class Helper
+ attr_reader :errors
+
+ def initialize(path)
+ @path = path
+ @errors = []
+ @debug = false
+ end
+
+ def validate_range
+ @errors = []
+ validate_range0(ast)
+
+ @errors.empty?
+ end
+
+ def validate_not_cared
+ @errors = []
+ validate_not_cared0(ast)
+
+ @errors.empty?
+ end
+
+ def ast
+ return @ast if defined?(@ast)
+ ast = RubyVM::AST.parse_file(@path)
+ raise "Syntax error: #{@path}" if ast.nil?
+ @ast = ast
+ end
+
+ private
+
+ def validate_range0(node)
+ beg_pos, end_pos = node.beg_pos, node.end_pos
+ children = node.children.compact
+
+ return true if children.empty?
+ # These NODE_D* has NODE_ARRAY as nd_next->nd_next whose last locations
+ # we can not update when item is appended.
+ return true if ["NODE_DSTR", "NODE_DXSTR", "NODE_DREGX", "NODE_DSYM"].include? node.type
+
+ min = children.map(&:beg_pos).min
+ max = children.map(&:end_pos).max
+
+ unless beg_pos <= min
+ @errors << { type: :min_validation_error, min: min, beg_pos: beg_pos, node: node }
+ end
+
+ unless max <= end_pos
+ @errors << { type: :max_validation_error, max: max, end_pos: end_pos, node: node }
+ end
+
+ p "#{node} => #{children}" if @debug
+
+ children.each do |child|
+ p child if @debug
+ validate_range0(child)
+ end
+ end
+
+ def validate_not_cared0(node)
+ beg_pos, end_pos = node.beg_pos, node.end_pos
+ children = node.children.compact
+
+ @errors << { type: :first_lineno, node: node } if beg_pos.lineno == 0
+ @errors << { type: :first_column, node: node } if beg_pos.column == -1
+ @errors << { type: :last_lineno, node: node } if end_pos.lineno == 0
+ @errors << { type: :last_column, node: node } if end_pos.column == -1
+
+ children.each {|c| validate_not_cared0(c) }
+ end
+ end
+
+ SRCDIR = File.expand_path("../../..", __FILE__)
+
+ Dir.glob("test/**/*.rb", base: SRCDIR).each do |path|
+ define_method("test_ranges:#{path}") do
+ helper = Helper.new("#{SRCDIR}/#{path}")
+ helper.validate_range
+
+ assert_equal([], helper.errors)
+ end
+ end
+
+ Dir.glob("test/**/*.rb", base: SRCDIR).each do |path|
+ define_method("test_not_cared:#{path}") do
+ helper = Helper.new("#{SRCDIR}/#{path}")
+ helper.validate_not_cared
+
+ assert_equal([], helper.errors)
+ end
+ end
+
+ def test_column_with_long_heredoc_identifier
+ term = "A"*257
+ ast = RubyVM::AST.parse("<<-#{term}\n""ddddddd\n#{term}\n")
+ node = ast.children[1]
+ assert_equal("NODE_STR", node.type)
+ assert_equal(0, node.first_column)
+ end
+end