blob: 52cb69d3e6497e43549910c13ca63297a3959bbc [file] [log] [blame]
// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "verilog/analysis/checkers/module_filename_rule.h"
#include <initializer_list>
#include <string>
#include "gtest/gtest.h"
#include "common/analysis/linter_test_utils.h"
#include "common/analysis/text_structure_linter_test_utils.h"
#include "common/text/symbol.h"
#include "verilog/analysis/verilog_analyzer.h"
#include "verilog/parser/verilog_token_enum.h"
namespace verilog {
namespace analysis {
namespace {
using verible::LintTestCase;
using verible::RunConfiguredLintTestCases;
using verible::RunLintTestCases;
// Expected token type of findings.
constexpr int kToken = SymbolIdentifier;
// Test that no violations are found with an empty filename.
TEST(ModuleFilenameRuleTest, BlankFilename) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"module m; endmodule"},
{"class c; endclass"},
};
const std::string filename = "";
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(kTestCases, filename);
}
// Test that as long as one module matches file name, no violations reported.
TEST(ModuleFilenameRuleTest, ModuleMatchesFilename) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"module m; endmodule"},
{"module n; endmodule\nmodule m; endmodule"},
{"module m; endmodule\nmodule n; endmodule"},
};
const std::string filename = "/path/to/m.sv";
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(kTestCases, filename);
}
TEST(ModuleFilenameRuleTest, DashAllowedWhenConfigured) {
const std::initializer_list<LintTestCase> kOkCases = {
{"module multi_word_module; endmodule"},
};
const std::initializer_list<LintTestCase> kComplaintCases = {
{"module ", {kToken, "multi_word_module"}, "; endmodule"},
};
const std::string f_with_underscore = "/path/to/multi_word_module.sv";
const std::string f_with_dash = "/path/to/multi-word-module.sv";
{
// With dashes not allowed, we only accept the underscore name
constexpr absl::string_view config = "allow-dash-for-underscore:off";
RunConfiguredLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(
kOkCases, config, f_with_underscore);
RunConfiguredLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(
kComplaintCases, config, f_with_dash);
}
{
// ... But with dashes allowed, dashes are also an ok case.
constexpr absl::string_view config = "allow-dash-for-underscore:on";
// With dashes not allowed, we only accept the underscore name
RunConfiguredLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(
kOkCases, config, f_with_underscore);
RunConfiguredLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(
kOkCases, config, f_with_dash);
}
}
// Test more unusual file names with multiple dots in them.
TEST(ModuleFilenameRuleTest, ModuleMatchesMultiDotComponentFilename) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"package q; endpackage\n"},
{"module m; endmodule\n"},
{"module n; endmodule\nmodule m; endmodule"},
{"module m; endmodule\nmodule n; endmodule"},
};
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(kTestCases,
"/path/to/m");
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(kTestCases,
"/path/to/m.v");
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(kTestCases,
"/path/to/m.sv");
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(kTestCases,
"/path/to/m.stub.sv");
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(
kTestCases, "/path/to/m.behavioral.model.sv");
}
// Test that some violations are found checked against a filename.
TEST(ModuleFilenameRuleTest, NoModuleMatchesFilenameAbsPath) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"package q; endpackage\n"},
{"module ", {kToken, "m"}, "; endmodule"},
{"module m; endmodule\nmodule ", {kToken, "n"}, "; endmodule"},
{"module ",
{kToken, "m"},
";\n"
" module q;\n" // Matches, but is not an outermost declaration
" endmodule : q\n"
"endmodule : m"},
{"module ",
{kToken, "m"},
";\n"
" module foo;\n"
" endmodule : foo\n"
" module q;\n"
" endmodule : q\n"
"endmodule : m"},
{"module ",
{kToken, "m"},
";\n"
" module foo;\n"
" module q;\n"
" endmodule : q\n"
" endmodule : foo\n"
"endmodule : m"},
};
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(kTestCases,
"/path/to/q.sv");
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(kTestCases,
"/path/to/q.stub.sv");
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(kTestCases,
"/path/to/q.m.sv");
}
// Test that some violations are found checked against a filename.
TEST(ModuleFilenameRuleTest, NoModuleMatchesFilenameRelPath) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"module ", {kToken, "m"}, "; endmodule"},
{"module m; endmodule\nmodule ", {kToken, "n"}, "; endmodule"},
{"module ",
{kToken, "m"},
";\n"
" module r;\n" // Matches, but is not an outermost declaration
" endmodule : r\n"
"endmodule : m"},
{"module ",
{kToken, "m"},
";\n"
" module foo;\n"
" endmodule : foo\n"
" module r;\n"
" endmodule : r\n"
"endmodule : m"},
{"module ",
{kToken, "m"},
";\n"
" module foo;\n"
" module r;\n"
" endmodule : r\n"
" endmodule : foo\n"
"endmodule : m"},
};
const std::string filename = "path/to/r.sv";
RunLintTestCases<VerilogAnalyzer, ModuleFilenameRule>(kTestCases, filename);
}
} // namespace
} // namespace analysis
} // namespace verilog