github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/src/cmd/cover/cover_test.go (about)

     1  // Copyright 2013 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 main_test
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"internal/testenv"
    11  	"io/ioutil"
    12  	"os"
    13  	"os/exec"
    14  	"path/filepath"
    15  	"regexp"
    16  	"testing"
    17  )
    18  
    19  const (
    20  	// Data directory, also the package directory for the test.
    21  	testdata = "testdata"
    22  
    23  	// Binaries we compile.
    24  	testcover = "./testcover.exe"
    25  )
    26  
    27  var (
    28  	// Files we use.
    29  	testMain    = filepath.Join(testdata, "main.go")
    30  	testTest    = filepath.Join(testdata, "test.go")
    31  	coverInput  = filepath.Join(testdata, "test_line.go")
    32  	coverOutput = filepath.Join(testdata, "test_cover.go")
    33  )
    34  
    35  var debug = false // Keeps the rewritten files around if set.
    36  
    37  // Run this shell script, but do it in Go so it can be run by "go test".
    38  //
    39  //	replace the word LINE with the line number < testdata/test.go > testdata/test_line.go
    40  // 	go build -o ./testcover
    41  // 	./testcover -mode=count -var=CoverTest -o ./testdata/test_cover.go testdata/test_line.go
    42  //	go run ./testdata/main.go ./testdata/test.go
    43  //
    44  func TestCover(t *testing.T) {
    45  	testenv.MustHaveGoBuild(t)
    46  
    47  	// Read in the test file (testTest) and write it, with LINEs specified, to coverInput.
    48  	file, err := ioutil.ReadFile(testTest)
    49  	if err != nil {
    50  		t.Fatal(err)
    51  	}
    52  	lines := bytes.Split(file, []byte("\n"))
    53  	for i, line := range lines {
    54  		lines[i] = bytes.Replace(line, []byte("LINE"), []byte(fmt.Sprint(i+1)), -1)
    55  	}
    56  	if err := ioutil.WriteFile(coverInput, bytes.Join(lines, []byte("\n")), 0666); err != nil {
    57  		t.Fatal(err)
    58  	}
    59  
    60  	// defer removal of test_line.go
    61  	if !debug {
    62  		defer os.Remove(coverInput)
    63  	}
    64  
    65  	// go build -o testcover
    66  	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", testcover)
    67  	run(cmd, t)
    68  
    69  	// defer removal of testcover
    70  	defer os.Remove(testcover)
    71  
    72  	// ./testcover -mode=count -var=thisNameMustBeVeryLongToCauseOverflowOfCounterIncrementStatementOntoNextLineForTest -o ./testdata/test_cover.go testdata/test_line.go
    73  	cmd = exec.Command(testcover, "-mode=count", "-var=thisNameMustBeVeryLongToCauseOverflowOfCounterIncrementStatementOntoNextLineForTest", "-o", coverOutput, coverInput)
    74  	run(cmd, t)
    75  
    76  	// defer removal of ./testdata/test_cover.go
    77  	if !debug {
    78  		defer os.Remove(coverOutput)
    79  	}
    80  
    81  	// go run ./testdata/main.go ./testdata/test.go
    82  	cmd = exec.Command(testenv.GoToolPath(t), "run", testMain, coverOutput)
    83  	run(cmd, t)
    84  
    85  	file, err = ioutil.ReadFile(coverOutput)
    86  	if err != nil {
    87  		t.Fatal(err)
    88  	}
    89  	// compiler directive must appear right next to function declaration.
    90  	if got, err := regexp.MatchString(".*\n//go:nosplit\nfunc someFunction().*", string(file)); err != nil || !got {
    91  		t.Errorf("misplaced compiler directive: got=(%v, %v); want=(true; nil)", got, err)
    92  	}
    93  	// "go:linkname" compiler directive should be present.
    94  	if got, err := regexp.MatchString(`.*go\:linkname some\_name some\_name.*`, string(file)); err != nil || !got {
    95  		t.Errorf("'go:linkname' compiler directive not found: got=(%v, %v); want=(true; nil)", got, err)
    96  	}
    97  
    98  	// No other comments should be present in generated code.
    99  	c := ".*// This comment shouldn't appear in generated go code.*"
   100  	if got, err := regexp.MatchString(c, string(file)); err != nil || got {
   101  		t.Errorf("non compiler directive comment %q found. got=(%v, %v); want=(false; nil)", c, got, err)
   102  	}
   103  }
   104  
   105  func run(c *exec.Cmd, t *testing.T) {
   106  	c.Stdout = os.Stdout
   107  	c.Stderr = os.Stderr
   108  	err := c.Run()
   109  	if err != nil {
   110  		t.Fatal(err)
   111  	}
   112  }