seeing_is_believing 3.0.0.beta.1 → 3.0.0.beta.2
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/features/xmpfilter-style.feature +22 -12
- data/lib/seeing_is_believing/binary.rb +1 -1
- data/lib/seeing_is_believing/binary/annotate_every_line.rb +6 -6
- data/lib/seeing_is_believing/binary/annotate_xmpfilter_style.rb +38 -44
- data/lib/seeing_is_believing/binary/interpret_flags.rb +18 -7
- data/lib/seeing_is_believing/binary/parse_args.rb +10 -2
- data/lib/seeing_is_believing/binary/remove_annotations.rb +62 -43
- data/lib/seeing_is_believing/binary/rewrite_comments.rb +49 -3
- data/lib/seeing_is_believing/version.rb +1 -1
- data/lib/seeing_is_believing/wrap_expressions.rb +9 -9
- data/spec/binary/interpret_flags_spec.rb +39 -0
- data/spec/binary/parse_args_spec.rb +15 -4
- data/spec/binary/remove_annotations_spec.rb +132 -28
- data/spec/binary/rewrite_comments_spec.rb +38 -2
- data/spec/wrap_expressions_spec.rb +7 -5
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 981bfb703701767923dee2010cd2073ec901e20f
|
4
|
+
data.tar.gz: 0eaa0290fac0e7b0b312196371507f717b2ad1d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 019b0ac6587cb94c98bc9e916daa49f8b21e6eba166a3a6c5e930de573ecce274004f11de8cd47e366af46c4da881376b05c4ef4d3a8a43a5e0c614517a53d75
|
7
|
+
data.tar.gz: d515e9959c12741755f0ff298a5f571d8860290a15f3548e3386ae7ef8b4b9c0364ccac1c7a7816a771fc9a100746f813e259dce2cac943d01c6f8d70510dc1d
|
@@ -3,6 +3,12 @@ Feature: Xmpfilter style
|
|
3
3
|
Support the same (or highly similar) interface as xmpfilter,
|
4
4
|
so that people who use that lib can easily transition to SiB.
|
5
5
|
|
6
|
+
TODO:
|
7
|
+
* multiple values on pp lines
|
8
|
+
* show that exceptions respect line-length restriction flags
|
9
|
+
* Scenario: pp output on line with exception
|
10
|
+
* when input has previously identified exception
|
11
|
+
|
6
12
|
|
7
13
|
Scenario: --xmpfilter-style Generic updating of marked lines
|
8
14
|
Given the file "magic_comments.rb":
|
@@ -18,6 +24,7 @@ Feature: Xmpfilter style
|
|
18
24
|
# =>
|
19
25
|
"omg2"
|
20
26
|
# => "not omg2"
|
27
|
+
3+3#=>
|
21
28
|
"""
|
22
29
|
When I run "seeing_is_believing --xmpfilter-style magic_comments.rb"
|
23
30
|
Then stderr is empty
|
@@ -35,6 +42,7 @@ Feature: Xmpfilter style
|
|
35
42
|
# => "omg"
|
36
43
|
"omg2"
|
37
44
|
# => "omg2"
|
45
|
+
3+3# => 6
|
38
46
|
"""
|
39
47
|
|
40
48
|
|
@@ -101,42 +109,44 @@ Feature: Xmpfilter style
|
|
101
109
|
"""
|
102
110
|
|
103
111
|
|
104
|
-
@josh1
|
105
112
|
Scenario: Errors on annotated lines
|
106
113
|
Given the file "xmpfilter_error_on_annotated_line.rb":
|
107
114
|
"""
|
108
|
-
raise "
|
115
|
+
raise "ZOMG\n!!!!" # =>
|
109
116
|
"""
|
110
117
|
When I run "seeing_is_believing --xmpfilter-style xmpfilter_error_on_annotated_line.rb"
|
111
118
|
Then stderr is empty
|
112
119
|
And the exit status is 1
|
113
120
|
Then stdout is:
|
114
121
|
"""
|
115
|
-
raise "
|
122
|
+
raise "ZOMG\n!!!!" # => RuntimeError: ZOMG\n!!!!
|
116
123
|
|
117
124
|
# ~> RuntimeError
|
118
|
-
# ~>
|
125
|
+
# ~> ZOMG
|
126
|
+
# ~> !!!!
|
119
127
|
# ~>
|
120
128
|
# ~> xmpfilter_error_on_annotated_line.rb:1:in `<main>'
|
121
129
|
"""
|
122
130
|
|
123
131
|
|
124
|
-
@josh2
|
125
132
|
Scenario: Errors on unannotated lines
|
126
|
-
Given the file "
|
133
|
+
Given the file "xmpfilter_error_on_unannotated_line.rb":
|
127
134
|
"""
|
128
|
-
raise "
|
135
|
+
raise "ZOMG\n!!!!"
|
129
136
|
"""
|
130
|
-
When I run "seeing_is_believing --xmpfilter-style
|
137
|
+
When I run "seeing_is_believing --xmpfilter-style xmpfilter_error_on_unannotated_line.rb"
|
131
138
|
Then stderr is empty
|
132
139
|
And the exit status is 1
|
133
140
|
Then stdout is:
|
134
141
|
"""
|
135
|
-
raise "
|
136
|
-
"""
|
142
|
+
raise "ZOMG\n!!!!" # ~> RuntimeError: ZOMG\n!!!!
|
137
143
|
|
138
|
-
|
139
|
-
|
144
|
+
# ~> RuntimeError
|
145
|
+
# ~> ZOMG
|
146
|
+
# ~> !!!!
|
147
|
+
# ~>
|
148
|
+
# ~> xmpfilter_error_on_unannotated_line.rb:1:in `<main>'
|
149
|
+
"""
|
140
150
|
|
141
151
|
|
142
152
|
Scenario: Cleaning previous output
|
@@ -34,7 +34,7 @@ class SeeingIsBelieving
|
|
34
34
|
end
|
35
35
|
|
36
36
|
if options.print_cleaned?
|
37
|
-
stdout.print RemoveAnnotations.call(options.prepared_body, true, options.
|
37
|
+
stdout.print RemoveAnnotations.call(options.prepared_body, true, options.marker_regexes)
|
38
38
|
return SUCCESS_STATUS
|
39
39
|
end
|
40
40
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
class SeeingIsBelieving
|
2
2
|
module Binary
|
3
3
|
class AnnotateEveryLine
|
4
|
-
def self.prepare_body(uncleaned_body,
|
4
|
+
def self.prepare_body(uncleaned_body, marker_regexes)
|
5
5
|
require 'seeing_is_believing/binary/remove_annotations'
|
6
|
-
RemoveAnnotations.call uncleaned_body, true,
|
6
|
+
RemoveAnnotations.call uncleaned_body, true, marker_regexes
|
7
7
|
end
|
8
8
|
|
9
|
-
def self.expression_wrapper(markers)
|
9
|
+
def self.expression_wrapper(markers, marker_regexes)
|
10
10
|
require 'seeing_is_believing/inspect_expressions'
|
11
11
|
InspectExpressions
|
12
12
|
end
|
@@ -45,7 +45,7 @@ class SeeingIsBelieving
|
|
45
45
|
AnnotateEndOfFile.add_stdout_stderr_and_exceptions_to new_body, @results, @options
|
46
46
|
|
47
47
|
# What's w/ this debugger? maybe this should move higher?
|
48
|
-
@options
|
48
|
+
@options.fetch(:debugger).context "OUTPUT"
|
49
49
|
new_body
|
50
50
|
end
|
51
51
|
end
|
@@ -53,11 +53,11 @@ class SeeingIsBelieving
|
|
53
53
|
private
|
54
54
|
|
55
55
|
def value_marker
|
56
|
-
@value_marker ||= @options
|
56
|
+
@value_marker ||= @options.fetch(:markers).fetch(:value)
|
57
57
|
end
|
58
58
|
|
59
59
|
def exception_marker
|
60
|
-
@
|
60
|
+
@xnextline_marker ||= @options.fetch(:markers).fetch(:exception)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -3,34 +3,17 @@ require 'seeing_is_believing/code'
|
|
3
3
|
class SeeingIsBelieving
|
4
4
|
module Binary
|
5
5
|
class AnnotateXmpfilterStyle
|
6
|
-
def self.prepare_body(uncleaned_body,
|
7
|
-
# TODO: There's definitely a lot of overlap in responsibilities with invoking of parser
|
8
|
-
# and this is a conspicuous hack, since this functionality should really be provided by RemoveAnnotations
|
9
|
-
code = Code.new(uncleaned_body)
|
10
|
-
code.inline_comments
|
11
|
-
.select { |c| c.whitespace_col == 0 } # TODO: Would be nice to support indentation here
|
12
|
-
.slice_before { |c| c.text.start_with? markers[:value] }
|
13
|
-
.flat_map { |cs|
|
14
|
-
consecutives = cs.each_cons(2).take_while { |c1, c2| c1.line_number.next == c2.line_number }
|
15
|
-
cs[1, consecutives.size]
|
16
|
-
}
|
17
|
-
.select { |c| c.text.start_with? markers[:nextline] }
|
18
|
-
.each { |c|
|
19
|
-
range_with_preceding_newline = code.range_for(c.comment_range.begin_pos.pred, c.comment_range.end_pos)
|
20
|
-
code.rewriter.remove range_with_preceding_newline
|
21
|
-
}
|
22
|
-
partially_cleaned_body = code.rewriter.process
|
23
|
-
|
6
|
+
def self.prepare_body(uncleaned_body, marker_regexes)
|
24
7
|
require 'seeing_is_believing/binary/remove_annotations'
|
25
|
-
RemoveAnnotations.call
|
8
|
+
RemoveAnnotations.call uncleaned_body, false, marker_regexes
|
26
9
|
end
|
27
10
|
|
28
|
-
def self.expression_wrapper(markers)
|
11
|
+
def self.expression_wrapper(markers, marker_regexes)
|
29
12
|
-> program, number_of_captures {
|
30
13
|
inspect_linenos = []
|
31
14
|
pp_linenos = []
|
32
15
|
Code.new(program).inline_comments.each do |c|
|
33
|
-
next unless c.text
|
16
|
+
next unless c.text[marker_regexes[:value]]
|
34
17
|
c.whitespace_col == 0 ? pp_linenos << c.line_number - 1
|
35
18
|
: inspect_linenos << c.line_number
|
36
19
|
end
|
@@ -73,14 +56,33 @@ class SeeingIsBelieving
|
|
73
56
|
def call
|
74
57
|
@new_body ||= begin
|
75
58
|
# TODO: doesn't currently realign output markers, do we want to do that?
|
76
|
-
require 'seeing_is_believing/binary' # defines the markers
|
77
59
|
require 'seeing_is_believing/binary/rewrite_comments'
|
78
60
|
require 'seeing_is_believing/binary/comment_formatter'
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
61
|
+
always_rewrite = []
|
62
|
+
|
63
|
+
if @results.has_exception?
|
64
|
+
exception_result = sprintf "%s: %s", @results.exception.class_name, @results.exception.message.gsub("\n", '\n')
|
65
|
+
exception_lineno = @results.exception.line_number
|
66
|
+
always_rewrite << exception_lineno
|
67
|
+
end
|
68
|
+
|
69
|
+
new_body = RewriteComments.call @body, always_rewrite: always_rewrite do |comment|
|
70
|
+
exception_on_line = exception_lineno == comment.line_number
|
71
|
+
annotate_this_line = comment.text[value_regex]
|
72
|
+
pp_annotation = annotate_this_line && comment.whitespace_col.zero?
|
73
|
+
normal_annotation = annotate_this_line && !pp_annotation
|
74
|
+
if exception_on_line && annotate_this_line
|
75
|
+
[comment.whitespace, CommentFormatter.call(comment.text_col, value_marker, exception_result, @options)]
|
76
|
+
elsif exception_on_line
|
77
|
+
whitespace = comment.whitespace
|
78
|
+
whitespace = " " if whitespace.empty?
|
79
|
+
[whitespace, CommentFormatter.call(comment.line_number, exception_marker, exception_result, @options)]
|
80
|
+
elsif normal_annotation
|
81
|
+
result = @results[comment.line_number].map { |result| result.gsub "\n", '\n' }.join(', ')
|
82
|
+
[comment.whitespace, CommentFormatter.call(comment.text_col, value_marker, result, @options)]
|
83
|
+
elsif pp_annotation
|
84
|
+
# result = sprintf "%s: %s", @results.exception.class_name, @results.exception.message.gsub("\n", '\n')
|
85
|
+
# CommentFormatter.call(line.size, exception_marker, result, options)
|
84
86
|
# TODO: check that having multiple mult-line output values here looks good (e.g. avdi's example in a loop)
|
85
87
|
result = @results[comment.line_number-1, :pp].map { |result| result.chomp }.join(', ')
|
86
88
|
comment_lines = result.each_line.map.with_index do |comment_line, result_offest|
|
@@ -92,41 +94,33 @@ class SeeingIsBelieving
|
|
92
94
|
end
|
93
95
|
[comment.whitespace, comment_lines.join("\n")]
|
94
96
|
else
|
95
|
-
|
96
|
-
[comment.whitespace, CommentFormatter.call(comment.text_col, value_marker, result, @options)]
|
97
|
+
[comment.whitespace, comment.text]
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
100
|
-
# if exception_lineno == line_number
|
101
|
-
# if comment.text[value_regex] # has exception and comment
|
102
|
-
# # '# => # ~> exception...'
|
103
|
-
# [comment.whitespace, comment.text]
|
104
|
-
# else # exception, no comment
|
105
|
-
# # NORMAL EXCEPTION
|
106
|
-
# # result = @results[line_number].map { |result| result.gsub "\n", '\n' }.join(', ')
|
107
|
-
# # CommentFormatter.call(line.size, value_marker, result, options)
|
108
|
-
# # [comment.whitespace, comment.text]
|
109
|
-
# end
|
110
|
-
|
111
101
|
require 'seeing_is_believing/binary/annotate_end_of_file'
|
112
102
|
AnnotateEndOfFile.add_stdout_stderr_and_exceptions_to new_body, @results, @options
|
113
103
|
|
114
104
|
# What's w/ this debugger? maybe this should move higher?
|
115
|
-
@options
|
105
|
+
@options.fetch(:debugger).context "OUTPUT"
|
116
106
|
new_body
|
117
107
|
end
|
118
108
|
end
|
119
109
|
|
120
110
|
def value_marker
|
121
|
-
@value_marker ||= @options
|
111
|
+
@value_marker ||= @options.fetch(:markers).fetch(:value)
|
122
112
|
end
|
123
113
|
|
124
114
|
def nextline_marker
|
125
|
-
@xnextline_marker ||=
|
115
|
+
@xnextline_marker ||= ('#' + ' '*value_marker.size.pred)
|
116
|
+
end
|
117
|
+
|
118
|
+
def exception_marker
|
119
|
+
@exception_marker ||= @options.fetch(:markers).fetch(:exception)
|
126
120
|
end
|
127
121
|
|
128
122
|
def value_regex
|
129
|
-
@value_regex ||=
|
123
|
+
@value_regex ||= @options.fetch(:marker_regexes).fetch(:value)
|
130
124
|
end
|
131
125
|
end
|
132
126
|
end
|
@@ -17,6 +17,14 @@ require 'seeing_is_believing/binary/annotate_xmpfilter_style'
|
|
17
17
|
class SeeingIsBelieving
|
18
18
|
module Binary
|
19
19
|
class InterpretFlags
|
20
|
+
def self.to_regex(string)
|
21
|
+
flag_to_bit = {'i' => 0b001, 'x' => 0b010, 'm' => 0b100}
|
22
|
+
string =~ %r{\A/(.*)/([mxi]*)\Z}
|
23
|
+
Regexp.new ($1||string),
|
24
|
+
($2||"").each_char.inject(0) { |bits, flag| bits|flag_to_bit[flag] }
|
25
|
+
end
|
26
|
+
|
27
|
+
|
20
28
|
def self.attr_predicate(name)
|
21
29
|
define_method("#{name}?") { predicates.fetch name }
|
22
30
|
end
|
@@ -35,6 +43,7 @@ class SeeingIsBelieving
|
|
35
43
|
attr_attribute :help_screen
|
36
44
|
attr_attribute :debugger
|
37
45
|
attr_attribute :markers
|
46
|
+
attr_attribute :marker_regexes
|
38
47
|
attr_attribute :timeout
|
39
48
|
attr_attribute :shebang
|
40
49
|
attr_attribute :filename
|
@@ -47,11 +56,12 @@ class SeeingIsBelieving
|
|
47
56
|
def initialize(flags, stdin, stdout)
|
48
57
|
# Some simple attributes
|
49
58
|
self.attributes = {}
|
50
|
-
attributes[:errors]
|
51
|
-
attributes[:markers]
|
52
|
-
attributes[:
|
53
|
-
attributes[:
|
54
|
-
attributes[:
|
59
|
+
attributes[:errors] = flags.fetch(:errors)
|
60
|
+
attributes[:markers] = flags.fetch(:markers) # TODO: Should probably object-ify these
|
61
|
+
attributes[:marker_regexes] = flags.fetch(:marker_regexes).each_with_object({}) { |(k, v), rs| rs[k] = self.class.to_regex v }
|
62
|
+
attributes[:timeout] = flags.fetch(:timeout) # b/c binary prints this out in the error message TODO: rename seconds_until_timeout
|
63
|
+
attributes[:shebang] = flags.fetch(:shebang) # b/c binary uses this to validate syntax atm
|
64
|
+
attributes[:filename] = flags.fetch(:filename)
|
55
65
|
|
56
66
|
# All predicates
|
57
67
|
self.predicates = {}
|
@@ -74,7 +84,7 @@ class SeeingIsBelieving
|
|
74
84
|
String.new
|
75
85
|
|
76
86
|
# Attributes that depend on predicates
|
77
|
-
attributes[:prepared_body] = body && annotator.prepare_body(body,
|
87
|
+
attributes[:prepared_body] = body && annotator.prepare_body(body, marker_regexes)
|
78
88
|
|
79
89
|
# The lib's options (passed to SeeingIsBelieving.new)
|
80
90
|
attributes[:lib_options] = {
|
@@ -88,7 +98,7 @@ class SeeingIsBelieving
|
|
88
98
|
timeout: timeout,
|
89
99
|
debugger: debugger,
|
90
100
|
number_of_captures: flags.fetch(:number_of_captures), # TODO: Rename to max_number_of_captures
|
91
|
-
record_expressions: annotator.expression_wrapper(markers), # TODO: rename to wrap_expressions
|
101
|
+
record_expressions: annotator.expression_wrapper(markers, marker_regexes), # TODO: rename to wrap_expressions
|
92
102
|
}
|
93
103
|
|
94
104
|
# The annotator's options (passed to annotator.call)
|
@@ -96,6 +106,7 @@ class SeeingIsBelieving
|
|
96
106
|
alignment_strategy: extract_alignment_strategy(flags.fetch(:alignment_strategy), errors),
|
97
107
|
debugger: debugger,
|
98
108
|
markers: markers,
|
109
|
+
marker_regexes: marker_regexes,
|
99
110
|
max_line_length: flags.fetch(:max_line_length),
|
100
111
|
max_result_length: flags.fetch(:max_result_length),
|
101
112
|
}
|
@@ -10,7 +10,15 @@ class SeeingIsBelieving
|
|
10
10
|
exception: '# ~> ',
|
11
11
|
stdout: '# >> ',
|
12
12
|
stderr: '# !> ',
|
13
|
-
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
# TODO: rename to default_marker_regexes ...or turn into fkn objects
|
17
|
+
def self.marker_regexes
|
18
|
+
{ value: '#\s*=>\s*',
|
19
|
+
exception: '#\s*~>\s*',
|
20
|
+
stdout: '#\s*>>\s*',
|
21
|
+
stderr: '#\s*!>\s*',
|
14
22
|
}
|
15
23
|
end
|
16
24
|
|
@@ -88,6 +96,7 @@ class SeeingIsBelieving
|
|
88
96
|
shebang: 'ruby',
|
89
97
|
result_as_json: false,
|
90
98
|
markers: self.class.default_markers,
|
99
|
+
marker_regexes: self.class.marker_regexes,
|
91
100
|
short_help_screen: self.class.help_screen(false),
|
92
101
|
long_help_screen: self.class.help_screen(true),
|
93
102
|
safe: false,
|
@@ -133,7 +142,6 @@ class SeeingIsBelieving
|
|
133
142
|
exception_marker = markers.fetch(:exception)
|
134
143
|
stdout_marker = markers.fetch(:stdout)
|
135
144
|
stderr_marker = markers.fetch(:stderr)
|
136
|
-
nextline_marker = markers.fetch(:nextline)
|
137
145
|
|
138
146
|
<<FLAGS + if include_examples then <<EXAMPLES else '' end
|
139
147
|
Usage: seeing_is_believing [options] [filename]
|
@@ -3,60 +3,53 @@ require 'seeing_is_believing/parser_helpers' # We have to parse the file to find
|
|
3
3
|
|
4
4
|
class SeeingIsBelieving
|
5
5
|
module Binary
|
6
|
+
# TODO: might be here that we hit the issue where
|
7
|
+
# you sometimes have to run it 2x to get it to correctly reset whitespace
|
8
|
+
# should wipe out the full_range rather than just the comment_range
|
6
9
|
class RemoveAnnotations
|
7
|
-
def self.call(
|
8
|
-
new(
|
10
|
+
def self.call(raw_code, should_clean_values, markers)
|
11
|
+
new(raw_code, should_clean_values, markers).call
|
9
12
|
end
|
10
13
|
|
11
|
-
def initialize(
|
14
|
+
def initialize(raw_code, should_clean_values, markers)
|
12
15
|
self.should_clean_values = should_clean_values
|
13
|
-
self.
|
14
|
-
self.markers = markers
|
16
|
+
self.raw_code = raw_code
|
17
|
+
self.markers = markers # TECHNICALLY THESE ARE REGEXES RIGHT NOW
|
18
|
+
self.code = Code.new(raw_code, 'strip_comments')
|
15
19
|
end
|
16
20
|
|
17
21
|
def call
|
18
|
-
|
19
|
-
|
22
|
+
annotation_chunks_in(code).each do |comment, rest|
|
23
|
+
rest.each { |comment|
|
24
|
+
code.rewriter.remove comment.comment_range
|
25
|
+
remove_whitespace_before comment.comment_range.begin_pos, code.buffer, code.rewriter, false
|
26
|
+
}
|
20
27
|
|
21
|
-
# TODO: This is why you sometimes have to run it 2x to get it to correctly reset whitespace
|
22
|
-
# should wipe out the full_range rather than just the comment_range
|
23
|
-
code_obj.inline_comments.each do |comment|
|
24
28
|
case comment.text
|
25
29
|
when value_regex
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
code_obj.rewriter.remove comment.comment_range
|
30
|
-
end
|
30
|
+
next unless should_clean_values
|
31
|
+
code.rewriter.remove comment.comment_range
|
32
|
+
remove_whitespace_before comment.comment_range.begin_pos, code.buffer, code.rewriter, false
|
31
33
|
when exception_regex
|
32
|
-
|
33
|
-
|
34
|
-
code_obj.rewriter.remove comment.comment_range
|
34
|
+
code.rewriter.remove comment.comment_range
|
35
|
+
remove_whitespace_before comment.comment_range.begin_pos, code.buffer, code.rewriter, true
|
35
36
|
when stdout_regex
|
36
|
-
|
37
|
-
|
38
|
-
code_obj.rewriter.remove comment.comment_range
|
37
|
+
code.rewriter.remove comment.comment_range
|
38
|
+
remove_whitespace_before comment.comment_range.begin_pos, code.buffer, code.rewriter, true
|
39
39
|
when stderr_regex
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
code.rewriter.remove comment.comment_range
|
41
|
+
remove_whitespace_before comment.comment_range.begin_pos, code.buffer, code.rewriter, true
|
42
|
+
else
|
43
|
+
raise "This should be impossible! Something must be broken in the comment section above"
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
-
code_obj.rewriter.process
|
47
|
+
code.rewriter.process
|
48
48
|
end
|
49
49
|
|
50
50
|
private
|
51
51
|
|
52
|
-
attr_accessor :
|
53
|
-
|
54
|
-
def remove_whitespace_preceding_comments(buffer, rewriter, removed_comments)
|
55
|
-
removed_comments[:result].each { |comment| remove_whitespace_before comment.comment_range.begin_pos, buffer, rewriter, false }
|
56
|
-
removed_comments[:exception].each { |comment| remove_whitespace_before comment.comment_range.begin_pos, buffer, rewriter, true }
|
57
|
-
removed_comments[:stdout].each { |comment| remove_whitespace_before comment.comment_range.begin_pos, buffer, rewriter, true }
|
58
|
-
removed_comments[:stderr].each { |comment| remove_whitespace_before comment.comment_range.begin_pos, buffer, rewriter, true }
|
59
|
-
end
|
52
|
+
attr_accessor :raw_code, :should_clean_values, :markers, :code
|
60
53
|
|
61
54
|
# any whitespace before the index (on the same line) will be removed
|
62
55
|
# if the preceding whitespace is at the beginning of the line, the newline will be removed
|
@@ -64,31 +57,57 @@ class SeeingIsBelieving
|
|
64
57
|
def remove_whitespace_before(index, buffer, rewriter, remove_preceding_newline)
|
65
58
|
end_pos = index
|
66
59
|
begin_pos = end_pos - 1
|
67
|
-
begin_pos -= 1 while
|
68
|
-
begin_pos -= 1 if
|
69
|
-
begin_pos -= 1 if
|
60
|
+
begin_pos -= 1 while raw_code[begin_pos] =~ /\s/ && raw_code[begin_pos] != "\n"
|
61
|
+
begin_pos -= 1 if raw_code[begin_pos] == "\n"
|
62
|
+
begin_pos -= 1 if raw_code[begin_pos] == "\n" && remove_preceding_newline
|
70
63
|
return if begin_pos.next == end_pos
|
71
64
|
rewriter.remove Parser::Source::Range.new(buffer, begin_pos.next, end_pos)
|
72
65
|
end
|
73
66
|
|
67
|
+
def annotation_chunks_in(code)
|
68
|
+
code
|
69
|
+
.inline_comments
|
70
|
+
.map { |comment| [ (comment.text[value_regex] || # associates each comment to its annotation
|
71
|
+
comment.text[exception_regex] ||
|
72
|
+
comment.text[stdout_regex] ||
|
73
|
+
comment.text[stderr_regex]
|
74
|
+
),
|
75
|
+
comment]}
|
76
|
+
.slice_before { |annotation, comment| annotation } # annotatios begin chunks
|
77
|
+
.select { |(annotation, start), *| annotation } # discard chunks not beginning with an annotation (probably can only happens on first comment)
|
78
|
+
.map { |(annotation, start), *rest| # end the chunk if the comment doesn't meet nextline criteria
|
79
|
+
nextline_comments = []
|
80
|
+
prev = start
|
81
|
+
rest.each { |_, potential_nextline|
|
82
|
+
break unless prev.line_number.next == potential_nextline.line_number &&
|
83
|
+
start.text_col == potential_nextline.text_col &&
|
84
|
+
potential_nextline.whitespace_col.zero? &&
|
85
|
+
annotation.length <= potential_nextline.text[/#\s*/].length
|
86
|
+
prev = potential_nextline
|
87
|
+
nextline_comments << potential_nextline
|
88
|
+
}
|
89
|
+
[start, nextline_comments]
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
74
93
|
def value_regex
|
75
|
-
|
94
|
+
markers.fetch(:value)
|
76
95
|
end
|
77
96
|
|
78
97
|
def exception_regex
|
79
|
-
|
98
|
+
markers.fetch(:exception)
|
80
99
|
end
|
81
100
|
|
82
101
|
def stdout_regex
|
83
|
-
|
102
|
+
markers.fetch(:stdout)
|
84
103
|
end
|
85
104
|
|
86
105
|
def stderr_regex
|
87
|
-
|
106
|
+
markers.fetch(:stderr)
|
88
107
|
end
|
89
108
|
|
90
|
-
def
|
91
|
-
|
109
|
+
def nextline_regex
|
110
|
+
markers.fetch(:nextline)
|
92
111
|
end
|
93
112
|
end
|
94
113
|
end
|
@@ -3,15 +3,61 @@ require 'seeing_is_believing/code'
|
|
3
3
|
class SeeingIsBelieving
|
4
4
|
module Binary
|
5
5
|
module RewriteComments
|
6
|
-
def self.call(code, &mapping)
|
7
|
-
code
|
8
|
-
code.inline_comments
|
6
|
+
def self.call(code, options={}, &mapping)
|
7
|
+
code = Code.new(code)
|
8
|
+
comments = code.inline_comments
|
9
|
+
buffer = code.buffer
|
10
|
+
|
11
|
+
comments.each do |comment|
|
9
12
|
new_whitespace, new_comment = mapping.call comment
|
10
13
|
code.rewriter.replace comment.whitespace_range, new_whitespace
|
11
14
|
code.rewriter.replace comment.comment_range, new_comment
|
12
15
|
end
|
16
|
+
|
17
|
+
line_begins = line_begins_for(buffer.source)
|
18
|
+
options.fetch(:always_rewrite, []).each { |line_number|
|
19
|
+
next if comments.any? { |c| c.line_number == line_number }
|
20
|
+
|
21
|
+
# TODO: can this move down into Code?
|
22
|
+
_, next_line_index = (line_begins.find { |ln, index| ln == line_number } || [nil, buffer.source.size.next])
|
23
|
+
col = 0
|
24
|
+
col += 1 until col == next_line_index || buffer.source[next_line_index-2-col] == "\n"
|
25
|
+
|
26
|
+
index = next_line_index - 1
|
27
|
+
range = Parser::Source::Range.new buffer, index, index
|
28
|
+
|
29
|
+
comment = Code::InlineComment.new line_number, # line_number,
|
30
|
+
col, # preceding_whitespace_range.column,
|
31
|
+
"", # preceding_whitespace,
|
32
|
+
col, # comment.location.column,
|
33
|
+
"", # comment.text,
|
34
|
+
range, # range_for(first_char, comment.location.expression.end_pos),
|
35
|
+
range, # preceding_whitespace_range,
|
36
|
+
range # comment.location.expression
|
37
|
+
|
38
|
+
whitespace, body = mapping.call comment
|
39
|
+
code.rewriter.insert_before range, "#{whitespace}#{body}"
|
40
|
+
}
|
41
|
+
|
13
42
|
code.rewriter.process
|
14
43
|
end
|
44
|
+
|
45
|
+
# TODO: Move down into the Code obj?
|
46
|
+
# returns: [[lineno, index], ...]
|
47
|
+
def self.line_begins_for(raw_code)
|
48
|
+
# Copied from here https://github.com/whitequark/parser/blob/34c40479293bb9b5ba217039cf349111466d1f9a/lib/parser/source/buffer.rb#L213-227
|
49
|
+
# I figured it's better to copy it than to violate encapsulation since this is private
|
50
|
+
line_begins, index = [ [ 0, 0 ] ], 1
|
51
|
+
|
52
|
+
raw_code.each_char do |char|
|
53
|
+
if char == "\n"
|
54
|
+
line_begins.unshift [ line_begins.length, index ]
|
55
|
+
end
|
56
|
+
|
57
|
+
index += 1
|
58
|
+
end
|
59
|
+
line_begins
|
60
|
+
end
|
15
61
|
end
|
16
62
|
end
|
17
63
|
end
|
@@ -27,7 +27,7 @@ class SeeingIsBelieving
|
|
27
27
|
|
28
28
|
def call
|
29
29
|
@called ||= begin
|
30
|
-
|
30
|
+
wrap_recursive
|
31
31
|
|
32
32
|
rewriter.insert_before root_range, before_all.call
|
33
33
|
|
@@ -81,19 +81,19 @@ class SeeingIsBelieving
|
|
81
81
|
|
82
82
|
def add_children(ast, omit_first = false)
|
83
83
|
(omit_first ? ast.children.drop(1) : ast.children)
|
84
|
-
.each { |child|
|
84
|
+
.each { |child| wrap_recursive child }
|
85
85
|
end
|
86
86
|
|
87
|
-
|
87
|
+
# todo: is this actually add_wrappings
|
88
|
+
# and add_wrappings is actually add_wrapping?
|
89
|
+
def wrap_recursive(ast=root)
|
88
90
|
return wrappings unless ast.kind_of? ::AST::Node
|
89
|
-
|
90
91
|
case ast.type
|
91
92
|
when :args, :redo, :retry, :alias, :undef, :splat, :match_current_line
|
92
93
|
# no op
|
93
94
|
when :defs
|
94
95
|
add_to_wrappings ast
|
95
|
-
|
96
|
-
add_to_wrappings child if child
|
96
|
+
add_children ast, true
|
97
97
|
when :rescue, :ensure, :return, :break, :next
|
98
98
|
add_children ast
|
99
99
|
when :if
|
@@ -108,10 +108,10 @@ class SeeingIsBelieving
|
|
108
108
|
add_children ast
|
109
109
|
end
|
110
110
|
when :when, :pair, :class, :module, :sclass
|
111
|
-
|
111
|
+
wrap_recursive ast.children.last
|
112
112
|
when :resbody
|
113
113
|
exception_type, variable_name, body = ast.children
|
114
|
-
|
114
|
+
wrap_recursive body
|
115
115
|
when :array
|
116
116
|
add_to_wrappings ast
|
117
117
|
the_begin = ast.location.begin
|
@@ -136,7 +136,7 @@ class SeeingIsBelieving
|
|
136
136
|
# I can't think of anything other than a :send that could be the first child
|
137
137
|
# but I'll check for it anyway.
|
138
138
|
the_send = ast.children[0]
|
139
|
-
|
139
|
+
wrap_recursive the_send.children.first if the_send.type == :send
|
140
140
|
add_children ast, true
|
141
141
|
when :masgn
|
142
142
|
# we must look at RHS because [1,<<A] and 1,<<A are both allowed
|
@@ -24,6 +24,45 @@ class SeeingIsBelieving
|
|
24
24
|
InterpretFlags.new(flags.merge(overrides), stdin, stdout)
|
25
25
|
end
|
26
26
|
|
27
|
+
describe '.to_regex' do
|
28
|
+
def call(input, regex)
|
29
|
+
expect(InterpretFlags.to_regex input).to eq regex
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'converts strings into regexes' do
|
33
|
+
call '', %r()
|
34
|
+
call 'a', %r(a)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'ignores surrounding slashes' do
|
38
|
+
call '//', %r()
|
39
|
+
call '/a/', %r(a)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'respects flags after the trailing slash in surrounding slashes' do
|
43
|
+
call '/a/', %r(a)
|
44
|
+
call '/a//', %r(a/)
|
45
|
+
call '//a/', %r(/a)
|
46
|
+
call '/a/i', %r(a)i
|
47
|
+
call '/a/im', %r(a)im
|
48
|
+
call '/a/xim', %r(a)xim
|
49
|
+
call '/a/mix', %r(a)mix
|
50
|
+
call '/a/mixi', %r(a)mixi
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'isn\'t fooled by strings that kinda look regexy' do
|
54
|
+
call '/a', %r(/a)
|
55
|
+
call 'a/', %r(a/)
|
56
|
+
call '/', %r(/)
|
57
|
+
call '/i', %r(/i)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not escape the content' do
|
61
|
+
call 'a\\s+', %r(a\s+)
|
62
|
+
call '/a\\s+/', %r(a\s+)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
27
66
|
describe 'annotator' do
|
28
67
|
it 'annotates every line by default' do
|
29
68
|
expect(call.annotator).to eq AnnotateEveryLine
|
@@ -380,8 +380,8 @@ RSpec.describe SeeingIsBelieving::Binary::ParseArgs do
|
|
380
380
|
end
|
381
381
|
|
382
382
|
describe ':markers' do
|
383
|
-
it 'defaults to a hash with :value, :exception, :stdout,
|
384
|
-
expect(parse([])[:markers].keys).to eq [:value, :exception, :stdout, :stderr
|
383
|
+
it 'defaults to a hash with :value, :exception, :stdout, and :stderr' do
|
384
|
+
expect(parse([])[:markers].keys).to eq [:value, :exception, :stdout, :stderr]
|
385
385
|
end
|
386
386
|
|
387
387
|
def assert_default(marker_name, value)
|
@@ -392,14 +392,25 @@ RSpec.describe SeeingIsBelieving::Binary::ParseArgs do
|
|
392
392
|
it('defaults :exception to "# ~> "') { assert_default :exception , "# ~> " }
|
393
393
|
it('defaults :stdout to "# >> "') { assert_default :stdout , "# >> " }
|
394
394
|
it('defaults :stderr to "# !> "') { assert_default :stderr , "# !> " }
|
395
|
-
it('defaults :nextline to "# "') { assert_default :nextline , "# " }
|
396
395
|
|
397
396
|
# TODO: When things get a little more stable, don't feel like adding all the cukes to play with this right now
|
398
397
|
it 'overrides :value with --value-marker'
|
399
398
|
it 'overrides :exception with --exception-marker'
|
400
399
|
it 'overrides :stdout with --stdout-marker'
|
401
400
|
it 'overrides :stderr with --stderr-marker'
|
402
|
-
|
401
|
+
end
|
402
|
+
|
403
|
+
describe ':marker_regexes' do
|
404
|
+
it 'is a hash with the same keys as the markers' do
|
405
|
+
marker_keys = parse([])[:markers].keys
|
406
|
+
marker_regexes_keys = parse([])[:marker_regexes].keys
|
407
|
+
expect(marker_regexes_keys).to eq marker_keys
|
408
|
+
end
|
409
|
+
|
410
|
+
it 'overrides :value with --value-regex'
|
411
|
+
it 'overrides :exception with --exception-regex'
|
412
|
+
it 'overrides :stdout with --stdout-regex'
|
413
|
+
it 'overrides :stderr with --stderr-regex'
|
403
414
|
end
|
404
415
|
end
|
405
416
|
|
@@ -1,51 +1,155 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'seeing_is_believing/binary/remove_annotations'
|
3
|
+
require 'seeing_is_believing/binary/parse_args' # for marker info
|
3
4
|
|
4
5
|
RSpec.describe SeeingIsBelieving::Binary::RemoveAnnotations do
|
5
6
|
def call(code, should_clean_values=true)
|
6
7
|
indentation = code[/\A */]
|
7
8
|
code = code.gsub /^#{indentation}/, ''
|
8
|
-
described_class.call(code,
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
described_class.call(code, should_clean_values, regexes).chomp
|
10
|
+
end
|
11
|
+
|
12
|
+
def regexes
|
13
|
+
SeeingIsBelieving::Binary::ParseArgs
|
14
|
+
.marker_regexes
|
15
|
+
.each_with_object({}) { |(name, str), rs| rs[name] = Regexp.new str }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when there are lines that are just normal comments' do
|
19
|
+
example { expect(call "1 # hello").to eq "1 # hello" }
|
20
|
+
example { expect(call "1 # hello\n"\
|
21
|
+
"# world").to eq "1 # hello\n"\
|
22
|
+
"# world" }
|
23
|
+
example { expect(call "1 # not special\n"\
|
24
|
+
"2 # => 3").to eq "1 # not special\n2" }
|
16
25
|
end
|
17
26
|
|
18
27
|
context 'when told to clean out value annotations' do
|
19
|
-
example { expect(call "1# => 1",
|
20
|
-
example { expect(call "1 # => 1",
|
21
|
-
example { expect(call "1 # => 1",
|
22
|
-
example { expect(call "1 # => 1",
|
23
|
-
example { expect(call "1 # => 1",
|
24
|
-
example { expect(call "1 # => 1",
|
28
|
+
example { expect(call "1# => 1", true).to eq "1" }
|
29
|
+
example { expect(call "1 # => 1", true).to eq "1" }
|
30
|
+
example { expect(call "1 # => 1", true).to eq "1" }
|
31
|
+
example { expect(call "1 # => 1", true).to eq "1" }
|
32
|
+
example { expect(call "1 # => 1", true).to eq "1" }
|
33
|
+
example { expect(call "1 # => 1", true).to eq "1" }
|
25
34
|
example { expect(call "\n1 # => 1", true).to eq "\n1" }
|
26
35
|
end
|
27
36
|
|
28
37
|
context 'when told not to clean out value annotations' do
|
29
|
-
example { expect(call "1# => 1",
|
30
|
-
example { expect(call "1 # => 1",
|
31
|
-
example { expect(call "1 # => 1",
|
32
|
-
example { expect(call "1 # => 1",
|
33
|
-
example { expect(call "1 # => 1",
|
34
|
-
example { expect(call "1 # => 1",
|
38
|
+
example { expect(call "1# => 1", false).to eq "1# => 1" }
|
39
|
+
example { expect(call "1 # => 1", false).to eq "1 # => 1" }
|
40
|
+
example { expect(call "1 # => 1", false).to eq "1 # => 1" }
|
41
|
+
example { expect(call "1 # => 1", false).to eq "1 # => 1" }
|
42
|
+
example { expect(call "1 # => 1", false).to eq "1 # => 1" }
|
43
|
+
example { expect(call "1 # => 1", false).to eq "1 # => 1" }
|
35
44
|
example { expect(call "\n1 # => 1", false).to eq "\n1 # => 1" }
|
36
45
|
end
|
37
46
|
|
38
47
|
context 'cleaning inline exception annotations' do
|
39
|
-
example { expect(call "1# ~> 1"
|
40
|
-
example { expect(call "1 # ~> 1"
|
41
|
-
example { expect(call "1 # ~> 1"
|
42
|
-
example { expect(call "1 # ~> 1"
|
43
|
-
example { expect(call "1 # ~> 1"
|
44
|
-
example { expect(call "1 # ~> 1"
|
48
|
+
example { expect(call "1# ~> 1" ).to eq "1" }
|
49
|
+
example { expect(call "1 # ~> 1" ).to eq "1" }
|
50
|
+
example { expect(call "1 # ~> 1" ).to eq "1" }
|
51
|
+
example { expect(call "1 # ~> 1" ).to eq "1" }
|
52
|
+
example { expect(call "1 # ~> 1").to eq "1" }
|
53
|
+
example { expect(call "1 # ~> 1").to eq "1" }
|
45
54
|
example { expect(call "\n1 # ~> 1").to eq "\n1" }
|
46
55
|
|
47
|
-
example { expect(call "# >> 1").to eq ""
|
48
|
-
example { expect(call "# !> 1").to eq ""
|
56
|
+
example { expect(call "# >> 1").to eq "" }
|
57
|
+
example { expect(call "# !> 1").to eq "" }
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'cleaning multiline results' do
|
61
|
+
it 'cleans values whose hash and value locations exactly match the annotation on the line prior' do
|
62
|
+
expect(call "1# => 2\n"\
|
63
|
+
" # 3").to eq "1"
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'does not clean values where the comment appears at a different position' do
|
67
|
+
expect(call "1# => 2\n"\
|
68
|
+
"# 3").to eq "1\n"\
|
69
|
+
"# 3"
|
70
|
+
|
71
|
+
expect(call "1# => 2\n"\
|
72
|
+
" # 3").to eq "1\n"\
|
73
|
+
" # 3"
|
74
|
+
|
75
|
+
expect(call "1# => 2\n"\
|
76
|
+
"# 3").to eq "1\n"\
|
77
|
+
"# 3"
|
78
|
+
expect(call "1# => 2\n"\
|
79
|
+
" # 3").to eq "1\n"\
|
80
|
+
" # 3"
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'does not clean values where the nextline value appears before the initial annotation value' do
|
85
|
+
# does clean
|
86
|
+
expect(call "1# => 2\n"\
|
87
|
+
" # 3").to eq "1"
|
88
|
+
expect(call "1# => 2\n"\
|
89
|
+
" # 3").to eq "1"
|
90
|
+
|
91
|
+
# does not clean
|
92
|
+
expect(call "1# => 2\n"\
|
93
|
+
" # 3 4").to eq "1\n"\
|
94
|
+
" # 3 4"
|
95
|
+
expect(call "1# => 2\n"\
|
96
|
+
" # 3").to eq "1\n"\
|
97
|
+
" # 3"
|
98
|
+
expect(call "1# => 2\n"\
|
99
|
+
" # 3").to eq "1\n"\
|
100
|
+
" # 3"
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'does not clean values where there is content before the comment' do
|
104
|
+
expect(call "1# => 2\n"\
|
105
|
+
"3# 4").to eq "1\n"\
|
106
|
+
"3# 4"
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'cleans successive rows of these' do
|
110
|
+
expect(call "1# => 2\n"\
|
111
|
+
" # 3\n"\
|
112
|
+
" # 4" ).to eq "1"
|
113
|
+
expect(call "1# => 2\n"\
|
114
|
+
" # 3\n"\
|
115
|
+
" # 4\n"\
|
116
|
+
"5# => 6\n"\
|
117
|
+
" # 7\n"\
|
118
|
+
" # 8" ).to eq "1\n5"
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'does not clean values where there is non-annotation inbetween' do
|
122
|
+
expect(call "1# => 2\n"\
|
123
|
+
"# 3\n"\
|
124
|
+
" # 4").to eq "1\n"\
|
125
|
+
"# 3\n"\
|
126
|
+
" # 4"
|
127
|
+
|
128
|
+
expect(call "1# => 2\n"\
|
129
|
+
"3 \n"\
|
130
|
+
" # 4").to eq "1\n"\
|
131
|
+
"3 \n"\
|
132
|
+
" # 4"
|
133
|
+
expect(call "1# => 2\n"\
|
134
|
+
"# 3\n"\
|
135
|
+
" # 4").to eq "1\n"\
|
136
|
+
"# 3\n"\
|
137
|
+
" # 4"
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'cleans multiline portion, regardless of whether cleaning values (this is soooooo xmpfilter specific)' do
|
141
|
+
expect(call "1# => 2\n"\
|
142
|
+
" # 3").to eq "1"
|
143
|
+
|
144
|
+
expect(call "1# => 2\n"\
|
145
|
+
" # 3",
|
146
|
+
false).to eq "1# => 2"
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'works on inline exceptions' do
|
150
|
+
expect(call "1# ~> 2\n"\
|
151
|
+
" # 3").to eq "1"
|
152
|
+
end
|
49
153
|
end
|
50
154
|
|
51
155
|
context 'cleaning stdout annotations' do
|
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
require 'seeing_is_believing/binary/rewrite_comments'
|
3
3
|
|
4
4
|
RSpec.describe SeeingIsBelieving::Binary::RewriteComments do
|
5
|
-
def call(code, &block)
|
6
|
-
described_class.call code, &block
|
5
|
+
def call(code, options={}, &block)
|
6
|
+
described_class.call code, options, &block
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'ignores multiline comments' do
|
@@ -52,4 +52,40 @@ RSpec.describe SeeingIsBelieving::Binary::RewriteComments do
|
|
52
52
|
"%Q{\n"\
|
53
53
|
" 1}NEW_WHITESPACE6--COMMENT-6--"
|
54
54
|
end
|
55
|
+
|
56
|
+
it 'can be given additional lines to make sure are provided, whether they have comments on them or not' do
|
57
|
+
rewritten = call("'a'\n"\
|
58
|
+
"'b'\n"\
|
59
|
+
"'c' # c\n"\
|
60
|
+
"'d'",
|
61
|
+
always_rewrite: [2, 3]) do |c|
|
62
|
+
value = sprintf "%d|%d|%p|%d|%p|%d..%d|%d..%d|%d..%d",
|
63
|
+
c.line_number,
|
64
|
+
c.whitespace_col,
|
65
|
+
c.whitespace,
|
66
|
+
c.text_col,
|
67
|
+
c.text,
|
68
|
+
c.full_range.begin_pos,
|
69
|
+
c.full_range.end_pos,
|
70
|
+
c.whitespace_range.begin_pos,
|
71
|
+
c.whitespace_range.end_pos,
|
72
|
+
c.comment_range.begin_pos,
|
73
|
+
c.comment_range.end_pos
|
74
|
+
['pre', value]
|
75
|
+
end
|
76
|
+
expect(rewritten).to eq \
|
77
|
+
"'a'\n"\
|
78
|
+
"'b'pre2|3|\"\"|3|\"\"|7..7|7..7|7..7\n"\
|
79
|
+
"'c'pre3|3|\" \"|4|\"# c\"|11..15|11..12|12..15\n"\
|
80
|
+
"'d'"
|
81
|
+
|
82
|
+
rewritten = call("", always_rewrite: [1]) { |c| ['a', 'b'] }
|
83
|
+
expect(rewritten).to eq "ab"
|
84
|
+
|
85
|
+
rewritten = call("a", always_rewrite: [1]) { |c| ['b', 'c'] }
|
86
|
+
expect(rewritten).to eq "abc"
|
87
|
+
|
88
|
+
rewritten = call("a\n", always_rewrite: [1]) { |c| ['b', 'c'] }
|
89
|
+
expect(rewritten).to eq "abc\n"
|
90
|
+
end
|
55
91
|
end
|
@@ -17,8 +17,8 @@ RSpec.describe SeeingIsBelieving::WrapExpressions do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
describe 'wrapping the body' do
|
20
|
-
let(:options) { { before_all:
|
21
|
-
after_all:
|
20
|
+
let(:options) { { before_all: -> { "[".freeze },
|
21
|
+
after_all: -> { "]".freeze },
|
22
22
|
before_each: -> * { '<'.freeze },
|
23
23
|
after_each: -> * { '>'.freeze } } }
|
24
24
|
|
@@ -798,14 +798,16 @@ RSpec.describe SeeingIsBelieving::WrapExpressions do
|
|
798
798
|
expect(wrap("def a(b,c=1,*d,&e)\nend")).to eq "<def a(b,c=1,*d,&e)\nend>"
|
799
799
|
end
|
800
800
|
|
801
|
-
it 'wraps the body' do
|
801
|
+
it 'wraps the the body' do
|
802
802
|
expect(wrap("def a\n1\nend")).to eq "<def a\n<1>\nend>"
|
803
803
|
expect(wrap("def a()\n1\nend")).to eq "<def a()\n<1>\nend>"
|
804
|
+
expect(wrap("def a\n1\n2\nend")).to eq "<def a\n<1>\n<2>\nend>"
|
804
805
|
end
|
805
806
|
|
806
|
-
it '
|
807
|
+
it 'wraps singleton method definitions' do
|
807
808
|
expect(wrap("def a.b\n1\nend")).to eq "<def a.b\n<1>\nend>"
|
808
|
-
|
809
|
+
expect(wrap("def a.b()\n1\nend")).to eq "<def a.b()\n<1>\nend>"
|
810
|
+
expect(wrap("def a.b\n1\n2\nend")).to eq "<def a.b\n<1>\n<2>\nend>" # <-- seems redundant, but this was a regression
|
809
811
|
end
|
810
812
|
|
811
813
|
it 'wraps calls to yield' 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.beta.
|
4
|
+
version: 3.0.0.beta.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Cheek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eval_in
|
@@ -267,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
267
267
|
version: 1.3.1
|
268
268
|
requirements: []
|
269
269
|
rubyforge_project: seeing_is_believing
|
270
|
-
rubygems_version: 2.
|
270
|
+
rubygems_version: 2.0.14
|
271
271
|
signing_key:
|
272
272
|
specification_version: 4
|
273
273
|
summary: Records results of every line of code in your file
|
@@ -293,4 +293,3 @@ test_files:
|
|
293
293
|
- spec/seeing_is_believing_spec.rb
|
294
294
|
- spec/spec_helper.rb
|
295
295
|
- spec/wrap_expressions_spec.rb
|
296
|
-
has_rdoc:
|