seeing_is_believing 3.6.0 → 3.6.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|