forked from smartystreets/goconvey
-
Notifications
You must be signed in to change notification settings - Fork 0
/
goconvey.go
146 lines (121 loc) · 4.43 KB
/
goconvey.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// This executable provides an HTTP server that watches for file system changes
// to .go files within the working directory (and all nested go packages).
// Navigating to the configured host and port will show a web UI showing the
// results of running `go test` in each go package.
package main
import (
"flag"
"fmt"
"log"
"net/http"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/smartystreets/goconvey/web/server/api"
"github.com/smartystreets/goconvey/web/server/contract"
exec "github.com/smartystreets/goconvey/web/server/executor"
parse "github.com/smartystreets/goconvey/web/server/parser"
"github.com/smartystreets/goconvey/web/server/system"
watch "github.com/smartystreets/goconvey/web/server/watcher"
)
func init() {
flags()
folders()
}
func flags() {
flag.IntVar(&port, "port", 8080, "The port at which to serve http.")
flag.StringVar(&host, "host", "127.0.0.1", "The host at which to serve http.")
flag.DurationVar(&nap, "poll", quarterSecond, "The interval to wait between polling the file system for changes (default: 250ms).")
flag.IntVar(&packages, "packages", 10, "The number of packages to test in parallel. Higher == faster but more costly in terms of computing. (default: 10)")
flag.StringVar(&gobin, "gobin", "go", "The path to the 'go' binary (default: search on the PATH).")
flag.BoolVar(&cover, "cover", true, "Enable package-level coverage statistics. Requires Go 1.2+ and the go cover tool. (default: true)")
flag.IntVar(&depth, "depth", -1, "The directory scanning depth. If -1, scan infinitely deep directory structures. 0: scan working directory. 1+: Scan into nested directories, limited to value. (default: -1)")
flag.StringVar(&testflags, "testflags", "", `Any extra flags to be passed to go test tool (default: '') (example: '-testflags="-test.short=true")`)
log.SetOutput(os.Stdout)
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
func folders() {
_, file, _, _ := runtime.Caller(0)
here := filepath.Dir(file)
static = filepath.Join(here, "/web/client")
reports = filepath.Join(static, "reports")
}
func main() {
flag.Parse()
ensureProperGoTestFlags()
log.Printf("Initial configuration: [host: %s] [port: %d] [poll: %v] [cover: %v] [testflags: %v]\n", host, port, nap, cover, testflags)
monitor, server := wireup()
go monitor.ScanForever()
serveHTTP(server)
}
func ensureProperGoTestFlags() {
testflags = strings.TrimSpace(testflags)
for _, a := range strings.Fields(testflags) {
if a == "-test.parallel" || a == "-parallel" {
log.Fatal("GoConvey does not support the parallel test flag")
}
}
}
func serveHTTP(server contract.Server) {
serveStaticResources()
serveAjaxMethods(server)
activateServer()
}
func serveStaticResources() {
http.Handle("/", http.FileServer(http.Dir(static)))
}
func serveAjaxMethods(server contract.Server) {
http.HandleFunc("/watch", server.Watch)
http.HandleFunc("/ignore", server.Ignore)
http.HandleFunc("/reinstate", server.Reinstate)
http.HandleFunc("/latest", server.Results)
http.HandleFunc("/execute", server.Execute)
http.HandleFunc("/status", server.Status)
http.HandleFunc("/status/poll", server.LongPollStatus)
http.HandleFunc("/pause", server.TogglePause)
}
func activateServer() {
log.Printf("Serving HTTP at: http://%s:%d\n", host, port)
err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
if err != nil {
fmt.Println(err)
}
}
func wireup() (*contract.Monitor, contract.Server) {
log.Println("Constructing components...")
working, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
depthLimit := system.NewDepthLimit(system.NewFileSystem(), depth)
shell := system.NewShell(gobin, testflags, cover, reports)
watcher := watch.NewWatcher(depthLimit, shell)
watcher.Adjust(working)
parser := parse.NewParser(parse.ParsePackageResults)
tester := exec.NewConcurrentTester(shell)
tester.SetBatchSize(packages)
longpollChan, pauseUpdate := make(chan chan string), make(chan bool, 1)
executor := exec.NewExecutor(tester, parser, longpollChan)
server := api.NewHTTPServer(watcher, executor, longpollChan, pauseUpdate)
scanner := watch.NewScanner(depthLimit, watcher)
monitor := contract.NewMonitor(scanner, watcher, executor, server, pauseUpdate, sleeper)
return monitor, server
}
func sleeper() {
time.Sleep(nap)
}
var (
port int
host string
gobin string
nap time.Duration
packages int
cover bool
depth int
testflags string
static string
reports string
quarterSecond = time.Millisecond * 250
)