Home | History | Annotate | Download | only in fixedbugs
      1 // +build !nacl
      2 // run
      3 
      4 // Copyright 2017 The Go Authors. All rights reserved.
      5 // Use of this source code is governed by a BSD-style
      6 // license that can be found in the LICENSE file.
      7 
      8 // ensure that panic(x) where x is a numeric type displays a readable number
      9 package main
     10 
     11 import (
     12 	"bytes"
     13 	"fmt"
     14 	"io/ioutil"
     15 	"log"
     16 	"os"
     17 	"os/exec"
     18 	"path/filepath"
     19 )
     20 
     21 const fn = `
     22 package main
     23 
     24 import  "errors"
     25 type S struct {
     26 
     27 }
     28 func (s S) String() string {
     29 	return "s-stringer"
     30 }
     31 func main() {
     32  	_ = errors.New
     33   panic(%s(%s))
     34 }
     35 `
     36 
     37 func main() {
     38 	tempDir, err := ioutil.TempDir("", "")
     39 	if err != nil {
     40 		log.Fatal(err)
     41 	}
     42 	defer os.RemoveAll(tempDir)
     43 	tmpFile := filepath.Join(tempDir, "tmp.go")
     44 
     45 	for _, tc := range []struct {
     46 		Type   string
     47 		Input  string
     48 		Expect string
     49 	}{{"", "nil", "panic: nil"},
     50 		{"errors.New", `"test"`, "panic: test"},
     51 		{"S", "S{}", "panic: s-stringer"},
     52 		{"byte", "8", "panic: 8"},
     53 		{"rune", "8", "panic: 8"},
     54 		{"int", "8", "panic: 8"},
     55 		{"int8", "8", "panic: 8"},
     56 		{"int16", "8", "panic: 8"},
     57 		{"int32", "8", "panic: 8"},
     58 		{"int64", "8", "panic: 8"},
     59 		{"uint", "8", "panic: 8"},
     60 		{"uint8", "8", "panic: 8"},
     61 		{"uint16", "8", "panic: 8"},
     62 		{"uint32", "8", "panic: 8"},
     63 		{"uint64", "8", "panic: 8"},
     64 		{"uintptr", "8", "panic: 8"},
     65 		{"bool", "true", "panic: true"},
     66 		{"complex64", "8 + 16i", "panic: (+8.000000e+000+1.600000e+001i)"},
     67 		{"complex128", "8+16i", "panic: (+8.000000e+000+1.600000e+001i)"},
     68 		{"string", `"test"`, "panic: test"}} {
     69 
     70 		b := bytes.Buffer{}
     71 		fmt.Fprintf(&b, fn, tc.Type, tc.Input)
     72 
     73 		err = ioutil.WriteFile(tmpFile, b.Bytes(), 0644)
     74 		if err != nil {
     75 			log.Fatal(err)
     76 		}
     77 
     78 		cmd := exec.Command("go", "run", tmpFile)
     79 		var buf bytes.Buffer
     80 		cmd.Stdout = &buf
     81 		cmd.Stderr = &buf
     82 		cmd.Env = os.Environ()
     83 		cmd.Run() // ignore err as we expect a panic
     84 
     85 		out := buf.Bytes()
     86 		panicIdx := bytes.Index(out, []byte("panic: "))
     87 		if panicIdx == -1 {
     88 			log.Fatalf("expected a panic in output for %s, got: %s", tc.Type, out)
     89 		}
     90 		eolIdx := bytes.IndexByte(out[panicIdx:], '\n') + panicIdx
     91 		if panicIdx == -1 {
     92 			log.Fatalf("expected a newline in output for %s after the panic, got: %s", tc.Type, out)
     93 		}
     94 		out = out[0:eolIdx]
     95 		if string(out) != tc.Expect {
     96 			log.Fatalf("expected '%s' for panic(%s(%s)), got %s", tc.Expect, tc.Type, tc.Input, out)
     97 		}
     98 	}
     99 }
    100