...
Run Format

Source file src/cmd/cover/testdata/test.go

Documentation: cmd/cover/testdata

  // 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) }() {
  		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 shouldn't appear in generated go code.
  func haha() {
  	// Needed for cover to add counter increment here.
  	_ = 42
  }
  
  // Some someFunction.
  //
  //go:nosplit
  func someFunction() {
  }
  

View as plain text