Black Lives Matter. Support the Equal Justice Initiative.

Source file src/cmd/fix/main_test.go

Documentation: cmd/fix

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"go/ast"
     9  	"go/parser"
    10  	"strings"
    11  	"testing"
    12  
    13  	"cmd/internal/diff"
    14  )
    15  
    16  type testCase struct {
    17  	Name string
    18  	Fn   func(*ast.File) bool
    19  	In   string
    20  	Out  string
    21  }
    22  
    23  var testCases []testCase
    24  
    25  func addTestCases(t []testCase, fn func(*ast.File) bool) {
    26  	// Fill in fn to avoid repetition in definitions.
    27  	if fn != nil {
    28  		for i := range t {
    29  			if t[i].Fn == nil {
    30  				t[i].Fn = fn
    31  			}
    32  		}
    33  	}
    34  	testCases = append(testCases, t...)
    35  }
    36  
    37  func fnop(*ast.File) bool { return false }
    38  
    39  func parseFixPrint(t *testing.T, fn func(*ast.File) bool, desc, in string, mustBeGofmt bool) (out string, fixed, ok bool) {
    40  	file, err := parser.ParseFile(fset, desc, in, parserMode)
    41  	if err != nil {
    42  		t.Errorf("parsing: %v", err)
    43  		return
    44  	}
    45  
    46  	outb, err := gofmtFile(file)
    47  	if err != nil {
    48  		t.Errorf("printing: %v", err)
    49  		return
    50  	}
    51  	if s := string(outb); in != s && mustBeGofmt {
    52  		t.Errorf("not gofmt-formatted.\n--- %s\n%s\n--- %s | gofmt\n%s",
    53  			desc, in, desc, s)
    54  		tdiff(t, in, s)
    55  		return
    56  	}
    57  
    58  	if fn == nil {
    59  		for _, fix := range fixes {
    60  			if fix.f(file) {
    61  				fixed = true
    62  			}
    63  		}
    64  	} else {
    65  		fixed = fn(file)
    66  	}
    67  
    68  	outb, err = gofmtFile(file)
    69  	if err != nil {
    70  		t.Errorf("printing: %v", err)
    71  		return
    72  	}
    73  
    74  	return string(outb), fixed, true
    75  }
    76  
    77  func TestRewrite(t *testing.T) {
    78  	for _, tt := range testCases {
    79  		tt := tt
    80  		t.Run(tt.Name, func(t *testing.T) {
    81  			t.Parallel()
    82  			// Apply fix: should get tt.Out.
    83  			out, fixed, ok := parseFixPrint(t, tt.Fn, tt.Name, tt.In, true)
    84  			if !ok {
    85  				return
    86  			}
    87  
    88  			// reformat to get printing right
    89  			out, _, ok = parseFixPrint(t, fnop, tt.Name, out, false)
    90  			if !ok {
    91  				return
    92  			}
    93  
    94  			if out != tt.Out {
    95  				t.Errorf("incorrect output.\n")
    96  				if !strings.HasPrefix(tt.Name, "testdata/") {
    97  					t.Errorf("--- have\n%s\n--- want\n%s", out, tt.Out)
    98  				}
    99  				tdiff(t, out, tt.Out)
   100  				return
   101  			}
   102  
   103  			if changed := out != tt.In; changed != fixed {
   104  				t.Errorf("changed=%v != fixed=%v", changed, fixed)
   105  				return
   106  			}
   107  
   108  			// Should not change if run again.
   109  			out2, fixed2, ok := parseFixPrint(t, tt.Fn, tt.Name+" output", out, true)
   110  			if !ok {
   111  				return
   112  			}
   113  
   114  			if fixed2 {
   115  				t.Errorf("applied fixes during second round")
   116  				return
   117  			}
   118  
   119  			if out2 != out {
   120  				t.Errorf("changed output after second round of fixes.\n--- output after first round\n%s\n--- output after second round\n%s",
   121  					out, out2)
   122  				tdiff(t, out, out2)
   123  			}
   124  		})
   125  	}
   126  }
   127  
   128  func tdiff(t *testing.T, a, b string) {
   129  	data, err := diff.Diff("go-fix-test", []byte(a), []byte(b))
   130  	if err != nil {
   131  		t.Error(err)
   132  		return
   133  	}
   134  	t.Error(string(data))
   135  }
   136  

View as plain text