seeing_is_believing 3.0.0 → 3.0.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 +4 -4
- data/Readme.md +62 -1
- data/features/xmpfilter-style.feature +46 -0
- data/lib/seeing_is_believing/binary/annotate_marked_lines.rb +36 -14
- data/lib/seeing_is_believing/version.rb +1 -1
- data/lib/seeing_is_believing/wrap_expressions.rb +14 -2
- data/spec/wrap_expressions_spec.rb +21 -16
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae473580cc4e716bb259237bd9a3f9f0e3983591
|
4
|
+
data.tar.gz: ac008a8042513f1facb360b0056c68f62abc29bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1d3d802588b733162f26ef0a55985b9dd1987759f96f45e6af5de45ba531654fb6e92a2db8c6498ce4fc6a8ed0dee44bbc9bbac0d3d01e98b698e903484d186
|
7
|
+
data.tar.gz: 7268519db2a550356f6ca29044ac68177678dd6509f9bcdcd6f24c23676eae14d79167b8a88ee5cb3aa84ce0e76d6ae87259127c4390863863c5ae442af2845d
|
data/Readme.md
CHANGED
@@ -44,12 +44,73 @@ end
|
|
44
44
|
`$ seeing_is_believing simple_example.rb` will print:
|
45
45
|
|
46
46
|
```ruby
|
47
|
-
|
48
47
|
5.times do |i| # => 5
|
49
48
|
i * 2 # => 0, 2, 4, 6, 8
|
50
49
|
end # => 5
|
51
50
|
```
|
52
51
|
|
52
|
+
`$ seeing_is_believing simple_example.rb --json` will print:
|
53
|
+
|
54
|
+
```json
|
55
|
+
{"stdout":"","stderr":"","exitstatus":0,"exception":null,"lines":{"1":["5"],"2":["0","2","4","6","8"],"3":["5"]}}
|
56
|
+
```
|
57
|
+
|
58
|
+
Protips
|
59
|
+
=======
|
60
|
+
|
61
|
+
These things have been useful for integrating.
|
62
|
+
|
63
|
+
If you want to execute from some specific dir (eg if your editor is in the wrong dir)
|
64
|
+
try using `Dir.chdir` at the top of the script.
|
65
|
+
Eg I used that [here](https://github.com/JoshCheek/seeing_is_believing/issues/58#issuecomment-91600783)
|
66
|
+
so I could run with a full Rails app available in "Completely against the real env".
|
67
|
+
|
68
|
+
If you want some specific file to be available in that environment, require the fullpath to the file.
|
69
|
+
Eg I used that [here](https://github.com/JoshCheek/seeing_is_believing/issues/58#issuecomment-91600783)
|
70
|
+
to load up the Rils schema in "Running against the real schema".
|
71
|
+
|
72
|
+
You can also set the `$LOAD_PATH` to a gem you're working on and then require files as if
|
73
|
+
it was installed.
|
74
|
+
|
75
|
+
You work with `gets` by setting `$stdin` to the `DATA` segment and writing inputs there.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
$stdin = DATA
|
79
|
+
|
80
|
+
puts "What's your name?"
|
81
|
+
name = gets.chomp
|
82
|
+
puts "What's your favourite colour?"
|
83
|
+
colour = gets.chomp
|
84
|
+
puts "#{name}'s favourite colour is #{colour}."
|
85
|
+
|
86
|
+
# >> What's your name?
|
87
|
+
# >> What's your favourite colour?
|
88
|
+
# >> Josh's favourite colour is brown.
|
89
|
+
|
90
|
+
__END__
|
91
|
+
Josh
|
92
|
+
brown
|
93
|
+
```
|
94
|
+
|
95
|
+
Rescue lines you expect to explode so that it displays the expected result and continues evaluating.
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
lambda { |x| x }.call() rescue $! # => #<ArgumentError: wrong number of arguments (given 0, expected 1)>
|
99
|
+
lambda { |x| x }.call(1) # => 1
|
100
|
+
lambda { |x| x }.call(1, 2) rescue $! # => #<ArgumentError: wrong number of arguments (given 2, expected 1)>
|
101
|
+
```
|
102
|
+
|
103
|
+
Use `fork` to look at what a program does when run two different ways.
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
class A
|
107
|
+
fork && raise("omg") # => nil
|
108
|
+
rescue
|
109
|
+
$! # => #<RuntimeError: omg>
|
110
|
+
else
|
111
|
+
:nothing_raised # => :nothing_raised
|
112
|
+
end # => #<RuntimeError: omg>, :nothing_raised
|
113
|
+
```
|
53
114
|
|
54
115
|
Use The Lib
|
55
116
|
===========
|
@@ -319,6 +319,52 @@ Feature: Xmpfilter style
|
|
319
319
|
"""
|
320
320
|
|
321
321
|
|
322
|
+
Scenario: When there are no results for the previous line it looks further back (#77)
|
323
|
+
Given the file "heredocs_and_blank_lines.rb":
|
324
|
+
"""
|
325
|
+
# =>
|
326
|
+
|
327
|
+
<<DOC
|
328
|
+
1
|
329
|
+
DOC
|
330
|
+
# =>
|
331
|
+
|
332
|
+
2
|
333
|
+
|
334
|
+
# =>
|
335
|
+
|
336
|
+
if true
|
337
|
+
3
|
338
|
+
# =>
|
339
|
+
else
|
340
|
+
4
|
341
|
+
# =>
|
342
|
+
end
|
343
|
+
"""
|
344
|
+
When I run "seeing_is_believing --xmpfilter-style heredocs_and_blank_lines.rb"
|
345
|
+
Then stdout is:
|
346
|
+
"""
|
347
|
+
# =>
|
348
|
+
|
349
|
+
<<DOC
|
350
|
+
1
|
351
|
+
DOC
|
352
|
+
# => "1\n"
|
353
|
+
|
354
|
+
2
|
355
|
+
|
356
|
+
# => 2
|
357
|
+
|
358
|
+
if true
|
359
|
+
3
|
360
|
+
# => 3
|
361
|
+
else
|
362
|
+
4
|
363
|
+
# =>
|
364
|
+
end
|
365
|
+
"""
|
366
|
+
|
367
|
+
|
322
368
|
|
323
369
|
Scenario: Xmpfilter uses the same comment formatting as normal
|
324
370
|
Given the file "xmpfilter_result_lengths.rb":
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'seeing_is_believing/code'
|
3
3
|
|
4
|
-
|
5
4
|
# *sigh* need to find a way to join the annotators.
|
6
5
|
# They are sinful ugly, kinda hard to work with,
|
7
6
|
# and absurdly duplicated.
|
@@ -11,16 +10,37 @@ class SeeingIsBelieving
|
|
11
10
|
# Based on the behaviour of xmpfilger (a binary in the rcodetools gem)
|
12
11
|
# See https://github.com/JoshCheek/seeing_is_believing/issues/44 for more details
|
13
12
|
class AnnotateMarkedLines
|
13
|
+
def self.map_markers_to_linenos(program, markers)
|
14
|
+
value_regex = markers[:value][:regex]
|
15
|
+
recordable_lines = []
|
16
|
+
inspect_linenos = []
|
17
|
+
pp_map = {}
|
18
|
+
WrapExpressions.call program, before_each: -> line_number {
|
19
|
+
recordable_lines << line_number
|
20
|
+
''
|
21
|
+
}
|
22
|
+
|
23
|
+
Code.new(program).inline_comments.each do |c|
|
24
|
+
next unless c.text[value_regex]
|
25
|
+
if c.whitespace_col == 0
|
26
|
+
lineno = c.line_number
|
27
|
+
loop do
|
28
|
+
lineno -= 1
|
29
|
+
break if recordable_lines.include?(lineno) || lineno.zero?
|
30
|
+
end
|
31
|
+
pp_map[c.line_number] = lineno
|
32
|
+
else
|
33
|
+
inspect_linenos << c.line_number
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
return inspect_linenos, pp_map
|
38
|
+
end
|
39
|
+
|
14
40
|
def self.code_rewriter(markers)
|
15
41
|
lambda do |program|
|
16
|
-
inspect_linenos =
|
17
|
-
pp_linenos
|
18
|
-
value_regex = markers[:value][:regex]
|
19
|
-
Code.new(program).inline_comments.each do |c|
|
20
|
-
next unless c.text[value_regex]
|
21
|
-
c.whitespace_col == 0 ? pp_linenos << c.line_number - 1
|
22
|
-
: inspect_linenos << c.line_number
|
23
|
-
end
|
42
|
+
inspect_linenos, pp_map = map_markers_to_linenos(program, markers)
|
43
|
+
pp_linenos = pp_map.values
|
24
44
|
|
25
45
|
should_inspect = false
|
26
46
|
should_pp = false
|
@@ -81,6 +101,7 @@ class SeeingIsBelieving
|
|
81
101
|
include_lines << exception_lineno
|
82
102
|
end
|
83
103
|
|
104
|
+
_, pp_map = self.class.map_markers_to_linenos(@body, @options[:markers])
|
84
105
|
new_body = RewriteComments.call @body, include_lines: include_lines do |comment|
|
85
106
|
exception_on_line = exception_lineno == comment.line_number
|
86
107
|
annotate_this_line = comment.text[value_regex]
|
@@ -93,12 +114,13 @@ class SeeingIsBelieving
|
|
93
114
|
whitespace = " " if whitespace.empty?
|
94
115
|
[whitespace, FormatComment.call(0, exception_prefix, exception_result, @options)]
|
95
116
|
elsif normal_annotation
|
96
|
-
|
97
|
-
[comment.whitespace, FormatComment.call(comment.text_col, value_prefix,
|
117
|
+
annotation = @results[comment.line_number].map { |result| result.gsub "\n", '\n' }.join(', ')
|
118
|
+
[comment.whitespace, FormatComment.call(comment.text_col, value_prefix, annotation, @options)]
|
98
119
|
elsif pp_annotation
|
99
|
-
result
|
100
|
-
|
101
|
-
|
120
|
+
result = @results[pp_map[comment.line_number], :pp]
|
121
|
+
annotation = result.map { |result| result.chomp }.join("\n,") # ["1\n2", "1\n2", ...
|
122
|
+
swap_leading_whitespace_in_multiline_comment(annotation)
|
123
|
+
comment_lines = annotation.each_line.map.with_index do |comment_line, result_offest|
|
102
124
|
if result_offest == 0
|
103
125
|
FormatComment.call(comment.whitespace_col, value_prefix, comment_line.chomp, @options)
|
104
126
|
else
|
@@ -98,11 +98,17 @@ class SeeingIsBelieving
|
|
98
98
|
case ast.type
|
99
99
|
when :args, :redo, :retry, :alias, :undef, :null_node
|
100
100
|
# no op
|
101
|
-
when :defs, :
|
101
|
+
when :defs, :module
|
102
102
|
add_to_wrappings ast
|
103
103
|
add_children ast, true
|
104
104
|
when :rescue, :ensure, :return, :break, :next, :splat, :kwsplat
|
105
105
|
add_children ast
|
106
|
+
when :class
|
107
|
+
name, * = ast.children
|
108
|
+
namespace, * = name.children
|
109
|
+
add_to_wrappings ast
|
110
|
+
wrap_recursive namespace
|
111
|
+
add_children ast, true
|
106
112
|
when :if
|
107
113
|
if ast.location.kind_of? Parser::Source::Map::Ternary
|
108
114
|
add_to_wrappings ast unless ast.children.any? { |child| code.void_value? child }
|
@@ -196,8 +202,14 @@ class SeeingIsBelieving
|
|
196
202
|
add_to_wrappings ast
|
197
203
|
end
|
198
204
|
add_children ast
|
199
|
-
when :str
|
205
|
+
when :str
|
206
|
+
add_to_wrappings ast
|
207
|
+
|
208
|
+
when :dstr, :regexp
|
200
209
|
add_to_wrappings ast
|
210
|
+
ast.children
|
211
|
+
.select { |child| child.type == :begin }
|
212
|
+
.each { |child| add_children child }
|
201
213
|
|
202
214
|
when :hash
|
203
215
|
# method arguments might not have braces around them
|
@@ -217,9 +217,9 @@ RSpec.describe SeeingIsBelieving::WrapExpressions do
|
|
217
217
|
expect(wrap("alias $a $b")).to eq "alias $a $b"
|
218
218
|
end
|
219
219
|
|
220
|
-
it 'wraps syscalls,
|
220
|
+
it 'wraps syscalls, and the code interpolated into them' do
|
221
221
|
expect(wrap("`a\nb`")).to eq "<`a\nb`>"
|
222
|
-
expect(wrap("`a\n\#{1\n2\n3}b`")).to eq "<`a\n\#{1
|
222
|
+
expect(wrap("`a\n\#{1\n2\n3}b`")).to eq "<`a\n\#{<1>\n<2>\n3}b`>"
|
223
223
|
end
|
224
224
|
end
|
225
225
|
|
@@ -586,12 +586,10 @@ RSpec.describe SeeingIsBelieving::WrapExpressions do
|
|
586
586
|
expect(wrap("/a\nb/i")).to eq "</a\nb/i>"
|
587
587
|
end
|
588
588
|
|
589
|
-
|
590
|
-
# when the end of the line was not back inside the regexp
|
591
|
-
it 'wraps regexes with interpolation, but not the interpolated portion' do
|
589
|
+
it 'wraps regexes with interpolation, including the interpolated portion' do
|
592
590
|
expect(wrap("/a\#{1}/")).to eq "</a\#{1}/>"
|
593
|
-
expect(wrap("/a\n\#{1}\nb/")).to eq "</a\n\#{1}\nb/>"
|
594
|
-
expect(wrap("/a\n\#{1\n}b/")).to eq "</a\n\#{1
|
591
|
+
expect(wrap("/a\n\#{1}\nb/")).to eq "</a\n\#{<1>}\nb/>"
|
592
|
+
expect(wrap("/a\n\#{1\n}b/")).to eq "</a\n\#{<1>\n}b/>"
|
595
593
|
end
|
596
594
|
end
|
597
595
|
|
@@ -612,12 +610,10 @@ RSpec.describe SeeingIsBelieving::WrapExpressions do
|
|
612
610
|
expect(wrap(%'"a\nb"')).to eq %'<"a\nb">'
|
613
611
|
end
|
614
612
|
|
615
|
-
|
616
|
-
# when the end of the line was not back inside the string
|
617
|
-
it 'wraps strings with interpolation, but not the interpolated portion' do
|
613
|
+
it 'wraps strings with interpolation, including the interpolated portion' do
|
618
614
|
expect(wrap('"a#{1}"')).to eq '<"a#{1}">'
|
619
|
-
expect(wrap(%'"a\n\#{1}\nb"')).to eq %'<"a\n\#{1}\nb">'
|
620
|
-
expect(wrap(%'"a\n\#{1\n}b"')).to eq %'<"a\n\#{1
|
615
|
+
expect(wrap(%'"a\n\#{1}\nb"')).to eq %'<"a\n\#{<1>}\nb">'
|
616
|
+
expect(wrap(%'"a\n\#{1\n}b"')).to eq %'<"a\n\#{<1>\n}b">'
|
621
617
|
end
|
622
618
|
|
623
619
|
it 'wraps %, %q, %Q' do
|
@@ -709,21 +705,30 @@ RSpec.describe SeeingIsBelieving::WrapExpressions do
|
|
709
705
|
end
|
710
706
|
|
711
707
|
describe 'class definitions' do
|
712
|
-
it 'does
|
708
|
+
it 'does wraps the class definition, and body' do
|
713
709
|
expect(wrap("class A\n1\nend")).to eq "<class A\n<1>\nend>"
|
714
710
|
end
|
715
711
|
|
716
|
-
it 'does
|
712
|
+
it 'does wraps the superclass definition' do
|
717
713
|
expect(wrap("class A < B\nend")).to eq "<class A < <B>\nend>"
|
718
714
|
end
|
719
715
|
|
720
|
-
it 'wraps the rescue body' do
|
716
|
+
it 'wraps the rescue, else, ensure body' do
|
717
|
+
expect(wrap("class A < B\n1\nrescue\n2\nelse\n3\nensure\n4\nend")).to eq "<class A < <B>\n<1>\nrescue\n<2>\nelse\n<3>\nensure\n<4>\nend>"
|
718
|
+
end
|
719
|
+
|
720
|
+
it 'wraps the else body' do
|
721
721
|
expect(wrap("class A < B\n1\nrescue\n2\nend")).to eq "<class A < <B>\n<1>\nrescue\n<2>\nend>"
|
722
722
|
end
|
723
723
|
|
724
|
-
it '
|
724
|
+
it 'wraps the singleton class' do
|
725
725
|
expect(wrap("class << self\n end")).to eq "<class << <self>\n end>"
|
726
726
|
end
|
727
|
+
|
728
|
+
it 'wraps the namespace' do
|
729
|
+
expect(wrap("class A::B\nend")).to eq "<class <A>::B\nend>"
|
730
|
+
expect(wrap("class (\n1\nObject\n)::String\nend")).to eq "<class <(\n<1>\n<Object>\n)>::String\nend>"
|
731
|
+
end
|
727
732
|
end
|
728
733
|
|
729
734
|
describe 'module definitions' 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.0.
|
4
|
+
version: 3.0.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: 2016-10-
|
11
|
+
date: 2016-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -261,7 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
261
261
|
version: '0'
|
262
262
|
requirements: []
|
263
263
|
rubyforge_project: seeing_is_believing
|
264
|
-
rubygems_version: 2.
|
264
|
+
rubygems_version: 2.5.1
|
265
265
|
signing_key:
|
266
266
|
specification_version: 4
|
267
267
|
summary: Records results of every line of code in your file
|