github.com/nya3jp/tast@v0.0.0-20230601000426-85c8e4d83a9b/src/go.chromium.org/tast/core/cmd/tast-lint/internal/check/common_test.go (about)

     1  // Copyright 2018 The ChromiumOS Authors
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file.
     4  
     5  package check
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"go/ast"
    11  	"go/format"
    12  	"go/parser"
    13  	"go/token"
    14  	"io/ioutil"
    15  	"os"
    16  	"os/exec"
    17  	"path/filepath"
    18  	"strings"
    19  	"testing"
    20  
    21  	"github.com/google/go-cmp/cmp"
    22  	"github.com/google/go-cmp/cmp/cmpopts"
    23  
    24  	"go.chromium.org/tast/core/testutil"
    25  )
    26  
    27  func parse(code, filename string) (*ast.File, *token.FileSet) {
    28  	fs := token.NewFileSet()
    29  	f, err := parser.ParseFile(fs, filename, code, parser.ParseComments)
    30  	if err != nil {
    31  		panic(err)
    32  	}
    33  	return f, fs
    34  }
    35  
    36  func verifyIssues(t *testing.T, issues []*Issue, want []string) {
    37  	t.Helper()
    38  
    39  	SortIssues(issues)
    40  
    41  	got := make([]string, len(issues))
    42  	for i, issue := range issues {
    43  		got[i] = issue.String()
    44  	}
    45  
    46  	if diff := cmp.Diff(got, want, cmpopts.EquateEmpty()); diff != "" {
    47  		t.Errorf("Issues mismatch (-got +want):\n%s", diff)
    48  	}
    49  }
    50  
    51  func verifyAutoFix(t *testing.T, lintfunc func(*token.FileSet, *ast.File, bool) []*Issue, files, expects map[string]string) {
    52  	t.Helper()
    53  
    54  	tempDir := testutil.TempDir(t)
    55  	defer os.RemoveAll(tempDir)
    56  	testutil.WriteFiles(tempDir, files)
    57  
    58  	fs := token.NewFileSet()
    59  	for filename := range files {
    60  		path := filepath.Join(tempDir, filename)
    61  		f, err := parser.ParseFile(fs, path, nil, parser.ParseComments)
    62  		if err != nil {
    63  			t.Error(err)
    64  			continue
    65  		}
    66  
    67  		lintfunc(fs, f, true)
    68  
    69  		if err := func() error {
    70  			file, err := os.Create(path)
    71  			if err != nil {
    72  				return err
    73  			}
    74  			defer file.Close()
    75  			if err := format.Node(file, fs, f); err != nil {
    76  				return err
    77  			}
    78  			return nil
    79  		}(); err != nil {
    80  			t.Error(err)
    81  			continue
    82  		}
    83  
    84  		bytesread, err := ioutil.ReadFile(path)
    85  		if err != nil {
    86  			t.Error(err)
    87  			continue
    88  		}
    89  		if err := fmtError(bytesread); err != nil {
    90  			t.Error(err)
    91  			continue
    92  		}
    93  	}
    94  
    95  	files, err := testutil.ReadFiles(tempDir)
    96  	if err != nil {
    97  		t.Error(err)
    98  	}
    99  
   100  	for filename := range files {
   101  		got := splitLines(files[filename])
   102  		want := splitLines(expects[filename])
   103  
   104  		if len(got) > len(want) {
   105  			for i := range want {
   106  				if diff := cmp.Diff(got[i], want[i], cmpopts.EquateEmpty()); diff != "" {
   107  					t.Errorf("AutoFix failed (-got +want):%s:%d:\n%s", filename, i+1, diff)
   108  				}
   109  			}
   110  			for i := len(want); i < len(got); i++ {
   111  				if diff := cmp.Diff(got[i], "", cmpopts.EquateEmpty()); diff != "" {
   112  					t.Errorf("AutoFix failed (-got +want):%s:%d:\n%s", filename, i+1, diff)
   113  				}
   114  			}
   115  		} else {
   116  			for i := range got {
   117  				if diff := cmp.Diff(got[i], want[i], cmpopts.EquateEmpty()); diff != "" {
   118  					t.Errorf("AutoFix failed (-got +want):%s:%d:\n%s", filename, i+1, diff)
   119  				}
   120  			}
   121  			for i := len(got); i < len(want); i++ {
   122  				if diff := cmp.Diff("", want[i], cmpopts.EquateEmpty()); diff != "" {
   123  					t.Errorf("AutoFix failed (-got +want):%s:%d:\n%s", filename, i+1, diff)
   124  				}
   125  			}
   126  		}
   127  	}
   128  }
   129  
   130  // splitLines split given string into string slice of lines which was ended with "\n".
   131  // Also, all "\t" are replaced by a white space.
   132  func splitLines(s string) []string {
   133  	lines := strings.Split(s, "\n")
   134  	for i := range lines {
   135  		lines[i] = strings.Replace(lines[i], "\t", " ", -1)
   136  	}
   137  	return lines
   138  }
   139  
   140  // fmtError runs gofmt to see if code has any formatting error.
   141  func fmtError(code []byte) error {
   142  	cmd := exec.Command("gofmt", "-l")
   143  	cmd.Stdin = bytes.NewBuffer(code)
   144  	out, err := cmd.Output()
   145  	if err != nil {
   146  		return fmt.Errorf("Failed gofmt: %v", err)
   147  	}
   148  	if len(out) > 0 {
   149  		return fmt.Errorf("File's formatting is different from gofmt's: %s", out)
   150  	}
   151  	return nil
   152  }