1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// This program is processed by the cover command, and then testAll is called.
6// The test driver in main.go can then compare the coverage statistics with expectation.
7
8// The word LINE is replaced by the line number in this file. When the file is executed,
9// the coverage processing has changed the line numbers, so we can't use runtime.Caller.
10
11package main
12
13const anything = 1e9 // Just some unlikely value that means "we got here, don't care how often"
14
15func testAll() {
16	testSimple()
17	testBlockRun()
18	testIf()
19	testFor()
20	testRange()
21	testSwitch()
22	testTypeSwitch()
23	testSelect1()
24	testSelect2()
25	testPanic()
26	testEmptySwitches()
27}
28
29// The indexes of the counters in testPanic are known to main.go
30const panicIndex = 3
31
32// This test appears first because the index of its counters is known to main.go
33func testPanic() {
34	defer func() {
35		recover()
36	}()
37	check(LINE, 1)
38	panic("should not get next line")
39	check(LINE, 0) // this is GoCover.Count[panicIndex]
40	// The next counter is in testSimple and it will be non-zero.
41	// If the panic above does not trigger a counter, the test will fail
42	// because GoCover.Count[panicIndex] will be the one in testSimple.
43}
44
45func testSimple() {
46	check(LINE, 1)
47}
48
49func testIf() {
50	if true {
51		check(LINE, 1)
52	} else {
53		check(LINE, 0)
54	}
55	if false {
56		check(LINE, 0)
57	} else {
58		check(LINE, 1)
59	}
60	for i := 0; i < 3; i++ {
61		if checkVal(LINE, 3, i) <= 2 {
62			check(LINE, 3)
63		}
64		if checkVal(LINE, 3, i) <= 1 {
65			check(LINE, 2)
66		}
67		if checkVal(LINE, 3, i) <= 0 {
68			check(LINE, 1)
69		}
70	}
71	for i := 0; i < 3; i++ {
72		if checkVal(LINE, 3, i) <= 1 {
73			check(LINE, 2)
74		} else {
75			check(LINE, 1)
76		}
77	}
78	for i := 0; i < 3; i++ {
79		if checkVal(LINE, 3, i) <= 0 {
80			check(LINE, 1)
81		} else if checkVal(LINE, 2, i) <= 1 {
82			check(LINE, 1)
83		} else if checkVal(LINE, 1, i) <= 2 {
84			check(LINE, 1)
85		} else if checkVal(LINE, 0, i) <= 3 {
86			check(LINE, 0)
87		}
88	}
89	if func(a, b int) bool { return a < b }(3, 4) {
90		check(LINE, 1)
91	}
92}
93
94func testFor() {
95	for i := 0; i < 10; func() { i++; check(LINE, 10) }() {
96		check(LINE, 10)
97	}
98}
99
100func testRange() {
101	for _, f := range []func(){
102		func() { check(LINE, 1) },
103	} {
104		f()
105		check(LINE, 1)
106	}
107}
108
109func testBlockRun() {
110	check(LINE, 1)
111	{
112		check(LINE, 1)
113	}
114	{
115		check(LINE, 1)
116	}
117	check(LINE, 1)
118	{
119		check(LINE, 1)
120	}
121	{
122		check(LINE, 1)
123	}
124	check(LINE, 1)
125}
126
127func testSwitch() {
128	for i := 0; i < 5; func() { i++; check(LINE, 5) }() {
129		switch i {
130		case 0:
131			check(LINE, 1)
132		case 1:
133			check(LINE, 1)
134		case 2:
135			check(LINE, 1)
136		default:
137			check(LINE, 2)
138		}
139	}
140}
141
142func testTypeSwitch() {
143	var x = []interface{}{1, 2.0, "hi"}
144	for _, v := range x {
145		switch func() { check(LINE, 3) }(); v.(type) {
146		case int:
147			check(LINE, 1)
148		case float64:
149			check(LINE, 1)
150		case string:
151			check(LINE, 1)
152		case complex128:
153			check(LINE, 0)
154		default:
155			check(LINE, 0)
156		}
157	}
158}
159
160func testSelect1() {
161	c := make(chan int)
162	go func() {
163		for i := 0; i < 1000; i++ {
164			c <- i
165		}
166	}()
167	for {
168		select {
169		case <-c:
170			check(LINE, anything)
171		case <-c:
172			check(LINE, anything)
173		default:
174			check(LINE, 1)
175			return
176		}
177	}
178}
179
180func testSelect2() {
181	c1 := make(chan int, 1000)
182	c2 := make(chan int, 1000)
183	for i := 0; i < 1000; i++ {
184		c1 <- i
185		c2 <- i
186	}
187	for {
188		select {
189		case <-c1:
190			check(LINE, 1000)
191		case <-c2:
192			check(LINE, 1000)
193		default:
194			check(LINE, 1)
195			return
196		}
197	}
198}
199
200// Empty control statements created syntax errors. This function
201// is here just to be sure that those are handled correctly now.
202func testEmptySwitches() {
203	check(LINE, 1)
204	switch 3 {
205	}
206	check(LINE, 1)
207	switch i := (interface{})(3).(int); i {
208	}
209	check(LINE, 1)
210	c := make(chan int)
211	go func() {
212		check(LINE, 1)
213		c <- 1
214		select {}
215	}()
216	<-c
217	check(LINE, 1)
218}
219