-
Notifications
You must be signed in to change notification settings - Fork 54
/
seeing_is_believing.rb
69 lines (59 loc) · 2.35 KB
/
seeing_is_believing.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
require 'tmpdir'
require 'seeing_is_believing/result'
require 'seeing_is_believing/version'
require 'seeing_is_believing/debugger'
require 'seeing_is_believing/wrap_expressions_with_inspect'
require 'seeing_is_believing/hash_struct'
require 'seeing_is_believing/evaluate_by_moving_files'
require 'seeing_is_believing/event_stream/handlers/debug'
require 'seeing_is_believing/event_stream/handlers/update_result'
class SeeingIsBelieving
class Options < HashStruct
predicate(:event_handler) { EventStream::Handlers::UpdateResult.new Result.new }
predicate(:local_cwd) { false }
attribute(:filename) { nil }
attribute(:encoding) { nil }
attribute(:stdin) { "" }
attribute(:require_files) { ['seeing_is_believing/the_matrix'] }
attribute(:load_path_dirs) { [File.realpath(__dir__)] }
attribute(:timeout_seconds) { 0 }
attribute(:debugger) { Debugger::Null }
attribute(:max_line_captures) { Float::INFINITY }
attribute(:rewrite_code) { WrapExpressionsWithInspect }
end
def self.call(*args)
new(*args).call
end
attr_reader :options
def initialize(program, options={})
@program = program
@program += "\n" unless @program.end_with? "\n"
@options = Options.new options
end
def call
@memoized_result ||= Dir.mktmpdir("seeing_is_believing_temp_dir") { |dir|
filename = options.filename || File.join(dir, 'program.rb')
new_program = options.rewrite_code.call @program
options.debugger.context("REWRITTEN PROGRAM") { new_program }
EvaluateByMovingFiles.call \
filename,
@program,
new_program,
event_handler: event_handler(options.debugger, options.event_handler),
provided_input: options.stdin,
require_files: options.require_files,
load_path_dirs: options.load_path_dirs,
encoding: options.encoding,
timeout_seconds: options.timeout_seconds,
max_line_captures: options.max_line_captures,
local_cwd: options.local_cwd?
options.event_handler
}
end
private
# If we need debugging, wrap a debugging handler around the current handler
def event_handler(debugger, current_handler)
return current_handler unless debugger.enabled?
EventStream::Handlers::Debug.new debugger, current_handler
end
end