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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c0318721dea2259939dac9f239eaf465f9a7d605
4
- data.tar.gz: a9c3681770369df1da596a736c266ff51624603e
3
+ metadata.gz: ae473580cc4e716bb259237bd9a3f9f0e3983591
4
+ data.tar.gz: ac008a8042513f1facb360b0056c68f62abc29bb
5
5
  SHA512:
6
- metadata.gz: 06109b5b546f05c712f17d3856fb5faf8e41579a00758dd3fe05a4bec5dd12028a532c6429529db257a15aebfe4bee5a574999f714f0ac2e22ab1986eafc267c
7
- data.tar.gz: 12f47cae8b1613713ec81bc66a7156d89ed15a967b8c1b3a54af4bdc520cb25541bf2327cadf452eef2da14f4cf35ec4cd103c4718a3319ecbd1bdc035e076a4
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
- result = @results[comment.line_number].map { |result| result.gsub "\n", '\n' }.join(', ')
97
- [comment.whitespace, FormatComment.call(comment.text_col, value_prefix, result, @options)]
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 = @results[comment.line_number-1, :pp].map { |result| result.chomp }.join("\n,") # ["1\n2", "1\n2", ...
100
- swap_leading_whitespace_in_multiline_comment(result)
101
- comment_lines = result.each_line.map.with_index do |comment_line, result_offest|
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
@@ -1,3 +1,3 @@
1
1
  class SeeingIsBelieving
2
- VERSION = '3.0.0'
2
+ VERSION = '3.0.1'
3
3
  end
@@ -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, :class, :module
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, :dstr, :xstr, :regexp
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, but not code interpolated into them' do
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\n2\n3}b`>"
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
- # eventually it would be nice if it wraped the interpolated portion,
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\n}b/>"
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
- # eventually it would be nice if it wraped the interpolated portion,
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\n}b">'
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 not wrap the class definition, does wrap the body' do
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 not wrap the superclass definition' do
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 'does not wrap the singleton class' do
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.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-08 00:00:00.000000000 Z
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.4.8
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