summaryrefslogtreecommitdiffstats
path: root/message_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'message_test.go')
-rw-r--r--message_test.go204
1 files changed, 204 insertions, 0 deletions
diff --git a/message_test.go b/message_test.go
new file mode 100644
index 0000000..6955fc3
--- /dev/null
+++ b/message_test.go
@@ -0,0 +1,204 @@
+package cnp
+
+import (
+ "bytes"
+ "io"
+ "strconv"
+ "strings"
+ "testing"
+)
+
+var (
+ messageTests = []messageTest{
+ {
+ "qweasd", "text/plain", nil, nil,
+ "cnp/0.3 test1 length=6 type=text/plain\nqweasd",
+ &Message{
+ Header: Header{
+ VersionMajor: 0,
+ VersionMinor: 3,
+ Intent: "test1",
+ Parameters: Parameters{
+ "type": "text/plain",
+ "length": "6",
+ },
+ },
+ Body: strings.NewReader("qweasd"),
+ },
+ },
+
+ {
+ "qweasd", "text", nil, ErrorInvalid{},
+ "cnp/0.3 test2 length=w type=text/plain\nqweasd",
+ &Message{
+ Header: Header{
+ VersionMajor: 0,
+ VersionMinor: 3,
+ Intent: "test2",
+ Parameters: Parameters{
+ "type": "text/plain",
+ "length": "w",
+ },
+ },
+ Body: strings.NewReader("qweasd"),
+ },
+ },
+
+ {
+ "", "text/plain", ErrorSyntax{}, nil,
+ "cnp/0.3 test3 type=text/plain",
+ nil,
+ },
+
+ {
+ "", "text/plain", nil, nil,
+ "cnp/0.3 test4 type=text/plain\n",
+ &Message{
+ Header: Header{
+ VersionMajor: 0,
+ VersionMinor: 3,
+ Intent: "test4",
+ Parameters: Parameters{
+ "type": "text/plain",
+ },
+ },
+ Body: nil,
+ },
+ },
+ }
+)
+
+type messageTest struct {
+ b, t string
+ p, v error
+ s string
+ m *Message
+}
+
+func (tst *messageTest) Reset() {
+ if tst.m != nil && tst.b != "" {
+ tst.m.Body = strings.NewReader(tst.b)
+ }
+}
+
+func TestParse(t *testing.T) {
+ for _, tst := range messageTests {
+ tst.Reset()
+ msg, err := ParseMessage(strings.NewReader(tst.s))
+ if tst.p != nil || err != nil {
+ if !errorEqual(tst.p, err) {
+ t.Errorf("ParseMessage(%q): expected error %+v, got %+v (%v)", tst.s, tst.p, err, err)
+ continue
+ }
+ } else if !msgEqual(msg, tst.m) {
+ t.Errorf("\nexpected: %+v\ngot: %+v", tst.m, msg)
+ } else if l := msg.Length(); tst.v == nil && l != int64(len(tst.b)) {
+ t.Errorf("%+v: expected length %d, got %d", tst.m, len(tst.b), l)
+ } else if err = msg.Validate(); !errorEqual(err, tst.v) {
+ t.Errorf("%+v: expected validation error %+v, got %+v (%s)", msg, tst.v, err, err)
+ }
+ }
+}
+
+func TestNew(t *testing.T) {
+ for i, tst := range messageTests {
+ if tst.v != nil || tst.p != nil {
+ continue // skip invalid messages
+ }
+ tst.Reset()
+ var r io.Reader
+ if tst.b != "" {
+ r = strings.NewReader(tst.b)
+ }
+ msg := NewMessage("test"+strconv.Itoa(i+1), r)
+ msg.SetParam("type", tst.t)
+ if !msgEqual(msg, tst.m) {
+ t.Errorf("\nexpected: %+v\ngot: %+v", tst.m, msg)
+ }
+ }
+}
+
+func TestWrite(t *testing.T) {
+ for _, tst := range messageTests {
+ if tst.p != nil {
+ continue // skip invalid messages
+ }
+ tst.Reset()
+ var buf bytes.Buffer
+ err := tst.m.Write(&buf)
+ if err != nil {
+ t.Errorf("%+v: error writing message body: %s", tst.m, err)
+ }
+ if buf.String() != tst.s {
+ t.Errorf("%+v:\nexpected: %q\ngot: %q", tst.m, tst.s, buf.String())
+ }
+ }
+}
+
+func TestComputeLength(t *testing.T) {
+ s := "qweasd"
+ r := &testStringReader{"qweasd"}
+ msg := NewMessage("ok", r)
+ if _, ok := msg.Header.Parameters["length"]; msg.Length() != 0 || msg.Param("length") != "" || ok {
+ t.Fatalf("%+v: expected no length parameter", msg)
+ }
+ if err := msg.ComputeLength(); err != nil {
+ t.Fatalf("%+v.ComputeLength(): error: %s", msg, err)
+ }
+ if l := msg.Length(); l != int64(len(s)) {
+ t.Fatalf("%+v: invalid length %d, expected %d\n", msg, l, len(s))
+ }
+ if _, ok := msg.Body.(*testStringReader); r.s != "" || ok || r == msg.Body {
+ t.Fatalf("%+v: did not buffer body correctly", msg)
+ }
+ if !bodyEqual(msg.Body, strings.NewReader(s)) {
+ t.Fatalf("%+v: incorrect buffered body", msg)
+ }
+}
+
+func TestParseTooLarge(t *testing.T) {
+ s := "cnp/0.3 ok text="
+ str := s + strings.Repeat(".", MaxHeaderLength-len(s)) + "\n"
+ _, err := ParseMessage(strings.NewReader(str))
+ if _, ok := err.(ErrorTooLarge); !ok {
+ t.Errorf("\nexpected: ErrorTooLarge\ngot: %+v", err)
+ }
+}
+
+type noopCloser struct {
+ r io.Reader
+ closed bool
+}
+
+func (n *noopCloser) Close() error {
+ n.closed = true
+ return nil
+}
+
+func (n *noopCloser) Read(b []byte) (int, error) {
+ return n.r.Read(b)
+}
+
+func TestClose(t *testing.T) {
+ var r io.Reader = strings.NewReader("cnp/0.3 ok\nqweasd")
+ if msg, err := ParseMessage(r); err != nil {
+ t.Errorf("ParseMessage error: %v", err)
+ } else if err = msg.Close(); err != nil {
+ t.Errorf("Error closing message: %v", err)
+ }
+ r = &noopCloser{r: strings.NewReader("cnp/0.3 ok\nqweasd")}
+ if msg, err := ParseMessage(r); err != nil {
+ t.Errorf("ParseMessage error: %v", err)
+ } else if err = msg.Close(); err != nil {
+ t.Errorf("Error closing message: %v", err)
+ } else if !r.(*noopCloser).closed {
+ t.Errorf("Reader was not closed")
+ }
+ r = &noopCloser{r: strings.NewReader("qweasd")}
+ msg := NewMessage("ok", r)
+ if err := msg.Close(); err != nil {
+ t.Errorf("Error closing message: %v", err)
+ } else if !r.(*noopCloser).closed {
+ t.Errorf("Reader was not closed")
+ }
+}