sourcify 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitignore +1 -0
  2. data/HISTORY.txt +11 -0
  3. data/README.rdoc +52 -28
  4. data/VERSION +1 -1
  5. data/lib/sourcify.rb +13 -1
  6. data/lib/sourcify/proc.rb +7 -4
  7. data/lib/sourcify/proc/parser.rb +109 -40
  8. data/lib/sourcify/proc/scanner.rb +2140 -0
  9. data/lib/sourcify/proc/scanner.rl +285 -0
  10. data/lib/sourcify/proc/scanner/comment.rb +21 -0
  11. data/lib/sourcify/proc/scanner/counter.rb +44 -0
  12. data/lib/sourcify/proc/scanner/dstring.rb +58 -0
  13. data/lib/sourcify/proc/scanner/extensions.rb +135 -0
  14. data/lib/sourcify/proc/scanner/heredoc.rb +24 -0
  15. data/sourcify.gemspec +38 -9
  16. data/spec/dump_object_space_procs.rb +84 -0
  17. data/spec/proc/created_on_the_fly_proc_spec.rb +172 -0
  18. data/spec/proc/others_spec.rb +36 -0
  19. data/spec/proc/to_sexp_variables_spec.rb +6 -6
  20. data/spec/proc/to_source_from_do_end_block_w_nested_literal_keyword_spec.rb +2 -0
  21. data/spec/proc/to_source_from_multi_blocks_w_many_matches_spec.rb +105 -29
  22. data/spec/proc/to_source_from_multi_blocks_w_single_match_spec.rb +85 -17
  23. data/spec/proc_scanner/block_comment_spec.rb +59 -0
  24. data/spec/proc_scanner/double_colons_spec.rb +14 -0
  25. data/spec/proc_scanner/double_quote_str_w_interpolation_spec.rb +62 -0
  26. data/spec/proc_scanner/double_quote_str_wo_interpolation_spec.rb +75 -0
  27. data/spec/proc_scanner/heredoc_spec.rb +142 -0
  28. data/spec/proc_scanner/kw_do_alias1_spec.rb +87 -0
  29. data/spec/proc_scanner/kw_do_alias2_spec.rb +86 -0
  30. data/spec/proc_scanner/per_line_comment_spec.rb +34 -0
  31. data/spec/proc_scanner/single_quote_str_spec.rb +68 -0
  32. data/spec/proc_scanner/spec_helper.rb +33 -0
  33. data/spec/proc_scanner/to_proc_spec.rb +15 -0
  34. data/spec/spec_helper.rb +23 -0
  35. metadata +39 -10
  36. data/lib/sourcify/proc/counter.rb +0 -41
  37. data/lib/sourcify/proc/lexer.rb +0 -40
  38. data/lib/sourcify/proc/lexer18.rb +0 -237
  39. data/lib/sourcify/proc/lexer19.rb +0 -204
  40. data/spec/proc/misc_spec.rb +0 -16
@@ -2,6 +2,8 @@ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
2
 
3
3
  describe "Proc#to_source from do ... end block (w nested literal keyword)" do
4
4
 
5
+ # See http://redmine.ruby-lang.org/issues/show/3764
6
+
5
7
  should 'handle :class' do
6
8
  (
7
9
  lambda do
@@ -32,40 +32,116 @@ describe 'Proc#to_source from multi blocks w many matches' do
32
32
 
33
33
  else
34
34
 
35
- # Need this line since the parser file is dynamically required, otherwise we will get
36
- # undefined constant error
37
- require 'sourcify/proc/parser'
38
-
39
- should 'raise Sourcify::MultipleMatchingProcsPerLineError (all do...end blocks)' do
40
- lambda {
41
- (
42
- b1 = lambda do |a| @x1 end; b2 = lambda do @x1 end; b3 = lambda do @x1 end ; b2
43
- ).to_source
44
- }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
45
- end
35
+ describe 'wo nesting on same line' do
36
+
37
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (all do...end blocks)' do
38
+ lambda {
39
+ (
40
+ b1 = lambda do |a| @x1 end; b2 = lambda do @x1 end; b3 = lambda do @x1 end ; b2
41
+ ).to_source
42
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
43
+ end
44
+
45
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (all {...} blocks)' do
46
+ lambda {
47
+ (
48
+ b1 = lambda {|a| @x2 }; b2 = lambda { @x2 }; b3 = lambda { @x2 } ; b2
49
+ ).to_source
50
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
51
+ end
52
+
53
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (mixed {...} w do...end blocks)' do
54
+ lambda {
55
+ (
56
+ b1 = lambda {|a| @x3 }; b2 = lambda do @x3 end; b3 = lambda { @x4 } ; b2
57
+ ).to_source
58
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
59
+ end
60
+
61
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (mixed do...end w {...} blocks)' do
62
+ lambda {
63
+ (
64
+ b1 = lambda do |a| @x4 end; b2 = lambda { @x4 }; b3 = lambda do @x4 end ; b2
65
+ ).to_source
66
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
67
+ end
46
68
 
47
- should 'raise Sourcify::MultipleMatchingProcsPerLineError (all {...} blocks)' do
48
- lambda {
49
- (
50
- b1 = lambda {|a| @x2 }; b2 = lambda { @x2 }; b3 = lambda { @x2 } ; b2
51
- ).to_source
52
- }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
53
69
  end
54
70
 
55
- should 'raise Sourcify::MultipleMatchingProcsPerLineError (mixed {...} w do...end blocks)' do
56
- lambda {
57
- (
58
- b1 = lambda {|a| @x3 }; b2 = lambda do @x3 end; b3 = lambda { @x4 } ; b2
59
- ).to_source
60
- }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
71
+ describe 'w single level nesting on same line' do
72
+
73
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (all do...end blocks)' do
74
+ lambda {
75
+ (
76
+ b1 = lambda do |a| @x1 end; b2 = lambda do lambda do @x1 end end; b2
77
+ ).to_source
78
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
79
+ end
80
+
81
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (all {...} blocks)' do
82
+ lambda {
83
+ (
84
+ b1 = lambda {|a| @x2 }; b2 = lambda { lambda { @x2 } }; b2
85
+ ).to_source
86
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
87
+ end
88
+
89
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (mixed {...} w do...end blocks)' do
90
+ lambda {
91
+ (
92
+ b1 = lambda {|a| @x3 }; b2 = lambda do lambda { @x4 } end; b2
93
+ ).to_source
94
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
95
+ end
96
+
97
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (mixed do...end w {...} blocks)' do
98
+ lambda {
99
+ (
100
+ b1 = lambda do |a| @x4 end; b2 = lambda { lambda do @x4 end }; b2
101
+ ).to_source
102
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
103
+ end
104
+
61
105
  end
62
106
 
63
- should 'raise Sourcify::MultipleMatchingProcsPerLineError (mixed do...end w {...} blocks)' do
64
- lambda {
65
- (
66
- b1 = lambda do |a| @x4 end; b2 = lambda { @x4 }; b3 = lambda do @x4 end ; b2
67
- ).to_source
68
- }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
107
+ describe 'w multi level nesting on same line' do
108
+
109
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (all do...end blocks)' do
110
+ lambda {
111
+ (
112
+ b1 = lambda do |a| lambda do lambda do @x1 end end end
113
+ b2 = b1.call(1)
114
+ ).to_source
115
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
116
+ end
117
+
118
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (all {...} blocks)' do
119
+ lambda {
120
+ (
121
+ b1 = lambda {|a| lambda { lambda { @x2 } } }
122
+ b2 = b1.call(1)
123
+ ).to_source
124
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
125
+ end
126
+
127
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (mixed {...} w do...end blocks)' do
128
+ lambda {
129
+ (
130
+ b1 = lambda {|a| lambda do lambda { @x4 } end }
131
+ b2 = b1.call(1)
132
+ ).to_source
133
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
134
+ end
135
+
136
+ should 'raise Sourcify::MultipleMatchingProcsPerLineError (mixed do...end w {...} blocks)' do
137
+ lambda {
138
+ (
139
+ b1 = lambda do |a| lambda { lambda do @x4 end } end
140
+ b2 = b1.call(1)
141
+ ).to_source
142
+ }.should.raise(Sourcify::MultipleMatchingProcsPerLineError)
143
+ end
144
+
69
145
  end
70
146
 
71
147
  end
@@ -4,28 +4,96 @@ describe 'Proc#to_source from multi blocks w single match' do
4
4
 
5
5
  expected = 'proc { @x%s }'
6
6
 
7
- should 'skip non-matching (all do...end blocks)' do
8
- (
9
- b1 = lambda do |a| @x1 end; b2 = lambda do @x1 end; b2
10
- ).should.be having_source(expected%1)
11
- end
7
+ describe 'wo nesting on same line' do
8
+
9
+ should 'skip non-matching (all do...end blocks)' do
10
+ (
11
+ b1 = lambda do |a| @x1 end; b2 = lambda do @x1 end; b2
12
+ ).should.be having_source(expected%1)
13
+ end
14
+
15
+ should 'skip non-matching (all {...} blocks)' do
16
+ (
17
+ b1 = lambda {|a| @x2 }; b2 = lambda { @x2 }; b2
18
+ ).should.be having_source(expected%2)
19
+ end
20
+
21
+ should 'skip non-matching (mixed {...} with do...end blocks)' do
22
+ (
23
+ b1 = lambda {|a| @x3 }; b2 = lambda do @x3 end; b2
24
+ ).should.be having_source(expected%3)
25
+ end
26
+
27
+ should 'skip non-matching (mixed do...end with {...} blocks)' do
28
+ (
29
+ b1 = lambda do |a| @x4 end; b2 = lambda { @x4 }; b2
30
+ ).should.be having_source(expected%4)
31
+ end
12
32
 
13
- should 'skip non-matching (all {...} blocks)' do
14
- (
15
- b1 = lambda {|a| @x2 }; b2 = lambda { @x2 }; b2
16
- ).should.be having_source(expected%2)
17
33
  end
18
34
 
19
- should 'skip non-matching (mixed {...} with do...end blocks)' do
20
- (
21
- b1 = lambda {|a| @x3 }; b2 = lambda do @x3 end; b2
22
- ).should.be having_source(expected%3)
35
+ describe 'w single level nesting on same line' do
36
+
37
+ should 'skip non-matching (all do...end blocks)' do
38
+ (
39
+ b1 = lambda do |a| lambda do @x1 end end
40
+ b2 = b1.call(1) # returns the inner proc
41
+ ).should.be having_source(expected%1)
42
+ end
43
+
44
+ should 'skip non-matching (all {...} blocks)' do
45
+ (
46
+ b1 = lambda {|a| lambda { @x2 } }
47
+ b2 = b1.call(1) # returns the inner proc
48
+ ).should.be having_source(expected%2)
49
+ end
50
+
51
+ should 'skip non-matching (mixed {...} with do...end blocks)' do
52
+ (
53
+ b1 = lambda {|a| lambda do @x3 end }
54
+ b2 = b1.call(1) # returns the inner proc
55
+ ).should.be having_source(expected%3)
56
+ end
57
+
58
+ should 'skip non-matching (mixed do...end with {...} blocks)' do
59
+ (
60
+ b1 = lambda do |a| lambda { @x4 } end
61
+ b2 = b1.call(1) # returns the inner proc
62
+ ).should.be having_source(expected%4)
63
+ end
64
+
23
65
  end
24
66
 
25
- should 'skip non-matching (mixed do...end with {...} blocks)' do
26
- (
27
- b1 = lambda do |a| @x4 end; b2 = lambda { @x4 }; b2
28
- ).should.be having_source(expected%4)
67
+ describe 'w multi level nesting on same line' do
68
+
69
+ should 'skip non-matching (all do...end blocks)' do
70
+ (
71
+ b1 = lambda do |a| lambda do |a| b2 = lambda do @x1 end end end
72
+ b2 = b1.call(1).call(1) # returns the inner-most proc
73
+ ).should.be having_source(expected%1)
74
+ end
75
+
76
+ should 'skip non-matching (all {...} blocks)' do
77
+ (
78
+ b1 = lambda {|a| lambda {|a| b2 = lambda { @x2 } } }
79
+ b2 = b1.call(1).call(1) # returns the inner-most proc
80
+ ).should.be having_source(expected%2)
81
+ end
82
+
83
+ should 'skip non-matching (mixed {...} with do...end blocks)' do
84
+ (
85
+ b1 = lambda {|a| lambda do |a| b2 = lambda do @x3 end end }
86
+ b2 = b1.call(1).call(1) # returns the inner-most proc
87
+ ).should.be having_source(expected%3)
88
+ end
89
+
90
+ should 'skip non-matching (mixed do...end with {...} blocks)' do
91
+ (
92
+ b1 = lambda do |a| lambda do |a| lambda { @x4 } end end
93
+ b2 = b1.call(1).call(1) # returns the inner-most proc
94
+ ).should.be having_source(expected%4)
95
+ end
96
+
29
97
  end
30
98
 
31
99
  end
@@ -0,0 +1,59 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "Block comment (=begin ... =end)" do
4
+
5
+ should 'handle =begin\n ... =end\n' do
6
+ process(<<EOL
7
+ aa
8
+ =begin
9
+ bb
10
+ =end
11
+ cc
12
+ EOL
13
+ ).should.include([:comment, "\n=begin\n bb \n=end"])
14
+ end
15
+
16
+ should 'handle =begin \n ... =end\n' do
17
+ process(<<EOL
18
+ aa
19
+ =begin
20
+ bb
21
+ =end
22
+ cc
23
+ EOL
24
+ ).should.include([:comment, "\n=begin \n bb \n=end"])
25
+ end
26
+
27
+ should 'handle =begin aa \n ... =end\n' do
28
+ process(<<EOL
29
+
30
+ =begin aa
31
+ bb
32
+ =end
33
+ cc
34
+ EOL
35
+ ).should.include([:comment, "\n=begin aa \n bb \n=end"])
36
+ end
37
+
38
+ should 'handle =begin\n ... =end \n' do
39
+ process(<<EOL
40
+ aa
41
+ =begin
42
+ bb
43
+ =end
44
+ cc
45
+ EOL
46
+ ).should.include([:comment, "\n=begin\n bb \n=end "])
47
+ end
48
+
49
+ should 'not handle =begin\n ... =end ... \n' do
50
+ process(<<EOL
51
+ aa
52
+ =begin
53
+ bb
54
+ =end cc
55
+ EOL
56
+ ).should.not.include([:comment, "\n=begin\n bb \n=end cc"])
57
+ end
58
+
59
+ end
@@ -0,0 +1,14 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "Double colons" do
4
+
5
+ should "handle A::B as :const" do
6
+ process(" A::B ").should.include([:const, 'A::B'])
7
+ end
8
+
9
+ should "handle A::aa as :const" do
10
+ process(" A::aa ").should.include([:const, 'A::aa'])
11
+ end
12
+
13
+ end
14
+
@@ -0,0 +1,62 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe 'Double quote strings (w interpolation)' do
4
+
5
+ # NOTE: we skip %Q#...# cos %Q#..#{..}..# is invalid syntax.
6
+ %w{~ ` ! @ $ % ^ & * _ - + = | ; : ' " , . ? / \\}.map{|w| [w,w] }.concat(
7
+ [%w{( )}, %w{[ ]}, %w({ }), %w{< >}]
8
+ ).each do |q1,q2|
9
+ ['Q', 'W', 'x', 'r', ''].each do |t|
10
+
11
+ should "handle %#{t}#{q1}...#{q2} (wo nesting (single))" do
12
+ process(" xx %#{t}#{q1}h\#{%#{t}#{q1}ell#{q2}}o#{q2} ").
13
+ should.include([:dstring, "%#{t}#{q1}h\#{%#{t}#{q1}ell#{q2}}o#{q2}"])
14
+ end
15
+
16
+ should "handle %#{t}#{q1}...#{q2} (wo nesting (multiple))" do
17
+ tokens = process(" xx %#{t}#{q1}h\#{%#{t}#{q1}ell#{q2}}o#{q2} %#{t}#{q1}w\#{%#{t}#{q1}orl#{q2}}d#{q2} ")
18
+ tokens.should.include([:dstring, "%#{t}#{q1}h\#{%#{t}#{q1}ell#{q2}}o#{q2}"])
19
+ tokens.should.include([:dstring, "%#{t}#{q1}w\#{%#{t}#{q1}orl#{q2}}d#{q2}"])
20
+ end
21
+
22
+ should "handle %#{t}#{q1}...#{q2} (w nesting (single))" do
23
+ process(" xx %#{t}#{q1}h\#{%#{t}#{q1}e\#{%#{t}#{q1}l#{q2}}l#{q2}}o#{q2} ").
24
+ should.include([:dstring, "%#{t}#{q1}h\#{%#{t}#{q1}e\#{%#{t}#{q1}l#{q2}}l#{q2}}o#{q2}"])
25
+ end
26
+
27
+ should "handle %#{t}#{q1}...#{q2} (w nesting (multiple))" do
28
+ tokens = process(" xx " +
29
+ "%#{t}#{q1}h\#{%#{t}#{q1}e\#{%#{t}#{q1}l#{q2}}l#{q2}}o#{q2} " +
30
+ "%#{t}#{q1}w\#{%#{t}#{q1}o\#{%#{t}#{q1}r#{q2}}l#{q2}}d#{q2} "
31
+ )
32
+ tokens.should.include([:dstring, "%#{t}#{q1}h\#{%#{t}#{q1}e\#{%#{t}#{q1}l#{q2}}l#{q2}}o#{q2}"])
33
+ tokens.should.include([:dstring, "%#{t}#{q1}w\#{%#{t}#{q1}o\#{%#{t}#{q1}r#{q2}}l#{q2}}d#{q2}"])
34
+ end
35
+
36
+ end
37
+ end
38
+
39
+ %w{" / `}.each do |q|
40
+
41
+ should "handle #{q}...#{q} (wo escape (single))" do
42
+ process(%Q( xx #{q}hello#{q} )).should.include([:dstring, %Q(#{q}hello#{q})])
43
+ end
44
+
45
+ should "handle #{q}...#{q} (wo escape & multiple)" do
46
+ tokens = process(%Q( xx #{q}hello#{q} #{q}world#{q} ))
47
+ tokens.should.include([:dstring, %Q(#{q}hello#{q})])
48
+ tokens.should.include([:dstring, %Q(#{q}world#{q})])
49
+ end
50
+
51
+ should "handle #{q}...#{q} (w escape (single))" do
52
+ process(%Q( xx #{q}hel\\#{q}lo#{q} )).should.
53
+ include([:dstring, %Q(#{q}hel\\#{q}lo#{q})])
54
+ end
55
+
56
+ should "handle #{q}...#{q} (w escape (multiple))" do
57
+ process(%Q( xx #{q}h\\#{q}el\\#{q}lo#{q} )).should.include([:dstring, %Q(#{q}h\\#{q}el\\#{q}lo#{q})])
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,75 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe 'Double quote strings (wo interpolation)' do
4
+
5
+ %w{~ ` ! @ # $ % ^ & * _ - + = | \\ ; : ' " , . ? /}.map{|w| [w,w] }.concat(
6
+ [%w{( )}, %w{[ ]}, %w({ }), %w{< >}]
7
+ ).each do |q1,q2|
8
+ ['Q', 'W', 'x', 'r', ''].each do |t|
9
+
10
+ should "handle %#{t}#{q1}...#{q2} (wo escape (single))" do
11
+ process(" xx %#{t}#{q1}hello#{q2} ").should.include([:dstring, "%#{t}#{q1}hello#{q2}"])
12
+ end
13
+
14
+ should "handle %#{t}#{q1}...#{q2} (wo escape (multiple))" do
15
+ tokens = process(" xx %#{t}#{q1}hello#{q2} %#{t}#{q1}world#{q2} ")
16
+ tokens.should.include([:dstring, "%#{t}#{q1}hello#{q2}"])
17
+ tokens.should.include([:dstring, "%#{t}#{q1}world#{q2}"])
18
+ end
19
+
20
+ # NOTE: We are skipping '\\' cos %Q\hel\\o\ is always raise SyntaxError no matter
21
+ # how many backslashes we add
22
+ unless q1 == '\\'
23
+
24
+ should "handle %#{t}#{q1}...#{q2} (w escape (single))" do
25
+ process(" xx %#{t}#{q1}hel\\#{q2}lo#{q2} ").should.
26
+ include([:dstring, "%#{t}#{q1}hel\\#{q2}lo#{q2}"])
27
+ end
28
+
29
+ should "handle %#{t}#{q1}...#{q2} (w escape (multiple))" do
30
+ process(" xx %#{t}#{q1}h\\#{q2}el\\#{q2}lo#{q2} ").should.
31
+ include([:dstring, "%#{t}#{q1}h\\#{q2}el\\#{q2}lo#{q2}"])
32
+ end
33
+
34
+ should "handle %#{t}#{q1}\\\\#{q2}" do
35
+ process(" xx %#{t}#{q1}\\\\#{q2} %#{t}#{q2}lo#{q2} ").should.
36
+ include([:dstring, "%#{t}#{q1}\\\\#{q2}"])
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
43
+
44
+ %w{" / `}.each do |q|
45
+
46
+ should "handle #{q}...#{q} (wo escape (single))" do
47
+ process(%Q( xx #{q}hello#{q} )).should.include([:dstring, %Q(#{q}hello#{q})])
48
+ end
49
+
50
+ should "handle #{q}...#{q} (wo escape & multiple)" do
51
+ tokens = process(%Q( xx #{q}hello#{q} #{q}world#{q} ))
52
+ tokens.should.include([:dstring, %Q(#{q}hello#{q})])
53
+ tokens.should.include([:dstring, %Q(#{q}world#{q})])
54
+ end
55
+
56
+ should "handle #{q}...#{q} (w escape (single))" do
57
+ process(%Q( xx #{q}hel\\#{q}lo#{q} )).should.include([:dstring, %Q(#{q}hel\\#{q}lo#{q})])
58
+ end
59
+
60
+ should "handle #{q}...#{q} (w escape (multiple))" do
61
+ process(%Q( xx #{q}h\\#{q}el\\#{q}lo#{q} )).should.
62
+ include([:dstring, %Q(#{q}h\\#{q}el\\#{q}lo#{q})])
63
+ end
64
+
65
+ should "handle #{q}\\\\#{q}" do
66
+ process(%Q(
67
+ aa #{q}\\\\#{q}
68
+ cc
69
+ #{q}dd#{q}
70
+ )).should.include([:dstring, "#{q}\\\\#{q}"])
71
+ end
72
+
73
+ end
74
+
75
+ end