| 30 | } |
| 31 | |
| 32 | func TestFrameReader(t *testing.T) { |
| 33 | const timeout = 100 * time.Millisecond |
| 34 | |
| 35 | var ( |
| 36 | doWrite = func(fk *fakeReader, p []byte, _ error) { |
| 37 | fk.p <- p |
| 38 | close(fk.p) |
| 39 | } |
| 40 | doTimeout = func(fk *fakeReader, p []byte, _ error) { |
| 41 | time.AfterFunc(2*timeout, func() { |
| 42 | fk.p <- p |
| 43 | close(fk.p) |
| 44 | }) |
| 45 | } |
| 46 | doError = func(fk *fakeReader, _ []byte, err error) { |
| 47 | fk.err = err |
| 48 | close(fk.p) |
| 49 | } |
| 50 | ) |
| 51 | |
| 52 | cases := map[string]struct { |
| 53 | write func(*fakeReader, []byte, error) |
| 54 | p []byte |
| 55 | err error |
| 56 | }{ |
| 57 | "session open": {doWrite, []byte{'o'}, nil}, |
| 58 | "session open timeout": {doTimeout, []byte{'o'}, ErrPollTimeout}, |
| 59 | "session open error": {doError, []byte{'o'}, &net.AddrError{}}, |
| 60 | "message": {doWrite, []byte(`m"hello world"`), nil}, |
| 61 | "message timeout": {doTimeout, []byte(`m"hello world"`), ErrPollTimeout}, |
| 62 | "message error": {doError, []byte(`m"hello world"`), &net.AddrError{}}, |
| 63 | } |
| 64 | |
| 65 | for name, cas := range cases { |
| 66 | name := name |
| 67 | t.Run(name, func(t *testing.T) { |
| 68 | fk := &fakeReader{ |
| 69 | p: make(chan []byte, 1), |
| 70 | } |
| 71 | |
| 72 | fr := &frameReader{ |
| 73 | r: bufio.NewReader(fk), |
| 74 | timeout: timeout, |
| 75 | } |
| 76 | |
| 77 | cas.write(fk, cas.p, cas.err) |
| 78 | |
| 79 | p, err := ioutil.ReadAll(fr) |
| 80 | if cas.err != nil { |
| 81 | if err != cas.err { |
| 82 | t.Fatalf("got %v, want %v", err, cas.err) |
| 83 | } |
| 84 | |
| 85 | return |
| 86 | } |
| 87 | |
| 88 | if bytes.Compare(p, cas.p) != 0 { |
| 89 | t.Fatalf("got %q, want %q", p, cas.p) |