cover_test.go 2.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
// Copyright 2013 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main_test

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
Dave Cheney's avatar
Dave Cheney committed
14
	"runtime"
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
	"testing"
)

const (
	// Data directory, also the package directory for the test.
	testdata = "testdata"

	// Binaries we compile.
	testcover = "./testcover.exe"
)

var (
	// Files we use.
	testMain    = filepath.Join(testdata, "main.go")
	testTest    = filepath.Join(testdata, "test.go")
	coverInput  = filepath.Join(testdata, "test_line.go")
	coverOutput = filepath.Join(testdata, "test_cover.go")
)

var debug = false // Keeps the rewritten files around if set.

// Run this shell script, but do it in Go so it can be run by "go test".
//
//	replace the word LINE with the line number < testdata/test.go > testdata/test_line.go
// 	go build -o ./testcover
// 	./testcover -mode=count -var=CoverTest -o ./testdata/test_cover.go testdata/test_line.go
//	go run ./testdata/main.go ./testdata/test.go
//
func TestCover(t *testing.T) {
Dave Cheney's avatar
Dave Cheney committed
44 45 46 47 48 49 50 51 52
	switch runtime.GOOS {
	case "nacl":
		t.Skipf("skipping; %v/%v no support for forking", runtime.GOOS, runtime.GOARCH)
	case "darwin", "android":
		switch runtime.GOARCH {
		case "arm", "arm64":
			t.Skipf("skipping; %v/%v no support for forking", runtime.GOOS, runtime.GOARCH)
		}
	}
53 54 55 56 57 58 59 60 61
	// Read in the test file (testTest) and write it, with LINEs specified, to coverInput.
	file, err := ioutil.ReadFile(testTest)
	if err != nil {
		t.Fatal(err)
	}
	lines := bytes.Split(file, []byte("\n"))
	for i, line := range lines {
		lines[i] = bytes.Replace(line, []byte("LINE"), []byte(fmt.Sprint(i+1)), -1)
	}
62 63 64
	if err := ioutil.WriteFile(coverInput, bytes.Join(lines, []byte("\n")), 0666); err != nil {
		t.Fatal(err)
	}
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99

	// defer removal of test_line.go
	if !debug {
		defer os.Remove(coverInput)
	}

	// go build -o testcover
	cmd := exec.Command("go", "build", "-o", testcover)
	run(cmd, t)

	// defer removal of testcover
	defer os.Remove(testcover)

	// ./testcover -mode=count -var=coverTest -o ./testdata/test_cover.go testdata/test_line.go
	cmd = exec.Command(testcover, "-mode=count", "-var=coverTest", "-o", coverOutput, coverInput)
	run(cmd, t)

	// defer removal of ./testdata/test_cover.go
	if !debug {
		defer os.Remove(coverOutput)
	}

	// go run ./testdata/main.go ./testdata/test.go
	cmd = exec.Command("go", "run", testMain, coverOutput)
	run(cmd, t)
}

func run(c *exec.Cmd, t *testing.T) {
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	err := c.Run()
	if err != nil {
		t.Fatal(err)
	}
}