|
- 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)
- }
|