// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package page import ( "fmt" "math/rand" "testing" "time" qt "github.com/frankban/quicktest" ) func TestSearchPage(t *testing.T) { t.Parallel() c := qt.New(t) pages := createSortTestPages(10) for i, p := range pages { p.(*testPage).title = fmt.Sprintf("Title %d", i%2) } for _, pages := range []Pages{pages.ByTitle(), pages.ByTitle().Reverse()} { less := isPagesProbablySorted(pages, lessPageTitle) c.Assert(less, qt.Not(qt.IsNil)) for i, p := range pages { idx := searchPageBinary(p, pages, less) c.Assert(idx, qt.Equals, i) } } } func BenchmarkSearchPage(b *testing.B) { type Variant struct { name string preparePages func(pages Pages) Pages search func(p Page, pages Pages) int } shufflePages := func(pages Pages) Pages { rand.Shuffle(len(pages), func(i, j int) { pages[i], pages[j] = pages[j], pages[i] }) return pages } linearSearch := func(p Page, pages Pages) int { return searchPageLinear(p, pages, 0) } createPages := func(num int) Pages { pages := createSortTestPages(num) for _, p := range pages { tp := p.(*testPage) tp.weight = rand.Intn(len(pages)) tp.title = fmt.Sprintf("Title %d", rand.Intn(len(pages))) tp.pubDate = time.Now().Add(time.Duration(rand.Intn(len(pages)/5)) * time.Hour) tp.date = time.Now().Add(time.Duration(rand.Intn(len(pages)/5)) * time.Hour) } return pages } for _, variant := range []Variant{ {"Shuffled", shufflePages, searchPage}, {"ByWeight", func(pages Pages) Pages { return pages.ByWeight() }, searchPage}, {"ByWeight.Reverse", func(pages Pages) Pages { return pages.ByWeight().Reverse() }, searchPage}, {"ByDate", func(pages Pages) Pages { return pages.ByDate() }, searchPage}, {"ByPublishDate", func(pages Pages) Pages { return pages.ByPublishDate() }, searchPage}, {"ByTitle", func(pages Pages) Pages { return pages.ByTitle() }, searchPage}, {"ByTitle Linear", func(pages Pages) Pages { return pages.ByTitle() }, linearSearch}, } { for _, numPages := range []int{100, 500, 1000, 5000} { b.Run(fmt.Sprintf("%s-%d", variant.name, numPages), func(b *testing.B) { b.StopTimer() pages := createPages(numPages) if variant.preparePages != nil { pages = variant.preparePages(pages) } b.StartTimer() for i := 0; i < b.N; i++ { j := rand.Intn(numPages) k := variant.search(pages[j], pages) if k != j { b.Fatalf("%d != %d", k, j) } } }) } } } func TestIsPagesProbablySorted(t *testing.T) { t.Parallel() c := qt.New(t) c.Assert(isPagesProbablySorted(createSortTestPages(6).ByWeight(), DefaultPageSort), qt.Not(qt.IsNil)) c.Assert(isPagesProbablySorted(createSortTestPages(300).ByWeight(), DefaultPageSort), qt.Not(qt.IsNil)) c.Assert(isPagesProbablySorted(createSortTestPages(6), DefaultPageSort), qt.IsNil) c.Assert(isPagesProbablySorted(createSortTestPages(300).ByTitle(), pageLessFunctions...), qt.Not(qt.IsNil)) }