diff --git a/model/search_params_test.go b/model/search_params_test.go index 30d61b94d5..db162d9556 100644 --- a/model/search_params_test.go +++ b/model/search_params_test.go @@ -12,924 +12,1500 @@ import ( ) func TestSplitWords(t *testing.T) { - words := splitWords("") - require.Empty(t, words) + for _, testCase := range []struct { + Name string + Input string - words = splitWords(" ") - require.Empty(t, words) + Output []string + }{ + { + Name: "string is empty, output should be empty", + Input: "", + Output: []string{}, + }, + { + Name: "string is only spaces, output should be empty", + Input: " ", + Output: []string{}, + }, + { + Name: "string is a single word, output should be one word length", + Input: "word", + Output: []string{"word"}, + }, + { + Name: "string has a single \" character, output should be two words", + Input: "wo\"rd", + Output: []string{"wo", "\"rd"}, + }, + { + Name: "string has multiple \" characters, output should be two words", + Input: "wo\"rd\"", + Output: []string{"wo", "\"rd\""}, + }, + { + Name: "string has multiple \" characters and a -, output should be two words", + Input: "wo-\"rd\"", + Output: []string{"wo", "-\"rd\""}, + }, + { + Name: "string has multiple words, output should be 3 words", + Input: "word1 word2 word3", + Output: []string{"word1", "word2", "word3"}, + }, + { + Name: "string has multiple words with a \" in the middle, output should be 3 words", + Input: "word1 \"word2 word3", + Output: []string{"word1", "\"word2", "word3"}, + }, + { + Name: "string has multiple words with a \" at the start, output should be 3 words", + Input: "\"word1 word2 word3", + Output: []string{"\"word1", "word2", "word3"}, + }, + { + Name: "string has multiple words with a \" at the end, output should be 3 words and a \"", + Input: "word1 word2 word3\"", + Output: []string{"word1", "word2", "word3", "\""}, + }, + { + Name: "string has multiple words with # as a prefix, output should be 3 words and prefixes kept", + Input: "word1 #word2 ##word3", + Output: []string{"word1", "#word2", "##word3"}, + }, + { + Name: "string has multiple words with multiple space between them, output should still be 3 words", + Input: " word1 word2 word3", + Output: []string{"word1", "word2", "word3"}, + }, + { + Name: "string has a quoted word, output should also be quoted", + Input: "\"quoted\"", + Output: []string{"\"quoted\""}, + }, + { + Name: "string has a quoted word with a - prefix, output should also be quoted with the same prefix", + Input: "-\"quoted\"", + Output: []string{"-\"quoted\""}, + }, + { + Name: "string has multiple quoted words, output should not be splitted and quotes should be kept", + Input: "\"quoted multiple words\"", + Output: []string{"\"quoted multiple words\""}, + }, + { + Name: "string has a mix of qouted words and non quoted words, output should contain 5 entries, quoted words should not be split", + Input: "some stuff \"quoted multiple words\" more stuff", + Output: []string{"some", "stuff", "\"quoted multiple words\"", "more", "stuff"}, + }, + { + Name: "string has a mix of qouted words with a - prefix and non quoted words, output should contain 5 entries, quoted words should not be split, - should be kept", + Input: "some stuff -\"quoted multiple words\" more stuff", + Output: []string{"some", "stuff", "-\"quoted multiple words\"", "more", "stuff"}, + }, + { + Name: "string has a mix of multiple qouted words with a - prefix and non quoted words including a # character, output should contain 5 entries, quoted words should not be split, # and - should be kept", + Input: "some \"stuff\" \"quoted multiple words\" #some \"more stuff\"", + Output: []string{"some", "\"stuff\"", "\"quoted multiple words\"", "#some", "\"more stuff\""}, + }, + } { + t.Run(testCase.Name, func(t *testing.T) { + assert.Equal(t, testCase.Output, splitWords(testCase.Input)) + }) + } - words = splitWords("word") - require.Len(t, words, 1) - require.Equal(t, "word", words[0]) - - words = splitWords("wo\"rd") - require.Len(t, words, 2) - require.Equal(t, "wo", words[0]) - require.Equal(t, "\"rd", words[1]) - - words = splitWords("wo\"rd\"") - require.Len(t, words, 2) - require.Equal(t, "wo", words[0]) - require.Equal(t, "\"rd\"", words[1]) - - words = splitWords("wo-\"rd\"") - require.Len(t, words, 2) - require.Equal(t, "wo", words[0]) - require.Equal(t, "-\"rd\"", words[1]) - - words = splitWords("word1 word2 word3") - require.Len(t, words, 3) - require.Equal(t, "word1", words[0]) - require.Equal(t, "word2", words[1]) - require.Equal(t, "word3", words[2]) - - words = splitWords("word1 \"word2 word3") - require.Len(t, words, 3) - require.Equal(t, "word1", words[0]) - require.Equal(t, "\"word2", words[1]) - require.Equal(t, "word3", words[2]) - - words = splitWords("\"word1 word2 word3") - require.Len(t, words, 3) - require.Equal(t, "\"word1", words[0]) - require.Equal(t, "word2", words[1]) - require.Equal(t, "word3", words[2]) - - words = splitWords("word1 word2 word3\"") - require.Len(t, words, 4) - require.Equal(t, "word1", words[0]) - require.Equal(t, "word2", words[1]) - require.Equal(t, "word3", words[2]) - require.Equal(t, "\"", words[3]) - - words = splitWords("word1 #word2 ##word3") - require.Len(t, words, 3) - require.Equal(t, "word1", words[0]) - require.Equal(t, "#word2", words[1]) - require.Equal(t, "##word3", words[2]) - - words = splitWords(" word1 word2 word3 ") - require.Len(t, words, 3) - require.Equal(t, "word1", words[0]) - require.Equal(t, "word2", words[1]) - require.Equal(t, "word3", words[2]) - - words = splitWords("\"quoted\"") - require.Len(t, words, 1) - require.Equal(t, "\"quoted\"", words[0]) - - words = splitWords("-\"quoted\"") - require.Len(t, words, 1) - require.Equal(t, "-\"quoted\"", words[0]) - - words = splitWords("\"quoted multiple words\"") - require.Len(t, words, 1) - require.Equal(t, "\"quoted multiple words\"", words[0]) - - words = splitWords("some stuff \"quoted multiple words\" more stuff") - require.Len(t, words, 5) - require.Equal(t, "some", words[0]) - require.Equal(t, "stuff", words[1]) - require.Equal(t, "\"quoted multiple words\"", words[2]) - require.Equal(t, "more", words[3]) - require.Equal(t, "stuff", words[4]) - - words = splitWords("some stuff -\"quoted multiple words\" more stuff") - require.Len(t, words, 5) - require.Equal(t, "some", words[0]) - require.Equal(t, "stuff", words[1]) - require.Equal(t, "-\"quoted multiple words\"", words[2]) - require.Equal(t, "more", words[3]) - require.Equal(t, "stuff", words[4]) - - words = splitWords("some \"stuff\" \"quoted multiple words\" #some \"more stuff\"") - require.Len(t, words, 5) - require.Equal(t, "some", words[0]) - require.Equal(t, "\"stuff\"", words[1]) - require.Equal(t, "\"quoted multiple words\"", words[2]) - require.Equal(t, "#some", words[3]) - require.Equal(t, "\"more stuff\"", words[4]) } -func TestParseSearchFlags(t *testing.T) { - words, flags := parseSearchFlags(splitWords("")) - require.Empty(t, words) - require.Equal(t, 0, len(flags)) +func TestParseSearchFlags2(t *testing.T) { + for _, testCase := range []struct { + Name string + Input string - words, flags = parseSearchFlags(splitWords("word")) - require.Len(t, words, 1) - require.Equal(t, "word", words[0].value) - require.False(t, words[0].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("-word")) - require.Len(t, words, 1) - require.Equal(t, "word", words[0].value) - require.True(t, words[0].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("apple banana cherry")) - require.Len(t, words, 3) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Equal(t, "cherry", words[2].value) - require.False(t, words[2].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("-apple -banana -cherry")) - require.Len(t, words, 3) - require.Equal(t, "apple", words[0].value) - require.True(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.True(t, words[1].exclude) - require.Equal(t, "cherry", words[2].value) - require.True(t, words[2].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("apple -banana cherry")) - require.Len(t, words, 3) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.True(t, words[1].exclude) - require.Equal(t, "cherry", words[2].value) - require.False(t, words[2].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("apple banana from:chan")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "from", flags[0].name) - require.Equal(t, "chan", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("apple -banana from:chan")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.True(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "from", flags[0].name) - require.Equal(t, "chan", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("-apple -banana from:chan")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.True(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.True(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "from", flags[0].name) - require.Equal(t, "chan", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("#apple #banana from:chan")) - require.Len(t, words, 2) - require.Equal(t, "#apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "#banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "from", flags[0].name) - require.Equal(t, "chan", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("-#apple #banana from:chan")) - require.Len(t, words, 2) - require.Equal(t, "#apple", words[0].value) - require.True(t, words[0].exclude) - require.Equal(t, "#banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "from", flags[0].name) - require.Equal(t, "chan", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("#apple #banana -from:chan")) - require.Len(t, words, 2) - require.Equal(t, "#apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "#banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "from", flags[0].name) - require.Equal(t, "chan", flags[0].value) - require.True(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("-#apple -#banana -from:chan")) - require.Len(t, words, 2) - require.Equal(t, "#apple", words[0].value) - require.True(t, words[0].exclude) - require.Equal(t, "#banana", words[1].value) - require.True(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "from", flags[0].name) - require.Equal(t, "chan", flags[0].value) - require.True(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana from: chan")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "from", flags[0].name) - require.Equal(t, "chan", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana in: chan")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "in", flags[0].name) - require.Equal(t, "chan", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana channel:chan")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "channel", flags[0].name) - require.Equal(t, "chan", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("fruit: cherry")) - require.Len(t, words, 2) - require.Equal(t, "fruit", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "cherry", words[1].value) - require.False(t, words[1].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("channel:")) - require.Len(t, words, 1) - require.Equal(t, "channel", words[0].value) - require.False(t, words[0].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("channel:first")) - require.Empty(t, words) - require.Len(t, flags, 1) - require.Equal(t, "channel", flags[0].name) - require.Equal(t, "first", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("-channel:first")) - require.Empty(t, words) - require.Len(t, flags, 1) - require.Equal(t, "channel", flags[0].name) - require.Equal(t, "first", flags[0].value) - require.True(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("channel: first in: second from:")) - require.Len(t, words, 1) - require.Equal(t, "from", words[0].value) - require.False(t, words[0].exclude) - require.Len(t, flags, 2) - require.Equal(t, "channel", flags[0].name) - require.Equal(t, "first", flags[0].value) - require.False(t, flags[0].exclude) - require.Equal(t, "in", flags[1].name) - require.Equal(t, "second", flags[1].value) - require.False(t, flags[1].exclude) - - words, flags = parseSearchFlags(splitWords("channel: first -in: second from:")) - require.Len(t, words, 1) - require.Equal(t, "from", words[0].value) - require.False(t, words[0].exclude) - require.Len(t, flags, 2) - require.Equal(t, "channel", flags[0].name) - require.Equal(t, "first", flags[0].value) - require.False(t, flags[0].exclude) - require.Equal(t, "in", flags[1].name) - require.Equal(t, "second", flags[1].value) - require.True(t, flags[1].exclude) - - words, flags = parseSearchFlags(splitWords("-channel: first in: second from:")) - require.Len(t, words, 1) - require.Equal(t, "from", words[0].value) - require.False(t, words[0].exclude) - require.Len(t, flags, 2) - require.Equal(t, "channel", flags[0].name) - require.Equal(t, "first", flags[0].value) - require.True(t, flags[0].exclude) - require.Equal(t, "in", flags[1].name) - require.Equal(t, "second", flags[1].value) - require.False(t, flags[1].exclude) - - words, flags = parseSearchFlags(splitWords("channel: first channel: second from: third from: fourth")) - require.Empty(t, words) - require.Len(t, flags, 4) - require.Equal(t, "channel", flags[0].name) - require.Equal(t, "first", flags[0].value) - require.False(t, flags[0].exclude) - require.Equal(t, "channel", flags[1].name) - require.Equal(t, "second", flags[1].value) - require.False(t, flags[1].exclude) - require.Equal(t, "from", flags[2].name) - require.Equal(t, "third", flags[2].value) - require.False(t, flags[2].exclude) - require.Equal(t, "from", flags[3].name) - require.Equal(t, "fourth", flags[3].value) - require.False(t, flags[3].exclude) - - words, flags = parseSearchFlags(splitWords("\"quoted\"")) - require.Len(t, words, 1) - require.Equal(t, "\"quoted\"", words[0].value) - require.False(t, words[0].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("\"-quoted\"")) - require.Len(t, words, 1) - require.Equal(t, "\"-quoted\"", words[0].value) - require.False(t, words[0].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("-\"quoted\"")) - require.Len(t, words, 1) - require.Equal(t, "\"quoted\"", words[0].value) - require.True(t, words[0].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("\"quoted multiple words\"")) - require.Len(t, words, 1) - require.Equal(t, "\"quoted multiple words\"", words[0].value) - require.False(t, words[0].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("\"quoted -multiple words\"")) - require.Len(t, words, 1) - require.Equal(t, "\"quoted -multiple words\"", words[0].value) - require.False(t, words[0].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("some \"stuff\" \"quoted multiple words\" some \"more stuff\"")) - require.Len(t, words, 5) - require.Equal(t, "some", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "\"stuff\"", words[1].value) - require.False(t, words[1].exclude) - require.Equal(t, "\"quoted multiple words\"", words[2].value) - require.False(t, words[2].exclude) - require.Equal(t, "some", words[3].value) - require.False(t, words[3].exclude) - require.Equal(t, "\"more stuff\"", words[4].value) - require.False(t, words[4].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("some -\"stuff\" \"quoted multiple words\" some -\"more stuff\"")) - require.Len(t, words, 5) - require.Equal(t, "some", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "\"stuff\"", words[1].value) - require.True(t, words[1].exclude) - require.Equal(t, "\"quoted multiple words\"", words[2].value) - require.False(t, words[2].exclude) - require.Equal(t, "some", words[3].value) - require.False(t, words[3].exclude) - require.Equal(t, "\"more stuff\"", words[4].value) - require.True(t, words[4].exclude) - require.Empty(t, flags) - - words, flags = parseSearchFlags(splitWords("some in:here \"stuff\" \"quoted multiple words\" from:someone \"more stuff\"")) - require.Len(t, words, 4) - require.Equal(t, "some", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "\"stuff\"", words[1].value) - require.False(t, words[1].exclude) - require.Equal(t, "\"quoted multiple words\"", words[2].value) - require.False(t, words[2].exclude) - require.Equal(t, "\"more stuff\"", words[3].value) - require.False(t, words[3].exclude) - require.Len(t, flags, 2) - require.Equal(t, "in", flags[0].name) - require.Equal(t, "here", flags[0].value) - require.False(t, flags[0].exclude) - require.Equal(t, "from", flags[1].name) - require.Equal(t, "someone", flags[1].value) - require.False(t, flags[1].exclude) - - words, flags = parseSearchFlags(splitWords("after:2018-1-1")) - require.Empty(t, words) - require.Len(t, flags, 1) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("-after:2018-1-1")) - require.Empty(t, words) - require.Len(t, flags, 1) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.True(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana after:2018-1-1")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana before:2018-1-1")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "before", flags[0].name) - require.False(t, flags[0].exclude) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana -before:2018-1-1")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "before", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.True(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana after:2018-1-1 before:2018-1-10")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 2) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - require.Equal(t, "before", flags[1].name) - require.Equal(t, "2018-1-10", flags[1].value) - require.False(t, flags[1].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana -after:2018-1-1 -before:2018-1-10")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 2) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.True(t, flags[0].exclude) - require.Equal(t, "before", flags[1].name) - require.Equal(t, "2018-1-10", flags[1].value) - require.True(t, flags[1].exclude) - - words, flags = parseSearchFlags(splitWords("#apple #banana after:2018-1-1")) - require.Len(t, words, 2) - require.Equal(t, "#apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "#banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("#apple #banana before:2018-1-1")) - require.Len(t, words, 2) - require.Equal(t, "#apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "#banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "before", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("#apple #banana after:2018-1-1 before:2018-1-10")) - require.Len(t, words, 2) - require.Equal(t, "#apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "#banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 2) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - require.Equal(t, "before", flags[1].name) - require.Equal(t, "2018-1-10", flags[1].value) - require.False(t, flags[1].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana after: 2018-1-1")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana before: 2018-1-1")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 1) - require.Equal(t, "before", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana after: 2018-1-1 before: 2018-1-10")) - require.Len(t, words, 2) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Len(t, flags, 2) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - require.Equal(t, "before", flags[1].name) - require.Equal(t, "2018-1-10", flags[1].value) - require.False(t, flags[1].exclude) - - words, flags = parseSearchFlags(splitWords("apple banana after: 2018-1-1 before: 2018-1-10 #fruit")) - require.Len(t, words, 3) - require.Equal(t, "apple", words[0].value) - require.False(t, words[0].exclude) - require.Equal(t, "banana", words[1].value) - require.False(t, words[1].exclude) - require.Equal(t, "#fruit", words[2].value) - require.False(t, words[2].exclude) - require.Len(t, flags, 2) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-1-1", flags[0].value) - require.False(t, flags[0].exclude) - require.Equal(t, "before", flags[1].name) - require.Equal(t, "2018-1-10", flags[1].value) - require.False(t, flags[1].exclude) - - words, flags = parseSearchFlags(splitWords("test after:2018-7-1")) - require.Len(t, words, 1) - require.Equal(t, "test", words[0].value) - require.False(t, words[0].exclude) - require.Len(t, flags, 1) - require.Equal(t, "after", flags[0].name) - require.Equal(t, "2018-7-1", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("test on:2018-7-1")) - require.Len(t, words, 1) - require.Equal(t, "test", words[0].value) - require.False(t, words[0].exclude) - require.Len(t, flags, 1) - require.Equal(t, "on", flags[0].name) - require.Equal(t, "2018-7-1", flags[0].value) - require.False(t, flags[0].exclude) - - words, flags = parseSearchFlags(splitWords("-on:2018-7-1 test")) - require.Len(t, words, 1) - require.Equal(t, "test", words[0].value) - require.False(t, words[0].exclude) - require.Len(t, flags, 1) - require.Equal(t, "on", flags[0].name) - require.Equal(t, "2018-7-1", flags[0].value) - require.True(t, flags[0].exclude) + Words []searchWord + Flags []flag + }{ + { + Name: "string is empty", + Input: "", + Words: []searchWord{}, + Flags: []flag{}, + }, + { + Name: "string is a single word", + Input: "word", + Words: []searchWord{ + { + value: "word", + exclude: false, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is a single word with a - prefix", + Input: "-word", + Words: []searchWord{ + { + value: "word", + exclude: true, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is multiple words all with - prefix", + Input: "-apple -banana -cherry", + Words: []searchWord{ + { + value: "apple", + exclude: true, + }, + { + value: "banana", + exclude: true, + }, + { + value: "cherry", + exclude: true, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is multiple words with a single - prefix", + Input: "apple -banana cherry", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: true, + }, + { + value: "cherry", + exclude: false, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is multiple words containing a flag", + Input: "apple banana from:chan", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "from", + value: "chan", + }, + }, + }, + { + Name: "string is multiple words containing a flag and a - prefix", + Input: "apple -banana from:chan", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: true, + }, + }, + Flags: []flag{ + { + name: "from", + value: "chan", + }, + }, + }, + { + Name: "string is multiple words containing a flag and multiple - prefixes", + Input: "-apple -banana from:chan", + Words: []searchWord{ + { + value: "apple", + exclude: true, + }, + { + value: "banana", + exclude: true, + }, + }, + Flags: []flag{ + { + name: "from", + value: "chan", + }, + }, + }, + { + Name: "string is multiple words containing a flag and multiple # prefixes", + Input: "#apple #banana from:chan", + Words: []searchWord{ + { + value: "#apple", + exclude: false, + }, + { + value: "#banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "from", + value: "chan", + }, + }, + }, + { + Name: "string is multiple words containing a flag with a single - and multiple # prefixes", + Input: "-#apple #banana from:chan", + Words: []searchWord{ + { + value: "#apple", + exclude: true, + }, + { + value: "#banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "from", + value: "chan", + }, + }, + }, + { + Name: "string is multiple words containing a flag prefixed with - and multiple # prefixes", + Input: "#apple #banana -from:chan", + Words: []searchWord{ + { + value: "#apple", + exclude: false, + }, + { + value: "#banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "from", + value: "chan", + exclude: true, + }, + }, + }, + { + Name: "string is multiple words containing a flag prefixed with multiple - and multiple # prefixes", + Input: "-#apple -#banana -from:chan", + Words: []searchWord{ + { + value: "#apple", + exclude: true, + }, + { + value: "#banana", + exclude: true, + }, + }, + Flags: []flag{ + { + name: "from", + value: "chan", + exclude: true, + }, + }, + }, + { + Name: "string is multiple words containing a flag with a space", + Input: "apple banana from: chan", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "from", + value: "chan", + }, + }, + }, + { + Name: "string is multiple words containing a in flag with a space", + Input: "apple banana in: chan", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "in", + value: "chan", + }, + }, + }, + { + Name: "string is multiple words containing a channel flag with a space", + Input: "apple banana channel: chan", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "channel", + value: "chan", + }, + }, + }, + { + Name: "string with a non-floag followed by :", + Input: "fruit: cherry", + Words: []searchWord{ + { + value: "fruit", + exclude: false, + }, + { + value: "cherry", + exclude: false, + }, + }, + Flags: []flag{}, + }, + { + Name: "string with the a flag but without the value for that flag should be threaded as a word", + Input: "channel:", + Words: []searchWord{ + { + value: "channel", + exclude: false, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is a single flag which results in a single flag", + Input: "channel:first", + Words: []searchWord{}, + Flags: []flag{ + { + name: "channel", + value: "first", + }, + }, + }, + { + Name: "single flag with - which results in a excluded flag", + Input: "-channel:first", + Words: []searchWord{}, + Flags: []flag{ + { + name: "channel", + value: "first", + exclude: true, + }, + }, + }, + { + Name: "string is multiple flags which results in multiple unexcluded flags and a single search word", + Input: "channel: first in: second from:", + Words: []searchWord{ + { + value: "from", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "channel", + value: "first", + exclude: false, + }, + { + name: "in", + value: "second", + exclude: false, + }, + }, + }, + { + Name: "string is multiple flags which results in multiple unexcluded and excluded flags and a single search word", + Input: "channel: first -in: second from:", + Words: []searchWord{ + { + value: "from", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "channel", + value: "first", + exclude: false, + }, + { + name: "in", + value: "second", + exclude: true, + }, + }, + }, + { + Name: "string is multiple flags which results in multiple excluded and unexcluded flags and a single search word", + Input: "-channel: first in: second from:", + Words: []searchWord{ + { + value: "from", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "channel", + value: "first", + exclude: true, + }, + { + name: "in", + value: "second", + exclude: false, + }, + }, + }, + { + Name: "string is four flags which results four unexcluded flags", + Input: "channel: first channel: second from: third from: fourth", + Words: []searchWord{}, + Flags: []flag{ + { + name: "channel", + value: "first", + exclude: false, + }, + { + name: "channel", + value: "second", + exclude: false, + }, + { + name: "from", + value: "third", + exclude: false, + }, + { + name: "from", + value: "fourth", + exclude: false, + }, + }, + }, + { + Name: "string is a single quoted flag which results in a single search word which is quoted", + Input: "\"quoted\"", + Words: []searchWord{ + { + value: "\"quoted\"", + exclude: false, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is a single quoted flag prefixed with a - which results in a single search word which is quoted", + Input: "\"-quoted\"", + Words: []searchWord{ + { + value: "\"-quoted\"", + exclude: false, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is a single quoted flag prefixed with a - which results in a single search word which is quoted and exported", + Input: "-\"quoted\"", + Words: []searchWord{ + { + value: "\"quoted\"", + exclude: true, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is multiple quoted flags which results in a single search word which is quoted and unexported", + Input: "\"quoted multiple words\"", + Words: []searchWord{ + { + value: "\"quoted multiple words\"", + exclude: false, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is multiple quoted flags prefixed with - which results in a single search word which is quoted and unexported", + Input: "\"quoted -multiple words\"", + Words: []searchWord{ + { + value: "\"quoted -multiple words\"", + exclude: false, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is multiple quoted flags and unquoted words", + Input: "some \"stuff\" \"quoted multiple words\" some \"more stuff\"", + Words: []searchWord{ + { + value: "some", + exclude: false, + }, + { + value: "\"stuff\"", + exclude: false, + }, + { + value: "\"quoted multiple words\"", + exclude: false, + }, + { + value: "some", + exclude: false, + }, + { + value: "\"more stuff\"", + exclude: false, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is multiple quoted flags and unquoted words some being prefixed with -", + Input: "some -\"stuff\" \"quoted multiple words\" some -\"more stuff\"", + Words: []searchWord{ + { + value: "some", + exclude: false, + }, + { + value: "\"stuff\"", + exclude: true, + }, + { + value: "\"quoted multiple words\"", + exclude: false, + }, + { + value: "some", + exclude: false, + }, + { + value: "\"more stuff\"", + exclude: true, + }, + }, + Flags: []flag{}, + }, + { + Name: "string is multiple quoted flags and unquoted words some being flags", + Input: "some in:here \"stuff\" \"quoted multiple words\" from:someone \"more stuff\"", + Words: []searchWord{ + { + value: "some", + exclude: false, + }, + { + value: "\"stuff\"", + exclude: false, + }, + { + value: "\"quoted multiple words\"", + exclude: false, + }, + { + value: "\"more stuff\"", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "in", + value: "here", + exclude: false, + }, + { + name: "from", + value: "someone", + exclude: false, + }, + }, + }, + { + Name: "string is a single flag with multiple -", + Input: "after:2018-1-1", + Words: []searchWord{}, + Flags: []flag{ + { + name: "after", + value: "2018-1-1", + exclude: false, + }, + }, + }, + { + Name: "string is a single flag with multiple - prefixed with a -", + Input: "-after:2018-1-1", + Words: []searchWord{}, + Flags: []flag{ + { + name: "after", + value: "2018-1-1", + exclude: true, + }, + }, + }, + { + Name: "string is a single flag with multiple - prefixed with two words", + Input: "apple banana before:2018-1-1", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "before", + value: "2018-1-1", + exclude: false, + }, + }, + }, + { + Name: "string is a single before flag with multiple - prefixed with - and two words", + Input: "apple banana -before:2018-1-1", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "before", + value: "2018-1-1", + exclude: true, + }, + }, + }, + { + Name: "string is multiple before/after flags with two words before", + Input: "apple banana after:2018-1-1 before:2018-1-10", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "after", + value: "2018-1-1", + exclude: false, + }, + { + name: "before", + value: "2018-1-10", + exclude: false, + }, + }, + }, + { + Name: "string is multiple before/after flags prefixed with - with two words before", + Input: "apple banana -after:2018-1-1 -before:2018-1-10", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "after", + value: "2018-1-1", + exclude: true, + }, + { + name: "before", + value: "2018-1-10", + exclude: true, + }, + }, + }, + { + Name: "string is a single after flag with two words before which are prefixed with #", + Input: "#apple #banana after:2018-1-1", + Words: []searchWord{ + { + value: "#apple", + exclude: false, + }, + { + value: "#banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "after", + value: "2018-1-1", + exclude: false, + }, + }, + }, + { + Name: "string is a single after flag with two words before which are prefixed with #", + Input: "#apple #banana before:2018-1-1", + Words: []searchWord{ + { + value: "#apple", + exclude: false, + }, + { + value: "#banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "before", + value: "2018-1-1", + exclude: false, + }, + }, + }, + { + Name: "string is two after and before flags with two words before which are prefixed with #", + Input: "#apple #banana after:2018-1-1 before:2018-1-10", + Words: []searchWord{ + { + value: "#apple", + exclude: false, + }, + { + value: "#banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "after", + value: "2018-1-1", + exclude: false, + }, + { + name: "before", + value: "2018-1-10", + exclude: false, + }, + }, + }, + { + Name: "string is a single after flag with two words before", + Input: "apple banana after: 2018-1-1", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "after", + value: "2018-1-1", + exclude: false, + }, + }, + }, + { + Name: "string is a single before flag with two words before", + Input: "apple banana before: 2018-1-1", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "before", + value: "2018-1-1", + exclude: false, + }, + }, + }, + { + Name: "string is two after and before flags with two words before", + Input: "apple banana after: 2018-1-1 before: 2018-1-10", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "after", + value: "2018-1-1", + exclude: false, + }, + { + name: "before", + value: "2018-1-10", + exclude: false, + }, + }, + }, + { + Name: "string is two after and before flags with two words before and a single after", + Input: "apple banana after: 2018-1-1 before: 2018-1-10 #fruit", + Words: []searchWord{ + { + value: "apple", + exclude: false, + }, + { + value: "banana", + exclude: false, + }, + { + value: "#fruit", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "after", + value: "2018-1-1", + exclude: false, + }, + { + name: "before", + value: "2018-1-10", + exclude: false, + }, + }, + }, + { + Name: "string is one after flag with one word before", + Input: "test after:2018-7-1", + Words: []searchWord{ + { + value: "test", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "after", + value: "2018-7-1", + exclude: false, + }, + }, + }, + { + Name: "string is one on flag with one word before", + Input: "test on:2018-7-1", + Words: []searchWord{ + { + value: "test", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "on", + value: "2018-7-1", + exclude: false, + }, + }, + }, + { + Name: "string is one excluded on flag with one word after", + Input: "-on:2018-7-1 test", + Words: []searchWord{ + { + value: "test", + exclude: false, + }, + }, + Flags: []flag{ + { + name: "on", + value: "2018-7-1", + exclude: true, + }, + }, + }, + } { + t.Run(testCase.Name, func(t *testing.T) { + words, flags := parseSearchFlags(splitWords(testCase.Input)) + require.Equal(t, testCase.Words, words) + require.Equal(t, testCase.Flags, flags) + }) + } } func TestParseSearchParams(t *testing.T) { - sp := ParseSearchParams("", 0) - require.Empty(t, sp) + for _, testCase := range []struct { + Name string + Input string - sp = ParseSearchParams(" ", 0) - require.Empty(t, sp) - - sp = ParseSearchParams("words words", 0) - require.Len(t, sp, 1) - require.Equal(t, "words words", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("word1 -word2", 0) - require.Len(t, sp, 1) - require.Equal(t, "word1", sp[0].Terms) - require.Equal(t, "word2", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("-word1 -word2", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "word1 word2", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("\"my stuff\"", 0) - require.Len(t, sp, 1) - require.Equal(t, "\"my stuff\"", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("-\"my stuff\"", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "\"my stuff\"", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("#words #words", 0) - require.Len(t, sp, 1) - require.Equal(t, "#words #words", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.True(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("#words words", 0) - require.Len(t, sp, 2) - require.Equal(t, "words", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Equal(t, "#words", sp[1].Terms) - require.Equal(t, "", sp[1].ExcludedTerms) - require.True(t, sp[1].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - require.Empty(t, sp[1].InChannels) - require.Empty(t, sp[1].ExcludedChannels) - require.Empty(t, sp[1].FromUsers) - require.Empty(t, sp[1].ExcludedUsers) - - sp = ParseSearchParams("-#hashtag", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "#hashtag", sp[0].ExcludedTerms) - require.True(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("-#hashtag1 -#hashtag2", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "#hashtag1 #hashtag2", sp[0].ExcludedTerms) - require.True(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("#hashtag1 -#hashtag2", 0) - require.Len(t, sp, 1) - require.Equal(t, "#hashtag1", sp[0].Terms) - require.Equal(t, "#hashtag2", sp[0].ExcludedTerms) - require.True(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("word1 #hashtag1 -#hashtag2 -word2", 0) - require.Len(t, sp, 2) - require.Equal(t, "word1", sp[0].Terms) - require.Equal(t, "word2", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Equal(t, "#hashtag1", sp[1].Terms) - require.Equal(t, "#hashtag2", sp[1].ExcludedTerms) - require.True(t, sp[1].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - require.Empty(t, sp[1].InChannels) - require.Empty(t, sp[1].ExcludedChannels) - require.Empty(t, sp[1].FromUsers) - require.Empty(t, sp[1].ExcludedUsers) - - sp = ParseSearchParams("in:channel", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Len(t, sp[0].InChannels, 1) - require.Equal(t, "channel", sp[0].InChannels[0]) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("-in:channel", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Len(t, sp[0].ExcludedChannels, 1) - require.Equal(t, "channel", sp[0].ExcludedChannels[0]) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("in: channel", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Len(t, sp[0].InChannels, 1) - require.Equal(t, "channel", sp[0].InChannels[0]) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("testing in:channel", 0) - require.Len(t, sp, 1) - require.Equal(t, "testing", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Len(t, sp[0].InChannels, 1) - require.Equal(t, "channel", sp[0].InChannels[0]) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("testing -in:channel", 0) - require.Len(t, sp, 1) - require.Equal(t, "testing", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Len(t, sp[0].ExcludedChannels, 1) - require.Equal(t, "channel", sp[0].ExcludedChannels[0]) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("in:channel testing", 0) - require.Len(t, sp, 1) - require.Equal(t, "testing", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Len(t, sp[0].InChannels, 1) - require.Equal(t, "channel", sp[0].InChannels[0]) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("in:channel in:otherchannel", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Len(t, sp[0].InChannels, 2) - require.Equal(t, "channel", sp[0].InChannels[0]) - require.Equal(t, "otherchannel", sp[0].InChannels[1]) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("testing in:channel from:someone", 0) - require.Len(t, sp, 1) - require.Equal(t, "testing", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Len(t, sp[0].InChannels, 1) - require.Equal(t, "channel", sp[0].InChannels[0]) - require.Empty(t, sp[0].ExcludedChannels) - require.Len(t, sp[0].FromUsers, 1) - require.Equal(t, "someone", sp[0].FromUsers[0]) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("testing in:channel -from:someone", 0) - require.Len(t, sp, 1) - require.Equal(t, "testing", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Len(t, sp[0].InChannels, 1) - require.Equal(t, "channel", sp[0].InChannels[0]) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Len(t, sp[0].ExcludedUsers, 1) - require.Equal(t, "someone", sp[0].ExcludedUsers[0]) - - sp = ParseSearchParams("testing in:channel from:someone -from:someoneelse", 0) - require.Len(t, sp, 1) - require.Equal(t, "testing", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Len(t, sp[0].InChannels, 1) - require.Equal(t, "channel", sp[0].InChannels[0]) - require.Empty(t, sp[0].ExcludedChannels) - require.Len(t, sp[0].FromUsers, 1) - require.Equal(t, "someone", sp[0].FromUsers[0]) - require.Len(t, sp[0].ExcludedUsers, 1) - require.Equal(t, "someoneelse", sp[0].ExcludedUsers[0]) - - sp = ParseSearchParams("##hashtag +#plus+", 0) - require.Len(t, sp, 1) - require.Equal(t, "#hashtag #plus", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.True(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("wildcar*", 0) - require.Len(t, sp, 1) - require.Equal(t, "wildcar*", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.False(t, sp[0].IsHashtag) - require.Empty(t, sp[0].InChannels) - require.Empty(t, sp[0].ExcludedChannels) - require.Empty(t, sp[0].FromUsers) - require.Empty(t, sp[0].ExcludedUsers) - - sp = ParseSearchParams("after:2018-8-1 testing", 0) - require.Len(t, sp, 1) - require.Equal(t, "testing", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.Equal(t, "2018-8-1", sp[0].AfterDate) - require.Equal(t, "", sp[0].ExcludedAfterDate) - - sp = ParseSearchParams("-after:2018-8-1 testing", 0) - require.Len(t, sp, 1) - require.Equal(t, "testing", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.Equal(t, "", sp[0].AfterDate) - require.Equal(t, "2018-8-1", sp[0].ExcludedAfterDate) - - sp = ParseSearchParams("on:2018-8-1 testing", 0) - require.Len(t, sp, 1) - require.Equal(t, "testing", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.Equal(t, "2018-8-1", sp[0].OnDate) - require.Equal(t, "", sp[0].ExcludedDate) - - sp = ParseSearchParams("-on:2018-8-1 testing", 0) - require.Len(t, sp, 1) - require.Equal(t, "testing", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.Equal(t, "", sp[0].OnDate) - require.Equal(t, "2018-8-1", sp[0].ExcludedDate) - - sp = ParseSearchParams("after:2018-8-1", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.Equal(t, "2018-8-1", sp[0].AfterDate) - require.Equal(t, "", sp[0].ExcludedAfterDate) - - sp = ParseSearchParams("before:2018-8-1", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.Equal(t, "2018-8-1", sp[0].BeforeDate) - require.Equal(t, "", sp[0].ExcludedBeforeDate) - - sp = ParseSearchParams("-before:2018-8-1", 0) - require.Len(t, sp, 1) - require.Equal(t, "", sp[0].Terms) - require.Equal(t, "", sp[0].ExcludedTerms) - require.Equal(t, "2018-8-1", sp[0].ExcludedBeforeDate) - require.Equal(t, "", sp[0].BeforeDate) + Output []*SearchParams + }{ + { + Name: "input is empty should result in no params", + Input: "", + Output: []*SearchParams{}, + }, + { + Name: "input is only spaces should result in no params", + Input: " ", + Output: []*SearchParams{}, + }, + { + Name: "input is two words should result in one param", + Input: "words words", + Output: []*SearchParams{ + { + Terms: "words words", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two words should result in one param with two excluded terms", + Input: "-word1 -word2", + Output: []*SearchParams{ + { + Terms: "", + ExcludedTerms: "word1 word2", + IsHashtag: false, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two quoted words should result in one term", + Input: "\"my stuff\"", + Output: []*SearchParams{ + { + Terms: "\"my stuff\"", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two quoted words should result in one excluded term", + Input: "-\"my stuff\"", + Output: []*SearchParams{ + { + Terms: "", + ExcludedTerms: "\"my stuff\"", + IsHashtag: false, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two words prefixed with hashtags should result in one term", + Input: "#words #words", + Output: []*SearchParams{ + { + Terms: "#words #words", + ExcludedTerms: "", + IsHashtag: true, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two words one is prefixed with a hashtag should result in two terms", + Input: "#words words", + Output: []*SearchParams{ + { + Terms: "words", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + { + Terms: "#words", + ExcludedTerms: "", + IsHashtag: true, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is one word prefixed with hashtag and a dash should result in one excluded term", + Input: "-#hashtag", + Output: []*SearchParams{ + { + Terms: "", + ExcludedTerms: "#hashtag", + IsHashtag: true, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two words prefixed with hashtags and dashes should result in excluded term", + Input: "-#hashtag1 -#hashtag2", + Output: []*SearchParams{ + { + Terms: "", + ExcludedTerms: "#hashtag1 #hashtag2", + IsHashtag: true, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two words prefixed with hashtags and one dash should result in excluded and nonexcluded term", + Input: "#hashtag1 -#hashtag2", + Output: []*SearchParams{ + { + Terms: "#hashtag1", + ExcludedTerms: "#hashtag2", + IsHashtag: true, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is 4 words prefixed with hashtags and a dash should result in excluded and nonexcluded multiple SearchParams", + Input: "word1 #hashtag1 -#hashtag2 -word2", + Output: []*SearchParams{ + { + Terms: "word1", + ExcludedTerms: "word2", + IsHashtag: false, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + { + Terms: "#hashtag1", + ExcludedTerms: "#hashtag2", + IsHashtag: true, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two words seperated with : and should result in a single InChannel", + Input: "in:channel", + Output: []*SearchParams{ + { + Terms: "", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{"channel"}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two words seperated with :, prefied with - and should result in a single ExcludedChannel", + Input: "-in:channel", + Output: []*SearchParams{ + { + Terms: "", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{}, + ExcludedChannels: []string{"channel"}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two words seperated with : with a prefixed word should result in a single InChannel and a term", + Input: "testing in:channel", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{"channel"}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two words seperated with : with a prefixed word should result in a single ExcludedChannel and a term", + Input: "testing -in:channel", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{}, + ExcludedChannels: []string{"channel"}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is two words seperated with : with a postfix word should result in a single InChannel and a term", + Input: "in:channel testing", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{"channel"}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is four words seperated with : should result in a two InChannels", + Input: "in:channel in:otherchannel", + Output: []*SearchParams{ + { + Terms: "", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{"channel", "otherchannel"}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is four words seperated with : prefixed with a word should result in two InChannels and one term", + Input: "testing in:channel in:otherchannel", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{"channel", "otherchannel"}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is four words seperated with : prefixed with a word should result in one InChannel, one FromUser and one term", + Input: "testing in:channel from:someone", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{"channel"}, + ExcludedChannels: []string{}, + FromUsers: []string{"someone"}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is four words seperated with : prefixed with a word should result in one InChannel, one ExcludedUser and one term", + Input: "testing in:channel -from:someone", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{"channel"}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{"someone"}, + }, + }, + }, + { + Name: "input is six words seperated with : prefixed with a word should result in one InChannel, one FromUser, one ExcludedUser and one term", + Input: "testing in:channel from:someone -from:someoneelse", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{"channel"}, + ExcludedChannels: []string{}, + FromUsers: []string{"someone"}, + ExcludedUsers: []string{"someoneelse"}, + }, + }, + }, + { + Name: "input is two words first one is prefixed with two #, should result in one term with IsHashtag = true, pluses should be removed", + Input: "##hashtag +#plus+", + Output: []*SearchParams{ + { + Terms: "#hashtag #plus", + ExcludedTerms: "", + IsHashtag: true, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is a wilrdcar with a *, should result in one term with a *", + Input: "wildcar*", + Output: []*SearchParams{ + { + Terms: "wildcar*", + ExcludedTerms: "", + IsHashtag: false, + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is an after date with one word, should in one AfterDate and one term", + Input: "after:2018-8-1 testing", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + AfterDate: "2018-8-1", + ExcludedAfterDate: "", + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is an after date with one word, should in one ExcludedAfterDate and one term", + Input: "-after:2018-8-1 testing", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + AfterDate: "", + ExcludedAfterDate: "2018-8-1", + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is an on date with one word, should in one OnDate and one term", + Input: "on:2018-8-1 testing", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + OnDate: "2018-8-1", + AfterDate: "", + ExcludedAfterDate: "", + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is an on date with one word, should in one ExcludedDate and one term", + Input: "-on:2018-8-1 testing", + Output: []*SearchParams{ + { + Terms: "testing", + ExcludedTerms: "", + AfterDate: "", + ExcludedDate: "2018-8-1", + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is an after date, should in one AfterDate", + Input: "after:2018-8-1", + Output: []*SearchParams{ + { + Terms: "", + ExcludedTerms: "", + AfterDate: "2018-8-1", + ExcludedDate: "", + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is an before date, should in one BeforeDate", + Input: "before:2018-8-1", + Output: []*SearchParams{ + { + Terms: "", + ExcludedTerms: "", + BeforeDate: "2018-8-1", + AfterDate: "", + ExcludedDate: "", + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + { + Name: "input is an before date, should in one ExcludedBeforeDate", + Input: "-before:2018-8-1", + Output: []*SearchParams{ + { + Terms: "", + ExcludedTerms: "", + BeforeDate: "", + AfterDate: "", + ExcludedBeforeDate: "2018-8-1", + InChannels: []string{}, + ExcludedChannels: []string{}, + FromUsers: []string{}, + ExcludedUsers: []string{}, + }, + }, + }, + } { + t.Run(testCase.Name, func(t *testing.T) { + require.Equal(t, testCase.Output, ParseSearchParams(testCase.Input, 0)) + }) + } } func TestGetOnDateMillis(t *testing.T) {