github.com/seeker-insurance/kit@v0.0.13/tsv/tsv_test.go (about) 1 package tsv 2 3 import ( 4 "bytes" 5 "io" 6 "io/ioutil" 7 "log" 8 "net/http" 9 "os" 10 "reflect" 11 "sort" 12 "strings" 13 "testing" 14 ) 15 16 const ( 17 johnFirst = `john` 18 johnLast = `doe` 19 johnAge = `22` 20 janeFirst = `jane` 21 janeLast = `doe` 22 janeAge = `58` 23 last, lng = 22.3, -22.4 24 firstLabel = "first" 25 lastLabel = "last" 26 ageLabel = "age" 27 testFileName = "test.tsv" 28 localURL = `http://localhost:3000/test.tsv` 29 ownerAllUserReadExecute = os.FileMode(0755) 30 ) 31 32 var ( 33 wd, _ = os.Getwd() 34 testFilePath = wd + "/" + testFileName 35 testLabels = []string{firstLabel, lastLabel, ageLabel} 36 johnDoe = []string{johnFirst, johnLast, johnAge} 37 janeDoe = []string{janeFirst, janeLast, janeAge} 38 testTSVBody = strings.Join([]string{ 39 strings.Join(testLabels, "\t"), 40 strings.Join(johnDoe, "\t"), 41 strings.Join(janeDoe, "\t"), 42 }, 43 "\n", 44 ) 45 46 johnRecord = Record{ 47 firstLabel: johnFirst, 48 lastLabel: johnLast, 49 ageLabel: johnAge, 50 } 51 janeRecord = Record{ 52 firstLabel: janeFirst, 53 lastLabel: janeLast, 54 ageLabel: janeAge, 55 } 56 ) 57 58 func testTSV(args ...string) string { 59 return strings.Join(args, "\t") 60 } 61 62 func serveFromMockTSVServer() http.Handler { 63 fs := http.FileServer(http.Dir("")) 64 http.Handle("/", fs) 65 log.Println("serving...") 66 go func() { 67 err := http.ListenAndServe(":3000", nil) 68 if err != nil { 69 log.Println("serving failed") 70 } 71 }() 72 return fs 73 } 74 75 func createTestFile() error { 76 return ioutil.WriteFile("test.tsv", []byte(testTSVBody), ownerAllUserReadExecute) 77 } 78 79 func init() { 80 if err := createTestFile(); err != nil { 81 log.Fatalf("could not create test file") 82 } 83 serveFromMockTSVServer() 84 85 } 86 87 func TestRecord_Float64(t *testing.T) { 88 type args struct { 89 key string 90 } 91 tests := []struct { 92 name string 93 record Record 94 args args 95 want float64 96 wantErr bool 97 }{ 98 { 99 name: "ok", 100 record: Record{"latitude": "-22.34"}, 101 args: args{"latitude"}, 102 want: -22.34, 103 }, { 104 name: "key dne", 105 record: Record{}, 106 args: args{"latitude"}, 107 wantErr: true, 108 }, { 109 name: "key bad float", 110 record: Record{"latitude": "aaddmm"}, 111 args: args{"latitude"}, 112 wantErr: true, 113 }, 114 } 115 for _, tt := range tests { 116 t.Run(tt.name, func(t *testing.T) { 117 got, err := tt.record.Float64(tt.args.key) 118 if (err != nil) != tt.wantErr { 119 t.Errorf("Record.Float64() error = %v, wantErr %v", err, tt.wantErr) 120 return 121 } 122 if got != tt.want { 123 t.Errorf("Record.Float64() = %v, want %v", got, tt.want) 124 } 125 }) 126 } 127 } 128 129 func TestParseLine(t *testing.T) { 130 type args struct { 131 line string 132 labels []string 133 } 134 tests := []struct { 135 name string 136 args args 137 want Record 138 ok bool 139 }{ 140 { 141 name: "ok", 142 args: args{line: testTSV(johnDoe...), labels: testLabels}, 143 want: Record{"first": johnFirst, "last": johnLast, "age": johnAge}, 144 ok: true, 145 }, { 146 name: "wrong length", 147 args: args{line: testTSV(`"hello"`, `"my"`, `"name"`, `"is"`), labels: testLabels}, 148 want: nil, 149 ok: false, 150 }, 151 } 152 for _, tt := range tests { 153 t.Run(tt.name, func(t *testing.T) { 154 got, ok := parseLine(tt.args.line, tt.args.labels) 155 if !reflect.DeepEqual(got, tt.want) { 156 t.Errorf("ParseLine() got = %v, want %v", got, tt.want) 157 } 158 if ok != tt.ok { 159 t.Errorf("ParseLine() ok = %v, want %v", ok, tt.ok) 160 } 161 recover() 162 }) 163 } 164 } 165 166 func Test_asReadCloser(t *testing.T) { 167 type args struct { 168 s string 169 } 170 wd, _ := os.Getwd() 171 172 tests := []struct { 173 name string 174 args args 175 wantString string 176 wantErr bool 177 }{ 178 { 179 name: "good url", 180 args: args{localURL}, 181 wantString: testTSVBody, 182 }, { 183 name: "does not exist", 184 args: args{"thisseemslike.agoodurl.com/right.tsv"}, 185 wantErr: true, 186 }, 187 { 188 name: "good file", 189 wantString: testTSVBody, 190 args: args{wd + "/" + testFileName}, 191 }, 192 { 193 name: "bad file", 194 args: args{"thisfiledoesnotexist.tsv"}, 195 wantErr: true, 196 }, 197 } 198 for _, tt := range tests { 199 t.Run(tt.name, func(t *testing.T) { 200 gotReadCloser, err := asReadCloser(tt.args.s) 201 if (err != nil) != tt.wantErr { 202 t.Errorf("asReadCloser() error = %v, wantErr %v", err, tt.wantErr) 203 return 204 } else if err != nil { 205 return 206 } 207 var got bytes.Buffer 208 io.Copy(&got, gotReadCloser) 209 if !reflect.DeepEqual(got.String(), tt.wantString) { 210 t.Errorf("asReadCLoser(): got %v, want %v", got.String(), tt.wantString) 211 } 212 213 }) 214 215 } 216 } 217 218 func Test_FromPath(t *testing.T) { 219 want := []Record{johnRecord, janeRecord} 220 type args struct { 221 path string 222 } 223 tests := []struct { 224 name string 225 args args 226 wantRecords []Record 227 wantErr bool 228 }{ 229 { 230 name: "ok website", 231 args: args{localURL}, 232 wantRecords: want, 233 }, { 234 name: "ok local file", 235 args: args{testFileName}, 236 wantRecords: want, 237 }, { 238 name: "bad path", 239 args: args{"badfile.asdasd"}, 240 wantErr: true, 241 }, 242 } 243 for _, tt := range tests { 244 t.Run(tt.name, func(t *testing.T) { 245 gotRecords, err := FromPath(tt.args.path) 246 if (err != nil) != tt.wantErr { 247 t.Errorf("parseFromPath() error = %v, wantErr %v", err, tt.wantErr) 248 return 249 } 250 if !reflect.DeepEqual(gotRecords, tt.wantRecords) { 251 t.Errorf("parseFromPath() = %v, want %v", gotRecords, tt.wantRecords) 252 } 253 }) 254 } 255 } 256 257 func TestParse(t *testing.T) { 258 type args struct { 259 reader io.Reader 260 } 261 mismatched := bytes.NewBufferString("first\tlast\tage\njohn\tdoe\t22\njane\tdoe\n") 262 tests := []struct { 263 name string 264 args args 265 wantRecords []Record 266 wantErr bool 267 }{ 268 { 269 name: "ok", 270 args: args{reader: bytes.NewBufferString(testTSVBody)}, 271 wantRecords: []Record{johnRecord, janeRecord}, 272 }, { 273 name: "mistmatched records", 274 args: args{reader: mismatched}, 275 wantErr: true, 276 }, 277 } 278 for _, tt := range tests { 279 t.Run(tt.name, func(t *testing.T) { 280 gotRecords, err := Parse(tt.args.reader) 281 if (err != nil) != tt.wantErr { 282 t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr) 283 return 284 } 285 if !reflect.DeepEqual(gotRecords, tt.wantRecords) { 286 t.Errorf("Parse() = %v, want %v", gotRecords, tt.wantRecords) 287 } 288 }) 289 } 290 } 291 292 type byFirstName []Record 293 294 func (r byFirstName) Less(i, j int) bool { 295 fI, _ := r[i]["first"] 296 fJ, _ := r[j]["first"] 297 return fI < fJ 298 } 299 300 func (r byFirstName) Len() int { 301 return len(r) 302 } 303 304 func (r byFirstName) Swap(i, j int) { 305 r[i], r[j] = r[j], r[i] 306 } 307 308 func chanToSlice(ch <-chan Record) []Record { 309 var records []Record 310 for r := range ch { 311 records = append(records, r) 312 } 313 return records 314 } 315 316 func TestStreamFromPaths(t *testing.T) { 317 type args struct { 318 out chan Record 319 paths []string 320 } 321 tests := []struct { 322 name string 323 args args 324 want []Record 325 wantErr bool 326 }{ 327 { 328 name: "ok - one path", 329 args: args{paths: []string{testFileName}, out: make(chan Record)}, 330 want: []Record{johnRecord, janeRecord}, 331 }, { 332 name: "ok - two paths", 333 args: args{paths: []string{testFileName, localURL}, out: make(chan Record, 2)}, 334 want: []Record{johnRecord, johnRecord, janeRecord, janeRecord}, 335 }, { 336 name: "err - bad filepath", 337 args: args{paths: []string{"somebadfilename"}, out: make(chan Record)}, 338 wantErr: true, 339 }, 340 } 341 for _, tt := range tests { 342 t.Run(tt.name, func(t *testing.T) { 343 if err := StreamFromPaths(tt.args.out, tt.args.paths...); (err != nil) != tt.wantErr { 344 t.Errorf("StreamFromPaths() error = %v, wantErr %v", err, tt.wantErr) 345 } 346 got := chanToSlice(tt.args.out) 347 sort.Sort(byFirstName(got)) 348 sort.Sort(byFirstName(tt.want)) 349 if !reflect.DeepEqual(got, tt.want) { 350 t.Errorf("StreamFromPaths(): \n got %v: \n want %v", got, tt.want) 351 } 352 353 }) 354 } 355 } 356 357 func Test_labels_ParseLine(t *testing.T) { 358 type args struct { 359 line string 360 } 361 tests := []struct { 362 name string 363 l labels 364 args args 365 want Record 366 want1 bool 367 }{ 368 // TODO: Add test cases. 369 } 370 for _, tt := range tests { 371 t.Run(tt.name, func(t *testing.T) { 372 got, got1 := tt.l.ParseLine(tt.args.line) 373 if !reflect.DeepEqual(got, tt.want) { 374 t.Errorf("labels.ParseLine() got = %v, want %v", got, tt.want) 375 } 376 if got1 != tt.want1 { 377 t.Errorf("labels.ParseLine() got1 = %v, want %v", got1, tt.want1) 378 } 379 }) 380 } 381 } 382 383 func TestFromPath(t *testing.T) { 384 type args struct { 385 path string 386 } 387 tests := []struct { 388 name string 389 args args 390 wantRecords []Record 391 wantErr bool 392 }{ 393 // TODO: Add test cases. 394 } 395 for _, tt := range tests { 396 t.Run(tt.name, func(t *testing.T) { 397 gotRecords, err := FromPath(tt.args.path) 398 if (err != nil) != tt.wantErr { 399 t.Errorf("FromPath() error = %v, wantErr %v", err, tt.wantErr) 400 return 401 } 402 if !reflect.DeepEqual(gotRecords, tt.wantRecords) { 403 t.Errorf("FromPath() = %v, want %v", gotRecords, tt.wantRecords) 404 } 405 }) 406 } 407 } 408 409 func TestStreamFromBindataPaths(t *testing.T) { 410 type args struct { 411 out chan Record 412 paths []string 413 } 414 tests := []struct { 415 name string 416 args args 417 wantErr bool 418 }{ 419 // TODO: Add test cases. 420 } 421 for _, tt := range tests { 422 t.Run(tt.name, func(t *testing.T) { 423 if err := StreamFromBindataPaths(tt.args.out, tt.args.paths...); (err != nil) != tt.wantErr { 424 t.Errorf("StreamFromBindataPaths() error = %v, wantErr %v", err, tt.wantErr) 425 } 426 }) 427 } 428 } 429 430 func Test_asBinReadCloser(t *testing.T) { 431 } 432 433 func Test_parseStream(t *testing.T) { 434 } 435 436 func Test_parseStreams(t *testing.T) { 437 }