github.com/sixpointsix/raftshardkv@v0.0.0-20240507130406-765b65f17bb3/pkg/mod/golang.org/x/text@v0.4.0/message/pipeline/pipeline_test.go (about)

     1  // Copyright 2017 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 pipeline
     6  
     7  import (
     8  	"bufio"
     9  	"bytes"
    10  	"encoding/json"
    11  	"flag"
    12  	"fmt"
    13  	"go/build"
    14  	"os"
    15  	"os/exec"
    16  	"path"
    17  	"path/filepath"
    18  	"reflect"
    19  	"runtime"
    20  	"strings"
    21  	"testing"
    22  
    23  	"golang.org/x/text/language"
    24  )
    25  
    26  var genFiles = flag.Bool("gen", false, "generate output files instead of comparing")
    27  
    28  // setHelper is testing.T.Helper on Go 1.9+, overridden by go19_test.go.
    29  var setHelper = func(t *testing.T) {}
    30  
    31  func TestFullCycle(t *testing.T) {
    32  	if runtime.GOOS == "android" {
    33  		t.Skip("cannot load outside packages on android")
    34  	}
    35  	if b := os.Getenv("GO_BUILDER_NAME"); b == "plan9-arm" {
    36  		t.Skipf("skipping: test frequently times out on %s", b)
    37  	}
    38  	if _, err := exec.LookPath("go"); err != nil {
    39  		t.Skipf("skipping because 'go' command is unavailable: %v", err)
    40  	}
    41  
    42  	GOPATH, err := os.MkdirTemp("", "pipeline_test")
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	defer os.RemoveAll(GOPATH)
    47  	testdata := filepath.Join(GOPATH, "src", "testdata")
    48  
    49  	// Copy the testdata contents into a new module.
    50  	copyTestdata(t, testdata)
    51  	initTestdataModule(t, testdata)
    52  
    53  	// Several places hard-code the use of build.Default.
    54  	// Adjust it to match the test's temporary GOPATH.
    55  	defer func(prev string) { build.Default.GOPATH = prev }(build.Default.GOPATH)
    56  	build.Default.GOPATH = GOPATH + string(filepath.ListSeparator) + build.Default.GOPATH
    57  	if wd := reflect.ValueOf(&build.Default).Elem().FieldByName("WorkingDir"); wd.IsValid() {
    58  		defer func(prev string) { wd.SetString(prev) }(wd.String())
    59  		wd.SetString(testdata)
    60  	}
    61  
    62  	// To work around https://golang.org/issue/34860, execute the commands
    63  	// that (transitively) use go/build in the working directory of the
    64  	// corresponding module.
    65  	wd, _ := os.Getwd()
    66  	defer os.Chdir(wd)
    67  
    68  	dirs, err := os.ReadDir(testdata)
    69  	if err != nil {
    70  		t.Fatal(err)
    71  	}
    72  	for _, f := range dirs {
    73  		if !f.IsDir() {
    74  			continue
    75  		}
    76  		t.Run(f.Name(), func(t *testing.T) {
    77  			chk := func(t *testing.T, err error) {
    78  				setHelper(t)
    79  				if err != nil {
    80  					t.Fatal(err)
    81  				}
    82  			}
    83  			dir := filepath.Join(testdata, f.Name())
    84  			pkgPath := "testdata/" + f.Name()
    85  			config := Config{
    86  				SourceLanguage: language.AmericanEnglish,
    87  				Packages:       []string{pkgPath},
    88  				Dir:            filepath.Join(dir, "locales"),
    89  				GenFile:        "catalog_gen.go",
    90  				GenPackage:     pkgPath,
    91  			}
    92  
    93  			os.Chdir(dir)
    94  
    95  			// TODO: load config if available.
    96  			s, err := Extract(&config)
    97  			chk(t, err)
    98  			chk(t, s.Import())
    99  			chk(t, s.Merge())
   100  			// TODO:
   101  			//  for range s.Config.Actions {
   102  			//  	//  TODO: do the actions.
   103  			//  }
   104  			chk(t, s.Export())
   105  			chk(t, s.Generate())
   106  
   107  			os.Chdir(wd)
   108  
   109  			writeJSON(t, filepath.Join(dir, "extracted.gotext.json"), s.Extracted)
   110  			checkOutput(t, dir, f.Name())
   111  		})
   112  	}
   113  }
   114  
   115  func copyTestdata(t *testing.T, dst string) {
   116  	err := filepath.Walk("testdata", func(p string, f os.FileInfo, err error) error {
   117  		if p == "testdata" || strings.HasSuffix(p, ".want") {
   118  			return nil
   119  		}
   120  
   121  		rel := strings.TrimPrefix(p, "testdata"+string(filepath.Separator))
   122  		if f.IsDir() {
   123  			return os.MkdirAll(filepath.Join(dst, rel), 0755)
   124  		}
   125  
   126  		data, err := os.ReadFile(p)
   127  		if err != nil {
   128  			return err
   129  		}
   130  		return os.WriteFile(filepath.Join(dst, rel), data, 0644)
   131  	})
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  }
   136  
   137  func initTestdataModule(t *testing.T, dst string) {
   138  	xTextDir, err := filepath.Abs("../..")
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  
   143  	goMod := fmt.Sprintf(`module testdata
   144  
   145  replace golang.org/x/text => %s
   146  `, xTextDir)
   147  	if err := os.WriteFile(filepath.Join(dst, "go.mod"), []byte(goMod), 0644); err != nil {
   148  		t.Fatal(err)
   149  	}
   150  
   151  	// Copy in the checksums from the parent module so that we won't
   152  	// need to re-fetch them from the checksum database.
   153  	data, err := os.ReadFile(filepath.Join(xTextDir, "go.sum"))
   154  	if err != nil {
   155  		t.Fatal(err)
   156  	}
   157  	if err := os.WriteFile(filepath.Join(dst, "go.sum"), data, 0644); err != nil {
   158  		t.Fatal(err)
   159  	}
   160  
   161  	// We've added a replacement for the parent version of x/text,
   162  	// but now we need to populate the correct version.
   163  	// (We can't just replace the zero-version because x/text
   164  	// may indirectly depend on some nonzero version of itself.)
   165  	//
   166  	// We use 'go get' instead of 'go mod tidy' to avoid the old-release
   167  	// compatibility check when graph pruning is enabled, and to avoid doing
   168  	// more work than necessary for test dependencies of imported packages
   169  	// (we're not going to run those tests here anyway).
   170  	//
   171  	// We 'go get' the packages in the testdata module — not specific dependencies
   172  	// of those packages — so that they will resolve to whatever version is
   173  	// already required in the (replaced) x/text go.mod file.
   174  
   175  	getCmd := exec.Command("go", "get", "-d", "./...")
   176  	getCmd.Dir = dst
   177  	getCmd.Env = append(os.Environ(), "PWD="+dst, "GOPROXY=off", "GOCACHE=off")
   178  	if out, err := getCmd.CombinedOutput(); err != nil {
   179  		t.Logf("%s", out)
   180  		t.Fatal(err)
   181  	}
   182  }
   183  
   184  func checkOutput(t *testing.T, gen string, testdataDir string) {
   185  	err := filepath.Walk(gen, func(gotFile string, f os.FileInfo, err error) error {
   186  		if f.IsDir() {
   187  			return nil
   188  		}
   189  		rel := strings.TrimPrefix(gotFile, gen+string(filepath.Separator))
   190  
   191  		wantFile := filepath.Join("testdata", testdataDir, rel+".want")
   192  		if _, err := os.Stat(wantFile); os.IsNotExist(err) {
   193  			return nil
   194  		}
   195  
   196  		got, err := os.ReadFile(gotFile)
   197  		if err != nil {
   198  			t.Errorf("failed to read %q", gotFile)
   199  			return nil
   200  		}
   201  		if *genFiles {
   202  			if err := os.WriteFile(wantFile, got, 0644); err != nil {
   203  				t.Fatal(err)
   204  			}
   205  		}
   206  		want, err := os.ReadFile(wantFile)
   207  		if err != nil {
   208  			t.Errorf("failed to read %q", wantFile)
   209  		} else {
   210  			scanGot := bufio.NewScanner(bytes.NewReader(got))
   211  			scanWant := bufio.NewScanner(bytes.NewReader(want))
   212  			line := 0
   213  			clean := func(s string) string {
   214  				if i := strings.LastIndex(s, "//"); i != -1 {
   215  					s = s[:i]
   216  				}
   217  				return path.Clean(filepath.ToSlash(s))
   218  			}
   219  			for scanGot.Scan() && scanWant.Scan() {
   220  				got := clean(scanGot.Text())
   221  				want := clean(scanWant.Text())
   222  				if got != want {
   223  					t.Errorf("file %q differs from .want file at line %d:\n\t%s\n\t%s", gotFile, line, got, want)
   224  					break
   225  				}
   226  				line++
   227  			}
   228  			if scanGot.Scan() || scanWant.Scan() {
   229  				t.Errorf("file %q differs from .want file at line %d.", gotFile, line)
   230  			}
   231  		}
   232  		return nil
   233  	})
   234  	if err != nil {
   235  		t.Fatal(err)
   236  	}
   237  }
   238  
   239  func writeJSON(t *testing.T, path string, x interface{}) {
   240  	data, err := json.MarshalIndent(x, "", "    ")
   241  	if err != nil {
   242  		t.Fatal(err)
   243  	}
   244  	if err := os.WriteFile(path, data, 0644); err != nil {
   245  		t.Fatal(err)
   246  	}
   247  }