filters: supporting alternative characters for quote

The regexp syntax can have some nasty characters to handle quoting
correctly, in practice. In certain scenarios a double quote works well,
but it can affect readability for certain regexps. This introduces a
quoting mode that treats `/` and `|` as a double quote to make the
quoting in regular expressions more familiar and readable.

This change is introduced in a backwards compatible manner, so existing
regexp quoting is not affected.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day
2017-12-04 17:12:41 -08:00
parent 617c63de06
commit 4dfcf60bec
5 changed files with 343 additions and 11 deletions

View File

@@ -95,6 +95,20 @@ func TestScanner(t *testing.T) {
{pos: 22, token: tokenEOF},
},
},
{
name: "RegexpQuotedValue",
input: `name~=/[abc]{0,2}/,foo=test`,
expected: []tokenResult{
{pos: 0, token: tokenField, text: "name"},
{pos: 4, token: tokenOperator, text: "~="},
{pos: 6, token: tokenQuoted, text: "/[abc]{0,2}/"},
{pos: 18, token: tokenSeparator, text: ","},
{pos: 19, token: tokenField, text: "foo"},
{pos: 22, token: tokenOperator, text: "="},
{pos: 23, token: tokenValue, text: "test"},
{pos: 27, token: tokenEOF},
},
},
{
name: "Cowsay",
input: "name~=牛,labels.moo=true",
@@ -111,6 +125,22 @@ func TestScanner(t *testing.T) {
{pos: 25, token: tokenEOF},
},
},
{
name: "CowsayRegexpQuoted",
input: "name~=|牛|,labels.moo=true",
expected: []tokenResult{
{pos: 0, token: tokenField, text: "name"},
{pos: 4, token: tokenOperator, text: "~="},
{pos: 6, token: tokenQuoted, text: "|牛|"},
{pos: 11, token: tokenSeparator, text: ","},
{pos: 12, token: tokenField, text: "labels"},
{pos: 18, token: tokenSeparator, text: "."},
{pos: 19, token: tokenField, text: "moo"},
{pos: 22, token: tokenOperator, text: "="},
{pos: 23, token: tokenValue, text: "true"},
{pos: 27, token: tokenEOF},
},
},
{
name: "Escapes",
input: `name~="asdf\n\tfooo"`,
@@ -187,15 +217,45 @@ func TestScanner(t *testing.T) {
},
{
name: "MissingValue",
input: "input==,id?=ff",
input: "input==,id!=ff",
expected: []tokenResult{
{pos: 0, token: tokenField, text: "input"},
{pos: 5, token: tokenOperator, text: "=="},
{pos: 7, token: tokenSeparator, text: ","},
{pos: 8, token: tokenValue, text: "id?=ff"},
{pos: 8, token: tokenField, text: "id"},
{pos: 10, token: tokenOperator, text: "!="},
{pos: 12, token: tokenValue, text: "ff"},
{pos: 14, token: tokenEOF},
},
},
{
name: "QuotedRegexp",
input: "input~=/foo\\/bar/,id!=ff",
expected: []tokenResult{
{pos: 0, token: tokenField, text: "input"},
{pos: 5, token: tokenOperator, text: "~="},
{pos: 7, token: tokenQuoted, text: "/foo\\/bar/"},
{pos: 17, token: tokenSeparator, text: ","},
{pos: 18, token: tokenField, text: "id"},
{pos: 20, token: tokenOperator, text: "!="},
{pos: 22, token: tokenValue, text: "ff"},
{pos: 24, token: tokenEOF},
},
},
{
name: "QuotedRegexpAlt",
input: "input~=|foo/bar|,id!=ff",
expected: []tokenResult{
{pos: 0, token: tokenField, text: "input"},
{pos: 5, token: tokenOperator, text: "~="},
{pos: 7, token: tokenQuoted, text: "|foo/bar|"},
{pos: 16, token: tokenSeparator, text: ","},
{pos: 17, token: tokenField, text: "id"},
{pos: 19, token: tokenOperator, text: "!="},
{pos: 21, token: tokenValue, text: "ff"},
{pos: 23, token: tokenEOF},
},
},
} {
t.Run(testcase.name, func(t *testing.T) {
var sc scanner