| // 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 |