ripper_ruby_parser 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/Rakefile +2 -2
  4. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +55 -4
  5. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +20 -13
  6. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +27 -12
  7. data/lib/ripper_ruby_parser/sexp_handlers/hashes.rb +25 -12
  8. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +4 -2
  9. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +19 -15
  10. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +25 -11
  11. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +12 -4
  12. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +8 -4
  13. data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +1 -5
  14. data/lib/ripper_ruby_parser/version.rb +1 -1
  15. data/lib/ripper_ruby_parser.rb +2 -2
  16. data/test/end_to_end/comments_test.rb +4 -4
  17. data/test/end_to_end/comparison_test.rb +15 -15
  18. data/test/end_to_end/error_conditions_test.rb +16 -16
  19. data/test/end_to_end/lib_comparison_test.rb +3 -3
  20. data/test/end_to_end/line_numbering_test.rb +4 -4
  21. data/test/end_to_end/samples_comparison_test.rb +4 -4
  22. data/test/end_to_end/test_comparison_test.rb +3 -3
  23. data/test/pt_testcase/pt_test.rb +4 -4
  24. data/test/test_helper.rb +1 -1
  25. data/test/unit/commenting_ripper_parser_test.rb +33 -33
  26. data/test/unit/parser_assignment_test.rb +30 -30
  27. data/test/unit/parser_blocks_test.rb +83 -65
  28. data/test/unit/parser_conditionals_test.rb +96 -64
  29. data/test/unit/parser_literals_test.rb +308 -212
  30. data/test/unit/parser_loops_test.rb +85 -15
  31. data/test/unit/parser_method_calls_test.rb +100 -41
  32. data/test/unit/parser_operators_test.rb +60 -28
  33. data/test/unit/parser_test.rb +435 -410
  34. data/test/unit/sexp_processor_test.rb +82 -82
  35. data/test/unit/version_test.rb +1 -1
  36. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24bee2a5b16f3e73b0ee4ab6f4d9047c02838ed2
4
- data.tar.gz: bbd519d4b303b61f2ba83d8393b1c8193e877c4a
3
+ metadata.gz: 44bd9ec7c716649fbcf3698e39d9d7951b70a3d0
4
+ data.tar.gz: 1b54fd14347e28a5c253b8f00be1a641dc7cbda5
5
5
  SHA512:
6
- metadata.gz: 0a4572c224a31698738e9cfd10e0474a0fef689e1ec79aab95c29dfc67ce597008896c76dcfb96f67824c61cfb0445f3c60f294ec56699be631566f09276ca8e
7
- data.tar.gz: edd4c9d7b15846b34c4d586bdea846f484b91ed2d4df52324b95922c180850f659569e0703742c87fa67866376a76af57bc5424835d157a5aeaed1466f64508a
6
+ metadata.gz: 4fd9c3ffee9de0d9948a126ca5e44d3dc46b50b36b4fd7d9537263b84b123ebeac09118f3b0ae12f203f7c3ee1eb438bca92b2b630502b7bc83f6d3ea1a47668
7
+ data.tar.gz: c24028ea9320a5fdba4eee182d257e9f3c5db7fc57f9b3e6ba15471e90eb96b48c291b7046e8ca52b83af4957a62e6b4321901179d53fe53ea549f431baf7f85
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Change log
2
2
 
3
+ ## 1.1.2 / 2017-10-07
4
+
5
+ * Fix support for newer Ruby syntax
6
+ - Handle optional keyword arguments
7
+ - Handle mandatory keyword arguments (Ruby 2.1 and up)
8
+ - Handle double splat arguments in function definitions
9
+ - Handle double splat in hash literals and method calls
10
+ - Handle symbol arrays with %i and %I
11
+ - Handle use of dynamic symbols as hash keys (Ruby 2.2 and up)
12
+ - Handle safe call operator (Ruby 2.3 and up)
13
+ * Other bug fixes
14
+ - Fix handling of return and yield with a function call without parentheses
15
+ - Handle stabby lambdas with any number of statements
16
+ - Handle more complex interpolation in %W word arrays
17
+ - Distinguish unary minus from negative sign for int and float literals
18
+ * Compatibility improvements
19
+ - Match RubyParser's rewriting of conditionals with the negative match
20
+ operator
21
+
3
22
  ## 1.1.1 / 2017-10-03
4
23
 
5
24
  * Fix handling of non-final splats in LHS
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'rake/clean'
2
- require "bundler/gem_tasks"
2
+ require 'bundler/gem_tasks'
3
3
  require 'rake/testtask'
4
4
 
5
5
  namespace :test do
@@ -21,7 +21,7 @@ namespace :test do
21
21
  t.warning = true
22
22
  end
23
23
 
24
- desc "Run all three test suites"
24
+ desc 'Run all three test suites'
25
25
  task run: [:unit, :end_to_end, :pt_testcase]
26
26
  end
27
27
 
@@ -14,20 +14,20 @@ module RipperRubyParser
14
14
 
15
15
  def parse
16
16
  result = suppress_warnings { super }
17
- raise "Ripper parse failed." unless result
17
+ raise 'Ripper parse failed.' unless result
18
18
 
19
19
  Sexp.from_array(result)
20
20
  end
21
21
 
22
22
  def on_comment tok
23
- @comment ||= ""
23
+ @comment ||= ''
24
24
  @comment += tok
25
25
  super
26
26
  end
27
27
 
28
28
  def on_kw tok
29
29
  case tok
30
- when "class", "def", "module"
30
+ when 'class', 'def', 'module'
31
31
  unless @in_symbol
32
32
  @comment_stack.push [tok.to_sym, @comment]
33
33
  @comment = nil
@@ -56,6 +56,57 @@ module RipperRubyParser
56
56
  commentize(:def, super)
57
57
  end
58
58
 
59
+ def on_qsymbols_add list, elem
60
+ super list, [:dyna_symbol, [elem]]
61
+ end
62
+
63
+ def on_symbols_add list, elem
64
+ super list, [:dyna_symbol, elem]
65
+ end
66
+
67
+ def on_words_add list, elem
68
+ if elem.count == 1
69
+ super
70
+ else
71
+ super list, [:string_content, *elem]
72
+ end
73
+ end
74
+
75
+ def on_op(token)
76
+ @seen_space = false
77
+ super
78
+ end
79
+
80
+ def on_sp(_token)
81
+ @seen_space = true
82
+ super
83
+ end
84
+
85
+ def on_int(_token)
86
+ @space_before = @seen_space
87
+ super
88
+ end
89
+
90
+ def on_float(_token)
91
+ @space_before = @seen_space
92
+ super
93
+ end
94
+
95
+ NUMBER_LITERAL_TYPES = [:@int, :@float]
96
+
97
+ def on_unary(op, value)
98
+ if !@space_before && op == :-@ && NUMBER_LITERAL_TYPES.include?(value.first)
99
+ type, literal, lines = value
100
+ if literal[0] == '-'
101
+ super
102
+ else
103
+ [type, "-#{literal}", lines]
104
+ end
105
+ else
106
+ super
107
+ end
108
+ end
109
+
59
110
  def on_symbeg *args
60
111
  @in_symbol = true
61
112
  super
@@ -105,7 +156,7 @@ module RipperRubyParser
105
156
  unless tok == name
106
157
  raise "Expected on_#{tok} event, got on_#{name}"
107
158
  end
108
- [:comment, comment || "", exp]
159
+ [:comment, comment || '', exp]
109
160
  end
110
161
 
111
162
  def suppress_warnings
@@ -22,21 +22,17 @@ module RipperRubyParser
22
22
  if exp.size == 6
23
23
  _, normal, defaults, splat, rest, block = exp.shift 6
24
24
  else
25
- _, normal, defaults, splat, rest, _, _, block = exp.shift 8
25
+ _, normal, defaults, splat, rest, kwargs, doublesplat, block = exp.shift 8
26
26
  end
27
27
 
28
- args = [*normal].map do |id|
29
- process(id)
30
- end
31
-
32
- [*defaults].each do |pair|
33
- sym = process(pair[0])
34
- val = process(pair[1])
35
- args << s(:lasgn, sym[1], val)
36
- end
28
+ args = []
29
+ args += normal.map { |id| process(id) } if normal
30
+ args += defaults.map { |sym, val| s(:lasgn, process(sym)[1], process(val)) } if defaults
37
31
 
38
32
  args << process(splat) unless splat.nil? || splat == 0
39
- [*rest].each { |arg| args << process(arg) }
33
+ args += rest.map { |it| process(it) } if rest
34
+ args += handle_kwargs kwargs if kwargs
35
+ args << s(:dsplat, process(doublesplat)) if doublesplat
40
36
  args << process(block) unless block.nil?
41
37
 
42
38
  s(:args, *args)
@@ -125,7 +121,7 @@ module RipperRubyParser
125
121
 
126
122
  def process_ensure exp
127
123
  _, block = exp.shift 2
128
- strip_typeless_sexp safe_wrap_in_block s(*map_body(block))
124
+ strip_typeless_sexp safe_wrap_in_block map_body(block)
129
125
  end
130
126
 
131
127
  def process_next exp
@@ -153,7 +149,7 @@ module RipperRubyParser
153
149
  args = 0 if args == s(:args) && old_type == :params
154
150
  make_iter(s(:call, nil, :lambda),
155
151
  args,
156
- *handle_potentially_typeless_sexp(statements))
152
+ wrap_in_block(map_body(statements)))
157
153
  end
158
154
 
159
155
  private
@@ -165,6 +161,17 @@ module RipperRubyParser
165
161
  s(:block, args, s(wrap_in_block(map_body(stmts))))
166
162
  end
167
163
 
164
+ def handle_kwargs(kwargs)
165
+ kwargs.map do |sym, val|
166
+ symbol = process(sym)[1]
167
+ if val
168
+ s(:kwarg, symbol, process(val))
169
+ else
170
+ s(:kwarg, symbol)
171
+ end
172
+ end
173
+ end
174
+
168
175
  def strip_typeless_sexp block
169
176
  case block.length
170
177
  when 0
@@ -4,9 +4,9 @@ module RipperRubyParser
4
4
  def process_if exp
5
5
  _, cond, truepart, falsepart = exp.shift 4
6
6
 
7
- s(:if, handle_condition(cond),
8
- wrap_in_block(map_body(truepart)),
9
- process(falsepart))
7
+ construct_conditional(handle_condition(cond),
8
+ wrap_in_block(map_body(truepart)),
9
+ process(falsepart))
10
10
  end
11
11
 
12
12
  def process_elsif exp
@@ -19,20 +19,26 @@ module RipperRubyParser
19
19
 
20
20
  def process_if_mod exp
21
21
  _, cond, truepart = exp.shift 3
22
- s(:if, handle_condition(cond), process(truepart), nil)
23
- end
24
22
 
25
- def process_unless_mod exp
26
- _, cond, truepart = exp.shift 3
27
- s(:if, handle_condition(cond), nil, process(truepart))
23
+ construct_conditional(handle_condition(cond),
24
+ process(truepart),
25
+ nil)
28
26
  end
29
27
 
30
28
  def process_unless exp
31
29
  _, cond, truepart, falsepart = exp.shift 4
32
- s(:if,
33
- handle_condition(cond),
34
- process(falsepart),
35
- wrap_in_block(map_body(truepart)))
30
+
31
+ construct_conditional(handle_condition(cond),
32
+ process(falsepart),
33
+ wrap_in_block(map_body(truepart)))
34
+ end
35
+
36
+ def process_unless_mod exp
37
+ _, cond, truepart = exp.shift 3
38
+
39
+ construct_conditional(handle_condition(cond),
40
+ nil,
41
+ process(truepart))
36
42
  end
37
43
 
38
44
  def process_case exp
@@ -83,6 +89,15 @@ module RipperRubyParser
83
89
  cond
84
90
  end
85
91
  end
92
+
93
+ def construct_conditional(cond, truepart, falsepart)
94
+ if cond.sexp_type == :not
95
+ _, inner = cond
96
+ s(:if, inner, falsepart, truepart)
97
+ else
98
+ s(:if, cond, truepart, falsepart)
99
+ end
100
+ end
86
101
  end
87
102
  end
88
103
  end
@@ -1,21 +1,28 @@
1
1
  module RipperRubyParser
2
2
  module SexpHandlers
3
3
  module Hashes
4
+ # Handle hash literals sexps. These can be either empty, or contain a
5
+ # nested :assoclist_from_args Sexp.
6
+ #
7
+ # @example Empty hash
8
+ # s(:hash, nil)
9
+ # @example Hash with contents
10
+ # s(:hash, s(:assoclist_from_args, ...))
4
11
  def process_hash exp
5
- _, elems = exp.shift 2
6
- s(:hash, *process(elems))
7
- end
8
-
9
- def process_assoclist_from_args exp
10
- _, elems = exp.shift 2
11
- make_hash_items elems
12
+ _, body = exp.shift 2
13
+ return s(:hash) unless body
14
+ _, elems = body
15
+ s(:hash, *make_hash_items(elems))
12
16
  end
13
17
 
14
- def process_assoc_new exp
15
- _, left, right = exp.shift 3
16
- s(process(left), process(right))
18
+ # @example
19
+ # s(:assoc_splat, s(:vcall, s(:@ident, "bar")))
20
+ def process_assoc_splat exp
21
+ _, param = exp.shift 2
22
+ s(:kwsplat, process(param))
17
23
  end
18
24
 
25
+ # Handle implied hashes, such as at the end of argument lists.
19
26
  def process_bare_assoc_hash exp
20
27
  _, elems = exp.shift 2
21
28
  s(:hash, *make_hash_items(elems))
@@ -23,11 +30,17 @@ module RipperRubyParser
23
30
 
24
31
  private
25
32
 
33
+ # Process list of items that can be either :assoc_new or :assoc_splat
26
34
  def make_hash_items elems
27
35
  result = s()
28
36
  elems.each do |sub_exp|
29
- process(sub_exp).each do |elm|
30
- result << elm
37
+ case sub_exp.sexp_type
38
+ when :assoc_new
39
+ sub_exp.sexp_body.each { |elem| result << process(elem) }
40
+ when :assoc_splat
41
+ result << process(sub_exp)
42
+ else
43
+ raise ArgumentError
31
44
  end
32
45
  end
33
46
  result
@@ -92,8 +92,10 @@ module RipperRubyParser
92
92
  end
93
93
 
94
94
  def handle_return_argument_list arglist
95
- arglist = process(arglist)
96
- args = arglist[1..-1]
95
+ args = handle_potentially_typeless_sexp(arglist)
96
+ if args.sexp_type == :arglist
97
+ args = args[1..-1]
98
+ end
97
99
 
98
100
  if args.length == 1
99
101
  arg = args[0]
@@ -25,16 +25,16 @@ module RipperRubyParser
25
25
  when :str
26
26
  val
27
27
  when :void_stmt
28
- s(:dstr, "", s(:evstr))
28
+ s(:dstr, '', s(:evstr))
29
29
  else
30
- s(:dstr, "", s(:evstr, val))
30
+ s(:dstr, '', s(:evstr, val))
31
31
  end
32
32
  end
33
33
 
34
34
  def process_string_dvar exp
35
35
  _, list = exp.shift 2
36
36
  val = process(list)
37
- s(:dstr, "", s(:evstr, val))
37
+ s(:dstr, '', s(:evstr, val))
38
38
  end
39
39
 
40
40
  def process_string_concat exp
@@ -48,7 +48,7 @@ module RipperRubyParser
48
48
  right
49
49
  else # Expecting left.sexp_type == :dstr
50
50
  _, first, *rest = right
51
- left.push s(:str, first) unless first.empty?
51
+ left.push s(:str, first) if !first.empty? || rest.empty?
52
52
  left.push(*rest)
53
53
  left
54
54
  end
@@ -96,7 +96,11 @@ module RipperRubyParser
96
96
  def process_dyna_symbol exp
97
97
  _, list = exp.shift 2
98
98
 
99
- string, rest = extract_unescaped_string_parts list
99
+ if list.sexp_type == :string_content
100
+ string, rest = extract_unescaped_string_parts list.sexp_body
101
+ else
102
+ string, rest = extract_unescaped_string_parts list
103
+ end
100
104
  if rest.empty?
101
105
  s(:lit, string.to_sym)
102
106
  else
@@ -114,7 +118,7 @@ module RipperRubyParser
114
118
  def extract_string_parts exp
115
119
  parts = internal_process_string_parts(exp)
116
120
 
117
- string = ""
121
+ string = ''
118
122
  while !parts.empty? && parts.first.sexp_type == :str
119
123
  str = parts.shift
120
124
  string += str[1]
@@ -156,15 +160,15 @@ module RipperRubyParser
156
160
  end
157
161
 
158
162
  SINGLE_LETTER_ESCAPES = {
159
- "a" => "\a",
160
- "b" => "\b",
161
- "e" => "\e",
162
- "f" => "\f",
163
- "n" => "\n",
164
- "r" => "\r",
165
- "s" => "\s",
166
- "t" => "\t",
167
- "v" => "\v"
163
+ 'a' => "\a",
164
+ 'b' => "\b",
165
+ 'e' => "\e",
166
+ 'f' => "\f",
167
+ 'n' => "\n",
168
+ 'r' => "\r",
169
+ 's' => "\s",
170
+ 't' => "\t",
171
+ 'v' => "\v"
168
172
  }.freeze
169
173
 
170
174
  SINGLE_LETTER_ESCAPES_REGEXP =
@@ -2,19 +2,19 @@ module RipperRubyParser
2
2
  module SexpHandlers
3
3
  module Loops
4
4
  def process_until exp
5
- handle_conditional_loop(:until, exp)
5
+ handle_conditional_loop :until, :while, exp
6
6
  end
7
7
 
8
8
  def process_until_mod exp
9
- handle_conditional_loop_mod(:until, exp)
9
+ handle_conditional_loop_mod :until, :while, exp
10
10
  end
11
11
 
12
12
  def process_while exp
13
- handle_conditional_loop(:while, exp)
13
+ handle_conditional_loop :while, :until, exp
14
14
  end
15
15
 
16
16
  def process_while_mod exp
17
- handle_conditional_loop_mod(:while, exp)
17
+ handle_conditional_loop_mod :while, :until, exp
18
18
  end
19
19
 
20
20
  def process_for exp
@@ -35,18 +35,32 @@ module RipperRubyParser
35
35
  block.sexp_type != :begin
36
36
  end
37
37
 
38
- def handle_conditional_loop type, exp
39
- _, cond, block = exp.shift 3
38
+ def handle_conditional_loop type, negated_type, exp
39
+ _, cond, body = exp.shift 3
40
40
 
41
- s(type, process(cond), wrap_in_block(map_body(block)), true)
41
+ construct_conditional_loop(type, negated_type,
42
+ process(cond),
43
+ wrap_in_block(map_body(body)),
44
+ true)
42
45
  end
43
46
 
44
- def handle_conditional_loop_mod type, exp
45
- _, cond, block = exp.shift 3
47
+ def handle_conditional_loop_mod type, negated_type, exp
48
+ _, cond, body = exp.shift 3
46
49
 
47
- check_at_start = check_at_start?(block)
50
+ check_at_start = check_at_start?(body)
51
+ construct_conditional_loop(type, negated_type,
52
+ process(cond),
53
+ process(body),
54
+ check_at_start)
55
+ end
48
56
 
49
- s(type, process(cond), process(block), check_at_start)
57
+ def construct_conditional_loop(type, negated_type, cond, body, check_at_start)
58
+ if cond.sexp_type == :not
59
+ _, inner = cond
60
+ s(negated_type, inner, body, check_at_start)
61
+ else
62
+ s(type, cond, body, check_at_start)
63
+ end
50
64
  end
51
65
  end
52
66
  end
@@ -14,10 +14,17 @@ module RipperRubyParser
14
14
  call
15
15
  end
16
16
 
17
+ CALL_OP_MAP = {
18
+ :'.' => :call,
19
+ :'::' => :call,
20
+ :'&.' => :safe_call
21
+ }
22
+
17
23
  def process_call exp
18
- _, receiver, _, ident = exp.shift 4
24
+ _, receiver, op, ident = exp.shift 4
25
+ type = CALL_OP_MAP.fetch op
19
26
  with_position_from_node_symbol(ident) do |method|
20
- s(:call, process(receiver), method)
27
+ s(type, process(receiver), method)
21
28
  end
22
29
  end
23
30
 
@@ -30,10 +37,11 @@ module RipperRubyParser
30
37
  end
31
38
 
32
39
  def process_command_call exp
33
- _, receiver, _, ident, arguments = exp.shift 5
40
+ _, receiver, op, ident, arguments = exp.shift 5
41
+ type = CALL_OP_MAP.fetch op
34
42
  with_position_from_node_symbol(ident) do |method|
35
43
  args = handle_argument_list(arguments)
36
- s(:call, process(receiver), method, *args)
44
+ s(type, process(receiver), method, *args)
37
45
  end
38
46
  end
39
47
 
@@ -31,8 +31,11 @@ module RipperRubyParser
31
31
 
32
32
  def process_yield exp
33
33
  _, arglist = exp.shift 2
34
- arglist = process arglist
35
- s(:yield, *arglist[1..-1])
34
+ args = handle_potentially_typeless_sexp(arglist)
35
+ if args.sexp_type == :arglist
36
+ args = args[1..-1]
37
+ end
38
+ s(:yield, *args)
36
39
  end
37
40
 
38
41
  def process_yield0 exp
@@ -90,8 +93,9 @@ module RipperRubyParser
90
93
  end
91
94
 
92
95
  SPECIAL_ARG_MARKER = {
93
- splat: "*",
94
- blockarg: "&"
96
+ splat: '*',
97
+ dsplat: '**',
98
+ blockarg: '&'
95
99
  }.freeze
96
100
 
97
101
  def convert_special_args args
@@ -52,11 +52,7 @@ module RipperRubyParser
52
52
  _, op, arg = exp.shift 3
53
53
  arg = process(arg)
54
54
  op = UNARY_OPERATOR_MAP[op] || op
55
- if literal?(arg) && op != :!
56
- s(:lit, arg[1].send(op))
57
- else
58
- s(:call, arg, op)
59
- end
55
+ s(:call, arg, op)
60
56
  end
61
57
 
62
58
  def process_dot2 exp
@@ -1,3 +1,3 @@
1
1
  module RipperRubyParser
2
- VERSION = '1.1.1'.freeze
2
+ VERSION = '1.1.2'.freeze
3
3
  end
@@ -1,5 +1,5 @@
1
- if RUBY_VERSION < "1.9.3"
2
- raise LoadError, "Only ruby version 1.9.3 and up are supported"
1
+ if RUBY_VERSION < '1.9.3'
2
+ raise LoadError, 'Only ruby version 1.9.3 and up are supported'
3
3
  end
4
4
 
5
5
  require 'ripper_ruby_parser/version'
@@ -1,7 +1,7 @@
1
1
  require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
2
  require 'ruby_parser'
3
3
 
4
- describe "Using RipperRubyParser and RubyParser" do
4
+ describe 'Using RipperRubyParser and RubyParser' do
5
5
  let :newparser do
6
6
  RipperRubyParser::Parser.new
7
7
  end
@@ -10,7 +10,7 @@ describe "Using RipperRubyParser and RubyParser" do
10
10
  RubyParser.new
11
11
  end
12
12
 
13
- describe "for a program with quite some comments" do
13
+ describe 'for a program with quite some comments' do
14
14
  let :program do
15
15
  <<-END
16
16
  # Foo
@@ -46,11 +46,11 @@ describe "Using RipperRubyParser and RubyParser" do
46
46
  newparser.parse program
47
47
  end
48
48
 
49
- it "gives the same result" do
49
+ it 'gives the same result' do
50
50
  imitation.must_equal original
51
51
  end
52
52
 
53
- it "gives the same result with comments" do
53
+ it 'gives the same result with comments' do
54
54
  to_comments(imitation).must_equal to_comments(original)
55
55
  end
56
56
  end