Skip to content

Commit

Permalink
Add specs for reserved keywords
Browse files Browse the repository at this point in the history
  • Loading branch information
amomchilov committed Jul 30, 2024
1 parent 80f1817 commit 8908ead
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 0 deletions.
155 changes: 155 additions & 0 deletions language/reserved_keywords.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
require_relative '../spec_helper'

describe "Ruby's reserved keywords" do
# Copied from Prism::Translation::Ripper
keywords = [
"alias",
"and",
"begin",
"BEGIN",
"break",
"case",
"class",
"def",
"defined?",
"do",
"else",
"elsif",
"end",
"END",
"ensure",
"false",
"for",
"if",
"in",
"module",
"next",
"nil",
"not",
"or",
"redo",
"rescue",
"retry",
"return",
"self",
"super",
"then",
"true",
"undef",
"unless",
"until",
"when",
"while",
"yield",
"__ENCODING__",
"__FILE__",
"__LINE__"
]

keywords.each do |kw|
describe "keyword '#{kw}'" do
it "can't be used as local variable name" do
expect_syntax_error <<~RUBY
#{kw} = "a local variable named '#{kw}'"
RUBY
end

invalid_ivar_names = ["defined?"]

if invalid_ivar_names.include?(kw)
it "can't be used as an instance variable name" do
expect_syntax_error <<~RUBY
@#{kw} = "an instance variable named '#{kw}'"
RUBY
end
else
it "can be used as an instance variable name" do
result = sandboxed_eval <<~RUBY
@#{kw} = "an instance variable named '#{kw}'"
@#{kw}
RUBY

result.should == "an instance variable named '#{kw}'"
end
end

invalid_class_var_names = ["defined?"]

if invalid_class_var_names.include?(kw)
it "can't be used as a global variable name" do
expect_syntax_error <<~RUBY
@@#{kw} = "a class variable named '#{kw}'"
RUBY
end
else
it "can be used as a class variable name" do
result = sandboxed_eval <<~RUBY
@@#{kw} = "a class variable named '#{kw}'"
@@#{kw}
RUBY

result.should == "a class variable named '#{kw}'"
end
end

invalid_global_var_names = ["defined?"]

if invalid_global_var_names.include?(kw)
it "can't be used as a global variable name" do
expect_syntax_error <<~RUBY
$#{kw} = "a global variable named '#{kw}'"
RUBY
end
else
it "can be used as a global variable name" do
result = sandboxed_eval <<~RUBY
$#{kw} = "a global variable named '#{kw}'"
$#{kw}
RUBY

result.should == "a global variable named '#{kw}'"
end
end

it "can't be used as a positional parameter name" do
expect_syntax_error <<~RUBY
def x(#{kw}); end
RUBY
end

invalid_kw_param_names = ["BEGIN","END","defined?"]

if invalid_kw_param_names.include?(kw)
it "can't be used a keyword parameter name" do
expect_syntax_error <<~RUBY
def m(#{kw}:); end
RUBY
end
else
it "can be used a keyword parameter name" do
result = sandboxed_eval <<~RUBY
def m(#{kw}:)
binding.local_variable_get(:#{kw})
end
m(#{kw}: "an argument to '#{kw}'")
RUBY

result.should == "an argument to '#{kw}'"
end
end

it "can be used as a method name" do
result = sandboxed_eval <<~RUBY
def #{kw}
"a method named '#{kw}'"
end
send(:#{kw})
RUBY

result.should == "a method named '#{kw}'"
end
end
end
end
10 changes: 10 additions & 0 deletions spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,13 @@ def report_on_exception=(value)
def expect_syntax_error(ruby_src)
-> { eval(ruby_src) }.should raise_error(SyntaxError)
end

# Evaluates the given Ruby source in a temporary Module, to prevent
# the surrounding context from being polluted with the new methods.
def sandboxed_eval(ruby_src)
Module.new do
# Allows instance methods defined by `ruby_src` to be called directly.
extend self
end
.class_eval(ruby_src)
end

0 comments on commit 8908ead

Please sign in to comment.