seeing_is_believing 2.2.0 → 3.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
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