// Code generated by testifylint/internal/testgen. DO NOT EDIT.

package gorequire

import (
	"fmt"
	"sync"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/stretchr/testify/suite"
)

func TestGoRequireChecker_Smoke(t *testing.T) {
	var err error
	var b bool

	run()
	assertSomething(t)
	requireSomething(t)

	assert.Fail(t, "boom!")
	assert.Failf(t, "boom!", "msg with args %d %s", 42, "42")
	assert.FailNow(t, "boom!")
	assert.FailNowf(t, "boom!", "msg with args %d %s", 42, "42")
	assert.NoError(t, err)
	assert.NoErrorf(t, err, "msg with args %d %s", 42, "42")
	assert.True(t, b)
	assert.Truef(t, b, "msg with args %d %s", 42, "42")

	require.Fail(t, "boom!")
	require.Failf(t, "boom!", "msg with args %d %s", 42, "42")
	require.FailNow(t, "boom!")
	require.FailNowf(t, "boom!", "msg with args %d %s", 42, "42")
	require.NoError(t, err)
	require.NoErrorf(t, err, "msg with args %d %s", 42, "42")
	require.True(t, b)
	require.Truef(t, b, "msg with args %d %s", 42, "42")

	var wg sync.WaitGroup
	defer wg.Wait()

	for i := 0; i < 2; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()

			run()
			assertSomething(t)
			requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"

			assert.Fail(t, "boom!")
			assert.Failf(t, "boom!", "msg with args %d %s", 42, "42")
			assert.FailNow(t, "boom!")                                   // want "go-require: assert\\.FailNow must only be used in the goroutine running the test function"
			assert.FailNowf(t, "boom!", "msg with args %d %s", 42, "42") // want "go-require: assert\\.FailNowf must only be used in the goroutine running the test function"
			assert.NoError(t, err)
			assert.NoErrorf(t, err, "msg with args %d %s", 42, "42")
			assert.True(t, b)
			assert.Truef(t, b, "msg with args %d %s", 42, "42")

			require.Fail(t, "boom!")                                      // want "go-require: require must only be used in the goroutine running the test function"
			require.Failf(t, "boom!", "msg with args %d %s", 42, "42")    // want "go-require: require must only be used in the goroutine running the test function"
			require.FailNow(t, "boom!")                                   // want "go-require: require must only be used in the goroutine running the test function"
			require.FailNowf(t, "boom!", "msg with args %d %s", 42, "42") // want "go-require: require must only be used in the goroutine running the test function"
			require.NoError(t, err)                                       // want "go-require: require must only be used in the goroutine running the test function"
			require.NoErrorf(t, err, "msg with args %d %s", 42, "42")     // want "go-require: require must only be used in the goroutine running the test function"
			require.True(t, b)                                            // want "go-require: require must only be used in the goroutine running the test function"
			require.Truef(t, b, "msg with args %d %s", 42, "42")          // want "go-require: require must only be used in the goroutine running the test function"

			if assert.Error(t, err) {
				assert.FailNow(t, "boom!")                                   // want "go-require: assert\\.FailNow must only be used in the goroutine running the test function"
				assert.FailNowf(t, "boom!", "msg with args %d %s", 42, "42") // want "go-require: assert\\.FailNowf must only be used in the goroutine running the test function"
			}
		}(i)
	}
}

func TestGoRequireChecker(t *testing.T) {
	defer func() {
		run()
		assertSomething(t)
		requireSomething(t)
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!")

		func() {
			run()
			assertSomething(t)
			requireSomething(t)
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!")
		}()
	}()

	defer func() {
		go func() {

			run()
			assertSomething(t)
			requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
		}()
	}()

	defer run()
	defer assertSomething(t)
	defer requireSomething(t)

	t.Cleanup(func() {
		run()
		assertSomething(t)
		requireSomething(t)
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!")

		func() {
			run()
			assertSomething(t)
			requireSomething(t)
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!")
		}()

		go func() {
			run()
			assertSomething(t)
			requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"

			func() {
				func(t *testing.T) {
					run()
					assertSomething(t)
					requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
					assert.Fail(t, "boom!")
					require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
				}(t)
			}()
		}()
	})

	func() {
		func() {
			func() {
				func() {
					run()
					assertSomething(t)
					requireSomething(t)
					assert.Fail(t, "boom!")
					require.Fail(t, "boom!")
				}()

				func(t *testing.T) {
					run()
					assertSomething(t)
					requireSomething(t)
					assert.Fail(t, "boom!")
					require.Fail(t, "boom!")

					t.Run("", func(t *testing.T) {
						run()
						assertSomething(t)
						requireSomething(t)
						assert.Fail(t, "boom!")
						require.Fail(t, "boom!")

						go func() {
							run()
							assertSomething(t)
							requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
							assert.Fail(t, "boom!")
							require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
						}()
					})
				}(t)

				go func() {
					run()
					assertSomething(t)
					requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
					assert.Fail(t, "boom!")
					require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
				}()
			}()
		}()
	}()

	if false {
		run()
		assertSomething(t)
		requireSomething(t)
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!")
	}

	go func() {
		run()
		assertSomething(t)
		requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"

		go func() {
			run()
			assertSomething(t)
			requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"

			go func() {
				run()
				assertSomething(t)
				requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
				assert.Fail(t, "boom!")
				require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"

				t.Run("", func(t *testing.T) {
					run()
					assertSomething(t)
					requireSomething(t)
					assert.Fail(t, "boom!")
					require.Fail(t, "boom!")
				})

				run()
				assertSomething(t)
				requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
				assert.Fail(t, "boom!")
				require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
			}()

			run()
			assertSomething(t)
			requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
		}()

		run()
		assertSomething(t)
		requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
	}()

	t.Run("", func(t *testing.T) {
		run()
		assertSomething(t)
		requireSomething(t)
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!")

		t.Run("", func(t *testing.T) {
			run()
			assertSomething(t)
			requireSomething(t)
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!")

			t.Run("", func(t *testing.T) {
				run()
				assertSomething(t)
				requireSomething(t)
				assert.Fail(t, "boom!")
				require.Fail(t, "boom!")

				go func() {
					run()
					assertSomething(t)
					requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
					assert.Fail(t, "boom!")
					require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"

					go func() {
						go genericHelper[*testing.T](t)           // want "go-require: genericHelper\\[\\*testing\\.T\\] contains assertions that must only be used in the goroutine running the test function"
						go superGenericHelper[*testing.T, int](t) // want "go-require: superGenericHelper\\[\\*testing\\.T, int\\] contains assertions that must only be used in the goroutine running the test function"
					}()
				}()

				run()
				assertSomething(t)
				requireSomething(t)
				assert.Fail(t, "boom!")
				require.Fail(t, "boom!")
			})

			run()
			assertSomething(t)
			requireSomething(t)
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!")
		})

		run()
		assertSomething(t)
		requireSomething(t)
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!")
	})

	go func() {
		run()
		assertSomething(t)
		requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"

		t.Run("", func(t *testing.T) {
			run()
			assertSomething(t)
			requireSomething(t)
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!")

			go func(t *testing.T) {
				run()
				assertSomething(t)
				requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
				assert.Fail(t, "boom!")
				require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"

				t.Run("", func(t *testing.T) {
					run()
					assertSomething(t)
					requireSomething(t)
					assert.Fail(t, "boom!")
					require.Fail(t, "boom!")
				})

				if true {
					run()
					assertSomething(t)
					requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
					assert.Fail(t, "boom!")
					require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
				}
			}(t)

			run()
			assertSomething(t)
			requireSomething(t)
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!")
		})

		run()
		assertSomething(t)
		requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
	}()

	cases := []struct{}{}
	for _, tt := range cases {
		tt := tt
		t.Run("", func(t *testing.T) {
			run()
			assertSomething(t)
			requireSomething(t)
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!")

			go func() {
				run()
				assertSomething(t)
				requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
				assert.Fail(t, "boom!")
				require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
				_ = tt
			}()
		})
	}

	run()
	assertSomething(t)
	requireSomething(t)

	go run()
	go assertSomething(t)
	go requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"

	go func() {
		run()
	}()
	go func() {
		assertSomething(t)
	}()
	go func() {
		requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
	}()

	var err error
	var b bool

	go assert.Fail(t, "boom!")
	go assert.FailNow(t, "boom!") // want "go-require: assert\\.FailNow must only be used in the goroutine running the test function"
	go assert.NoError(t, err)
	go assert.True(t, b)

	go require.Fail(t, "boom!")    // want "go-require: require must only be used in the goroutine running the test function"
	go require.FailNow(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
	go require.NoError(t, err)     // want "go-require: require must only be used in the goroutine running the test function"
	go require.True(t, b)          // want "go-require: require must only be used in the goroutine running the test function"

	go requireSomethingInGo(t)
	go func() {
		requireSomethingInGo(t)
	}()

	go proxy(t) // want "go-require: proxy contains assertions that must only be used in the goroutine running the test function"
	go func() {
		proxy(t) // want "go-require: proxy contains assertions that must only be used in the goroutine running the test function"
	}()

	t.Run("", assertSomething)
	t.Run("", requireSomething)

	go t.Run("", assertSomething)
	go t.Run("", requireSomething)

	var wg sync.WaitGroup
	wg.Add(2)
	for i := 1; i <= 2; i++ {
		i := i
		go t.Run(fmt.Sprintf("uncaught-%d", i), func(t *testing.T) {
			defer wg.Done()
			run()
			assertSomething(t)
			requireSomething(t)
			assert.Fail(t, "boom!")
			require.Fail(t, "boom!")
		})
	}
	wg.Wait()

	genericHelper(t)
	genericHelper[*testing.T](t)
	superGenericHelper[*testing.T, int](t)

	go func() {
		genericHelper(t)                       // want "go-require: genericHelper contains assertions that must only be used in the goroutine running the test function"
		genericHelper[*testing.T](t)           // want "go-require: genericHelper\\[\\*testing\\.T\\] contains assertions that must only be used in the goroutine running the test function"
		superGenericHelper[*testing.T, int](t) // want "go-require: superGenericHelper\\[\\*testing\\.T, int\\] contains assertions that must only be used in the goroutine running the test function"
	}()
}

type GoRequireCheckerSuite struct {
	suite.Suite
}

func TestGoRequireCheckerSuite(t *testing.T) {
	suite.Run(t, new(GoRequireCheckerSuite))
}

func (s *GoRequireCheckerSuite) TestAll() {
	run()
	assertSomething(s.T())
	requireSomething(s.T())
	s.suiteHelper()
	s.Fail("boom!")
	s.Require().Fail("boom!")

	go func() {
		run()
		assertSomething(s.T())
		requireSomething(s.T()) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
		s.suiteHelper()         // want "go-require: s.suiteHelper contains assertions that must only be used in the goroutine running the test function"
		s.Fail("boom!")
		s.Require().Fail("boom!") // want "go-require: require must only be used in the goroutine running the test function"

		s.Run("", func() {
			run()
			assertSomething(s.T())
			requireSomething(s.T())
			s.suiteHelper()
			s.Fail("boom!")
			s.Require().Fail("boom!")

			go func(t *testing.T) {
				run()
				assertSomething(t)
				requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
				assert.Fail(t, "boom!")
				require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"

				s.T().Run("", func(t *testing.T) {
					run()
					assertSomething(t)
					requireSomething(t)
					assert.Fail(t, "boom!")
					require.Fail(t, "boom!")
				})

				if true {
					run()
					assertSomething(t)
					requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
					assert.Fail(t, "boom!")
					require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
				}
			}(s.T())

			run()
			assertSomething(s.T())
			requireSomething(s.T())
			s.suiteHelper()
			s.Fail("boom!")
			s.Require().Fail("boom!")
		})

		run()
		assertSomething(s.T())
		requireSomething(s.T()) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
		s.suiteHelper()         // want "go-require: s.suiteHelper contains assertions that must only be used in the goroutine running the test function"
		s.Fail("boom!")
		s.Require().Fail("boom!") // want "go-require: require must only be used in the goroutine running the test function"
	}()

	run()
	assertSomething(s.T())
	requireSomething(s.T())
	s.suiteHelper()
	s.Fail("boom!")
	s.Require().Fail("boom!")

	go run()
	go assertSomething(s.T())
	go requireSomething(s.T()) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
	go s.suiteHelper()         // want "go-require: s.suiteHelper contains assertions that must only be used in the goroutine running the test function"

	s.Run("", s.suiteHelper)
	s.T().Run("", func(t *testing.T) { requireSomething(t) })

	go s.T().Run("", requireSomething)
	go s.Run("", s.suiteHelper)
}

func (s *GoRequireCheckerSuite) TestAsertFailNow() {
	var err error
	var b bool

	s.Fail("boom!")
	s.Failf("boom!", "msg with args %d %s", 42, "42")
	s.Assert().Fail("boom!")
	s.Assert().Failf("boom!", "msg with args %d %s", 42, "42")
	s.FailNow("boom!")
	s.FailNowf("boom!", "msg with args %d %s", 42, "42")
	s.Assert().FailNow("boom!")
	s.Assert().FailNowf("boom!", "msg with args %d %s", 42, "42")
	s.NoError(err)
	s.NoErrorf(err, "msg with args %d %s", 42, "42")
	s.Assert().NoError(err)
	s.Assert().NoErrorf(err, "msg with args %d %s", 42, "42")
	s.True(b)
	s.Truef(b, "msg with args %d %s", 42, "42")
	s.Assert().True(b)
	s.Assert().Truef(b, "msg with args %d %s", 42, "42")

	go func() {
		s.Fail("boom!")
		s.Failf("boom!", "msg with args %d %s", 42, "42")
		s.Assert().Fail("boom!")
		s.Assert().Failf("boom!", "msg with args %d %s", 42, "42")
		s.FailNow("boom!")                                            // want "go-require: s\\.FailNow must only be used in the goroutine running the test function"
		s.FailNowf("boom!", "msg with args %d %s", 42, "42")          // want "go-require: s\\.FailNowf must only be used in the goroutine running the test function"
		s.Assert().FailNow("boom!")                                   // want "go-require: s\\.Assert\\(\\)\\.FailNow must only be used in the goroutine running the test function"
		s.Assert().FailNowf("boom!", "msg with args %d %s", 42, "42") // want "go-require: s\\.Assert\\(\\)\\.FailNowf must only be used in the goroutine running the test function"
		s.NoError(err)
		s.NoErrorf(err, "msg with args %d %s", 42, "42")
		s.Assert().NoError(err)
		s.Assert().NoErrorf(err, "msg with args %d %s", 42, "42")
		s.True(b)
		s.Truef(b, "msg with args %d %s", 42, "42")
		s.Assert().True(b)
		s.Assert().Truef(b, "msg with args %d %s", 42, "42")
	}()
}

func (s *GoRequireCheckerSuite) suiteHelper() {
	s.T().Helper()

	run()
	assertSomething(s.T())
	requireSomething(s.T())
	s.suiteHelper()
	s.Fail("boom!")
	s.Require().Fail("boom!")

	go func() {
		run()
		assertSomething(s.T())
		requireSomething(s.T()) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
		s.suiteHelper()         // want "go-require: s.suiteHelper contains assertions that must only be used in the goroutine running the test function"
		s.Fail("boom!")
		s.Require().Fail("boom!") // want "go-require: require must only be used in the goroutine running the test function"
	}()

	run()
	assertSomething(s.T())
	requireSomething(s.T())
	s.suiteHelper()
	s.Fail("boom!")
	s.Require().Fail("boom!")
}

func run() {}

func assertSomething(t *testing.T) {
	t.Helper()

	assert.NoError(t, nil)
	assert.Error(t, nil)
	assert.True(t, false)
}

func proxy(t *testing.T) {
	requireSomething(t)
}

func requireSomething(t *testing.T) {
	t.Helper()

	run()
	assertSomething(t)
	requireSomething(t)
	assert.Fail(t, "boom!")
	require.Fail(t, "boom!")
}

func requireSomethingInGo(t *testing.T) {
	go func() {
		run()
		assertSomething(t)
		requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
	}()
}

func helperNotUsedInGoroutine(t *testing.T) {
	t.Helper()

	run()
	assertSomething(t)
	requireSomething(t)
	assert.Fail(t, "boom!")
	require.Fail(t, "boom!")

	go func() {
		run()
		assertSomething(t)
		requireSomething(t) // want "go-require: requireSomething contains assertions that must only be used in the goroutine running the test function"
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
	}()
}

type testingT interface {
	require.TestingT
}

func genericHelper[T testingT](t T) {
	run()

	assert.Fail(t, "boom!")
	require.Fail(t, "boom!")

	go func() {
		assert.Fail(t, "boom!")
		require.Fail(t, "boom!") // want "go-require: require must only be used in the goroutine running the test function"
	}()
}

func superGenericHelper[T testingT, T2 any](t T) T2 {
	require.Fail(t, "boom!")
	var zero T2
	return zero
}
