D-Scanner/src/dscanner/analysis/explicitly_annotated_unitte...

97 lines
2.5 KiB
D

// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
module dscanner.analysis.explicitly_annotated_unittests;
import dscanner.analysis.base;
import dscanner.analysis.helpers;
/**
* Requires unittests to be explicitly annotated with either @safe or @system
*/
extern(C++) class ExplicitlyAnnotatedUnittestCheck(AST) : BaseAnalyzerDmd
{
mixin AnalyzerInfo!"explicitly_annotated_unittests";
alias visit = BaseAnalyzerDmd.visit;
extern(D) this(string fileName)
{
super(fileName);
}
override void visit(AST.UnitTestDeclaration d)
{
import dmd.astenums : STC;
if (!(d.storage_class & STC.safe || d.storage_class & STC.system))
addErrorMessage(cast(ulong) d.loc.linnum, cast(ulong) d.loc.charnum,
KEY, MESSAGE);
super.visit(d);
}
private:
enum string KEY = "dscanner.style.explicitly_annotated_unittest";
enum string MESSAGE = "A unittest should be annotated with at least @safe or @system";
}
unittest
{
import std.stdio : stderr;
import std.format : format;
import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig;
import dscanner.analysis.helpers : assertAnalyzerWarnings;
StaticAnalysisConfig sac = disabledConfig();
sac.explicitly_annotated_unittests = Check.enabled;
assertAnalyzerWarningsDMD(q{
@disable foo() {}
@safe unittest {}
@system unittest {}
pure nothrow @system @nogc unittest {}
unittest {} // [warn]: A unittest should be annotated with at least @safe or @system
pure nothrow @nogc unittest {} // [warn]: A unittest should be annotated with at least @safe or @system
}c, sac);
// nested
assertAnalyzerWarningsDMD(q{
struct Foo
{
@safe unittest {}
@system unittest {}
unittest {} // [warn]: A unittest should be annotated with at least @safe or @system
pure nothrow @nogc unittest {} // [warn]: A unittest should be annotated with at least @safe or @system
}
}c, sac);
// TODO: Check and fix
//// nested
//assertAutoFix(q{
//unittest {} // fix:0
//pure nothrow @nogc unittest {} // fix:0
//struct Foo
//{
//unittest {} // fix:1
//pure nothrow @nogc unittest {} // fix:1
//}
//}c, q{
//@safe unittest {} // fix:0
//pure nothrow @nogc @safe unittest {} // fix:0
//struct Foo
//{
//@system unittest {} // fix:1
//pure nothrow @nogc @system unittest {} // fix:1
//}
//}c, sac);
stderr.writeln("Unittest for ExplicitlyAnnotatedUnittestCheck passed.");
}