Source file tour/content_test.go

     1  // Copyright 2016 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 content
     6  
     7  import (
     8  	"bytes"
     9  	"errors"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"os"
    13  	"os/exec"
    14  	"path/filepath"
    15  	"strings"
    16  	"testing"
    17  
    18  	// Keep golang.org/x/tour in our go.mod require list for use during test.
    19  	_ "golang.org/x/tour/wc"
    20  )
    21  
    22  // Test that all the .go files inside the content file build
    23  // and execute (without checking for output correctness).
    24  // Files that contain the string "// +build no-build" are not built.
    25  // Files that contain the string "// +build no-run" are not executed.
    26  func TestContent(t *testing.T) {
    27  	if _, err := exec.LookPath("go"); err != nil {
    28  		t.Skipf("skipping because 'go' executable not available: %v", err)
    29  	}
    30  
    31  	scratch, err := ioutil.TempDir("", "tour-content-test")
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  	defer os.RemoveAll(scratch)
    36  
    37  	err = filepath.Walk(".", func(path string, fi os.FileInfo, err error) error {
    38  		if filepath.Ext(path) != ".go" {
    39  			return nil
    40  		}
    41  		if filepath.Base(path) == "content_test.go" {
    42  			return nil
    43  		}
    44  		t.Run(path, func(t *testing.T) {
    45  			t.Parallel()
    46  			if err := testSnippet(t, filepath.ToSlash(path), scratch); err != nil {
    47  				t.Errorf("%v: %v", path, err)
    48  			}
    49  		})
    50  		return nil
    51  	})
    52  	if err != nil {
    53  		t.Error(err)
    54  	}
    55  }
    56  
    57  func testSnippet(t *testing.T, path, scratch string) error {
    58  	b, err := ioutil.ReadFile(path)
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	build := string(bytes.SplitN(b, []byte{'\n'}, 2)[0])
    64  	if !strings.HasPrefix(build, "// +build ") {
    65  		return errors.New("first line is not a +build comment")
    66  	}
    67  	if !strings.Contains(build, "OMIT") {
    68  		return errors.New(`+build comment does not contain "OMIT"`)
    69  	}
    70  
    71  	if strings.Contains(build, "no-build") {
    72  		return nil
    73  	}
    74  	bin := filepath.Join(scratch, filepath.Base(path)+".exe")
    75  	out, err := exec.Command("go", "build", "-o", bin, path).CombinedOutput()
    76  	if err != nil {
    77  		return fmt.Errorf("build error: %v\noutput:\n%s", err, out)
    78  	}
    79  	defer os.Remove(bin)
    80  
    81  	if strings.Contains(build, "no-run") {
    82  		return nil
    83  	}
    84  	out, err = exec.Command(bin).CombinedOutput()
    85  	if err != nil {
    86  		return fmt.Errorf("%v\nOutput:\n%s", err, out)
    87  	}
    88  	return nil
    89  }
    90  

View as plain text