rubycop 0.5.0
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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +3 -0
- data/Rakefile +1 -0
- data/lib/rubycop.rb +6 -0
- data/lib/rubycop/analyzer.rb +6 -0
- data/lib/rubycop/analyzer/gray_list.rb +28 -0
- data/lib/rubycop/analyzer/node_builder.rb +523 -0
- data/lib/rubycop/analyzer/policy.rb +354 -0
- data/lib/rubycop/analyzer/ruby.rb +24 -0
- data/lib/rubycop/analyzer/ruby/args.rb +28 -0
- data/lib/rubycop/analyzer/ruby/array.rb +11 -0
- data/lib/rubycop/analyzer/ruby/assignment.rb +45 -0
- data/lib/rubycop/analyzer/ruby/assoc.rb +15 -0
- data/lib/rubycop/analyzer/ruby/blocks.rb +23 -0
- data/lib/rubycop/analyzer/ruby/call.rb +33 -0
- data/lib/rubycop/analyzer/ruby/case.rb +24 -0
- data/lib/rubycop/analyzer/ruby/constants.rb +49 -0
- data/lib/rubycop/analyzer/ruby/definitions.rb +27 -0
- data/lib/rubycop/analyzer/ruby/for.rb +17 -0
- data/lib/rubycop/analyzer/ruby/hash.rb +13 -0
- data/lib/rubycop/analyzer/ruby/if.rb +33 -0
- data/lib/rubycop/analyzer/ruby/list.rb +17 -0
- data/lib/rubycop/analyzer/ruby/node.rb +11 -0
- data/lib/rubycop/analyzer/ruby/operators.rb +54 -0
- data/lib/rubycop/analyzer/ruby/params.rb +23 -0
- data/lib/rubycop/analyzer/ruby/position.rb +15 -0
- data/lib/rubycop/analyzer/ruby/range.rb +17 -0
- data/lib/rubycop/analyzer/ruby/statements.rb +34 -0
- data/lib/rubycop/analyzer/ruby/string.rb +26 -0
- data/lib/rubycop/analyzer/ruby/tokens.rb +46 -0
- data/lib/rubycop/analyzer/ruby/variables.rb +26 -0
- data/lib/rubycop/analyzer/ruby/while.rb +29 -0
- data/lib/rubycop/version.rb +3 -0
- data/rubycop.gemspec +25 -0
- data/spec/node_builder_spec.rb +374 -0
- data/spec/policy_spec.rb +405 -0
- metadata +97 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
module Rubycop
|
2
|
+
module Analyzer
|
3
|
+
module Ruby
|
4
|
+
class Token < Node
|
5
|
+
def initialize(token, position)
|
6
|
+
@token = token
|
7
|
+
@position = position
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :token
|
11
|
+
attr_reader :position
|
12
|
+
|
13
|
+
# def inspect
|
14
|
+
# "#{@token}<t>"
|
15
|
+
# end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Integer < Token
|
19
|
+
end
|
20
|
+
|
21
|
+
class Float < Token
|
22
|
+
end
|
23
|
+
|
24
|
+
class Char < Token
|
25
|
+
end
|
26
|
+
|
27
|
+
class Label < Token
|
28
|
+
end
|
29
|
+
|
30
|
+
class Symbol < Token
|
31
|
+
# def inspect
|
32
|
+
# ":#{@token.inspect}"
|
33
|
+
# end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Keyword < Token
|
37
|
+
end
|
38
|
+
|
39
|
+
class Identifier < Token
|
40
|
+
def assignment(rvalue, operator)
|
41
|
+
LocalVariableAssignment.new(self, rvalue, operator)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Rubycop
|
2
|
+
module Analyzer
|
3
|
+
module Ruby
|
4
|
+
class Variable < Identifier
|
5
|
+
end
|
6
|
+
|
7
|
+
class ClassVariable < Variable
|
8
|
+
def assignment(rvalue, operator)
|
9
|
+
ClassVariableAssignment.new(self, rvalue, operator)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class GlobalVariable < Variable
|
14
|
+
def assignment(rvalue, operator)
|
15
|
+
GlobalVariableAssignment.new(self, rvalue, operator)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class InstanceVariable < Variable
|
20
|
+
def assignment(rvalue, operator)
|
21
|
+
InstanceVariableAssignment.new(self, rvalue, operator)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Rubycop
|
2
|
+
module Analyzer
|
3
|
+
module Ruby
|
4
|
+
class While < Block
|
5
|
+
def initialize(expression, statements)
|
6
|
+
@expression = expression
|
7
|
+
super(statements)
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :expression
|
11
|
+
end
|
12
|
+
|
13
|
+
class WhileMod < Block
|
14
|
+
def initialize(expression, statements)
|
15
|
+
@expression = expression
|
16
|
+
super(statements)
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :expression
|
20
|
+
end
|
21
|
+
|
22
|
+
class Until < While
|
23
|
+
end
|
24
|
+
|
25
|
+
class UntilMod < WhileMod
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/rubycop.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rubycop/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rubycop"
|
7
|
+
s.version = Rubycop::VERSION
|
8
|
+
s.authors = ["Dray Lacy", "Eric Allam"]
|
9
|
+
s.email = ["dray@envylabs.com", "rubymaverick@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{A semantic analyzer for Ruby 1.9}
|
12
|
+
s.description = %q{A semantic analyzer for Ruby 1.9}
|
13
|
+
|
14
|
+
s.rubyforge_project = "rubycop"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
24
|
+
s.add_development_dependency "rspec"
|
25
|
+
end
|
@@ -0,0 +1,374 @@
|
|
1
|
+
require 'rubycop'
|
2
|
+
|
3
|
+
describe Rubycop::Analyzer::NodeBuilder do
|
4
|
+
subject { described_class }
|
5
|
+
|
6
|
+
RSpec::Matchers.define(:parse) do |ruby|
|
7
|
+
match { |nb| nb.build(ruby).is_a?(Rubycop::Analyzer::Ruby::Node) }
|
8
|
+
end
|
9
|
+
|
10
|
+
context "arrays" do
|
11
|
+
it { should parse('[:foo, :bar]') }
|
12
|
+
it { should parse('%w(foo bar)') }
|
13
|
+
it { should parse('%(foo)') }
|
14
|
+
it { should parse("%(\nfoo bar\n)") }
|
15
|
+
it { should parse("%( \nfoo bar\n )") }
|
16
|
+
it { should parse('%W[foo bar]') }
|
17
|
+
it { should parse('%w()') }
|
18
|
+
it { should parse('%W()') }
|
19
|
+
it { should parse('%w[]') }
|
20
|
+
it { should parse('%W[]') }
|
21
|
+
it { should parse('%W[#{foo}]') }
|
22
|
+
it { should parse('foo[1]') }
|
23
|
+
it { should parse('foo[]') }
|
24
|
+
it { should parse('foo.bar[]') }
|
25
|
+
it { should parse('[ foo[bar] ]') }
|
26
|
+
it { should parse('result[0] = :value') }
|
27
|
+
it { should parse("\n [type, [row]]\n") }
|
28
|
+
end
|
29
|
+
|
30
|
+
context "assignment" do
|
31
|
+
it { should parse('a = b') }
|
32
|
+
it { should parse('a ||= b') }
|
33
|
+
it { should parse('a, b = c') }
|
34
|
+
it { should parse('a, b = c, d') }
|
35
|
+
it { should parse('a, *b = c') }
|
36
|
+
it { should parse('A::B = 1') }
|
37
|
+
end
|
38
|
+
|
39
|
+
context "blocks" do
|
40
|
+
it { should parse("t do\nfoo\nbar\nend") }
|
41
|
+
it { should parse('t do ; end') }
|
42
|
+
it { should parse("t do ||\nfoo\nend") }
|
43
|
+
it { should parse('t do ;; ;foo ; ;;bar; ; end') }
|
44
|
+
it { should parse("t do |(a, b), *c|\n foo\n bar\nend") }
|
45
|
+
it { should parse('t { |(a, b), *c| }') }
|
46
|
+
it { should parse('t do |(a, b), *c| end') }
|
47
|
+
it { should parse('t do |*a, &c| end') }
|
48
|
+
it { should parse('t { |a, (b)| }') }
|
49
|
+
it { should parse("begin\nend") }
|
50
|
+
it { should parse('begin ; end') }
|
51
|
+
it { should parse('begin foo; end') }
|
52
|
+
it { should parse("begin\nfoo\nelse\nbar\nend") }
|
53
|
+
it { should parse("begin\nfoo\nrescue\nbar\nend") }
|
54
|
+
it { should parse("begin \n rescue A \n end") }
|
55
|
+
it { should parse("begin foo\n rescue A => e\n bar\n end") }
|
56
|
+
it { should parse("begin foo\n rescue A, B => e\n bar\n end") }
|
57
|
+
it { should parse("begin foo\n rescue A, B => e\n bar\nrescue C => e\n bam\nensure\nbaz\n end") }
|
58
|
+
it { should parse('begin a; rescue NameError => e then e else :foo end') }
|
59
|
+
it { should parse("begin\nrescue A => e\nrescue B\nend") }
|
60
|
+
it { should parse("begin\nrescue A\nelse\nend\n") }
|
61
|
+
it { should parse('foo rescue bar') }
|
62
|
+
it { should parse('foo rescue 0') }
|
63
|
+
end
|
64
|
+
|
65
|
+
context "calls" do
|
66
|
+
it { should parse('t') }
|
67
|
+
it { should parse('I18n.t') }
|
68
|
+
it { should parse('a.b(:foo)') }
|
69
|
+
it { should parse('I18n.t()') }
|
70
|
+
it { should parse("I18n.t('foo')") }
|
71
|
+
it { should parse("I18n.t 'foo'") }
|
72
|
+
it { should parse('I18n::t') }
|
73
|
+
it { should parse('I18n::t()') }
|
74
|
+
it { should parse("I18n::t('foo')") }
|
75
|
+
it { should parse('foo.<=>(bar)') }
|
76
|
+
it { should parse('foo.<< bar') }
|
77
|
+
it { should parse('foo("#{bar}")') }
|
78
|
+
it { should parse("t('foo', 'bar')") }
|
79
|
+
it { should parse("t('foo', 'bar'); t 'baz'") }
|
80
|
+
it { should parse("t 'foo'") }
|
81
|
+
it { should parse('t %(foo #{bar}), %(baz)') }
|
82
|
+
it { should parse('t()') }
|
83
|
+
it { should parse('t(:a, b(:b))') }
|
84
|
+
it { should parse('t(:`)') }
|
85
|
+
it { should parse("t do |a, b, *c|\nfoo\nend") }
|
86
|
+
it { should parse("t do |(a, b), *c|\nfoo\nend") }
|
87
|
+
it { should parse('t(:foo, &block)') }
|
88
|
+
it { should parse('foo(bar do |a| ; end)') }
|
89
|
+
it { should parse('self.b') }
|
90
|
+
it { should parse('super') }
|
91
|
+
it { should parse('super(:foo)') }
|
92
|
+
it { should parse('yield') }
|
93
|
+
it { should parse('yield(:foo)') }
|
94
|
+
it { should parse('return :foo') }
|
95
|
+
it { should parse('next') }
|
96
|
+
it { should parse('redo') }
|
97
|
+
it { should parse('break') }
|
98
|
+
it { should parse('retry') }
|
99
|
+
it { should parse('a.b = :c') }
|
100
|
+
it { should parse('defined?(A)') }
|
101
|
+
it { should parse('BEGIN { foo }') }
|
102
|
+
it { should parse('END { foo }') }
|
103
|
+
it { should parse('alias eql? ==') }
|
104
|
+
it { should parse('alias :foo :bar') }
|
105
|
+
it { should parse('alias $ERROR_INFO $!') }
|
106
|
+
it { should parse('undef :foo') }
|
107
|
+
it { should parse('undef foo, bar, baz') }
|
108
|
+
it { should parse('undef =~') }
|
109
|
+
end
|
110
|
+
|
111
|
+
context "case" do
|
112
|
+
it { should parse('case a; when 1; 2 end') }
|
113
|
+
it { should parse('case (a) when 1; 2 end') }
|
114
|
+
it { should parse('case (a;) when 1; 2 end') }
|
115
|
+
it { should parse('case (a); when 1; 2 end') }
|
116
|
+
it { should parse('case (a;;); when 1; 2 end') }
|
117
|
+
it { should parse('case (a;b); when 1; 2 end') }
|
118
|
+
it { should parse('case a; when 1; 2 end') }
|
119
|
+
it { should parse('case a; when 1, 2; 2 end') }
|
120
|
+
it { should parse('case a; when (1; 2), (3; 4;); 2 end') }
|
121
|
+
it { should parse('case (true); when 1; false; when 2, 3, 4; nil; else; nil; end') }
|
122
|
+
it { should parse("case true\n when 1\n false\n when 2\n nil\n else\n nil\n end") }
|
123
|
+
it { should parse("case true\n when 1 then false\n when 2 then nil\n else\n nil\n end") }
|
124
|
+
end
|
125
|
+
|
126
|
+
context "constants" do
|
127
|
+
it { should parse('A') }
|
128
|
+
it { should parse('module A::B ; end') }
|
129
|
+
it { should parse('class A::B < C ; end') }
|
130
|
+
it { should parse('self.class::A') }
|
131
|
+
it { should parse('class << self; self; end') }
|
132
|
+
it { should parse('foo (class << @bar; self; end)') }
|
133
|
+
it { should parse("class A ; end\n::B = 3") }
|
134
|
+
end
|
135
|
+
|
136
|
+
context "for" do
|
137
|
+
it { should parse('for i in [1]; a; end') }
|
138
|
+
it { should parse("for i in [1]\n a\n end") }
|
139
|
+
it { should parse("for i in [1] do a\n end") }
|
140
|
+
it { should parse("lambda do\n for a in b\n end\nend") }
|
141
|
+
it { should parse("\nfor i in 0...1 do\n for j in 0...2 do\n end\nend\n") }
|
142
|
+
end
|
143
|
+
|
144
|
+
context "hash" do
|
145
|
+
it { should parse('{ :foo => :bar }') }
|
146
|
+
it { should parse('{ :a => { :b => { :b => :c, }, }, }') }
|
147
|
+
it { should parse('t(:a => { :b => :b, :c => { :d => :d } })') }
|
148
|
+
it { should parse('{ :if => :foo }') }
|
149
|
+
it { should parse('{ :a => :a, :b => "#{b 1}" }') }
|
150
|
+
it { should parse('{ foo: bar }') }
|
151
|
+
it { should parse('t(:a => :a, :b => :b)') }
|
152
|
+
it { should parse('foo[:bar] = :baz') }
|
153
|
+
end
|
154
|
+
|
155
|
+
context "heredoc" do
|
156
|
+
it { should parse("\n<<-eos\neos\n") }
|
157
|
+
it { should parse("<<-eos\nfoo\neos") }
|
158
|
+
it { should parse("'string'\n<<-eos\nheredoc\neos\n'string'") }
|
159
|
+
it { should parse(":'symbol'\n<<-eos\nheredoc\neos\n:'symbol'") }
|
160
|
+
it { should parse("%w(words)\n<<-eoc\n heredoc\neoc\n%w(words)") }
|
161
|
+
it { should parse("foo(%w(words))\n<<-eoc\n\neoc") }
|
162
|
+
it { should parse("\n<<-end;\nfoo\nend\n") }
|
163
|
+
it { should parse("\n<<-'end' ;\n foo\nend\nfoo;") }
|
164
|
+
it { should parse("<<-eos\n foo \#{bar} baz\neos") }
|
165
|
+
it { should parse("<<-end\n\#{a['b']}\nend") }
|
166
|
+
it { should parse("<<-end\n\#{'a'}\nend") }
|
167
|
+
it { should parse("foo(<<-eos)\n foo\neos") }
|
168
|
+
it { should parse("foo(<<-eos\n foo\neos\n)") }
|
169
|
+
it { should parse("foo(<<-eos, __FILE__, __LINE__ + 1)\n foo\neos") }
|
170
|
+
it { should parse("foo(<<-eos, __FILE__, line)\n foo\neos") }
|
171
|
+
it { should parse("foo(<<-eos, \"\#{bar}\")\n foo\neos") }
|
172
|
+
it { should parse("begin <<-src \n\n\nfoo\nsrc\n end") }
|
173
|
+
it { should parse("each do\n <<-src \n\nfoo\n\#{bar}\nsrc\n end\n") }
|
174
|
+
it { should parse("<<-eos\n \#{\"\n \#{sym}\n \"}\neos") }
|
175
|
+
it { should parse("<<-eos\n \t\#{ a\n }\neos") }
|
176
|
+
it { should parse("<<-eos\n\#{:'dyna_symbol'}\neos") }
|
177
|
+
it { should parse("<<-eos # comment\neos\nfoo\nfoo\n") }
|
178
|
+
it { should parse("<<-eos # comment\nstring\neos\n'index'") }
|
179
|
+
it { should parse("foo <<-eos if bar\na\neos\nbaz") }
|
180
|
+
it { should parse("<<-eos.foo\neos\nbar\n") }
|
181
|
+
it { should parse("<<-end\nend\n<<-end\n\nend\n") }
|
182
|
+
it { should parse("heredocs = <<-\"foo\", <<-\"bar\"\n I said foo.\nfoo\n I said bar.\nbar\n") }
|
183
|
+
it { should parse("a = %w[]\n<<-eos\nfoo\neos") }
|
184
|
+
it { should parse("<<-eos\nfoo\n__END__\neos") }
|
185
|
+
it { should parse("foo = <<-`foo`\nfoo") }
|
186
|
+
end
|
187
|
+
|
188
|
+
context "identifier" do
|
189
|
+
it { should parse('foo') }
|
190
|
+
it { should parse('@foo') }
|
191
|
+
it { should parse('@@foo') }
|
192
|
+
it { should parse('$foo') }
|
193
|
+
it { should parse('__FILE__') }
|
194
|
+
it { should parse('__LINE__') }
|
195
|
+
it { should parse('__ENCODING__') }
|
196
|
+
end
|
197
|
+
|
198
|
+
context "if" do
|
199
|
+
it { should parse('if true; false end') }
|
200
|
+
it { should parse("if true\n false\n end") }
|
201
|
+
it { should parse("if true\n false\n end") }
|
202
|
+
it { should parse('if true then false end') }
|
203
|
+
it { should parse('if true; false; else; true end') }
|
204
|
+
it { should parse("if true\n false\n else\n true end") }
|
205
|
+
it { should parse("if true\n false\n elsif false\n true end") }
|
206
|
+
it { should parse("if true then false; elsif false then true; else nil end") }
|
207
|
+
it { should parse("if a == 1 then b\nelsif b == c then d\ne\nf\nelse e end") }
|
208
|
+
it { should parse('foo if true') }
|
209
|
+
it { should parse('return if true') }
|
210
|
+
it { should parse('foo.bar += bar if bar') }
|
211
|
+
it { should parse('foo, bar = *baz if bum') }
|
212
|
+
it { should parse('foo *args if bar?') }
|
213
|
+
it { should parse('pos[1] if pos') }
|
214
|
+
it { should parse('a if (defined? a)') }
|
215
|
+
it { should parse('rescued rescue rescuing') }
|
216
|
+
it { should parse('rescued = assigned rescue rescuing') }
|
217
|
+
end
|
218
|
+
|
219
|
+
context "literals" do
|
220
|
+
it { should parse('1') }
|
221
|
+
it { should parse('1.1') }
|
222
|
+
it { should parse('nil') }
|
223
|
+
it { should parse('true') }
|
224
|
+
it { should parse('false') }
|
225
|
+
it { should parse('1..2') }
|
226
|
+
it { should parse('1...2') }
|
227
|
+
it { should parse('?a') }
|
228
|
+
end
|
229
|
+
|
230
|
+
context "methods" do
|
231
|
+
it { should parse("def foo(a, b = nil, c = :foo, *d, &block)\n bar\n baz\nend") }
|
232
|
+
it { should parse("def foo(a, b = {})\nend") }
|
233
|
+
it { should parse("def foo a, b = nil, c = :foo, *d, &block\n bar\n baz\nend") }
|
234
|
+
it { should parse("def self.for(options)\nend") }
|
235
|
+
it { should parse('def foo(a = 1, b=2); end') }
|
236
|
+
it { should parse('def t(a = []) end') }
|
237
|
+
it { should parse('def t(*) end') }
|
238
|
+
it { should parse('def <<(arg) end') }
|
239
|
+
it { should parse('def | ; end') }
|
240
|
+
it { should parse('class A < B; def |(foo); end; end') }
|
241
|
+
it { should parse('def <<(arg) foo; bar; end') }
|
242
|
+
it { should parse("def t\nrescue => e\nend") }
|
243
|
+
it { should parse("def a(b, c)\n d\nrescue A\n e\nensure\nb\nend") }
|
244
|
+
it { should parse('def foo ; bar { |k, v| k } end') }
|
245
|
+
it { should parse("class A\n def class\n end\nend") }
|
246
|
+
it { should parse("def end\nend") }
|
247
|
+
it { should parse('def def; 234; end') }
|
248
|
+
end
|
249
|
+
|
250
|
+
context "operators" do
|
251
|
+
context "unary" do
|
252
|
+
it { should parse('+1') }
|
253
|
+
it { should parse('-1') }
|
254
|
+
it { should parse('!1') }
|
255
|
+
it { should parse('not 1') }
|
256
|
+
it { should parse('not(1)') }
|
257
|
+
it { should parse('~1') }
|
258
|
+
it { should parse('(~1)') }
|
259
|
+
it { should parse('not (@main or @sub)') }
|
260
|
+
end
|
261
|
+
|
262
|
+
context "binary" do
|
263
|
+
context "mathematical" do
|
264
|
+
it { should parse('1 + 2') }
|
265
|
+
it { should parse('1 - 2') }
|
266
|
+
it { should parse('1 * 2') }
|
267
|
+
it { should parse('1 / 2') }
|
268
|
+
it { should parse('1 ** 2') }
|
269
|
+
it { should parse('1 % 2') }
|
270
|
+
it { should parse('(1 + 2)') }
|
271
|
+
end
|
272
|
+
context "logical" do
|
273
|
+
it { should parse('1 && 2') }
|
274
|
+
it { should parse('1 || 2') }
|
275
|
+
it { should parse('1 and 2') }
|
276
|
+
it { should parse('1 or 2') }
|
277
|
+
it { should parse('(1 and 2)') }
|
278
|
+
end
|
279
|
+
context "bitwise" do
|
280
|
+
it { should parse('1 << 2') }
|
281
|
+
it { should parse('1 >> 2') }
|
282
|
+
it { should parse('1 & 2') }
|
283
|
+
it { should parse('1 | 2') }
|
284
|
+
it { should parse('1 ^ 2') }
|
285
|
+
end
|
286
|
+
context "comparison, equality, matching" do
|
287
|
+
it { should parse('1 < 2') }
|
288
|
+
it { should parse('1 <= 2') }
|
289
|
+
it { should parse('1 > 2') }
|
290
|
+
it { should parse('1 >= 2') }
|
291
|
+
it { should parse('1 <=> 2') }
|
292
|
+
it { should parse('1 == 2') }
|
293
|
+
it { should parse('1 != 2') }
|
294
|
+
it { should parse('1 === 2') }
|
295
|
+
it { should parse('1 =~ 2') }
|
296
|
+
it { should parse('1 !~ 2') }
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
context "ternary" do
|
301
|
+
it { should parse('1 == 1 ? 2 : 3') }
|
302
|
+
it { should parse('((1) ? 2 : (3))') }
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
context "statements" do
|
307
|
+
it { should parse('foo') }
|
308
|
+
it { should parse(';foo') }
|
309
|
+
it { should parse('foo;') }
|
310
|
+
it { should parse(';foo;') }
|
311
|
+
it { should parse(';foo;;bar;baz;') }
|
312
|
+
it { should parse(';foo;;bar;;;;baz;') }
|
313
|
+
it { should parse(';;;foo;;bar;baz;;;;') }
|
314
|
+
it { should parse('(foo)') }
|
315
|
+
it { should parse('(((foo)); (bar))') }
|
316
|
+
it { should parse('(((foo)); ((bar); (baz)));') }
|
317
|
+
it { should parse("\n foo \n \n") }
|
318
|
+
it { should parse("foo\n__END__\nbar") }
|
319
|
+
end
|
320
|
+
|
321
|
+
context "string" do
|
322
|
+
it { should parse('""') }
|
323
|
+
it { should parse('"foo"') }
|
324
|
+
it { should parse("'foo'") }
|
325
|
+
it { should parse('%(foo)') }
|
326
|
+
it { should parse('%.foo.') }
|
327
|
+
it { should parse('%|foo|') }
|
328
|
+
it { should parse('"foo#{bar}"') }
|
329
|
+
it { should parse('%(foo #{bar})') }
|
330
|
+
it { should parse("%w(a)\n%(b)") }
|
331
|
+
it { should parse('/foo/') }
|
332
|
+
it { should parse('%r(foo)') }
|
333
|
+
it { should parse('"#{$1}"') }
|
334
|
+
it { should parse('"#$0"') }
|
335
|
+
it { should parse("'a' 'b'") }
|
336
|
+
it { should parse('`foo`') }
|
337
|
+
it { should parse('%x(foo)') }
|
338
|
+
end
|
339
|
+
|
340
|
+
context "symbol" do
|
341
|
+
it { should parse(':foo') }
|
342
|
+
it { should parse(':!') }
|
343
|
+
it { should parse(':-@') }
|
344
|
+
it { should parse(':if') }
|
345
|
+
it { should parse(':[]') }
|
346
|
+
it { should parse(':[]=') }
|
347
|
+
it { should parse(':"foo.bar"') }
|
348
|
+
it { should parse(":'foo.bar'") }
|
349
|
+
it { should parse(':"@#{token}"') }
|
350
|
+
end
|
351
|
+
|
352
|
+
context "unless" do
|
353
|
+
it { should parse('unless true; false end') }
|
354
|
+
it { should parse("unless true\n false end") }
|
355
|
+
it { should parse('unless true then false end') }
|
356
|
+
it { should parse('unless true; false; else; true end') }
|
357
|
+
it { should parse("unless true\n false\n else\n true end") }
|
358
|
+
it { should parse('foo unless true') }
|
359
|
+
it { should parse('1 unless false if true') }
|
360
|
+
end
|
361
|
+
|
362
|
+
context "until" do
|
363
|
+
it { should parse('until true; false end') }
|
364
|
+
it { should parse('until (true); false end') }
|
365
|
+
it { should parse('until (true;); false end') }
|
366
|
+
it { should parse("until true\n false end") }
|
367
|
+
it { should parse("until (true)\n false end") }
|
368
|
+
it { should parse('until foo do ; end') }
|
369
|
+
it { should parse('begin; false; end until true') }
|
370
|
+
it { should parse("begin\n false\n end until true") }
|
371
|
+
it { should parse('foo until true') }
|
372
|
+
it { should parse('foo until (true)') }
|
373
|
+
end
|
374
|
+
end
|