diff options
| -rw-r--r-- | android/util.go | 44 | ||||
| -rw-r--r-- | android/util_test.go | 114 |
2 files changed, 153 insertions, 5 deletions
diff --git a/android/util.go b/android/util.go index 0ee253e59..47c45833b 100644 --- a/android/util.go +++ b/android/util.go @@ -65,21 +65,55 @@ func JoinWithSuffix(strs []string, suffix string, separator string) string { return buf.String() } -// SorterStringKeys returns the keys of the given string-keyed map in the ascending order +// SorterStringKeys returns the keys of the given string-keyed map in the ascending order. func SortedStringKeys(m interface{}) []string { v := reflect.ValueOf(m) if v.Kind() != reflect.Map { panic(fmt.Sprintf("%#v is not a map", m)) } - keys := v.MapKeys() - s := make([]string, 0, len(keys)) - for _, key := range keys { - s = append(s, key.String()) + if v.Len() == 0 { + return nil + } + iter := v.MapRange() + s := make([]string, 0, v.Len()) + for iter.Next() { + s = append(s, iter.Key().String()) + } + sort.Strings(s) + return s +} + +// stringValues returns the values of the given string-valued map in randomized map order. +func stringValues(m interface{}) []string { + v := reflect.ValueOf(m) + if v.Kind() != reflect.Map { + panic(fmt.Sprintf("%#v is not a map", m)) + } + if v.Len() == 0 { + return nil } + iter := v.MapRange() + s := make([]string, 0, v.Len()) + for iter.Next() { + s = append(s, iter.Value().String()) + } + return s +} + +// SortedStringValues returns the values of the given string-valued map in the ascending order. +func SortedStringValues(m interface{}) []string { + s := stringValues(m) sort.Strings(s) return s } +// SortedUniqueStringValues returns the values of the given string-valued map in the ascending order +// with duplicates removed. +func SortedUniqueStringValues(m interface{}) []string { + s := stringValues(m) + return SortedUniqueStrings(s) +} + // IndexList returns the index of the first occurrence of the given string in the list or -1 func IndexList(s string, list []string) int { for i, l := range list { diff --git a/android/util_test.go b/android/util_test.go index 09bec01cc..9b9253b49 100644 --- a/android/util_test.go +++ b/android/util_test.go @@ -640,3 +640,117 @@ func BenchmarkFirstUniqueStrings(b *testing.B) { }) } } + +func TestSortedStringKeys(t *testing.T) { + testCases := []struct { + name string + in interface{} + expected []string + }{ + { + name: "nil", + in: map[string]string(nil), + expected: nil, + }, + { + name: "empty", + in: map[string]string{}, + expected: nil, + }, + { + name: "simple", + in: map[string]string{"a": "foo", "b": "bar"}, + expected: []string{"a", "b"}, + }, + { + name: "interface values", + in: map[string]interface{}{"a": nil, "b": nil}, + expected: []string{"a", "b"}, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + got := SortedStringKeys(tt.in) + if g, w := got, tt.expected; !reflect.DeepEqual(g, w) { + t.Errorf("wanted %q, got %q", w, g) + } + }) + } +} + +func TestSortedStringValues(t *testing.T) { + testCases := []struct { + name string + in interface{} + expected []string + }{ + { + name: "nil", + in: map[string]string(nil), + expected: nil, + }, + { + name: "empty", + in: map[string]string{}, + expected: nil, + }, + { + name: "simple", + in: map[string]string{"foo": "a", "bar": "b"}, + expected: []string{"a", "b"}, + }, + { + name: "duplicates", + in: map[string]string{"foo": "a", "bar": "b", "baz": "b"}, + expected: []string{"a", "b", "b"}, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + got := SortedStringValues(tt.in) + if g, w := got, tt.expected; !reflect.DeepEqual(g, w) { + t.Errorf("wanted %q, got %q", w, g) + } + }) + } +} + +func TestSortedUniqueStringValues(t *testing.T) { + testCases := []struct { + name string + in interface{} + expected []string + }{ + { + name: "nil", + in: map[string]string(nil), + expected: nil, + }, + { + name: "empty", + in: map[string]string{}, + expected: nil, + }, + { + name: "simple", + in: map[string]string{"foo": "a", "bar": "b"}, + expected: []string{"a", "b"}, + }, + { + name: "duplicates", + in: map[string]string{"foo": "a", "bar": "b", "baz": "b"}, + expected: []string{"a", "b"}, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + got := SortedUniqueStringValues(tt.in) + if g, w := got, tt.expected; !reflect.DeepEqual(g, w) { + t.Errorf("wanted %q, got %q", w, g) + } + }) + } +} |