OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package cmpbin |
| 6 |
| 7 import ( |
| 8 "bytes" |
| 9 "io" |
| 10 "math/rand" |
| 11 "sort" |
| 12 "testing" |
| 13 |
| 14 . "github.com/smartystreets/goconvey/convey" |
| 15 ) |
| 16 |
| 17 func TestBytes(t *testing.T) { |
| 18 t.Parallel() |
| 19 |
| 20 Convey("bytes", t, func() { |
| 21 b := &bytes.Buffer{} |
| 22 t := []byte("this is a test") |
| 23 |
| 24 Convey("good", func() { |
| 25 _, err := WriteBytes(b, t) |
| 26 So(err, ShouldBeNil) |
| 27 exn := b.Len() |
| 28 r, n, err := ReadBytes(b) |
| 29 So(err, ShouldBeNil) |
| 30 So(n, ShouldEqual, exn) |
| 31 So(r, ShouldResemble, t) |
| 32 }) |
| 33 |
| 34 Convey("bad (truncated buffer)", func() { |
| 35 _, err := WriteBytes(b, t) |
| 36 So(err, ShouldBeNil) |
| 37 bs := b.Bytes()[:b.Len()-4] |
| 38 _, n, err := ReadBytes(bytes.NewBuffer(bs)) |
| 39 So(err, ShouldEqual, io.EOF) |
| 40 So(n, ShouldEqual, len(bs)) |
| 41 }) |
| 42 |
| 43 Convey("bad (bad varint)", func() { |
| 44 _, n, err := ReadBytes(bytes.NewBuffer([]byte{b10001111}
)) |
| 45 So(err, ShouldEqual, io.EOF) |
| 46 So(n, ShouldEqual, 1) |
| 47 }) |
| 48 |
| 49 Convey("bad (huge data)", func() { |
| 50 n, err := WriteBytes(b, make([]byte, 2*1024*1024+1)) |
| 51 So(err, ShouldBeNil) |
| 52 So(n, ShouldEqual, ReadByteLimit+2) |
| 53 _, n, err = ReadBytes(b) |
| 54 So(err.Error(), ShouldContainSubstring, "too big!") |
| 55 So(n, ShouldEqual, ReadByteLimit) |
| 56 }) |
| 57 |
| 58 Convey("bad (write errors)", func() { |
| 59 _, err := WriteBytes(&fakeWriter{1}, t) |
| 60 So(err.Error(), ShouldContainSubstring, "nope") |
| 61 |
| 62 // transition boundary |
| 63 _, err = WriteBytes(&fakeWriter{7}, t) |
| 64 So(err.Error(), ShouldContainSubstring, "nope") |
| 65 }) |
| 66 }) |
| 67 } |
| 68 |
| 69 func TestStrings(t *testing.T) { |
| 70 t.Parallel() |
| 71 |
| 72 Convey("strings", t, func() { |
| 73 b := &bytes.Buffer{} |
| 74 t := "this is a test" |
| 75 |
| 76 Convey("empty", func() { |
| 77 n, err := WriteString(b, "") |
| 78 So(err, ShouldBeNil) |
| 79 So(n, ShouldEqual, 1) |
| 80 So(b.Bytes(), ShouldResemble, []byte{0}) |
| 81 r, n, err := ReadString(b) |
| 82 So(err, ShouldBeNil) |
| 83 So(n, ShouldEqual, 1) |
| 84 So(r, ShouldEqual, "") |
| 85 }) |
| 86 |
| 87 Convey("nulls", func() { |
| 88 t := "\x00\x00\x00\x00\x00" |
| 89 n, err := WriteString(b, t) |
| 90 So(n, ShouldEqual, 6) |
| 91 So(err, ShouldBeNil) |
| 92 exn := b.Len() |
| 93 r, n, err := ReadString(b) |
| 94 So(err, ShouldBeNil) |
| 95 So(n, ShouldEqual, exn) |
| 96 So(r, ShouldEqual, t) |
| 97 }) |
| 98 |
| 99 Convey("bad (truncated buffer)", func() { |
| 100 n, err := WriteString(b, t) |
| 101 So(n, ShouldEqual, (len(t)*8)/7+1) |
| 102 So(err, ShouldBeNil) |
| 103 bs := b.Bytes()[:b.Len()-1] |
| 104 _, n, err = ReadString(bytes.NewBuffer(bs)) |
| 105 So(err, ShouldEqual, io.EOF) |
| 106 So(n, ShouldEqual, len(bs)) |
| 107 }) |
| 108 |
| 109 Convey("single", func() { |
| 110 n, err := WriteString(b, "1") |
| 111 So(err, ShouldBeNil) |
| 112 So(n, ShouldEqual, 2) |
| 113 So(b.Bytes(), ShouldResemble, []byte{b00110001, b1000000
0}) |
| 114 r, n, err := ReadString(b) |
| 115 So(err, ShouldBeNil) |
| 116 So(n, ShouldEqual, 2) |
| 117 So(r, ShouldEqual, "1") |
| 118 }) |
| 119 |
| 120 Convey("good", func() { |
| 121 n, err := WriteString(b, t) |
| 122 So(err, ShouldBeNil) |
| 123 So(n, ShouldEqual, (len(t)*8)/7+1) |
| 124 So(b.Bytes()[:8], ShouldResemble, []byte{ |
| 125 b01110101, b00110101, b00011011, b00101111, b001
10011, b00000011, |
| 126 b10100101, b11100111, |
| 127 }) |
| 128 exn := b.Len() |
| 129 r, n, err := ReadString(b) |
| 130 So(err, ShouldBeNil) |
| 131 So(len(r), ShouldEqual, len(t)) |
| 132 So(n, ShouldEqual, exn) |
| 133 So(r, ShouldEqual, t) |
| 134 }) |
| 135 |
| 136 }) |
| 137 } |
| 138 |
| 139 // TODO(riannucci): make it [][]string instead |
| 140 |
| 141 func TestStringSortability(t *testing.T) { |
| 142 t.Parallel() |
| 143 |
| 144 Convey("strings maintain sort order", t, func() { |
| 145 special := []string{ |
| 146 "", |
| 147 "\x00", |
| 148 "\x00\x00", |
| 149 "\x00\x00\x00", |
| 150 "\x00\x00\x00\x00", |
| 151 "\x00\x00\x00\x00\x00", |
| 152 "\x00\x00\x00\x00\x01", |
| 153 "\x00\x00\x00\x00\xFF", |
| 154 "1234567", |
| 155 "12345678", |
| 156 "123456789", |
| 157 string(make([]byte, 7*8)), |
| 158 } |
| 159 orig := make(sort.StringSlice, randomTestSize, randomTestSize+le
n(special)) |
| 160 |
| 161 r := rand.New(rand.NewSource(*seed)) |
| 162 for i := range orig { |
| 163 buf := make([]byte, r.Intn(100)) |
| 164 for j := range buf { |
| 165 buf[j] = byte(r.Uint32()) // watch me not care! |
| 166 } |
| 167 orig[i] = string(buf) |
| 168 } |
| 169 orig = append(orig, special...) |
| 170 |
| 171 enc := make(sort.StringSlice, len(orig)) |
| 172 b := &bytes.Buffer{} |
| 173 for i := range enc { |
| 174 b.Reset() |
| 175 _, err := WriteString(b, orig[i]) |
| 176 So(err, ShouldBeNil) |
| 177 enc[i] = b.String() |
| 178 } |
| 179 |
| 180 orig.Sort() |
| 181 enc.Sort() |
| 182 |
| 183 for i := range orig { |
| 184 decoded, _, err := ReadString(bytes.NewBufferString(enc[
i])) |
| 185 So(err, ShouldBeNil) |
| 186 So(decoded, ShouldResemble, orig[i]) |
| 187 } |
| 188 }) |
| 189 } |
| 190 |
| 191 type StringSliceSlice [][]string |
| 192 |
| 193 func (s StringSliceSlice) Len() int { return len(s) } |
| 194 func (s StringSliceSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } |
| 195 func (s StringSliceSlice) Less(i, j int) bool { |
| 196 a, b := s[i], s[j] |
| 197 lim := len(a) |
| 198 if len(b) < lim { |
| 199 lim = len(b) |
| 200 } |
| 201 for k := 0; k < lim; k++ { |
| 202 if a[k] > b[k] { |
| 203 return false |
| 204 } else if a[k] < b[k] { |
| 205 return true |
| 206 } |
| 207 } |
| 208 return len(a) < len(b) |
| 209 } |
| 210 |
| 211 func TestConcatenatedStringSortability(t *testing.T) { |
| 212 t.Parallel() |
| 213 |
| 214 Convey("concatenated strings maintain sort order", t, func() { |
| 215 orig := make(StringSliceSlice, randomTestSize) |
| 216 |
| 217 r := rand.New(rand.NewSource(*seed)) |
| 218 for i := range orig { |
| 219 count := r.Intn(10) |
| 220 for j := 0; j < count; j++ { |
| 221 buf := make([]byte, r.Intn(100)) |
| 222 for j := range buf { |
| 223 buf[j] = byte(r.Uint32()) // watch me no
t care! |
| 224 } |
| 225 orig[i] = append(orig[i], string(buf)) |
| 226 } |
| 227 } |
| 228 orig = append(orig, [][]string{ |
| 229 nil, |
| 230 {"", "aaa"}, |
| 231 {"a", "aa"}, |
| 232 {"aa", "a"}, |
| 233 }...) |
| 234 |
| 235 enc := make(sort.StringSlice, len(orig)) |
| 236 b := &bytes.Buffer{} |
| 237 for i, slice := range orig { |
| 238 b.Reset() |
| 239 for _, s := range slice { |
| 240 _, err := WriteString(b, s) |
| 241 So(err, ShouldBeNil) |
| 242 } |
| 243 enc[i] = b.String() |
| 244 } |
| 245 |
| 246 sort.Sort(orig) |
| 247 enc.Sort() |
| 248 |
| 249 for i := range orig { |
| 250 decoded := []string(nil) |
| 251 buf := bytes.NewBufferString(enc[i]) |
| 252 for { |
| 253 dec, _, err := ReadString(buf) |
| 254 if err != nil { |
| 255 break |
| 256 } |
| 257 decoded = append(decoded, dec) |
| 258 } |
| 259 So(decoded, ShouldResemble, orig[i]) |
| 260 } |
| 261 }) |
| 262 } |
OLD | NEW |