// Copyright (c) The EfficientGo Authors.
// Licensed under the Apache License 2.0.

package testutil

import (
	
)

// TB represents union of test and benchmark.
// This allows the same test suite to be run by both benchmark and test, helping to reuse more code.
// The reason is that usually benchmarks are not being run on CI, especially for short tests, so you need to recreate
// usually similar tests for `Test<Name>(t *testing.T)` methods. Example of usage is presented here:
//
//	 func TestTestOrBench(t *testing.T) {
//		tb := NewTB(t)
//		tb.Run("1", func(tb TB) { testorbenchComplexTest(tb) })
//		tb.Run("2", func(tb TB) { testorbenchComplexTest(tb) })
//	}
//
//	func BenchmarkTestOrBench(b *testing.B) {
//		tb := NewTB(t)
//		tb.Run("1", func(tb TB) { testorbenchComplexTest(tb) })
//		tb.Run("2", func(tb TB) { testorbenchComplexTest(tb) })
//	}
type TB interface {
	testing.TB
	IsBenchmark() bool
	Run(name string, f func(t TB)) bool

	SetBytes(n int64)
	N() int
	ResetTimer()
}

// tb implements TB as well as testing.TB interfaces.
type tb struct {
	testing.TB
}

// NewTB creates tb from testing.TB.
func ( testing.TB) TB { return &tb{TB: } }

// Run benchmarks/tests f as a subbenchmark/subtest with the given name. It reports
// whether there were any failures.
//
// A subbenchmark/subtest is like any other benchmark/test.
func ( *tb) ( string,  func( TB)) bool {
	if ,  := .TB.(*testing.B);  {
		return .Run(, func( *testing.B) { (&tb{TB: }) })
	}
	if ,  := .TB.(*testing.T);  {
		return .Run(, func( *testing.T) { (&tb{TB: }) })
	}
	panic("not a benchmark and not a test")
}

// N returns number of iterations to do for benchmark, 1 in case of test.
func ( *tb) () int {
	if ,  := .TB.(*testing.B);  {
		return .N
	}
	return 1
}

// SetBytes records the number of bytes processed in a single operation for benchmark, noop otherwise.
// If this is called, the benchmark will report ns/op and MB/s.
func ( *tb) ( int64) {
	if ,  := .TB.(*testing.B);  {
		.SetBytes()
	}
}

// ResetTimer resets a timer, if it's a benchmark, noop otherwise.
func ( *tb) () {
	if ,  := .TB.(*testing.B);  {
		.ResetTimer()
	}
}

// IsBenchmark returns true if it's a benchmark.
func ( *tb) () bool {
	,  := .TB.(*testing.B)
	return 
}