-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Expand file tree
/
Copy pathquery_fastpath_test.go
More file actions
66 lines (59 loc) · 1.96 KB
/
Copy pathquery_fastpath_test.go
File metadata and controls
66 lines (59 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
package echo
import (
"net/url"
"testing"
)
const benchQuery = "id=42&name=Jon&lang=en&page=2"
// BenchmarkQueryParam_FastPath measures the single-key raw scan (current behavior).
func BenchmarkQueryParam_FastPath(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
_ = getRawQueryParam(benchQuery, "name")
}
}
// BenchmarkQueryParam_Map measures the previous behavior: build the full url.Values then Get.
func BenchmarkQueryParam_Map(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
v, _ := url.ParseQuery(benchQuery)
_ = v.Get("name")
}
}
// TestGetRawQueryParamMatchesStdlib asserts the single-key fast path returns exactly what
// url.Values.Get (over url.ParseQuery output) would return, across a battery of edge cases.
func TestGetRawQueryParamMatchesStdlib(t *testing.T) {
queries := []string{
"",
"a=1",
"a=1&b=2",
"a=1&a=2", // first match wins
"a=&b=2", // empty value
"=v", // empty key
"a", // key without '='
"a=x+y", // '+' -> space
"a=%20space", // percent escape
"a=%2", // bad value escape -> pair skipped
"a=%ZZ&a=2", // bad escape on first match -> skip, fall through to second
"%ZZ=1&a=2", // bad key escape -> pair skipped
"a%3Db=c", // encoded key 'a=b'
"a=1;b=2", // semicolon segment skipped entirely
"a=1&c=3;d=4&e=5",
"name=Jon&name=Snow&age=24",
"q=%E4%B8%AD%E6%96%87", // unicode value
"empty=&x=1",
"a=1&&b=2", // empty segment
}
names := []string{"a", "b", "c", "d", "e", "name", "age", "q", "empty", "x", "a=b", "missing", ""}
for _, q := range queries {
want, _ := url.ParseQuery(q) // url.Values; mirrors URL.Query() (error ignored)
for _, name := range names {
got := getRawQueryParam(q, name)
exp := want.Get(name)
if got != exp {
t.Errorf("getRawQueryParam(%q, %q) = %q; url.Values.Get = %q", q, name, got, exp)
}
}
}
}