diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:15:26 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:15:26 +0000 |
commit | 82539ad8d59729fb45b0bb0edda8f2bddb719eb1 (patch) | |
tree | 58f0b58e6f44f0e04d4a6373132cf426fa835fa7 /src/go/format/format_test.go | |
parent | Initial commit. (diff) | |
download | golang-1.17-82539ad8d59729fb45b0bb0edda8f2bddb719eb1.tar.xz golang-1.17-82539ad8d59729fb45b0bb0edda8f2bddb719eb1.zip |
Adding upstream version 1.17.13.upstream/1.17.13upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/go/format/format_test.go')
-rw-r--r-- | src/go/format/format_test.go | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/src/go/format/format_test.go b/src/go/format/format_test.go new file mode 100644 index 0000000..6cc0278 --- /dev/null +++ b/src/go/format/format_test.go @@ -0,0 +1,187 @@ +// Copyright 2012 The Go 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 format + +import ( + "bytes" + "go/ast" + "go/parser" + "go/token" + "os" + "strings" + "testing" +) + +const testfile = "format_test.go" + +func diff(t *testing.T, dst, src []byte) { + line := 1 + offs := 0 // line offset + for i := 0; i < len(dst) && i < len(src); i++ { + d := dst[i] + s := src[i] + if d != s { + t.Errorf("dst:%d: %s\n", line, dst[offs:i+1]) + t.Errorf("src:%d: %s\n", line, src[offs:i+1]) + return + } + if s == '\n' { + line++ + offs = i + 1 + } + } + if len(dst) != len(src) { + t.Errorf("len(dst) = %d, len(src) = %d\nsrc = %q", len(dst), len(src), src) + } +} + +func TestNode(t *testing.T) { + src, err := os.ReadFile(testfile) + if err != nil { + t.Fatal(err) + } + + fset := token.NewFileSet() + file, err := parser.ParseFile(fset, testfile, src, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + + var buf bytes.Buffer + + if err = Node(&buf, fset, file); err != nil { + t.Fatal("Node failed:", err) + } + + diff(t, buf.Bytes(), src) +} + +// Node is documented to not modify the AST. +// Test that it is so even when numbers are normalized. +func TestNodeNoModify(t *testing.T) { + const ( + src = "package p\n\nconst _ = 0000000123i\n" + golden = "package p\n\nconst _ = 123i\n" + ) + + fset := token.NewFileSet() + file, err := parser.ParseFile(fset, "", src, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + + // Capture original address and value of a BasicLit node + // which will undergo formatting changes during printing. + wantLit := file.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec).Values[0].(*ast.BasicLit) + wantVal := wantLit.Value + + var buf bytes.Buffer + if err = Node(&buf, fset, file); err != nil { + t.Fatal("Node failed:", err) + } + diff(t, buf.Bytes(), []byte(golden)) + + // Check if anything changed after Node returned. + gotLit := file.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec).Values[0].(*ast.BasicLit) + gotVal := gotLit.Value + + if gotLit != wantLit { + t.Errorf("got *ast.BasicLit address %p, want %p", gotLit, wantLit) + } + if gotVal != wantVal { + t.Errorf("got *ast.BasicLit value %q, want %q", gotVal, wantVal) + } +} + +func TestSource(t *testing.T) { + src, err := os.ReadFile(testfile) + if err != nil { + t.Fatal(err) + } + + res, err := Source(src) + if err != nil { + t.Fatal("Source failed:", err) + } + + diff(t, res, src) +} + +// Test cases that are expected to fail are marked by the prefix "ERROR". +// The formatted result must look the same as the input for successful tests. +var tests = []string{ + // declaration lists + `import "go/format"`, + "var x int", + "var x int\n\ntype T struct{}", + + // statement lists + "x := 0", + "f(a, b, c)\nvar x int = f(1, 2, 3)", + + // indentation, leading and trailing space + "\tx := 0\n\tgo f()", + "\tx := 0\n\tgo f()\n\n\n", + "\n\t\t\n\n\tx := 0\n\tgo f()\n\n\n", + "\n\t\t\n\n\t\t\tx := 0\n\t\t\tgo f()\n\n\n", + "\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 + "\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 + + // comments + "/* Comment */", + "\t/* Comment */ ", + "\n/* Comment */ ", + "i := 5 /* Comment */", // issue #5551 + "\ta()\n//line :1", // issue #11276 + "\t//xxx\n\ta()\n//line :2", // issue #11276 + "\ta() //line :1\n\tb()\n", // issue #11276 + "x := 0\n//line :1\n//line :2", // issue #11276 + + // whitespace + "", // issue #11275 + " ", // issue #11275 + "\t", // issue #11275 + "\t\t", // issue #11275 + "\n", // issue #11275 + "\n\n", // issue #11275 + "\t\n", // issue #11275 + + // erroneous programs + "ERROR1 + 2 +", + "ERRORx := 0", + + // build comments + "// copyright\n\n//go:build x\n\npackage p\n", + "// copyright\n\n//go:build x\n// +build x\n\npackage p\n", +} + +func String(s string) (string, error) { + res, err := Source([]byte(s)) + if err != nil { + return "", err + } + return string(res), nil +} + +func TestPartial(t *testing.T) { + for _, src := range tests { + if strings.HasPrefix(src, "ERROR") { + // test expected to fail + src = src[5:] // remove ERROR prefix + res, err := String(src) + if err == nil && res == src { + t.Errorf("formatting succeeded but was expected to fail:\n%q", src) + } + } else { + // test expected to succeed + res, err := String(src) + if err != nil { + t.Errorf("formatting failed (%s):\n%q", err, src) + } else if res != src { + t.Errorf("formatting incorrect:\nsource: %q\nresult: %q", src, res) + } + } + } +} |