github.com/HACKERALERT/Picocrypt/src/external/sys@v0.0.0-20210609020157-e519952f829f/unix/mkmerge_test.go (about)

     1  // Copyright 2020 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  //go:build ignore
     6  // +build ignore
     7  
     8  // Test cases for mkmerge.go.
     9  // Usage:
    10  //     $ go test mkmerge.go mkmerge_test.go
    11  package main
    12  
    13  import (
    14  	"bytes"
    15  	"fmt"
    16  	"go/parser"
    17  	"go/token"
    18  	"html/template"
    19  	"strings"
    20  	"testing"
    21  )
    22  
    23  func TestImports(t *testing.T) {
    24  	t.Run("importName", func(t *testing.T) {
    25  		cases := []struct {
    26  			src   string
    27  			ident string
    28  		}{
    29  			{`"syscall"`, "syscall"},
    30  			{`. "foobar"`, "."},
    31  			{`"go/ast"`, "ast"},
    32  			{`moo "go/format"`, "moo"},
    33  			{`. "go/token"`, "."},
    34  			{`"golang.org/x/sys/unix"`, "unix"},
    35  			{`nix "golang.org/x/sys/unix"`, "nix"},
    36  			{`_ "golang.org/x/sys/unix"`, "_"},
    37  		}
    38  
    39  		for _, c := range cases {
    40  			pkgSrc := fmt.Sprintf("package main\nimport %s", c.src)
    41  
    42  			f, err := parser.ParseFile(token.NewFileSet(), "", pkgSrc, parser.ImportsOnly)
    43  			if err != nil {
    44  				t.Error(err)
    45  				continue
    46  			}
    47  			if len(f.Imports) != 1 {
    48  				t.Errorf("Got %d imports, expected 1", len(f.Imports))
    49  				continue
    50  			}
    51  
    52  			got, err := importName(f.Imports[0])
    53  			if err != nil {
    54  				t.Fatal(err)
    55  			}
    56  			if got != c.ident {
    57  				t.Errorf("Got %q, expected %q", got, c.ident)
    58  			}
    59  		}
    60  	})
    61  
    62  	t.Run("filterImports", func(t *testing.T) {
    63  		cases := []struct{ before, after string }{
    64  			{`package test
    65  
    66  			import (
    67  				"foo"
    68  				"bar"
    69  			)`,
    70  				"package test\n"},
    71  			{`package test
    72  
    73  			import (
    74  				"foo"
    75  				"bar"
    76  			)
    77  
    78  			func useFoo() { foo.Usage() }`,
    79  				`package test
    80  
    81  import (
    82  	"foo"
    83  )
    84  
    85  func useFoo() { foo.Usage() }
    86  `},
    87  		}
    88  		for _, c := range cases {
    89  			got, err := filterImports([]byte(c.before))
    90  			if err != nil {
    91  				t.Error(err)
    92  			}
    93  
    94  			if string(got) != c.after {
    95  				t.Errorf("Got:\n%s\nExpected:\n%s\n", got, c.after)
    96  			}
    97  		}
    98  	})
    99  }
   100  
   101  func TestMerge(t *testing.T) {
   102  	// Input architecture files
   103  	inTmpl := template.Must(template.New("input").Parse(`
   104  // Package comments
   105  
   106  // build directives for arch{{.}}
   107  
   108  // +build goos,arch{{.}}
   109  
   110  package main
   111  
   112  /*
   113  #include <stdint.h>
   114  #include <stddef.h>
   115  int utimes(uintptr_t, uintptr_t);
   116  int utimensat(int, uintptr_t, uintptr_t, int);
   117  */
   118  import "C"
   119  
   120  // The imports
   121  import (
   122  	"commonDep"
   123  	"uniqueDep{{.}}"
   124  )
   125  
   126  // Vars
   127  var (
   128  	commonVar = commonDep.Use("common")
   129  
   130  	uniqueVar{{.}} = "unique{{.}}"
   131  )
   132  
   133  // Common free standing comment
   134  
   135  // Common comment
   136  const COMMON_INDEPENDENT = 1234
   137  const UNIQUE_INDEPENDENT_{{.}} = "UNIQUE_INDEPENDENT_{{.}}"
   138  
   139  // Group comment
   140  const (
   141  	COMMON_GROUP = "COMMON_GROUP"
   142  	UNIQUE_GROUP_{{.}} = "UNIQUE_GROUP_{{.}}"
   143  )
   144  
   145  // Group2 comment
   146  const (
   147  	UNIQUE_GROUP21_{{.}} = "UNIQUE_GROUP21_{{.}}"
   148  	UNIQUE_GROUP22_{{.}} = "UNIQUE_GROUP22_{{.}}"
   149  )
   150  
   151  // Group3 comment
   152  const (
   153  	sub1Common1 = 11
   154  	sub1Unique2{{.}} = 12
   155  	sub1Common3_LONG = 13
   156  
   157  	sub2Unique1{{.}} = 21
   158  	sub2Common2 = 22
   159  	sub2Common3 = 23
   160  	sub2Unique4{{.}} = 24
   161  )
   162  
   163  type commonInt int
   164  
   165  type uniqueInt{{.}} int
   166  
   167  func commonF() string {
   168  	return commonDep.Use("common")
   169  	}
   170  
   171  func uniqueF() string {
   172  	C.utimes(0, 0)
   173  	return uniqueDep{{.}}.Use("{{.}}")
   174  	}
   175  
   176  // Group4 comment
   177  const (
   178  	sub3Common1 = 31
   179  	sub3Unique2{{.}} = 32
   180  	sub3Unique3{{.}} = 33
   181  	sub3Common4 = 34
   182  
   183  	sub4Common1, sub4Unique2{{.}} = 41, 42
   184  	sub4Unique3{{.}}, sub4Common4 = 43, 44
   185  )
   186  `))
   187  
   188  	// Filtered architecture files
   189  	outTmpl := template.Must(template.New("output").Parse(`// Package comments
   190  
   191  // build directives for arch{{.}}
   192  
   193  // +build goos,arch{{.}}
   194  
   195  package main
   196  
   197  /*
   198  #include <stdint.h>
   199  #include <stddef.h>
   200  int utimes(uintptr_t, uintptr_t);
   201  int utimensat(int, uintptr_t, uintptr_t, int);
   202  */
   203  import "C"
   204  
   205  // The imports
   206  import (
   207  	"commonDep"
   208  	"uniqueDep{{.}}"
   209  )
   210  
   211  // Vars
   212  var (
   213  	commonVar = commonDep.Use("common")
   214  
   215  	uniqueVar{{.}} = "unique{{.}}"
   216  )
   217  
   218  const UNIQUE_INDEPENDENT_{{.}} = "UNIQUE_INDEPENDENT_{{.}}"
   219  
   220  // Group comment
   221  const (
   222  	UNIQUE_GROUP_{{.}} = "UNIQUE_GROUP_{{.}}"
   223  )
   224  
   225  // Group2 comment
   226  const (
   227  	UNIQUE_GROUP21_{{.}} = "UNIQUE_GROUP21_{{.}}"
   228  	UNIQUE_GROUP22_{{.}} = "UNIQUE_GROUP22_{{.}}"
   229  )
   230  
   231  // Group3 comment
   232  const (
   233  	sub1Unique2{{.}} = 12
   234  
   235  	sub2Unique1{{.}} = 21
   236  	sub2Unique4{{.}} = 24
   237  )
   238  
   239  type uniqueInt{{.}} int
   240  
   241  func uniqueF() string {
   242  	C.utimes(0, 0)
   243  	return uniqueDep{{.}}.Use("{{.}}")
   244  }
   245  
   246  // Group4 comment
   247  const (
   248  	sub3Unique2{{.}} = 32
   249  	sub3Unique3{{.}} = 33
   250  
   251  	sub4Common1, sub4Unique2{{.}} = 41, 42
   252  	sub4Unique3{{.}}, sub4Common4 = 43, 44
   253  )
   254  `))
   255  
   256  	const mergedFile = `// Package comments
   257  
   258  package main
   259  
   260  // The imports
   261  import (
   262  	"commonDep"
   263  )
   264  
   265  // Common free standing comment
   266  
   267  // Common comment
   268  const COMMON_INDEPENDENT = 1234
   269  
   270  // Group comment
   271  const (
   272  	COMMON_GROUP = "COMMON_GROUP"
   273  )
   274  
   275  // Group3 comment
   276  const (
   277  	sub1Common1      = 11
   278  	sub1Common3_LONG = 13
   279  
   280  	sub2Common2 = 22
   281  	sub2Common3 = 23
   282  )
   283  
   284  type commonInt int
   285  
   286  func commonF() string {
   287  	return commonDep.Use("common")
   288  }
   289  
   290  // Group4 comment
   291  const (
   292  	sub3Common1 = 31
   293  	sub3Common4 = 34
   294  )
   295  `
   296  
   297  	// Generate source code for different "architectures"
   298  	var inFiles, outFiles []srcFile
   299  	for _, arch := range strings.Fields("A B C D") {
   300  		buf := new(bytes.Buffer)
   301  		err := inTmpl.Execute(buf, arch)
   302  		if err != nil {
   303  			t.Fatal(err)
   304  		}
   305  		inFiles = append(inFiles, srcFile{"file" + arch, buf.Bytes()})
   306  
   307  		buf = new(bytes.Buffer)
   308  		err = outTmpl.Execute(buf, arch)
   309  		if err != nil {
   310  			t.Fatal(err)
   311  		}
   312  		outFiles = append(outFiles, srcFile{"file" + arch, buf.Bytes()})
   313  	}
   314  
   315  	t.Run("getCodeSet", func(t *testing.T) {
   316  		got, err := getCodeSet(inFiles[0].src)
   317  		if err != nil {
   318  			t.Fatal(err)
   319  		}
   320  
   321  		expectedElems := []codeElem{
   322  			{token.COMMENT, "Package comments\n"},
   323  			{token.COMMENT, "build directives for archA\n"},
   324  			{token.COMMENT, "+build goos,archA\n"},
   325  			{token.CONST, `COMMON_INDEPENDENT = 1234`},
   326  			{token.CONST, `UNIQUE_INDEPENDENT_A = "UNIQUE_INDEPENDENT_A"`},
   327  			{token.CONST, `COMMON_GROUP = "COMMON_GROUP"`},
   328  			{token.CONST, `UNIQUE_GROUP_A = "UNIQUE_GROUP_A"`},
   329  			{token.CONST, `UNIQUE_GROUP21_A = "UNIQUE_GROUP21_A"`},
   330  			{token.CONST, `UNIQUE_GROUP22_A = "UNIQUE_GROUP22_A"`},
   331  			{token.CONST, `sub1Common1 = 11`},
   332  			{token.CONST, `sub1Unique2A = 12`},
   333  			{token.CONST, `sub1Common3_LONG = 13`},
   334  			{token.CONST, `sub2Unique1A = 21`},
   335  			{token.CONST, `sub2Common2 = 22`},
   336  			{token.CONST, `sub2Common3 = 23`},
   337  			{token.CONST, `sub2Unique4A = 24`},
   338  			{token.CONST, `sub3Common1 = 31`},
   339  			{token.CONST, `sub3Unique2A = 32`},
   340  			{token.CONST, `sub3Unique3A = 33`},
   341  			{token.CONST, `sub3Common4 = 34`},
   342  			{token.CONST, `sub4Common1, sub4Unique2A = 41, 42`},
   343  			{token.CONST, `sub4Unique3A, sub4Common4 = 43, 44`},
   344  			{token.TYPE, `commonInt int`},
   345  			{token.TYPE, `uniqueIntA int`},
   346  			{token.FUNC, `func commonF() string {
   347  	return commonDep.Use("common")
   348  }`},
   349  			{token.FUNC, `func uniqueF() string {
   350  	C.utimes(0, 0)
   351  	return uniqueDepA.Use("A")
   352  }`},
   353  		}
   354  		expected := newCodeSet()
   355  		for _, d := range expectedElems {
   356  			expected.add(d)
   357  		}
   358  
   359  		if len(got.set) != len(expected.set) {
   360  			t.Errorf("Got %d codeElems, expected %d", len(got.set), len(expected.set))
   361  		}
   362  		for expElem := range expected.set {
   363  			if !got.has(expElem) {
   364  				t.Errorf("Didn't get expected codeElem %#v", expElem)
   365  			}
   366  		}
   367  		for gotElem := range got.set {
   368  			if !expected.has(gotElem) {
   369  				t.Errorf("Got unexpected codeElem %#v", gotElem)
   370  			}
   371  		}
   372  	})
   373  
   374  	t.Run("getCommonSet", func(t *testing.T) {
   375  		got, err := getCommonSet(inFiles)
   376  		if err != nil {
   377  			t.Fatal(err)
   378  		}
   379  
   380  		expected := newCodeSet()
   381  		expected.add(codeElem{token.COMMENT, "Package comments\n"})
   382  		expected.add(codeElem{token.CONST, `COMMON_INDEPENDENT = 1234`})
   383  		expected.add(codeElem{token.CONST, `COMMON_GROUP = "COMMON_GROUP"`})
   384  		expected.add(codeElem{token.CONST, `sub1Common1 = 11`})
   385  		expected.add(codeElem{token.CONST, `sub1Common3_LONG = 13`})
   386  		expected.add(codeElem{token.CONST, `sub2Common2 = 22`})
   387  		expected.add(codeElem{token.CONST, `sub2Common3 = 23`})
   388  		expected.add(codeElem{token.CONST, `sub3Common1 = 31`})
   389  		expected.add(codeElem{token.CONST, `sub3Common4 = 34`})
   390  		expected.add(codeElem{token.TYPE, `commonInt int`})
   391  		expected.add(codeElem{token.FUNC, `func commonF() string {
   392  	return commonDep.Use("common")
   393  }`})
   394  
   395  		if len(got.set) != len(expected.set) {
   396  			t.Errorf("Got %d codeElems, expected %d", len(got.set), len(expected.set))
   397  		}
   398  		for expElem := range expected.set {
   399  			if !got.has(expElem) {
   400  				t.Errorf("Didn't get expected codeElem %#v", expElem)
   401  			}
   402  		}
   403  		for gotElem := range got.set {
   404  			if !expected.has(gotElem) {
   405  				t.Errorf("Got unexpected codeElem %#v", gotElem)
   406  			}
   407  		}
   408  	})
   409  
   410  	t.Run("filter(keepCommon)", func(t *testing.T) {
   411  		commonSet, err := getCommonSet(inFiles)
   412  		if err != nil {
   413  			t.Fatal(err)
   414  		}
   415  
   416  		got, err := filter(inFiles[0].src, commonSet.keepCommon)
   417  		expected := []byte(mergedFile)
   418  
   419  		if !bytes.Equal(got, expected) {
   420  			t.Errorf("Got:\n%s\nExpected:\n%s", addLineNr(got), addLineNr(expected))
   421  			diffLines(t, got, expected)
   422  		}
   423  	})
   424  
   425  	t.Run("filter(keepArchSpecific)", func(t *testing.T) {
   426  		commonSet, err := getCommonSet(inFiles)
   427  		if err != nil {
   428  			t.Fatal(err)
   429  		}
   430  
   431  		for i := range inFiles {
   432  			got, err := filter(inFiles[i].src, commonSet.keepArchSpecific)
   433  			if err != nil {
   434  				t.Fatal(err)
   435  			}
   436  
   437  			expected := outFiles[i].src
   438  
   439  			if !bytes.Equal(got, expected) {
   440  				t.Errorf("Got:\n%s\nExpected:\n%s", addLineNr(got), addLineNr(expected))
   441  				diffLines(t, got, expected)
   442  			}
   443  		}
   444  	})
   445  }
   446  
   447  func TestMergedName(t *testing.T) {
   448  	t.Run("getValidGOOS", func(t *testing.T) {
   449  		testcases := []struct {
   450  			filename, goos string
   451  			ok             bool
   452  		}{
   453  			{"zerrors_aix.go", "aix", true},
   454  			{"zerrors_darwin.go", "darwin", true},
   455  			{"zerrors_dragonfly.go", "dragonfly", true},
   456  			{"zerrors_freebsd.go", "freebsd", true},
   457  			{"zerrors_linux.go", "linux", true},
   458  			{"zerrors_netbsd.go", "netbsd", true},
   459  			{"zerrors_openbsd.go", "openbsd", true},
   460  			{"zerrors_solaris.go", "solaris", true},
   461  			{"zerrors_multics.go", "", false},
   462  		}
   463  		for _, tc := range testcases {
   464  			goos, ok := getValidGOOS(tc.filename)
   465  			if goos != tc.goos {
   466  				t.Errorf("got GOOS %q, expected %q", goos, tc.goos)
   467  			}
   468  			if ok != tc.ok {
   469  				t.Errorf("got ok %v, expected %v", ok, tc.ok)
   470  			}
   471  		}
   472  	})
   473  }
   474  
   475  // Helper functions to diff test sources
   476  
   477  func diffLines(t *testing.T, got, expected []byte) {
   478  	t.Helper()
   479  
   480  	gotLines := bytes.Split(got, []byte{'\n'})
   481  	expLines := bytes.Split(expected, []byte{'\n'})
   482  
   483  	i := 0
   484  	for i < len(gotLines) && i < len(expLines) {
   485  		if !bytes.Equal(gotLines[i], expLines[i]) {
   486  			t.Errorf("Line %d: Got:\n%q\nExpected:\n%q", i+1, gotLines[i], expLines[i])
   487  			return
   488  		}
   489  		i++
   490  	}
   491  
   492  	if i < len(gotLines) && i >= len(expLines) {
   493  		t.Errorf("Line %d: got %q, expected EOF", i+1, gotLines[i])
   494  	}
   495  	if i >= len(gotLines) && i < len(expLines) {
   496  		t.Errorf("Line %d: got EOF, expected %q", i+1, gotLines[i])
   497  	}
   498  }
   499  
   500  func addLineNr(src []byte) []byte {
   501  	lines := bytes.Split(src, []byte("\n"))
   502  	for i, line := range lines {
   503  		lines[i] = []byte(fmt.Sprintf("%d: %s", i+1, line))
   504  	}
   505  	return bytes.Join(lines, []byte("\n"))
   506  }