diff --git a/linters/codequality/rules.go b/linters/codequality/rules.go index af9de46..79fa409 100644 --- a/linters/codequality/rules.go +++ b/linters/codequality/rules.go @@ -31,7 +31,7 @@ Linter | Why? This rule will be satisfied, iff for each of these linters: - **Either** there is a configuration file for this linter in the project -- **Or** the linter is a dependency of the project`, +- **Or** the linter is a dependency of the project (preferably a dev dependency)`, Weight: 1, } diff --git a/linters/testing/linter.go b/linters/testing/linter.go index 51a2c5e..3f6a455 100644 --- a/linters/testing/linter.go +++ b/linters/testing/linter.go @@ -1,4 +1,4 @@ -package template +package testing import ( "fmt" @@ -48,10 +48,17 @@ func (l *TestingLinter) LintProject(project api.Project) (api.Report, error) { } func (l *TestingLinter) ScoreRuleHasTests(report *api.Report, project api.Project) { + if len(project.PythonFiles) == 0 { + report.Scores[RuleHasTests] = 0 + return + } + testFiles := project.PythonFiles.Filter(func(filename string) bool { return strings.HasSuffix(filename, "_test.py") || strings.HasPrefix(path.Base(filename), "test_") }) + // Possible TODO: have a config option for the target amount of tests per file? + // there should be at 1 test file per 4 non-test Python files. report.Scores[RuleHasTests] = 100 * (float64(len(testFiles)) * 4 / float64(len(project.PythonFiles)-len(testFiles))) } diff --git a/linters/testing/linter_test.go b/linters/testing/linter_test.go new file mode 100644 index 0000000..5e186d5 --- /dev/null +++ b/linters/testing/linter_test.go @@ -0,0 +1,87 @@ +package testing_test + +import ( + "fmt" + stdtesting "testing" + + "github.com/bvobart/mllint/api" + "github.com/bvobart/mllint/config" + "github.com/bvobart/mllint/linters/testing" + "github.com/bvobart/mllint/linters/testutils" + "github.com/bvobart/mllint/utils" + "github.com/stretchr/testify/require" +) + +func TestTestingLinter(t *stdtesting.T) { + linter := testing.NewLinter() + require.Equal(t, "Testing", linter.Name()) + + suite := testutils.NewLinterTestSuite(linter, []testutils.LinterTest{ + { + Name: "NoTestsNoFiles", + Dir: ".", + Expect: func(report api.Report, err error) { + require.NoError(t, err) + require.EqualValues(t, 0, report.Scores[testing.RuleHasTests]) + require.EqualValues(t, 0, report.Scores[testing.RuleTestsPass]) + // require.Equal(t, 0, report.Scores[testing.RuleTestsFolder]) + // require.Equal(t, 0, report.Scores[testing.RuleTestCoverage]) + }, + }, + { + Name: "NoTestsSixteenFiles", + Dir: ".", + Options: testutils.NewOptions().UsePythonFiles(createPythonFilenames(16)), + Expect: func(report api.Report, err error) { + require.NoError(t, err) + require.EqualValues(t, 0, report.Scores[testing.RuleHasTests]) + require.EqualValues(t, 0, report.Scores[testing.RuleTestsPass]) + // require.Equal(t, 0, report.Scores[testing.RuleTestsFolder]) + // require.Equal(t, 0, report.Scores[testing.RuleTestCoverage]) + }, + }, + { + Name: "OneTestSixteenFiles", + Dir: ".", + Options: testutils.NewOptions().UsePythonFiles(createPythonFilenames(16).Concat(createPythonTestFilenames(1))), + Expect: func(report api.Report, err error) { + require.NoError(t, err) + require.EqualValues(t, 25, report.Scores[testing.RuleHasTests]) + require.EqualValues(t, 0, report.Scores[testing.RuleTestsPass]) + // require.Equal(t, 0, report.Scores[testing.RuleTestsFolder]) + // require.Equal(t, 0, report.Scores[testing.RuleTestCoverage]) + }, + }, + { + Name: "FourTestsSixteenFiles", + Dir: ".", + Options: testutils.NewOptions().UsePythonFiles(createPythonFilenames(16).Concat(createPythonTestFilenames(4))), + Expect: func(report api.Report, err error) { + require.NoError(t, err) + require.EqualValues(t, 100, report.Scores[testing.RuleHasTests]) + require.EqualValues(t, 0, report.Scores[testing.RuleTestsPass]) + // require.Equal(t, 0, report.Scores[testing.RuleTestsFolder]) + // require.Equal(t, 0, report.Scores[testing.RuleTestCoverage]) + }, + }, + }) + + suite.DefaultOptions().WithConfig(config.Default()) + suite.RunAll(t) +} + +func createPythonFilenames(n int) utils.Filenames { + files := make(utils.Filenames, n) + for i := 0; i < n; i++ { + files[i] = fmt.Sprint("file", i, ".py") + } + return files +} + +func createPythonTestFilenames(n int) utils.Filenames { + files := make(utils.Filenames, n) + for i := 0; i < n; i++ { + files[i] = fmt.Sprint("file", i, "_test.py") + } + return files +} diff --git a/linters/testing/rules.go b/linters/testing/rules.go index b826c08..e0d2bd1 100644 --- a/linters/testing/rules.go +++ b/linters/testing/rules.go @@ -1,4 +1,4 @@ -package template +package testing import "github.com/bvobart/mllint/api"