blob: 8d4825aa9fb302924d266842db073030cc3659fd [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/package_filename_rule.h"
#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;
constexpr int kToken = SymbolIdentifier;
// Test that no violations are found with an empty filename.
TEST(PackageFilenameRuleTest, BlankFilename) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"package m; endpackage"},
{"class c; endclass"},
};
const std::string filename = "";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCases, filename);
}
// Test that as every package that doesn't match begets a violation.
TEST(PackageFilenameRuleTest, PackageMatchesFilename) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"package m; endpackage"},
{"package ", {kToken, "n"}, "; endpackage\npackage m; endpackage"},
{"package m; endpackage\npackage ", {kToken, "n"}, "; endpackage"},
{"package m; endpackage\n"
"package ",
{kToken, "n"},
"; endpackage\n"
"package ",
{kToken, "o"},
"; endpackage"},
{"package ", {kToken, "m_pkg"}, "; endpackage"},
};
const std::string filename = "/path/to/m.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCases, filename);
}
// Test that as every package that doesn't match begets a violation.
TEST(PackageFilenameRuleTest, PackagePlusPkgMatchesFilename) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"package m; endpackage"},
{"package ", {kToken, "n"}, "; endpackage\npackage m; endpackage"},
{"package m; endpackage\npackage ", {kToken, "n"}, "; endpackage"},
{"package m; endpackage\n"
"package ",
{kToken, "n"},
"; endpackage\n"
"package ",
{kToken, "o"},
"; endpackage"},
{"package m_pkg; endpackage"},
};
const std::string filename = "/path/to/m_pkg.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCases, filename);
}
// Test that we correctly discard everything in the filename after the first
// dot.
TEST(PackageFilenameRuleTest, UnitNameIsFilenameBeforeTheFirstDot) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"package m; endpackage"},
{"package ", {kToken, "n"}, "; endpackage\npackage m; endpackage"},
{"package m; endpackage\npackage ", {kToken, "n"}, "; endpackage"},
{"package m; endpackage\n"
"package ",
{kToken, "n"},
"; endpackage\n"
"package ",
{kToken, "o"},
"; endpackage"},
{"package m_pkg; endpackage"},
};
const std::string filename = "/path/to/m_pkg.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCases, filename);
const std::string filename2 = "/path/to/m_pkg.this.is.junk.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCases, filename2);
}
TEST(PackageFilenameRuleTest, LegalPackagesForFooPkgSv) {
const std::initializer_list<LintTestCase> kTestCasesForFooPkgSv = {
{"package foo; endpackage"},
{"package foo_pkg; endpackage"},
};
const std::string foo_pkg_sv = "/path/to/foo_pkg.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCasesForFooPkgSv,
foo_pkg_sv);
}
TEST(PackageFilenameRuleTest, LegalPackagesForFooSv) {
const std::initializer_list<LintTestCase> kTestCasesForFooSv = {
{"package foo; endpackage"},
{"package ", {kToken, "foo_pkg"}, "; endpackage"},
};
const std::string foo_sv = "/path/to/foo.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCasesForFooSv,
foo_sv);
}
TEST(PackageFilenameRuleTest, LegalPackagesForFooPkgPkgSv) {
// It is weird, but legal, to put package "foo_pkg" in "foo_pkg_pkg.sv".
const std::initializer_list<LintTestCase> kTestCasesForFooPkgPkgSv = {
{"package ", {kToken, "foo"}, "; endpackage"},
{"package foo_pkg; endpackage"},
{"package foo_pkg_pkg; endpackage"},
{"package ", {kToken, "foo_pkg_pkg_pkg"}, "; endpackage"},
};
const std::string foo_pkg_pkg_sv = "/path/to/foo_pkg_pkg.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(
kTestCasesForFooPkgPkgSv, foo_pkg_pkg_sv);
}
// Test that violations are reporter for every mismatch against absolute path.
TEST(PackageFilenameRuleTest, NoPackageMatchesFilenameAbsPath) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"package ", {kToken, "m"}, "; endpackage"},
{"package ",
{kToken, "m"},
"; endpackage\npackage ",
{kToken, "n"},
"; endpackage"},
};
const std::string filename = "/path/to/q.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCases, filename);
}
// Test that some violations are found checked against a relative filename.
TEST(PackageFilenameRuleTest, NoPackageMatchesFilenameRelPath) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"package ", {kToken, "m"}, "; endpackage"},
{"package ",
{kToken, "m"},
"; endpackage\npackage ",
{kToken, "n"},
"; endpackage"},
};
const std::string filename = "path/to/r.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCases, filename);
}
// Test that optional _pkg suffixes on declaration are illegal.
TEST(PackageFilenameRuleTest, PackageMatchesOptionalDeclarationSuffix) {
const std::initializer_list<LintTestCase> kTestCases = {
{"package q; endpackage"},
{"package ", {kToken, "q_pkg"}, "; endpackage"},
};
const std::string filename = "/path/to/q.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCases, filename);
}
// Test that optional _pkg suffixes on filename are forgiven.
TEST(PackageFilenameRuleTest, PackageMatchesOptionalFileSuffix) {
const std::initializer_list<LintTestCase> kTestCases = {
{"package q; endpackage"},
{"package q_pkg; endpackage"},
};
const std::string filename = "/path/to/q_pkg.sv";
RunLintTestCases<VerilogAnalyzer, PackageFilenameRule>(kTestCases, filename);
}
TEST(PackageFilenameRuleTest, DashAllowedWhenConfigured) {
const std::initializer_list<LintTestCase> kOkCases = {
{"package foo_bar; endpackage"},
};
const std::initializer_list<LintTestCase> kComplaintCases = {
{"package ", {kToken, "foo_bar"}, "; endpackage"},
};
const std::string f_with_underscore = "/path/to/foo_bar.sv";
const std::string f_with_dash = "/path/to/foo-bar.sv";
const std::string f_with_dash_pkg = "/path/to/foo-bar-pkg.sv";
{
// With dashes not allowed, we only accept the underscore name
constexpr absl::string_view config = "allow-dash-for-underscore:off";
RunConfiguredLintTestCases<VerilogAnalyzer, PackageFilenameRule>(
kOkCases, config, f_with_underscore);
RunConfiguredLintTestCases<VerilogAnalyzer, PackageFilenameRule>(
kComplaintCases, config, f_with_dash);
RunConfiguredLintTestCases<VerilogAnalyzer, PackageFilenameRule>(
kComplaintCases, config, f_with_dash_pkg);
}
{
// ... 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, PackageFilenameRule>(
kOkCases, config, f_with_underscore);
RunConfiguredLintTestCases<VerilogAnalyzer, PackageFilenameRule>(
kOkCases, config, f_with_dash);
RunConfiguredLintTestCases<VerilogAnalyzer, PackageFilenameRule>(
kOkCases, config, f_with_dash_pkg);
}
}
} // namespace
} // namespace analysis
} // namespace verilog