Skip to content

Commit 8908ead

Browse files
committed
Add specs for reserved keywords
1 parent 80f1817 commit 8908ead

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-0
lines changed

language/reserved_keywords.rb

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
require_relative '../spec_helper'
2+
3+
describe "Ruby's reserved keywords" do
4+
# Copied from Prism::Translation::Ripper
5+
keywords = [
6+
"alias",
7+
"and",
8+
"begin",
9+
"BEGIN",
10+
"break",
11+
"case",
12+
"class",
13+
"def",
14+
"defined?",
15+
"do",
16+
"else",
17+
"elsif",
18+
"end",
19+
"END",
20+
"ensure",
21+
"false",
22+
"for",
23+
"if",
24+
"in",
25+
"module",
26+
"next",
27+
"nil",
28+
"not",
29+
"or",
30+
"redo",
31+
"rescue",
32+
"retry",
33+
"return",
34+
"self",
35+
"super",
36+
"then",
37+
"true",
38+
"undef",
39+
"unless",
40+
"until",
41+
"when",
42+
"while",
43+
"yield",
44+
"__ENCODING__",
45+
"__FILE__",
46+
"__LINE__"
47+
]
48+
49+
keywords.each do |kw|
50+
describe "keyword '#{kw}'" do
51+
it "can't be used as local variable name" do
52+
expect_syntax_error <<~RUBY
53+
#{kw} = "a local variable named '#{kw}'"
54+
RUBY
55+
end
56+
57+
invalid_ivar_names = ["defined?"]
58+
59+
if invalid_ivar_names.include?(kw)
60+
it "can't be used as an instance variable name" do
61+
expect_syntax_error <<~RUBY
62+
@#{kw} = "an instance variable named '#{kw}'"
63+
RUBY
64+
end
65+
else
66+
it "can be used as an instance variable name" do
67+
result = sandboxed_eval <<~RUBY
68+
@#{kw} = "an instance variable named '#{kw}'"
69+
@#{kw}
70+
RUBY
71+
72+
result.should == "an instance variable named '#{kw}'"
73+
end
74+
end
75+
76+
invalid_class_var_names = ["defined?"]
77+
78+
if invalid_class_var_names.include?(kw)
79+
it "can't be used as a global variable name" do
80+
expect_syntax_error <<~RUBY
81+
@@#{kw} = "a class variable named '#{kw}'"
82+
RUBY
83+
end
84+
else
85+
it "can be used as a class variable name" do
86+
result = sandboxed_eval <<~RUBY
87+
@@#{kw} = "a class variable named '#{kw}'"
88+
@@#{kw}
89+
RUBY
90+
91+
result.should == "a class variable named '#{kw}'"
92+
end
93+
end
94+
95+
invalid_global_var_names = ["defined?"]
96+
97+
if invalid_global_var_names.include?(kw)
98+
it "can't be used as a global variable name" do
99+
expect_syntax_error <<~RUBY
100+
$#{kw} = "a global variable named '#{kw}'"
101+
RUBY
102+
end
103+
else
104+
it "can be used as a global variable name" do
105+
result = sandboxed_eval <<~RUBY
106+
$#{kw} = "a global variable named '#{kw}'"
107+
$#{kw}
108+
RUBY
109+
110+
result.should == "a global variable named '#{kw}'"
111+
end
112+
end
113+
114+
it "can't be used as a positional parameter name" do
115+
expect_syntax_error <<~RUBY
116+
def x(#{kw}); end
117+
RUBY
118+
end
119+
120+
invalid_kw_param_names = ["BEGIN","END","defined?"]
121+
122+
if invalid_kw_param_names.include?(kw)
123+
it "can't be used a keyword parameter name" do
124+
expect_syntax_error <<~RUBY
125+
def m(#{kw}:); end
126+
RUBY
127+
end
128+
else
129+
it "can be used a keyword parameter name" do
130+
result = sandboxed_eval <<~RUBY
131+
def m(#{kw}:)
132+
binding.local_variable_get(:#{kw})
133+
end
134+
135+
m(#{kw}: "an argument to '#{kw}'")
136+
RUBY
137+
138+
result.should == "an argument to '#{kw}'"
139+
end
140+
end
141+
142+
it "can be used as a method name" do
143+
result = sandboxed_eval <<~RUBY
144+
def #{kw}
145+
"a method named '#{kw}'"
146+
end
147+
148+
send(:#{kw})
149+
RUBY
150+
151+
result.should == "a method named '#{kw}'"
152+
end
153+
end
154+
end
155+
end

spec_helper.rb

+10
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,13 @@ def report_on_exception=(value)
4040
def expect_syntax_error(ruby_src)
4141
-> { eval(ruby_src) }.should raise_error(SyntaxError)
4242
end
43+
44+
# Evaluates the given Ruby source in a temporary Module, to prevent
45+
# the surrounding context from being polluted with the new methods.
46+
def sandboxed_eval(ruby_src)
47+
Module.new do
48+
# Allows instance methods defined by `ruby_src` to be called directly.
49+
extend self
50+
end
51+
.class_eval(ruby_src)
52+
end

0 commit comments

Comments
 (0)