| // 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 |
| |
| import _ "unsafe" // for go:linkname |
| |
| //go:linkname some_name some_name |
| |
| 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() |
| testFunctionLiteral() |
| testGoto() |
| } |
| |
| // 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) }() { |
| goto label2 |
| label1: |
| goto label1 |
| label2: |
| 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) |
| } |
| |
| func testFunctionLiteral() { |
| a := func(f func()) error { |
| f() |
| f() |
| return nil |
| } |
| |
| b := func(f func()) bool { |
| f() |
| f() |
| return true |
| } |
| |
| check(LINE, 1) |
| a(func() { |
| check(LINE, 2) |
| }) |
| |
| if err := a(func() { |
| check(LINE, 2) |
| }); err != nil { |
| } |
| |
| switch b(func() { |
| check(LINE, 2) |
| }) { |
| } |
| |
| x := 2 |
| switch x { |
| case func() int { check(LINE, 1); return 1 }(): |
| check(LINE, 0) |
| panic("2=1") |
| case func() int { check(LINE, 1); return 2 }(): |
| check(LINE, 1) |
| case func() int { check(LINE, 0); return 3 }(): |
| check(LINE, 0) |
| panic("2=3") |
| } |
| } |
| |
| func testGoto() { |
| for i := 0; i < 2; i++ { |
| if i == 0 { |
| goto Label |
| } |
| check(LINE, 1) |
| Label: |
| check(LINE, 2) |
| } |
| // Now test that we don't inject empty statements |
| // between a label and a loop. |
| loop: |
| for { |
| check(LINE, 1) |
| break loop |
| } |
| } |
| |
| // This comment didn't appear in generated go code. |
| func haha() { |
| // Needed for cover to add counter increment here. |
| _ = 42 |
| } |
| |
| // Some someFunction. |
| // |
| //go:nosplit |
| func someFunction() { |
| } |