func TestBuildWithNilEventHandler(t *testing.T) { t.Log("When a Handler is defined to respond to /* and response with Hello <path>!") handler := http.NewServeMux() handler.HandleFunc("/hello/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello %s!", filepath.Base(r.URL.Path)) }) t.Log("And Options are defined with defaults and an OutputDir that does not exist.") options := static.DefaultOptions tempDir, _ := ioutil.TempDir("", "") options.OutputDir = filepath.Join(tempDir, "build") t.Logf("OutputDir: %s", options.OutputDir) t.Log("And there are multiple paths to build.") paths := []string{ "/hello/go", "/hello/world", "/hello/universe", } t.Log("Expect Build to create the output path and write a file for each path with contents Hello <file>! And send one event per path to the EventHandler containing no error.") expected := []struct { OutputFilePath string OutputFileContents string }{ { filepath.Join(options.OutputDir, "hello", "go"), "Hello go!", }, { filepath.Join(options.OutputDir, "hello", "world"), "Hello world!", }, { filepath.Join(options.OutputDir, "hello", "universe"), "Hello universe!", }, } static.Build(options, handler, paths, nil) for _, expect := range expected { outputFileContents, err := ioutil.ReadFile(expect.OutputFilePath) if err != nil { t.Fatalf("Error opening output file => %#v, expected to exist.", err) } if string(outputFileContents) == expect.OutputFileContents { t.Logf("Contents of %s => %s", expect.OutputFilePath, outputFileContents) } else { t.Fatalf(`Contents of %s => %s, expected %s`, expect.OutputFilePath, outputFileContents, expect.OutputFileContents) } } }
func ExampleBuild() { handler := http.NewServeMux() paths := []string{} handler.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello %s!", path.Base(r.URL.Path)) }) paths = append(paths, "/world") static.Build(static.DefaultOptions, handler, paths, func(e static.Event) { fmt.Println(e) }) // Output: // Action: build, Path: /world, StatusCode: 200, OutputPath: build/world }
func TestBuildErrors(t *testing.T) { t.Log("When a Handler is defined to respond to /* and response with Hello <path>!") handler := http.NewServeMux() handler.HandleFunc("/hello/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello %s!", filepath.Base(r.URL.Path)) }) t.Log("And Options are defined with defaults and an OutputDir that does not exist.") options := static.DefaultOptions tempDir, _ := ioutil.TempDir("", "") options.OutputDir = filepath.Join(tempDir, "build") t.Logf("OutputDir: %s", options.OutputDir) t.Log("And a file exists at the same path as the OutputDir (a problem).") f, _ := os.Create(options.OutputDir) defer f.Close() t.Log("And there are multiple paths to build.") paths := []string{ "/hello/go", "/hello/world", "/hello/universe", } t.Log("Expect Build to send one event per path to the EventHandler containing an Unable to create dir error.") expectedNumberOfEvents := len(paths) numberOfEvents := 0 events := make(chan static.Event, expectedNumberOfEvents) static.Build(options, handler, paths, func(e static.Event) { select { case events <- e: t.Logf("Event received => %#v", e) default: t.Errorf("Additional event received => %#v", e) } numberOfEvents++ }) close(events) if numberOfEvents != expectedNumberOfEvents { t.Errorf("Number of events received => %d, expected %d", numberOfEvents, expectedNumberOfEvents) } eventsSeen := make(map[string]*static.Event) for event := range events { storeEvent := event if eventsSeen[event.Path] != nil { t.Errorf("Event received => %#v, multiple times but was expected once.", event) } eventsSeen[event.Path] = &storeEvent } for _, path := range paths { event := eventsSeen[path] if event == nil { t.Errorf("Event not received for path => %s, but was expected once.", path) } expectedAction := static.BUILD if event.Action != expectedAction { t.Errorf("Event for %s Action => %s, expected %s.", path, event.Action, expectedAction) } if event.Path != path { t.Errorf("Event for %s Path => %s, expected %s.", path, event.Path, path) } expectedErrString := "Unable to create dir" if event.Error != nil && strings.Contains(event.Error.Error(), expectedErrString) { t.Logf("Build(%#v) => %v", path, event.Error) } else { t.Errorf("Build(%#v) => %v, expected a %s error", path, event.Error, expectedErrString) } } }
func TestBuild(t *testing.T) { t.Log("When a Handler is defined to respond to /* and response with Hello directory for the directory and Hello <path> for all other requests!") handler := http.NewServeMux() handler.HandleFunc("/hello/", func(w http.ResponseWriter, r *http.Request) { var subject string if strings.HasSuffix(r.URL.Path, "/") { subject = "directory" } else { subject = filepath.Base(r.URL.Path) } fmt.Fprintf(w, "Hello %s!", subject) }) t.Log("And Options are defined with defaults and an OutputDir that does not exist.") options := static.DefaultOptions tempDir, _ := ioutil.TempDir("", "") options.OutputDir = filepath.Join(tempDir, "build") t.Logf("OutputDir: %s", options.OutputDir) t.Log("And Options are defined with a DirFilename of index.html.") t.Log("And there are multiple paths to build.") paths := []string{ "/hello/", "/hello/go", "/hello/world", "/hello/universe", "/bye", } t.Log("Expect Build to create the output path and write a file for each path with contents Hello directory! for the directory and Hello <file>! for the others. And send one event per path to the EventHandler containing no error.") expected := []struct { OutputFilePath string OutputFileContents string Event static.Event }{ { filepath.Join(options.OutputDir, "hello", "index.html"), "Hello directory!", static.Event{"build", "/hello/", 200, filepath.Join(options.OutputDir, "hello", "index.html"), nil}, }, { filepath.Join(options.OutputDir, "hello", "go"), "Hello go!", static.Event{"build", "/hello/go", 200, filepath.Join(options.OutputDir, "hello", "go"), nil}, }, { filepath.Join(options.OutputDir, "hello", "world"), "Hello world!", static.Event{"build", "/hello/world", 200, filepath.Join(options.OutputDir, "hello", "world"), nil}, }, { filepath.Join(options.OutputDir, "hello", "universe"), "Hello universe!", static.Event{"build", "/hello/universe", 200, filepath.Join(options.OutputDir, "hello", "universe"), nil}, }, { filepath.Join(options.OutputDir, "bye"), "404 page not found\n", static.Event{"build", "/bye", 404, filepath.Join(options.OutputDir, "bye"), nil}, }, } expectedNumberOfEvents := len(paths) numberOfEvents := 0 events := make(chan static.Event, expectedNumberOfEvents) static.Build(options, handler, paths, func(e static.Event) { select { case events <- e: t.Logf("Event received => %#v", e) default: t.Errorf("Additional event received => %#v", e) } numberOfEvents++ }) close(events) if numberOfEvents != expectedNumberOfEvents { t.Errorf("Number of events received => %d, expected %d", numberOfEvents, expectedNumberOfEvents) } eventsSeen := make(map[static.Event]bool) for event := range events { if eventsSeen[event] { t.Errorf("Event received => %#v, multiple times but was expected once.", event) } eventsSeen[event] = true } for _, expect := range expected { if !eventsSeen[expect.Event] { t.Errorf("Event not received => %#v, but was expected once.", expect.Event) } outputFileContents, err := ioutil.ReadFile(expect.OutputFilePath) if err != nil { t.Fatalf("Error opening output file => %#v, expected to exist.", err) } if string(outputFileContents) == expect.OutputFileContents { t.Logf("Contents of %s => %s", expect.OutputFilePath, outputFileContents) } else { t.Fatalf(`Contents of %s => %s, expected %s`, expect.OutputFilePath, outputFileContents, expect.OutputFileContents) } } }
func main() { mux := http.NewServeMux() paths := []string{} numberPages := len(bibles) * len(days) pages := make([]pageDay, 0, numberPages) uniqPages := pages[0:len(days)] for _, bible := range bibles { var previousPage *pageDay for _, day := range days { page := pageDay{ PreviousPage: previousPage, Day: day, Bible: bible, Bibles: bibles, } pages = append(pages, page) if previousPage != nil { previousPage.NextPage = &page } previousPage = &pages[len(pages)-1] } } paths = append(paths, "/") mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" { templateIndex.ExecuteTemplate(w, "entry", nil) } else { fs := http.FileServer(http.Dir("build")) fs.ServeHTTP(w, r) } }) paths = append(paths, "/plan") mux.HandleFunc("/plan", func(w http.ResponseWriter, r *http.Request) { templatePlan.ExecuteTemplate(w, "entry", uniqPages) }) for i := range pages { page := pages[i] path := page.Path() paths = append(paths, path) mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { err := page.LoadPassages() if err != nil { log.Fatal(err) } templateDay.ExecuteTemplate(w, "entry", page) }) } log.Printf("Registered handlers for %d pages", len(pages)) if build { static.Build(static.DefaultOptions, mux, paths, func(e static.Event) { if e.Error == nil { return } log.Printf("%10s %d %-20s %s", e.Action, e.StatusCode, e.Path, e.Error) }) } else { s := &http.Server{Addr: ":8080", Handler: mux} log.Fatal(s.ListenAndServe()) } }