seeing_is_believing 3.0.0.beta.3 → 3.0.0.beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/features/deprecated-flags.feature +12 -0
- data/features/flags.feature +2 -16
- data/features/regression.feature +46 -0
- data/features/xmpfilter-style.feature +55 -0
- data/lib/seeing_is_believing/binary/interpret_flags.rb +1 -5
- data/lib/seeing_is_believing/binary/parse_args.rb +12 -12
- data/lib/seeing_is_believing/binary/remove_annotations.rb +1 -1
- data/lib/seeing_is_believing/binary.rb +3 -3
- data/lib/seeing_is_believing/evaluate_by_moving_files.rb +60 -11
- data/lib/seeing_is_believing/event_stream/consumer.rb +61 -37
- data/lib/seeing_is_believing/event_stream/events.rb +3 -1
- data/lib/seeing_is_believing/event_stream/producer.rb +38 -21
- data/lib/seeing_is_believing/event_stream/update_result.rb +6 -2
- data/lib/seeing_is_believing/inspect_expressions.rb +5 -1
- data/lib/seeing_is_believing/parser_helpers.rb +11 -1
- data/lib/seeing_is_believing/result.rb +6 -1
- data/lib/seeing_is_believing/the_matrix.rb +18 -18
- data/lib/seeing_is_believing/version.rb +1 -1
- data/lib/seeing_is_believing/wrap_expressions.rb +0 -1
- data/lib/seeing_is_believing.rb +0 -2
- data/seeing_is_believing.gemspec +2 -4
- data/spec/binary/interpret_flags_spec.rb +0 -14
- data/spec/binary/parse_args_spec.rb +5 -6
- data/spec/event_stream_spec.rb +161 -70
- data/spec/seeing_is_believing_spec.rb +29 -63
- metadata +8 -37
- data/features/safe.feature +0 -33
- data/lib/seeing_is_believing/evaluate_with_eval_in.rb +0 -27
@@ -6,10 +6,12 @@ class SeeingIsBelieving
|
|
6
6
|
Stdout = Struct.new(:value)
|
7
7
|
Stderr = Struct.new(:value)
|
8
8
|
MaxLineCaptures = Struct.new(:value)
|
9
|
+
Filename = Struct.new(:value)
|
9
10
|
NumLines = Struct.new(:value)
|
11
|
+
SiBVersion = Struct.new(:value)
|
12
|
+
RubyVersion = Struct.new(:value)
|
10
13
|
Exitstatus = Struct.new(:value)
|
11
14
|
Exception = Struct.new(:line_number, :class_name, :message, :backtrace)
|
12
|
-
Finish = Class.new
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -1,8 +1,16 @@
|
|
1
1
|
require 'seeing_is_believing/event_stream/events'
|
2
|
+
require 'thread'
|
3
|
+
|
2
4
|
class SeeingIsBelieving
|
3
5
|
module EventStream
|
4
|
-
require 'thread'
|
5
6
|
class Producer
|
7
|
+
|
8
|
+
module NullQueue
|
9
|
+
extend self
|
10
|
+
def <<(*) end
|
11
|
+
def shift() end
|
12
|
+
end
|
13
|
+
|
6
14
|
attr_accessor :exitstatus, :max_line_captures, :num_lines, :filename
|
7
15
|
|
8
16
|
def initialize(resultstream)
|
@@ -11,31 +19,38 @@ class SeeingIsBelieving
|
|
11
19
|
self.max_line_captures = Float::INFINITY
|
12
20
|
self.num_lines = 0
|
13
21
|
self.recorded_results = []
|
14
|
-
self.queue =
|
22
|
+
self.queue = Queue.new
|
15
23
|
self.producer_thread = Thread.new do
|
16
|
-
finish = "finish"
|
17
24
|
begin
|
18
25
|
resultstream.sync = true
|
19
26
|
loop do
|
20
27
|
to_publish = queue.shift
|
21
|
-
if to_publish ==
|
22
|
-
|
23
|
-
break
|
24
|
-
else
|
25
|
-
resultstream << (to_publish << "\n")
|
26
|
-
end
|
28
|
+
break if to_publish == :break
|
29
|
+
resultstream << (to_publish << "\n")
|
27
30
|
end
|
28
31
|
rescue IOError, Errno::EPIPE
|
29
|
-
|
32
|
+
queue.clear
|
30
33
|
ensure
|
31
34
|
resultstream.flush rescue nil
|
32
35
|
end
|
36
|
+
self.queue = NullQueue
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
36
|
-
|
37
|
-
|
38
|
-
|
40
|
+
attr_reader :version
|
41
|
+
alias ver version
|
42
|
+
def record_sib_version(sib_version)
|
43
|
+
@version = sib_version
|
44
|
+
queue << "sib_version #{to_string_token sib_version}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def record_ruby_version(ruby_version)
|
48
|
+
queue << "ruby_version #{to_string_token ruby_version}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def record_max_line_captures(max_line_captures)
|
52
|
+
self.max_line_captures = max_line_captures
|
53
|
+
queue << "max_line_captures #{max_line_captures}"
|
39
54
|
end
|
40
55
|
|
41
56
|
StackErrors = [SystemStackError]
|
@@ -89,25 +104,27 @@ class SeeingIsBelieving
|
|
89
104
|
queue << "end"
|
90
105
|
end
|
91
106
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
def record_stderr(stderr)
|
97
|
-
queue << "stderr #{to_string_token stderr}"
|
107
|
+
def record_filename(filename)
|
108
|
+
self.filename = filename
|
109
|
+
queue << "filename #{to_string_token filename}"
|
98
110
|
end
|
99
111
|
|
112
|
+
# note that producer will continue reading until stream is closed
|
100
113
|
def finish!
|
101
|
-
queue << "max_line_captures #{max_line_captures}"
|
102
114
|
queue << "num_lines #{num_lines}"
|
103
115
|
queue << "exitstatus #{exitstatus}"
|
104
|
-
queue <<
|
116
|
+
queue << :break
|
105
117
|
producer_thread.join
|
106
118
|
end
|
107
119
|
|
108
120
|
private
|
109
121
|
|
110
122
|
attr_accessor :resultstream, :queue, :producer_thread, :recorded_results
|
123
|
+
|
124
|
+
# for a consideration of many different ways of doing this, see 5633064
|
125
|
+
def to_string_token(string)
|
126
|
+
[Marshal.dump(string.to_s)].pack('m0')
|
127
|
+
end
|
111
128
|
end
|
112
129
|
end
|
113
130
|
end
|
@@ -1,17 +1,21 @@
|
|
1
1
|
require 'seeing_is_believing/event_stream/events'
|
2
2
|
class SeeingIsBelieving
|
3
3
|
module EventStream
|
4
|
+
# Adapter between EventStream and Result
|
4
5
|
module UpdateResult
|
5
6
|
def self.call(result, event)
|
6
7
|
case event
|
7
8
|
when EventStream::Events::LineResult then result.record_result(event.type, event.line_number, event.inspected)
|
8
9
|
when EventStream::Events::UnrecordedResult then result.record_result(event.type, event.line_number, '...') # <-- is this really what I want?
|
9
10
|
when EventStream::Events::Exception then result.record_exception event.line_number, event.class_name, event.message, event.backtrace
|
10
|
-
when EventStream::Events::Stdout then result.stdout
|
11
|
-
when EventStream::Events::Stderr then result.stderr
|
11
|
+
when EventStream::Events::Stdout then result.stdout << event.value
|
12
|
+
when EventStream::Events::Stderr then result.stderr << event.value
|
12
13
|
when EventStream::Events::MaxLineCaptures then result.number_of_captures = event.value
|
13
14
|
when EventStream::Events::Exitstatus then result.exitstatus = event.value
|
14
15
|
when EventStream::Events::NumLines then result.num_lines = event.value
|
16
|
+
when EventStream::Events::SiBVersion then result.sib_version = event.value
|
17
|
+
when EventStream::Events::RubyVersion then result.ruby_version = event.value
|
18
|
+
when EventStream::Events::Filename then result.filename = event.value
|
15
19
|
else raise "Unknown event: #{event.inspect}"
|
16
20
|
end
|
17
21
|
end
|
@@ -7,7 +7,11 @@ class SeeingIsBelieving
|
|
7
7
|
number_of_captures_as_str = 'Float::INFINITY' if number_of_captures == Float::INFINITY
|
8
8
|
|
9
9
|
wrap_expressions_callbacks = {}
|
10
|
-
wrap_expressions_callbacks[:before_all] = options.fetch :before_all, -> { "$SiB.
|
10
|
+
wrap_expressions_callbacks[:before_all] = options.fetch :before_all, -> { "$SiB.record_ruby_version RUBY_VERSION;"\
|
11
|
+
"$SiB.record_sib_version #{VERSION.inspect};"\
|
12
|
+
"$SiB.record_filename #{filename.inspect};"\
|
13
|
+
"$SiB.record_max_line_captures #{number_of_captures_as_str};"\
|
14
|
+
"$SiB.num_lines = #{program.lines.count}; " }
|
11
15
|
wrap_expressions_callbacks[:after_all] = options.fetch :after_all, -> { "" }
|
12
16
|
wrap_expressions_callbacks[:before_each] = options.fetch :before_each, -> line_number { "(" }
|
13
17
|
wrap_expressions_callbacks[:after_each] = options.fetch :after_each, -> line_number { ").tap { |v| $SiB.record_result(:inspect, #{line_number}, v) }" }
|
@@ -1,4 +1,14 @@
|
|
1
|
-
|
1
|
+
module Parser
|
2
|
+
class << self
|
3
|
+
# With new versioning, there's lots of small versions
|
4
|
+
# we don't need it to complain that we're on 2.1.1 and its parsing 2.1.5
|
5
|
+
# https://github.com/whitequark/parser/blob/e2249d7051b1adb6979139928e14a81bc62f566e/lib/parser/current.rb#L3
|
6
|
+
def warn(*) end
|
7
|
+
require 'parser/current'
|
8
|
+
remove_method :warn
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
2
12
|
class SeeingIsBelieving
|
3
13
|
module ParserHelpers
|
4
14
|
|
@@ -3,7 +3,12 @@ class SeeingIsBelieving
|
|
3
3
|
include Enumerable
|
4
4
|
RecordedException = Struct.new :line_number, :class_name, :message, :backtrace
|
5
5
|
|
6
|
-
attr_accessor :stdout, :stderr, :exitstatus, :number_of_captures, :exception, :num_lines
|
6
|
+
attr_accessor :stdout, :stderr, :exitstatus, :number_of_captures, :exception, :num_lines, :sib_version, :ruby_version, :filename
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
self.stdout = ''
|
10
|
+
self.stderr = ''
|
11
|
+
end
|
7
12
|
|
8
13
|
alias has_exception? exception
|
9
14
|
|
@@ -8,28 +8,28 @@
|
|
8
8
|
require_relative 'version'
|
9
9
|
require_relative 'event_stream/producer'
|
10
10
|
|
11
|
-
event_stream =
|
11
|
+
event_stream = IO.open(ARGV.shift.to_i, "w")
|
12
12
|
$SiB = SeeingIsBelieving::EventStream::Producer.new(event_stream)
|
13
13
|
|
14
|
-
stdout = STDOUT
|
15
|
-
|
16
|
-
|
14
|
+
stdout, stderr = STDOUT, STDERR
|
15
|
+
finish = lambda do
|
16
|
+
$SiB.finish!
|
17
|
+
event_stream.close
|
18
|
+
stdout.flush
|
19
|
+
stderr.flush
|
20
|
+
end
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
|
22
|
+
real_exec = method :exec
|
23
|
+
Kernel.module_eval do
|
24
|
+
private
|
25
|
+
define_method :exec do |*args, &block| # TODO: Add an event for exec?
|
26
|
+
finish.call
|
27
|
+
real_exec.call(*args, &block)
|
28
|
+
end
|
29
|
+
end
|
21
30
|
|
22
31
|
at_exit do
|
23
|
-
_, blackhole = IO.pipe
|
24
|
-
stdout.reopen(blackhole)
|
25
|
-
stderr.reopen(blackhole)
|
26
|
-
|
27
|
-
write_stdout.close unless write_stdout.closed?
|
28
|
-
$SiB.record_stdout read_stdout.read
|
29
|
-
|
30
|
-
write_stderr.close unless write_stderr.closed?
|
31
|
-
$SiB.record_stderr read_stderr.read
|
32
|
-
|
33
32
|
$SiB.record_exception nil, $! if $!
|
34
|
-
|
33
|
+
finish.call
|
34
|
+
Kernel.exit! 0 # clear the exception so it doesn't print to stderr and change the processes actual exit status (we recorded what it should be)
|
35
35
|
end
|
data/lib/seeing_is_believing.rb
CHANGED
@@ -23,7 +23,6 @@ class SeeingIsBelieving
|
|
23
23
|
@encoding = options.fetch :encoding, nil
|
24
24
|
@timeout = options[:timeout]
|
25
25
|
@debugger = options.fetch :debugger, Debugger.new(stream: nil)
|
26
|
-
@ruby_executable = options.fetch :ruby_executable, 'ruby'
|
27
26
|
@number_of_captures = options.fetch :number_of_captures, Float::INFINITY
|
28
27
|
@evaluator = options.fetch :evaluator, EvaluateByMovingFiles
|
29
28
|
@record_expressions = options.fetch :record_expressions, InspectExpressions # TODO: rename to wrap_expressions
|
@@ -42,7 +41,6 @@ class SeeingIsBelieving
|
|
42
41
|
load_path: @load_path,
|
43
42
|
encoding: @encoding,
|
44
43
|
timeout: @timeout,
|
45
|
-
ruby_executable: @ruby_executable,
|
46
44
|
debugger: @debugger
|
47
45
|
|
48
46
|
@debugger.context("RESULT") { result.inspect }
|
data/seeing_is_believing.gemspec
CHANGED
@@ -19,11 +19,9 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_dependency "
|
23
|
-
s.add_dependency "parser", ">= 2.1.4", "< 2.3"
|
22
|
+
s.add_dependency "parser", ">= 2.2", "< 3.0"
|
24
23
|
|
25
|
-
s.add_development_dependency "
|
26
|
-
s.add_development_dependency "haiti", ">= 0.1", "< 0.3"
|
24
|
+
s.add_development_dependency "haiti", ">= 0.1", "< 0.3"
|
27
25
|
s.add_development_dependency "rake", "~> 10.0"
|
28
26
|
s.add_development_dependency "rspec", "~> 3.0"
|
29
27
|
s.add_development_dependency "cucumber", "~> 1.2"
|
@@ -131,12 +131,6 @@ class SeeingIsBelieving
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
-
context 'shebang' do
|
135
|
-
it 'sets shebang to the value' do
|
136
|
-
expect(call(shebang: 'whatevz').shebang).to eq 'whatevz'
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
134
|
context 'filename' do
|
141
135
|
it 'sets this as the filename' do
|
142
136
|
expect(call(filename: 'somefilename').filename).to eq 'somefilename'
|
@@ -239,20 +233,12 @@ class SeeingIsBelieving
|
|
239
233
|
expect(call[:evaluate_with]).to eq EvaluateByMovingFiles
|
240
234
|
end
|
241
235
|
|
242
|
-
specify 'evaluate_with is EvaluateWithEvalIn if safe is set' do
|
243
|
-
expect(call(safe: true)[:evaluate_with]).to eq EvaluateWithEvalIn
|
244
|
-
end
|
245
|
-
|
246
236
|
specify 'filename is the as option or the provided filename' do
|
247
237
|
expect(call(filename: 'from_fn')[:filename]).to eq 'from_fn'
|
248
238
|
expect(call(as: 'from_as')[:filename]).to eq 'from_as'
|
249
239
|
expect(call(as: 'from_as', filename: 'from_fn')[:filename]).to eq 'from_as'
|
250
240
|
end
|
251
241
|
|
252
|
-
specify 'ruby_executable is the shebang' do
|
253
|
-
expect(call(shebang: 'shebangprog')[:ruby_executable]).to eq 'shebangprog'
|
254
|
-
end
|
255
|
-
|
256
242
|
specify 'stdin is empty when the program is on stdin, and is stdin otherwise' do
|
257
243
|
# NOTE: the lib will normalize this into a stream
|
258
244
|
expect(call(filename: nil, program_from_args: nil)[:stdin]).to eq ''
|
@@ -341,12 +341,11 @@ RSpec.describe SeeingIsBelieving::Binary::ParseArgs do
|
|
341
341
|
end
|
342
342
|
|
343
343
|
describe ':shebang' do
|
344
|
-
it '
|
345
|
-
expect(parse([])[:
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
expect(parse(['--shebang', 'not_ruby'])[:shebang]).to eq 'not_ruby'
|
344
|
+
it 'is added to the list of deprecated flags' do
|
345
|
+
expect(parse([])[:deprecated_flags]).to eq []
|
346
|
+
parsed = parse(['--shebang', 'not_ruby', 'other'])
|
347
|
+
expect(parsed[:shebang]).to eq nil
|
348
|
+
expect(parsed[:deprecated_flags]).to eq ['--shebang', 'not_ruby']
|
350
349
|
end
|
351
350
|
|
352
351
|
it 'sets an error if not given a next arg to execute' do
|
data/spec/event_stream_spec.rb
CHANGED
@@ -5,28 +5,54 @@ require 'seeing_is_believing/event_stream/consumer'
|
|
5
5
|
|
6
6
|
module SeeingIsBelieving::EventStream
|
7
7
|
RSpec.describe SeeingIsBelieving::EventStream do
|
8
|
-
attr_accessor :producer, :consumer
|
8
|
+
attr_accessor :producer, :consumer
|
9
|
+
attr_accessor :eventstream_consumer, :eventstream_producer
|
10
|
+
attr_accessor :stdout_consumer, :stdout_producer
|
11
|
+
attr_accessor :stderr_consumer, :stderr_producer
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
self.producer = SeeingIsBelieving::EventStream::Producer.new(writestream)
|
13
|
-
self.consumer = SeeingIsBelieving::EventStream::Consumer.new(readstream)
|
13
|
+
def close_streams(*streams)
|
14
|
+
streams.each { |fd| fd.close unless fd.closed? }
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
+
def finish!
|
17
18
|
producer.finish!
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
close_streams eventstream_producer, stdout_producer, stderr_producer
|
20
|
+
end
|
21
|
+
|
22
|
+
before do
|
23
|
+
self.eventstream_consumer, self.eventstream_producer = IO.pipe
|
24
|
+
self.stdout_consumer, self.stdout_producer = IO.pipe
|
25
|
+
self.stderr_consumer, self.stderr_producer = IO.pipe
|
26
|
+
|
27
|
+
self.producer = SeeingIsBelieving::EventStream::Producer.new eventstream_producer
|
28
|
+
self.consumer = SeeingIsBelieving::EventStream::Consumer.new \
|
29
|
+
events: eventstream_consumer,
|
30
|
+
stdout: stdout_consumer,
|
31
|
+
stderr: stderr_consumer
|
32
|
+
end
|
33
|
+
|
34
|
+
after do
|
35
|
+
finish!
|
36
|
+
close_streams eventstream_consumer, stdout_consumer, stderr_consumer
|
37
|
+
end
|
21
38
|
|
22
39
|
describe 'emitting an event' do
|
23
|
-
|
24
|
-
|
25
|
-
|
40
|
+
def has_message?(io)
|
41
|
+
io.read_nonblock(1) # ~> IO::EAGAINWaitReadable: Resource temporarily unavailable - read would block
|
42
|
+
rescue Errno::EAGAIN
|
43
|
+
return false
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'writes its events to the event stream' do
|
47
|
+
read, write = IO.pipe
|
48
|
+
producer = SeeingIsBelieving::EventStream::Producer.new(write)
|
49
|
+
expect(has_message? read).to eq false
|
50
|
+
producer.record_filename "whatever.rb"
|
51
|
+
expect(read.gets).to start_with 'filename'
|
52
|
+
end
|
26
53
|
|
27
|
-
# This test is irrelevant on MRI b/c of the GIL,
|
28
|
-
|
29
|
-
it 'is wrapped in a mutex to prevent multiple values from writing at the same time' do
|
54
|
+
# This test is irrelevant on MRI b/c of the GIL, but I ran it on Rbx to make sure it works
|
55
|
+
it 'is threadsafe as multiple events can occur at once' do
|
30
56
|
num_threads = 10
|
31
57
|
num_results = 600
|
32
58
|
line_nums_and_inspections = num_threads.times.flat_map { |line_num|
|
@@ -51,58 +77,58 @@ module SeeingIsBelieving::EventStream
|
|
51
77
|
expect(producer_threads).to be_none(&:alive?)
|
52
78
|
end
|
53
79
|
|
54
|
-
it 'raises NoMoreInput
|
55
|
-
|
80
|
+
it 'raises NoMoreInput if input is closed before it finishes reading the number of requested inputs' do
|
81
|
+
finish!
|
56
82
|
expect { consumer.call 10 }.to raise_error SeeingIsBelieving::EventStream::Consumer::NoMoreInput
|
57
83
|
end
|
58
84
|
|
59
|
-
it 'raises NoMoreInput
|
85
|
+
it 'raises NoMoreInput once it its input streams are all closed' do
|
60
86
|
producer.finish!
|
61
|
-
|
87
|
+
close_streams eventstream_producer, stdout_producer, stderr_producer
|
88
|
+
consumer.call 2
|
62
89
|
expect { consumer.call }.to raise_error SeeingIsBelieving::EventStream::Consumer::NoMoreInput
|
63
|
-
expect(consumer).to be_finished
|
64
90
|
end
|
65
91
|
|
66
|
-
it 'raises NoMoreInput
|
67
|
-
|
92
|
+
it 'raises NoMoreInput if its end of the stream is closed and there is no more stdout/stderr' do
|
93
|
+
close_streams eventstream_consumer, stdout_producer, stderr_producer
|
94
|
+
expect { consumer.call }.to raise_error SeeingIsBelieving::EventStream::Consumer::WtfWhoClosedMyShit
|
68
95
|
expect { consumer.call }.to raise_error SeeingIsBelieving::EventStream::Consumer::NoMoreInput
|
69
|
-
expect(consumer).to be_finished
|
70
96
|
end
|
71
97
|
|
72
|
-
it 'raises WtfWhoClosedMyShit
|
73
|
-
|
98
|
+
it 'raises WtfWhoClosedMyShit if its end of the stream is closed' do
|
99
|
+
close_streams eventstream_consumer, stdout_producer, stderr_producer
|
74
100
|
expect { consumer.call }.to raise_error SeeingIsBelieving::EventStream::Consumer::WtfWhoClosedMyShit
|
75
|
-
expect(consumer).to be_finished
|
76
101
|
end
|
77
102
|
end
|
78
103
|
|
79
104
|
describe 'each' do
|
80
|
-
it 'loops through and yields all events
|
105
|
+
it 'loops through and yields all events' do
|
81
106
|
producer.record_result :inspect, 100, 2
|
82
|
-
|
107
|
+
finish!
|
83
108
|
|
84
109
|
events = []
|
85
110
|
consumer.each { |e| events << e }
|
86
|
-
finish_event = events.find { |e| e.kind_of? Events::Finish }
|
87
111
|
line_result = events.find { |e| e.kind_of? Events::LineResult }
|
88
112
|
exitstatus = events.find { |e| e.kind_of? Events::Exitstatus }
|
89
|
-
expect(finish_event).to be_nil
|
90
113
|
expect(line_result.line_number).to eq 100
|
91
114
|
expect(exitstatus.value).to eq 0
|
92
115
|
end
|
93
116
|
|
94
117
|
it 'stops looping if there is no more input' do
|
95
|
-
|
96
|
-
expect(consumer.each.map { |e| e }).to eq [
|
118
|
+
finish!
|
119
|
+
expect(consumer.each.map { |e| e }).to eq [
|
120
|
+
Events::NumLines.new(0),
|
121
|
+
Events::Exitstatus.new(0),
|
122
|
+
]
|
97
123
|
end
|
98
124
|
|
99
125
|
it 'returns nil' do
|
100
|
-
|
126
|
+
finish!
|
101
127
|
expect(consumer.each { 1 }).to eq nil
|
102
128
|
end
|
103
129
|
|
104
130
|
it 'returns an enumerator if not given a block' do
|
105
|
-
|
131
|
+
finish!
|
106
132
|
expect(consumer.each.map &:class).to include Events::Exitstatus
|
107
133
|
end
|
108
134
|
end
|
@@ -257,6 +283,29 @@ module SeeingIsBelieving::EventStream
|
|
257
283
|
end
|
258
284
|
end
|
259
285
|
|
286
|
+
describe 'max_line_captures (value and recording)' do
|
287
|
+
it 'is infinity by default' do
|
288
|
+
expect(producer.max_line_captures).to eq Float::INFINITY
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'emits the event and sets the max_line_captures' do
|
292
|
+
producer.record_max_line_captures 123
|
293
|
+
expect(producer.max_line_captures).to eq 123
|
294
|
+
expect(consumer.call).to eq Events::MaxLineCaptures.new(123)
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'interprets numbers' do
|
298
|
+
producer.record_max_line_captures 12
|
299
|
+
expect(consumer.call).to eq Events::MaxLineCaptures.new(12)
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'interprets infinity' do
|
303
|
+
producer.record_max_line_captures Float::INFINITY
|
304
|
+
expect(consumer.call).to eq Events::MaxLineCaptures.new(Float::INFINITY)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
|
260
309
|
describe 'exceptions' do
|
261
310
|
def record_exception(linenum=nil, &raises_exception)
|
262
311
|
raises_exception.call
|
@@ -326,45 +375,45 @@ module SeeingIsBelieving::EventStream
|
|
326
375
|
context 'recorded line number | line num is provided | it knows the file | exception comes from within file' do
|
327
376
|
let(:exception) { begin; raise "zomg"; rescue; $!; end }
|
328
377
|
let(:linenum) { __LINE__ - 1 }
|
329
|
-
|
378
|
+
example "provided one | true | true | true" do
|
330
379
|
producer.filename = __FILE__
|
331
380
|
producer.record_exception 12, exception
|
332
381
|
assert_exception consumer.call, recorded_line_no: 12
|
333
382
|
end
|
334
|
-
|
383
|
+
example "provided one | true | true | false" do
|
335
384
|
exception.backtrace.replace ['otherfile.rb']
|
336
385
|
producer.record_exception 12, exception
|
337
386
|
producer.filename = __FILE__
|
338
387
|
assert_exception consumer.call, recorded_line_no: 12
|
339
388
|
end
|
340
|
-
|
389
|
+
example "provided one | true | false | true" do
|
341
390
|
producer.filename = nil
|
342
391
|
producer.record_exception 12, exception
|
343
392
|
assert_exception consumer.call, recorded_line_no: 12
|
344
393
|
end
|
345
|
-
|
394
|
+
example "provided one | true | false | false" do
|
346
395
|
exception.backtrace.replace ['otherfile.rb']
|
347
396
|
producer.filename = nil
|
348
397
|
producer.record_exception 12, exception
|
349
398
|
assert_exception consumer.call, recorded_line_no: 12
|
350
399
|
end
|
351
|
-
|
400
|
+
example "from backtrace | false | true | true" do
|
352
401
|
producer.filename = __FILE__
|
353
402
|
producer.record_exception nil, exception
|
354
403
|
assert_exception consumer.call, recorded_line_no: linenum
|
355
404
|
end
|
356
|
-
|
405
|
+
example "-1 | false | true | false" do
|
357
406
|
exception.backtrace.replace ['otherfile.rb']
|
358
407
|
producer.filename = __FILE__
|
359
408
|
producer.record_exception nil, exception
|
360
409
|
assert_exception consumer.call, recorded_line_no: -1
|
361
410
|
end
|
362
|
-
|
411
|
+
example "-1 | false | false | true" do
|
363
412
|
producer.filename = nil
|
364
413
|
producer.record_exception nil, exception
|
365
414
|
assert_exception consumer.call, recorded_line_no: -1
|
366
415
|
end
|
367
|
-
|
416
|
+
example "-1 | false | false | false" do
|
368
417
|
exception.backtrace.replace ['otherfile.rb']
|
369
418
|
producer.filename = nil
|
370
419
|
producer.record_exception nil, exception
|
@@ -373,40 +422,83 @@ module SeeingIsBelieving::EventStream
|
|
373
422
|
end
|
374
423
|
end
|
375
424
|
|
425
|
+
describe 'seeing is believing version' do
|
426
|
+
describe 'recording the version' do
|
427
|
+
it 'emits the version info' do
|
428
|
+
producer.record_sib_version '1.2.3'
|
429
|
+
expect(consumer.call).to eq Events::SiBVersion.new("1.2.3")
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
specify 'version return the version, if it has been set' do
|
434
|
+
expect(producer.version).to eq nil
|
435
|
+
producer.record_sib_version '4.5.6'
|
436
|
+
expect(producer.version).to eq '4.5.6'
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
describe 'record_ruby_version' do
|
441
|
+
it 'emits the ruby version info' do
|
442
|
+
producer.record_ruby_version 'o.m.g.'
|
443
|
+
expect(consumer.call).to eq Events::RubyVersion.new('o.m.g.')
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
describe 'record_filename' do
|
448
|
+
it 'sets the filename' do
|
449
|
+
producer.record_filename 'this-iz-mah-file.rb'
|
450
|
+
expect(producer.filename).to eq 'this-iz-mah-file.rb'
|
451
|
+
end
|
452
|
+
it 'emits the filename' do
|
453
|
+
producer.record_filename 'this-iz-mah-file.rb'
|
454
|
+
expect(consumer.call).to eq Events::Filename.new('this-iz-mah-file.rb')
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
376
458
|
describe 'stdout' do
|
377
|
-
it 'is
|
378
|
-
|
379
|
-
expect(consumer.call).to eq Events::Stdout.new("this is the stdout
|
459
|
+
it 'is emitted along with the events from the event stream' do
|
460
|
+
stdout_producer.puts "this is the stdout¡"
|
461
|
+
expect(consumer.call).to eq Events::Stdout.new("this is the stdout¡\n")
|
462
|
+
end
|
463
|
+
specify 'each line is emitted as an event' do
|
464
|
+
stdout_producer.puts "first"
|
465
|
+
stdout_producer.puts "second\nthird"
|
466
|
+
expect(consumer.call).to eq Events::Stdout.new("first\n")
|
467
|
+
expect(consumer.call).to eq Events::Stdout.new("second\n")
|
468
|
+
expect(consumer.call).to eq Events::Stdout.new("third\n")
|
380
469
|
end
|
381
470
|
end
|
382
471
|
|
383
472
|
describe 'stderr' do
|
384
|
-
it 'is
|
385
|
-
|
386
|
-
expect(consumer.call).to eq Events::Stderr.new("this is the stderr
|
473
|
+
it 'is emitted along with the events from the event stream' do
|
474
|
+
stderr_producer.puts "this is the stderr¡"
|
475
|
+
expect(consumer.call).to eq Events::Stderr.new("this is the stderr¡\n")
|
476
|
+
end
|
477
|
+
specify 'each line is emitted as an event' do
|
478
|
+
stderr_producer.puts "first"
|
479
|
+
stderr_producer.puts "second\nthird"
|
480
|
+
expect(consumer.call).to eq Events::Stderr.new("first\n")
|
481
|
+
expect(consumer.call).to eq Events::Stderr.new("second\n")
|
482
|
+
expect(consumer.call).to eq Events::Stderr.new("third\n")
|
387
483
|
end
|
388
484
|
end
|
389
485
|
|
486
|
+
|
390
487
|
describe 'finish!' do
|
391
488
|
def final_event(producer, consumer, event_class)
|
392
|
-
|
393
|
-
consumer.call(
|
489
|
+
finish!
|
490
|
+
consumer.call(2).find { |e| e.class == event_class }
|
394
491
|
end
|
395
492
|
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
end
|
406
|
-
|
407
|
-
it 'is infinity by default' do
|
408
|
-
expect(final_event(producer, consumer, Events::MaxLineCaptures).value).to eq Float::INFINITY
|
409
|
-
end
|
493
|
+
it 'stops the producer from producing' do
|
494
|
+
read, write = IO.pipe
|
495
|
+
producer = SeeingIsBelieving::EventStream::Producer.new write
|
496
|
+
producer.finish!
|
497
|
+
read.gets
|
498
|
+
read.gets
|
499
|
+
producer.record_filename("zomg")
|
500
|
+
write.close
|
501
|
+
expect(read.gets).to eq nil
|
410
502
|
end
|
411
503
|
|
412
504
|
describe 'num_lines' do
|
@@ -443,13 +535,12 @@ module SeeingIsBelieving::EventStream
|
|
443
535
|
expect(final_event(producer, consumer, Events::Exitstatus).value).to eq 74
|
444
536
|
end
|
445
537
|
end
|
538
|
+
end
|
446
539
|
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
end
|
452
|
-
end
|
540
|
+
specify 'if an incomprehensible event is received, it raises an UnknownEvent' do
|
541
|
+
eventstream_producer.puts "this is nonsense!"
|
542
|
+
eventstream_producer.close
|
543
|
+
expect{ consumer.call }.to raise_error SeeingIsBelieving::EventStream::Consumer::UnknownEvent, /nonsense/
|
453
544
|
end
|
454
545
|
end
|
455
546
|
end
|