Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add several rules regarding type restrictions #518

1 change: 1 addition & 0 deletions spec/ameba/base_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module Ameba::Rule
Naming
Performance
Style
Typing
]
end
end
Expand Down
51 changes: 51 additions & 0 deletions spec/ameba/rule/typing/macro_call_var_type_restriction_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require "../../../spec_helper"

module Ameba::Rule::Typing
subject = MacroCallVarTypeRestriction.new

it "passes if macro call args have type restrictions" do
expect_no_issues subject, <<-CRYSTAL
class Greeter
getter name : String?
class_getter age : Int32 = 0
setter tasks : Array(String) = [] of String
class_setter queue : Array(Int32)?
property task_mutex : Mutex = Mutex.new
class_property asdf : String

record Task,
var1 : String,
var2 : String = "asdf"
end
CRYSTAL
end

it "fails if a macro call arg doesn't have a type restriction" do
expect_issue subject, <<-CRYSTAL
class Greeter
getter name
# ^^^^ error: Variable arguments to `getter` should have a type restriction
end
CRYSTAL
end

it "fails if a record call arg doesn't have a type restriction" do
expect_issue subject, <<-CRYSTAL
class Greeter
record Task,
var1 : String,
var2 = "asdf"
# ^^^^ error: Variable arguments to `record` should have a type restriction
end
CRYSTAL
end

it "fails if a top-level record call arg doesn't have a type restriction" do
expect_issue subject, <<-CRYSTAL
record Task,
var1 : String,
var2 = "asdf"
# ^^^^ error: Variable arguments to `record` should have a type restriction
CRYSTAL
end
end
143 changes: 143 additions & 0 deletions spec/ameba/rule/typing/method_param_type_restriction_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
require "../../../spec_helper"

module Ameba::Rule::Typing
subject = MethodParamTypeRestriction.new
subject.private_methods = true
subject.protected_methods = true
subject.undocumented = true
subject.default_value = true

it "passes if a method param has a type" do
expect_no_issues subject, <<-CRYSTAL
def hello(a : String) : String
"hello world" + a
end
CRYSTAL
end

it "fails if a method param doesn't have a type" do
expect_issue subject, <<-CRYSTAL
def hello(a)
# ^ error: Method parameters should have a type restriction
"hello world" + a
end
CRYSTAL
end

it "fails if a private method method param doesn't have a type" do
expect_issue subject, <<-CRYSTAL
class Greeter
private def hello(a)
# ^ error: Method parameters should have a type restriction
"hello world" + a
end
end
CRYSTAL
end

it "fails if a protected method param doesn't have a type" do
expect_issue subject, <<-CRYSTAL
class Greeter
protected def hello(a)
# ^ error: Method parameters should have a type restriction
"hello world" + a
end
end
CRYSTAL
end

it "fails if a documented method param doesn't have a type" do
expect_issue subject, <<-CRYSTAL
# This is documentation about `hello`
def hello(a)
# ^ error: Method parameters should have a type restriction
"hello world" + a
end
CRYSTAL
end

it "fails if a method param with a default value doesn't have a type" do
expect_issue subject, <<-CRYSTAL
def hello(a = "jim")
# ^ error: Method parameters should have a type restriction
"hello there, " + a
end
CRYSTAL
end

context "properties" do
context "#private_methods" do
it "allows relaxing restriction requirement for private methods" do
rule = MethodParamTypeRestriction.new
rule.undocumented = true
rule.private_methods = false

expect_no_issues rule, <<-CRYSTAL
class Greeter
private def hello
"hello world"
end
end
CRYSTAL
end
end

context "#protected_methods" do
it "allows relaxing restriction requirement for protected methods" do
rule = MethodParamTypeRestriction.new
rule.undocumented = true
rule.protected_methods = false

expect_no_issues rule, <<-CRYSTAL
class Greeter
protected def hello
"hello world"
end
end
CRYSTAL
end
end

context "#default_value" do
it "allows relaxing restriction requirement for params with default value" do
rule = MethodParamTypeRestriction.new
rule.undocumented = true
rule.default_value = false

expect_no_issues rule, <<-CRYSTAL
class Greeter
def hello(a = "world")
"hello \#{a}"
end
end
CRYSTAL
end
end

context "#undocumented" do
rule = MethodParamTypeRestriction.new
rule.undocumented = false

it "allows relaxing restriction requirement for undocumented methods" do
expect_no_issues rule, <<-CRYSTAL
class Greeter
def hello(a)
"hello world"
end
end
CRYSTAL
end

it "allows relaxing restriction requirement for methods with a :nodoc: directive" do
expect_no_issues rule, <<-CRYSTAL
class Greeter
# :nodoc:
def hello(a)
"hello world"
end
end
CRYSTAL
end
end
end
end
117 changes: 117 additions & 0 deletions spec/ameba/rule/typing/method_return_type_restriction_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
require "../../../spec_helper"

module Ameba::Rule::Typing
subject = MethodReturnTypeRestriction.new
subject.private_methods = true
subject.protected_methods = true
subject.undocumented = true

it "passes if a method has a return type" do
expect_no_issues subject, <<-CRYSTAL
def hello : String
"hello world"
end
CRYSTAL
end

it "fails if a method doesn't have a return type" do
expect_issue subject, <<-CRYSTAL
def hello
# ^^^^^ error: Methods should have a return type restriction
"hello world"
end
CRYSTAL
end

it "fails if a private method doesn't have a return type" do
expect_issue subject, <<-CRYSTAL
class Greeter
private def hello
# ^^^^^ error: Methods should have a return type restriction
"hello world"
end
end
CRYSTAL
end

it "fails if a protected method doesn't have a return type" do
expect_issue subject, <<-CRYSTAL
class Greeter
protected def hello
# ^^^^^ error: Methods should have a return type restriction
"hello world"
end
end
CRYSTAL
end

it "fails if a documented method doesn't have a return type" do
expect_issue subject, <<-CRYSTAL
# This is documentation about `hello`
def hello(a)
# ^^^^^ error: Methods should have a return type restriction
"hello world" + a
end
CRYSTAL
end

context "properties" do
context "#private_methods" do
it "allows relaxing restriction requirement for private methods" do
rule = MethodReturnTypeRestriction.new
rule.undocumented = true
rule.private_methods = false

expect_no_issues rule, <<-CRYSTAL
class Greeter
private def hello
"hello world"
end
end
CRYSTAL
end
end

context "#protected_methods" do
it "allows relaxing restriction requirement for protected methods" do
rule = MethodReturnTypeRestriction.new
rule.undocumented = true
rule.protected_methods = false

expect_no_issues rule, <<-CRYSTAL
class Greeter
protected def hello
"hello world"
end
end
CRYSTAL
end
end

context "#undocumented" do
rule = MethodReturnTypeRestriction.new
rule.undocumented = false

it "allows relaxing restriction requirement for undocumented methods" do
expect_no_issues rule, <<-CRYSTAL
class Greeter
def hello
"hello world"
end
end
CRYSTAL
end

it "allows relaxing restriction requirement for methods with a :nodoc: directive" do
expect_no_issues rule, <<-CRYSTAL
class Greeter
# :nodoc:
def hello
"hello world"
end
end
CRYSTAL
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require "../../../spec_helper"

module Ameba::Rule::Typing
subject = ProcReturnTypeRestriction.new

it "passes if a proc literal has a return type" do
expect_no_issues subject, <<-CRYSTAL
my_proc = ->(var : Nil) : Nil { puts var }
my_proc.call(nil)
CRYSTAL
end

it "fails if a proc literal doesn't have a return type" do
expect_issue subject, <<-CRYSTAL
my_proc = ->(var : Nil) { puts var }
# ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Proc literals should have a return type
my_proc.call(nil)
CRYSTAL
end
end
1 change: 1 addition & 0 deletions src/ameba/ast/visitors/node_visitor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module Ameba::AST
ModuleDef,
MultiAssign,
NilLiteral,
ProcLiteral,
StringInterpolation,
Unless,
Until,
Expand Down
Loading