371 lines
9.9 KiB
Go
371 lines
9.9 KiB
Go
package search
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
var trueBool = true
|
|
|
|
func TestStandardSearchString(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
query Query
|
|
out string
|
|
}{
|
|
{
|
|
name: "empty query",
|
|
out: "",
|
|
},
|
|
{
|
|
name: "converts query to string",
|
|
query: Query{
|
|
Keywords: []string{"some", "keywords"},
|
|
Qualifiers: Qualifiers{
|
|
Archived: &trueBool,
|
|
AuthorEmail: "foo@example.com",
|
|
CommitterDate: "2021-02-28",
|
|
Created: "created",
|
|
Extension: "go",
|
|
Filename: ".vimrc",
|
|
Followers: "1",
|
|
Fork: "true",
|
|
Forks: "2",
|
|
GoodFirstIssues: "3",
|
|
HelpWantedIssues: "4",
|
|
In: []string{"description", "readme"},
|
|
Language: "language",
|
|
License: []string{"license"},
|
|
Pushed: "updated",
|
|
Size: "5",
|
|
Stars: "6",
|
|
Topic: []string{"topic"},
|
|
Topics: "7",
|
|
User: []string{"user1", "user2"},
|
|
Is: []string{"public"},
|
|
},
|
|
},
|
|
out: "some keywords archived:true author-email:foo@example.com committer-date:2021-02-28 " +
|
|
"created:created extension:go filename:.vimrc followers:1 fork:true forks:2 good-first-issues:3 help-wanted-issues:4 " +
|
|
"in:description in:readme is:public language:language license:license pushed:updated size:5 " +
|
|
"stars:6 topic:topic topics:7 user:user1 user:user2",
|
|
},
|
|
{
|
|
name: "quotes keywords",
|
|
query: Query{
|
|
Keywords: []string{"quote keywords"},
|
|
},
|
|
out: `"quote keywords"`,
|
|
},
|
|
{
|
|
name: "quotes keywords that are qualifiers",
|
|
query: Query{
|
|
Keywords: []string{"quote:keywords", "quote:multiword keywords"},
|
|
},
|
|
out: `quote:keywords quote:"multiword keywords"`,
|
|
},
|
|
{
|
|
name: "quotes qualifiers",
|
|
query: Query{
|
|
Qualifiers: Qualifiers{
|
|
Topic: []string{"quote qualifier"},
|
|
},
|
|
},
|
|
out: `topic:"quote qualifier"`,
|
|
},
|
|
{
|
|
name: "respects immutable keywords",
|
|
query: Query{
|
|
ImmutableKeywords: "immutable keyword that should be left as is",
|
|
},
|
|
out: `immutable keyword that should be left as is`,
|
|
},
|
|
{
|
|
name: "respects immutable keywords, with qualifiers",
|
|
query: Query{
|
|
ImmutableKeywords: "immutable keyword that should be left as is",
|
|
Qualifiers: Qualifiers{
|
|
Topic: []string{"quote qualifier"},
|
|
},
|
|
},
|
|
out: `immutable keyword that should be left as is topic:"quote qualifier"`,
|
|
},
|
|
{
|
|
name: "prioritises immutable keywords over keywords slice",
|
|
query: Query{
|
|
Keywords: []string{"foo", "bar"},
|
|
ImmutableKeywords: "immutable keyword",
|
|
},
|
|
out: `immutable keyword`,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.out, tt.query.StandardSearchString())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAdvancedIssueSearchString(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
query Query
|
|
out string
|
|
}{
|
|
{
|
|
name: "empty query",
|
|
out: "",
|
|
},
|
|
{
|
|
name: "quotes keywords",
|
|
query: Query{
|
|
Keywords: []string{"quote keywords"},
|
|
},
|
|
out: `"quote keywords"`,
|
|
},
|
|
{
|
|
name: "quotes keywords that are qualifiers",
|
|
query: Query{
|
|
Keywords: []string{"quote:keywords", "quote:multiword keywords"},
|
|
},
|
|
out: `quote:keywords quote:"multiword keywords"`,
|
|
},
|
|
{
|
|
name: "quotes qualifiers",
|
|
query: Query{
|
|
Qualifiers: Qualifiers{
|
|
Label: []string{"quote qualifier"},
|
|
},
|
|
},
|
|
out: `label:"quote qualifier"`,
|
|
},
|
|
{
|
|
name: "respects immutable keywords",
|
|
query: Query{
|
|
ImmutableKeywords: "immutable keyword that should be left as is",
|
|
},
|
|
out: `immutable keyword that should be left as is`,
|
|
},
|
|
{
|
|
name: "respects immutable keywords, with qualifiers",
|
|
query: Query{
|
|
ImmutableKeywords: "immutable keyword that should be left as is",
|
|
Qualifiers: Qualifiers{
|
|
Topic: []string{"quote qualifier"},
|
|
},
|
|
},
|
|
out: `( immutable keyword that should be left as is ) topic:"quote qualifier"`,
|
|
},
|
|
{
|
|
name: "prioritises immutable keywords over keywords slice",
|
|
query: Query{
|
|
Keywords: []string{"foo", "bar"},
|
|
ImmutableKeywords: "immutable keyword",
|
|
},
|
|
out: `immutable keyword`,
|
|
},
|
|
{
|
|
name: "unused qualifiers should not appear in query",
|
|
query: Query{
|
|
Keywords: []string{"keyword"},
|
|
Qualifiers: Qualifiers{
|
|
Label: []string{"foo", "bar"},
|
|
},
|
|
},
|
|
out: `( keyword ) label:bar label:foo`,
|
|
},
|
|
{
|
|
name: "special qualifiers when used once",
|
|
query: Query{
|
|
Keywords: []string{"keyword"},
|
|
Qualifiers: Qualifiers{
|
|
Repo: []string{"foo/bar"},
|
|
Is: []string{"private"},
|
|
User: []string{"johndoe"},
|
|
In: []string{"title"},
|
|
},
|
|
},
|
|
out: `( keyword ) in:title is:private repo:foo/bar user:johndoe`,
|
|
},
|
|
{
|
|
name: "special qualifiers are OR-ed when used multiple times",
|
|
query: Query{
|
|
Keywords: []string{"keyword"},
|
|
Qualifiers: Qualifiers{
|
|
Repo: []string{"foo/bar", "foo/baz"},
|
|
Is: []string{"private", "public", "issue", "pr", "open", "closed", "locked", "unlocked", "merged", "unmerged", "blocked", "blocking", "foo"}, // "foo" is to ensure only "public" and "private" are grouped
|
|
User: []string{"johndoe", "janedoe"},
|
|
In: []string{"title", "body", "comments", "foo"}, // "foo" is to ensure only "title", "body", and "comments" are grouped
|
|
},
|
|
},
|
|
out: `( keyword ) (in:body OR in:comments OR in:title) in:foo (is:blocked OR is:blocking) (is:closed OR is:open) (is:issue OR is:pr) (is:locked OR is:unlocked) (is:merged OR is:unmerged) (is:private OR is:public) is:foo (repo:foo/bar OR repo:foo/baz) (user:janedoe OR user:johndoe)`,
|
|
},
|
|
{
|
|
// Since this is a general purpose package, we can't assume with know all
|
|
// use cases of special qualifiers. So, here we ensure unknown values are
|
|
// not OR-ed by default.
|
|
name: "special qualifiers without special values",
|
|
query: Query{
|
|
Keywords: []string{"keyword"},
|
|
Qualifiers: Qualifiers{
|
|
Is: []string{"foo", "bar"},
|
|
In: []string{"foo", "bar"},
|
|
},
|
|
},
|
|
out: `( keyword ) in:bar in:foo is:bar is:foo`,
|
|
},
|
|
{
|
|
name: "non-special qualifiers used multiple times",
|
|
query: Query{
|
|
Keywords: []string{"keyword"},
|
|
Qualifiers: Qualifiers{
|
|
In: []string{"foo", "bar"}, // "in:" is a special qualifier but its values here are not special
|
|
Is: []string{"foo", "bar"}, // "is:" is a special qualifier but its values here are not special
|
|
Label: []string{"foo", "bar"},
|
|
License: []string{"foo", "bar"},
|
|
No: []string{"foo", "bar"},
|
|
Topic: []string{"foo", "bar"},
|
|
},
|
|
},
|
|
out: `( keyword ) in:bar in:foo is:bar is:foo label:bar label:foo license:bar license:foo no:bar no:foo topic:bar topic:foo`,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.out, tt.query.AdvancedIssueSearchString())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestQualifiersMap(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
qualifiers Qualifiers
|
|
out map[string][]string
|
|
}{
|
|
{
|
|
name: "changes qualifiers to map",
|
|
qualifiers: Qualifiers{
|
|
Archived: &trueBool,
|
|
AuthorEmail: "foo@example.com",
|
|
CommitterDate: "2021-02-28",
|
|
Created: "created",
|
|
Extension: "go",
|
|
Filename: ".vimrc",
|
|
Followers: "1",
|
|
Fork: "true",
|
|
Forks: "2",
|
|
GoodFirstIssues: "3",
|
|
HelpWantedIssues: "4",
|
|
In: []string{"readme"},
|
|
Is: []string{"public"},
|
|
Language: "language",
|
|
License: []string{"license"},
|
|
Pushed: "updated",
|
|
Size: "5",
|
|
Stars: "6",
|
|
Topic: []string{"topic"},
|
|
Topics: "7",
|
|
User: []string{"user1", "user2"},
|
|
},
|
|
out: map[string][]string{
|
|
"archived": {"true"},
|
|
"author-email": {"foo@example.com"},
|
|
"committer-date": {"2021-02-28"},
|
|
"created": {"created"},
|
|
"extension": {"go"},
|
|
"filename": {".vimrc"},
|
|
"followers": {"1"},
|
|
"fork": {"true"},
|
|
"forks": {"2"},
|
|
"good-first-issues": {"3"},
|
|
"help-wanted-issues": {"4"},
|
|
"in": {"readme"},
|
|
"is": {"public"},
|
|
"language": {"language"},
|
|
"license": {"license"},
|
|
"pushed": {"updated"},
|
|
"size": {"5"},
|
|
"stars": {"6"},
|
|
"topic": {"topic"},
|
|
"topics": {"7"},
|
|
"user": {"user1", "user2"},
|
|
},
|
|
},
|
|
{
|
|
name: "excludes unset qualifiers from map",
|
|
qualifiers: Qualifiers{
|
|
Pushed: "updated",
|
|
Size: "5",
|
|
Stars: "6",
|
|
User: []string{"user"},
|
|
},
|
|
out: map[string][]string{
|
|
"pushed": {"updated"},
|
|
"size": {"5"},
|
|
"stars": {"6"},
|
|
"user": {"user"},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.out, tt.qualifiers.Map())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCamelToKebab(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
in string
|
|
out string
|
|
}{
|
|
{
|
|
name: "single lowercase word",
|
|
in: "test",
|
|
out: "test",
|
|
},
|
|
{
|
|
name: "multiple mixed words",
|
|
in: "testTestTest",
|
|
out: "test-test-test",
|
|
},
|
|
{
|
|
name: "multiple uppercase words",
|
|
in: "TestTest",
|
|
out: "test-test",
|
|
},
|
|
{
|
|
name: "multiple lowercase words",
|
|
in: "testtest",
|
|
out: "testtest",
|
|
},
|
|
{
|
|
name: "multiple mixed words with number",
|
|
in: "test2Test",
|
|
out: "test2-test",
|
|
},
|
|
{
|
|
name: "multiple lowercase words with number",
|
|
in: "test2test",
|
|
out: "test2test",
|
|
},
|
|
{
|
|
name: "multiple lowercase words with dash",
|
|
in: "test-test",
|
|
out: "test-test",
|
|
},
|
|
{
|
|
name: "multiple uppercase words with dash",
|
|
in: "Test-Test",
|
|
out: "test--test",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert.Equal(t, tt.out, camelToKebab(tt.in))
|
|
})
|
|
}
|
|
}
|