191 lines
4.3 KiB
Go
191 lines
4.3 KiB
Go
package gopher_test
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"code.as/writefreely/go-gopher"
|
|
)
|
|
|
|
var (
|
|
testHost string = "localhost"
|
|
testPort int
|
|
)
|
|
|
|
func pickUnusedPort() (int, error) {
|
|
addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0")
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
l, err := net.ListenTCP("tcp", addr)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
port := l.Addr().(*net.TCPAddr).Port
|
|
if err := l.Close(); err != nil {
|
|
return 0, err
|
|
}
|
|
return port, nil
|
|
}
|
|
|
|
func TestMain(m *testing.M) {
|
|
port, err := pickUnusedPort()
|
|
if err != nil {
|
|
log.Fatalf("error finding a free port: %s", err)
|
|
}
|
|
testPort = port
|
|
|
|
go func() {
|
|
gopher.Handle("/", gopher.FileServer(gopher.Dir("./testdata")))
|
|
gopher.HandleFunc("/hello", hello)
|
|
log.Printf("Test server starting on :%d\n", testPort)
|
|
log.Fatal(gopher.ListenAndServe(fmt.Sprintf(":%d", testPort), nil))
|
|
}()
|
|
|
|
// Because it can take some time for the server to spin up
|
|
// the tests are inconsistent - they'll fail if the server isn't
|
|
// ready, but pass otherwise. This problem seems more pronounced
|
|
// when running via the makefile.
|
|
//
|
|
// It seems like there should be a better way to do this
|
|
for attempts := 3; attempts > 0; attempts-- {
|
|
_, err := gopher.Get(fmt.Sprintf("gopher://%s:%d", testHost, testPort))
|
|
if err == nil {
|
|
log.Println("Server ready")
|
|
break
|
|
}
|
|
log.Printf("Server not ready, going to try again in a sec. %v\n", err)
|
|
time.Sleep(1 * time.Second)
|
|
}
|
|
|
|
code := m.Run()
|
|
os.Exit(code)
|
|
}
|
|
|
|
func hello(w gopher.ResponseWriter, r *gopher.Request) {
|
|
w.WriteInfo("Hello World!")
|
|
}
|
|
|
|
func Example_client() {
|
|
res, err := gopher.Get("gopher://gopher.floodgap.com")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
fmt.Print(res.Dir.ToText())
|
|
}
|
|
|
|
func Example_server() {
|
|
gopher.HandleFunc("/hello", hello)
|
|
log.Fatal(gopher.ListenAndServe("localhost:7000", nil))
|
|
}
|
|
|
|
func Example_fileserver() {
|
|
gopher.Handle("/", gopher.FileServer(gopher.Dir("/tmp")))
|
|
log.Fatal(gopher.ListenAndServe("localhost:7000", nil))
|
|
}
|
|
|
|
func TestGet(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
res, err := gopher.Get(fmt.Sprintf("gopher://%s:%d/1hello", testHost, testPort))
|
|
require.NoError(err)
|
|
assert.Len(res.Dir.Items, 1)
|
|
assert.Equal(res.Dir.Items[0].Type, gopher.INFO)
|
|
assert.Equal(res.Dir.Items[0].Description, "Hello World!")
|
|
|
|
out, err := res.Dir.ToText()
|
|
require.NoError(err)
|
|
assert.Equal(string(out), "iHello World!\t\terror.host\t1\r\n")
|
|
}
|
|
|
|
func TestFileServer(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
res, err := gopher.Get(fmt.Sprintf("gopher://%s:%d/", testHost, testPort))
|
|
require.NoError(err)
|
|
assert.Len(res.Dir.Items, 1)
|
|
|
|
json, err := res.Dir.ToJSON()
|
|
require.NoError(err)
|
|
|
|
log.Println(string(json))
|
|
assert.JSONEq(
|
|
`{"items":[{"type":"0","description":"hello.txt","selector":"/hello.txt","host":"127.0.0.1","port":7000,"extras":[]}]}`,
|
|
string(json))
|
|
}
|
|
|
|
func TestParseItemNull(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
item, err := gopher.ParseItem("")
|
|
assert.Nil(item)
|
|
assert.Error(err)
|
|
}
|
|
|
|
func TestParseItem(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
item, err := gopher.ParseItem("0foo\t/foo\tlocalhost\t70\r\n")
|
|
require.NoError(err)
|
|
assert.NotNil(item)
|
|
assert.Equal(item, &gopher.Item{
|
|
Type: gopher.FILE,
|
|
Description: "foo",
|
|
Selector: "/foo",
|
|
Host: "localhost",
|
|
Port: 70,
|
|
Extras: []string{},
|
|
})
|
|
}
|
|
|
|
func TestParseItemMarshal(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
data := "0foo\t/foo\tlocalhost\t70\r\n"
|
|
item, err := gopher.ParseItem(data)
|
|
require.NoError(err)
|
|
assert.NotNil(item)
|
|
assert.Equal(item, &gopher.Item{
|
|
Type: gopher.FILE,
|
|
Description: "foo",
|
|
Selector: "/foo",
|
|
Host: "localhost",
|
|
Port: 70,
|
|
Extras: []string{},
|
|
})
|
|
|
|
data1, err := item.MarshalText()
|
|
assert.Nil(err)
|
|
assert.Equal(data, string(data1))
|
|
}
|
|
|
|
func TestParseItemMarshalIdempotency(t *testing.T) {
|
|
assert := assert.New(t)
|
|
require := require.New(t)
|
|
|
|
data := "0"
|
|
item, err := gopher.ParseItem(data)
|
|
require.NoError(err)
|
|
assert.NotNil(item)
|
|
|
|
data1, err := item.MarshalText()
|
|
assert.Nil(err)
|
|
|
|
item1, err := gopher.ParseItem(string(data1))
|
|
assert.NoError(err)
|
|
assert.NotNil(item1)
|
|
assert.Equal(item, item1)
|
|
}
|