github.com/liquid-dev/text@v0.3.3-liquid/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  	"io/ioutil"
    15  	"os"
    16  	"os/exec"
    17  	"path"
    18  	"path/filepath"
    19  	"reflect"
    20  	"runtime"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/liquid-dev/text/language"
    25  )
    26  
    27  var genFiles = flag.Bool("gen", false, "generate output files instead of comparing")
    28  
    29  // setHelper is testing.T.Helper on Go 1.9+, overridden by go19_test.go.
    30  var setHelper = func(t *testing.T) {}
    31  
    32  func TestFullCycle(t *testing.T) {
    33  	if runtime.GOOS == "android" {
    34  		t.Skip("cannot load outside packages on android")
    35  	}
    36  	if _, err := exec.LookPath("go"); err != nil {
    37  		t.Skipf("skipping because 'go' command is unavailable: %v", err)
    38  	}
    39  
    40  	GOPATH, err := ioutil.TempDir("", "pipeline_test")
    41  	if err != nil {
    42  		t.Fatal(err)
    43  	}
    44  	defer os.RemoveAll(GOPATH)
    45  	testdata := filepath.Join(GOPATH, "src", "testdata")
    46  
    47  	// Copy the testdata contents into a new module.
    48  	copyTestdata(t, testdata)
    49  	initTestdataModule(t, testdata)
    50  
    51  	// Several places hard-code the use of build.Default.
    52  	// Adjust it to match the test's temporary GOPATH.
    53  	defer func(prev string) { build.Default.GOPATH = prev }(build.Default.GOPATH)
    54  	build.Default.GOPATH = GOPATH + string(filepath.ListSeparator) + build.Default.GOPATH
    55  	if wd := reflect.ValueOf(&build.Default).Elem().FieldByName("WorkingDir"); wd.IsValid() {
    56  		defer func(prev string) { wd.SetString(prev) }(wd.String())
    57  		wd.SetString(testdata)
    58  	}
    59  
    60  	// To work around https://golang.org/issue/34860, execute the commands
    61  	// that (transitively) use go/build in the working directory of the
    62  	// corresponding module.
    63  	wd, _ := os.Getwd()
    64  	defer os.Chdir(wd)
    65  
    66  	dirs, err := ioutil.ReadDir(testdata)
    67  	if err != nil {
    68  		t.Fatal(err)
    69  	}
    70  	for _, f := range dirs {
    71  		if !f.IsDir() {
    72  			continue
    73  		}
    74  		t.Run(f.Name(), func(t *testing.T) {
    75  			chk := func(t *testing.T, err error) {
    76  				setHelper(t)
    77  				if err != nil {
    78  					t.Fatal(err)
    79  				}
    80  			}
    81  			dir := filepath.Join(testdata, f.Name())
    82  			pkgPath := "testdata/" + f.Name()
    83  			config := Config{
    84  				SourceLanguage: language.AmericanEnglish,
    85  				Packages:       []string{pkgPath},
    86  				Dir:            filepath.Join(dir, "locales"),
    87  				GenFile:        "catalog_gen.go",
    88  				GenPackage:     pkgPath,
    89  			}
    90  
    91  			os.Chdir(dir)
    92  
    93  			// TODO: load config if available.
    94  			s, err := Extract(&config)
    95  			chk(t, err)
    96  			chk(t, s.Import())
    97  			chk(t, s.Merge())
    98  			// TODO:
    99  			//  for range s.Config.Actions {
   100  			//  	//  TODO: do the actions.
   101  			//  }
   102  			chk(t, s.Export())
   103  			chk(t, s.Generate())
   104  
   105  			os.Chdir(wd)
   106  
   107  			writeJSON(t, filepath.Join(dir, "extracted.gotext.json"), s.Extracted)
   108  			checkOutput(t, dir, f.Name())
   109  		})
   110  	}
   111  }
   112  
   113  func copyTestdata(t *testing.T, dst string) {
   114  	err := filepath.Walk("testdata", func(p string, f os.FileInfo, err error) error {
   115  		if p == "testdata" || strings.HasSuffix(p, ".want") {
   116  			return nil
   117  		}
   118  
   119  		rel := strings.TrimPrefix(p, "testdata"+string(filepath.Separator))
   120  		if f.IsDir() {
   121  			return os.MkdirAll(filepath.Join(dst, rel), 0755)
   122  		}
   123  
   124  		data, err := ioutil.ReadFile(p)
   125  		if err != nil {
   126  			return err
   127  		}
   128  		return ioutil.WriteFile(filepath.Join(dst, rel), data, 0644)
   129  	})
   130  	if err != nil {
   131  		t.Fatal(err)
   132  	}
   133  }
   134  
   135  func initTestdataModule(t *testing.T, dst string) {
   136  	xTextDir, err := filepath.Abs("../..")
   137  	if err != nil {
   138  		t.Fatal(err)
   139  	}
   140  
   141  	goMod := fmt.Sprintf(`module testdata
   142  go 1.11
   143  require github.com/liquid-dev/text v0.0.0-00010101000000-000000000000
   144  replace github.com/liquid-dev/text v0.0.0-00010101000000-000000000000 => %s
   145  `, xTextDir)
   146  	if err := ioutil.WriteFile(filepath.Join(dst, "go.mod"), []byte(goMod), 0644); err != nil {
   147  		t.Fatal(err)
   148  	}
   149  
   150  	data, err := ioutil.ReadFile(filepath.Join(xTextDir, "go.sum"))
   151  	if err := ioutil.WriteFile(filepath.Join(dst, "go.sum"), data, 0644); err != nil {
   152  		t.Fatal(err)
   153  	}
   154  }
   155  
   156  func checkOutput(t *testing.T, gen string, testdataDir string) {
   157  	err := filepath.Walk(gen, func(gotFile string, f os.FileInfo, err error) error {
   158  		if f.IsDir() {
   159  			return nil
   160  		}
   161  		rel := strings.TrimPrefix(gotFile, gen+string(filepath.Separator))
   162  
   163  		wantFile := filepath.Join("testdata", testdataDir, rel+".want")
   164  		if _, err := os.Stat(wantFile); os.IsNotExist(err) {
   165  			return nil
   166  		}
   167  
   168  		got, err := ioutil.ReadFile(gotFile)
   169  		if err != nil {
   170  			t.Errorf("failed to read %q", gotFile)
   171  			return nil
   172  		}
   173  		if *genFiles {
   174  			if err := ioutil.WriteFile(wantFile, got, 0644); err != nil {
   175  				t.Fatal(err)
   176  			}
   177  		}
   178  		want, err := ioutil.ReadFile(wantFile)
   179  		if err != nil {
   180  			t.Errorf("failed to read %q", wantFile)
   181  		} else {
   182  			scanGot := bufio.NewScanner(bytes.NewReader(got))
   183  			scanWant := bufio.NewScanner(bytes.NewReader(want))
   184  			line := 0
   185  			clean := func(s string) string {
   186  				if i := strings.LastIndex(s, "//"); i != -1 {
   187  					s = s[:i]
   188  				}
   189  				return path.Clean(filepath.ToSlash(s))
   190  			}
   191  			for scanGot.Scan() && scanWant.Scan() {
   192  				got := clean(scanGot.Text())
   193  				want := clean(scanWant.Text())
   194  				if got != want {
   195  					t.Errorf("file %q differs from .want file at line %d:\n\t%s\n\t%s", gotFile, line, got, want)
   196  					break
   197  				}
   198  				line++
   199  			}
   200  			if scanGot.Scan() || scanWant.Scan() {
   201  				t.Errorf("file %q differs from .want file at line %d.", gotFile, line)
   202  			}
   203  		}
   204  		return nil
   205  	})
   206  	if err != nil {
   207  		t.Fatal(err)
   208  	}
   209  }
   210  
   211  func writeJSON(t *testing.T, path string, x interface{}) {
   212  	data, err := json.MarshalIndent(x, "", "    ")
   213  	if err != nil {
   214  		t.Fatal(err)
   215  	}
   216  	if err := ioutil.WriteFile(path, data, 0644); err != nil {
   217  		t.Fatal(err)
   218  	}
   219  }