mirror of
https://github.com/golang/go
synced 2024-11-18 15:34:53 -07:00
65b5a8eca7
This peculiar case arose in range statements but there are other contexts and one turned up in the auto-generated translation of the compiler. Take care of it always. for i := 0; i < 0; func() {i++; q=q.Link}() { ... } That code has been given the obvious rewrite but we should still handle it. Odd but easy to fix (tricky to test). Fixes #10269. Change-Id: I66e1404eb24da15a24be7f67403e19ed66fba0a7 Reviewed-on: https://go-review.googlesource.com/8284 Reviewed-by: Robert Griesemer <gri@golang.org>
219 lines
3.8 KiB
Go
219 lines
3.8 KiB
Go
// 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.
|
|
|
|
// This program is processed by the cover command, and then testAll is called.
|
|
// The test driver in main.go can then compare the coverage statistics with expectation.
|
|
|
|
// The word LINE is replaced by the line number in this file. When the file is executed,
|
|
// the coverage processing has changed the line numbers, so we can't use runtime.Caller.
|
|
|
|
package main
|
|
|
|
const anything = 1e9 // Just some unlikely value that means "we got here, don't care how often"
|
|
|
|
func testAll() {
|
|
testSimple()
|
|
testBlockRun()
|
|
testIf()
|
|
testFor()
|
|
testRange()
|
|
testSwitch()
|
|
testTypeSwitch()
|
|
testSelect1()
|
|
testSelect2()
|
|
testPanic()
|
|
testEmptySwitches()
|
|
}
|
|
|
|
// The indexes of the counters in testPanic are known to main.go
|
|
const panicIndex = 3
|
|
|
|
// This test appears first because the index of its counters is known to main.go
|
|
func testPanic() {
|
|
defer func() {
|
|
recover()
|
|
}()
|
|
check(LINE, 1)
|
|
panic("should not get next line")
|
|
check(LINE, 0) // this is GoCover.Count[panicIndex]
|
|
// The next counter is in testSimple and it will be non-zero.
|
|
// If the panic above does not trigger a counter, the test will fail
|
|
// because GoCover.Count[panicIndex] will be the one in testSimple.
|
|
}
|
|
|
|
func testSimple() {
|
|
check(LINE, 1)
|
|
}
|
|
|
|
func testIf() {
|
|
if true {
|
|
check(LINE, 1)
|
|
} else {
|
|
check(LINE, 0)
|
|
}
|
|
if false {
|
|
check(LINE, 0)
|
|
} else {
|
|
check(LINE, 1)
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
if checkVal(LINE, 3, i) <= 2 {
|
|
check(LINE, 3)
|
|
}
|
|
if checkVal(LINE, 3, i) <= 1 {
|
|
check(LINE, 2)
|
|
}
|
|
if checkVal(LINE, 3, i) <= 0 {
|
|
check(LINE, 1)
|
|
}
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
if checkVal(LINE, 3, i) <= 1 {
|
|
check(LINE, 2)
|
|
} else {
|
|
check(LINE, 1)
|
|
}
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
if checkVal(LINE, 3, i) <= 0 {
|
|
check(LINE, 1)
|
|
} else if checkVal(LINE, 2, i) <= 1 {
|
|
check(LINE, 1)
|
|
} else if checkVal(LINE, 1, i) <= 2 {
|
|
check(LINE, 1)
|
|
} else if checkVal(LINE, 0, i) <= 3 {
|
|
check(LINE, 0)
|
|
}
|
|
}
|
|
if func(a, b int) bool { return a < b }(3, 4) {
|
|
check(LINE, 1)
|
|
}
|
|
}
|
|
|
|
func testFor() {
|
|
for i := 0; i < 10; func() { i++; check(LINE, 10) }() {
|
|
check(LINE, 10)
|
|
}
|
|
}
|
|
|
|
func testRange() {
|
|
for _, f := range []func(){
|
|
func() { check(LINE, 1) },
|
|
} {
|
|
f()
|
|
check(LINE, 1)
|
|
}
|
|
}
|
|
|
|
func testBlockRun() {
|
|
check(LINE, 1)
|
|
{
|
|
check(LINE, 1)
|
|
}
|
|
{
|
|
check(LINE, 1)
|
|
}
|
|
check(LINE, 1)
|
|
{
|
|
check(LINE, 1)
|
|
}
|
|
{
|
|
check(LINE, 1)
|
|
}
|
|
check(LINE, 1)
|
|
}
|
|
|
|
func testSwitch() {
|
|
for i := 0; i < 5; func() { i++; check(LINE, 5) }() {
|
|
switch i {
|
|
case 0:
|
|
check(LINE, 1)
|
|
case 1:
|
|
check(LINE, 1)
|
|
case 2:
|
|
check(LINE, 1)
|
|
default:
|
|
check(LINE, 2)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testTypeSwitch() {
|
|
var x = []interface{}{1, 2.0, "hi"}
|
|
for _, v := range x {
|
|
switch func() { check(LINE, 3) }(); v.(type) {
|
|
case int:
|
|
check(LINE, 1)
|
|
case float64:
|
|
check(LINE, 1)
|
|
case string:
|
|
check(LINE, 1)
|
|
case complex128:
|
|
check(LINE, 0)
|
|
default:
|
|
check(LINE, 0)
|
|
}
|
|
}
|
|
}
|
|
|
|
func testSelect1() {
|
|
c := make(chan int)
|
|
go func() {
|
|
for i := 0; i < 1000; i++ {
|
|
c <- i
|
|
}
|
|
}()
|
|
for {
|
|
select {
|
|
case <-c:
|
|
check(LINE, anything)
|
|
case <-c:
|
|
check(LINE, anything)
|
|
default:
|
|
check(LINE, 1)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func testSelect2() {
|
|
c1 := make(chan int, 1000)
|
|
c2 := make(chan int, 1000)
|
|
for i := 0; i < 1000; i++ {
|
|
c1 <- i
|
|
c2 <- i
|
|
}
|
|
for {
|
|
select {
|
|
case <-c1:
|
|
check(LINE, 1000)
|
|
case <-c2:
|
|
check(LINE, 1000)
|
|
default:
|
|
check(LINE, 1)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// Empty control statements created syntax errors. This function
|
|
// is here just to be sure that those are handled correctly now.
|
|
func testEmptySwitches() {
|
|
check(LINE, 1)
|
|
switch 3 {
|
|
}
|
|
check(LINE, 1)
|
|
switch i := (interface{})(3).(int); i {
|
|
}
|
|
check(LINE, 1)
|
|
c := make(chan int)
|
|
go func() {
|
|
check(LINE, 1)
|
|
c <- 1
|
|
select {}
|
|
}()
|
|
<-c
|
|
check(LINE, 1)
|
|
}
|