seeing_is_believing 3.0.1 → 3.1.0
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/Gemfile +0 -1
- data/features/flags.feature +39 -0
- data/features/regression.feature +154 -0
- data/features/xmpfilter-style.feature +57 -0
- data/lib/seeing_is_believing/binary/annotate_every_line.rb +11 -4
- data/lib/seeing_is_believing/binary/annotate_marked_lines.rb +11 -5
- data/lib/seeing_is_believing/binary/config.rb +9 -0
- data/lib/seeing_is_believing/binary/data_structures.rb +1 -0
- data/lib/seeing_is_believing/binary/interline_align.rb +57 -0
- data/lib/seeing_is_believing/customize_pp.rb +5 -0
- data/lib/seeing_is_believing/event_stream/consumer.rb +39 -43
- data/lib/seeing_is_believing/event_stream/producer.rb +24 -31
- data/lib/seeing_is_believing/safe.rb +93 -39
- data/lib/seeing_is_believing/the_matrix.rb +10 -10
- data/lib/seeing_is_believing/version.rb +1 -1
- data/lib/seeing_is_believing/wrap_expressions.rb +24 -5
- data/spec/binary/config_spec.rb +17 -2
- data/spec/event_stream_spec.rb +1 -0
- data/spec/seeing_is_believing_spec.rb +58 -53
- data/spec/spec_helper.rb +22 -0
- data/spec/spec_helper_spec.rb +16 -0
- data/spec/wrap_expressions_spec.rb +35 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9dd0b2eff60a43943a68255a2278300ad4d687d
|
4
|
+
data.tar.gz: c85b26392092e308c2a2dc0fdbaf41371da88a8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21a4e75fa8f2191b74c4305e879f5e53ad67680c3091089a83d0af64cfecc687ef86e1ebd76341717710d18e9c2d57479f0b11017f28cd8cf42da60d4092ecff
|
7
|
+
data.tar.gz: 2afc31b2a89c7f6d0a4ee544b8eb8acdcfceef34c4ae6fce57a0c46f30d2501117fa45628f2100849332715f80bd85d3927bbc4cfab81d34093ad9d67ee98eaf
|
data/Gemfile
CHANGED
data/features/flags.feature
CHANGED
@@ -528,3 +528,42 @@ Feature: Using flags
|
|
528
528
|
Then the exit status is 0
|
529
529
|
And stderr is empty
|
530
530
|
And stdout is "1 # => 1"
|
531
|
+
|
532
|
+
Scenario: --interline-align and --no-interline-align determine whether adjacent lines with the same number of results get lined up, it defaults to --align
|
533
|
+
Given the file "interline_alignment.rb":
|
534
|
+
"""
|
535
|
+
3.times do |num|
|
536
|
+
num
|
537
|
+
.to_s
|
538
|
+
end
|
539
|
+
"""
|
540
|
+
When I run "seeing_is_believing interline_alignment.rb"
|
541
|
+
Then stderr is empty
|
542
|
+
And the exit status is 0
|
543
|
+
And stdout is:
|
544
|
+
"""
|
545
|
+
3.times do |num| # => 3
|
546
|
+
num # => 0, 1, 2
|
547
|
+
.to_s # => "0", "1", "2"
|
548
|
+
end # => 3
|
549
|
+
"""
|
550
|
+
When I run "seeing_is_believing --interline-align interline_alignment.rb"
|
551
|
+
Then stderr is empty
|
552
|
+
And the exit status is 0
|
553
|
+
And stdout is:
|
554
|
+
"""
|
555
|
+
3.times do |num| # => 3
|
556
|
+
num # => 0, 1, 2
|
557
|
+
.to_s # => "0", "1", "2"
|
558
|
+
end # => 3
|
559
|
+
"""
|
560
|
+
When I run "seeing_is_believing --no-interline-align interline_alignment.rb"
|
561
|
+
Then stderr is empty
|
562
|
+
And the exit status is 0
|
563
|
+
And stdout is:
|
564
|
+
"""
|
565
|
+
3.times do |num| # => 3
|
566
|
+
num # => 0, 1, 2
|
567
|
+
.to_s # => "0", "1", "2"
|
568
|
+
end # => 3
|
569
|
+
"""
|
data/features/regression.feature
CHANGED
@@ -503,3 +503,157 @@ Feature:
|
|
503
503
|
__END__
|
504
504
|
"""
|
505
505
|
|
506
|
+
@not-implemented
|
507
|
+
Scenario: Interpolating in a heredoc and walking backwards with xmpfilter style to figure out which expression to record (#83)
|
508
|
+
Given the file "heredoc_woes.rb":
|
509
|
+
"""
|
510
|
+
<<-HERE # =>
|
511
|
+
1#{1+1}3
|
512
|
+
HERE
|
513
|
+
# =>
|
514
|
+
"""
|
515
|
+
When I run "seeing_is_believing -x heredoc_woes.rb"
|
516
|
+
Then stdout is:
|
517
|
+
"""
|
518
|
+
<<-HERE # => "123\n"
|
519
|
+
1#{1+1}3
|
520
|
+
HERE
|
521
|
+
# => "123\n"
|
522
|
+
"""
|
523
|
+
|
524
|
+
Scenario: Executing correctly in a hostile world
|
525
|
+
Given the file "hostile_world.rb":
|
526
|
+
"""
|
527
|
+
# SiB works, but Ruby will explode while trying to make the exception
|
528
|
+
# if we do it later, so we'll make it up here
|
529
|
+
zde = (1/0 rescue $!)
|
530
|
+
|
531
|
+
if RUBY_VERSION != "2.0.0" # this breaks Ruby itself on v2.0.0
|
532
|
+
class Hash
|
533
|
+
undef []
|
534
|
+
undef []=
|
535
|
+
undef fetch
|
536
|
+
end
|
537
|
+
end
|
538
|
+
class IO
|
539
|
+
undef sync
|
540
|
+
undef <<
|
541
|
+
undef flush
|
542
|
+
undef puts
|
543
|
+
undef close
|
544
|
+
end
|
545
|
+
class Queue
|
546
|
+
undef <<
|
547
|
+
undef shift
|
548
|
+
undef clear
|
549
|
+
end
|
550
|
+
class Symbol
|
551
|
+
undef ==
|
552
|
+
undef to_s
|
553
|
+
undef inspect
|
554
|
+
end
|
555
|
+
class String
|
556
|
+
undef ==
|
557
|
+
undef to_s
|
558
|
+
undef to_str
|
559
|
+
undef inspect
|
560
|
+
undef to_i
|
561
|
+
end
|
562
|
+
class Fixnum
|
563
|
+
undef <
|
564
|
+
undef <<
|
565
|
+
undef ==
|
566
|
+
def next # "redefining instead of undefing b/c it comes from Integer"
|
567
|
+
end
|
568
|
+
undef to_s
|
569
|
+
undef inspect
|
570
|
+
end
|
571
|
+
class Array
|
572
|
+
undef pack
|
573
|
+
undef <<
|
574
|
+
undef to_ary
|
575
|
+
undef grep
|
576
|
+
undef first
|
577
|
+
undef []
|
578
|
+
undef []=
|
579
|
+
undef each
|
580
|
+
undef map
|
581
|
+
undef join
|
582
|
+
undef size
|
583
|
+
undef to_s
|
584
|
+
end
|
585
|
+
class << Marshal
|
586
|
+
undef dump
|
587
|
+
undef load
|
588
|
+
end
|
589
|
+
module Kernel
|
590
|
+
undef kind_of?
|
591
|
+
undef block_given?
|
592
|
+
end
|
593
|
+
module Enumerable
|
594
|
+
undef map
|
595
|
+
end
|
596
|
+
class SystemExit
|
597
|
+
undef status
|
598
|
+
end
|
599
|
+
class Exception
|
600
|
+
undef message
|
601
|
+
# undef backtrace # https://bugs.ruby-lang.org/issues/12925
|
602
|
+
def class
|
603
|
+
"totally the wrong thing"
|
604
|
+
end
|
605
|
+
end
|
606
|
+
class << Thread
|
607
|
+
undef new
|
608
|
+
undef current
|
609
|
+
end
|
610
|
+
class Thread
|
611
|
+
undef join
|
612
|
+
undef abort_on_exception
|
613
|
+
end
|
614
|
+
class Class
|
615
|
+
undef new
|
616
|
+
undef allocate
|
617
|
+
undef singleton_class
|
618
|
+
undef class_eval
|
619
|
+
end
|
620
|
+
class BasicObject
|
621
|
+
undef initialize
|
622
|
+
end
|
623
|
+
class Module
|
624
|
+
undef ===
|
625
|
+
undef define_method
|
626
|
+
undef instance_method
|
627
|
+
end
|
628
|
+
class UnboundMethod
|
629
|
+
undef bind
|
630
|
+
end
|
631
|
+
class Method
|
632
|
+
undef call
|
633
|
+
end
|
634
|
+
class Proc
|
635
|
+
undef call
|
636
|
+
undef to_proc
|
637
|
+
end
|
638
|
+
class NilClass
|
639
|
+
undef to_s
|
640
|
+
end
|
641
|
+
|
642
|
+
# ---
|
643
|
+
|
644
|
+
class Zomg
|
645
|
+
end
|
646
|
+
|
647
|
+
Zomg # =>
|
648
|
+
class << Zomg
|
649
|
+
attr_accessor :inspect
|
650
|
+
end
|
651
|
+
Zomg.inspect = "lolol"
|
652
|
+
Zomg # =>
|
653
|
+
raise zde
|
654
|
+
"""
|
655
|
+
When I run "seeing_is_believing -x hostile_world.rb"
|
656
|
+
Then stdout includes 'Zomg # => Zomg'
|
657
|
+
And stdout includes 'Zomg # => lolol'
|
658
|
+
And stdout includes '# ~> ZeroDivisionError'
|
659
|
+
And stdout includes '# ~> divided by 0'
|
@@ -72,6 +72,24 @@ Feature: Xmpfilter style
|
|
72
72
|
# :wibble=>{:magic_word=>"xyzzy"}}
|
73
73
|
"""
|
74
74
|
|
75
|
+
Scenario: --xmpfilter-style, when displayed on the next line, prints the string across multiple lines
|
76
|
+
Given the file "xmpfilter-prev-line-is-multiline-string.rb":
|
77
|
+
"""
|
78
|
+
"0123456789\nabcdefghij\n0123456789\n0123456789\n0123456789\n0123456789\n" # =>
|
79
|
+
# =>
|
80
|
+
"""
|
81
|
+
When I run "seeing_is_believing --xmpfilter-style xmpfilter-prev-line-is-multiline-string.rb"
|
82
|
+
Then stdout is:
|
83
|
+
"""
|
84
|
+
"0123456789\nabcdefghij\n0123456789\n0123456789\n0123456789\n0123456789\n" # => "0123456789\nabcdefghij\n0123456789\n0123456789\n0123456789\n0123456789\n"
|
85
|
+
# => "0123456789\n" +
|
86
|
+
# "abcdefghij\n" +
|
87
|
+
# "0123456789\n" +
|
88
|
+
# "0123456789\n" +
|
89
|
+
# "0123456789\n" +
|
90
|
+
# "0123456789\n"
|
91
|
+
"""
|
92
|
+
|
75
93
|
Scenario: --xmpfilter-style overrides previous multiline results
|
76
94
|
Given the file "xmpfilter-prev-line2.rb":
|
77
95
|
"""
|
@@ -410,3 +428,42 @@ Feature: Xmpfilter style
|
|
410
428
|
# ~>
|
411
429
|
# ~> xm...
|
412
430
|
"""
|
431
|
+
|
432
|
+
Scenario: --interline-align and --no-interline-align determine whether adjacent lines with the same number of results get lined up, it defaults to --align
|
433
|
+
Given the file "xmpfilter_interline_alignment.rb":
|
434
|
+
"""
|
435
|
+
3.times do |num|
|
436
|
+
num # =>
|
437
|
+
.to_s # =>
|
438
|
+
end
|
439
|
+
"""
|
440
|
+
When I run "seeing_is_believing -x xmpfilter_interline_alignment.rb"
|
441
|
+
Then stderr is empty
|
442
|
+
And the exit status is 0
|
443
|
+
And stdout is:
|
444
|
+
"""
|
445
|
+
3.times do |num|
|
446
|
+
num # => 0, 1, 2
|
447
|
+
.to_s # => "0", "1", "2"
|
448
|
+
end
|
449
|
+
"""
|
450
|
+
When I run "seeing_is_believing -x --interline-align xmpfilter_interline_alignment.rb"
|
451
|
+
Then stderr is empty
|
452
|
+
And the exit status is 0
|
453
|
+
And stdout is:
|
454
|
+
"""
|
455
|
+
3.times do |num|
|
456
|
+
num # => 0, 1, 2
|
457
|
+
.to_s # => "0", "1", "2"
|
458
|
+
end
|
459
|
+
"""
|
460
|
+
When I run "seeing_is_believing -x --no-interline-align xmpfilter_interline_alignment.rb"
|
461
|
+
Then stderr is empty
|
462
|
+
And the exit status is 0
|
463
|
+
And stdout is:
|
464
|
+
"""
|
465
|
+
3.times do |num|
|
466
|
+
num # => 0, 1, 2
|
467
|
+
.to_s # => "0", "1", "2"
|
468
|
+
end
|
469
|
+
"""
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'seeing_is_believing/binary/interline_align'
|
2
|
+
|
1
3
|
class SeeingIsBelieving
|
2
4
|
module Binary
|
3
5
|
class AnnotateEveryLine
|
@@ -6,9 +8,10 @@ class SeeingIsBelieving
|
|
6
8
|
end
|
7
9
|
|
8
10
|
def initialize(body, results, options={})
|
9
|
-
@options
|
10
|
-
@body
|
11
|
-
@results
|
11
|
+
@options = options
|
12
|
+
@body = body
|
13
|
+
@results = results
|
14
|
+
@interline_align = InterlineAlign.new(results)
|
12
15
|
end
|
13
16
|
|
14
17
|
def call
|
@@ -26,7 +29,11 @@ class SeeingIsBelieving
|
|
26
29
|
result = sprintf "%s: %s", @results.exception.class_name, @results.exception.message.gsub("\n", '\n')
|
27
30
|
FormatComment.call(line.size, exception_text, result, options)
|
28
31
|
elsif @results[line_number].any?
|
29
|
-
|
32
|
+
if @options[:interline_align]
|
33
|
+
result = @interline_align.call line_number, @results[line_number].map { |result| result.gsub "\n", '\n' }
|
34
|
+
else
|
35
|
+
result = @results[line_number].map { |result| result.gsub "\n", '\n' }.join(', ')
|
36
|
+
end
|
30
37
|
FormatComment.call(line.size, value_text, result, options)
|
31
38
|
else
|
32
39
|
''
|
@@ -82,9 +82,10 @@ class SeeingIsBelieving
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def initialize(body, results, options={})
|
85
|
-
@options
|
86
|
-
@body
|
87
|
-
@results
|
85
|
+
@options = options
|
86
|
+
@body = body
|
87
|
+
@results = results
|
88
|
+
@interline_align = InterlineAlign.new(results)
|
88
89
|
end
|
89
90
|
|
90
91
|
# seems like maybe this should respect the alignment strategy (not what xmpfilter does, but there are other ways I'd like to deviate anyway)
|
@@ -114,8 +115,13 @@ class SeeingIsBelieving
|
|
114
115
|
whitespace = " " if whitespace.empty?
|
115
116
|
[whitespace, FormatComment.call(0, exception_prefix, exception_result, @options)]
|
116
117
|
elsif normal_annotation
|
117
|
-
|
118
|
-
|
118
|
+
if @options[:interline_align]
|
119
|
+
annotation = @interline_align.call comment.line_number, @results[comment.line_number].map { |result| result.gsub "\n", '\n' }
|
120
|
+
[comment.whitespace, FormatComment.call(comment.text_col, value_prefix, annotation, @options)]
|
121
|
+
else
|
122
|
+
annotation = @results[comment.line_number].map { |result| result.gsub "\n", '\n' }.join(', ')
|
123
|
+
[comment.whitespace, FormatComment.call(comment.text_col, value_prefix, annotation, @options)]
|
124
|
+
end
|
119
125
|
elsif pp_annotation
|
120
126
|
result = @results[pp_map[comment.line_number], :pp]
|
121
127
|
annotation = result.map { |result| result.chomp }.join("\n,") # ["1\n2", "1\n2", ...
|
@@ -102,6 +102,7 @@ class SeeingIsBelieving
|
|
102
102
|
self.lib_options.rewrite_code = AnnotateMarkedLines.code_rewriter(markers)
|
103
103
|
self.remove_value_prefixes = false
|
104
104
|
self.lib_options.require_files << 'pp'
|
105
|
+
self.lib_options.require_files << 'seeing_is_believing/customize_pp'
|
105
106
|
|
106
107
|
when '-i', '--inherit-exitstatus', '--inherit-exit-status'
|
107
108
|
self.inherit_exitstatus = true
|
@@ -186,6 +187,12 @@ class SeeingIsBelieving
|
|
186
187
|
end
|
187
188
|
end
|
188
189
|
|
190
|
+
when '--interline-align'
|
191
|
+
self.annotator_options.interline_align = true
|
192
|
+
|
193
|
+
when '--no-interline-align'
|
194
|
+
self.annotator_options.interline_align = false
|
195
|
+
|
189
196
|
when '--shebang'
|
190
197
|
executable = args.shift
|
191
198
|
if executable
|
@@ -301,6 +308,8 @@ Options:
|
|
301
308
|
chunk (DEFAULT) => each chunk of code is at the same alignment
|
302
309
|
file => the entire file is at the same alignment
|
303
310
|
line => each line is at its own alignment
|
311
|
+
--[no-]-interline-align # align results on adjacent lines when they have the same number of results
|
312
|
+
defautls to --align
|
304
313
|
-t, --timeout-seconds s # how long to evaluate the source file before timing out
|
305
314
|
0 means it will never timeout (this is the default)
|
306
315
|
accepts floating point values (e.g. 0.5 would timeout after half a second)
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class SeeingIsBelieving
|
2
|
+
module Binary
|
3
|
+
class InterlineAlign
|
4
|
+
def initialize(results)
|
5
|
+
@results = results
|
6
|
+
@format_strings = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(lineno, results)
|
10
|
+
format_string_for_line(lineno) % results
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
attr_accessor :results
|
16
|
+
|
17
|
+
def format_string_for_line(lineno)
|
18
|
+
group = groups_with_same_number_of_results(@results)[lineno]
|
19
|
+
format_string_for(results, group, lineno)
|
20
|
+
end
|
21
|
+
|
22
|
+
def groups_with_same_number_of_results(results)
|
23
|
+
@grouped_by_no_results ||= begin
|
24
|
+
length = 0
|
25
|
+
groups = 1.upto(results.num_lines)
|
26
|
+
.slice_before { |num|
|
27
|
+
new_length = results[num].length
|
28
|
+
slice = length != new_length
|
29
|
+
length = new_length
|
30
|
+
slice
|
31
|
+
}.to_a
|
32
|
+
|
33
|
+
groups.each_with_object Hash.new do |group, lineno_to_group|
|
34
|
+
group.each { |lineno| lineno_to_group[lineno] = group }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def format_string_for(results, group, lineno)
|
40
|
+
@format_strings[lineno] ||= begin
|
41
|
+
index = group.index lineno
|
42
|
+
group
|
43
|
+
.map { |lineno| results[lineno] }
|
44
|
+
.transpose
|
45
|
+
.map { |col|
|
46
|
+
lengths = col.map(&:length)
|
47
|
+
max = lengths.max
|
48
|
+
crnt = lengths[index]
|
49
|
+
"%-#{crnt}s,#{" "*(max-crnt)} "
|
50
|
+
}
|
51
|
+
.join
|
52
|
+
.sub(/, *$/, "")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|