seeing_is_believing 3.0.0.beta.4 → 3.0.0.beta.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -8
  3. data/Rakefile +1 -1
  4. data/Readme.md +65 -25
  5. data/bin/seeing_is_believing +1 -0
  6. data/docs/sib-streaming.gif +0 -0
  7. data/features/deprecated-flags.feature +62 -2
  8. data/features/errors.feature +12 -7
  9. data/features/examples.feature +143 -4
  10. data/features/flags.feature +89 -29
  11. data/features/regression.feature +58 -14
  12. data/features/support/env.rb +4 -0
  13. data/features/xmpfilter-style.feature +181 -36
  14. data/lib/seeing_is_believing.rb +44 -33
  15. data/lib/seeing_is_believing/binary.rb +31 -88
  16. data/lib/seeing_is_believing/binary/align_chunk.rb +30 -11
  17. data/lib/seeing_is_believing/binary/annotate_end_of_file.rb +10 -16
  18. data/lib/seeing_is_believing/binary/annotate_every_line.rb +5 -25
  19. data/lib/seeing_is_believing/binary/annotate_marked_lines.rb +136 -0
  20. data/lib/seeing_is_believing/binary/comment_lines.rb +8 -10
  21. data/lib/seeing_is_believing/binary/commentable_lines.rb +20 -26
  22. data/lib/seeing_is_believing/binary/config.rb +392 -0
  23. data/lib/seeing_is_believing/binary/data_structures.rb +57 -0
  24. data/lib/seeing_is_believing/binary/engine.rb +104 -0
  25. data/lib/seeing_is_believing/binary/{comment_formatter.rb → format_comment.rb} +6 -6
  26. data/lib/seeing_is_believing/binary/remove_annotations.rb +29 -28
  27. data/lib/seeing_is_believing/binary/rewrite_comments.rb +42 -43
  28. data/lib/seeing_is_believing/code.rb +105 -49
  29. data/lib/seeing_is_believing/debugger.rb +6 -5
  30. data/lib/seeing_is_believing/error.rb +6 -17
  31. data/lib/seeing_is_believing/evaluate_by_moving_files.rb +78 -129
  32. data/lib/seeing_is_believing/event_stream/consumer.rb +114 -64
  33. data/lib/seeing_is_believing/event_stream/events.rb +169 -11
  34. data/lib/seeing_is_believing/event_stream/handlers/debug.rb +57 -0
  35. data/lib/seeing_is_believing/event_stream/handlers/record_exitstatus.rb +18 -0
  36. data/lib/seeing_is_believing/event_stream/handlers/stream_json_events.rb +45 -0
  37. data/lib/seeing_is_believing/event_stream/handlers/update_result.rb +39 -0
  38. data/lib/seeing_is_believing/event_stream/producer.rb +25 -24
  39. data/lib/seeing_is_believing/hash_struct.rb +206 -0
  40. data/lib/seeing_is_believing/result.rb +20 -3
  41. data/lib/seeing_is_believing/the_matrix.rb +20 -12
  42. data/lib/seeing_is_believing/version.rb +1 -1
  43. data/lib/seeing_is_believing/wrap_expressions.rb +55 -115
  44. data/lib/seeing_is_believing/wrap_expressions_with_inspect.rb +14 -0
  45. data/seeing_is_believing.gemspec +1 -1
  46. data/spec/binary/alignment_specs.rb +27 -0
  47. data/spec/binary/comment_lines_spec.rb +3 -2
  48. data/spec/binary/config_spec.rb +657 -0
  49. data/spec/binary/engine_spec.rb +97 -0
  50. data/spec/binary/{comment_formatter_spec.rb → format_comment_spec.rb} +2 -2
  51. data/spec/binary/marker_spec.rb +71 -0
  52. data/spec/binary/options_spec.rb +0 -0
  53. data/spec/binary/remove_annotations_spec.rb +31 -18
  54. data/spec/binary/rewrite_comments_spec.rb +26 -11
  55. data/spec/code_spec.rb +190 -6
  56. data/spec/debugger_spec.rb +4 -0
  57. data/spec/evaluate_by_moving_files_spec.rb +38 -20
  58. data/spec/event_stream_spec.rb +265 -116
  59. data/spec/hash_struct_spec.rb +514 -0
  60. data/spec/seeing_is_believing_spec.rb +108 -46
  61. data/spec/spec_helper.rb +9 -0
  62. data/spec/wrap_expressions_spec.rb +207 -172
  63. metadata +30 -18
  64. data/docs/for-presentations +0 -33
  65. data/lib/seeing_is_believing/binary/annotate_xmpfilter_style.rb +0 -128
  66. data/lib/seeing_is_believing/binary/interpret_flags.rb +0 -156
  67. data/lib/seeing_is_believing/binary/parse_args.rb +0 -263
  68. data/lib/seeing_is_believing/event_stream/update_result.rb +0 -24
  69. data/lib/seeing_is_believing/inspect_expressions.rb +0 -21
  70. data/lib/seeing_is_believing/parser_helpers.rb +0 -82
  71. data/spec/binary/interpret_flags_spec.rb +0 -332
  72. data/spec/binary/parse_args_spec.rb +0 -415
@@ -1,28 +1,26 @@
1
1
  require 'seeing_is_believing/binary/commentable_lines'
2
2
 
3
3
  class SeeingIsBelieving
4
- # spec/binary/comment_lines_spec.rb
5
4
  module Binary
6
-
7
5
  # takes a body and a block
8
6
  # passes the block the line
9
7
  # the block returns the comment to add at the end of it
10
8
  class CommentLines
11
- def self.call(code, &commenter)
12
- new(code, &commenter).call
9
+ def self.call(raw_code, &commenter)
10
+ new(raw_code, &commenter).call
13
11
  end
14
12
 
15
- def initialize(code, &commenter)
16
- self.code, self.commenter = code, commenter
13
+ def initialize(raw_code, &commenter)
14
+ self.raw_code, self.commenter = raw_code, commenter
17
15
  end
18
16
 
19
17
  def call
20
18
  @call ||= begin
21
- commentable_lines = CommentableLines.new code
19
+ commentable_lines = CommentableLines.new raw_code
22
20
  commentable_lines.call.each do |line_number, (index_of_newline, col)|
23
21
  first_index = last_index = index_of_newline
24
- first_index -= 1 while first_index > 0 && code[first_index-1] != "\n"
25
- comment_text = commenter.call code[first_index...last_index], line_number
22
+ first_index -= 1 while first_index > 0 && raw_code[first_index-1] != "\n"
23
+ comment_text = commenter.call raw_code[first_index...last_index], line_number
26
24
  range = Parser::Source::Range.new(commentable_lines.buffer, first_index, last_index)
27
25
  commentable_lines.rewriter.insert_after range, comment_text
28
26
  end
@@ -32,7 +30,7 @@ class SeeingIsBelieving
32
30
 
33
31
  private
34
32
 
35
- attr_accessor :code, :commenter
33
+ attr_accessor :raw_code, :commenter
36
34
  end
37
35
  end
38
36
  end
@@ -1,24 +1,16 @@
1
- require 'seeing_is_believing/parser_helpers'
1
+ require 'seeing_is_believing/code'
2
2
 
3
3
  class SeeingIsBelieving
4
4
  module Binary
5
5
 
6
- # could possibly be sped up by just reflecting on the tokens instead of the whole ast
7
- #
8
- # specs for this class are in spec/binary/comment_lines_spec.rb
9
- # because it was extracted from that class
10
6
  class CommentableLines
11
-
12
- include ParserHelpers
13
-
14
7
  def self.call(code)
15
8
  new(code).call
16
9
  end
17
10
 
18
11
  def initialize(code)
19
12
  self.code = code
20
- self.buffer, self.parser, self.rewriter = initialize_parser(code, 'finding_commentable_lines')
21
- self.root, self.comments = parser.parse_with_comments(buffer)
13
+ self.code_obj = Code.new(code, 'finding_commentable_lines')
22
14
  end
23
15
 
24
16
  def call
@@ -26,18 +18,28 @@ class SeeingIsBelieving
26
18
  line_num_to_location = line_nums_to_last_index_and_col(buffer)
27
19
  remove_lines_after_data_segment line_num_to_location
28
20
  remove_lines_whose_newline_is_escaped line_num_to_location
29
- remove_lines_ending_in_comments line_num_to_location, comments
21
+ remove_lines_ending_in_comments line_num_to_location, code_obj.raw_comments
30
22
  remove_lines_inside_of_strings_and_things line_num_to_location, root
31
23
  line_num_to_location
32
24
  end
33
25
  end
34
26
 
35
- attr_reader :buffer, :rewriter
27
+ def buffer
28
+ code_obj.buffer
29
+ end
30
+
31
+ def rewriter
32
+ code_obj.rewriter
33
+ end
36
34
 
37
35
  private
38
36
 
39
37
  attr_writer :buffer, :rewriter
40
- attr_accessor :code, :parser, :root, :comments
38
+ attr_accessor :code, :code_obj
39
+
40
+ def root
41
+ code_obj.root
42
+ end
41
43
 
42
44
  def line_nums_to_last_index_and_col(buffer)
43
45
  line_num_to_location = code.each_char
@@ -83,7 +85,7 @@ class SeeingIsBelieving
83
85
 
84
86
  def ranges_of_atomic_expressions(ast, found_ranges)
85
87
  return found_ranges unless ast.kind_of? ::AST::Node
86
- if no_comment_zone?(ast) && heredoc?(ast)
88
+ if no_comment_zone?(ast) && code_obj.heredoc?(ast)
87
89
  begin_pos = ast.location.heredoc_body.begin_pos
88
90
  end_pos = ast.location.heredoc_end.end_pos.next
89
91
  found_ranges << (begin_pos...end_pos)
@@ -110,18 +112,10 @@ class SeeingIsBelieving
110
112
  end
111
113
 
112
114
  def remove_lines_after_data_segment(line_num_to_location)
113
- data_segment_line, _ = line_num_to_location.find do |line_number, (end_index, col)|
114
- if end_index == 7
115
- code.start_with? '__END__'
116
- elsif end_index < 7
117
- false
118
- else
119
- code[(end_index-8)...end_index] == "\n__END__"
120
- end
121
- end
122
- return unless data_segment_line
123
- max_line = line_num_to_location.keys.max
124
- data_segment_line.upto(max_line) { |line_number| line_num_to_location.delete line_number }
115
+ end_index = code_obj.body_range.end_pos
116
+ body_end = code_obj.index_to_linenum end_index
117
+ file_end = line_num_to_location.keys.max
118
+ body_end.upto(file_end) { |line_number| line_num_to_location.delete line_number }
125
119
  end
126
120
  end
127
121
  end
@@ -0,0 +1,392 @@
1
+ # encoding: utf-8
2
+ require 'seeing_is_believing'
3
+ require 'seeing_is_believing/binary/data_structures'
4
+
5
+ # one of these will be the alignment strategy
6
+ require 'seeing_is_believing/binary/align_file'
7
+ require 'seeing_is_believing/binary/align_line'
8
+ require 'seeing_is_believing/binary/align_chunk'
9
+
10
+ # one of these will annotate the bdoy
11
+ require 'seeing_is_believing/binary/annotate_every_line'
12
+ require 'seeing_is_believing/binary/annotate_marked_lines'
13
+
14
+
15
+ class SeeingIsBelieving
16
+ module Binary
17
+ class Config < HashStruct
18
+ DeprecatedArgMessage = Binary::ErrorMessage.for :args do
19
+ def to_s
20
+ "Deprecated: `#{args.join ' '}` #{explanation}"
21
+ end
22
+ end
23
+
24
+ predicate(:print_version) { false }
25
+ predicate(:print_cleaned) { false }
26
+ predicate(:print_help) { false }
27
+ predicate(:print_event_stream) { false }
28
+ predicate(:result_as_json) { false }
29
+ predicate(:inherit_exitstatus) { false }
30
+ predicate(:remove_value_prefixes) { true }
31
+ predicate(:debug) { false }
32
+ attribute(:body) { nil }
33
+ attribute(:filename) { nil }
34
+ attribute(:errors) { [] }
35
+ attribute(:deprecations) { [] }
36
+ attribute(:timeout_seconds) { 0 }
37
+ attribute(:annotator) { AnnotateEveryLine }
38
+ attribute(:debugger) { Debugger::Null }
39
+ attribute(:markers) { Markers.new }
40
+ attribute(:help_screen) { |c| Binary.help_screen c.markers }
41
+ attribute(:lib_options) { SeeingIsBelieving::Options.new }
42
+ attribute(:annotator_options) { AnnotatorOptions.new }
43
+
44
+ def add_error(explanation)
45
+ errors << ErrorMessage.new(explanation: explanation)
46
+ end
47
+
48
+ def parse_args(args)
49
+ as = nil
50
+ filenames = []
51
+ args = args.dup
52
+
53
+ extract_positive_int_for = lambda do |flagname, &on_success|
54
+ string = args.shift
55
+ int = string.to_i
56
+ if int.to_s == string && 0 < int
57
+ on_success.call int
58
+ else
59
+ add_error "#{flagname} expects a positive integer argument"
60
+ end
61
+ string
62
+ end
63
+
64
+ extract_non_negative_float_for = lambda do |flagname, &on_success|
65
+ begin
66
+ string = args.shift
67
+ float = Float string
68
+ raise if float < 0
69
+ on_success.call float
70
+ string
71
+ rescue
72
+ add_error "#{flagname} expects a positive float or integer argument"
73
+ end
74
+ end
75
+
76
+ saw_deprecated = lambda do |explanation, *args|
77
+ self.deprecations << DeprecatedArgMessage.new(explanation: explanation, args: args)
78
+ end
79
+
80
+ next_arg = lambda do |flagname, argtype, &on_success|
81
+ arg = args.shift
82
+ arg ? on_success.call(arg) :
83
+ add_error("#{flagname} needs an argument (#{argtype})")
84
+ arg
85
+ end
86
+
87
+ until args.empty?
88
+ case (arg = args.shift)
89
+ when '-c', '--clean'
90
+ self.print_cleaned = true
91
+
92
+ when '-v', '--version'
93
+ self.print_version = true
94
+
95
+ when '-x', '--xmpfilter-style'
96
+ self.annotator = AnnotateMarkedLines
97
+ self.lib_options.rewrite_code = AnnotateMarkedLines.code_rewriter(markers)
98
+ self.remove_value_prefixes = false
99
+ self.lib_options.require_files << 'pp'
100
+
101
+ when '-i', '--inherit-exitstatus', '--inherit-exit-status'
102
+ self.inherit_exitstatus = true
103
+ arg.include?("exit-status") &&
104
+ saw_deprecated.call("Dash has been removed for consistency, use --inherit-exitstatus", arg)
105
+
106
+ when '-j', '--json'
107
+ self.result_as_json = true
108
+
109
+ when '--stream'
110
+ self.print_event_stream = true
111
+
112
+ when '-h', '--help'
113
+ self.print_help = true
114
+ self.help_screen = Binary.help_screen(markers)
115
+
116
+ when '-h+', '--help+'
117
+ self.print_help = true
118
+ self.help_screen = Binary.help_screen_extended(markers)
119
+
120
+ when '-g', '--debug'
121
+ self.debug = true
122
+
123
+ when '-d', '--line-length'
124
+ extract_positive_int_for.call arg do |n|
125
+ self.annotator_options.max_line_length = n
126
+ end
127
+
128
+ when '-D', '--result-length'
129
+ extract_positive_int_for.call arg do |n|
130
+ self.annotator_options.max_result_length = n
131
+ end
132
+
133
+ when '-n', '--max-line-captures', '--number-of-captures'
134
+ extracted = extract_positive_int_for.call arg do |n|
135
+ self.lib_options.max_line_captures = n
136
+ end
137
+ seen = [arg]
138
+ seen << extracted if extracted
139
+ '--number-of-captures' == arg && saw_deprecated.call("use --max-line-captures instead", *seen)
140
+
141
+ when '-t', '--timeout-seconds', '--timeout'
142
+ extracted = extract_non_negative_float_for.call arg do |n|
143
+ self.timeout_seconds = n
144
+ self.lib_options.timeout_seconds = n
145
+ end
146
+ '--timeout' == arg && saw_deprecated.call("use --timeout-seconds instead", arg, extracted)
147
+
148
+ when '-r', '--require'
149
+ next_arg.call arg, "a filename" do |filename|
150
+ self.lib_options.require_files << filename
151
+ end
152
+
153
+ when '-I', '--load-path'
154
+ next_arg.call arg, "a directory" do |dir|
155
+ self.lib_options.load_path_dirs << dir
156
+ end
157
+
158
+ when '-e', '--program'
159
+ next_arg.call arg, "the program body" do |program|
160
+ self.body = program
161
+ end
162
+
163
+ when '-a', '--as'
164
+ next_arg.call arg, "a filename" do |filename|
165
+ as = filename
166
+ end
167
+
168
+ when '-s', '--alignment-strategy'
169
+ strategies = {'file' => AlignFile, 'chunk' => AlignChunk, 'line' => AlignLine}
170
+ strategy_names = strategies.keys.inspect
171
+ next_arg.call arg, "one of these alignment strategies: #{strategy_names}" do |name|
172
+ if strategies[name]
173
+ self.annotator_options.alignment_strategy = strategies[name]
174
+ else
175
+ add_error("#{arg} got the alignment strategy #{name.inspect}, expected one of: #{strategy_names}")
176
+ end
177
+ end
178
+
179
+ when '--shebang'
180
+ executable = args.shift
181
+ if executable
182
+ saw_deprecated.call "SiB now uses the Ruby it was invoked with", arg, executable
183
+ else
184
+ add_error("#{arg} expected an arg: path to a ruby executable")
185
+ saw_deprecated.call "SiB now uses the Ruby it was invoked with", arg
186
+ end
187
+
188
+ when /\A-K(.+)/
189
+ self.lib_options.encoding = $1
190
+
191
+ when '-K', '--encoding'
192
+ next_arg.call arg, "an encoding" do |encoding|
193
+ self.lib_options.encoding = encoding
194
+ end
195
+
196
+ when /^(-.|--.*)$/
197
+ add_error("#{arg} is not an option, see the help screen (-h) for a list of options")
198
+
199
+ when /^-[^-]/
200
+ args.unshift *arg.scan(/[^-]\+?/).map { |flag| "-#{flag}" }
201
+
202
+ else
203
+ filenames << arg
204
+ end
205
+ end
206
+
207
+ filenames.size > 1 &&
208
+ add_error("can only have one filename but found #{filenames.map(&:inspect).join ', '}")
209
+
210
+ result_as_json? && annotator == AnnotateMarkedLines &&
211
+ add_error("SiB does not currently support output with both json and xmpfilter... maybe v4 :)")
212
+
213
+ print_event_stream? && (result_as_json? || annotator == AnnotateMarkedLines) &&
214
+ add_error("can only have one output format, --stream is not compatible with --json, -x, and --xmpfilter-style")
215
+
216
+ self.filename = filenames.first
217
+ self.lib_options.filename = as || filename
218
+ self.lib_options.debugger = debugger
219
+ self.annotator_options.markers = markers
220
+
221
+ self
222
+ end
223
+
224
+ def finalize(stdin, stdout, stderr, file_class)
225
+ if print_event_stream?
226
+ require 'seeing_is_believing/event_stream/handlers/stream_json_events'
227
+ lib_options.event_handler = EventStream::Handlers::StreamJsonEvents.new(stdout)
228
+ end
229
+
230
+ if debug?
231
+ self.debugger = Debugger.new stream: stderr, colour: true
232
+ self.lib_options.debugger = debugger
233
+ end
234
+
235
+ if filename && body
236
+ add_error("Cannot give a program body and a filename to get the program body from.")
237
+ elsif filename && file_class.exist?(filename)
238
+ self.lib_options.stdin = stdin
239
+ self.body = file_class.read filename
240
+ elsif filename
241
+ add_error("#{filename} does not exist!")
242
+ elsif body
243
+ self.lib_options.stdin = stdin
244
+ elsif print_version? || print_help? || errors.any?
245
+ self.body = ""
246
+ else
247
+ self.body = stdin.read
248
+ end
249
+
250
+ self
251
+ end
252
+
253
+ end
254
+ end
255
+
256
+ def Binary.help_screen(markers)
257
+ value = markers[:value][:prefix]
258
+ stdout = markers[:stdout][:prefix]
259
+
260
+ <<FLAGS
261
+ Usage: seeing_is_believing [options] [filename]
262
+
263
+ seeing_is_believing is a program and library that will evaluate a Ruby file and capture/display the results.
264
+
265
+ Notes:
266
+
267
+ * If no filename or program (-e flag) are provided, the program will read from standard input.
268
+ * The process's stdin will be passed to the program unless the program body is on stdin.
269
+ * The exit status will be:
270
+ 0 - No errors
271
+ 1 - Displayable error (e.g. code raises an exception while running)
272
+ 2 - Non-displayable error (e.g. a syntax error, a timeout)
273
+ n - The program's exit status if the --inherit-exitstatus flag is set
274
+
275
+ Options:
276
+ -d, --line-length n # max length of the entire line (only truncates results, not source lines)
277
+ -D, --result-length n # max length of the portion after the "#{value}"
278
+ -n, --max-line-captures n # how many results to capture for a given line
279
+ if you had 1 million results on a line, it could take a long time to record
280
+ and serialize them, you might limit it to 1000 results as an optimization
281
+ -s, --alignment-strategy name # select the alignment strategy:
282
+ chunk (DEFAULT) => each chunk of code is at the same alignment
283
+ file => the entire file is at the same alignment
284
+ line => each line is at its own alignment
285
+ -t, --timeout-seconds s # how long to evaluate the source file before timing out
286
+ 0 means it will never timeout (this is the default)
287
+ accepts floating point values (e.g. 0.5 would timeout after half a second)
288
+ -I, --load-path dir # a dir that should be added to the $LOAD_PATH
289
+ -r, --require file # additional files to be required before running the program
290
+ -e, --program program-body # pass the program body to execute as an argument
291
+ -K, --encoding encoding # sets file encoding, equivalent to Ruby's -Kx (see `man ruby` for valid values)
292
+ -a, --as filename # run the program as if it was the specified filename
293
+ -c, --clean # remove annotations from previous runs of seeing_is_believing
294
+ -g, --debug # print debugging information
295
+ -x, --xmpfilter-style # annotate marked lines instead of every line
296
+ -j, --json # print results in json format (i.e. so another program can consume them)
297
+ -i, --inherit-exitstatus # exit with the exit status of the program being evaluated
298
+ --stream # a JSON stream of every event ias it is seen (such as recording a line)
299
+ -v, --version # print the version (#{VERSION})
300
+ -h, --help # help screen without examples
301
+ -h+, --help+ # help screen with examples
302
+ FLAGS
303
+ end
304
+
305
+ def Binary.help_screen_extended(markers)
306
+ value = markers[:value][:prefix]
307
+ stdout = markers[:stdout][:prefix]
308
+ help_screen(markers) << <<EXAMPLES
309
+ Examples: A few examples, for a more comprehensive set of examples, check out features/flags.feature
310
+ NOTE: $'1\\n2' is the bash string literal for Ruby's "1\\n2"
311
+
312
+ Run the file myfile.rb
313
+ $ echo __FILE__ > myfile.rb; seeing_is_believing myfile.rb
314
+ __FILE__ #{value}"myfile.rb"
315
+
316
+ Run against standard input
317
+ $ echo ':program' | seeing_is_believing
318
+ :program #{value}:program
319
+
320
+ Pass the program in an argument
321
+ $ seeing_is_believing -e ':program'
322
+ :program #{value}:program
323
+
324
+ Remove previous output
325
+ $ seeing_is_believing -e ":program" | seeing_is_believing --clean
326
+ :program
327
+
328
+ Aligning comments
329
+ $ seeing_is_believing -s line -e $'123\\n4\\n\\n567890'
330
+ 123 #{value}123
331
+ 4 #{value}4
332
+
333
+ 567890 #{value}567890
334
+
335
+
336
+ $ seeing_is_believing -s chunk -e $'123\\n4\\n\\n567890'
337
+ 123 #{value}123
338
+ 4 #{value}4
339
+
340
+ 567890 #{value}567890
341
+
342
+
343
+ $ seeing_is_believing -s file -e $'123\\n4\\n\\n567890'
344
+ 123 #{value}123
345
+ 4 #{value}4
346
+
347
+ 567890 #{value}567890
348
+
349
+ Run against a library you're working on by fixing the load path
350
+ $ seeing_is_believing -I ./lib f.rb
351
+
352
+ Require a file before yours is run (can be used in tandem with -I)
353
+ $ seeing_is_believing -r pp -e 'pp [[*1..5]]*5'
354
+ pp [[*1..5]]*5 #{value}[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]
355
+
356
+ #{stdout}[[1, 2, 3, 4, 5],
357
+ #{stdout} [1, 2, 3, 4, 5],
358
+ #{stdout} [1, 2, 3, 4, 5],
359
+ #{stdout} [1, 2, 3, 4, 5],
360
+ #{stdout} [1, 2, 3, 4, 5]]
361
+
362
+ Only update the lines you've marked
363
+ $ seeing_is_believing -x -e $'1\\n2 # =>\\n3' |
364
+ 1
365
+ 2 #{value}2
366
+ 3
367
+
368
+ Display a complex structure across multiple lines
369
+ $ seeing_is_believing -x -e $'{foo: 42, bar: {baz: 1, buz: 2, fuz: 3}, wibble: {magic_word: "xyzzy"}}\\n#{value}'
370
+ {foo: 42, bar: {baz: 1, buz: 2, fuz: 3}, wibble: {magic_word: "xyzzy"}}
371
+ #{value} {:foo=>42,
372
+ # :bar=>{:baz=>1, :buz=>2, :fuz=>3},
373
+ # :wibble=>{:magic_word=>"xyzzy"}}
374
+
375
+ Display a stream of events as they are seen
376
+ $ seeing_is_believing -e $':a\\n:b\\n:c' --stream
377
+ ["ruby_version",{"value":#{RUBY_VERSION.inspect}}]
378
+ ["sib_version",{"value":#{SeeingIsBelieving::VERSION.inspect}}]
379
+ ["filename",{"value":"/var/folders/7g/mbft22555w3_2nqs_h1kbglw0000gn/T/seeing_is_believing_temp_dir20150116-49548-kr0xop/program.rb"}]
380
+ ["max_line_captures",{"value":-1,"is_infinity":true}]
381
+ ["num_lines",{"value":3}]
382
+ ["line_result",{"type":"inspect","line_number":1,"inspected":":a"}]
383
+ ["line_result",{"type":"inspect","line_number":2,"inspected":":b"}]
384
+ ["line_result",{"type":"inspect","line_number":3,"inspected":":c"}]
385
+ ["event_stream_closed",{"side":"producer"}]
386
+ ["stderr_closed",{"side":"producer"}]
387
+ ["stdout_closed",{"side":"producer"}]
388
+ ["exitstatus",{"value":0}]
389
+ ["finished",{}]
390
+ EXAMPLES
391
+ end
392
+ end