-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mountinfo: simpify, speedup, and fix unescape #144
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -731,43 +731,70 @@ func TestParseMountinfoExtraCases(t *testing.T) { | |
} | ||
|
||
func TestUnescape(t *testing.T) { | ||
// When adding test cases below, be aware that Go interprets \NNN | ||
// inside strings enclosed in double quotes in the same way as the | ||
// function being tested, so: | ||
// - for input: either escape every backslash character (i.e. \\), or | ||
// enclose the whole string in `backticks` so \NNN is passed as-is; | ||
// - for output: write it like "\040", which is identical to " ". | ||
testCases := []struct { | ||
input, output string | ||
isErr bool | ||
}{ | ||
{"", "", false}, | ||
{"/", "/", false}, | ||
{"/some/longer/path", "/some/longer/path", false}, | ||
{"/path\\040with\\040spaces", "/path with spaces", false}, | ||
{"/path/with\\134backslash", "/path/with\\backslash", false}, | ||
{"/tab\\011in/path", "/tab\tin/path", false}, | ||
{`/path/"with'quotes`, `/path/"with'quotes`, false}, | ||
{`/path/"with'quotes,\040space,\011tab`, `/path/"with'quotes, space, tab`, false}, | ||
{`\12`, "", true}, | ||
{`\134`, `\`, false}, | ||
{`"'"'"'`, `"'"'"'`, false}, | ||
{`/\1345`, `/\5`, false}, | ||
{`/\12x`, "", true}, | ||
{`\0`, "", true}, | ||
{`\x`, "", true}, | ||
{"\\\\", "", true}, | ||
{"", ""}, | ||
{"/", "/"}, | ||
{"/some/longer/path", "/some/longer/path"}, | ||
{`/path\040with\040spaces`, "/path\040with\040spaces"}, | ||
{"/path/with\\134backslash", "/path/with\\backslash"}, | ||
{"/tab\\011in/path", "/tab\011in/path"}, | ||
{`/path/"with'quotes`, `/path/"with'quotes`}, | ||
{`/path/"with'quotes,\040space,\011tab`, `/path/"with'quotes, space, tab`}, | ||
{`\12`, `\12`}, // Not enough digits. | ||
{`\134`, `\`}, // Backslash. | ||
{`"'"'"'`, `"'"'"'`}, | ||
{`/\1345`, `/\5`}, // Backslash with extra digit. | ||
{`/\12x`, `/\12x`}, | ||
{`\0`, `\0`}, // Not enough digits. | ||
{`\000\000`, "\000\000"}, // NUL (min allowed ASCII value). | ||
{`\x`, `\x`}, | ||
{"\\\\", "\\\\"}, | ||
{`\177`, "\177"}, // Max allowed ASCII value. | ||
{`\222`, `\222`}, // Too large value -- not unescaped. | ||
{`Это\040комон\040какой-то`, "Это комон какой-то"}, // Some UTF-8 -- not unescaped. | ||
} | ||
|
||
for _, tc := range testCases { | ||
res, err := unescape(tc.input) | ||
if tc.isErr == true { | ||
if err == nil { | ||
t.Errorf("Input %q, want error, got nil", tc.input) | ||
} | ||
// no more checks | ||
continue | ||
} | ||
res := unescape(tc.input) | ||
if res != tc.output { | ||
t.Errorf("Input %q, want %q, got %q", tc.input, tc.output, res) | ||
} | ||
if err != nil { | ||
t.Errorf("Input %q, want nil, got error %v", tc.input, err) | ||
continue | ||
} | ||
} | ||
|
||
func BenchmarkUnescape(b *testing.B) { | ||
testCases := []string{ | ||
Comment on lines
+773
to
+774
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW; I copied these test cases from the other test. We could possibly consider making those test-cases a package-variable, so that we can use the same ones here as part of the benchmark (if we don't want to repeat the cases). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about it, but:
|
||
"", | ||
"/", | ||
"/some/longer/path", | ||
"/path\\040with\\040spaces", | ||
"/path/with\\134backslash", | ||
"/tab\\011in/path", | ||
`/path/"with'quotes`, | ||
`/path/"with'quotes,\040space,\011tab`, | ||
`\12`, | ||
`\134`, | ||
`"'"'"'`, | ||
`/\1345`, | ||
`/\12x`, | ||
`\0`, | ||
`\x`, | ||
"\\\\", | ||
} | ||
|
||
b.ResetTimer() | ||
b.ReportAllocs() | ||
for i := 0; i < b.N; i++ { | ||
for x := 0; x < len(testCases); x++ { | ||
_ = unescape(testCases[x]) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering; as we're updating all of these, should we also use keys here? I know it would be a lot more verbose, but it's generally "best practice" (I think?).
We could even consider adding a
doc
field to describe test-cases (instead of adding a comment), but I realise most don't have a description if they have a specific purpose 🤔Happy to hear what you think though; if it's too verbose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, with two fields only I think this will be overly verbose and taking too much vertical space.