seeing_is_believing 3.6.0 → 3.6.1
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 +5 -5
- data/Rakefile +1 -1
- data/features/regression.feature +81 -0
- data/lib/seeing_is_believing/binary/annotate_marked_lines.rb +2 -2
- data/lib/seeing_is_believing/binary/format_comment.rb +9 -6
- data/lib/seeing_is_believing/compatibility.rb +28 -0
- data/lib/seeing_is_believing/evaluate_by_moving_files.rb +1 -1
- data/lib/seeing_is_believing/event_stream/consumer.rb +24 -28
- data/lib/seeing_is_believing/event_stream/producer.rb +11 -5
- data/lib/seeing_is_believing/safe.rb +7 -0
- data/lib/seeing_is_believing/version.rb +1 -1
- data/lib/seeing_is_believing/wrap_expressions_with_inspect.rb +1 -1
- data/spec/binary/format_comment_spec.rb +5 -1
- data/spec/event_stream_spec.rb +7 -0
- data/spec/seeing_is_believing_spec.rb +32 -2
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: abaf2ec44d75ad4ca500c71bf90128baea06be5c0bd61fef5a0de81a402fef49
|
4
|
+
data.tar.gz: b487790b90fb61b27e77fee26622c8210a0b6e435c2084205bb791bcf3e28c08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '03996ee758737b276089eec6037a0c999678097759fc1dac9a1a338eae62327cb5d76253e0c491ae77a7e0852edb104da629e59db1c60228c43076d100ae8215'
|
7
|
+
data.tar.gz: 915f7e561d0bcb18f863c068e72305fa445f1b4f5f9d390843478a4ddb662cf8c38af388d5cc8da5f9ddaeeba1e569ad803c5d5c5b913d92bc6642e60155484e
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
desc 'Have Bundler setup a standalone environment -- run tests in this, b/c its faster and safer'
|
2
2
|
task :install do
|
3
|
-
# Running without rubygems
|
3
|
+
# Running without rubygems http://myronmars.to/n/dev-blog/2012/03/faster-test-boot-times-with-bundler-standalone
|
4
4
|
which("bundle") or sh 'gem', 'install', 'bundler', '--no-ri', '--no-rdoc'
|
5
5
|
Dir.exist? 'bundle' or sh 'bundle', 'install', '--standalone', '--binstubs', 'bundle/bin'
|
6
6
|
end
|
data/features/regression.feature
CHANGED
@@ -834,3 +834,84 @@ Feature:
|
|
834
834
|
Then stdout is "1 # => 1"
|
835
835
|
When I run "seeing_is_believing -e '1;'"
|
836
836
|
Then stdout is "1; # => 1"
|
837
|
+
|
838
|
+
|
839
|
+
Scenario: A spy / proxy class (Issue #136)
|
840
|
+
Given the file "spy_class.rb":
|
841
|
+
"""
|
842
|
+
class String
|
843
|
+
def self.===(obj)
|
844
|
+
true
|
845
|
+
end
|
846
|
+
end
|
847
|
+
class Spy < BasicObject
|
848
|
+
def method_missing(name, *args, &block)
|
849
|
+
self
|
850
|
+
end
|
851
|
+
end
|
852
|
+
Spy.new # =>
|
853
|
+
"""
|
854
|
+
When I run "seeing_is_believing -x spy_class.rb"
|
855
|
+
Then stderr is empty
|
856
|
+
And the exit status is 0
|
857
|
+
And stdout includes "Spy.new # => #<Spy:"
|
858
|
+
|
859
|
+
|
860
|
+
Scenario: Refined inspect
|
861
|
+
Given the file "refined_inspect.rb":
|
862
|
+
"""
|
863
|
+
module Humanize
|
864
|
+
refine Float do
|
865
|
+
def inspect
|
866
|
+
rounded = "%.2f" % self
|
867
|
+
rounded.reverse!
|
868
|
+
rounded.gsub! /(\d{3})/, '\1,'
|
869
|
+
rounded.chomp! ","
|
870
|
+
rounded.reverse!
|
871
|
+
rounded
|
872
|
+
end #
|
873
|
+
end
|
874
|
+
end
|
875
|
+
using Humanize
|
876
|
+
12345.6789 # =>
|
877
|
+
"""
|
878
|
+
When I run "seeing_is_believing refined_inspect.rb"
|
879
|
+
Then stderr is empty
|
880
|
+
And the exit status is 0
|
881
|
+
And stdout is:
|
882
|
+
"""
|
883
|
+
module Humanize
|
884
|
+
refine Float do
|
885
|
+
def inspect
|
886
|
+
rounded = "%.2f" % self # => "12345.68"
|
887
|
+
rounded.reverse! # => "86.54321"
|
888
|
+
rounded.gsub! /(\d{3})/, '\1,' # => "86.543,21"
|
889
|
+
rounded.chomp! "," # => nil
|
890
|
+
rounded.reverse! # => "12,345.68"
|
891
|
+
rounded # => "12,345.68"
|
892
|
+
end #
|
893
|
+
end # => #<refinement:Float@Humanize>
|
894
|
+
end # => #<refinement:Float@Humanize>
|
895
|
+
using Humanize # => main
|
896
|
+
12345.6789 # => 12,345.68
|
897
|
+
"""
|
898
|
+
When I run "seeing_is_believing refined_inspect.rb -x"
|
899
|
+
Then stderr is empty
|
900
|
+
And the exit status is 0
|
901
|
+
Then stdout is:
|
902
|
+
"""
|
903
|
+
module Humanize
|
904
|
+
refine Float do
|
905
|
+
def inspect
|
906
|
+
rounded = "%.2f" % self
|
907
|
+
rounded.reverse!
|
908
|
+
rounded.gsub! /(\d{3})/, '\1,'
|
909
|
+
rounded.chomp! ","
|
910
|
+
rounded.reverse!
|
911
|
+
rounded
|
912
|
+
end #
|
913
|
+
end
|
914
|
+
end
|
915
|
+
using Humanize
|
916
|
+
12345.6789 # => 12,345.68
|
917
|
+
"""
|
@@ -7,7 +7,7 @@ require 'seeing_is_believing/code'
|
|
7
7
|
|
8
8
|
class SeeingIsBelieving
|
9
9
|
module Binary
|
10
|
-
# Based on the behaviour of
|
10
|
+
# Based on the behaviour of xmpfilter (a binary in the rcodetools gem)
|
11
11
|
# See https://github.com/JoshCheek/seeing_is_believing/issues/44 for more details
|
12
12
|
class AnnotateMarkedLines
|
13
13
|
def self.map_markers_to_linenos(program, markers)
|
@@ -64,7 +64,7 @@ class SeeingIsBelieving
|
|
64
64
|
# 79 - "# => ".length # => 4
|
65
65
|
# ALSO: This should be configurable, b/c otherwise you have to go into the guts of `pp`
|
66
66
|
# https://gist.github.com/JoshCheek/6472c8f334ae493f4ab1f7865e2470e5
|
67
|
-
inspect = "))"
|
67
|
+
inspect = ")) { |v| v.inspect }"
|
68
68
|
pp = ")) { |v| PP.pp v, '', 74 }"
|
69
69
|
|
70
70
|
should_inspect = inspect_linenos.include? line_number
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# Polyfill String#scrub on Ruby 2.0.0
|
2
|
+
require 'seeing_is_believing/compatibility'
|
3
|
+
using SeeingIsBelieving::Compatibility
|
4
|
+
|
1
5
|
class SeeingIsBelieving
|
2
6
|
module Binary
|
3
7
|
# not sure I like this name, it formats comments that show results
|
@@ -64,12 +68,11 @@ class SeeingIsBelieving
|
|
64
68
|
end
|
65
69
|
|
66
70
|
def escape_non_printable(str, omissions)
|
67
|
-
str.
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
}.join('')
|
71
|
+
str.scrub { |c| c.inspect[1...-1] }
|
72
|
+
.gsub(/[\u0000-\u0020]/) { |char|
|
73
|
+
next char if omissions.include? char
|
74
|
+
char.inspect[1...-1]
|
75
|
+
}
|
73
76
|
end
|
74
77
|
end
|
75
78
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class SeeingIsBelieving
|
2
|
+
module Compatibility
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
# Ruby 2.0.0 is soooooo painful >.<
|
7
|
+
# want to stop supporting this so bad!!
|
8
|
+
is_v2_0 = !String.instance_methods.include?(:scrub)
|
9
|
+
|
10
|
+
is_v2_0 && begin
|
11
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
12
|
+
module SeeingIsBelieving::Compatibility
|
13
|
+
refine String do
|
14
|
+
def scrub(char=nil, &block)
|
15
|
+
char && block = lambda { |c| char }
|
16
|
+
each_char.inject("") do |new_str, char|
|
17
|
+
if char.valid_encoding?
|
18
|
+
new_str << char
|
19
|
+
else
|
20
|
+
new_str << block.call(char)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
ensure
|
27
|
+
$VERBOSE = old_verbose
|
28
|
+
end
|
@@ -39,7 +39,7 @@ class SeeingIsBelieving
|
|
39
39
|
self.timeout_seconds = options.delete(:timeout_seconds) || 0 # 0 is the new infinity
|
40
40
|
self.provided_input = options.delete(:provided_input) || String.new
|
41
41
|
self.event_handler = options.delete(:event_handler) || raise(ArgumentError, "must provide an :event_handler")
|
42
|
-
self.load_path_flags = (options.delete(:load_path_dirs) || []).
|
42
|
+
self.load_path_flags = (options.delete(:load_path_dirs) || []).flat_map { |dir| ['-I', dir] }
|
43
43
|
self.require_flags = (options.delete(:require_files) || ['seeing_is_believing/the_matrix']).map { |filename| ['-r', filename] }.flatten
|
44
44
|
self.max_line_captures = (options.delete(:max_line_captures) || Float::INFINITY) # (optimization: child stops producing results at this number, even though it might make more sense for the consumer to stop emitting them)
|
45
45
|
self.local_cwd = options.delete(:local_cwd) || false
|
@@ -4,6 +4,10 @@ require 'seeing_is_believing/event_stream/events'
|
|
4
4
|
require 'seeing_is_believing/error'
|
5
5
|
require 'thread'
|
6
6
|
|
7
|
+
# Polyfill String#scrub on Ruby 2.0.0
|
8
|
+
require 'seeing_is_believing/compatibility'
|
9
|
+
using SeeingIsBelieving::Compatibility
|
10
|
+
|
7
11
|
class SeeingIsBelieving
|
8
12
|
module EventStream
|
9
13
|
class Consumer
|
@@ -60,15 +64,7 @@ class SeeingIsBelieving
|
|
60
64
|
rescue EncodingError
|
61
65
|
str = str.force_encoding(Encoding::UTF_8)
|
62
66
|
end
|
63
|
-
|
64
|
-
# basically reimplement scrub, b/c it's not implemented on 2.0.0
|
65
|
-
str.each_char.inject("") do |new_str, char|
|
66
|
-
if char.valid_encoding?
|
67
|
-
new_str << char
|
68
|
-
else
|
69
|
-
new_str << '�'
|
70
|
-
end
|
71
|
-
end
|
67
|
+
str.scrub('�')
|
72
68
|
end
|
73
69
|
|
74
70
|
def initialize(streams)
|
@@ -169,51 +165,51 @@ class SeeingIsBelieving
|
|
169
165
|
end
|
170
166
|
end
|
171
167
|
|
172
|
-
def
|
168
|
+
def shift_token(line)
|
173
169
|
event_name = line[/[^ ]+/]
|
174
170
|
line.sub!(/^\s*[^ ]+\s*/, '')
|
175
171
|
event_name
|
176
172
|
end
|
177
173
|
|
178
174
|
# For a consideration of many different ways of passing the message, see 5633064
|
179
|
-
def
|
180
|
-
str = Marshal.load
|
175
|
+
def shift_string(line)
|
176
|
+
str = Marshal.load shift_token(line).unpack('m0').first
|
181
177
|
Consumer.fix_encoding(str)
|
182
178
|
end
|
183
179
|
|
184
180
|
def event_for(original_line)
|
185
181
|
line = original_line.chomp
|
186
|
-
event_name =
|
182
|
+
event_name = shift_token(line).intern
|
187
183
|
case event_name
|
188
184
|
when :result
|
189
|
-
line_number =
|
190
|
-
type =
|
191
|
-
inspected =
|
185
|
+
line_number = shift_token(line).to_i
|
186
|
+
type = shift_token(line).intern
|
187
|
+
inspected = shift_string(line)
|
192
188
|
Events::LineResult.new(type: type, line_number: line_number, inspected: inspected)
|
193
189
|
when :maxed_result
|
194
|
-
line_number =
|
195
|
-
type =
|
190
|
+
line_number = shift_token(line).to_i
|
191
|
+
type = shift_token(line).intern
|
196
192
|
Events::ResultsTruncated.new(type: type, line_number: line_number)
|
197
193
|
when :exception
|
198
194
|
Events::Exception.new \
|
199
|
-
line_number:
|
200
|
-
class_name:
|
201
|
-
message:
|
202
|
-
backtrace:
|
195
|
+
line_number: shift_token(line).to_i,
|
196
|
+
class_name: shift_string(line),
|
197
|
+
message: shift_string(line),
|
198
|
+
backtrace: shift_token(line).to_i.times.map { shift_string line }
|
203
199
|
when :max_line_captures
|
204
|
-
token =
|
200
|
+
token = shift_token(line)
|
205
201
|
value = token =~ /infinity/i ? Float::INFINITY : token.to_i
|
206
202
|
Events::MaxLineCaptures.new(value: value)
|
207
203
|
when :num_lines
|
208
|
-
Events::NumLines.new(value:
|
204
|
+
Events::NumLines.new(value: shift_token(line).to_i)
|
209
205
|
when :sib_version
|
210
|
-
Events::SiBVersion.new(value:
|
206
|
+
Events::SiBVersion.new(value: shift_string(line))
|
211
207
|
when :ruby_version
|
212
|
-
Events::RubyVersion.new(value:
|
208
|
+
Events::RubyVersion.new(value: shift_string(line))
|
213
209
|
when :filename
|
214
|
-
Events::Filename.new(value:
|
210
|
+
Events::Filename.new(value: shift_string(line))
|
215
211
|
when :exec
|
216
|
-
Events::Exec.new(args:
|
212
|
+
Events::Exec.new(args: shift_string(line))
|
217
213
|
else
|
218
214
|
raise UnknownEvent, original_line.inspect
|
219
215
|
end
|
@@ -49,9 +49,13 @@ class SeeingIsBelieving
|
|
49
49
|
if count < max_line_captures
|
50
50
|
begin
|
51
51
|
if block_given?
|
52
|
-
inspected = yield(value)
|
52
|
+
inspected = yield(value)
|
53
53
|
else
|
54
|
-
inspected = value.inspect
|
54
|
+
inspected = value.inspect
|
55
|
+
end
|
56
|
+
unless String === inspected
|
57
|
+
inspected = inspected.to_str
|
58
|
+
raise unless String === inspected
|
55
59
|
end
|
56
60
|
rescue *StackErrors
|
57
61
|
# this is necessary because SystemStackError won't show the backtrace of the method we tried to call
|
@@ -76,9 +80,11 @@ class SeeingIsBelieving
|
|
76
80
|
# records the exception, returns the exitstatus for that exception
|
77
81
|
def record_exception(line_number, exception)
|
78
82
|
return exception.status if SystemExit === exception # TODO === is not in the list
|
79
|
-
|
80
|
-
|
81
|
-
|
83
|
+
unless line_number
|
84
|
+
if filename
|
85
|
+
begin line_number = exception.backtrace.grep(/#{filename.to_s}/).first[/:\d+/][1..-1].to_i
|
86
|
+
rescue NoMethodError
|
87
|
+
end
|
82
88
|
end
|
83
89
|
end
|
84
90
|
line_number ||= -1
|
@@ -1,6 +1,13 @@
|
|
1
1
|
# require this before anything else, b/c it expects the world to be sane when it is loaded
|
2
2
|
class SeeingIsBelieving
|
3
3
|
module Safe
|
4
|
+
|
5
|
+
# Subclasses must refine before superclasses in older Rubies, otherwise
|
6
|
+
# it finds the superclass method and behaves unexpectedly.
|
7
|
+
refine String.singleton_class do
|
8
|
+
alias === ===
|
9
|
+
end
|
10
|
+
|
4
11
|
refine Class do
|
5
12
|
alias === ===
|
6
13
|
end
|
@@ -60,7 +60,10 @@ RSpec.describe SeeingIsBelieving::Binary::FormatComment do
|
|
60
60
|
|
61
61
|
def assert_printed(c, printed)
|
62
62
|
c = c.force_encoding 'utf-8'
|
63
|
-
|
63
|
+
result = result_for 0, '', c
|
64
|
+
expect(result).to eq printed
|
65
|
+
expect(result.encoding).to eq Encoding::UTF_8
|
66
|
+
expect(result).to be_valid_encoding
|
64
67
|
end
|
65
68
|
|
66
69
|
it 'escapes any non-printable characters' do
|
@@ -192,6 +195,7 @@ RSpec.describe SeeingIsBelieving::Binary::FormatComment do
|
|
192
195
|
assert_printed 124.chr , "|"
|
193
196
|
assert_printed 125.chr , "}"
|
194
197
|
assert_printed 126.chr , "~"
|
198
|
+
assert_printed 127.chr, "\u007F"
|
195
199
|
end
|
196
200
|
|
197
201
|
it 'can be given a list of characters to not escape' do
|
data/spec/event_stream_spec.rb
CHANGED
@@ -437,6 +437,13 @@ module SeeingIsBelieving::EventStream
|
|
437
437
|
end
|
438
438
|
end
|
439
439
|
|
440
|
+
it 'works with objects whose boolean inquiries have been messed with (#131)' do
|
441
|
+
exception = begin; raise; rescue; $!; end
|
442
|
+
bad_bool = Object.new
|
443
|
+
def bad_bool.!(*) raise; end
|
444
|
+
producer.record_exception bad_bool, exception # should not explode
|
445
|
+
end
|
446
|
+
|
440
447
|
context 'recorded line number | line num is provided | it knows the file | exception comes from within file' do
|
441
448
|
let(:exception) { begin; raise "zomg"; rescue; $!; end }
|
442
449
|
let(:linenum) { __LINE__ - 1 }
|
@@ -531,6 +531,13 @@ RSpec.describe SeeingIsBelieving do
|
|
531
531
|
expect(result.exception.message).to match /recursive/i
|
532
532
|
end
|
533
533
|
|
534
|
+
it 'does not blow up when returning an object that recursively responds to everything' do
|
535
|
+
result = invoke('obj = BasicObject.new
|
536
|
+
def obj.method_missing(*) self; end
|
537
|
+
obj')
|
538
|
+
expect(result[3][0]).to start_with '#<BasicObject:'
|
539
|
+
end
|
540
|
+
|
534
541
|
it 'does not blow up when the first line looks like it might have a magic comment in it (#126)' do
|
535
542
|
expect(values_for "1+1 # and a comment with 'Accept-Encoding: gzip' in it").to eq [['2']]
|
536
543
|
end
|
@@ -547,6 +554,25 @@ RSpec.describe SeeingIsBelieving do
|
|
547
554
|
expect(values_for 'o = BasicObject.new; def o.inspect; "some obj"; end; o').to eq [['some obj']]
|
548
555
|
end
|
549
556
|
|
557
|
+
it 'sees refined inspect (#128)' do
|
558
|
+
result = invoke <<-RUBY
|
559
|
+
module BinMeUp
|
560
|
+
refine Fixnum do
|
561
|
+
def inspect
|
562
|
+
"%08b" % self
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
566
|
+
using BinMeUp
|
567
|
+
5
|
568
|
+
RUBY
|
569
|
+
expect(result[9]).to eq ['00000101']
|
570
|
+
end
|
571
|
+
|
572
|
+
it 'works when the exception does not have a backtrace (#134)' do
|
573
|
+
|
574
|
+
end
|
575
|
+
|
550
576
|
it 'respects timeout, even when children do semi-ridiculous things, it cleans up children rather than orphaning them' do
|
551
577
|
pre = Time.now
|
552
578
|
result = invoke <<-CHILD, timeout_seconds: 0.5
|
@@ -783,14 +809,18 @@ RSpec.describe SeeingIsBelieving do
|
|
783
809
|
end').stderr).to eq ''
|
784
810
|
end
|
785
811
|
|
786
|
-
specify 'when String does not have ==, to_s, inspect, to_i' do
|
812
|
+
specify 'when String does not have ==, to_s, inspect, to_i, ===' do
|
787
813
|
expect(invoke('class String
|
788
814
|
undef ==
|
789
815
|
undef to_s
|
790
816
|
undef to_str
|
791
817
|
undef inspect
|
792
818
|
undef to_i
|
793
|
-
end
|
819
|
+
end
|
820
|
+
class << String
|
821
|
+
undef ===
|
822
|
+
end
|
823
|
+
').stderr).to eq ''
|
794
824
|
end
|
795
825
|
|
796
826
|
specify 'when Fixnum does not have <, <<, next, ==, inspect, to_s' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seeing_is_believing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.6.
|
4
|
+
version: 3.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Cheek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -189,6 +189,7 @@ files:
|
|
189
189
|
- lib/seeing_is_believing/binary/remove_annotations.rb
|
190
190
|
- lib/seeing_is_believing/binary/rewrite_comments.rb
|
191
191
|
- lib/seeing_is_believing/code.rb
|
192
|
+
- lib/seeing_is_believing/compatibility.rb
|
192
193
|
- lib/seeing_is_believing/customize_pp.rb
|
193
194
|
- lib/seeing_is_believing/debugger.rb
|
194
195
|
- lib/seeing_is_believing/error.rb
|
@@ -287,7 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
287
288
|
version: '0'
|
288
289
|
requirements: []
|
289
290
|
rubyforge_project: seeing_is_believing
|
290
|
-
rubygems_version: 2.
|
291
|
+
rubygems_version: 2.7.6
|
291
292
|
signing_key:
|
292
293
|
specification_version: 4
|
293
294
|
summary: Records results of every line of code in your file
|