From ec269c5c9d8bb338e472716f7c15b09235cade4b Mon Sep 17 00:00:00 2001 From: Adnan Maolood Date: Mon, 15 Feb 2021 19:20:37 -0500 Subject: [PATCH] Add some tests --- request_test.go | 148 +++++++++++++++++++++++++++++++++++++++++++++++ response_test.go | 104 +++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 request_test.go create mode 100644 response_test.go diff --git a/request_test.go b/request_test.go new file mode 100644 index 0000000..ea42c70 --- /dev/null +++ b/request_test.go @@ -0,0 +1,148 @@ +package gemini + +import ( + "bufio" + "io" + "net/url" + "strings" + "testing" +) + +// 1024 bytes +const maxURL = "gemini://example.net/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + +func TestReadRequest(t *testing.T) { + tests := []struct { + Raw string + URL *url.URL + Err error + }{ + { + Raw: "gemini://example.com\r\n", + URL: &url.URL{ + Scheme: "gemini", + Host: "example.com", + }, + }, + { + Raw: "http://example.org/path/?query#fragment\r\n", + URL: &url.URL{ + Scheme: "http", + Host: "example.org", + Path: "/path/", + RawQuery: "query", + Fragment: "fragment", + }, + }, + { + Raw: "\r\n", + URL: &url.URL{}, + }, + { + Raw: "gemini://example.com\n", + Err: io.EOF, + }, + { + Raw: "gemini://example.com", + Err: io.EOF, + }, + { + Raw: "gemini://user:password@example.com\r\n", + Err: ErrInvalidURL, + }, + { + Raw: "https://user:password@example.net\r\n", + Err: ErrInvalidURL, + }, + { + // 1030 bytes + Raw: maxURL + "xxxxxx", + Err: io.EOF, + }, + { + // 1027 bytes + Raw: maxURL + "x" + "\r\n", + Err: io.EOF, + }, + { + // 1024 bytes + Raw: maxURL[:len(maxURL)-2] + "\r\n", + URL: &url.URL{ + Scheme: "gemini", + Host: "example.net", + Path: maxURL[len("gemini://example.net") : len(maxURL)-2], + }, + }, + } + + for _, test := range tests { + t.Logf("%#v", test.Raw) + req, err := ReadRequest(strings.NewReader(test.Raw)) + if err != test.Err { + t.Errorf("expected err = %v, got %v", test.Err, err) + } + if req == nil && test.URL != nil { + t.Errorf("expected url = %s, got nil", test.URL) + } else if req != nil && test.URL == nil { + t.Errorf("expected req = nil, got %v", req) + } else if req != nil && *req.URL != *test.URL { + t.Errorf("expected url = %v, got %v", *test.URL, *req.URL) + } + } +} + +func newRequest(rawurl string) *Request { + req, err := NewRequest(rawurl) + if err != nil { + panic(err) + } + return req +} + +func TestWriteRequest(t *testing.T) { + tests := []struct { + Req *Request + Raw string + Err error + }{ + { + Req: newRequest("gemini://example.com"), + Raw: "gemini://example.com\r\n", + }, + { + Req: newRequest("gemini://example.com/path/?query#fragment"), + Raw: "gemini://example.com/path/?query#fragment\r\n", + }, + { + Req: newRequest(maxURL), + Raw: maxURL + "\r\n", + }, + { + Req: newRequest(maxURL + "x"), + Err: ErrInvalidRequest, + }, + { + Req: newRequest("gemini://user:password@example.org"), + Err: ErrInvalidURL, + }, + { + Req: newRequest("https://user:password@example.org"), + Err: ErrInvalidURL, + }, + } + + for _, test := range tests { + t.Logf("%s", test.Req.URL) + var b strings.Builder + bw := bufio.NewWriter(&b) + err := test.Req.Write(bw) + if err != test.Err { + t.Errorf("expected err = %v, got %v", test.Err, err) + } + bw.Flush() + got := b.String() + if got != test.Raw { + t.Errorf("expected %#v, got %#v", test.Raw, got) + } + } +} diff --git a/response_test.go b/response_test.go new file mode 100644 index 0000000..abf71c0 --- /dev/null +++ b/response_test.go @@ -0,0 +1,104 @@ +package gemini + +import ( + "io" + "io/ioutil" + "strings" + "testing" +) + +func TestReadResponse(t *testing.T) { + tests := []struct { + Raw string + Status int + Meta string + Body string + Err error + }{ + { + Raw: "20 text/gemini\r\nHello, world!\nWelcome to my capsule.", + Status: 20, + Meta: "text/gemini", + Body: "Hello, world!\nWelcome to my capsule.", + }, + { + Raw: "10 Search query\r\n", + Status: 10, + Meta: "Search query", + }, + { + Raw: "30 /redirect\r\n", + Status: 30, + Meta: "/redirect", + }, + { + Raw: "31 /redirect\r\nThis body is ignored.", + Status: 31, + Meta: "/redirect", + }, + { + Raw: "99 Unknown status code\r\n", + Status: 99, + Meta: "Unknown status code", + }, + { + Raw: "\r\n", + Err: ErrInvalidResponse, + }, + { + Raw: "\n", + Err: ErrInvalidResponse, + }, + { + Raw: "1 Bad response\r\n", + Err: ErrInvalidResponse, + }, + { + Raw: "", + Err: io.EOF, + }, + { + Raw: "10 Search query", + Err: io.EOF, + }, + { + Raw: "20 text/gemini\nHello, world!", + Err: io.EOF, + }, + { + Raw: "20 text/gemini\rHello, world!", + Err: ErrInvalidResponse, + }, + { + Raw: "20 text/gemini\r", + Err: io.EOF, + }, + { + Raw: "abcdefghijklmnopqrstuvwxyz", + Err: ErrInvalidResponse, + }, + } + + for _, test := range tests { + t.Logf("%#v", test.Raw) + resp, err := ReadResponse(ioutil.NopCloser(strings.NewReader(test.Raw))) + if err != test.Err { + t.Errorf("expected err = %v, got %v", test.Err, err) + } + if test.Err != nil { + // No response + continue + } + if resp.Status != test.Status { + t.Errorf("expected status = %d, got %d", test.Status, resp.Status) + } + if resp.Meta != test.Meta { + t.Errorf("expected meta = %s, got %s", test.Meta, resp.Meta) + } + b, _ := ioutil.ReadAll(resp.Body) + body := string(b) + if body != test.Body { + t.Errorf("expected body = %#v, got %#v", test.Body, body) + } + } +}