@@ -15,9 +15,12 @@ package resource
1515
1616import (
1717 "fmt"
18+ "math/rand"
1819 "path"
1920 "path/filepath"
21+ "strings"
2022 "testing"
23+ "time"
2124
2225 "github.com/stretchr/testify/require"
2326)
@@ -137,6 +140,52 @@ func TestResourcesGetByPrefix(t *testing.T) {
137140
138141}
139142
143+ func TestResourcesGetMatch (t * testing.T ) {
144+ assert := require .New (t )
145+ spec := newTestResourceSpec (assert )
146+ resources := Resources {
147+ spec .newGenericResource (nil , nil , "/public" , "/a/foo1.css" , "foo1.css" , "css" ),
148+ spec .newGenericResource (nil , nil , "/public" , "/a/logo1.png" , "logo1.png" , "image" ),
149+ spec .newGenericResource (nil , nil , "/public" , "/b/Logo2.png" , "Logo2.png" , "image" ),
150+ spec .newGenericResource (nil , nil , "/public" , "/b/foo2.css" , "foo2.css" , "css" ),
151+ spec .newGenericResource (nil , nil , "/public" , "/b/foo3.css" , "foo3.css" , "css" ),
152+ spec .newGenericResource (nil , nil , "/public" , "/b/c/foo4.css" , "c/foo4.css" , "css" ),
153+ spec .newGenericResource (nil , nil , "/public" , "/b/c/foo5.css" , "c/foo5.css" , "css" ),
154+ spec .newGenericResource (nil , nil , "/public" , "/b/c/d/foo6.css" , "c/d/foo6.css" , "css" ),
155+ }
156+
157+ assert .Equal ("/logo1.png" , resources .GetMatch ("logo*" ).RelPermalink ())
158+ assert .Equal ("/logo1.png" , resources .GetMatch ("loGo*" ).RelPermalink ())
159+ assert .Equal ("/Logo2.png" , resources .GetMatch ("logo2*" ).RelPermalink ())
160+ assert .Equal ("/foo2.css" , resources .GetMatch ("foo2*" ).RelPermalink ())
161+ assert .Equal ("/foo1.css" , resources .GetMatch ("foo1*" ).RelPermalink ())
162+ assert .Equal ("/foo1.css" , resources .GetMatch ("foo1*" ).RelPermalink ())
163+ assert .Equal ("/c/foo4.css" , resources .GetMatch ("*/foo*" ).RelPermalink ())
164+
165+ assert .Nil (resources .GetMatch ("asdfasdf" ))
166+
167+ assert .Equal (2 , len (resources .Match ("Logo*" )))
168+ assert .Equal (1 , len (resources .Match ("logo2*" )))
169+ assert .Equal (2 , len (resources .Match ("c/*" )))
170+
171+ assert .Equal (6 , len (resources .Match ("**.css" )))
172+ assert .Equal (3 , len (resources .Match ("**/*.css" )))
173+ assert .Equal (1 , len (resources .Match ("c/**/*.css" )))
174+
175+ // Matches only CSS files in c/
176+ assert .Equal (3 , len (resources .Match ("c/**.css" )))
177+
178+ // Matches all CSS files below c/ (including in c/d/)
179+ assert .Equal (3 , len (resources .Match ("c/**.css" )))
180+
181+ // Patterns beginning with a slash will not match anything.
182+ // We could maybe consider trimming that slash, but let's be explicit about this.
183+ // (it is possible for users to do a rename)
184+ // This is analogous to standing in a directory and doing "ls *.*".
185+ assert .Equal (0 , len (resources .Match ("/c/**.css" )))
186+
187+ }
188+
140189func TestAssignMetadata (t * testing.T ) {
141190 assert := require .New (t )
142191 spec := newTestResourceSpec (assert )
@@ -290,6 +339,73 @@ func TestAssignMetadata(t *testing.T) {
290339
291340}
292341
342+ func BenchmarkResourcesByPrefix (b * testing.B ) {
343+ resources := benchResources (b )
344+ prefixes := []string {"abc" , "jkl" , "nomatch" , "sub/" }
345+ rnd := rand .New (rand .NewSource (time .Now ().Unix ()))
346+
347+ b .RunParallel (func (pb * testing.PB ) {
348+ for pb .Next () {
349+ resources .ByPrefix (prefixes [rnd .Intn (len (prefixes ))])
350+ }
351+ })
352+ }
353+
354+ func BenchmarkResourcesMatch (b * testing.B ) {
355+ resources := benchResources (b )
356+ prefixes := []string {"abc*" , "jkl*" , "nomatch*" , "sub/*" }
357+ rnd := rand .New (rand .NewSource (time .Now ().Unix ()))
358+
359+ b .RunParallel (func (pb * testing.PB ) {
360+ for pb .Next () {
361+ resources .Match (prefixes [rnd .Intn (len (prefixes ))])
362+ }
363+ })
364+ }
365+
366+ // This adds a benchmark for the a100 test case as described by Russ Cox here:
367+ // https://research.swtch.com/glob (really interesting article)
368+ // I don't expect Hugo users to "stumble upon" this problem, so this is more to satisfy
369+ // my own curiosity.
370+ func BenchmarkResourcesMatchA100 (b * testing.B ) {
371+ assert := require .New (b )
372+ spec := newTestResourceSpec (assert )
373+ a100 := strings .Repeat ("a" , 100 )
374+ pattern := "a*a*a*a*a*a*a*a*b"
375+
376+ resources := Resources {spec .newGenericResource (nil , nil , "/public" , "/a/" + a100 , a100 , "css" )}
377+
378+ b .ResetTimer ()
379+ for i := 0 ; i < b .N ; i ++ {
380+ resources .Match (pattern )
381+ }
382+
383+ }
384+
385+ func benchResources (b * testing.B ) Resources {
386+ assert := require .New (b )
387+ spec := newTestResourceSpec (assert )
388+ var resources Resources
389+
390+ for i := 0 ; i < 30 ; i ++ {
391+ name := fmt .Sprintf ("abcde%d_%d.css" , i % 5 , i )
392+ resources = append (resources , spec .newGenericResource (nil , nil , "/public" , "/a/" + name , name , "css" ))
393+ }
394+
395+ for i := 0 ; i < 30 ; i ++ {
396+ name := fmt .Sprintf ("efghi%d_%d.css" , i % 5 , i )
397+ resources = append (resources , spec .newGenericResource (nil , nil , "/public" , "/a/" + name , name , "css" ))
398+ }
399+
400+ for i := 0 ; i < 30 ; i ++ {
401+ name := fmt .Sprintf ("jklmn%d_%d.css" , i % 5 , i )
402+ resources = append (resources , spec .newGenericResource (nil , nil , "/public" , "/b/sub/" + name , "sub/" + name , "css" ))
403+ }
404+
405+ return resources
406+
407+ }
408+
293409func BenchmarkAssignMetadata (b * testing.B ) {
294410 assert := require .New (b )
295411 spec := newTestResourceSpec (assert )
@@ -320,5 +436,4 @@ func BenchmarkAssignMetadata(b *testing.B) {
320436 }
321437
322438 }
323-
324439}
0 commit comments