seeing_is_believing 0.0.24 → 0.0.26

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dda86a6b926231e08234e6a6a7c7fde07d650888
4
+ data.tar.gz: 39ab6eff76179f074c4382d5ffef3d49683bc624
5
+ SHA512:
6
+ metadata.gz: c4ad0cc0e416f1c1e01b9650a6e5a2143dbeccb4c668478b179e2a3898b0b9655c5b920b334f69e7bce7d748b4204930ab9a5d376b51dc49b727399b40e6c875
7
+ data.tar.gz: c27f2c5220c0a9e6991384de68dc4c9e3de44f7de954356311fae9989b45d531240f40be3cb6ffca5536820967efd2123aa7353ec2f1cc474566120b634bf311
data/Readme.md CHANGED
@@ -146,8 +146,14 @@ Known Issues
146
146
  Todo
147
147
  ====
148
148
 
149
+ * Make a Lines class which is a collection of lines, responsible for managing the trailing newlines in Binary::PrintResultsNextToLines and SeeingIsBelieving/ExpressionList
150
+ * Add examples of invocations to the help screen
151
+ * Add xmpfilter option to sublime text
152
+ * Update TextMate examples to use same keys as sublime, add xmpfilter option on cmd+opt+N
149
153
  * Move as much of the SyntaxAnalyzer as possible over to Parser and ditch Ripper altogether
150
- * Refactor ExpressionList/SeeingIsBelieving to store lines in an array instead of as a string, so everyone doesn't magically need to know when to chomp
154
+ * print exceptions at the end of the file, too
155
+
156
+
151
157
 
152
158
  License
153
159
  =======
@@ -3,4 +3,4 @@
3
3
  $LOAD_PATH.unshift File.expand_path '../../lib', __FILE__
4
4
 
5
5
  require 'seeing_is_believing/binary'
6
- exit SeeingIsBelieving::Binary.new(ARGV, $stdin, $stdout, $stderr).exitstatus
6
+ exit SeeingIsBelieving::Binary.new(ARGV, $stdin, $stdout, $stderr).call
@@ -420,20 +420,32 @@ Feature: Using flags
420
420
  When I run "seeing_is_believing --inherit-exit-status exit_status_in_at_exit_block.rb"
421
421
  Then the exit status is 10
422
422
 
423
- @wip
423
+ # after making this use the parser instead of regexes, add a test showing that the line `"1 # =>"` does not get updated
424
424
  Scenario: --xmpfilter-style
425
425
  Given the file "magic_comments.rb":
426
426
  """
427
- 1# =>
428
- 1 # =>
427
+ 1+1# =>
428
+ 2+2 # => 10
429
+ "a
430
+ b" # =>
429
431
  1
432
+ "omg"
433
+ # =>
434
+ "omg2"
435
+ # => "not omg2"
430
436
  """
431
437
  When I run "seeing_is_believing --xmpfilter-style magic_comments.rb"
432
438
  Then stderr is empty
433
439
  And the exit status is 0
434
440
  And stdout is:
435
441
  """
436
- 1# => 1
437
- 1 # => 1
442
+ 1+1# => 2
443
+ 2+2 # => 4
444
+ "a
445
+ b" # => "a\n b"
438
446
  1
447
+ "omg"
448
+ # => "omg"
449
+ "omg2"
450
+ # => "omg2"
439
451
  """
@@ -60,3 +60,43 @@ Feature:
60
60
  m # => 1
61
61
  """
62
62
 
63
+ Scenario: comments aren't updated with values
64
+ Given the file "comments_arent_updated_with_values.rb":
65
+ """
66
+ 1 # some comment
67
+ 2 # some other comment
68
+ """
69
+ When I run "seeing_is_believing comments_arent_updated_with_values.rb"
70
+ Then stdout is:
71
+ """
72
+ 1 # some comment
73
+ 2 # some other comment
74
+ """
75
+
76
+ # NOTE: Don't change the body of this file, it's nondeterministic
77
+ # I have no idea why this particular string fucks Parser up, but other similar ones don't
78
+ # We can probably remove this once parser reaches 2.0.0, they've fixed this bug now.
79
+ Scenario: Parser correctly identify comments
80
+ Given the file "parser_bug.rb" "Class # whatever"
81
+ When I run "seeing_is_believing parser_bug.rb"
82
+ Then stdout is "Class # whatever"
83
+ Then stderr is empty
84
+ And the exit status is 0
85
+
86
+
87
+ Scenario: Modifying output doesn't fuck it up when passing it back again as input
88
+ Given the file "modified_result.rb":
89
+ """
90
+ 1
91
+ # >> stdout
92
+ 2
93
+ # !> stderr
94
+ __END__
95
+ """
96
+ When I run "seeing_is_believing modified_result.rb"
97
+ Then stdout is:
98
+ """
99
+ 1 # => 1
100
+ 2 # => 2
101
+ __END__
102
+ """
@@ -67,19 +67,21 @@ class SeeingIsBelieving
67
67
 
68
68
  def options
69
69
  @options ||= {
70
- version: false,
71
- clean: false,
72
- program: nil,
73
- filename: nil,
74
- start_line: 1,
75
- line_length: Float::INFINITY,
76
- end_line: Float::INFINITY,
77
- result_length: Float::INFINITY,
78
- timeout: 0, # timeout lib treats this as infinity
79
- errors: [],
80
- require: [],
81
- load_path: [],
82
- alignment_strategy: AlignChunk,
70
+ version: false,
71
+ clean: false,
72
+ xmpfilter_style: false,
73
+ inherit_exit_status: false,
74
+ program: nil,
75
+ filename: nil,
76
+ start_line: 1,
77
+ line_length: Float::INFINITY,
78
+ end_line: Float::INFINITY,
79
+ result_length: Float::INFINITY,
80
+ timeout: 0, # timeout lib treats this as infinity
81
+ errors: [],
82
+ require: [],
83
+ load_path: [],
84
+ alignment_strategy: AlignChunk,
83
85
  }
84
86
  end
85
87
 
@@ -132,24 +134,25 @@ Usage: seeing_is_believing [options] [filename]
132
134
 
133
135
  If no filename is provided, the binary will read the program from standard input.
134
136
 
135
- -l, --start-line n # line number to begin showing results on
136
- -L, --end-line n # line number to stop showing results on
137
- -d, --line-length n # max length of the entire line (only truncates results, not source lines)
138
- -D, --result-length n # max length of the portion after the "# => "
139
- -s, --alignment-strategy # select the alignment strategy:
140
- chunk (DEFAULT) => each chunk of code is at the same alignment
141
- file => the entire file is at the same alignment
142
- line => each line is at its own alignment
143
- -t, --timeout n # timeout limit in seconds when evaluating source file (ex. -t 0.3 or -t 3)
144
- -I, --load-path dir # a dir that should be added to the $LOAD_PATH
145
- -r, --require file # additional files to be required before running the program
146
- -e, --program program # Pass the program to execute as an argument
147
- -K, --encoding encoding # sets file encoding, equivalent to Ruby's -Kx (see `man ruby` for valid values)
148
- -a, --as filename # run the program as if it was the specified filename
149
- -c, --clean # remove annotations from previous runs of seeing_is_believing
150
- -i, --inherit-exit-status # exit with the exit status of the program being eval
151
- -v, --version # print the version (#{VERSION})
152
- -h, --help # this help screen
137
+ -l, --start-line n # line number to begin showing results on
138
+ -L, --end-line n # line number to stop showing results on
139
+ -d, --line-length n # max length of the entire line (only truncates results, not source lines)
140
+ -D, --result-length n # max length of the portion after the "# => "
141
+ -s, --alignment-strategy name # select the alignment strategy:
142
+ chunk (DEFAULT) => each chunk of code is at the same alignment
143
+ file => the entire file is at the same alignment
144
+ line => each line is at its own alignment
145
+ -t, --timeout n # timeout limit in seconds when evaluating source file (ex. -t 0.3 or -t 3)
146
+ -I, --load-path dir # a dir that should be added to the $LOAD_PATH
147
+ -r, --require file # additional files to be required before running the program
148
+ -e, --program program # Pass the program to execute as an argument
149
+ -K, --encoding encoding # sets file encoding, equivalent to Ruby's -Kx (see `man ruby` for valid values)
150
+ -a, --as filename # run the program as if it was the specified filename
151
+ -c, --clean # remove annotations from previous runs of seeing_is_believing
152
+ -x, --xmpfilter-style # annotate marked lines instead of every line
153
+ -i, --inherit-exit-status # exit with the exit status of the program being eval
154
+ -v, --version # print the version (#{VERSION})
155
+ -h, --help # this help screen
153
156
  HELP_SCREEN
154
157
  end
155
158
  end
@@ -2,6 +2,17 @@ require 'seeing_is_believing/queue'
2
2
  require 'seeing_is_believing/has_exception'
3
3
  require 'seeing_is_believing/binary/line_formatter'
4
4
 
5
+ # I think there is a bug where with xmpfilter_style set,
6
+ # the exceptions won't be shown. But it's not totally clear
7
+ # how to show them with this option set, anyway.
8
+ # probably do what xmpfilter does and print them at the bottom
9
+ # of the file (probably do this regardless of whether xmpfilter_style
10
+ # is set)
11
+ #
12
+ # Would also be nice to support
13
+ # 1 + 1
14
+ # # => 2
15
+ # style updates like xmpfilter does
5
16
 
6
17
  class SeeingIsBelieving
7
18
  class Binary
@@ -15,8 +26,8 @@ class SeeingIsBelieving
15
26
 
16
27
  def self.remove_previous_output_from(string)
17
28
  string.gsub(/\s+(#{EXCEPTION_PREFIX}|#{RESULT_PREFIX}).*?$/, '')
18
- .gsub(/\n?(^#{STDOUT_PREFIX}[^\n]*\r?\n?)+/m, '')
19
- .gsub(/\n?(^#{STDERR_PREFIX}[^\n]*\r?\n?)+/m, '')
29
+ .gsub(/(^\n)?(^#{STDOUT_PREFIX}[^\n]*\r?\n?)+/m, '')
30
+ .gsub(/(^\n)?(^#{STDERR_PREFIX}[^\n]*\r?\n?)+/m, '')
20
31
  end
21
32
 
22
33
 
@@ -27,14 +38,23 @@ class SeeingIsBelieving
27
38
  method_from_options :filename, nil
28
39
  method_from_options :start_line
29
40
  method_from_options :end_line
30
- method_from_options :line_length, Float::INFINITY
31
- method_from_options :result_length, Float::INFINITY
41
+ method_from_options :line_length, Float::INFINITY
42
+ method_from_options :result_length, Float::INFINITY
43
+ method_from_options :xmpfilter_style
32
44
 
33
- def initialize(body, file_result, options={})
34
- self.body = body
45
+ attr_accessor :file_result
46
+ def initialize(body, options={})
47
+ cleaned_body = self.class.remove_previous_output_from body
35
48
  self.options = options
36
- self.file_result = file_result
37
- self.alignment_strategy = options[:alignment_strategy].new body, start_line, end_line
49
+ self.body = (xmpfilter_style ? body : cleaned_body)
50
+ self.file_result = SeeingIsBelieving.call body(),
51
+ filename: (options[:as] || options[:filename]),
52
+ require: options[:require],
53
+ load_path: options[:load_path],
54
+ encoding: options[:encoding],
55
+ stdin: options[:stdin],
56
+ timeout: options[:timeout]
57
+ self.alignment_strategy = options[:alignment_strategy].new cleaned_body, start_line, end_line
38
58
  end
39
59
 
40
60
  def new_body
@@ -42,44 +62,51 @@ class SeeingIsBelieving
42
62
  end
43
63
 
44
64
  def call
45
- add_each_line_until_start_or_data_segment
46
- add_lines_with_results_until_end_or_data_segment
47
- add_lines_until_data_segment
48
- add_stdout
49
- add_stderr
50
- add_remaining_lines
51
- return new_body
65
+ @printed_program ||= begin
66
+ # can we put the call to chomp into the line_queue initialization code?
67
+ line_queue.until { |line, line_number| SyntaxAnalyzer.begins_data_segment?(line.chomp) }
68
+ .each { |line, line_number| add_line line, line_number }
69
+ add_stdout
70
+ add_stderr
71
+ add_remaining_lines
72
+ new_body
73
+ end
52
74
  end
53
75
 
54
76
  private
55
77
 
56
- attr_accessor :body, :file_result, :options, :alignment_strategy
57
-
58
- def add_each_line_until_start_or_data_segment
59
- line_queue.until { |line, line_number| line_number == start_line || start_of_data_segment?(line) }
60
- .each { |line, line_number| new_body << line }
61
- end
62
-
63
- def add_lines_with_results_until_end_or_data_segment
64
- line_queue.until { |line, line_number| end_line < line_number || start_of_data_segment?(line) }
65
- .each { |line, line_number| new_body << format_line(line.chomp, line_number, file_result[line_number]) }
66
- end
78
+ attr_accessor :body, :options, :alignment_strategy
67
79
 
68
- def add_lines_until_data_segment
69
- line_queue.until { |line, line_number| start_of_data_segment?(line) }
70
- .each { |line, line_number| new_body << line }
80
+ def line_queue
81
+ @line_queue ||= Queue.new &body.each_line.with_index(1).to_a.method(:shift)
71
82
  end
72
83
 
73
- def add_remaining_lines
74
- line_queue.each { |line, line_number| new_body << line }
84
+ # if we want to pull this into a strategy
85
+ # we need to make available:
86
+ # file_result, start_line, end_line, alignment_strategy, line_length, result_length
87
+ def add_line(line, line_number)
88
+ should_record = should_record? line, line_number
89
+ if should_record && xmpfilter_style && line.strip =~ /^# =>/
90
+ new_body << xmpfilter_update(line, file_result[line_number - 1])
91
+ elsif should_record && xmpfilter_style
92
+ new_body << xmpfilter_update(line, file_result[line_number])
93
+ elsif should_record
94
+ new_body << format_line(line.chomp, line_number, file_result[line_number])
95
+ else
96
+ new_body << line
97
+ end
75
98
  end
76
99
 
77
- def line_queue
78
- @line_queue ||= Queue.new &body.each_line.with_index(1).to_a.method(:shift)
100
+ def should_record?(line, line_number)
101
+ (start_line <= line_number) &&
102
+ (line_number <= end_line) &&
103
+ (xmpfilter_style ? line =~ /# =>/ : # technically you could fuck this up with a line like "# =>", should later delegate to syntax analyzer
104
+ !SyntaxAnalyzer.ends_in_comment?(line))
79
105
  end
80
106
 
81
- def start_of_data_segment?(line)
82
- SyntaxAnalyzer.begins_data_segment?(line.chomp)
107
+ # again, this is too naive, should actually parse the comments and update them
108
+ def xmpfilter_update(line, line_results)
109
+ line.gsub /# =>.*?$/, "# => #{line_results.join ', '}"
83
110
  end
84
111
 
85
112
  def add_stdout
@@ -98,6 +125,10 @@ class SeeingIsBelieving
98
125
  end
99
126
  end
100
127
 
128
+ def add_remaining_lines
129
+ line_queue.each { |line, line_number| new_body << line }
130
+ end
131
+
101
132
  def format_line(line, line_number, line_results)
102
133
  options = options().merge pad_to: alignment_strategy.line_length_for(line_number)
103
134
  formatted_line = if line_results.has_exception?
@@ -20,23 +20,26 @@ class SeeingIsBelieving
20
20
  end
21
21
 
22
22
  def call
23
- @exitstatus ||= if flags_have_errors? then print_errors ; NONDISPLAYABLE_ERROR_STATUS
24
- elsif should_print_help? then print_help ; SUCCESS_STATUS
25
- elsif should_print_version? then print_version ; SUCCESS_STATUS
26
- elsif has_filename? && file_dne? then print_file_dne ; NONDISPLAYABLE_ERROR_STATUS
27
- elsif should_clean? then print_cleaned_program ; SUCCESS_STATUS
28
- elsif invalid_syntax? then print_syntax_error ; NONDISPLAYABLE_ERROR_STATUS
29
- elsif program_timedout? then print_timeout_error ; NONDISPLAYABLE_ERROR_STATUS
30
- elsif something_blew_up? then print_unexpected_error ; NONDISPLAYABLE_ERROR_STATUS
31
- else print_program ; program_exit_status
32
- end
23
+ @exitstatus ||= begin
24
+ parse_flags
25
+
26
+ if flags_have_errors? then print_errors ; NONDISPLAYABLE_ERROR_STATUS
27
+ elsif should_print_help? then print_help ; SUCCESS_STATUS
28
+ elsif should_print_version? then print_version ; SUCCESS_STATUS
29
+ elsif has_filename? && file_dne? then print_file_dne ; NONDISPLAYABLE_ERROR_STATUS
30
+ elsif should_clean? then print_cleaned_program ; SUCCESS_STATUS
31
+ elsif invalid_syntax? then print_syntax_error ; NONDISPLAYABLE_ERROR_STATUS
32
+ elsif (evaluate_program; program_timedout?) then print_timeout_error ; NONDISPLAYABLE_ERROR_STATUS
33
+ elsif something_blew_up? then print_unexpected_error ; NONDISPLAYABLE_ERROR_STATUS
34
+ else print_program ; program_exit_status
35
+ end
36
+ end
33
37
  end
34
38
 
35
- # uhm, this is dumb
36
- alias exitstatus call
37
-
38
39
  private
39
40
 
41
+ attr_accessor :flags, :interpolated_program
42
+
40
43
  def program_exit_status
41
44
  if flags[:inherit_exit_status]
42
45
  results.exitstatus
@@ -47,12 +50,25 @@ class SeeingIsBelieving
47
50
  end
48
51
  end
49
52
 
53
+ def parse_flags
54
+ self.flags = ArgParser.parse argv
55
+ end
56
+
50
57
  def has_filename?
51
58
  flags[:filename]
52
59
  end
53
60
 
61
+ def evaluate_program
62
+ self.interpolated_program = printer.call
63
+ rescue Timeout::Error
64
+ self.timeout_error = true
65
+ rescue Exception
66
+ self.unexpected_exception = $!
67
+ end
68
+
69
+ # could we make this more obvious? I'd like to to be clear from #call
70
+ # that this is when the program gets evaluated
54
71
  def program_timedout?
55
- results
56
72
  timeout_error
57
73
  end
58
74
 
@@ -60,23 +76,8 @@ class SeeingIsBelieving
60
76
  stderr.puts "Timeout Error after #{@flags[:timeout]} seconds!"
61
77
  end
62
78
 
63
- def cleaned_body
64
- @body ||= PrintResultsNextToLines.remove_previous_output_from \
65
- flags[:program] || (file_is_on_stdin? && stdin.read) || File.read(flags[:filename])
66
- end
67
-
68
- def results
69
- @results ||= SeeingIsBelieving.call cleaned_body,
70
- filename: (flags[:as] || flags[:filename]),
71
- require: flags[:require],
72
- load_path: flags[:load_path],
73
- encoding: flags[:encoding],
74
- stdin: (file_is_on_stdin? ? '' : stdin),
75
- timeout: flags[:timeout]
76
- rescue Timeout::Error
77
- self.timeout_error = true
78
- rescue Exception
79
- self.unexpected_exception = $!
79
+ def body
80
+ @body ||= (flags[:program] || (file_is_on_stdin? && stdin.read) || File.read(flags[:filename]))
80
81
  end
81
82
 
82
83
  def something_blew_up?
@@ -88,11 +89,11 @@ class SeeingIsBelieving
88
89
  end
89
90
 
90
91
  def printer
91
- @printer ||= PrintResultsNextToLines.new cleaned_body, results, flags
92
+ @printer ||= PrintResultsNextToLines.new body, flags.merge(stdin: (file_is_on_stdin? ? '' : stdin))
92
93
  end
93
94
 
94
- def flags
95
- @flags ||= ArgParser.parse argv
95
+ def results
96
+ printer.file_result
96
97
  end
97
98
 
98
99
  def flags_have_errors?
@@ -132,11 +133,11 @@ class SeeingIsBelieving
132
133
  end
133
134
 
134
135
  def print_program
135
- stdout.puts printer.call
136
+ stdout.puts interpolated_program
136
137
  end
137
138
 
138
139
  def syntax_error_notice
139
- out, err, syntax_status = Open3.capture3 'ruby', '-c', stdin_data: cleaned_body
140
+ out, err, syntax_status = Open3.capture3 'ruby', '-c', stdin_data: body
140
141
  return err unless syntax_status.success?
141
142
  end
142
143
 
@@ -153,7 +154,7 @@ class SeeingIsBelieving
153
154
  end
154
155
 
155
156
  def print_cleaned_program
156
- stdout.print cleaned_body
157
+ stdout.print PrintResultsNextToLines.remove_previous_output_from body
157
158
  end
158
159
  end
159
160
  end
@@ -26,9 +26,8 @@ class SeeingIsBelieving
26
26
  def call
27
27
  offset, expressions, expression = 0, [], nil
28
28
  begin
29
- pending_expression = generate
29
+ pending_expression = generate(expressions)
30
30
  debug { "GENERATED: #{pending_expression.expression.inspect}, ADDING IT TO #{inspected_expressions expressions}" }
31
- expressions << pending_expression
32
31
 
33
32
  expression = reduce expressions, offset unless next_line_modifies_current?
34
33
 
@@ -41,10 +40,15 @@ class SeeingIsBelieving
41
40
 
42
41
  attr_accessor :debug_stream, :should_debug, :get_next_line, :peek_next_line, :on_complete, :expressions
43
42
 
44
- def generate
43
+ def generate(expressions)
45
44
  expression = get_next_line.call
46
45
  raise SyntaxError unless expression
47
- PendingExpression.new(expression, [])
46
+ if expressions.last && SyntaxAnalyzer.unfinished_here_doc?(expressions.last.expression)
47
+ expressions.last.expression << "\n" << expression # more stupid \n -.-
48
+ else
49
+ expressions << PendingExpression.new(expression, [])
50
+ end
51
+ expressions.last
48
52
  end
49
53
 
50
54
  def next_line_modifies_current?
@@ -0,0 +1,22 @@
1
+ require 'parser/current'
2
+
3
+ class SeeingIsBelieving
4
+ module RemoveInlineComments
5
+ extend self
6
+
7
+ def self.call(code)
8
+ remove_inline_comments code
9
+ end
10
+
11
+ def remove_inline_comments(code)
12
+ buffer = Parser::Source::Buffer.new "strip_comments"
13
+ buffer.source = code
14
+ parser = Parser::CurrentRuby.new
15
+ rewriter = Parser::Source::Rewriter.new(buffer)
16
+ ast, comments = parser.parse_with_comments(buffer)
17
+ comments.select { |comment| comment.type == :inline }
18
+ .each { |comment| rewriter.remove comment.location }
19
+ rewriter.process
20
+ end
21
+ end
22
+ end
@@ -162,7 +162,7 @@ class SeeingIsBelieving
162
162
  ast = Parser::CurrentRuby.parse(code_or_ast) if code_or_ast.kind_of? String
163
163
 
164
164
  case ast && ast.type
165
- when :begin, :resbody
165
+ when :begin, :kwbegin, :resbody # begin and kwbegin should be the same thing, but it changed in parser 1.4.1 to 2.0.0, so just adding them both for safety
166
166
  void_value_expression?(ast.children[-1])
167
167
  when :rescue, :ensure
168
168
  ast.children.any? { |child| void_value_expression? child }
@@ -182,6 +182,11 @@ class SeeingIsBelieving
182
182
  instance.has_heredoc? && code.scan("\n").size.next <= instance.here_doc_last_line_number
183
183
  end
184
184
 
185
+ def self.unfinished_here_doc?(code)
186
+ instance = parsed code
187
+ instance.heredocs.any? { |heredoc| heredoc.size == 1 }
188
+ end
189
+
185
190
  def heredocs
186
191
  @heredocs ||= []
187
192
  end
@@ -1,3 +1,3 @@
1
1
  class SeeingIsBelieving
2
- VERSION = '0.0.24'
2
+ VERSION = '0.0.26'
3
3
  end
@@ -6,6 +6,7 @@ require 'seeing_is_believing/queue'
6
6
  require 'seeing_is_believing/result'
7
7
  require 'seeing_is_believing/version'
8
8
  require 'seeing_is_believing/expression_list'
9
+ require 'seeing_is_believing/remove_inline_comments'
9
10
  require 'seeing_is_believing/evaluate_by_moving_files'
10
11
 
11
12
  # might not work on windows b/c of assumptions about line ends
@@ -37,6 +38,7 @@ class SeeingIsBelieving
37
38
  @memoized_result ||= begin
38
39
  leading_comments = ''
39
40
 
41
+
40
42
  # extract leading comments (e.g. encoding) so they don't get wrapped in begin/rescue/end
41
43
  while SyntaxAnalyzer.line_is_comment?(next_line_queue.peek)
42
44
  leading_comments << next_line_queue.dequeue << "\n"
@@ -83,7 +85,9 @@ class SeeingIsBelieving
83
85
  @expression_list ||= ExpressionList.new get_next_line: lambda { next_line_queue.dequeue },
84
86
  peek_next_line: lambda { next_line_queue.peek },
85
87
  on_complete: lambda { |line, children, completions, offset|
86
- expression = [line, *children, *completions].map(&:chomp).join("\n")
88
+ expression = RemoveInlineComments.call \
89
+ [line, *children, *completions].map(&:chomp).join("\n")
90
+
87
91
  if do_not_record? expression
88
92
  expression + "\n"
89
93
  else
@@ -141,6 +145,7 @@ class SeeingIsBelieving
141
145
  @next_line_queue ||= Queue.new { (line = stream.gets) && line.chomp }
142
146
  end
143
147
 
148
+ # eh? -.^ (can't we pull the rest of this out of the queue instead of breaking encapsulation?)
144
149
  def the_rest_of_the_stream
145
150
  next_line_queue.dequeue << "\n" << stream.read
146
151
  end
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
21
 
22
- s.add_dependency "parser", "~> 1.4"
22
+ s.add_dependency "parser", "~> 2.0.0.beta9"
23
23
 
24
24
  s.add_development_dependency "haiti", "~> 0.0.3"
25
25
  s.add_development_dependency "rake", "~> 10.0.3"
@@ -107,12 +107,6 @@ describe SeeingIsBelieving do
107
107
  # values_for("<<-HEREDOC\n1\nHEREDOC").should == [[], [], ['"\n1\n"']]
108
108
  end
109
109
 
110
- it 'does not record expressions that end in a comment' do
111
- values_for("1
112
- 2 # on internal expression
113
- 3 # at end of program").should == [['1'], [], []]
114
- end
115
-
116
110
  it "does not record expressions that are here docs (only really b/c it's not smart enough)" do
117
111
  values_for("<<A\n1\nA").should be_all &:empty?
118
112
  values_for(" <<A\n1\nA").should be_all &:empty?
@@ -122,6 +116,27 @@ describe SeeingIsBelieving do
122
116
  values_for("def meth\n<<-A\n1\nA\nend").should == [[], [], [], [], ['nil']]
123
117
  end
124
118
 
119
+ it 'does not insert code into the middle of heredocs', t:true do
120
+ invoked = invoke(<<-HEREDOC.gsub(/^ /, ''))
121
+ puts <<DOC1
122
+ doc1
123
+ DOC1
124
+ puts <<-DOC2
125
+ doc2
126
+ DOC2
127
+ puts <<-DOC3
128
+ doc3
129
+ DOC3
130
+ puts <<DOC4, <<-DOC5
131
+ doc4
132
+ DOC4
133
+ doc5
134
+ DOC5
135
+ HEREDOC
136
+
137
+ invoked.stdout.should == "doc1\ndoc2\ndoc3\ndoc4\ndoc5\n"
138
+ end
139
+
125
140
  it 'has no output for empty lines' do
126
141
  values_for('').should == [[]]
127
142
  values_for(' ').should == [[]]
@@ -189,7 +204,7 @@ describe SeeingIsBelieving do
189
204
  DOC
190
205
  end
191
206
 
192
- it 'does not try to record the keyword retry', t2:true do
207
+ it 'does not try to record the keyword retry' do
193
208
  values_for(<<-DOC).should == [[], [], [], ['nil']]
194
209
  def meth
195
210
  rescue
@@ -290,6 +305,12 @@ describe SeeingIsBelieving do
290
305
  invoke('at_exit { exit 121 }').exitstatus.should == 121
291
306
  end
292
307
 
308
+ it 'records lines that have comments on them' do
309
+ values_for('1+1 # comment uno
310
+ #comment dos
311
+ 3#comment tres').should == [['2'], [], ['3']]
312
+ end
313
+
293
314
  it 'can record the middle of a chain of calls', not_implemented: true do
294
315
  values_for("[*1..5]
295
316
  .select(&:even?)
@@ -35,6 +35,18 @@ describe SeeingIsBelieving::SyntaxAnalyzer do
35
35
  is_here_doc["a<<b\nb"].should be_false
36
36
  end
37
37
 
38
+ it 'knows if the expression is an unfinished heredoc' do
39
+ is_unfinished_heredoc = lambda { |code| described_class.unfinished_here_doc? code }
40
+ is_unfinished_heredoc["<<A"].should be_true
41
+ is_unfinished_heredoc["puts <<A, <<B\na\nA"].should be_true
42
+ is_unfinished_heredoc["<<-A\n"].should be_true
43
+
44
+ is_unfinished_heredoc["puts <<A\na\nA"].should be_false
45
+ is_unfinished_heredoc["puts <<-A\na\nA"].should be_false
46
+ is_unfinished_heredoc["puts <<-A\na\n A"].should be_false
47
+ is_unfinished_heredoc["puts <<A, <<B\na\nA\nB"].should be_false
48
+ end
49
+
38
50
  it 'knows if the last line is a comment' do
39
51
  is_comment = lambda { |code| described_class.ends_in_comment? code }
40
52
 
metadata CHANGED
@@ -1,112 +1,99 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: seeing_is_believing
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.0.24
4
+ version: 0.0.26
6
5
  platform: ruby
7
6
  authors:
8
7
  - Josh Cheek
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-06-21 00:00:00.000000000 Z
11
+ date: 2013-06-29 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- version_requirements: !ruby/object:Gem::Requirement
14
+ name: parser
15
+ requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: '1.4'
20
- none: false
21
- name: parser
19
+ version: 2.0.0.beta9
22
20
  type: :runtime
23
21
  prerelease: false
24
- requirement: !ruby/object:Gem::Requirement
22
+ version_requirements: !ruby/object:Gem::Requirement
25
23
  requirements:
26
24
  - - ~>
27
25
  - !ruby/object:Gem::Version
28
- version: '1.4'
29
- none: false
26
+ version: 2.0.0.beta9
30
27
  - !ruby/object:Gem::Dependency
31
- version_requirements: !ruby/object:Gem::Requirement
28
+ name: haiti
29
+ requirement: !ruby/object:Gem::Requirement
32
30
  requirements:
33
31
  - - ~>
34
32
  - !ruby/object:Gem::Version
35
33
  version: 0.0.3
36
- none: false
37
- name: haiti
38
34
  type: :development
39
35
  prerelease: false
40
- requirement: !ruby/object:Gem::Requirement
36
+ version_requirements: !ruby/object:Gem::Requirement
41
37
  requirements:
42
38
  - - ~>
43
39
  - !ruby/object:Gem::Version
44
40
  version: 0.0.3
45
- none: false
46
41
  - !ruby/object:Gem::Dependency
47
- version_requirements: !ruby/object:Gem::Requirement
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
48
44
  requirements:
49
45
  - - ~>
50
46
  - !ruby/object:Gem::Version
51
47
  version: 10.0.3
52
- none: false
53
- name: rake
54
48
  type: :development
55
49
  prerelease: false
56
- requirement: !ruby/object:Gem::Requirement
50
+ version_requirements: !ruby/object:Gem::Requirement
57
51
  requirements:
58
52
  - - ~>
59
53
  - !ruby/object:Gem::Version
60
54
  version: 10.0.3
61
- none: false
62
55
  - !ruby/object:Gem::Dependency
63
- version_requirements: !ruby/object:Gem::Requirement
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
64
58
  requirements:
65
59
  - - ~>
66
60
  - !ruby/object:Gem::Version
67
61
  version: 2.12.0
68
- none: false
69
- name: rspec
70
62
  type: :development
71
63
  prerelease: false
72
- requirement: !ruby/object:Gem::Requirement
64
+ version_requirements: !ruby/object:Gem::Requirement
73
65
  requirements:
74
66
  - - ~>
75
67
  - !ruby/object:Gem::Version
76
68
  version: 2.12.0
77
- none: false
78
69
  - !ruby/object:Gem::Dependency
79
- version_requirements: !ruby/object:Gem::Requirement
70
+ name: cucumber
71
+ requirement: !ruby/object:Gem::Requirement
80
72
  requirements:
81
73
  - - ~>
82
74
  - !ruby/object:Gem::Version
83
75
  version: 1.2.1
84
- none: false
85
- name: cucumber
86
76
  type: :development
87
77
  prerelease: false
88
- requirement: !ruby/object:Gem::Requirement
78
+ version_requirements: !ruby/object:Gem::Requirement
89
79
  requirements:
90
80
  - - ~>
91
81
  - !ruby/object:Gem::Version
92
82
  version: 1.2.1
93
- none: false
94
83
  - !ruby/object:Gem::Dependency
95
- version_requirements: !ruby/object:Gem::Requirement
84
+ name: ichannel
85
+ requirement: !ruby/object:Gem::Requirement
96
86
  requirements:
97
87
  - - ~>
98
88
  - !ruby/object:Gem::Version
99
89
  version: 5.1.1
100
- none: false
101
- name: ichannel
102
90
  type: :development
103
91
  prerelease: false
104
- requirement: !ruby/object:Gem::Requirement
92
+ version_requirements: !ruby/object:Gem::Requirement
105
93
  requirements:
106
94
  - - ~>
107
95
  - !ruby/object:Gem::Version
108
96
  version: 5.1.1
109
- none: false
110
97
  description: Records the results of every line of code in your file (intended to be
111
98
  like xmpfilter), inspired by Bret Victor's JavaScript example in his talk "Inventing
112
99
  on Principle"
@@ -143,6 +130,7 @@ files:
143
130
  - lib/seeing_is_believing/has_exception.rb
144
131
  - lib/seeing_is_believing/line.rb
145
132
  - lib/seeing_is_believing/queue.rb
133
+ - lib/seeing_is_believing/remove_inline_comments.rb
146
134
  - lib/seeing_is_believing/result.rb
147
135
  - lib/seeing_is_believing/syntax_analyzer.rb
148
136
  - lib/seeing_is_believing/the_matrix.rb
@@ -162,27 +150,26 @@ files:
162
150
  homepage: https://github.com/JoshCheek/seeing_is_believing
163
151
  licenses:
164
152
  - WTFPL
153
+ metadata: {}
165
154
  post_install_message:
166
155
  rdoc_options: []
167
156
  require_paths:
168
157
  - lib
169
158
  required_ruby_version: !ruby/object:Gem::Requirement
170
159
  requirements:
171
- - - ! '>='
160
+ - - '>='
172
161
  - !ruby/object:Gem::Version
173
162
  version: '0'
174
- none: false
175
163
  required_rubygems_version: !ruby/object:Gem::Requirement
176
164
  requirements:
177
- - - ! '>='
165
+ - - '>='
178
166
  - !ruby/object:Gem::Version
179
167
  version: '0'
180
- none: false
181
168
  requirements: []
182
169
  rubyforge_project: seeing_is_believing
183
- rubygems_version: 1.8.23
170
+ rubygems_version: 2.0.0
184
171
  signing_key:
185
- specification_version: 3
172
+ specification_version: 4
186
173
  summary: Records results of every line of code in your file
187
174
  test_files:
188
175
  - features/errors.feature