Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
search_test.go265 linesDownload Raw Back to sort
1// Copyright 2010 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4 5package sort_test6 7import (8	"math/bits"9	"runtime"10	. "sort"11	stringspkg "strings"12	"testing"13)14 15func f(a []int, x int) func(int) bool {16	return func(i int) bool {17		return a[i] >= x18	}19}20 21var data = []int{0: -10, 1: -5, 2: 0, 3: 1, 4: 2, 5: 3, 6: 5, 7: 7, 8: 11, 9: 100, 10: 100, 11: 100, 12: 1000, 13: 10000}22 23var tests = []struct {24	name string25	n    int26	f    func(int) bool27	i    int28}{29	{"empty", 0, nil, 0},30	{"1 1", 1, func(i int) bool { return i >= 1 }, 1},31	{"1 true", 1, func(i int) bool { return true }, 0},32	{"1 false", 1, func(i int) bool { return false }, 1},33	{"1e9 991", 1e9, func(i int) bool { return i >= 991 }, 991},34	{"1e9 true", 1e9, func(i int) bool { return true }, 0},35	{"1e9 false", 1e9, func(i int) bool { return false }, 1e9},36	{"data -20", len(data), f(data, -20), 0},37	{"data -10", len(data), f(data, -10), 0},38	{"data -9", len(data), f(data, -9), 1},39	{"data -6", len(data), f(data, -6), 1},40	{"data -5", len(data), f(data, -5), 1},41	{"data 3", len(data), f(data, 3), 5},42	{"data 11", len(data), f(data, 11), 8},43	{"data 99", len(data), f(data, 99), 9},44	{"data 100", len(data), f(data, 100), 9},45	{"data 101", len(data), f(data, 101), 12},46	{"data 10000", len(data), f(data, 10000), 13},47	{"data 10001", len(data), f(data, 10001), 14},48	{"descending a", 7, func(i int) bool { return []int{99, 99, 59, 42, 7, 0, -1, -1}[i] <= 7 }, 4},49	{"descending 7", 1e9, func(i int) bool { return 1e9-i <= 7 }, 1e9 - 7},50	{"overflow", 2e9, func(i int) bool { return false }, 2e9},51}52 53func TestSearch(t *testing.T) {54	for _, e := range tests {55		i := Search(e.n, e.f)56		if i != e.i {57			t.Errorf("%s: expected index %d; got %d", e.name, e.i, i)58		}59	}60}61 62func TestFind(t *testing.T) {63	str1 := []string{"foo"}64	str2 := []string{"ab", "ca"}65	str3 := []string{"mo", "qo", "vo"}66	str4 := []string{"ab", "ad", "ca", "xy"}67 68	// slice with repeating elements69	strRepeats := []string{"ba", "ca", "da", "da", "da", "ka", "ma", "ma", "ta"}70 71	// slice with all element equal72	strSame := []string{"xx", "xx", "xx"}73 74	tests := []struct {75		data      []string76		target    string77		wantPos   int78		wantFound bool79	}{80		{[]string{}, "foo", 0, false},81		{[]string{}, "", 0, false},82 83		{str1, "foo", 0, true},84		{str1, "bar", 0, false},85		{str1, "zx", 1, false},86 87		{str2, "aa", 0, false},88		{str2, "ab", 0, true},89		{str2, "ad", 1, false},90		{str2, "ca", 1, true},91		{str2, "ra", 2, false},92 93		{str3, "bb", 0, false},94		{str3, "mo", 0, true},95		{str3, "nb", 1, false},96		{str3, "qo", 1, true},97		{str3, "tr", 2, false},98		{str3, "vo", 2, true},99		{str3, "xr", 3, false},100 101		{str4, "aa", 0, false},102		{str4, "ab", 0, true},103		{str4, "ac", 1, false},104		{str4, "ad", 1, true},105		{str4, "ax", 2, false},106		{str4, "ca", 2, true},107		{str4, "cc", 3, false},108		{str4, "dd", 3, false},109		{str4, "xy", 3, true},110		{str4, "zz", 4, false},111 112		{strRepeats, "da", 2, true},113		{strRepeats, "db", 5, false},114		{strRepeats, "ma", 6, true},115		{strRepeats, "mb", 8, false},116 117		{strSame, "xx", 0, true},118		{strSame, "ab", 0, false},119		{strSame, "zz", 3, false},120	}121 122	for _, tt := range tests {123		t.Run(tt.target, func(t *testing.T) {124			cmp := func(i int) int {125				return stringspkg.Compare(tt.target, tt.data[i])126			}127 128			pos, found := Find(len(tt.data), cmp)129			if pos != tt.wantPos || found != tt.wantFound {130				t.Errorf("Find got (%v, %v), want (%v, %v)", pos, found, tt.wantPos, tt.wantFound)131			}132		})133	}134}135 136// log2 computes the binary logarithm of x, rounded up to the next integer.137// (log2(0) == 0, log2(1) == 0, log2(2) == 1, log2(3) == 2, etc.)138func log2(x int) int {139	if x < 1 {140		return 0141	}142	return bits.Len(uint(x - 1))143}144 145func TestSearchEfficiency(t *testing.T) {146	n := 100147	step := 1148	for exp := 2; exp < 10; exp++ {149		// n == 10**exp150		// step == 10**(exp-2)151		max := log2(n)152		for x := 0; x < n; x += step {153			count := 0154			i := Search(n, func(i int) bool { count++; return i >= x })155			if i != x {156				t.Errorf("n = %d: expected index %d; got %d", n, x, i)157			}158			if count > max {159				t.Errorf("n = %d, x = %d: expected <= %d calls; got %d", n, x, max, count)160			}161		}162		n *= 10163		step *= 10164	}165}166 167// Smoke tests for convenience wrappers - not comprehensive.168 169var fdata = []float64{0: -3.14, 1: 0, 2: 1, 3: 2, 4: 1000.7}170var sdata = []string{0: "f", 1: "foo", 2: "foobar", 3: "x"}171 172var wrappertests = []struct {173	name   string174	result int175	i      int176}{177	{"SearchInts", SearchInts(data, 11), 8},178	{"SearchFloat64s", SearchFloat64s(fdata, 2.1), 4},179	{"SearchStrings", SearchStrings(sdata, ""), 0},180	{"IntSlice.Search", IntSlice(data).Search(0), 2},181	{"Float64Slice.Search", Float64Slice(fdata).Search(2.0), 3},182	{"StringSlice.Search", StringSlice(sdata).Search("x"), 3},183}184 185func TestSearchWrappers(t *testing.T) {186	for _, e := range wrappertests {187		if e.result != e.i {188			t.Errorf("%s: expected index %d; got %d", e.name, e.i, e.result)189		}190	}191}192 193func runSearchWrappers() {194	SearchInts(data, 11)195	SearchFloat64s(fdata, 2.1)196	SearchStrings(sdata, "")197	IntSlice(data).Search(0)198	Float64Slice(fdata).Search(2.0)199	StringSlice(sdata).Search("x")200}201 202func TestSearchWrappersDontAlloc(t *testing.T) {203	if testing.Short() {204		t.Skip("skipping malloc count in short mode")205	}206	if runtime.GOMAXPROCS(0) > 1 {207		t.Skip("skipping; GOMAXPROCS>1")208	}209	allocs := testing.AllocsPerRun(100, runSearchWrappers)210	if allocs != 0 {211		t.Errorf("expected no allocs for runSearchWrappers, got %v", allocs)212	}213}214 215func BenchmarkSearchWrappers(b *testing.B) {216	for i := 0; i < b.N; i++ {217		runSearchWrappers()218	}219}220 221// Abstract exhaustive test: all sizes up to 100,222// all possible return values. If there are any small223// corner cases, this test exercises them.224func TestSearchExhaustive(t *testing.T) {225	for size := 0; size <= 100; size++ {226		for targ := 0; targ <= size; targ++ {227			i := Search(size, func(i int) bool { return i >= targ })228			if i != targ {229				t.Errorf("Search(%d, %d) = %d", size, targ, i)230			}231		}232	}233}234 235// Abstract exhaustive test for Find.236func TestFindExhaustive(t *testing.T) {237	// Test Find for different sequence sizes and search targets.238	// For each size, we have a (unmaterialized) sequence of integers:239	//   2,4...size*2240	// And we're looking for every possible integer between 1 and size*2 + 1.241	for size := 0; size <= 100; size++ {242		for x := 1; x <= size*2+1; x++ {243			var wantFound bool244			var wantPos int245 246			cmp := func(i int) int {247				// Encodes the unmaterialized sequence with elem[i] == (i+1)*2248				return x - (i+1)*2249			}250			pos, found := Find(size, cmp)251 252			if x%2 == 0 {253				wantPos = x/2 - 1254				wantFound = true255			} else {256				wantPos = x / 2257				wantFound = false258			}259			if found != wantFound || pos != wantPos {260				t.Errorf("Find(%d, %d): got (%v, %v), want (%v, %v)", size, x, pos, found, wantPos, wantFound)261			}262		}263	}264}265 
codekingpro/portable-devtools · Team Ai