seeing_is_believing 3.0.0.beta.5 → 3.0.0.beta.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -0
  3. data/.rspec +4 -0
  4. data/.travis.yml +1 -1
  5. data/Rakefile +28 -18
  6. data/Readme.md +22 -13
  7. data/bin/seeing_is_believing +0 -1
  8. data/features/errors.feature +3 -3
  9. data/features/examples.feature +65 -0
  10. data/features/flags.feature +19 -0
  11. data/lib/seeing_is_believing/binary.rb +1 -1
  12. data/lib/seeing_is_believing/binary/align_chunk.rb +0 -8
  13. data/lib/seeing_is_believing/binary/commentable_lines.rb +7 -12
  14. data/lib/seeing_is_believing/binary/config.rb +18 -6
  15. data/lib/seeing_is_believing/binary/engine.rb +11 -6
  16. data/lib/seeing_is_believing/binary/remove_annotations.rb +17 -19
  17. data/lib/seeing_is_believing/error.rb +2 -2
  18. data/lib/seeing_is_believing/evaluate_by_moving_files.rb +8 -6
  19. data/lib/seeing_is_believing/event_stream/consumer.rb +55 -24
  20. data/lib/seeing_is_believing/event_stream/events.rb +11 -0
  21. data/lib/seeing_is_believing/event_stream/handlers/record_exit_events.rb +26 -0
  22. data/lib/seeing_is_believing/event_stream/handlers/stream_json_events.rb +0 -22
  23. data/lib/seeing_is_believing/event_stream/handlers/update_result.rb +1 -0
  24. data/lib/seeing_is_believing/result.rb +5 -15
  25. data/lib/seeing_is_believing/version.rb +1 -1
  26. data/seeing_is_believing.gemspec +3 -2
  27. data/spec/binary/config_spec.rb +25 -8
  28. data/spec/binary/engine_spec.rb +12 -5
  29. data/spec/evaluate_by_moving_files_spec.rb +17 -4
  30. data/spec/event_stream_spec.rb +45 -10
  31. data/spec/seeing_is_believing_spec.rb +29 -4
  32. data/spec/wrap_expressions_spec.rb +6 -1
  33. metadata +23 -10
  34. data/Changelog.md +0 -33
  35. data/lib/seeing_is_believing/event_stream/handlers/record_exitstatus.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 19acf5dae90b9e2cbad24fb2152392f3d22ab1f2
4
- data.tar.gz: 8c9bc8df800a1289cd0997c392027351798cbee1
3
+ metadata.gz: 8715640842e97ae16fececb478cf4356169e1fdc
4
+ data.tar.gz: a2bfb634547740e23c0a71710a953496350fb2b0
5
5
  SHA512:
6
- metadata.gz: d2198f2a94a2c5a570c087d8753feec78e71b08ac1b300d8e68cb4439e73111df75e1e610899853ccf33f205fc23330c65de0c9d19fbb24b4eba844f7ba6ce29
7
- data.tar.gz: 0e5842837786d01d8d141c679b877074d0c4297059d1e2d80a7fc9f5d48a9e595b5c1be1ee0f3975b6edb70ffc995f97ba1be2076ae4154352c24818896505ac
6
+ metadata.gz: a4bbbaaa3640d0dd4b42051eb7416efb940af2b5b7a78df277c8047ec0a91e10b725e0c68a0d0ebf961d20583579ea231c1c2fd90504aded08ce81e20675b9e4
7
+ data.tar.gz: 319db0b7ee9047fa6c051659f8da8320f83828141e3e47e38448078f87720e7847c35e773ea50331684d644a70917129f0d2e91890aa535023472d797aa0a211
data/.gitignore CHANGED
@@ -1,4 +1,19 @@
1
+ # Transient test files
1
2
  proving_grounds/*
3
+
4
+ # Don't accidentally commit gems generated from the source code
2
5
  *.gem
6
+
7
+ # Since it's a gem, don't lock it down to specific versions
3
8
  Gemfile.lock
9
+
10
+ # local notes about what I'm working on
4
11
  todo
12
+
13
+ # Bundler stores its configuration information here
14
+ .bundle
15
+
16
+ # Where I'm vendoring gems for the standalone environment
17
+ # Going with this location b/c Bundler winds up creating this dir anyway
18
+ # to make `require "bundler/setup"` work
19
+ bundle
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --fail-fast
3
+ --require error_to_communicate/rspec_formatter
4
+ --format WhatWeveGotHereIsAnErrorToCommunicate::RSpecFormatter
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
- script: rake
2
+ script: rake ci
3
3
  rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
data/Rakefile CHANGED
@@ -1,29 +1,39 @@
1
- desc 'run specs'
2
- task :spec do
3
- sh 'rspec -cf d --fail-fast'
1
+ require 'bundler'
2
+
3
+ desc 'Have Bundler setup a standalone environment -- run tests in this, b/c its faster and safer'
4
+ task :build do
5
+ # Running without rubygems # http://myronmars.to/n/dev-blog/2012/03/faster-test-boot-times-with-bundler-standalone
6
+ sh 'bundle install --standalone --binstubs bundle/bin'
4
7
  end
5
8
 
6
- desc 'run cukes'
7
- task :cuke do
8
- sh 'cucumber -t ~@not-implemented -t ~@wip'
9
+ desc 'Remove generated and irrelevant files'
10
+ task :clean do
11
+ rm_rf [
12
+ 'bundle',
13
+ '.bundle',
14
+ 'Gemfile.lock',
15
+ 'proving_grounds',
16
+ *Dir['*.gem'],
17
+ ]
9
18
  end
10
19
 
11
- namespace :cuke do
12
- desc 'Run work in progress cukes'
13
- task :wip do
14
- sh 'cucumber -t @wip'
15
- end
20
+ file :bundle do
21
+ $stderr.puts "\e[31mLooks like the gems aren\'t installed, run `rake build` to install them\e[39m"
22
+ exit 1
16
23
  end
17
24
 
18
- namespace :spec do
19
- desc 'Run work in progress specs'
20
- task :wip do
21
- sh 'rspec -t wip'
22
- end
25
+ desc 'Run specs'
26
+ task spec: :bundle do
27
+ sh 'ruby', '--disable-gem', *Bundler.load.specs.flat_map(&:full_require_paths).flat_map { |p| ['-I', p ] }, '-S', 'bundle/bin/rspec'
23
28
  end
24
29
 
25
- desc 'Run work in progress specs and cukes'
26
- task wip: ['spec:wip', 'cuke:wip']
30
+ desc 'Run cukes'
31
+ task cuke: :bundle do
32
+ sh 'ruby', '--disable-gem', *Bundler.load.specs.flat_map(&:full_require_paths).flat_map { |p| ['-I', p ] }, '-S', 'bundle/bin/cucumber', '--tags', '~@not-implemented'
33
+ end
27
34
 
28
35
  desc 'Run all specs and cukes'
29
36
  task default: [:spec, :cuke]
37
+
38
+ desc 'Install dependencies and run tests (mainly for Travis CI)'
39
+ task ci: [:build, :spec, :cuke]
data/Readme.md CHANGED
@@ -64,19 +64,25 @@ Currently requires Ruby 1.9 or 2.x
64
64
  Editor Integration
65
65
  ==================
66
66
 
67
- * [sublime-text-2-seeing-is-believing](https://github.com/JoshCheek/sublime-text-2-seeing-is-believing)
67
+ * [Atom](https://github.com/JoshCheek/atom-seeing-is-believing) (prob has best installation instructions, overall best integration, but config and filesystem events are iffy)
68
+ * [Sublime 2 and 3](https://github.com/JoshCheek/sublime-text-2-and-3-seeing-is-believing) (works reasonably, but isn't integrated with the package manager)
68
69
  * [TextMate 1](https://github.com/JoshCheek/text_mate_1-seeing-is_believing)
69
- * [TextMate 2](https://github.com/JoshCheek/text_mate_2-seeing-is_believing)
70
- * [vim-ruby-xmpfilter](https://github.com/t9md/vim-ruby-xmpfilter) (has support for `seeing_is_believing`)
70
+ * [TextMate 2](https://github.com/JoshCheek/text_mate_2-seeing-is_believing) (TM2 is actually looking really nice these days -- Josh Cheek, 18 Feb 2015)
71
+
72
+ Vim
73
+ ===
74
+
75
+ I didn't write either of these, but they both support Seeing Is Beleiving. I've looked through the code, it works reasonably. One of them, I wound up having to edit the installed package, don't remember which.
76
+
77
+ * [vim-ruby-xmpfilter](https://github.com/t9md/vim-ruby-xmpfilter)
71
78
  * [vim-seeing-is-believing](https://github.com/hwartig/vim-seeing-is-believing)
72
- * [atom-seeing-is-believing](https://github.com/JoshCheek/atom-seeing-is-believing) (prob has best installation instructions)
73
79
 
74
80
  Emacs Integration
75
81
  =================
76
82
 
77
83
  Add this function to your Emacs configuration:
78
84
 
79
- ~~~~ scheme
85
+ ```scheme
80
86
  (defun seeing-is-believing ()
81
87
  "Replace the current region (or the whole buffer, if none) with the output
82
88
  of seeing_is_believing."
@@ -84,7 +90,7 @@ of seeing_is_believing."
84
90
  (let ((beg (if (region-active-p) (region-beginning) (point-min)))
85
91
  (end (if (region-active-p) (region-end) (point-max))))
86
92
  (shell-command-on-region beg end "seeing_is_believing" nil 'replace)))
87
- ~~~~
93
+ ```
88
94
 
89
95
  You can now call `seeing-is-believing` to replace the current region
90
96
  or current buffer contents with the output of running it through
@@ -95,8 +101,8 @@ Known Issues
95
101
 
96
102
  * `begin; else; break; end` this code (an else without a resecue) will emit a warning in Ruby, and is omitted from `Parser`'s AST.
97
103
  As such, I doubt that anyone will ever write it. But if you were to write it, it would blow up, because SiB rewrites your code, wrapping every expression that could have a value.
98
- This code will be wrapped. But using the value is syntactically invalid in Ruby, because it constitutes a "void value expression" (aka a nightmare for anyone working with code).
99
- I can't easily check it to seee if it's void since it's not in the parsed AST. But it's so edge taht I don't think it's worth worrying about.
104
+ This code will be wrapped. But using the value is **syntactically** invalid in Ruby, because it constitutes a "void value expression" (aka a pointless timesink and the cause of many bugs in SiB).
105
+ Unfortunately, I can't easily check it to seee if it's void since it's not in the parsed AST. But it's so edge that I don't think it's worth worrying about.
100
106
 
101
107
  Version 2
102
108
  =========
@@ -109,11 +115,14 @@ Version 3
109
115
  These need to be done before release:
110
116
 
111
117
  * Add default to number of captures (1000), require user to explicitly set it to infinity
112
- * Update changelog with all changes
113
- * Push the event stream up to the top level so we can expose it via the interface.
114
- * Get it working on JRuby and Rbx
115
- * Order frog stickers
116
- * Figure out how to handle markers
118
+ * Expose markers via the CLI
119
+ * Spruce up editor integration
120
+ * Integrate with package managers where they are available
121
+ * Expose options to use the streaming API (update as events are seen)
122
+ * Ship with Traveling Ruby so that new users can just press a button and it works,
123
+ rather than having to figure out all the compmlex ecosystem around installing
124
+ * Would be nice to have real integration with Emacs
125
+ * Would be nice to support Ruby Mine
117
126
 
118
127
  Version 4
119
128
  =========
@@ -2,6 +2,5 @@
2
2
 
3
3
  $LOAD_PATH.unshift File.expand_path '../../lib', __FILE__
4
4
 
5
- gem 'parser', '~> 2.2.0.2'
6
5
  require 'seeing_is_believing/binary'
7
6
  exit SeeingIsBelieving::Binary.call(ARGV, $stdin, $stdout, $stderr)
@@ -69,10 +69,10 @@ Feature: Running the binary unsuccessfully
69
69
  And the exit status is 2
70
70
  And stdout is empty
71
71
 
72
- Scenario: Passing unknown options
72
+ Scenario: Passing unknown flags
73
73
  Given the file "some_file" "1"
74
- When I run "seeing_is_believing --unknown-option"
75
- Then stderr is 'Error: --unknown-option is not an option, see the help screen (-h) for a list of options'
74
+ When I run "seeing_is_believing --unknown-flag"
75
+ Then stderr is 'Error: --unknown-flag is not a flag, see the help screen (-h) for a list of options'
76
76
  And the exit status is 2
77
77
  And stdout is empty
78
78
 
@@ -259,6 +259,71 @@ Feature: Running the binary successfully
259
259
  And the exit status is 0
260
260
 
261
261
 
262
+ @not-implemented
263
+ Scenario: Fork records data in parent and child, parent exec does not affect it.
264
+ Given the file "fork_exec_parent.rb":
265
+ """
266
+ :both
267
+ if fork #
268
+ :parent
269
+ exec 'echo', 'hello'
270
+ else
271
+ sleep 1
272
+ :child
273
+ end
274
+ :child
275
+
276
+ # >> hello
277
+ """
278
+ When I run "seeing_is_believing fork_exec_parent.rb"
279
+ Then stdout is:
280
+ """
281
+ :both # => :both
282
+ if fork #
283
+ :parent # => :parent
284
+ exec 'echo', 'hello'
285
+ else
286
+ sleep 1 # => 1
287
+ :child # => :child
288
+ end
289
+ :child # => :child
290
+
291
+ # >> hello
292
+ """
293
+
294
+ @not-implemented
295
+ Scenario: Fork records data in parent and child, child exec does not affect it.
296
+ Given the file "fork_exec_child.rb":
297
+ """
298
+ :both
299
+ if fork #
300
+ sleep 1
301
+ :parent
302
+ else
303
+ :child
304
+ exec 'echo', 'hello'
305
+ end
306
+ :parent
307
+
308
+ # >> hello
309
+ """
310
+ When I run "seeing_is_believing fork_exec_child.rb"
311
+ Then stdout is:
312
+ """
313
+ :both # => :both
314
+ if fork #
315
+ sleep 1 # => 1
316
+ :parent # => :parent
317
+ else
318
+ :child # => :child
319
+ exec 'echo', 'hello'
320
+ end
321
+ :parent # => :parent
322
+
323
+ # >> hello
324
+ """
325
+
326
+
262
327
  Scenario: Implicit regexp conditional
263
328
  Given the stdin content "abc"
264
329
  And the file "implicit_regex_conditional.rb":
@@ -509,3 +509,22 @@ Feature: Using flags
509
509
  """
510
510
  ["sib_version",{"value":"{{SeeingIsBelieving::VERSION}}"}]
511
511
  """
512
+
513
+ Scenario: --stream emits a timeout event and finishes successfully when the process times out.
514
+ When I run "seeing_is_believing -e 'loop { sleep 1 }' -t 0.01 --stream"
515
+ Then the exit status is 2
516
+ And stderr is "Timeout Error after 0.01 seconds!"
517
+ And stdout includes:
518
+ """
519
+ ["finished",{}]
520
+ """
521
+ And stdout includes:
522
+ """
523
+ ["timeout",{"seconds":0.01}]
524
+ """
525
+
526
+ Scenario: --ignore-unknown-flags prevents errors on unknown flags for forward compatibility
527
+ When I run "seeing_is_believing -e '1' --ignore-unknown-flags --zomg-wat"
528
+ Then the exit status is 0
529
+ And stderr is empty
530
+ And stdout is "1 # => 1"
@@ -40,7 +40,7 @@ class SeeingIsBelieving
40
40
  engine.evaluate!
41
41
 
42
42
  if engine.timed_out?
43
- stderr.puts "Timeout Error after #{config.timeout_seconds} seconds!"
43
+ stderr.puts "Timeout Error after #{engine.timeout_seconds} seconds!"
44
44
  return NONDISPLAYABLE_ERROR_STATUS
45
45
  end
46
46
 
@@ -37,14 +37,6 @@ class SeeingIsBelieving
37
37
  end
38
38
  end
39
39
 
40
- def trim_trailing_whitespace(line_nums_to_indexes)
41
- line_nums_to_indexes.each do |num, indexes|
42
- index_in_file = indexes[0]
43
- num_to_trim = amount_of_preceding_whitespace(index_in_file)
44
- indexes.map! { |index| index - num_to_trim }
45
- end
46
- end
47
-
48
40
  def amount_of_preceding_whitespace(index_of_trailing_newline)
49
41
  index = index_of_trailing_newline - 1
50
42
  index -= 1 while 0 <= index && body[index] !~ /[\S\n]/
@@ -42,18 +42,13 @@ class SeeingIsBelieving
42
42
  end
43
43
 
44
44
  def line_nums_to_last_index_and_col(buffer)
45
- line_num_to_location = code.each_char
46
- .with_index
47
- .select { |char, index| char == "\n" } # <-- is this okay? what about other OSes?
48
- .each_with_object(Hash.new) do |(_, index), hash|
49
- line, col = buffer.decompose_position index
50
- hash[line] = [index, col]
51
- end
52
- if code[code.size-1] != "\n" # account for the fact that the last line wouldn't have been found above if it doesn't end in a newline
53
- line, col = buffer.decompose_position code.size
54
- line_num_to_location[line] = [code.size, col]
55
- end
56
- line_num_to_location
45
+ code.each_char
46
+ .with_index
47
+ .select { |char, index| char == "\n" }
48
+ .each_with_object(Hash.new) do |(_, index), hash|
49
+ line, col = buffer.decompose_position index
50
+ hash[line] = [index, col]
51
+ end
57
52
  end
58
53
 
59
54
  def remove_lines_whose_newline_is_escaped(line_num_to_location)
@@ -29,6 +29,7 @@ class SeeingIsBelieving
29
29
  predicate(:inherit_exitstatus) { false }
30
30
  predicate(:remove_value_prefixes) { true }
31
31
  predicate(:debug) { false }
32
+ predicate(:ignore_unknown_flags) { false }
32
33
  attribute(:body) { nil }
33
34
  attribute(:filename) { nil }
34
35
  attribute(:errors) { [] }
@@ -46,9 +47,10 @@ class SeeingIsBelieving
46
47
  end
47
48
 
48
49
  def parse_args(args)
49
- as = nil
50
- filenames = []
51
- args = args.dup
50
+ args = args.dup
51
+ as = nil
52
+ filenames = []
53
+ unknown_flags = []
52
54
 
53
55
  extract_positive_int_for = lambda do |flagname, &on_success|
54
56
  string = args.shift
@@ -92,6 +94,9 @@ class SeeingIsBelieving
92
94
  when '-v', '--version'
93
95
  self.print_version = true
94
96
 
97
+ when '--ignore-unknown-flags'
98
+ self.ignore_unknown_flags = true
99
+
95
100
  when '-x', '--xmpfilter-style'
96
101
  self.annotator = AnnotateMarkedLines
97
102
  self.lib_options.rewrite_code = AnnotateMarkedLines.code_rewriter(markers)
@@ -194,7 +199,7 @@ class SeeingIsBelieving
194
199
  end
195
200
 
196
201
  when /^(-.|--.*)$/
197
- add_error("#{arg} is not an option, see the help screen (-h) for a list of options")
202
+ unknown_flags << arg
198
203
 
199
204
  when /^-[^-]/
200
205
  args.unshift *arg.scan(/[^-]\+?/).map { |flag| "-#{flag}" }
@@ -204,6 +209,11 @@ class SeeingIsBelieving
204
209
  end
205
210
  end
206
211
 
212
+ unknown_flags.each do |flag|
213
+ break if ignore_unknown_flags?
214
+ add_error "#{flag} is not a flag, see the help screen (-h) for a list of options"
215
+ end
216
+
207
217
  filenames.size > 1 &&
208
218
  add_error("can only have one filename but found #{filenames.map(&:inspect).join ', '}")
209
219
 
@@ -264,13 +274,13 @@ Usage: seeing_is_believing [options] [filename]
264
274
 
265
275
  Notes:
266
276
 
267
- * If no filename or program (-e flag) are provided, the program will read from standard input.
277
+ * If no filename or program (-e option) are provided, the program will read from standard input.
268
278
  * The process's stdin will be passed to the program unless the program body is on stdin.
269
279
  * The exit status will be:
270
280
  0 - No errors
271
281
  1 - Displayable error (e.g. code raises an exception while running)
272
282
  2 - Non-displayable error (e.g. a syntax error, a timeout)
273
- n - The program's exit status if the --inherit-exitstatus flag is set
283
+ n - The program's exit status if the --inherit-exitstatus option is set
274
284
 
275
285
  Options:
276
286
  -d, --line-length n # max length of the entire line (only truncates results, not source lines)
@@ -296,6 +306,8 @@ Options:
296
306
  -j, --json # print results in json format (i.e. so another program can consume them)
297
307
  -i, --inherit-exitstatus # exit with the exit status of the program being evaluated
298
308
  --stream # a JSON stream of every event ias it is seen (such as recording a line)
309
+ --ignore-unknown-flags # don't error when flag is not in this list
310
+ allows integrating code to support compatibility with future versions of SiB
299
311
  -v, --version # print the version (#{VERSION})
300
312
  -h, --help # help screen without examples
301
313
  -h+, --help+ # help screen with examples
@@ -1,7 +1,7 @@
1
1
  require 'seeing_is_believing/code'
2
2
  require 'seeing_is_believing/binary/data_structures'
3
3
  require 'seeing_is_believing/binary/remove_annotations'
4
- require 'seeing_is_believing/event_stream/handlers/record_exitstatus'
4
+ require 'seeing_is_believing/event_stream/handlers/record_exit_events'
5
5
 
6
6
  class SeeingIsBelieving
7
7
  module Binary
@@ -38,7 +38,7 @@ class SeeingIsBelieving
38
38
  def evaluate!
39
39
  @evaluated || begin
40
40
  SeeingIsBelieving.call normalized_cleaned_body,
41
- config.lib_options.merge(event_handler: record_exitstatus)
41
+ config.lib_options.merge(event_handler: record_exit_events)
42
42
  @timed_out = false
43
43
  @evaluated = true
44
44
  end
@@ -50,7 +50,12 @@ class SeeingIsBelieving
50
50
 
51
51
  def timed_out?
52
52
  @evaluated || raise(MustEvaluateFirst.new __method__)
53
- @timed_out
53
+ !!timeout_seconds
54
+ end
55
+
56
+ def timeout_seconds
57
+ @evaluated || raise(MustEvaluateFirst.new __method__)
58
+ record_exit_events.timeout_seconds
54
59
  end
55
60
 
56
61
  def result
@@ -71,7 +76,7 @@ class SeeingIsBelieving
71
76
 
72
77
  def exitstatus
73
78
  @evaluated || raise(MustEvaluateFirst.new __method__)
74
- record_exitstatus.exitstatus
79
+ record_exit_events.exitstatus
75
80
  end
76
81
 
77
82
  private
@@ -86,8 +91,8 @@ class SeeingIsBelieving
86
91
  @code ||= Code.new(normalized_cleaned_body, config.filename)
87
92
  end
88
93
 
89
- def record_exitstatus
90
- @record_exitstatus ||= SeeingIsBelieving::EventStream::Handlers::RecordExitStatus.new config.lib_options.event_handler
94
+ def record_exit_events
95
+ @record_exit_events ||= SeeingIsBelieving::EventStream::Handlers::RecordExitEvents.new config.lib_options.event_handler
91
96
  end
92
97
 
93
98
  def normalized_cleaned_body