diff --git a/pkg/printers/checkstyle.go b/pkg/printers/checkstyle.go
index 3cd1fa4cf600..bb347bd2baa6 100644
--- a/pkg/printers/checkstyle.go
+++ b/pkg/printers/checkstyle.go
@@ -5,6 +5,7 @@ import (
"encoding/xml"
"fmt"
"io"
+ "sort"
"github.com/go-xmlfmt/xmlfmt"
@@ -79,6 +80,10 @@ func (p Checkstyle) Print(ctx context.Context, issues []result.Issue) error {
out.Files = append(out.Files, file)
}
+ sort.Slice(out.Files, func(i, j int) bool {
+ return out.Files[i].Name < out.Files[j].Name
+ })
+
data, err := xml.Marshal(&out)
if err != nil {
return err
diff --git a/pkg/printers/checkstyle_test.go b/pkg/printers/checkstyle_test.go
new file mode 100644
index 000000000000..58b8db7f0960
--- /dev/null
+++ b/pkg/printers/checkstyle_test.go
@@ -0,0 +1,57 @@
+//nolint:dupl
+package printers
+
+import (
+ "bytes"
+ "context"
+ "go/token"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/golangci/golangci-lint/pkg/result"
+)
+
+func TestCheckstyle_Print(t *testing.T) {
+ issues := []result.Issue{
+ {
+ FromLinter: "linter-a",
+ Severity: "warning",
+ Text: "some issue",
+ Pos: token.Position{
+ Filename: "path/to/filea.go",
+ Offset: 2,
+ Line: 10,
+ Column: 4,
+ },
+ },
+ {
+ FromLinter: "linter-b",
+ Severity: "error",
+ Text: "another issue",
+ SourceLines: []string{
+ "func foo() {",
+ "\tfmt.Println(\"bar\")",
+ "}",
+ },
+ Pos: token.Position{
+ Filename: "path/to/fileb.go",
+ Offset: 5,
+ Line: 300,
+ Column: 9,
+ },
+ },
+ }
+
+ buf := new(bytes.Buffer)
+ printer := NewCheckstyle(buf)
+
+ err := printer.Print(context.Background(), issues)
+ require.NoError(t, err)
+
+ //nolint:lll
+ expected := "\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\n"
+
+ assert.Equal(t, expected, buf.String())
+}
diff --git a/pkg/printers/codeclimate_test.go b/pkg/printers/codeclimate_test.go
new file mode 100644
index 000000000000..5c25002a8907
--- /dev/null
+++ b/pkg/printers/codeclimate_test.go
@@ -0,0 +1,57 @@
+//nolint:dupl
+package printers
+
+import (
+ "bytes"
+ "context"
+ "go/token"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/golangci/golangci-lint/pkg/result"
+)
+
+func TestCodeClimate_Print(t *testing.T) {
+ issues := []result.Issue{
+ {
+ FromLinter: "linter-a",
+ Severity: "warning",
+ Text: "some issue",
+ Pos: token.Position{
+ Filename: "path/to/filea.go",
+ Offset: 2,
+ Line: 10,
+ Column: 4,
+ },
+ },
+ {
+ FromLinter: "linter-b",
+ Severity: "error",
+ Text: "another issue",
+ SourceLines: []string{
+ "func foo() {",
+ "\tfmt.Println(\"bar\")",
+ "}",
+ },
+ Pos: token.Position{
+ Filename: "path/to/fileb.go",
+ Offset: 5,
+ Line: 300,
+ Column: 9,
+ },
+ },
+ }
+
+ buf := new(bytes.Buffer)
+ printer := NewCodeClimate(buf)
+
+ err := printer.Print(context.Background(), issues)
+ require.NoError(t, err)
+
+ //nolint:lll
+ expected := `[{"description":"linter-a: some issue","severity":"warning","fingerprint":"BA73C5DF4A6FD8462FFF1D3140235777","location":{"path":"path/to/filea.go","lines":{"begin":10}}},{"description":"linter-b: another issue","severity":"error","fingerprint":"0777B4FE60242BD8B2E9B7E92C4B9521","location":{"path":"path/to/fileb.go","lines":{"begin":300}}}]`
+
+ assert.Equal(t, expected, buf.String())
+}
diff --git a/pkg/printers/github_test.go b/pkg/printers/github_test.go
index 0ab79bb82ee8..1e7772d25550 100644
--- a/pkg/printers/github_test.go
+++ b/pkg/printers/github_test.go
@@ -1,14 +1,61 @@
package printers
import (
+ "bytes"
+ "context"
"go/token"
"testing"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/golangci/golangci-lint/pkg/result"
)
+func TestGithub_Print(t *testing.T) {
+ issues := []result.Issue{
+ {
+ FromLinter: "linter-a",
+ Severity: "warning",
+ Text: "some issue",
+ Pos: token.Position{
+ Filename: "path/to/filea.go",
+ Offset: 2,
+ Line: 10,
+ Column: 4,
+ },
+ },
+ {
+ FromLinter: "linter-b",
+ Severity: "error",
+ Text: "another issue",
+ SourceLines: []string{
+ "func foo() {",
+ "\tfmt.Println(\"bar\")",
+ "}",
+ },
+ Pos: token.Position{
+ Filename: "path/to/fileb.go",
+ Offset: 5,
+ Line: 300,
+ Column: 9,
+ },
+ },
+ }
+
+ buf := new(bytes.Buffer)
+ printer := NewGithub(buf)
+
+ err := printer.Print(context.Background(), issues)
+ require.NoError(t, err)
+
+ expected := `::warning file=path/to/filea.go,line=10,col=4::some issue (linter-a)
+::error file=path/to/fileb.go,line=300,col=9::another issue (linter-b)
+`
+
+ assert.Equal(t, expected, buf.String())
+}
+
func TestFormatGithubIssue(t *testing.T) {
sampleIssue := result.Issue{
FromLinter: "sample-linter",
diff --git a/pkg/printers/html_test.go b/pkg/printers/html_test.go
new file mode 100644
index 000000000000..1c3306d7dec6
--- /dev/null
+++ b/pkg/printers/html_test.go
@@ -0,0 +1,160 @@
+package printers
+
+import (
+ "bytes"
+ "context"
+ "go/token"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/golangci/golangci-lint/pkg/result"
+)
+
+//nolint:lll
+const expectedHTML = `
+
+
+
+ golangci-lint
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`
+
+func TestHTML_Print(t *testing.T) {
+ issues := []result.Issue{
+ {
+ FromLinter: "linter-a",
+ Severity: "warning",
+ Text: "some issue",
+ Pos: token.Position{
+ Filename: "path/to/filea.go",
+ Offset: 2,
+ Line: 10,
+ Column: 4,
+ },
+ },
+ {
+ FromLinter: "linter-b",
+ Severity: "error",
+ Text: "another issue",
+ SourceLines: []string{
+ "func foo() {",
+ "\tfmt.Println(\"bar\")",
+ "}",
+ },
+ Pos: token.Position{
+ Filename: "path/to/fileb.go",
+ Offset: 5,
+ Line: 300,
+ Column: 9,
+ },
+ },
+ }
+
+ buf := new(bytes.Buffer)
+ printer := NewHTML(buf)
+
+ err := printer.Print(context.Background(), issues)
+ require.NoError(t, err)
+
+ assert.Equal(t, expectedHTML, buf.String())
+}
diff --git a/pkg/printers/json_test.go b/pkg/printers/json_test.go
new file mode 100644
index 000000000000..402c8d6a271b
--- /dev/null
+++ b/pkg/printers/json_test.go
@@ -0,0 +1,58 @@
+package printers
+
+import (
+ "bytes"
+ "context"
+ "go/token"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/golangci/golangci-lint/pkg/result"
+)
+
+func TestJSON_Print(t *testing.T) {
+ issues := []result.Issue{
+ {
+ FromLinter: "linter-a",
+ Severity: "warning",
+ Text: "some issue",
+ Pos: token.Position{
+ Filename: "path/to/filea.go",
+ Offset: 2,
+ Line: 10,
+ Column: 4,
+ },
+ },
+ {
+ FromLinter: "linter-b",
+ Severity: "error",
+ Text: "another issue",
+ SourceLines: []string{
+ "func foo() {",
+ "\tfmt.Println(\"bar\")",
+ "}",
+ },
+ Pos: token.Position{
+ Filename: "path/to/fileb.go",
+ Offset: 5,
+ Line: 300,
+ Column: 9,
+ },
+ },
+ }
+
+ buf := new(bytes.Buffer)
+
+ printer := NewJSON(nil, buf)
+
+ err := printer.Print(context.Background(), issues)
+ require.NoError(t, err)
+
+ //nolint:lll
+ expected := `{"Issues":[{"FromLinter":"linter-a","Text":"some issue","Severity":"warning","SourceLines":null,"Replacement":null,"Pos":{"Filename":"path/to/filea.go","Offset":2,"Line":10,"Column":4},"ExpectNoLint":false,"ExpectedNoLintLinter":""},{"FromLinter":"linter-b","Text":"another issue","Severity":"error","SourceLines":["func foo() {","\tfmt.Println(\"bar\")","}"],"Replacement":null,"Pos":{"Filename":"path/to/fileb.go","Offset":5,"Line":300,"Column":9},"ExpectNoLint":false,"ExpectedNoLintLinter":""}],"Report":null}
+`
+
+ assert.Equal(t, expected, buf.String())
+}
diff --git a/pkg/printers/junitxml.go b/pkg/printers/junitxml.go
index fd3aecac7518..0424f78b48d7 100644
--- a/pkg/printers/junitxml.go
+++ b/pkg/printers/junitxml.go
@@ -5,6 +5,7 @@ import (
"encoding/xml"
"fmt"
"io"
+ "sort"
"strings"
"github.com/golangci/golangci-lint/pkg/result"
@@ -75,6 +76,10 @@ func (p JunitXML) Print(ctx context.Context, issues []result.Issue) error {
res.TestSuites = append(res.TestSuites, val)
}
+ sort.Slice(res.TestSuites, func(i, j int) bool {
+ return res.TestSuites[i].Suite < res.TestSuites[j].Suite
+ })
+
enc := xml.NewEncoder(p.w)
enc.Indent("", " ")
if err := enc.Encode(res); err != nil {
diff --git a/pkg/printers/junitxml_test.go b/pkg/printers/junitxml_test.go
new file mode 100644
index 000000000000..bc994be2fb7c
--- /dev/null
+++ b/pkg/printers/junitxml_test.go
@@ -0,0 +1,77 @@
+//nolint:dupl
+package printers
+
+import (
+ "bytes"
+ "context"
+ "go/token"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/golangci/golangci-lint/pkg/result"
+)
+
+func TestJunitXML_Print(t *testing.T) {
+ issues := []result.Issue{
+ {
+ FromLinter: "linter-a",
+ Severity: "warning",
+ Text: "some issue",
+ Pos: token.Position{
+ Filename: "path/to/filea.go",
+ Offset: 2,
+ Line: 10,
+ Column: 4,
+ },
+ },
+ {
+ FromLinter: "linter-b",
+ Severity: "error",
+ Text: "another issue",
+ SourceLines: []string{
+ "func foo() {",
+ "\tfmt.Println(\"bar\")",
+ "}",
+ },
+ Pos: token.Position{
+ Filename: "path/to/fileb.go",
+ Offset: 5,
+ Line: 300,
+ Column: 9,
+ },
+ },
+ }
+
+ buf := new(bytes.Buffer)
+ printer := NewJunitXML(buf)
+
+ err := printer.Print(context.Background(), issues)
+ require.NoError(t, err)
+
+ expected := `
+
+
+
+
+
+
+
+
+
+
+`
+
+ assert.Equal(t, expected, buf.String())
+}
diff --git a/pkg/printers/tab_test.go b/pkg/printers/tab_test.go
new file mode 100644
index 000000000000..abef2a225ea0
--- /dev/null
+++ b/pkg/printers/tab_test.go
@@ -0,0 +1,59 @@
+package printers
+
+import (
+ "bytes"
+ "context"
+ "go/token"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/pkg/result"
+)
+
+func TestTab_Print(t *testing.T) {
+ issues := []result.Issue{
+ {
+ FromLinter: "linter-a",
+ Severity: "warning",
+ Text: "some issue",
+ Pos: token.Position{
+ Filename: "path/to/filea.go",
+ Offset: 2,
+ Line: 10,
+ Column: 4,
+ },
+ },
+ {
+ FromLinter: "linter-b",
+ Severity: "error",
+ Text: "another issue",
+ SourceLines: []string{
+ "func foo() {",
+ "\tfmt.Println(\"bar\")",
+ "}",
+ },
+ Pos: token.Position{
+ Filename: "path/to/fileb.go",
+ Offset: 5,
+ Line: 300,
+ Column: 9,
+ },
+ },
+ }
+
+ buf := new(bytes.Buffer)
+
+ printer := NewTab(true, logutils.NewStderrLog(""), buf)
+
+ err := printer.Print(context.Background(), issues)
+ require.NoError(t, err)
+
+ expected := `path/to/filea.go:10:4 linter-a some issue
+path/to/fileb.go:300:9 linter-b another issue
+`
+
+ assert.Equal(t, expected, buf.String())
+}
diff --git a/pkg/printers/text_test.go b/pkg/printers/text_test.go
new file mode 100644
index 000000000000..06e87214a1af
--- /dev/null
+++ b/pkg/printers/text_test.go
@@ -0,0 +1,62 @@
+package printers
+
+import (
+ "bytes"
+ "context"
+ "go/token"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/golangci/golangci-lint/pkg/logutils"
+ "github.com/golangci/golangci-lint/pkg/result"
+)
+
+func TestText_Print(t *testing.T) {
+ issues := []result.Issue{
+ {
+ FromLinter: "linter-a",
+ Severity: "warning",
+ Text: "some issue",
+ Pos: token.Position{
+ Filename: "path/to/filea.go",
+ Offset: 2,
+ Line: 10,
+ Column: 4,
+ },
+ },
+ {
+ FromLinter: "linter-b",
+ Severity: "error",
+ Text: "another issue",
+ SourceLines: []string{
+ "func foo() {",
+ "\tfmt.Println(\"bar\")",
+ "}",
+ },
+ Pos: token.Position{
+ Filename: "path/to/fileb.go",
+ Offset: 5,
+ Line: 300,
+ Column: 9,
+ },
+ },
+ }
+
+ buf := new(bytes.Buffer)
+
+ printer := NewText(true, false, true, logutils.NewStderrLog(""), buf)
+
+ err := printer.Print(context.Background(), issues)
+ require.NoError(t, err)
+
+ expected := `path/to/filea.go:10:4: some issue (linter-a)
+path/to/fileb.go:300:9: another issue (linter-b)
+func foo() {
+ fmt.Println("bar")
+}
+`
+
+ assert.Equal(t, expected, buf.String())
+}