github.com/david-imola/snapd@v0.0.0-20210611180407-2de8ddeece6d/strutil/strutil_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2014-2020 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package strutil_test 21 22 import ( 23 "math" 24 "sort" 25 "testing" 26 27 "gopkg.in/check.v1" 28 29 "github.com/snapcore/snapd/strutil" 30 ) 31 32 func Test(t *testing.T) { check.TestingT(t) } 33 34 type strutilSuite struct{} 35 36 var _ = check.Suite(&strutilSuite{}) 37 38 func (*strutilSuite) TestQuoted(c *check.C) { 39 for _, t := range []struct { 40 in []string 41 out string 42 }{ 43 {nil, ""}, 44 {[]string{}, ""}, 45 {[]string{"one"}, `"one"`}, 46 {[]string{"one", "two"}, `"one", "two"`}, 47 {[]string{"one", `tw"`}, `"one", "tw\""`}, 48 } { 49 c.Check(strutil.Quoted(t.in), check.Equals, t.out, check.Commentf("expected %#v -> %s", t.in, t.out)) 50 } 51 } 52 53 func (ts *strutilSuite) TestSizeToStr(c *check.C) { 54 for _, t := range []struct { 55 size int64 56 str string 57 }{ 58 {0, "0B"}, 59 {1, "1B"}, 60 {400, "400B"}, 61 {1000, "1kB"}, 62 {1000 + 1, "1kB"}, 63 {900 * 1000, "900kB"}, 64 {1000 * 1000, "1MB"}, 65 {20 * 1000 * 1000, "20MB"}, 66 {1000 * 1000 * 1000, "1GB"}, 67 {31 * 1000 * 1000 * 1000, "31GB"}, 68 {math.MaxInt64, "9EB"}, 69 } { 70 c.Check(strutil.SizeToStr(t.size), check.Equals, t.str) 71 } 72 } 73 74 func (ts *strutilSuite) TestListContains(c *check.C) { 75 for _, xs := range [][]string{ 76 {}, 77 nil, 78 {"foo"}, 79 {"foo", "baz", "barbar"}, 80 } { 81 c.Check(strutil.ListContains(xs, "bar"), check.Equals, false) 82 sort.Strings(xs) 83 c.Check(strutil.SortedListContains(xs, "bar"), check.Equals, false) 84 } 85 86 for _, xs := range [][]string{ 87 {"bar"}, 88 {"foo", "bar", "baz"}, 89 {"bar", "foo", "baz"}, 90 {"foo", "baz", "bar"}, 91 {"bar", "bar", "bar", "bar", "bar", "bar"}, 92 } { 93 c.Check(strutil.ListContains(xs, "bar"), check.Equals, true) 94 sort.Strings(xs) 95 c.Check(strutil.SortedListContains(xs, "bar"), check.Equals, true) 96 } 97 } 98 99 func (ts *strutilSuite) TestTruncateOutput(c *check.C) { 100 data := []byte("ab\ncd\nef\ngh\nij") 101 out := strutil.TruncateOutput(data, 3, 500) 102 c.Assert(out, check.DeepEquals, []byte("ef\ngh\nij")) 103 104 out = strutil.TruncateOutput(data, 1000, 8) 105 c.Assert(out, check.DeepEquals, []byte("ef\ngh\nij")) 106 107 out = strutil.TruncateOutput(data, 1000, 1000) 108 c.Assert(out, check.DeepEquals, []byte("ab\ncd\nef\ngh\nij")) 109 110 out = strutil.TruncateOutput(data, 99, 5) 111 c.Assert(out, check.DeepEquals, []byte("gh\nij")) 112 113 out = strutil.TruncateOutput(data, 99, 6) 114 c.Assert(out, check.DeepEquals, []byte("\ngh\nij")) 115 116 out = strutil.TruncateOutput(data, 5, 1000) 117 c.Assert(out, check.DeepEquals, []byte("ab\ncd\nef\ngh\nij")) 118 119 out = strutil.TruncateOutput(data, 1000, len(data)) 120 c.Assert(out, check.DeepEquals, []byte("ab\ncd\nef\ngh\nij")) 121 122 out = strutil.TruncateOutput(data, 1000, 1000) 123 c.Assert(out, check.DeepEquals, []byte("ab\ncd\nef\ngh\nij")) 124 125 out = strutil.TruncateOutput(data, 0, 0) 126 c.Assert(out, check.HasLen, 0) 127 } 128 129 func (ts *strutilSuite) TestParseByteSizeHappy(c *check.C) { 130 for _, t := range []struct { 131 str string 132 expected int64 133 }{ 134 {"0B", 0}, 135 {"1B", 1}, 136 {"400B", 400}, 137 {"1kB", 1000}, 138 // note the upper-case 139 {"1KB", 1000}, 140 {"900kB", 900 * 1000}, 141 {"1MB", 1000 * 1000}, 142 {"20MB", 20 * 1000 * 1000}, 143 {"1GB", 1000 * 1000 * 1000}, 144 {"31GB", 31 * 1000 * 1000 * 1000}, 145 {"4TB", 4 * 1000 * 1000 * 1000 * 1000}, 146 {"6PB", 6 * 1000 * 1000 * 1000 * 1000 * 1000}, 147 {"8EB", 8 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000}, 148 } { 149 val, err := strutil.ParseByteSize(t.str) 150 c.Check(err, check.IsNil) 151 c.Check(val, check.Equals, t.expected, check.Commentf("incorrect result for input %q", t.str)) 152 } 153 } 154 155 func (ts *strutilSuite) TestParseByteSizeUnhappy(c *check.C) { 156 for _, t := range []struct { 157 str string 158 errStr string 159 }{ 160 {"B", `cannot parse "B": no numerical prefix`}, 161 {"1", `cannot parse "1": need a number with a unit as input`}, 162 {"11", `cannot parse "11": need a number with a unit as input`}, 163 {"400x", `cannot parse "400x": try 'kB' or 'MB'`}, 164 {"400xx", `cannot parse "400xx": try 'kB' or 'MB'`}, 165 {"1k", `cannot parse "1k": try 'kB' or 'MB'`}, 166 {"200KiB", `cannot parse "200KiB": try 'kB' or 'MB'`}, 167 {"-200KB", `cannot parse "-200KB": size cannot be negative`}, 168 {"-200B", `cannot parse "-200B": size cannot be negative`}, 169 {"-B", `cannot parse "-B": "-" is not a number`}, 170 {"-", `cannot parse "-": "-" is not a number`}, 171 {"", `cannot parse "": "" is not a number`}, 172 // Digits outside of Latin1 range 173 // ARABIC-INDIC DIGIT SEVEN 174 {"٧kB", `cannot parse "٧kB": no numerical prefix`}, 175 {"1٧kB", `cannot parse "1٧kB": try 'kB' or 'MB'`}, 176 } { 177 _, err := strutil.ParseByteSize(t.str) 178 c.Check(err, check.ErrorMatches, t.errStr, check.Commentf("incorrect error for %q", t.str)) 179 } 180 } 181 182 func (strutilSuite) TestCommaSeparatedList(c *check.C) { 183 table := []struct { 184 in string 185 out []string 186 }{ 187 {"", []string{}}, 188 {",", []string{}}, 189 {"foo,bar", []string{"foo", "bar"}}, 190 {"foo , bar", []string{"foo", "bar"}}, 191 {"foo ,, bar", []string{"foo", "bar"}}, 192 {" foo ,, bar,baz", []string{"foo", "bar", "baz"}}, 193 {" foo bar ,,,baz", []string{"foo bar", "baz"}}, 194 } 195 196 for _, test := range table { 197 c.Check(strutil.CommaSeparatedList(test.in), check.DeepEquals, test.out, check.Commentf("%q", test.in)) 198 } 199 } 200 201 func (strutilSuite) TestEllipt(c *check.C) { 202 type T struct { 203 in string 204 n int 205 right string 206 left string 207 } 208 for _, t := range []T{ 209 {"", 10, "", ""}, 210 {"", -1, "", ""}, 211 {"hello", -1, "…", "…"}, 212 {"hello", 0, "…", "…"}, 213 {"hello", 1, "…", "…"}, 214 {"hello", 2, "h…", "…o"}, 215 {"hello", 3, "he…", "…lo"}, 216 {"hello", 4, "hel…", "…llo"}, 217 {"hello", 5, "hello", "hello"}, 218 {"hello", 10, "hello", "hello"}, 219 {"héllo", 4, "hé…", "…llo"}, 220 {"héllo", 3, "he…", "…lo"}, 221 {"he🐧lo", 4, "he🐧…", "…🐧lo"}, 222 {"he🐧lo", 3, "he…", "…lo"}, 223 } { 224 c.Check(strutil.ElliptRight(t.in, t.n), check.Equals, t.right, check.Commentf("%q[:%d] -> %q", t.in, t.n, t.right)) 225 c.Check(strutil.ElliptLeft(t.in, t.n), check.Equals, t.left, check.Commentf("%q[-%d:] -> %q", t.in, t.n, t.left)) 226 } 227 } 228 229 func (strutilSuite) TestSortedListsUniqueMerge(c *check.C) { 230 l1 := []string{"a", "a", "c", "d", "e", "f", "h", "h"} 231 l2 := []string{"b", "c", "d", "d", "g"} 232 l3 := []string{"a", "b", "c", "d", "e", "f", "g", "h"} 233 234 tests := []struct { 235 sl1 []string 236 sl2 []string 237 res []string 238 }{ 239 {nil, nil, nil}, 240 {nil, []string{"a", "a", "b"}, []string{"a", "b"}}, 241 {[]string{"a", "a", "b"}, nil, []string{"a", "b"}}, 242 {l1, l2, l3}, 243 {l2, l1, l3}, 244 {l3, l3, l3}, 245 } 246 247 for _, t := range tests { 248 res := strutil.SortedListsUniqueMerge(t.sl1, t.sl2) 249 c.Check(res, check.DeepEquals, t.res) 250 } 251 }