mirror of
https://github.com/mgechev/revive.git
synced 2024-11-21 17:16:40 +02:00
adds tests for specific go versions (#1043)
Co-authored-by: chavacava <salvador.cavadini@gmail.com>
This commit is contained in:
parent
4ac5cb5e39
commit
a65fb8d1b5
@ -9,3 +9,7 @@ import (
|
||||
func TestDatarace(t *testing.T) {
|
||||
testRule(t, "datarace", &rule.DataRaceRule{})
|
||||
}
|
||||
|
||||
func TestDataraceAfterGo1_22(t *testing.T) {
|
||||
testRule(t, "go1.22/datarace", &rule.DataRaceRule{})
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func TestFileExcludeFilterAtRuleLevel(t *testing.T) {
|
||||
|
||||
t.Run("not called if exclude not match", func(t *testing.T) {
|
||||
rule := &TestFileFilterRule{}
|
||||
cfg := &lint.RuleConfig{Exclude: []string{"file-to-exclude.go"}}
|
||||
cfg := &lint.RuleConfig{Exclude: []string{"../testdata/file-to-exclude.go"}}
|
||||
cfg.Initialize()
|
||||
testRule(t, "file-to-exclude", rule, cfg)
|
||||
if rule.WasApplyed {
|
||||
|
@ -64,7 +64,7 @@ func TestAll(t *testing.T) {
|
||||
t.Fatalf("Failed reading %s: %v", fi.Name(), err)
|
||||
}
|
||||
|
||||
if err := assertFailures(t, baseDir, fileInfo, src, rules, map[string]lint.RuleConfig{}); err != nil {
|
||||
if err := assertFailures(t, path.Dir(baseDir), fileInfo, src, rules, map[string]lint.RuleConfig{}); err != nil {
|
||||
t.Errorf("Linting %s: %v", fi.Name(), err)
|
||||
}
|
||||
})
|
||||
|
@ -10,3 +10,7 @@ import (
|
||||
func TestRangeValAddress(t *testing.T) {
|
||||
testRule(t, "range-val-address", &rule.RangeValAddress{}, &lint.RuleConfig{})
|
||||
}
|
||||
|
||||
func TestRangeValAddressAfterGo1_22(t *testing.T) {
|
||||
testRule(t, "go1.22/range-val-address", &rule.RangeValAddress{}, &lint.RuleConfig{})
|
||||
}
|
||||
|
@ -10,3 +10,7 @@ import (
|
||||
func TestRangeValInClosure(t *testing.T) {
|
||||
testRule(t, "range-val-in-closure", &rule.RangeValInClosureRule{}, &lint.RuleConfig{})
|
||||
}
|
||||
|
||||
func TestRangeValInClosureAfterGo1_22(t *testing.T) {
|
||||
testRule(t, "go1.22/range-val-in-closure", &rule.RangeValInClosureRule{}, &lint.RuleConfig{})
|
||||
}
|
||||
|
@ -10,3 +10,7 @@ import (
|
||||
func TestRedefinesBuiltinID(t *testing.T) {
|
||||
testRule(t, "redefines-builtin-id", &rule.RedefinesBuiltinIDRule{})
|
||||
}
|
||||
|
||||
func TestRedefinesBuiltinIDAfterGo1_21(t *testing.T) {
|
||||
testRule(t, "go1.21/redefines-builtin-id", &rule.RedefinesBuiltinIDRule{})
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"go/token"
|
||||
"go/types"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
@ -18,13 +19,14 @@ import (
|
||||
)
|
||||
|
||||
func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.RuleConfig) {
|
||||
baseDir := "../testdata/"
|
||||
filename = filename + ".go"
|
||||
src, err := os.ReadFile(baseDir + filename)
|
||||
baseDir := path.Join("../testdata/" + path.Dir(filename))
|
||||
filename = path.Base(filename) + ".go"
|
||||
fullFilePath := path.Join(baseDir, filename)
|
||||
src, err := os.ReadFile(fullFilePath)
|
||||
if err != nil {
|
||||
t.Fatalf("Bad filename path in test for %s: %v", rule.Name(), err)
|
||||
}
|
||||
stat, err := os.Stat(baseDir + filename)
|
||||
stat, err := os.Stat(fullFilePath)
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot get file info for %s: %v", rule.Name(), err)
|
||||
}
|
||||
@ -32,7 +34,7 @@ func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.Rul
|
||||
if config != nil {
|
||||
c[rule.Name()] = *config[0]
|
||||
}
|
||||
if parseInstructions(t, filename, src) == nil {
|
||||
if parseInstructions(t, fullFilePath, src) == nil {
|
||||
assertSuccess(t, baseDir, stat, []lint.Rule{rule}, c)
|
||||
return
|
||||
}
|
||||
@ -41,10 +43,11 @@ func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.Rul
|
||||
|
||||
func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Rule, config map[string]lint.RuleConfig) error {
|
||||
l := lint.New(func(file string) ([]byte, error) {
|
||||
return os.ReadFile(baseDir + file)
|
||||
return os.ReadFile(file)
|
||||
}, 0)
|
||||
|
||||
ps, err := l.Lint([][]string{{fi.Name()}}, rules, lint.Config{
|
||||
filePath := path.Join(baseDir, fi.Name())
|
||||
ps, err := l.Lint([][]string{{filePath}}, rules, lint.Config{
|
||||
Rules: config,
|
||||
})
|
||||
if err != nil {
|
||||
@ -63,15 +66,15 @@ func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Ru
|
||||
|
||||
func assertFailures(t *testing.T, baseDir string, fi os.FileInfo, src []byte, rules []lint.Rule, config map[string]lint.RuleConfig) error {
|
||||
l := lint.New(func(file string) ([]byte, error) {
|
||||
return os.ReadFile(baseDir + file)
|
||||
return os.ReadFile(file)
|
||||
}, 0)
|
||||
|
||||
ins := parseInstructions(t, fi.Name(), src)
|
||||
ins := parseInstructions(t, path.Join(baseDir, fi.Name()), src)
|
||||
if ins == nil {
|
||||
return fmt.Errorf("Test file %v does not have instructions", fi.Name())
|
||||
}
|
||||
|
||||
ps, err := l.Lint([][]string{{fi.Name()}}, rules, lint.Config{
|
||||
ps, err := l.Lint([][]string{{path.Join(baseDir, fi.Name())}}, rules, lint.Config{
|
||||
Rules: config,
|
||||
})
|
||||
if err != nil {
|
||||
|
5
testdata/go.mod
vendored
Normal file
5
testdata/go.mod
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
module github.com/mgechev/revive/testdata
|
||||
|
||||
// set the lowest go version
|
||||
// to trigger testing of all rules
|
||||
go 1.0
|
3
testdata/go1.21/go.mod
vendored
Normal file
3
testdata/go1.21/go.mod
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
module github.com/mgechev/revive/testdata
|
||||
|
||||
go 1.21
|
54
testdata/go1.21/redefines-builtin-id.go
vendored
Normal file
54
testdata/go1.21/redefines-builtin-id.go
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
package fixtures
|
||||
|
||||
func (this data) vmethod() {
|
||||
nil := true // MATCH /assignment creates a shadow of built-in identifier nil/
|
||||
iota = 1 // MATCH /assignment modifies built-in identifier iota/
|
||||
}
|
||||
|
||||
func append(i, j int) { // MATCH /redefinition of the built-in function append/
|
||||
|
||||
}
|
||||
|
||||
type string int16 // MATCH /redefinition of the built-in type string/
|
||||
|
||||
func delete(set []int64, i int) (y []int64) { // MATCH /redefinition of the built-in function delete/
|
||||
for j, v := range set {
|
||||
if j != i {
|
||||
y = append(y, v)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type any int // MATCH /redefinition of the built-in type any/
|
||||
|
||||
func any() {} // MATCH /redefinition of the built-in type any/
|
||||
|
||||
var any int // MATCH /redefinition of the built-in type any/
|
||||
|
||||
const any = 1 // MATCH /redefinition of the built-in type any/
|
||||
|
||||
var i, copy int // MATCH /redefinition of the built-in function copy/
|
||||
|
||||
// issue #792
|
||||
type ()
|
||||
|
||||
func foo() {
|
||||
clear := 0 // MATCH /redefinition of the built-in function clear/
|
||||
max := 0 // MATCH /redefinition of the built-in function max/
|
||||
min := 0 // MATCH /redefinition of the built-in function min/
|
||||
_ = clear
|
||||
_ = max
|
||||
_ = min
|
||||
}
|
||||
|
||||
func foo1(new int) { // MATCH /redefinition of the built-in function new/
|
||||
_ = new
|
||||
}
|
||||
|
||||
func foo2() (new int) { // MATCH /redefinition of the built-in function new/
|
||||
return
|
||||
}
|
||||
|
||||
func foo3[new any]() { // MATCH /redefinition of the built-in function new/
|
||||
}
|
30
testdata/go1.22/datarace.go
vendored
Normal file
30
testdata/go1.22/datarace.go
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
package fixtures
|
||||
|
||||
func datarace() (r int, c char) {
|
||||
for _, p := range []int{1, 2} {
|
||||
go func() {
|
||||
print(r) // MATCH /potential datarace: return value r is captured (by-reference) in goroutine/
|
||||
print(p) // Shall not match /datarace: range value p is captured (by-reference) in goroutine/
|
||||
}()
|
||||
for i, p1 := range []int{1, 2} {
|
||||
a := p1
|
||||
go func() {
|
||||
print(r) // MATCH /potential datarace: return value r is captured (by-reference) in goroutine/
|
||||
print(p) // Shall not match /datarace: range value p is captured (by-reference) in goroutine/
|
||||
print(p1) // Shall not match /datarace: range value p1 is captured (by-reference) in goroutine/
|
||||
print(a)
|
||||
print(i) // Shall not match /datarace: range value i is captured (by-reference) in goroutine/
|
||||
}()
|
||||
print(i)
|
||||
print(p)
|
||||
go func() {
|
||||
_ = c // MATCH /potential datarace: return value c is captured (by-reference) in goroutine/
|
||||
}()
|
||||
}
|
||||
print(p1)
|
||||
}
|
||||
go func() {
|
||||
print(r) // MATCH /potential datarace: return value r is captured (by-reference) in goroutine/
|
||||
}()
|
||||
print(r)
|
||||
}
|
3
testdata/go1.22/go.mod
vendored
Normal file
3
testdata/go1.22/go.mod
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
module github.com/mgechev/revive/testdata
|
||||
|
||||
go 1.22
|
163
testdata/go1.22/range-val-address.go
vendored
Normal file
163
testdata/go1.22/range-val-address.go
vendored
Normal file
@ -0,0 +1,163 @@
|
||||
package fixtures
|
||||
|
||||
func rangeValAddress() {
|
||||
m := map[string]*string{}
|
||||
|
||||
mySlice := []string{"A", "B", "C"}
|
||||
for _, value := range mySlice {
|
||||
m["address"] = &value // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress2() {
|
||||
m := map[string]*string{}
|
||||
|
||||
mySlice := []string{"A", "B", "C"}
|
||||
for i := range mySlice {
|
||||
m["address"] = &mySlice[i]
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress3() {
|
||||
m := map[string]*string{}
|
||||
|
||||
mySlice := []string{"A", "B", "C"}
|
||||
for _, value := range mySlice {
|
||||
a := &value // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||
m["address"] = a
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress4() {
|
||||
m := []*string{}
|
||||
|
||||
mySlice := []string{"A", "B", "C"}
|
||||
for _, value := range mySlice {
|
||||
m = append(m, &value) // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress5() {
|
||||
m := map[*string]string{}
|
||||
|
||||
mySlice := []string{"A", "B", "C"}
|
||||
for _, value := range mySlice {
|
||||
m[&value] = value // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress6() {
|
||||
type v struct {
|
||||
id string
|
||||
}
|
||||
m := []*string{}
|
||||
|
||||
mySlice := []v{{id: "A"}, {id: "B"}, {id: "C"}}
|
||||
for _, value := range mySlice {
|
||||
m = append(m, &value.id) // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress7() {
|
||||
type v struct {
|
||||
id string
|
||||
}
|
||||
m := []*string{}
|
||||
|
||||
for _, value := range []v{{id: "A"}, {id: "B"}, {id: "C"}} {
|
||||
m = append(m, &value.id) // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress8() {
|
||||
type v struct {
|
||||
id string
|
||||
}
|
||||
m := []*string{}
|
||||
|
||||
mySlice := []*v{{id: "A"}, {id: "B"}, {id: "C"}}
|
||||
for _, value := range mySlice {
|
||||
m = append(m, &value.id)
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress9() {
|
||||
type v struct {
|
||||
id string
|
||||
}
|
||||
m := []*string{}
|
||||
|
||||
mySlice := map[string]*v{"a": {id: "A"}, "b": {id: "B"}, "c": {id: "C"}}
|
||||
for _, value := range mySlice {
|
||||
m = append(m, &value.id)
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress10() {
|
||||
type v struct {
|
||||
id string
|
||||
}
|
||||
m := []*string{}
|
||||
|
||||
for _, value := range map[string]*v{"a": {id: "A"}, "b": {id: "B"}, "c": {id: "C"}} {
|
||||
m = append(m, &value.id)
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress11() {
|
||||
type v struct {
|
||||
id string
|
||||
}
|
||||
m := map[string]*string{}
|
||||
|
||||
for key, value := range map[string]*v{"a": {id: "A"}, "b": {id: "B"}, "c": {id: "C"}} {
|
||||
m[key] = &value.id
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress12() {
|
||||
type v struct {
|
||||
id string
|
||||
}
|
||||
m := map[string]*string{}
|
||||
|
||||
for key, value := range map[string]v{"a": {id: "A"}, "b": {id: "B"}, "c": {id: "C"}} {
|
||||
m[key] = &value.id // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress13() {
|
||||
type v struct {
|
||||
id string
|
||||
}
|
||||
m := []*string{}
|
||||
|
||||
otherSlice := map[string]*v{"a": {id: "A"}, "b": {id: "B"}, "c": {id: "C"}}
|
||||
mySlice := otherSlice
|
||||
for _, value := range mySlice {
|
||||
m = append(m, &value.id)
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress14() {
|
||||
type v struct {
|
||||
id *string
|
||||
}
|
||||
|
||||
m := []v{}
|
||||
for _, value := range []string{"A", "B", "C"} {
|
||||
a := v{id: &value} // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||
m = append(m, a)
|
||||
}
|
||||
}
|
||||
|
||||
func rangeValAddress15() {
|
||||
type v struct {
|
||||
id *string
|
||||
}
|
||||
|
||||
m := []v{}
|
||||
for _, value := range []string{"A", "B", "C"} {
|
||||
m = append(m, v{id: &value}) // Shall not match /suspicious assignment of 'value'. range-loop variables always have the same address/
|
||||
}
|
||||
}
|
49
testdata/go1.22/range-val-in-closure.go
vendored
Normal file
49
testdata/go1.22/range-val-in-closure.go
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
package fixtures
|
||||
|
||||
import "fmt"
|
||||
|
||||
func foo() {
|
||||
mySlice := []string{"A", "B", "C"}
|
||||
for index, value := range mySlice {
|
||||
go func() {
|
||||
fmt.Printf("Index: %d\n", index) // Shall not match
|
||||
fmt.Printf("Value: %s\n", value) // Shall not match
|
||||
}()
|
||||
}
|
||||
|
||||
myDict := make(map[string]int)
|
||||
myDict["A"] = 1
|
||||
myDict["B"] = 2
|
||||
myDict["C"] = 3
|
||||
for key, value := range myDict {
|
||||
defer func() {
|
||||
fmt.Printf("Index: %d\n", key) // Shall not match
|
||||
fmt.Printf("Value: %s\n", value) // Shall not match
|
||||
}()
|
||||
}
|
||||
|
||||
for i, newg := range groups {
|
||||
go func(newg int) {
|
||||
newg.run(m.opts.Context, i) // Shall not match
|
||||
}(newg)
|
||||
}
|
||||
|
||||
for i, newg := range groups {
|
||||
newg := newg
|
||||
go func() {
|
||||
newg.run(m.opts.Context, i) // Shall not match
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func issue637() {
|
||||
for key := range m {
|
||||
myKey := key
|
||||
go func() {
|
||||
println(t{
|
||||
key: myKey,
|
||||
otherField: (10 + key), // Shall not match
|
||||
})
|
||||
}()
|
||||
}
|
||||
}
|
6
testdata/redefines-builtin-id.go
vendored
6
testdata/redefines-builtin-id.go
vendored
@ -34,9 +34,9 @@ var i, copy int // MATCH /redefinition of the built-in function copy/
|
||||
type ()
|
||||
|
||||
func foo() {
|
||||
clear := 0 // MATCH /redefinition of the built-in function clear/
|
||||
max := 0 // MATCH /redefinition of the built-in function max/
|
||||
min := 0 // MATCH /redefinition of the built-in function min/
|
||||
clear := 0 // Shall not match /redefinition of the built-in function clear/
|
||||
max := 0 // Shall not match /redefinition of the built-in function max/
|
||||
min := 0 // Shall not match /redefinition of the built-in function min/
|
||||
_ = clear
|
||||
_ = max
|
||||
_ = min
|
||||
|
Loading…
Reference in New Issue
Block a user