mirror of
https://github.com/golang/go
synced 2024-11-05 16:26:11 -07:00
go.tools/cmd/stringer: add end-to-end test that compiles, runs, and verifies the generated method
In the process, fix a bug in one of the method generators. LGTM=gri R=gri CC=golang-codereviews https://golang.org/cl/141130043
This commit is contained in:
parent
d30a33e346
commit
d0448f16e3
99
cmd/stringer/endtoend_test.go
Normal file
99
cmd/stringer/endtoend_test.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// Copyright 2014 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
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This file contains a test that compiles and runs each program in testdata
|
||||||
|
// after generating the string method for its type. The rule is that for testdata/x.go
|
||||||
|
// we run stringer -type X and then compile and run the program. The resulting
|
||||||
|
// binary panics if the String method for X is not correct, including for error cases.
|
||||||
|
|
||||||
|
func TestEndToEnd(t *testing.T) {
|
||||||
|
dir, err := ioutil.TempDir("", "stringer")
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
// Create stringer in temporary directory.
|
||||||
|
stringer := filepath.Join(dir, "stringer")
|
||||||
|
err = run("go", "build", "-o", stringer, "stringer.go")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("building stringer: %s", err)
|
||||||
|
}
|
||||||
|
// Read the testdata directory.
|
||||||
|
fd, err := os.Open("testdata")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
names, err := fd.Readdirnames(-1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Readdirnames: %s", err)
|
||||||
|
}
|
||||||
|
// Generate, compile, and run the test programs.
|
||||||
|
for _, name := range names {
|
||||||
|
if !strings.HasSuffix(name, ".go") {
|
||||||
|
t.Errorf("%s is not a Go file", name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Names are known to be ASCII and long enough.
|
||||||
|
typeName := fmt.Sprintf("%c%s", name[0]+'A'-'a', name[1:len(name)-len(".go")])
|
||||||
|
stringerCompileAndRun(t, dir, stringer, typeName, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// stringerCompileAndRun runs stringer for the named file and compiles and
|
||||||
|
// runs the target binary in directory dir. That binary will panic if the String method is incorrect.
|
||||||
|
func stringerCompileAndRun(t *testing.T, dir, stringer, typeName, fileName string) {
|
||||||
|
t.Logf("run: %s %s\n", fileName, typeName)
|
||||||
|
source := filepath.Join(dir, fileName)
|
||||||
|
err := copy(source, filepath.Join("testdata", fileName))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("copying file to temporary directory: %s", err)
|
||||||
|
}
|
||||||
|
stringSource := filepath.Join(dir, typeName+"_string.go")
|
||||||
|
// Run stringer in temporary directory.
|
||||||
|
err = run(stringer, "-type", typeName, "-output", stringSource, source)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// Run the binary in the temporary directory.
|
||||||
|
err = run("go", "run", stringSource, source)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy copies the from file to the to file.
|
||||||
|
func copy(to, from string) error {
|
||||||
|
toFd, err := os.Create(to)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer toFd.Close()
|
||||||
|
fromFd, err := os.Open(from)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fromFd.Close()
|
||||||
|
_, err = io.Copy(toFd, fromFd)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// run runs a single command and returns an error if it does not succeed.
|
||||||
|
// os/exec should have this function, to be honest.
|
||||||
|
func run(name string, arg ...string) error {
|
||||||
|
cmd := exec.Command(name, arg...)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
@ -25,9 +25,9 @@ var golden = []Golden{
|
|||||||
{"day", day_in, day_out},
|
{"day", day_in, day_out},
|
||||||
{"offset", offset_in, offset_out},
|
{"offset", offset_in, offset_out},
|
||||||
{"gap", gap_in, gap_out},
|
{"gap", gap_in, gap_out},
|
||||||
{"neg", neg_in, neg_out},
|
{"num", num_in, num_out},
|
||||||
{"uneg", uneg_in, uneg_out},
|
{"unum", unum_in, unum_out},
|
||||||
{"map", map_in, map_out},
|
{"prime", prime_in, prime_out},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Each example starts with "type XXX [u]int", with a single space separating them.
|
// Each example starts with "type XXX [u]int", with a single space separating them.
|
||||||
@ -95,60 +95,58 @@ func (i Number) String() string {
|
|||||||
`
|
`
|
||||||
|
|
||||||
// Gaps and an offset.
|
// Gaps and an offset.
|
||||||
const gap_in = `type Num int
|
const gap_in = `type Gap int
|
||||||
const (
|
const (
|
||||||
Two Num = 2
|
Two Gap = 2
|
||||||
Three Num = 3
|
Three Gap = 3
|
||||||
Five Num = 5
|
Five Gap = 5
|
||||||
Six Num = 6
|
Six Gap = 6
|
||||||
Seven Num = 7
|
Seven Gap = 7
|
||||||
Eight Num = 8
|
Eight Gap = 8
|
||||||
Nine Num = 9
|
Nine Gap = 9
|
||||||
Eleven Num = 11
|
Eleven Gap = 11
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
const gap_out = `
|
const gap_out = `
|
||||||
const (
|
const (
|
||||||
_Num_name_0 = "TwoThree"
|
_Gap_name_0 = "TwoThree"
|
||||||
_Num_name_1 = "FiveSixSevenEightNine"
|
_Gap_name_1 = "FiveSixSevenEightNine"
|
||||||
_Num_name_2 = "Eleven"
|
_Gap_name_2 = "Eleven"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_Num_index_0 = [...]uint8{3, 8}
|
_Gap_index_0 = [...]uint8{3, 8}
|
||||||
_Num_index_1 = [...]uint8{4, 7, 12, 17, 21}
|
_Gap_index_1 = [...]uint8{4, 7, 12, 17, 21}
|
||||||
_Num_index_2 = [...]uint8{6}
|
_Gap_index_2 = [...]uint8{6}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (i Num) String() string {
|
func (i Gap) String() string {
|
||||||
switch {
|
switch {
|
||||||
case 2 <= i && i < 3:
|
case 2 <= i && i <= 3:
|
||||||
|
i -= 2
|
||||||
lo := uint8(0)
|
lo := uint8(0)
|
||||||
if i > 2 {
|
if i > 0 {
|
||||||
i -= 2
|
lo = _Gap_index_0[i-1]
|
||||||
} else {
|
|
||||||
lo = _Num_index_0[i-1]
|
|
||||||
}
|
}
|
||||||
return _Num_name_0[lo:_Num_index_0[i]]
|
return _Gap_name_0[lo:_Gap_index_0[i]]
|
||||||
case 5 <= i && i < 9:
|
case 5 <= i && i <= 9:
|
||||||
|
i -= 5
|
||||||
lo := uint8(0)
|
lo := uint8(0)
|
||||||
if i > 5 {
|
if i > 0 {
|
||||||
i -= 5
|
lo = _Gap_index_1[i-1]
|
||||||
} else {
|
|
||||||
lo = _Num_index_1[i-1]
|
|
||||||
}
|
}
|
||||||
return _Num_name_1[lo:_Num_index_1[i]]
|
return _Gap_name_1[lo:_Gap_index_1[i]]
|
||||||
case i == 11:
|
case i == 11:
|
||||||
return _Num_name_2
|
return _Gap_name_2
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("Num(%d)", i)
|
return fmt.Sprintf("Gap(%d)", i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
// Signed integers spanning zero.
|
// Signed integers spanning zero.
|
||||||
const neg_in = `type Num int
|
const num_in = `type Num int
|
||||||
const (
|
const (
|
||||||
m_2 Num = -2 + iota
|
m_2 Num = -2 + iota
|
||||||
m_1
|
m_1
|
||||||
@ -158,7 +156,7 @@ const (
|
|||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
const neg_out = `
|
const num_out = `
|
||||||
const _Num_name = "m_2m_1m0m1m2"
|
const _Num_name = "m_2m_1m0m1m2"
|
||||||
|
|
||||||
var _Num_index = [...]uint8{3, 6, 8, 10, 12}
|
var _Num_index = [...]uint8{3, 6, 8, 10, 12}
|
||||||
@ -178,38 +176,55 @@ func (i Num) String() string {
|
|||||||
`
|
`
|
||||||
|
|
||||||
// Unsigned integers spanning zero.
|
// Unsigned integers spanning zero.
|
||||||
const uneg_in = `type UNum uint
|
const unum_in = `type Unum uint
|
||||||
const (
|
const (
|
||||||
m_2 UNum = ^UNum(0)-2
|
m_2 Unum = iota + 253
|
||||||
m_1
|
m_1
|
||||||
m0
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
m0 Unum = iota
|
||||||
m1
|
m1
|
||||||
m2
|
m2
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
const uneg_out = `
|
const unum_out = `
|
||||||
const _UNum_name = "m_2"
|
const (
|
||||||
|
_Unum_name_0 = "m0m1m2"
|
||||||
|
_Unum_name_1 = "m_2m_1"
|
||||||
|
)
|
||||||
|
|
||||||
var _UNum_index = [...]uint8{3}
|
var (
|
||||||
|
_Unum_index_0 = [...]uint8{2, 4, 6}
|
||||||
|
_Unum_index_1 = [...]uint8{3, 6}
|
||||||
|
)
|
||||||
|
|
||||||
func (i UNum) String() string {
|
func (i Unum) String() string {
|
||||||
i -= 18446744073709551613
|
switch {
|
||||||
if i >= UNum(len(_UNum_index)) {
|
case 0 <= i && i <= 2:
|
||||||
return fmt.Sprintf("UNum(%d)", i+18446744073709551613)
|
i -= 0
|
||||||
|
lo := uint8(0)
|
||||||
|
if i > 0 {
|
||||||
|
lo = _Unum_index_0[i-1]
|
||||||
|
}
|
||||||
|
return _Unum_name_0[lo:_Unum_index_0[i]]
|
||||||
|
case 253 <= i && i <= 254:
|
||||||
|
i -= 253
|
||||||
|
lo := uint8(0)
|
||||||
|
if i > 0 {
|
||||||
|
lo = _Unum_index_1[i-1]
|
||||||
|
}
|
||||||
|
return _Unum_name_1[lo:_Unum_index_1[i]]
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("Unum(%d)", i)
|
||||||
}
|
}
|
||||||
hi := _UNum_index[i]
|
|
||||||
lo := uint8(0)
|
|
||||||
if i > 0 {
|
|
||||||
lo = _UNum_index[i-1]
|
|
||||||
}
|
|
||||||
return _UNum_name[lo:hi]
|
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
// Enough gaps to trigger a map implementation of the method.
|
// Enough gaps to trigger a map implementation of the method.
|
||||||
// Also includes a duplicate to test that it doesn't cause problems
|
// Also includes a duplicate to test that it doesn't cause problems
|
||||||
const map_in = `type Prime int
|
const prime_in = `type Prime int
|
||||||
const (
|
const (
|
||||||
p2 Prime = 2
|
p2 Prime = 2
|
||||||
p3 Prime = 3
|
p3 Prime = 3
|
||||||
@ -228,7 +243,7 @@ const (
|
|||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
const map_out = `
|
const prime_out = `
|
||||||
const _Prime_name = "p2p3p5p7p11p13p17p19p23p29p37p41p43"
|
const _Prime_name = "p2p3p5p7p11p13p17p19p23p29p37p41p43"
|
||||||
|
|
||||||
var _Prime_map = map[Prime]string{
|
var _Prime_map = map[Prime]string{
|
||||||
|
@ -103,11 +103,11 @@ func main() {
|
|||||||
log.SetPrefix("stringer: ")
|
log.SetPrefix("stringer: ")
|
||||||
flag.Usage = Usage
|
flag.Usage = Usage
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
types := strings.Split(*typeNames, ",")
|
if len(*typeNames) == 0 {
|
||||||
if len(types) == 0 {
|
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
types := strings.Split(*typeNames, ",")
|
||||||
|
|
||||||
// We accept either one directory or a list of files. Which do we have?
|
// We accept either one directory or a list of files. Which do we have?
|
||||||
args := flag.Args()
|
args := flag.Args()
|
||||||
@ -610,11 +610,10 @@ func (g *Generator) buildMultipleRuns(runs [][]Value, typeName string) {
|
|||||||
g.Printf("\t\treturn _%s_name_%d\n", typeName, i)
|
g.Printf("\t\treturn _%s_name_%d\n", typeName, i)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
g.Printf("\tcase %s <= i && i < %s:\n", &values[0], &values[len(values)-1])
|
g.Printf("\tcase %s <= i && i <= %s:\n", &values[0], &values[len(values)-1])
|
||||||
|
g.Printf("\t\ti -= %s\n", &values[0])
|
||||||
g.Printf("\t\tlo := uint%d(0)\n", usize(len(values)))
|
g.Printf("\t\tlo := uint%d(0)\n", usize(len(values)))
|
||||||
g.Printf("\t\tif i > %s {\n", &values[0])
|
g.Printf("\t\tif i > 0 {\n")
|
||||||
g.Printf("\t\t\ti -= %s\n", &values[0])
|
|
||||||
g.Printf("\t\t} else {\n")
|
|
||||||
g.Printf("\t\t\tlo = _%s_index_%d[i-1]\n", typeName, i)
|
g.Printf("\t\t\tlo = _%s_index_%d[i-1]\n", typeName, i)
|
||||||
g.Printf("\t\t}\n")
|
g.Printf("\t\t}\n")
|
||||||
g.Printf("\t\treturn _%s_name_%d[lo:_%s_index_%d[i]]\n", typeName, i, typeName, i)
|
g.Printf("\t\treturn _%s_name_%d[lo:_%s_index_%d[i]]\n", typeName, i, typeName, i)
|
||||||
|
39
cmd/stringer/testdata/day.go
vendored
Normal file
39
cmd/stringer/testdata/day.go
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
// Simple test: enumeration of type int starting at 0.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Day int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Monday Day = iota
|
||||||
|
Tuesday
|
||||||
|
Wednesday
|
||||||
|
Thursday
|
||||||
|
Friday
|
||||||
|
Saturday
|
||||||
|
Sunday
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ck(Monday, "Monday")
|
||||||
|
ck(Tuesday, "Tuesday")
|
||||||
|
ck(Wednesday, "Wednesday")
|
||||||
|
ck(Thursday, "Thursday")
|
||||||
|
ck(Friday, "Friday")
|
||||||
|
ck(Saturday, "Saturday")
|
||||||
|
ck(Sunday, "Sunday")
|
||||||
|
ck(-127, "Day(-127)")
|
||||||
|
ck(127, "Day(127)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ck(day Day, str string) {
|
||||||
|
if fmt.Sprint(day) != str {
|
||||||
|
panic("day.go: " + str)
|
||||||
|
}
|
||||||
|
}
|
44
cmd/stringer/testdata/gap.go
vendored
Normal file
44
cmd/stringer/testdata/gap.go
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
// Gaps and an offset.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Gap int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Two Gap = 2
|
||||||
|
Three Gap = 3
|
||||||
|
Five Gap = 5
|
||||||
|
Six Gap = 6
|
||||||
|
Seven Gap = 7
|
||||||
|
Eight Gap = 8
|
||||||
|
Nine Gap = 9
|
||||||
|
Eleven Gap = 11
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ck(0, "Gap(0)")
|
||||||
|
ck(1, "Gap(1)")
|
||||||
|
ck(Two, "Two")
|
||||||
|
ck(Three, "Three")
|
||||||
|
ck(4, "Gap(4)")
|
||||||
|
ck(Five, "Five")
|
||||||
|
ck(Six, "Six")
|
||||||
|
ck(Seven, "Seven")
|
||||||
|
ck(Eight, "Eight")
|
||||||
|
ck(Nine, "Nine")
|
||||||
|
ck(10, "Gap(10)")
|
||||||
|
ck(Eleven, "Eleven")
|
||||||
|
ck(12, "Gap(12)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ck(gap Gap, str string) {
|
||||||
|
if fmt.Sprint(gap) != str {
|
||||||
|
panic("gap.go: " + str)
|
||||||
|
}
|
||||||
|
}
|
35
cmd/stringer/testdata/num.go
vendored
Normal file
35
cmd/stringer/testdata/num.go
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
// Signed integers spanning zero.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Num int
|
||||||
|
|
||||||
|
const (
|
||||||
|
m_2 Num = -2 + iota
|
||||||
|
m_1
|
||||||
|
m0
|
||||||
|
m1
|
||||||
|
m2
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ck(-3, "Num(-3)")
|
||||||
|
ck(m_2, "m_2")
|
||||||
|
ck(m_1, "m_1")
|
||||||
|
ck(m0, "m0")
|
||||||
|
ck(m1, "m1")
|
||||||
|
ck(m2, "m2")
|
||||||
|
ck(3, "Num(3)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ck(num Num, str string) {
|
||||||
|
if fmt.Sprint(num) != str {
|
||||||
|
panic("num.go: " + str)
|
||||||
|
}
|
||||||
|
}
|
34
cmd/stringer/testdata/number.go
vendored
Normal file
34
cmd/stringer/testdata/number.go
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
// Enumeration with an offset.
|
||||||
|
// Also includes a duplicate.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Number int
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ Number = iota
|
||||||
|
One
|
||||||
|
Two
|
||||||
|
Three
|
||||||
|
AnotherOne = One // Duplicate; note that AnotherOne doesn't appear below.
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ck(One, "One")
|
||||||
|
ck(Two, "Two")
|
||||||
|
ck(Three, "Three")
|
||||||
|
ck(AnotherOne, "One")
|
||||||
|
ck(127, "Number(127)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ck(num Number, str string) {
|
||||||
|
if fmt.Sprint(num) != str {
|
||||||
|
panic("number.go: " + str)
|
||||||
|
}
|
||||||
|
}
|
56
cmd/stringer/testdata/prime.go
vendored
Normal file
56
cmd/stringer/testdata/prime.go
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
// Enough gaps to trigger a map implementation of the method.
|
||||||
|
// Also includes a duplicate to test that it doesn't cause problems
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Prime int
|
||||||
|
|
||||||
|
const (
|
||||||
|
p2 Prime = 2
|
||||||
|
p3 Prime = 3
|
||||||
|
p5 Prime = 5
|
||||||
|
p7 Prime = 7
|
||||||
|
p77 Prime = 7 // Duplicate; note that p77 doesn't appear below.
|
||||||
|
p11 Prime = 11
|
||||||
|
p13 Prime = 13
|
||||||
|
p17 Prime = 17
|
||||||
|
p19 Prime = 19
|
||||||
|
p23 Prime = 23
|
||||||
|
p29 Prime = 29
|
||||||
|
p37 Prime = 31
|
||||||
|
p41 Prime = 41
|
||||||
|
p43 Prime = 43
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ck(0, "Prime(0)")
|
||||||
|
ck(1, "Prime(1)")
|
||||||
|
ck(p2, "p2")
|
||||||
|
ck(p3, "p3")
|
||||||
|
ck(4, "Prime(4)")
|
||||||
|
ck(p5, "p5")
|
||||||
|
ck(p7, "p7")
|
||||||
|
ck(p77, "p7")
|
||||||
|
ck(p11, "p11")
|
||||||
|
ck(p13, "p13")
|
||||||
|
ck(p17, "p17")
|
||||||
|
ck(p19, "p19")
|
||||||
|
ck(p23, "p23")
|
||||||
|
ck(p29, "p29")
|
||||||
|
ck(p37, "p37")
|
||||||
|
ck(p41, "p41")
|
||||||
|
ck(p43, "p43")
|
||||||
|
ck(44, "Prime(44)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ck(prime Prime, str string) {
|
||||||
|
if fmt.Sprint(prime) != str {
|
||||||
|
panic("prime.go: " + str)
|
||||||
|
}
|
||||||
|
}
|
38
cmd/stringer/testdata/unum.go
vendored
Normal file
38
cmd/stringer/testdata/unum.go
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2014 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.
|
||||||
|
|
||||||
|
// Unsigned integers spanning zero.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type Unum uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
m_2 Unum = iota + 253
|
||||||
|
m_1
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
m0 Unum = iota
|
||||||
|
m1
|
||||||
|
m2
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ck(^Unum(0)-3, "Unum(252)")
|
||||||
|
ck(m_2, "m_2")
|
||||||
|
ck(m_1, "m_1")
|
||||||
|
ck(m0, "m0")
|
||||||
|
ck(m1, "m1")
|
||||||
|
ck(m2, "m2")
|
||||||
|
ck(3, "Unum(3)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ck(unum Unum, str string) {
|
||||||
|
if fmt.Sprint(unum) != str {
|
||||||
|
panic("unum.go: " + str)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user