github.com/goplus/gop@v1.2.6/printer/gop_test.go (about)

     1  /*
     2   * Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package printer_test
    18  
    19  import (
    20  	"bytes"
    21  	"io/fs"
    22  	"os"
    23  	"path/filepath"
    24  	"strings"
    25  	"testing"
    26  
    27  	"github.com/goplus/gop/ast"
    28  	"github.com/goplus/gop/format"
    29  	"github.com/goplus/gop/parser"
    30  	"github.com/goplus/gop/printer"
    31  	"github.com/goplus/gop/token"
    32  )
    33  
    34  func init() {
    35  	printer.SetDebug(printer.DbgFlagAll)
    36  }
    37  
    38  func TestNoPkgDecl(t *testing.T) {
    39  	var dst bytes.Buffer
    40  	fset := token.NewFileSet()
    41  	if err := format.Node(&dst, fset, &ast.File{
    42  		Name:      &ast.Ident{Name: "main"},
    43  		NoPkgDecl: true,
    44  	}); err != nil {
    45  		t.Fatal("format.Node failed:", err)
    46  	}
    47  	if dst.String() != "\n" {
    48  		t.Fatal("TestNoPkgDecl:", dst.String())
    49  	}
    50  }
    51  
    52  func TestFuncs(t *testing.T) {
    53  	var dst bytes.Buffer
    54  	fset := token.NewFileSet()
    55  	if err := format.Node(&dst, fset, &ast.File{
    56  		Name: &ast.Ident{Name: "main"},
    57  		Decls: []ast.Decl{
    58  			&ast.FuncDecl{
    59  				Type: &ast.FuncType{Params: &ast.FieldList{}},
    60  				Name: &ast.Ident{Name: "foo"},
    61  				Body: &ast.BlockStmt{
    62  					List: []ast.Stmt{&printer.NewlineStmt{}},
    63  				},
    64  			},
    65  			&ast.FuncDecl{
    66  				Type: &ast.FuncType{Params: &ast.FieldList{}},
    67  				Name: &ast.Ident{Name: "bar"},
    68  				Body: &ast.BlockStmt{},
    69  			},
    70  			&ast.FuncDecl{
    71  				Type:   &ast.FuncType{Params: &ast.FieldList{}},
    72  				Name:   &ast.Ident{Name: "Classname"},
    73  				Body:   &ast.BlockStmt{},
    74  				Shadow: true,
    75  			},
    76  		},
    77  		NoPkgDecl: true,
    78  	}); err != nil {
    79  		t.Fatal("format.Node failed:", err)
    80  	}
    81  	if dst.String() != `func foo() {
    82  
    83  }
    84  
    85  func bar() {
    86  }
    87  ` {
    88  		t.Fatal("TestNoPkgDecl:", dst.String())
    89  	}
    90  }
    91  
    92  func diffBytes(t *testing.T, dst, src []byte) {
    93  	line := 1
    94  	offs := 0 // line offset
    95  	for i := 0; i < len(dst) && i < len(src); i++ {
    96  		d := dst[i]
    97  		s := src[i]
    98  		if d != s {
    99  			t.Errorf("dst:%d: %s\n", line, dst[offs:])
   100  			t.Errorf("src:%d: %s\n", line, src[offs:])
   101  			return
   102  		}
   103  		if s == '\n' {
   104  			line++
   105  			offs = i + 1
   106  		}
   107  	}
   108  	if len(dst) != len(src) {
   109  		t.Errorf("len(dst) = %d, len(src) = %d\ndst = %q\nsrc = %q", len(dst), len(src), dst, src)
   110  	}
   111  }
   112  
   113  const (
   114  	excludeFormatSource = 1
   115  	excludeFormatNode   = 2
   116  )
   117  
   118  func testFrom(t *testing.T, fpath, sel string, mode int) {
   119  	if sel != "" && !strings.Contains(fpath, sel) {
   120  		return
   121  	}
   122  	src, err := os.ReadFile(fpath)
   123  	if err != nil {
   124  		t.Fatal(err)
   125  	}
   126  
   127  	if (mode & excludeFormatSource) == 0 {
   128  		t.Run("format.Source "+fpath, func(t *testing.T) {
   129  			var class bool
   130  			if filepath.Ext(fpath) == ".gox" {
   131  				class = true
   132  			}
   133  			res, err := format.Source(src, class, fpath)
   134  			if err != nil {
   135  				t.Fatal("Source failed:", err)
   136  			}
   137  			diffBytes(t, res, src)
   138  		})
   139  	}
   140  
   141  	if (mode & excludeFormatNode) == 0 {
   142  		t.Run("format.Node "+fpath, func(t *testing.T) {
   143  			fset := token.NewFileSet()
   144  			m := parser.ParseComments
   145  			if filepath.Ext(fpath) == ".gox" {
   146  				m |= parser.ParseGoPlusClass
   147  			}
   148  			f, err := parser.ParseFile(fset, fpath, src, m)
   149  			if err != nil {
   150  				t.Fatal(err)
   151  			}
   152  			var buf bytes.Buffer
   153  			err = format.Node(&buf, fset, f)
   154  			if err != nil {
   155  				t.Fatal(err)
   156  			}
   157  			diffBytes(t, buf.Bytes(), src)
   158  		})
   159  	}
   160  }
   161  
   162  func TestFromGopPrinter(t *testing.T) {
   163  	testFrom(t, "nodes.go", "", 0)
   164  	testFrom(t, "printer.go", "", 0)
   165  	testFrom(t, "printer_test.go", "", 0)
   166  }
   167  
   168  func TestFromTestdata(t *testing.T) {
   169  	sel := ""
   170  	dir, err := os.Getwd()
   171  	if err != nil {
   172  		t.Fatal("Getwd failed:", err)
   173  	}
   174  	dir = filepath.Join(dir, "./_testdata")
   175  	filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
   176  		if err != nil {
   177  			return err
   178  		}
   179  		if !info.IsDir() && filepath.Ext(path) == ".gop" {
   180  			testFrom(t, path, sel, 0)
   181  		}
   182  		return nil
   183  	})
   184  }
   185  
   186  func TestFromParse(t *testing.T) {
   187  	sel := ""
   188  	dir, err := os.Getwd()
   189  	if err != nil {
   190  		t.Fatal("Getwd failed:", err)
   191  	}
   192  	dir = filepath.Join(dir, "../parser/_testdata")
   193  	filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
   194  		if err != nil {
   195  			return err
   196  		}
   197  		name := info.Name()
   198  		ext := filepath.Ext(name)
   199  		if !info.IsDir() && (ext == ".gop" || ext == ".gox") {
   200  			testFrom(t, path, sel, 0)
   201  		}
   202  		return nil
   203  	})
   204  }