예제 #1
0
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)
		}
	}
}
예제 #2
0
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
}
예제 #3
0
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)
		}
	}
}
예제 #4
0
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)
		}
	}
}
예제 #5
0
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())
	}
}