github.com/jonsyu1/godel@v0.0.0-20171017211503-64567a0cf169/integration_test/integration_verify_test.go (about)

     1  // Copyright 2016 Palantir Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package integration_test
    16  
    17  import (
    18  	"fmt"
    19  	"io/ioutil"
    20  	"os"
    21  	"os/exec"
    22  	"path"
    23  	"regexp"
    24  	"testing"
    25  
    26  	"github.com/nmiyake/pkg/gofiles"
    27  	"github.com/stretchr/testify/assert"
    28  	"github.com/stretchr/testify/require"
    29  )
    30  
    31  const (
    32  	generateYML = `
    33  generators:
    34    foo:
    35      go-generate-dir: gen
    36      gen-paths:
    37        paths:
    38          - "gen/output.txt"
    39  `
    40  	importsYML = `
    41  root-dirs:
    42    - .`
    43  	licenseYML = `
    44  header: |
    45    // Copyright 2016 Palantir Technologies, Inc.
    46    //
    47    // Licensed under the Apache License, Version 2.0 (the "License");
    48    // you may not use this file except in compliance with the License.
    49    // You may obtain a copy of the License at
    50    //
    51    // http://www.apache.org/licenses/LICENSE-2.0
    52    //
    53    // Unless required by applicable law or agreed to in writing, software
    54    // distributed under the License is distributed on an "AS IS" BASIS,
    55    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    56    // See the License for the specific language governing permissions and
    57    // limitations under the License.
    58  `
    59  )
    60  
    61  func TestVerify(t *testing.T) {
    62  	testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version)
    63  
    64  	specs := []gofiles.GoFileSpec{
    65  		{
    66  			RelPath: "main.go",
    67  			Src: `package main
    68  	import "fmt"
    69  
    70  	func main() {
    71  		fmt.Println("hello, world!")
    72  	}`,
    73  		},
    74  		{
    75  			RelPath: "main_test.go",
    76  			Src: `package main_test
    77  	import "testing"
    78  
    79  	func TestFoo(t *testing.T) {
    80  		t=t
    81  		t.Fail()
    82  	}`,
    83  		},
    84  		{
    85  			RelPath: "gen/testbar.go",
    86  			Src: `package testbar
    87  
    88  //go:generate go run generator_main.go
    89  `,
    90  		},
    91  		{
    92  			RelPath: "gen/generator_main.go",
    93  			Src: `// +build ignore
    94  
    95  package main
    96  
    97  import (
    98  	"io/ioutil"
    99  )
   100  
   101  func main() {
   102  	if err := ioutil.WriteFile("output.txt", []byte("foo-output"), 0644); err != nil {
   103  		panic(err)
   104  	}
   105  }
   106  `,
   107  		},
   108  	}
   109  	_, err := gofiles.Write(testProjectDir, specs)
   110  	require.NoError(t, err)
   111  
   112  	err = ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "generate.yml"), []byte(generateYML), 0644)
   113  	require.NoError(t, err)
   114  	err = ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "imports.yml"), []byte(importsYML), 0644)
   115  	require.NoError(t, err)
   116  	err = ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "license.yml"), []byte(licenseYML), 0644)
   117  	require.NoError(t, err)
   118  
   119  	for i, currCase := range []struct {
   120  		args []string
   121  		want string
   122  	}{
   123  		{want: `(?s).+Failed tasks:\n\tformat -v -l\n\tgenerate --verify\n\timports --verify\n\tlicense --verify\n\tcheck\n\ttest`},
   124  		{args: []string{"--skip-format"}, want: `(?s).+Failed tasks:\n\tgenerate --verify\n\timports --verify\n\tlicense --verify\n\tcheck\n\ttest`},
   125  		{args: []string{"--skip-check"}, want: `(?s).+Failed tasks:\n\tformat -v -l\n\tgenerate --verify\n\timports --verify\n\tlicense --verify\n\ttest`},
   126  		{args: []string{"--skip-generate"}, want: `(?s).+Failed tasks:\n\tformat -v -l\n\timports --verify\n\tlicense --verify\n\tcheck\n\ttest`},
   127  		{args: []string{"--skip-imports"}, want: `(?s).+Failed tasks:\n\tformat -v -l\n\tgenerate --verify\n\tlicense --verify\n\tcheck\n\ttest`},
   128  		{args: []string{"--skip-license"}, want: `(?s).+Failed tasks:\n\tformat -v -l\n\tgenerate --verify\n\timports --verify\n\tcheck\n\ttest`},
   129  		{args: []string{"--skip-test"}, want: `(?s).+Failed tasks:\n\tformat -v -l\n\tgenerate --verify\n\timports --verify\n\tlicense --verify\n\tcheck`},
   130  	} {
   131  		err = os.MkdirAll(path.Join(testProjectDir, "gen"), 0755)
   132  		require.NoError(t, err)
   133  		err = ioutil.WriteFile(path.Join(testProjectDir, "gen", "output.txt"), []byte("bar-output"), 0644)
   134  		require.NoError(t, err)
   135  
   136  		cmd := exec.Command("./godelw", append([]string{"verify", "--apply=false"}, currCase.args...)...)
   137  		cmd.Dir = testProjectDir
   138  		output, err := cmd.CombinedOutput()
   139  		require.Error(t, err)
   140  		assert.Regexp(t, regexp.MustCompile(currCase.want), string(output), "Case %d", i)
   141  	}
   142  }
   143  
   144  func TestVerifyApply(t *testing.T) {
   145  	testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version)
   146  
   147  	specs := []gofiles.GoFileSpec{
   148  		{
   149  			RelPath: "main.go",
   150  			Src: `package main
   151  	import "fmt"
   152  
   153  	func main() {
   154  		fmt.Println("hello, world!")
   155  	}`,
   156  		},
   157  		{
   158  			RelPath: "main_test.go",
   159  			Src: `package main_test
   160  	import "testing"
   161  
   162  	func TestFoo(t *testing.T) {
   163  		t=t
   164  		t.Fail()
   165  	}`,
   166  		},
   167  		{
   168  			RelPath: "gen/testbar.go",
   169  			Src: `package testbar
   170  
   171  //go:generate go run generator_main.go
   172  `,
   173  		},
   174  		{
   175  			RelPath: "gen/generator_main.go",
   176  			Src: `// +build ignore
   177  
   178  package main
   179  
   180  import (
   181  	"io/ioutil"
   182  )
   183  
   184  func main() {
   185  	if err := ioutil.WriteFile("output.txt", []byte("foo-output"), 0644); err != nil {
   186  		panic(err)
   187  	}
   188  }
   189  `,
   190  		},
   191  	}
   192  
   193  	const (
   194  		formattedTestSrc = `package main_test
   195  
   196  import (
   197  	"testing"
   198  )
   199  
   200  func TestFoo(t *testing.T) {
   201  	t = t
   202  	t.Fail()
   203  }
   204  `
   205  		generatedOutput = `foo-output`
   206  		importsJSON     = `{
   207      "imports": [],
   208      "mainOnlyImports": [],
   209      "testOnlyImports": []
   210  }`
   211  		licensedTestSrc = `// Copyright 2016 Palantir Technologies, Inc.
   212  //
   213  // Licensed under the Apache License, Version 2.0 (the "License");
   214  // you may not use this file except in compliance with the License.
   215  // You may obtain a copy of the License at
   216  //
   217  // http://www.apache.org/licenses/LICENSE-2.0
   218  //
   219  // Unless required by applicable law or agreed to in writing, software
   220  // distributed under the License is distributed on an "AS IS" BASIS,
   221  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   222  // See the License for the specific language governing permissions and
   223  // limitations under the License.
   224  
   225  package main_test
   226  	import "testing"
   227  
   228  	func TestFoo(t *testing.T) {
   229  		t=t
   230  		t.Fail()
   231  	}`
   232  		licensedAndFormattedTestSrc = `// Copyright 2016 Palantir Technologies, Inc.
   233  //
   234  // Licensed under the Apache License, Version 2.0 (the "License");
   235  // you may not use this file except in compliance with the License.
   236  // You may obtain a copy of the License at
   237  //
   238  // http://www.apache.org/licenses/LICENSE-2.0
   239  //
   240  // Unless required by applicable law or agreed to in writing, software
   241  // distributed under the License is distributed on an "AS IS" BASIS,
   242  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   243  // See the License for the specific language governing permissions and
   244  // limitations under the License.
   245  
   246  package main_test
   247  
   248  import (
   249  	"testing"
   250  )
   251  
   252  func TestFoo(t *testing.T) {
   253  	t = t
   254  	t.Fail()
   255  }
   256  `
   257  	)
   258  	err := ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "generate.yml"), []byte(generateYML), 0644)
   259  	require.NoError(t, err)
   260  	err = ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "imports.yml"), []byte(importsYML), 0644)
   261  	require.NoError(t, err)
   262  	err = ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "license.yml"), []byte(licenseYML), 0644)
   263  	require.NoError(t, err)
   264  
   265  	for i, currCase := range []struct {
   266  		args               []string
   267  		want               string
   268  		wantTestSrc        string
   269  		wantImportsJSON    string
   270  		wantGenerateOutput string
   271  	}{
   272  		{want: `(?s).+Failed tasks:\n\tcheck\n\ttest`, wantTestSrc: licensedAndFormattedTestSrc, wantImportsJSON: importsJSON, wantGenerateOutput: generatedOutput},
   273  		{args: []string{"--skip-format"}, want: `(?s).+Failed tasks:\n\tcheck\n\ttest`, wantTestSrc: licensedTestSrc, wantImportsJSON: importsJSON, wantGenerateOutput: generatedOutput},
   274  		{args: []string{"--skip-check"}, want: `(?s).+Failed tasks:\n\ttest`, wantTestSrc: licensedAndFormattedTestSrc, wantImportsJSON: importsJSON, wantGenerateOutput: generatedOutput},
   275  		{args: []string{"--skip-generate"}, want: `(?s).+Failed tasks:\n\tcheck\n\ttest`, wantTestSrc: licensedAndFormattedTestSrc, wantImportsJSON: importsJSON},
   276  		{args: []string{"--skip-imports"}, want: `(?s).+Failed tasks:\n\tcheck\n\ttest`, wantTestSrc: licensedAndFormattedTestSrc, wantGenerateOutput: generatedOutput},
   277  		{args: []string{"--skip-license"}, want: `(?s).+Failed tasks:\n\tcheck\n\ttest`, wantTestSrc: formattedTestSrc, wantImportsJSON: importsJSON, wantGenerateOutput: generatedOutput},
   278  		{args: []string{"--skip-test"}, want: `(?s).+Failed tasks:\n\tcheck`, wantTestSrc: licensedAndFormattedTestSrc, wantImportsJSON: importsJSON, wantGenerateOutput: generatedOutput},
   279  	} {
   280  		_, err := gofiles.Write(testProjectDir, specs)
   281  		require.NoError(t, err)
   282  
   283  		err = ioutil.WriteFile(path.Join(testProjectDir, "gen", "output.txt"), []byte(""), 0644)
   284  		require.NoError(t, err)
   285  
   286  		cmd := exec.Command("./godelw", append([]string{"verify"}, currCase.args...)...)
   287  		cmd.Dir = testProjectDir
   288  		output, err := cmd.CombinedOutput()
   289  		require.Error(t, err, fmt.Sprintf("Case %d", i))
   290  		assert.Regexp(t, regexp.MustCompile(currCase.want), string(output), "Case %d", i)
   291  
   292  		bytes, err := ioutil.ReadFile(path.Join(testProjectDir, "main_test.go"))
   293  		require.NoError(t, err, "Case %d", i)
   294  		assert.Equal(t, currCase.wantTestSrc, string(bytes), "Case %d", i)
   295  
   296  		gotGeneratedOutput, err := ioutil.ReadFile(path.Join(testProjectDir, "gen", "output.txt"))
   297  		require.NoError(t, err, "Case %d", i)
   298  		assert.Equal(t, currCase.wantGenerateOutput, string(gotGeneratedOutput), "Case %d", i)
   299  
   300  		importsJSONPath := path.Join(testProjectDir, "gocd_imports.json")
   301  		if currCase.wantImportsJSON == "" {
   302  			_, err = os.Stat(importsJSONPath)
   303  			assert.True(t, os.IsNotExist(err), "Case %d: gocd_imports.json should not exist", i)
   304  		} else {
   305  			bytes, err = ioutil.ReadFile(importsJSONPath)
   306  			require.NoError(t, err, "Case %d", i)
   307  			assert.Equal(t, currCase.wantImportsJSON, string(bytes), "Case %d", i)
   308  			err = os.Remove(importsJSONPath)
   309  			require.NoError(t, err, "Case %d", i)
   310  		}
   311  	}
   312  }
   313  
   314  func TestVerifyWithJUnitOutput(t *testing.T) {
   315  	testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version)
   316  	src := `package main
   317  	import "fmt"
   318  	func main() {
   319  		fmt.Println("hello, world!")
   320  	}`
   321  	err := ioutil.WriteFile(path.Join(testProjectDir, "main.go"), []byte(src), 0644)
   322  	require.NoError(t, err)
   323  	testSrc := `package main_test
   324  	import "testing"
   325  	func TestFoo(t *testing.T) {
   326  	}`
   327  	err = ioutil.WriteFile(path.Join(testProjectDir, "main_test.go"), []byte(testSrc), 0644)
   328  	require.NoError(t, err)
   329  
   330  	junitOutputFile := "test-output.xml"
   331  	cmd := exec.Command("./godelw", "verify", "--apply=false", "--junit-output", junitOutputFile)
   332  	cmd.Dir = testProjectDir
   333  	err = cmd.Run()
   334  	require.Error(t, err)
   335  
   336  	fi, err := os.Stat(path.Join(testProjectDir, junitOutputFile))
   337  	require.NoError(t, err)
   338  
   339  	assert.False(t, fi.IsDir())
   340  }
   341  
   342  func TestVerifyTestTags(t *testing.T) {
   343  	testProjectDir := setUpGödelTestAndDownload(t, testRootDir, gödelTGZ, version)
   344  	specs := []gofiles.GoFileSpec{
   345  		{
   346  			RelPath: "main.go",
   347  			Src: `package main
   348  
   349  func main() {}
   350  `,
   351  		},
   352  		{
   353  			RelPath: "main_test.go",
   354  			Src: `package main_test
   355  
   356  import (
   357  	"testing"
   358  )
   359  
   360  func TestFoo(t *testing.T) {}
   361  `,
   362  		},
   363  		{
   364  			RelPath: "integration_tests/integration_test.go",
   365  			Src: `package main_test
   366  
   367  import (
   368  	"testing"
   369  )
   370  
   371  func TestFooIntegration(t *testing.T) {}
   372  `,
   373  		},
   374  	}
   375  	files, err := gofiles.Write(testProjectDir, specs)
   376  	require.NoError(t, err)
   377  
   378  	err = ioutil.WriteFile(path.Join(testProjectDir, "godel", "config", "test.yml"), []byte(`tags:
   379    integration:
   380      names:
   381        - "integration_tests"
   382  `), 0644)
   383  	require.NoError(t, err)
   384  
   385  	// run verify with "none" tags. Should include output for main package but not for integration_test package.
   386  	cmd := exec.Command("./godelw", "verify", "--apply=false", "--tags=none")
   387  	cmd.Dir = testProjectDir
   388  	output, err := cmd.CombinedOutput()
   389  	outputStr := string(output)
   390  	require.NoError(t, err, "Command %v failed with error %v. Output: %q", cmd.Args, err, outputStr)
   391  	assert.Regexp(t, fmt.Sprintf(`(?s).+%s\s+[0-9.]+s.+`, files["main.go"].ImportPath), outputStr)
   392  	assert.NotRegexp(t, fmt.Sprintf(`(?s).+%s\s+[0-9.]+s.+`, files["integration_tests/integration_test.go"].ImportPath), outputStr)
   393  
   394  	// run verify with "all" tags. Should include output for integration_test package but not for main package.
   395  	cmd = exec.Command("./godelw", "verify", "--apply=false", "--tags=all")
   396  	cmd.Dir = testProjectDir
   397  	output, err = cmd.CombinedOutput()
   398  	outputStr = string(output)
   399  	require.NoError(t, err, "Command %v failed with error %v. Output: %q", cmd.Args, err, outputStr)
   400  	assert.Regexp(t, fmt.Sprintf(`(?s).+%s\s+[0-9.]+s.+`, files["integration_tests/integration_test.go"].ImportPath), outputStr)
   401  	assert.NotRegexp(t, fmt.Sprintf(`(?s).+%s\s+[0-9.]+s.+`, files["main.go"].ImportPath), outputStr)
   402  
   403  	// run verify in regular mode. Should include output for all tests.
   404  	cmd = exec.Command("./godelw", "verify", "--apply=false")
   405  	cmd.Dir = testProjectDir
   406  	output, err = cmd.CombinedOutput()
   407  	outputStr = string(output)
   408  	require.NoError(t, err, "Command %v failed with error %v. Output: %q", cmd.Args, err, outputStr)
   409  	assert.Regexp(t, fmt.Sprintf(`(?s).+%s\s+[0-9.]+s.+`, files["main.go"].ImportPath), outputStr)
   410  	assert.Regexp(t, fmt.Sprintf(`(?s).+%s\s+[0-9.]+s.+`, files["integration_tests/integration_test.go"].ImportPath), outputStr)
   411  }