blob: 2176bb1d741fe430316ef9e6322fe96233a0b5da [file] [log] [blame] [edit]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package staticanalysis
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"go.fuchsia.dev/fuchsia/tools/build"
)
func TestClippyAnalyzer(t *testing.T) {
tests := []struct {
name string
path string
clippyTargets []build.ClippyTarget
clippyOutputs map[string][]clippyResult
expected []*Finding
}{
{
name: "file with no clippy target",
path: "src/bar.rs",
clippyTargets: []build.ClippyTarget{
{
Output: "bar.clippy",
Sources: []string{"../../src/foo.rs"},
},
},
expected: nil,
},
{
name: "file with clippy target",
path: "src/foo.rs",
clippyTargets: []build.ClippyTarget{
{
Output: "foo.clippy",
Sources: []string{"../../src/foo.rs"},
},
},
clippyOutputs: map[string][]clippyResult{
"foo.clippy": {
{
Message: "this function has too many arguments (8/7)",
Code: clippyCode{Code: "clippy::too_many_arguments"},
Level: "warning",
Spans: []clippySpan{
{
FileName: "../../src/foo.rs",
LineStart: 1,
LineEnd: 2,
ColumnStart: 3,
ColumnEnd: 4,
},
},
},
},
},
expected: []*Finding{
{
Message: "this function has too many arguments (8/7)",
Category: "Clippy/warning/too_many_arguments",
Path: "src/foo.rs",
StartLine: 1,
EndLine: 2,
StartChar: 3,
EndChar: 4,
},
},
},
{
name: "file with empty clippy output",
path: "src/foo.rs",
clippyTargets: []build.ClippyTarget{
{
Output: "foo.clippy",
Sources: []string{"../../src/foo.rs"},
},
},
clippyOutputs: map[string][]clippyResult{
"foo.clippy": nil,
},
expected: nil,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
checkoutDir := t.TempDir()
buildDir := filepath.Join(checkoutDir, "out", "testing")
if err := os.MkdirAll(buildDir, 0o700); err != nil {
t.Fatal(err)
}
analyzer := ClippyAnalyzer{
checkoutDir: checkoutDir,
buildDir: buildDir,
clippyTargets: test.clippyTargets,
}
for path, results := range test.clippyOutputs {
var b bytes.Buffer
for _, result := range results {
encoded, err := json.Marshal(result)
if err != nil {
t.Fatal(err)
}
b.Write([]byte("\n"))
b.Write(encoded)
}
absPath := filepath.Join(buildDir, path)
if err := ioutil.WriteFile(absPath, b.Bytes(), 0o600); err != nil {
t.Fatal(err)
}
}
findings, err := analyzer.Analyze(context.Background(), test.path)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(test.expected, findings, cmpopts.EquateEmpty()); diff != "" {
t.Errorf("clippy analyzer diff (-want +got): %s", diff)
}
})
}
}