github.com/carbocation/gotogether@v0.0.0-20130502180533-aa88e503440f/gotogether_test.go (about)

     1  package gotogether
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net/http"
     7  	"os"
     8  	"os/exec"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  )
    13  
    14  const (
    15  	root = "/tmp/gotogether-test"
    16  	port = 9888
    17  )
    18  
    19  func TestText(t *testing.T) {
    20  	expected := map[string]string{
    21  		"Content-Size": "12",
    22  		"Content-Type": "text/plain",
    23  	}
    24  	checkPath(t, "ht.txt", expected)
    25  }
    26  
    27  func TestSub(t *testing.T) {
    28  	expected := map[string]string{
    29  		"Content-Size": "1150",
    30  		"Content-Type": "image/",
    31  	}
    32  	checkPath(t, "sub/favicon.ico", expected)
    33  }
    34  
    35  // / serves a template
    36  func TestTempalte(t *testing.T) {
    37  	server := startServer(t)
    38  	if server == nil {
    39  		t.Fatalf("can't start server")
    40  	}
    41  	defer server.Process.Kill()
    42  
    43  	url := fmt.Sprintf("http://localhost:%d", port)
    44  	resp, err := http.Get(url)
    45  	if err != nil {
    46  		t.Fatalf("can't GET / - %s", err)
    47  	}
    48  
    49  	data, err := ioutil.ReadAll(resp.Body)
    50  	if err != nil {
    51  		t.Fatalf("can't read body - %s", err)
    52  	}
    53  
    54  	if string(data) != "The number is 7\n" {
    55  		t.Fatalf("bad template reply - %s", string(data))
    56  	}
    57  }
    58  
    59  func createMain() error {
    60  	filename := fmt.Sprintf("%s/main.go", root)
    61  	file, err := os.Create(filename)
    62  	if err != nil {
    63  		return err
    64  	}
    65  	defer file.Close()
    66  
    67  	fmt.Fprintf(file, code, port)
    68  	return nil
    69  }
    70  
    71  func initDir() error {
    72  	// Ignore error value, since it might not be there
    73  	os.RemoveAll(root)
    74  
    75  	err := os.Mkdir(root, 0777)
    76  	if err != nil {
    77  		return err
    78  	}
    79  
    80  	return createMain()
    81  }
    82  
    83  func get(path string) (*http.Response, error) {
    84  	url := fmt.Sprintf("http://localhost:%d/static/%s", port, path)
    85  	return http.Get(url)
    86  }
    87  
    88  func startServer(t *testing.T) *exec.Cmd {
    89  	cmd := exec.Command(fmt.Sprintf("%s/gotogether-test", root))
    90  	// Ignore errors, test will fail anyway if server not running
    91  	cmd.Start()
    92  
    93  	// Wait for server
    94  	url := fmt.Sprintf("http://localhost:%d", port)
    95  	start := time.Now()
    96  	for time.Since(start) < time.Duration(2*time.Second) {
    97  		_, err := http.Get(url)
    98  		if err == nil {
    99  			return cmd
   100  		}
   101  		time.Sleep(time.Second / 10)
   102  	}
   103  
   104  	if cmd.Process != nil {
   105  		cmd.Process.Kill()
   106  	}
   107  	t.Fatalf("can't connect to server")
   108  	return nil
   109  }
   110  
   111  func fixGOPATH(cwd string) {
   112  	path := os.Getenv("GOPATH")
   113  	if len(path) == 0 {
   114  		os.Setenv("GOPATH", fmt.Sprintf("%s/../..", cwd))
   115  	}
   116  }
   117  
   118  func init() {
   119  	if err := initDir(); err != nil {
   120  		panic(err)
   121  	}
   122  
   123  	cwd, _ := os.Getwd()
   124  	path := func(name string) string {
   125  		return fmt.Sprintf("%s/%s", cwd, name)
   126  	}
   127  	fixGOPATH(cwd)
   128  
   129  	os.Chdir(root)
   130  	defer os.Chdir(cwd)
   131  
   132  	cmd := exec.Command("go", "install")
   133  	if err := cmd.Run(); err != nil {
   134  		fmt.Printf("error building: %s\n", err)
   135  		panic(err)
   136  	}
   137  
   138  	cmd = exec.Command(path("gotogether"), "gotogether-test", path("test-resources"))
   139  	if err := cmd.Run(); err != nil {
   140  		fmt.Printf("error packing: %s\n", err)
   141  		panic(err)
   142  	}
   143  }
   144  
   145  func checkHeaders(t *testing.T, expected map[string]string, headers http.Header) {
   146  	for key := range expected {
   147  		v1 := expected[key]
   148  		v2 := headers.Get(key)
   149  		if !strings.HasPrefix(v2, v1) {
   150  			t.Fatalf("bad header %s: %s <-> %s", key, v1, v2)
   151  		}
   152  	}
   153  
   154  	key := "Last-Modified"
   155  	value := headers.Get(key)
   156  	if value == "" {
   157  		t.Fatalf("no %s header", key)
   158  	}
   159  }
   160  
   161  func checkPath(t *testing.T, path string, expected map[string]string) {
   162  	server := startServer(t)
   163  	if server == nil {
   164  		return
   165  	}
   166  	defer server.Process.Kill()
   167  
   168  	resp, err := get(path)
   169  	if err != nil {
   170  		t.Fatalf("%s\n", err)
   171  	}
   172  
   173  	if resp.StatusCode != http.StatusOK {
   174  		t.Fatalf("bad reply - %s", resp.Status)
   175  	}
   176  
   177  	checkHeaders(t, expected, resp.Header)
   178  }
   179  
   180  const code = `
   181  package main
   182  
   183  import (
   184  	"fmt"
   185  	"net/http"
   186  	"os"
   187  
   188  	"gotogether"
   189  )
   190  
   191  type params struct {
   192  	Number  int
   193  }
   194  
   195  func indexHandler(w http.ResponseWriter, req *http.Request) {
   196  	t, err := gotogether.LoadTemplates(nil, "t.html")
   197  	if err != nil {
   198  		http.NotFound(w, req)
   199  	}
   200  	if err = t.Execute(w, params{7}); err != nil {
   201  		http.NotFound(w, req)
   202  	}
   203  }
   204  
   205  func main() {
   206  	gotogether.Handle("/static/")
   207  	http.HandleFunc("/", indexHandler)
   208  	if err := http.ListenAndServe(":%d", nil); err != nil {
   209  		fmt.Fprintf(os.Stderr, "error: %%s\n", err)
   210  		os.Exit(1)
   211  	}
   212  }
   213  `