Skip to content

Commit

Permalink
test builder
Browse files Browse the repository at this point in the history
  • Loading branch information
ono-max committed Jun 28, 2021
1 parent 95a269f commit bfb62ac
Showing 1 changed file with 179 additions and 0 deletions.
179 changes: 179 additions & 0 deletions test/tool/test_builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# frozen_string_literal: true

require 'pty'
require 'expect'
require 'tempfile'
require 'json'

module DEBUGGER__
class TestBuilder
def program
<<~RUBY
module Foo
class Bar
def self.a
"hello"
end
def b(n)
2.times do
n
end
end
end
module Baz
def self.c
d = 1
end
end
Bar.a
bar = Bar.new
bar.b(1)
Baz.c
end
RUBY
end

def start
write_temp_file
create_pseudo_terminal
remove_temp_file
create_file
end

def write_temp_file
@temp_file = Tempfile.create(%w[debugger .rb])
@temp_file.write(program)
@temp_file.close
end

def remove_temp_file
File.unlink(@temp_file)
@temp_file = nil
end

RUBY = RbConfig.ruby

def create_pseudo_terminal
ENV['RUBYOPT'] = "-I #{__dir__}/../../lib"
ENV['RUBY_DEBUG_USE_COLORIZE'] = "false"
ENV['RUBY_DEBUG_TEST_MODE'] = 'true'

PTY.spawn("#{RUBY} -r debug/run #{@temp_file.path}") do |read, write, _|
@backlog = []
@last_backlog = []
@scenario = []
while (array = read.expect(%r{.*\n|\(rdbg\)|\[Y/n\]}))
line = array[0]
print line
case line.chomp
when '(rdbg)'
input = gets
write.puts(input)
command = input.chomp
when %r{\[Y/n\]}
input = gets
write.puts
@scenario.push("type '#{input.chomp}'")
when /INTERNAL_INFO:\s(.*)/
if command && !@last_backlog.join.match?(/unknown command:/)
@scenario.push("type '#{command}'")
case command
when 'step', 's', 'next', 'n', 'finish', 'fin', 'continue', 'c'
@internal_info = JSON.parse(Regexp.last_match(1))
@scenario.push("assert_line_num #{@internal_info['line']}")
end
@scenario.push("assert_line_text(\n#{format_last_backlog})")
end
@last_backlog.clear
next # INTERNAL_INFO shouldn't be pushed into @backlog and @last_backlog
end

@backlog.push(line)
@last_backlog.push(line)
end
end
end

def content
<<~TEST
require_relative '../support/test_case'
module DEBUGGER__
class SampleTest < TestCase
def program
<<~RUBY
#{format_program}
RUBY
end
def test_foo
debug_code(program) do
#{format_scenario}
end
end
end
end
TEST
end

def content_without_module
<<-TEST
def test_foo
debug_code(program) do
#{format_scenario}
end
end
TEST
end

def format_last_backlog
lines = ''
@last_backlog[3].slice!("\e[?2004l\r")
@last_backlog[3..].each{|l|
# l.gsub!(/(')|(")/) doesn't work.
l.gsub!(/(')/) { "\\#{Regexp.last_match(1)}" }
l.gsub!(/(")/) { "\\#{Regexp.last_match(1)}" }
lines += "\"#{l.chomp}\" \\\r\n"
}
lines
end

def format_scenario
lines = "#{@scenario[0]}\r\n"
@scenario[1..].each{|e|
lines += " #{e}\r\n"
}
lines.chomp
end

def create_file
path = "#{__dir__}/../debug/sample_test.rb"
if File.exist?(path)
File.open(path, 'r') do |f|
lines = f.read.split("\n")[..-2].join("\n")
@content = lines + content_without_module
end
end
@content ||= content
f = File.new(path)
f.write(@content)
f.close
end

def format_program
lines = program.split("\n")
lines_with_indents = " 1| #{lines[0]}\n"
lines[1..].each_with_index{|e, i|
if i < 9
lines_with_indents += " #{i + 1}| #{e}\r\n"
else
lines_with_indents += " #{i + 1}| #{e}\r\n"
end
}
lines_with_indents.chomp
end
end
end

DEBUGGER__::TestBuilder.new.start

0 comments on commit bfb62ac

Please sign in to comment.