github.com/lovishpuri/go-40569/src@v0.0.0-20230519171745-f8623e7c56cf/go/format/format_test.go (about) 1 // Copyright 2012 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 format 6 7 import ( 8 "bytes" 9 "go/ast" 10 "go/parser" 11 "go/token" 12 "os" 13 "strings" 14 "testing" 15 ) 16 17 const testfile = "format_test.go" 18 19 func diff(t *testing.T, dst, src []byte) { 20 line := 1 21 offs := 0 // line offset 22 for i := 0; i < len(dst) && i < len(src); i++ { 23 d := dst[i] 24 s := src[i] 25 if d != s { 26 t.Errorf("dst:%d: %s\n", line, dst[offs:i+1]) 27 t.Errorf("src:%d: %s\n", line, src[offs:i+1]) 28 return 29 } 30 if s == '\n' { 31 line++ 32 offs = i + 1 33 } 34 } 35 if len(dst) != len(src) { 36 t.Errorf("len(dst) = %d, len(src) = %d\nsrc = %q", len(dst), len(src), src) 37 } 38 } 39 40 func TestNode(t *testing.T) { 41 src, err := os.ReadFile(testfile) 42 if err != nil { 43 t.Fatal(err) 44 } 45 46 fset := token.NewFileSet() 47 file, err := parser.ParseFile(fset, testfile, src, parser.ParseComments) 48 if err != nil { 49 t.Fatal(err) 50 } 51 52 var buf bytes.Buffer 53 54 if err = Node(&buf, fset, file); err != nil { 55 t.Fatal("Node failed:", err) 56 } 57 58 diff(t, buf.Bytes(), src) 59 } 60 61 // Node is documented to not modify the AST. 62 // Test that it is so even when numbers are normalized. 63 func TestNodeNoModify(t *testing.T) { 64 const ( 65 src = "package p\n\nconst _ = 0000000123i\n" 66 golden = "package p\n\nconst _ = 123i\n" 67 ) 68 69 fset := token.NewFileSet() 70 file, err := parser.ParseFile(fset, "", src, parser.ParseComments) 71 if err != nil { 72 t.Fatal(err) 73 } 74 75 // Capture original address and value of a BasicLit node 76 // which will undergo formatting changes during printing. 77 wantLit := file.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec).Values[0].(*ast.BasicLit) 78 wantVal := wantLit.Value 79 80 var buf bytes.Buffer 81 if err = Node(&buf, fset, file); err != nil { 82 t.Fatal("Node failed:", err) 83 } 84 diff(t, buf.Bytes(), []byte(golden)) 85 86 // Check if anything changed after Node returned. 87 gotLit := file.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec).Values[0].(*ast.BasicLit) 88 gotVal := gotLit.Value 89 90 if gotLit != wantLit { 91 t.Errorf("got *ast.BasicLit address %p, want %p", gotLit, wantLit) 92 } 93 if gotVal != wantVal { 94 t.Errorf("got *ast.BasicLit value %q, want %q", gotVal, wantVal) 95 } 96 } 97 98 func TestSource(t *testing.T) { 99 src, err := os.ReadFile(testfile) 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 res, err := Source(src) 105 if err != nil { 106 t.Fatal("Source failed:", err) 107 } 108 109 diff(t, res, src) 110 } 111 112 // Test cases that are expected to fail are marked by the prefix "ERROR". 113 // The formatted result must look the same as the input for successful tests. 114 var tests = []string{ 115 // declaration lists 116 `import "go/format"`, 117 "var x int", 118 "var x int\n\ntype T struct{}", 119 120 // statement lists 121 "x := 0", 122 "f(a, b, c)\nvar x int = f(1, 2, 3)", 123 124 // indentation, leading and trailing space 125 "\tx := 0\n\tgo f()", 126 "\tx := 0\n\tgo f()\n\n\n", 127 "\n\t\t\n\n\tx := 0\n\tgo f()\n\n\n", 128 "\n\t\t\n\n\t\t\tx := 0\n\t\t\tgo f()\n\n\n", 129 "\n\t\t\n\n\t\t\tx := 0\n\t\t\tconst s = `\nfoo\n`\n\n\n", // no indentation added inside raw strings 130 "\n\t\t\n\n\t\t\tx := 0\n\t\t\tconst s = `\n\t\tfoo\n`\n\n\n", // no indentation removed inside raw strings 131 132 // comments 133 "/* Comment */", 134 "\t/* Comment */ ", 135 "\n/* Comment */ ", 136 "i := 5 /* Comment */", // issue #5551 137 "\ta()\n//line :1", // issue #11276 138 "\t//xxx\n\ta()\n//line :2", // issue #11276 139 "\ta() //line :1\n\tb()\n", // issue #11276 140 "x := 0\n//line :1\n//line :2", // issue #11276 141 142 // whitespace 143 "", // issue #11275 144 " ", // issue #11275 145 "\t", // issue #11275 146 "\t\t", // issue #11275 147 "\n", // issue #11275 148 "\n\n", // issue #11275 149 "\t\n", // issue #11275 150 151 // erroneous programs 152 "ERROR1 + 2 +", 153 "ERRORx := 0", 154 155 // build comments 156 "// copyright\n\n//go:build x\n\npackage p\n", 157 "// copyright\n\n//go:build x\n// +build x\n\npackage p\n", 158 } 159 160 func String(s string) (string, error) { 161 res, err := Source([]byte(s)) 162 if err != nil { 163 return "", err 164 } 165 return string(res), nil 166 } 167 168 func TestPartial(t *testing.T) { 169 for _, src := range tests { 170 if strings.HasPrefix(src, "ERROR") { 171 // test expected to fail 172 src = src[5:] // remove ERROR prefix 173 res, err := String(src) 174 if err == nil && res == src { 175 t.Errorf("formatting succeeded but was expected to fail:\n%q", src) 176 } 177 } else { 178 // test expected to succeed 179 res, err := String(src) 180 if err != nil { 181 t.Errorf("formatting failed (%s):\n%q", err, src) 182 } else if res != src { 183 t.Errorf("formatting incorrect:\nsource: %q\nresult: %q", src, res) 184 } 185 } 186 } 187 }