seeing_is_believing 2.2.0 → 3.0.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Changelog.md +33 -0
  4. data/bin/seeing_is_believing +1 -1
  5. data/features/errors.feature +3 -3
  6. data/features/examples.feature +6 -6
  7. data/features/flags.feature +51 -196
  8. data/features/regression.feature +12 -3
  9. data/features/safe.feature +33 -0
  10. data/features/support/env.rb +20 -0
  11. data/features/xmpfilter-style.feature +156 -0
  12. data/lib/seeing_is_believing.rb +17 -35
  13. data/lib/seeing_is_believing/binary.rb +81 -176
  14. data/lib/seeing_is_believing/binary/align_chunk.rb +5 -7
  15. data/lib/seeing_is_believing/binary/align_file.rb +4 -5
  16. data/lib/seeing_is_believing/binary/align_line.rb +4 -4
  17. data/lib/seeing_is_believing/binary/annotate_end_of_file.rb +60 -0
  18. data/lib/seeing_is_believing/binary/annotate_every_line.rb +64 -0
  19. data/lib/seeing_is_believing/binary/annotate_xmpfilter_style.rb +133 -0
  20. data/lib/seeing_is_believing/binary/comment_formatter.rb +19 -5
  21. data/lib/seeing_is_believing/binary/comment_lines.rb +1 -1
  22. data/lib/seeing_is_believing/binary/commentable_lines.rb +1 -1
  23. data/lib/seeing_is_believing/binary/interpret_flags.rb +149 -0
  24. data/lib/seeing_is_believing/binary/parse_args.rb +96 -104
  25. data/lib/seeing_is_believing/binary/remove_annotations.rb +95 -0
  26. data/lib/seeing_is_believing/binary/rewrite_comments.rb +8 -30
  27. data/lib/seeing_is_believing/code.rb +99 -0
  28. data/lib/seeing_is_believing/evaluate_by_moving_files.rb +27 -19
  29. data/lib/seeing_is_believing/evaluate_with_eval_in.rb +27 -0
  30. data/lib/seeing_is_believing/event_stream/consumer.rb +111 -0
  31. data/lib/seeing_is_believing/event_stream/events.rb +16 -0
  32. data/lib/seeing_is_believing/event_stream/producer.rb +106 -0
  33. data/lib/seeing_is_believing/event_stream/update_result.rb +21 -0
  34. data/lib/seeing_is_believing/inspect_expressions.rb +24 -0
  35. data/lib/seeing_is_believing/parser_helpers.rb +1 -11
  36. data/lib/seeing_is_believing/result.rb +14 -56
  37. data/lib/seeing_is_believing/the_matrix.rb +14 -14
  38. data/lib/seeing_is_believing/version.rb +1 -1
  39. data/lib/seeing_is_believing/wrap_expressions.rb +32 -9
  40. data/seeing_is_believing.gemspec +7 -7
  41. data/spec/binary/comment_formatter_spec.rb +169 -18
  42. data/spec/binary/comment_lines_spec.rb +1 -1
  43. data/spec/binary/interpret_flags_spec.rb +307 -0
  44. data/spec/binary/parse_args_spec.rb +93 -91
  45. data/spec/binary/{clean_body_spec.rb → remove_annotations_spec.rb} +29 -22
  46. data/spec/binary/rewrite_comments_spec.rb +13 -13
  47. data/spec/code_spec.rb +49 -0
  48. data/spec/debugger_spec.rb +1 -1
  49. data/spec/evaluate_by_moving_files_spec.rb +7 -3
  50. data/spec/event_stream_spec.rb +390 -0
  51. data/spec/hard_core_ensure_spec.rb +1 -1
  52. data/spec/seeing_is_believing_spec.rb +137 -40
  53. data/spec/spec_helper.rb +3 -3
  54. data/spec/wrap_expressions_spec.rb +48 -35
  55. metadata +58 -35
  56. data/lib/seeing_is_believing/binary/add_annotations.rb +0 -144
  57. data/lib/seeing_is_believing/binary/clean_body.rb +0 -95
  58. data/lib/seeing_is_believing/has_exception.rb +0 -27
  59. data/lib/seeing_is_believing/line.rb +0 -90
  60. data/spec/line_spec.rb +0 -86
@@ -0,0 +1,21 @@
1
+ require 'seeing_is_believing/event_stream/events'
2
+ class SeeingIsBelieving
3
+ module EventStream
4
+ module UpdateResult
5
+ def self.call(result, event)
6
+ case event
7
+ when EventStream::Events::LineResult then result.record_result(event.type, event.line_number, event.inspected)
8
+ when EventStream::Events::UnrecordedResult then result.record_result(event.type, event.line_number, '...') # <-- is this really what I want?
9
+ when EventStream::Events::Exception then result.record_exception event.line_number, event.class_name, event.message, event.backtrace
10
+ when EventStream::Events::Stdout then result.stdout = event.value
11
+ when EventStream::Events::Stderr then result.stderr = event.value
12
+ when EventStream::Events::BugInSiB then result.bug_in_sib = event.value
13
+ when EventStream::Events::MaxLineCaptures then result.number_of_captures = event.value
14
+ when EventStream::Events::Exitstatus then result.exitstatus = event.value
15
+ when EventStream::Events::NumLines then result.num_lines = event.value
16
+ else raise "Unknown event: #{event.inspect}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ require 'seeing_is_believing/wrap_expressions'
2
+ class SeeingIsBelieving
3
+ module InspectExpressions
4
+ def self.call(program, number_of_captures, options={})
5
+ number_of_captures_as_str = number_of_captures.inspect
6
+ number_of_captures_as_str = 'Float::INFINITY' if number_of_captures == Float::INFINITY
7
+
8
+ wrap_expressions_callbacks = {}
9
+ wrap_expressions_callbacks[:before_all] = options.fetch :before_all, -> { "begin; $SiB.max_line_captures = #{number_of_captures_as_str}; $SiB.num_lines = #{program.lines.count}; " }
10
+ wrap_expressions_callbacks[:after_all] = options.fetch :after_all, -> { ";rescue Exception;"\
11
+ "lambda {"\
12
+ "line_number = $!.backtrace.grep(/\#{__FILE__}/).first[/:\\d+/][1..-1].to_i;"\
13
+ "$SiB.record_exception line_number, $!;"\
14
+ "$SiB.exitstatus = 1;"\
15
+ "$SiB.exitstatus = $!.status if $!.kind_of? SystemExit;"\
16
+ "}.call;"\
17
+ "end"
18
+ }
19
+ wrap_expressions_callbacks[:before_each] = options.fetch :before_each, -> line_number { "(" }
20
+ wrap_expressions_callbacks[:after_each] = options.fetch :after_each, -> line_number { ").tap { |v| $SiB.record_result(:inspect, #{line_number}, v) }" }
21
+ WrapExpressions.call program, wrap_expressions_callbacks
22
+ end
23
+ end
24
+ end
@@ -1,14 +1,4 @@
1
- module Parser
2
- class << self
3
- # With new versioning, there's lots of small versions
4
- # we don't need it to complain that we're on 2.1.1 and its parsing 2.1.5
5
- # https://github.com/whitequark/parser/blob/e2249d7051b1adb6979139928e14a81bc62f566e/lib/parser/current.rb#L3
6
- def warn(*) end
7
- require 'parser/current'
8
- remove_method :warn
9
- end
10
- end
11
-
1
+ require 'parser/current'
12
2
  class SeeingIsBelieving
13
3
  module ParserHelpers
14
4
 
@@ -1,44 +1,11 @@
1
- require 'seeing_is_believing/line'
2
- require 'seeing_is_believing/has_exception'
3
-
4
1
  class SeeingIsBelieving
5
2
  class Result
6
- include HasException
7
3
  include Enumerable
4
+ RecordedException = Struct.new :line_number, :class_name, :message, :backtrace
8
5
 
9
- def self.from_primitive(primitive)
10
- new.from_primitive(primitive)
11
- end
12
-
13
- def from_primitive(primitive)
14
- self.exitstatus = primitive['exitstatus']
15
- self.stdout = primitive['stdout']
16
- self.stderr = primitive['stderr']
17
- self.bug_in_sib = primitive['bug_in_sib']
18
- self.exception = RecordedException.from_primitive primitive['exception']
19
- primitive['results'].each do |line_number, primitive_line|
20
- results_for(line_number.to_i).from_primitive(primitive_line)
21
- end
22
- self
23
- end
24
-
25
- def to_primitive
26
- primitive = {
27
- 'exitstatus' => exitstatus,
28
- 'stdout' => stdout,
29
- 'stderr' => stderr,
30
- 'bug_in_sib' => bug_in_sib,
31
- 'exception' => (exception && exception.to_primitive),
32
- }
33
- primitive['results'] = results.each_with_object({}) do |(line_number, line), r|
34
- r[line_number] = line.to_primitive
35
- end
36
- primitive
37
- end
38
-
39
-
40
- attr_accessor :stdout, :stderr, :exitstatus, :bug_in_sib, :number_of_captures
6
+ attr_accessor :stdout, :stderr, :exitstatus, :bug_in_sib, :number_of_captures, :exception, :num_lines
41
7
 
8
+ alias has_exception? exception
42
9
  alias bug_in_sib? bug_in_sib
43
10
 
44
11
  def has_stdout?
@@ -49,32 +16,22 @@ class SeeingIsBelieving
49
16
  stderr && !stderr.empty?
50
17
  end
51
18
 
52
- def record_result(line_number, value)
53
- results_for(line_number).record_result(value)
19
+ def record_result(type, line_number, value)
20
+ results_for(line_number, type) << value
54
21
  value
55
22
  end
56
23
 
57
- def record_exception(line_number, exception)
58
- recorded_exception = RecordedException.new exception.class.name,
59
- exception.message,
60
- exception.backtrace
61
- self.exception = recorded_exception
62
- results_for(line_number).exception = recorded_exception
24
+ def record_exception(line_number, exception_class, exception_message, exception_backtrace)
25
+ self.exception = RecordedException.new line_number, exception_class, exception_message, exception_backtrace
63
26
  end
64
27
 
65
- def [](line_number)
66
- results_for(line_number)
28
+ def [](line_number, type=:inspect)
29
+ results_for(line_number, type)
67
30
  end
68
31
 
69
32
  def each(&block)
70
- max = results.keys.max || 1
71
- (1..max).each { |line_number| block.call self[line_number] }
72
- end
73
-
74
- def each_with_line_number(&block)
75
- return to_enum :each_with_line_number unless block
76
- max = results.keys.max || 1
77
- (1..max).each { |line_number| block.call line_number, results_for(line_number) }
33
+ return to_enum :each unless block
34
+ (1..num_lines).each { |line_number| block.call self[line_number] }
78
35
  end
79
36
 
80
37
  def inspect
@@ -97,8 +54,9 @@ class SeeingIsBelieving
97
54
 
98
55
  private
99
56
 
100
- def results_for(line_number)
101
- results[line_number] ||= Line.new([], number_of_captures)
57
+ def results_for(line_number, type)
58
+ line_results = (results[line_number] ||= Hash.new { |h, k| h[k] = [] })
59
+ line_results[type]
102
60
  end
103
61
 
104
62
  def results
@@ -5,30 +5,30 @@
5
5
  #
6
6
  # (or if you want to understand why we do the pipe dance)
7
7
 
8
+ require_relative 'version'
9
+ require_relative 'event_stream/producer'
8
10
 
9
- require 'json'
10
- require 'seeing_is_believing/result'
11
- $SiB = SeeingIsBelieving::Result.new
11
+ stdout_real_obj = STDOUT # the real Ruby object, fake file descriptor
12
+ stdout_real_fd = STDOUT.dup # duped Ruby object, real file descriptor
13
+ read_from_mock_out, write_to_mock_out = IO.pipe
14
+ stdout_real_obj.reopen write_to_mock_out
12
15
 
13
- stdout_real_obj = STDOUT # the real Ruby object, but its FD is going to keep getting reopened
14
16
  stderr_real_obj = STDERR
15
- stdout_real_fd = STDOUT.dup # duped Ruby object, but with the real file descriptor
16
17
  stderr_real_fd = STDERR.dup
17
-
18
- read_from_mock_out, write_to_mock_out = IO.pipe
19
18
  read_from_mock_err, write_to_mock_err = IO.pipe
20
-
21
- stdout_real_obj.reopen write_to_mock_out
22
19
  stderr_real_obj.reopen write_to_mock_err
23
20
 
21
+ $SiB = SeeingIsBelieving::EventStream::Producer.new(stdout_real_fd)
22
+
24
23
  at_exit do
25
24
  stdout_real_obj.reopen stdout_real_fd
26
- stderr_real_obj.reopen stderr_real_fd
27
25
  write_to_mock_out.close unless write_to_mock_out.closed?
28
- write_to_mock_err.close unless write_to_mock_err.closed?
29
- $SiB.stdout = read_from_mock_out.read
30
- $SiB.stderr = read_from_mock_err.read
26
+ $SiB.record_stdout read_from_mock_out.read
31
27
  read_from_mock_out.close
28
+
29
+ stderr_real_obj.reopen stderr_real_fd
30
+ write_to_mock_err.close unless write_to_mock_err.closed?
31
+ $SiB.record_stderr read_from_mock_err.read
32
32
  read_from_mock_err.close
33
33
 
34
34
  $SiB.exitstatus ||= 0
@@ -36,5 +36,5 @@ at_exit do
36
36
  $SiB.exitstatus = $!.status if $!.kind_of? SystemExit
37
37
  $SiB.bug_in_sib = $! && ! $!.kind_of?(SystemExit)
38
38
 
39
- stdout_real_fd.write JSON.dump $SiB.to_primitive
39
+ $SiB.finish!
40
40
  end
@@ -1,3 +1,3 @@
1
1
  class SeeingIsBelieving
2
- VERSION = '2.2.0'
2
+ VERSION = '3.0.0.beta.1'
3
3
  end
@@ -1,3 +1,4 @@
1
+ require 'parser/current'
1
2
  require 'seeing_is_believing/parser_helpers'
2
3
 
3
4
  # comprehensive list of syntaxes that can come up
@@ -13,8 +14,8 @@ class SeeingIsBelieving
13
14
 
14
15
  def initialize(program, wrappings)
15
16
  self.program = program
16
- self.before_all = wrappings.fetch :before_all, ''.freeze
17
- self.after_all = wrappings.fetch :after_all, ''.freeze
17
+ self.before_all = wrappings.fetch :before_all, -> { ''.freeze }
18
+ self.after_all = wrappings.fetch :after_all, -> { ''.freeze }
18
19
  self.before_each = wrappings.fetch :before_each, -> * { '' }
19
20
  self.after_each = wrappings.fetch :after_each, -> * { '' }
20
21
  self.buffer, parser, self.rewriter = initialize_parser(program, 'program-without-annotations')
@@ -28,10 +29,9 @@ class SeeingIsBelieving
28
29
  @called ||= begin
29
30
  find_wrappings
30
31
 
31
- if root # file may be empty
32
- rewriter.insert_before root.location.expression, before_all
33
-
32
+ rewriter.insert_before root_range, before_all.call
34
33
 
34
+ if root # file may be empty
35
35
  wrappings.each do |line_num, (range, last_col, meta)|
36
36
  rewriter.insert_before range, before_each.call(line_num)
37
37
  if meta == :total_fucking_failure
@@ -39,11 +39,10 @@ class SeeingIsBelieving
39
39
  end
40
40
  rewriter.insert_after range, after_each.call(line_num)
41
41
  end
42
-
43
42
  range = root.location.expression
44
- rewriter.insert_after range, after_all
45
43
  end
46
44
 
45
+ rewriter.insert_after root_range, after_all_text
47
46
  rewriter.process
48
47
  end
49
48
  end
@@ -52,6 +51,26 @@ class SeeingIsBelieving
52
51
 
53
52
  attr_accessor :program, :before_all, :after_all, :before_each, :after_each, :buffer, :root, :rewriter, :wrappings
54
53
 
54
+ def root_range
55
+ if root
56
+ root.location.expression
57
+ else
58
+ Parser::Source::Range.new buffer, 0, 0
59
+ end
60
+ end
61
+
62
+ def after_all_text
63
+ after_all_text = after_all.call
64
+ data_segment_code = "__END__\n"
65
+ code_after_end_of_file = buffer.source[root_range.end_pos, data_segment_code.size]
66
+ ends_in_data_segment = code_after_end_of_file.chomp == data_segment_code.chomp
67
+ if ends_in_data_segment
68
+ "#{after_all_text}\n"
69
+ else
70
+ after_all_text
71
+ end
72
+ end
73
+
55
74
  def add_to_wrappings(range_or_ast, meta=nil)
56
75
  range = range_or_ast
57
76
  range = range_or_ast.location.expression if range.kind_of? ::AST::Node
@@ -71,7 +90,11 @@ class SeeingIsBelieving
71
90
  case ast.type
72
91
  when :args, :redo, :retry, :alias, :undef, :splat, :match_current_line
73
92
  # no op
74
- when :rescue, :ensure, :def, :return, :break, :next
93
+ when :defs
94
+ add_to_wrappings ast
95
+ child = ast.children.last
96
+ add_to_wrappings child if child
97
+ when :rescue, :ensure, :return, :break, :next
75
98
  add_children ast
76
99
  when :if
77
100
  if ast.location.kind_of? Parser::Source::Map::Ternary
@@ -84,7 +107,7 @@ class SeeingIsBelieving
84
107
  end
85
108
  add_children ast
86
109
  end
87
- when :when, :pair, :defs, :class, :module, :sclass
110
+ when :when, :pair, :class, :module, :sclass
88
111
  find_wrappings ast.children.last
89
112
  when :resbody
90
113
  exception_type, variable_name, body = ast.children
@@ -19,15 +19,15 @@ 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", ">= 2.2", "< 3.0"
23
- s.add_dependency "psych", "~> 2.0"
22
+ s.add_dependency "eval_in", "~> 0.1.6"
23
+ s.add_dependency "parser", ">= 2.1.4", "< 2.3"
24
24
 
25
- s.add_development_dependency "pry", "~> 0.10.0"
26
- s.add_development_dependency "haiti", "~> 0.1.0"
25
+ s.add_development_dependency "webmock", "~> 1.18"
26
+ s.add_development_dependency "haiti", ">= 0.1", "< 0.3"
27
27
  s.add_development_dependency "rake", "~> 10.0"
28
- s.add_development_dependency "rspec", "~> 3.0"
29
- s.add_development_dependency "cucumber", "~> 1.2"
30
- s.add_development_dependency "ichannel", "~> 5.1"
28
+ s.add_development_dependency "rspec", "~> 3.0"
29
+ s.add_development_dependency "cucumber", "~> 1.2"
30
+ s.add_development_dependency "ichannel", "~> 5.1"
31
31
 
32
32
  s.post_install_message = <<'Omg, frogs <3'.gsub(/(gg+)/) { |capture| "\e[32m#{capture.gsub 'g', '.'}\e[0m" }.gsub("brown", "\e[33m").gsub("off", "\e[0m")
33
33
  .7
@@ -1,44 +1,49 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
  require 'seeing_is_believing/binary/comment_formatter'
3
5
 
4
- describe SeeingIsBelieving::Binary::CommentFormatter do
5
- def result_for(line, separator, result, options={})
6
- described_class.new(line, separator, result, options).call
6
+ RSpec.describe SeeingIsBelieving::Binary::CommentFormatter do
7
+ def result_for(line_length, separator, result, options={})
8
+ described_class.new(line_length, separator, result, options).call
7
9
  end
8
10
 
9
11
  specify 'it returns the consolidated result if there are no truncations' do
10
12
  expect(result_for 1, '=>', '12345').to eq '=>12345'
11
13
  end
12
14
 
13
- specify 'result_length truncates a result to the specified length, using elipses up to that length if appropriate' do
15
+ specify 'max_result_length truncates a result to the specified length, using elipses up to that length if appropriate' do
14
16
  line_length = 1
15
17
  separator = '=>'
16
18
  result = '12345'
17
- expect(result_for line_length, separator, result, max_result_length: Float::INFINITY).to eq '=>12345'
18
- expect(result_for line_length, separator, result, max_result_length: 7 ).to eq '=>12345'
19
- expect(result_for line_length, separator, result, max_result_length: 6 ).to eq '=>1...'
20
- expect(result_for line_length, separator, result, max_result_length: 5 ).to eq '=>...'
21
- expect(result_for line_length, separator, result, max_result_length: 4 ).to eq ''
22
- expect(result_for line_length, separator, result, max_result_length: 0 ).to eq ''
19
+ expect(result_for line_length, separator, result, max_result_length: Float::INFINITY).to eq '=>12345'
20
+ expect(result_for line_length, separator, result, max_result_length: 7 ).to eq '=>12345'
21
+ expect(result_for line_length, separator, result, max_result_length: 6 ).to eq '=>1...'
22
+ expect(result_for line_length+1, separator, result, max_result_length: 6 ).to eq '=>1...'
23
+ expect(result_for line_length, separator, result, max_result_length: 5 ).to eq '=>...'
24
+ expect(result_for line_length, separator, result, max_result_length: 4 ).to eq ''
25
+ expect(result_for line_length, separator, result, max_result_length: 0 ).to eq ''
23
26
  end
24
27
 
25
- specify 'line_length truncates a result to the specified length, minus the length of the line' do
28
+ specify 'max_line_length truncates a result to the specified length, minus the length of the line' do
26
29
  line_length = 1
27
30
  separator = '=>'
28
31
  result = '12345'
29
- expect(result_for line_length, separator, result ).to eq '=>12345'
30
- expect(result_for line_length, separator, result, max_line_length: Float::INFINITY).to eq '=>12345'
31
- expect(result_for line_length, separator, result, max_line_length: 8 ).to eq '=>12345'
32
- expect(result_for line_length, separator, result, max_line_length: 7 ).to eq '=>1...'
33
- expect(result_for line_length, separator, result, max_line_length: 6 ).to eq '=>...'
34
- expect(result_for line_length, separator, result, max_line_length: 5 ).to eq ''
35
- expect(result_for line_length, separator, result, max_line_length: 0 ).to eq ''
32
+ expect(result_for line_length, separator, result ).to eq '=>12345'
33
+ expect(result_for line_length, separator, result, max_line_length: Float::INFINITY).to eq '=>12345'
34
+ expect(result_for line_length, separator, result, max_line_length: 8 ).to eq '=>12345'
35
+ expect(result_for line_length, separator, result, max_line_length: 7 ).to eq '=>1...'
36
+ expect(result_for line_length+1, separator, result, max_line_length: 7 ).to eq '=>...'
37
+ expect(result_for line_length, separator, result, max_line_length: 6 ).to eq '=>...'
38
+ expect(result_for line_length, separator, result, max_line_length: 5 ).to eq ''
39
+ expect(result_for line_length, separator, result, max_line_length: 0 ).to eq ''
36
40
  end
37
41
 
38
42
  specify 'pad_to will pad the length that the line is displayed in' do
39
43
  expect(result_for 1, '=>', '2', pad_to: 0).to eq '=>2'
40
44
  expect(result_for 1, '=>', '2', pad_to: 1).to eq '=>2'
41
45
  expect(result_for 1, '=>', '2', pad_to: 2).to eq ' =>2'
46
+ expect(result_for 2, '=>', '2', pad_to: 2).to eq '=>2'
42
47
  end
43
48
 
44
49
  specify 'pad_to is ignored when separator/result will not be printed' do
@@ -52,4 +57,150 @@ describe SeeingIsBelieving::Binary::CommentFormatter do
52
57
  expect(result_for 1, '=>', '12345', max_line_length: 100, max_result_length: 6, pad_to: 2).to eq ' =>1...'
53
58
  expect(result_for 1, '=>', '12345', max_line_length: 100, max_result_length: 6, pad_to: 2).to eq ' =>1...'
54
59
  end
60
+
61
+ def assert_printed(c, printed)
62
+ c = c.force_encoding 'utf-8'
63
+ expect(result_for 0, '', c).to eq printed
64
+ end
65
+
66
+ it 'escapes any non-printable characters' do
67
+ assert_printed '©' , '©'
68
+ assert_printed 0.chr , "\\u0000"
69
+ assert_printed 1.chr , "\\u0001"
70
+ assert_printed 2.chr , "\\u0002"
71
+ assert_printed 3.chr , "\\u0003"
72
+ assert_printed 4.chr , "\\u0004"
73
+ assert_printed 5.chr , "\\u0005"
74
+ assert_printed 6.chr , "\\u0006"
75
+ assert_printed 7.chr , "\\a"
76
+ assert_printed 8.chr , "\\b"
77
+ assert_printed 9.chr , "\\t"
78
+ assert_printed 10.chr , "\\n"
79
+ assert_printed 11.chr , "\\v"
80
+ assert_printed 12.chr , "\\f"
81
+ assert_printed 13.chr , "\\r"
82
+ assert_printed 14.chr , "\\u000E"
83
+ assert_printed 15.chr , "\\u000F"
84
+ assert_printed 16.chr , "\\u0010"
85
+ assert_printed 17.chr , "\\u0011"
86
+ assert_printed 18.chr , "\\u0012"
87
+ assert_printed 19.chr , "\\u0013"
88
+ assert_printed 20.chr , "\\u0014"
89
+ assert_printed 21.chr , "\\u0015"
90
+ assert_printed 22.chr , "\\u0016"
91
+ assert_printed 23.chr , "\\u0017"
92
+ assert_printed 24.chr , "\\u0018"
93
+ assert_printed 25.chr , "\\u0019"
94
+ assert_printed 26.chr , "\\u001A"
95
+ assert_printed 27.chr , "\\e"
96
+ assert_printed 28.chr , "\\u001C"
97
+ assert_printed 29.chr , "\\u001D"
98
+ assert_printed 30.chr , "\\u001E"
99
+ assert_printed 31.chr , "\\u001F"
100
+ assert_printed 32.chr , " "
101
+ assert_printed 33.chr , "!"
102
+ assert_printed 34.chr , '"' # printable, thus not escaped
103
+ assert_printed 35.chr , "#"
104
+ assert_printed 36.chr , "$"
105
+ assert_printed 37.chr , "%"
106
+ assert_printed 38.chr , "&"
107
+ assert_printed 39.chr , "'"
108
+ assert_printed 40.chr , "("
109
+ assert_printed 41.chr , ")"
110
+ assert_printed 42.chr , "*"
111
+ assert_printed 43.chr , "+"
112
+ assert_printed 44.chr , ","
113
+ assert_printed 45.chr , "-"
114
+ assert_printed 46.chr , "."
115
+ assert_printed 47.chr , "/"
116
+ assert_printed 48.chr , "0"
117
+ assert_printed 49.chr , "1"
118
+ assert_printed 50.chr , "2"
119
+ assert_printed 51.chr , "3"
120
+ assert_printed 52.chr , "4"
121
+ assert_printed 53.chr , "5"
122
+ assert_printed 54.chr , "6"
123
+ assert_printed 55.chr , "7"
124
+ assert_printed 56.chr , "8"
125
+ assert_printed 57.chr , "9"
126
+ assert_printed 58.chr , ":"
127
+ assert_printed 59.chr , ";"
128
+ assert_printed 60.chr , "<"
129
+ assert_printed 61.chr , "="
130
+ assert_printed 62.chr , ">"
131
+ assert_printed 63.chr , "?"
132
+ assert_printed 64.chr , "@"
133
+ assert_printed 65.chr , "A"
134
+ assert_printed 66.chr , "B"
135
+ assert_printed 67.chr , "C"
136
+ assert_printed 68.chr , "D"
137
+ assert_printed 69.chr , "E"
138
+ assert_printed 70.chr , "F"
139
+ assert_printed 71.chr , "G"
140
+ assert_printed 72.chr , "H"
141
+ assert_printed 73.chr , "I"
142
+ assert_printed 74.chr , "J"
143
+ assert_printed 75.chr , "K"
144
+ assert_printed 76.chr , "L"
145
+ assert_printed 77.chr , "M"
146
+ assert_printed 78.chr , "N"
147
+ assert_printed 79.chr , "O"
148
+ assert_printed 80.chr , "P"
149
+ assert_printed 81.chr , "Q"
150
+ assert_printed 82.chr , "R"
151
+ assert_printed 83.chr , "S"
152
+ assert_printed 84.chr , "T"
153
+ assert_printed 85.chr , "U"
154
+ assert_printed 86.chr , "V"
155
+ assert_printed 87.chr , "W"
156
+ assert_printed 88.chr , "X"
157
+ assert_printed 89.chr , "Y"
158
+ assert_printed 90.chr , "Z"
159
+ assert_printed 91.chr , "["
160
+ assert_printed 92.chr , "\\" # printable, thus not escaped
161
+ assert_printed 93.chr , "]"
162
+ assert_printed 94.chr , "^"
163
+ assert_printed 95.chr , "_"
164
+ assert_printed 96.chr , "`"
165
+ assert_printed 97.chr , "a"
166
+ assert_printed 98.chr , "b"
167
+ assert_printed 99.chr , "c"
168
+ assert_printed 100.chr , "d"
169
+ assert_printed 101.chr , "e"
170
+ assert_printed 102.chr , "f"
171
+ assert_printed 103.chr , "g"
172
+ assert_printed 104.chr , "h"
173
+ assert_printed 105.chr , "i"
174
+ assert_printed 106.chr , "j"
175
+ assert_printed 107.chr , "k"
176
+ assert_printed 108.chr , "l"
177
+ assert_printed 109.chr , "m"
178
+ assert_printed 110.chr , "n"
179
+ assert_printed 111.chr , "o"
180
+ assert_printed 112.chr , "p"
181
+ assert_printed 113.chr , "q"
182
+ assert_printed 114.chr , "r"
183
+ assert_printed 115.chr , "s"
184
+ assert_printed 116.chr , "t"
185
+ assert_printed 117.chr , "u"
186
+ assert_printed 118.chr , "v"
187
+ assert_printed 119.chr , "w"
188
+ assert_printed 120.chr , "x"
189
+ assert_printed 121.chr , "y"
190
+ assert_printed 122.chr , "z"
191
+ assert_printed 123.chr , "{"
192
+ assert_printed 124.chr , "|"
193
+ assert_printed 125.chr , "}"
194
+ assert_printed 126.chr , "~"
195
+ end
196
+
197
+ it 'can be given a list of characters to not escape' do
198
+ expect(result_for 0, '', "\r\n", dont_escape: ["\n"]).to eq "\\r\n"
199
+ expect(result_for 0, '', "\r\n", dont_escape: ["\r"]).to eq "\r\\n"
200
+ end
201
+
202
+ it 'escapes them before running through the other calculations' do
203
+ expect(result_for 1, '=>', "\r\n", max_line_length: 7).to eq '=>\r\n'
204
+ expect(result_for 1, '=>', "\r\n", max_line_length: 6).to eq '=>...'
205
+ end
55
206
  end