mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Ameba::Rule -> Ameba::Rule::Base
This commit is contained in:
parent
b6c0d3e8ad
commit
80e2ab4f55
39 changed files with 79 additions and 73 deletions
26
spec/ameba/rule/base_spec.cr
Normal file
26
spec/ameba/rule/base_spec.cr
Normal file
|
@ -0,0 +1,26 @@
|
|||
require "../../spec/spec_helper"
|
||||
|
||||
module Ameba
|
||||
describe Rule::Base do
|
||||
describe "#catch" do
|
||||
it "accepts and returns source" do
|
||||
s = Source.new "", ""
|
||||
DummyRule.new.catch(s).should eq s
|
||||
end
|
||||
end
|
||||
|
||||
describe "#name" do
|
||||
it "returns name of the rule" do
|
||||
DummyRule.new.name.should eq "Ameba::DummyRule"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe Rule do
|
||||
describe ".rules" do
|
||||
it "returns a list of all defined rules" do
|
||||
Rule.rules.includes?(DummyRule).should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
113
spec/ameba/rule/comparison_to_boolean_spec.cr
Normal file
113
spec/ameba/rule/comparison_to_boolean_spec.cr
Normal file
|
@ -0,0 +1,113 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba::Rule
|
||||
subject = ComparisonToBoolean.new
|
||||
|
||||
describe ComparisonToBoolean do
|
||||
it "passes if there is no comparison to boolean" do
|
||||
source = Source.new %(
|
||||
a = true
|
||||
|
||||
if a
|
||||
:ok
|
||||
end
|
||||
|
||||
if true
|
||||
:ok
|
||||
end
|
||||
|
||||
unless s.empty?
|
||||
:ok
|
||||
end
|
||||
|
||||
:ok if a
|
||||
|
||||
:ok if a != 1
|
||||
|
||||
:ok if a == "true"
|
||||
|
||||
case a
|
||||
when true
|
||||
:ok
|
||||
when false
|
||||
:not_ok
|
||||
end
|
||||
)
|
||||
subject.catch(source).should be_valid
|
||||
end
|
||||
|
||||
context "boolean on the right" do
|
||||
it "fails if there is == comparison to boolean" do
|
||||
source = Source.new %(
|
||||
if s.empty? == true
|
||||
:ok
|
||||
end
|
||||
)
|
||||
subject.catch(source).should_not be_valid
|
||||
end
|
||||
|
||||
it "fails if there is != comparison to boolean" do
|
||||
source = Source.new %(
|
||||
if a != false
|
||||
:ok
|
||||
end
|
||||
)
|
||||
subject.catch(source).should_not be_valid
|
||||
end
|
||||
|
||||
it "fails if there is case comparison to boolean" do
|
||||
source = Source.new %(
|
||||
a === true
|
||||
)
|
||||
subject.catch(source).should_not be_valid
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
source = Source.new "a != true", "source.cr"
|
||||
subject.catch(source)
|
||||
|
||||
error = source.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:1:1"
|
||||
error.message.should eq "Comparison to a boolean is pointless"
|
||||
end
|
||||
end
|
||||
|
||||
context "boolean on the left" do
|
||||
it "fails if there is == comparison to boolean" do
|
||||
source = Source.new %(
|
||||
if true == s.empty?
|
||||
:ok
|
||||
end
|
||||
)
|
||||
subject.catch(source).should_not be_valid
|
||||
end
|
||||
|
||||
it "fails if there is != comparison to boolean" do
|
||||
source = Source.new %(
|
||||
if false != a
|
||||
:ok
|
||||
end
|
||||
)
|
||||
subject.catch(source).should_not be_valid
|
||||
end
|
||||
|
||||
it "fails if there is case comparison to boolean" do
|
||||
source = Source.new %(
|
||||
true === a
|
||||
)
|
||||
subject.catch(source).should_not be_valid
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
source = Source.new "true != a", "source.cr"
|
||||
subject.catch(source).should_not be_valid
|
||||
|
||||
error = source.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:1:1"
|
||||
error.message.should eq "Comparison to a boolean is pointless"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
51
spec/ameba/rule/constant_names_spec.cr
Normal file
51
spec/ameba/rule/constant_names_spec.cr
Normal file
|
@ -0,0 +1,51 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba
|
||||
subject = Rule::ConstantNames.new
|
||||
|
||||
private def it_reports_constant(code, expected)
|
||||
it "reports constant name #{expected}" do
|
||||
s = Source.new code
|
||||
Rule::ConstantNames.new.catch(s).should_not be_valid
|
||||
s.errors.first.message.should contain expected
|
||||
end
|
||||
end
|
||||
|
||||
describe Rule::ConstantNames do
|
||||
it "passes if type names are screaming-cased" do
|
||||
s = Source.new %(
|
||||
LUCKY_NUMBERS = [3, 7, 11]
|
||||
DOCUMENTATION_URL = "http://crystal-lang.org/docs"
|
||||
|
||||
Int32
|
||||
|
||||
s : String = "str"
|
||||
|
||||
def works(n : Int32)
|
||||
end
|
||||
|
||||
a = 1
|
||||
myVar = 2
|
||||
m_var = 3
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it_reports_constant "MyBadConstant=1", "MYBADCONSTANT"
|
||||
it_reports_constant "Wrong_NAME=2", "WRONG_NAME"
|
||||
it_reports_constant "Wrong_Name=3", "WRONG_NAME"
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new %(
|
||||
Const = 1
|
||||
), "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:2:9"
|
||||
error.message.should eq(
|
||||
"Constant name should be screaming-cased: CONST, not Const"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
44
spec/ameba/rule/debugger_statement_spec.cr
Normal file
44
spec/ameba/rule/debugger_statement_spec.cr
Normal file
|
@ -0,0 +1,44 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba::Rule
|
||||
subject = DebuggerStatement.new
|
||||
|
||||
describe DebuggerStatement do
|
||||
it "passes if there is no debugger statement" do
|
||||
s = Source.new %(
|
||||
"this is not a debugger statement"
|
||||
s = "debugger"
|
||||
|
||||
def debugger(program)
|
||||
end
|
||||
debugger ""
|
||||
|
||||
class A
|
||||
def debugger
|
||||
end
|
||||
end
|
||||
A.new.debugger
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "fails if there is a debugger statement" do
|
||||
s = Source.new %(
|
||||
a = 2
|
||||
debugger
|
||||
a = a + 1
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new "debugger", "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:1:1"
|
||||
error.message.should eq "Possible forgotten debugger statement detected"
|
||||
end
|
||||
end
|
||||
end
|
85
spec/ameba/rule/empty_expression_spec.cr
Normal file
85
spec/ameba/rule/empty_expression_spec.cr
Normal file
|
@ -0,0 +1,85 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba
|
||||
subject = Rule::EmptyExpression.new
|
||||
|
||||
def it_detects_empty_expression(code)
|
||||
it "detects empty expression" do
|
||||
s = Source.new code
|
||||
rule = Rule::EmptyExpression.new
|
||||
rule.catch(s).should_not be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe Rule::EmptyExpression do
|
||||
it "passes if there is no empty expression" do
|
||||
s = Source.new %(
|
||||
def method()
|
||||
end
|
||||
|
||||
method()
|
||||
method(1, 2, 3)
|
||||
method(nil)
|
||||
|
||||
a = nil
|
||||
a = ""
|
||||
a = 0
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it_detects_empty_expression %(())
|
||||
it_detects_empty_expression %(((())))
|
||||
it_detects_empty_expression %(a = ())
|
||||
it_detects_empty_expression %((();()))
|
||||
it_detects_empty_expression %(if (); end)
|
||||
it_detects_empty_expression %(
|
||||
if foo
|
||||
1
|
||||
elsif ()
|
||||
2
|
||||
end
|
||||
)
|
||||
it_detects_empty_expression %(
|
||||
case foo
|
||||
when :foo then ()
|
||||
end
|
||||
)
|
||||
it_detects_empty_expression %(
|
||||
case foo
|
||||
when :foo then 1
|
||||
else
|
||||
()
|
||||
end
|
||||
)
|
||||
it_detects_empty_expression %(
|
||||
case foo
|
||||
when () then 1
|
||||
end
|
||||
)
|
||||
it_detects_empty_expression %(
|
||||
def method
|
||||
a = 1
|
||||
()
|
||||
end
|
||||
)
|
||||
it_detects_empty_expression %(
|
||||
def method
|
||||
rescue
|
||||
()
|
||||
end
|
||||
)
|
||||
|
||||
it "reports rule, location and message" do
|
||||
s = Source.new %(
|
||||
if ()
|
||||
end
|
||||
), "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:2:12"
|
||||
error.message.should eq "Avoid empty expression '()'"
|
||||
end
|
||||
end
|
||||
end
|
118
spec/ameba/rule/large_numbers_spec.cr
Normal file
118
spec/ameba/rule/large_numbers_spec.cr
Normal file
|
@ -0,0 +1,118 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba
|
||||
subject = Rule::LargeNumbers.new
|
||||
|
||||
private def it_transforms(number, expected)
|
||||
it "transforms large number #{number}" do
|
||||
s = Source.new number
|
||||
Rule::LargeNumbers.new.catch(s).should_not be_valid
|
||||
s.errors.first.message.should contain expected
|
||||
end
|
||||
end
|
||||
|
||||
describe Rule::LargeNumbers do
|
||||
it "passes if large number does not require underscore" do
|
||||
s = Source.new %q(
|
||||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
16 17 18 19 20 30 40 50 60 70 80 90
|
||||
100
|
||||
1_000
|
||||
10_000
|
||||
100_000
|
||||
200_000
|
||||
300_000
|
||||
400_000
|
||||
500_000
|
||||
600_000
|
||||
700_000
|
||||
800_000
|
||||
900_000
|
||||
1_000_000
|
||||
|
||||
-9_223_372_036_854_775_808
|
||||
9_223_372_036_854_775_807
|
||||
|
||||
141_592_654
|
||||
141_592_654.0
|
||||
141_592_654.001
|
||||
141_592_654.001_2
|
||||
141_592_654.001_23
|
||||
141_592_654.001_234
|
||||
141_592_654.001_234_5
|
||||
|
||||
0b1101
|
||||
0o123
|
||||
0xFE012D
|
||||
0xfe012d
|
||||
0xfe012dd11
|
||||
|
||||
1_i8
|
||||
12_i16
|
||||
123_i32
|
||||
1_234_i64
|
||||
|
||||
12_u8
|
||||
123_u16
|
||||
1_234_u32
|
||||
9_223_372_036_854_775_808_u64
|
||||
9_223_372_036_854_775_808.000_123_456_789_f64
|
||||
|
||||
+100_u32
|
||||
-900_000_i32
|
||||
|
||||
1_234.5e-7
|
||||
11_234e10_f32
|
||||
+1.123
|
||||
-0.000_5
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it_transforms "10000", "10_000"
|
||||
it_transforms "+10000", "+10_000"
|
||||
it_transforms "-10000", "-10_000"
|
||||
|
||||
it_transforms "9223372036854775808", "9_223_372_036_854_775_808"
|
||||
it_transforms "-9223372036854775808", "-9_223_372_036_854_775_808"
|
||||
it_transforms "+9223372036854775808", "+9_223_372_036_854_775_808"
|
||||
|
||||
it_transforms "1_00000", "100_000"
|
||||
|
||||
it_transforms "1_23_i8", "123_i8"
|
||||
it_transforms "1000_i16", "1_000_i16"
|
||||
it_transforms "1000_i32", "1_000_i32"
|
||||
it_transforms "1000_i64", "1_000_i64"
|
||||
|
||||
it_transforms "1_23_u8", "123_u8"
|
||||
it_transforms "1000_u16", "1_000_u16"
|
||||
it_transforms "1000_u32", "1_000_u32"
|
||||
it_transforms "1000_u64", "1_000_u64"
|
||||
|
||||
it_transforms "123456_f32", "123_456_f32"
|
||||
it_transforms "123456_f64", "123_456_f64"
|
||||
|
||||
it_transforms "123456.5e-7_f32", "123_456.5e-7_f32"
|
||||
it_transforms "123456e10_f64", "123_456e10_f64"
|
||||
|
||||
it_transforms "123456.5e-7", "123_456.5e-7"
|
||||
it_transforms "123456e10", "123_456e10"
|
||||
|
||||
it_transforms "3.00_1", "3.001"
|
||||
it_transforms "3.0012", "3.001_2"
|
||||
it_transforms "3.00123", "3.001_23"
|
||||
it_transforms "3.001234", "3.001_234"
|
||||
it_transforms "3.0012345", "3.001_234_5"
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new %q(
|
||||
1200000
|
||||
), "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:2:10"
|
||||
error.message.should match /1_200_000/
|
||||
end
|
||||
end
|
||||
end
|
33
spec/ameba/rule/line_length_spec.cr
Normal file
33
spec/ameba/rule/line_length_spec.cr
Normal file
|
@ -0,0 +1,33 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba::Rule
|
||||
subject = LineLength.new
|
||||
long_line = "*" * 81
|
||||
|
||||
describe LineLength do
|
||||
it "passes if all lines are shorter than 80 symbols" do
|
||||
source = Source.new "short line"
|
||||
subject.catch(source).should be_valid
|
||||
end
|
||||
|
||||
it "passes if line consists of 79 symbols" do
|
||||
source = Source.new "*" * 80
|
||||
subject.catch(source).should be_valid
|
||||
end
|
||||
|
||||
it "fails if there is at least one line longer than 79 symbols" do
|
||||
source = Source.new long_line
|
||||
subject.catch(source).should_not be_valid
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
source = Source.new long_line, "source.cr"
|
||||
subject.catch(source).should_not be_valid
|
||||
|
||||
error = source.errors.first
|
||||
error.rule.should eq subject
|
||||
error.location.to_s.should eq "source.cr:1:81"
|
||||
error.message.should eq "Line too long"
|
||||
end
|
||||
end
|
||||
end
|
72
spec/ameba/rule/literal_in_condition_spec.cr
Normal file
72
spec/ameba/rule/literal_in_condition_spec.cr
Normal file
|
@ -0,0 +1,72 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba::Rule
|
||||
subject = LiteralInCondition.new
|
||||
|
||||
describe LiteralInCondition do
|
||||
it "passes if there is not literals in conditional" do
|
||||
s = Source.new %(
|
||||
if a == 2
|
||||
:ok
|
||||
end
|
||||
|
||||
:ok unless b
|
||||
|
||||
case string
|
||||
when "a"
|
||||
:ok
|
||||
when "b"
|
||||
:ok
|
||||
end
|
||||
|
||||
unless a.nil?
|
||||
:ok
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "fails if there is a predicate in if conditional" do
|
||||
s = Source.new %(
|
||||
if "string"
|
||||
:ok
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
end
|
||||
|
||||
it "fails if there is a predicate in unless conditional" do
|
||||
s = Source.new %(
|
||||
unless true
|
||||
:ok
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
end
|
||||
|
||||
it "fails if there is a predicate in case conditional" do
|
||||
s = Source.new %(
|
||||
case [1, 2, 3]
|
||||
when :array
|
||||
:ok
|
||||
when :not_array
|
||||
:also_ok
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new %(
|
||||
puts "hello" if true
|
||||
), "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
s.errors.size.should eq 1
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:2:9"
|
||||
error.message.should eq "Literal value found in conditional"
|
||||
end
|
||||
end
|
||||
end
|
41
spec/ameba/rule/literal_in_interpolation_spec.cr
Normal file
41
spec/ameba/rule/literal_in_interpolation_spec.cr
Normal file
|
@ -0,0 +1,41 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba::Rule
|
||||
subject = LiteralInInterpolation.new
|
||||
|
||||
describe LiteralInInterpolation do
|
||||
it "passes with good interpolation examples" do
|
||||
s = Source.new %q(
|
||||
name = "Ary"
|
||||
"Hello, #{name}"
|
||||
|
||||
"#{name}"
|
||||
|
||||
"Name size: #{name.size}"
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "fails if there is useless interpolation" do
|
||||
[
|
||||
%q("#{:Ary}"),
|
||||
%q("#{[1, 2, 3]}"),
|
||||
%q("#{true}"),
|
||||
%q("#{false}"),
|
||||
%q("here are #{4} cats"),
|
||||
].each do |str|
|
||||
subject.catch(Source.new str).should_not be_valid
|
||||
end
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new %q("#{4}"), "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:1:1"
|
||||
error.message.should eq "Literal value found in interpolation"
|
||||
end
|
||||
end
|
||||
end
|
55
spec/ameba/rule/method_names_spec.cr
Normal file
55
spec/ameba/rule/method_names_spec.cr
Normal file
|
@ -0,0 +1,55 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba
|
||||
subject = Rule::MethodNames.new
|
||||
|
||||
private def it_reports_method_name(code, expected)
|
||||
it "reports method name #{expected}" do
|
||||
s = Source.new code
|
||||
Rule::MethodNames.new.catch(s).should_not be_valid
|
||||
s.errors.first.message.should contain expected
|
||||
end
|
||||
end
|
||||
|
||||
describe Rule::MethodNames do
|
||||
it "passes if method names are underscore-cased" do
|
||||
s = Source.new %(
|
||||
class Person
|
||||
def first_name
|
||||
end
|
||||
|
||||
def date_of_birth
|
||||
end
|
||||
|
||||
def homepage_url
|
||||
end
|
||||
|
||||
def valid?
|
||||
end
|
||||
|
||||
def name
|
||||
end
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it_reports_method_name %(def firstName; end), "first_name"
|
||||
it_reports_method_name %(def date_of_Birth; end), "date_of_birth"
|
||||
it_reports_method_name %(def homepageURL; end), "homepage_url"
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new %(
|
||||
def bad_Name
|
||||
end
|
||||
), "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:2:9"
|
||||
error.message.should eq(
|
||||
"Method name should be underscore-cased: bad_name, not bad_Name"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
68
spec/ameba/rule/negated_conditions_in_unless_spec.cr
Normal file
68
spec/ameba/rule/negated_conditions_in_unless_spec.cr
Normal file
|
@ -0,0 +1,68 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba::Rule
|
||||
subject = NegatedConditionsInUnless.new
|
||||
|
||||
describe NegatedConditionsInUnless do
|
||||
it "passes with a unless without negated condition" do
|
||||
s = Source.new %(
|
||||
unless a
|
||||
:ok
|
||||
end
|
||||
|
||||
:ok unless b
|
||||
|
||||
unless s.empty?
|
||||
:ok
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "fails if there is a negated condition in unless" do
|
||||
s = Source.new %(
|
||||
unless !a
|
||||
:nok
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
end
|
||||
|
||||
it "fails if one of AND conditions is negated" do
|
||||
s = Source.new %(
|
||||
unless a && !b
|
||||
:nok
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
end
|
||||
|
||||
it "fails if one of OR conditions is negated" do
|
||||
s = Source.new %(
|
||||
unless a || !b
|
||||
:nok
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
end
|
||||
|
||||
it "fails if one of inner conditions is negated" do
|
||||
s = Source.new %(
|
||||
unless a && (b || !c)
|
||||
:nok
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new ":nok unless !s.empty?", "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:1:1"
|
||||
error.message.should eq "Avoid negated conditions in unless blocks"
|
||||
end
|
||||
end
|
||||
end
|
45
spec/ameba/rule/predicate_name_spec.cr
Normal file
45
spec/ameba/rule/predicate_name_spec.cr
Normal file
|
@ -0,0 +1,45 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba::Rule
|
||||
subject = PredicateName.new
|
||||
|
||||
describe PredicateName do
|
||||
it "passes if predicate name is correct" do
|
||||
s = Source.new %q(
|
||||
def valid?(x)
|
||||
end
|
||||
|
||||
class Image
|
||||
def picture?(x)
|
||||
end
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "fails if predicate name is wrong" do
|
||||
s = Source.new %q(
|
||||
def is_valid?(x)
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new %q(
|
||||
class Image
|
||||
def has_picture?(x)
|
||||
true
|
||||
end
|
||||
end
|
||||
), "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:3:11"
|
||||
error.message.should eq(
|
||||
"Favour method name 'picture?' over 'has_picture?'")
|
||||
end
|
||||
end
|
||||
end
|
37
spec/ameba/rule/trailing_blank_lines_spec.cr
Normal file
37
spec/ameba/rule/trailing_blank_lines_spec.cr
Normal file
|
@ -0,0 +1,37 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba::Rule
|
||||
subject = TrailingBlankLines.new
|
||||
|
||||
describe TrailingBlankLines do
|
||||
it "passes if there is no blank lines at the end" do
|
||||
source = Source.new "no-blankline"
|
||||
subject.catch(source).should be_valid
|
||||
end
|
||||
|
||||
it "fails if there is a blank line at the end of a source" do
|
||||
source = Source.new "a = 1\n \n "
|
||||
subject.catch(source).should_not be_valid
|
||||
end
|
||||
|
||||
it "passes if source is empty" do
|
||||
source = Source.new ""
|
||||
subject.catch(source).should be_valid
|
||||
end
|
||||
|
||||
it "passes if last line is not blank" do
|
||||
source = Source.new "\n\n\n puts 22"
|
||||
subject.catch(source).should be_valid
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
source = Source.new "a = 1\n\n ", "source.cr"
|
||||
subject.catch(source).should_not be_valid
|
||||
|
||||
error = source.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:3:1"
|
||||
error.message.should eq "Blank lines detected at the end of the file"
|
||||
end
|
||||
end
|
||||
end
|
27
spec/ameba/rule/trailing_whitespace_spec.cr
Normal file
27
spec/ameba/rule/trailing_whitespace_spec.cr
Normal file
|
@ -0,0 +1,27 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba::Rule
|
||||
subject = TrailingWhitespace.new
|
||||
|
||||
describe TrailingWhitespace do
|
||||
it "passes if all lines do not have trailing whitespace" do
|
||||
source = Source.new "no-whispace"
|
||||
subject.catch(source).should be_valid
|
||||
end
|
||||
|
||||
it "fails if there is a line with trailing whitespace" do
|
||||
source = Source.new "whitespace at the end "
|
||||
subject.catch(source).should_not be_valid
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
source = Source.new "a = 1\n b = 2 ", "source.cr"
|
||||
subject.catch(source).should_not be_valid
|
||||
|
||||
error = source.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:2:7"
|
||||
error.message.should eq "Trailing whitespace detected"
|
||||
end
|
||||
end
|
||||
end
|
60
spec/ameba/rule/type_names_spec.cr
Normal file
60
spec/ameba/rule/type_names_spec.cr
Normal file
|
@ -0,0 +1,60 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba
|
||||
subject = Rule::TypeNames.new
|
||||
|
||||
private def it_reports_name(code, expected)
|
||||
it "reports type name #{expected}" do
|
||||
s = Source.new code
|
||||
Rule::TypeNames.new.catch(s).should_not be_valid
|
||||
s.errors.first.message.should contain expected
|
||||
end
|
||||
end
|
||||
|
||||
describe Rule::TypeNames do
|
||||
it "passes if type names are camelcased" do
|
||||
s = Source.new %(
|
||||
class ParseError < Exception
|
||||
end
|
||||
|
||||
module HTTP
|
||||
class RequestHandler
|
||||
end
|
||||
end
|
||||
|
||||
alias NumericValue = Float32 | Float64 | Int32 | Int64
|
||||
|
||||
lib LibYAML
|
||||
end
|
||||
|
||||
struct TagDirective
|
||||
end
|
||||
|
||||
enum Time::DayOfWeek
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it_reports_name "class My_class; end", "MyClass"
|
||||
it_reports_name "module HTT_p; end", "HTTP"
|
||||
it_reports_name "alias Numeric_value = Int32", "NumericValue"
|
||||
it_reports_name "lib Lib_YAML; end", "LibYAML"
|
||||
it_reports_name "struct Tag_directive; end", "TagDirective"
|
||||
it_reports_name "enum Time_enum::Day_of_week; end", "TimeEnum::DayOfWeek"
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new %(
|
||||
class My_class
|
||||
end
|
||||
), "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:2:9"
|
||||
error.message.should eq(
|
||||
"Type name should be camelcased: MyClass, but it was My_class"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
44
spec/ameba/rule/unless_else_spec.cr
Normal file
44
spec/ameba/rule/unless_else_spec.cr
Normal file
|
@ -0,0 +1,44 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba::Rule
|
||||
subject = UnlessElse.new
|
||||
|
||||
describe UnlessElse do
|
||||
it "passes if unless hasn't else" do
|
||||
s = Source.new %(
|
||||
unless something
|
||||
:ok
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "fails if unless has else" do
|
||||
s = Source.new %(
|
||||
unless something
|
||||
:one
|
||||
else
|
||||
:two
|
||||
end
|
||||
)
|
||||
subject.catch(s).should_not be_valid
|
||||
end
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new %(
|
||||
unless something
|
||||
:one
|
||||
else
|
||||
:two
|
||||
end
|
||||
), "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
|
||||
error = s.errors.first
|
||||
error.should_not be_nil
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:2:9"
|
||||
error.message.should eq "Favour if over unless with else"
|
||||
end
|
||||
end
|
||||
end
|
61
spec/ameba/rule/variable_names_spec.cr
Normal file
61
spec/ameba/rule/variable_names_spec.cr
Normal file
|
@ -0,0 +1,61 @@
|
|||
require "../../spec_helper"
|
||||
|
||||
module Ameba
|
||||
subject = Rule::VariableNames.new
|
||||
|
||||
private def it_reports_var_name(code, expected)
|
||||
it "reports method name #{expected}" do
|
||||
s = Source.new code
|
||||
Rule::VariableNames.new.catch(s).should_not be_valid
|
||||
s.errors.first.message.should contain expected
|
||||
end
|
||||
end
|
||||
|
||||
describe Rule::VariableNames do
|
||||
it "passes if var names are underscore-cased" do
|
||||
s = Source.new %(
|
||||
class Greeting
|
||||
@@default_greeting = "Hello world"
|
||||
|
||||
def initialize(@custom_greeting = nil)
|
||||
end
|
||||
|
||||
def print_greeting
|
||||
greeting = @custom_greeting || @@default_greeting
|
||||
puts greeting
|
||||
end
|
||||
end
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it_reports_var_name %(myBadNamedVar = 1), "my_bad_named_var"
|
||||
it_reports_var_name %(wrong_Name = 'y'), "wrong_name"
|
||||
|
||||
it_reports_var_name %(
|
||||
class Greeting
|
||||
def initialize(@badNamed = nil)
|
||||
end
|
||||
end
|
||||
), "bad_named"
|
||||
|
||||
it_reports_var_name %(
|
||||
class Greeting
|
||||
@@defaultGreeting = "Hello world"
|
||||
end
|
||||
), "default_greeting"
|
||||
|
||||
it "reports rule, pos and message" do
|
||||
s = Source.new %(
|
||||
badName = "Yeah"
|
||||
), "source.cr"
|
||||
subject.catch(s).should_not be_valid
|
||||
error = s.errors.first
|
||||
error.rule.should_not be_nil
|
||||
error.location.to_s.should eq "source.cr:2:9"
|
||||
error.message.should eq(
|
||||
"Var name should be underscore-cased: bad_name, not badName"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue