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 }