Skip to content

Commit 2847f41

Browse files
committed
Add more tests
1 parent 8e2f157 commit 2847f41

File tree

14 files changed

+175
-45
lines changed

14 files changed

+175
-45
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ GLOBAL OPTIONS:
5353
--version, -v print the version
5454
```
5555

56+
### Examples
57+
58+
Ignore watch over all test files:
59+
60+
```
61+
--ignore './**/*_test.go'
62+
```
63+
5664
## Contributing
5765

5866
See the [Contributing guide](/CONTRIBUTING.md) for steps on how to contribute to this project.

builder.go

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
type Builder interface {
1313
Build() error
1414
Binary() string
15-
Errors() string
1615
}
1716

1817
type builder struct {
@@ -25,8 +24,9 @@ type builder struct {
2524

2625
// NewBuilder ...
2726
func NewBuilder(dir string, bin string, wd string, buildArgs []string) Builder {
28-
if len(bin) == 0 {
29-
bin = "bin"
27+
// resolve bin name by current folder name
28+
if bin == "" {
29+
bin = filepath.Base(wd)
3030
}
3131

3232
// does not work on Windows without the ".exe" extension
@@ -45,11 +45,6 @@ func (b *builder) Binary() string {
4545
return b.binary
4646
}
4747

48-
// Errors ...
49-
func (b *builder) Errors() string {
50-
return b.errors
51-
}
52-
5348
// Build ...
5449
func (b *builder) Build() error {
5550
logger.Info("Building program")
@@ -64,14 +59,8 @@ func (b *builder) Build() error {
6459
return err
6560
}
6661

67-
if command.ProcessState.Success() {
68-
b.errors = ""
69-
} else {
70-
b.errors = string(output)
71-
}
72-
73-
if len(b.errors) > 0 {
74-
return fmt.Errorf(b.errors)
62+
if !command.ProcessState.Success() {
63+
return fmt.Errorf("error building: %s", output)
7564
}
7665

7766
return nil

builder_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,26 @@ func TestBuilderSuccessBuild(t *testing.T) {
2727
}
2828
assert.NotNil(t, file, "binary not written properly")
2929
}
30+
31+
func TestBuilderFailureBuild(t *testing.T) {
32+
bArgs := []string{}
33+
bin := "srv"
34+
dir := filepath.Join("testdata", "build-failure")
35+
wd, err := os.Getwd()
36+
if err != nil {
37+
t.Fatalf("couldn't get current working directory: %v", err)
38+
}
39+
40+
b := NewBuilder(dir, bin, wd, bArgs)
41+
err = b.Build()
42+
assert.NotNil(t, err, "build error")
43+
assert.Equal(t, err.Error(), "exit status 2")
44+
}
45+
46+
func TestBuilderDefaultBinName(t *testing.T) {
47+
bin := ""
48+
dir := filepath.Join("testdata", "server")
49+
wd := "/src/projects/project-name"
50+
b := NewBuilder(dir, bin, wd, nil)
51+
assert.Equal(t, b.Binary(), "project-name")
52+
}

main.go

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ import (
1515

1616
var logger = NewLogger("gaper")
1717

18-
// default values
19-
var defaultExtensions = cli.StringSlice{"go"}
20-
var defaultPoolInterval = 500
21-
2218
// exit statuses
2319
var exitStatusSuccess = 0
2420
var exitStatusError = 1
@@ -94,12 +90,10 @@ func main() {
9490
},
9591
cli.IntFlag{
9692
Name: "poll-interval, p",
97-
Value: defaultPoolInterval,
9893
Usage: "how often in milliseconds to poll watched files for changes",
9994
},
10095
cli.StringSliceFlag{
10196
Name: "extensions, e",
102-
Value: &defaultExtensions,
10397
Usage: "a comma-delimited list of file extensions to watch for changes",
10498
},
10599
cli.StringFlag{
@@ -135,11 +129,6 @@ func runGaper(cfg *Config) error {
135129
return err
136130
}
137131

138-
// resolve bin name by current folder name
139-
if cfg.BinName == "" {
140-
cfg.BinName = filepath.Base(wd)
141-
}
142-
143132
if len(cfg.WatchItems) == 0 {
144133
cfg.WatchItems = append(cfg.WatchItems, cfg.BuildPath)
145134
}
@@ -182,7 +171,9 @@ func runGaper(cfg *Config) error {
182171
case event := <-watcher.Events:
183172
logger.Debug("Detected new changed file: ", event)
184173
changeRestart = true
185-
restart(builder, runner)
174+
if err := restart(builder, runner); err != nil {
175+
return err
176+
}
186177
case err := <-watcher.Errors:
187178
return fmt.Errorf("error on watching files: %v", err)
188179
case err := <-runner.Errors():
@@ -249,8 +240,7 @@ func handleProgramExit(builder Builder, runner Runner, err error, noRestartOn st
249240
return nil
250241
}
251242

252-
restart(builder, runner)
253-
return nil
243+
return restart(builder, runner)
254244
}
255245

256246
func shutdown(runner Runner) {

runner.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"errors"
45
"fmt"
56
"io"
67
"os"
@@ -12,6 +13,9 @@ import (
1213
// OSWindows ...
1314
const OSWindows = "windows"
1415

16+
// os errors
17+
var errFinished = errors.New("os: process already finished")
18+
1519
// Runner ...
1620
type Runner interface {
1721
Run() (*exec.Cmd, error)
@@ -28,6 +32,7 @@ type runner struct {
2832
command *exec.Cmd
2933
starttime time.Time
3034
errors chan error
35+
end chan bool // used internally by Kill to wait a process die
3136
}
3237

3338
// NewRunner ...
@@ -39,22 +44,22 @@ func NewRunner(wStdout io.Writer, wStderr io.Writer, bin string, args []string)
3944
writerStderr: wStderr,
4045
starttime: time.Now(),
4146
errors: make(chan error),
47+
end: make(chan bool),
4248
}
4349
}
4450

4551
// Run ...
4652
func (r *runner) Run() (*exec.Cmd, error) {
4753
logger.Info("Starting program")
4854

49-
if r.command == nil || r.Exited() {
50-
if err := r.runBin(); err != nil {
51-
return nil, fmt.Errorf("error running: %v", err)
52-
}
53-
54-
time.Sleep(250 * time.Millisecond)
55+
if r.command != nil && !r.Exited() {
5556
return r.command, nil
5657
}
5758

59+
if err := r.runBin(); err != nil {
60+
return nil, fmt.Errorf("error running: %v", err)
61+
}
62+
5863
return r.command, nil
5964
}
6065

@@ -66,7 +71,7 @@ func (r *runner) Kill() error {
6671

6772
done := make(chan error)
6873
go func() {
69-
r.command.Wait() // nolint errcheck
74+
<-r.end
7075
close(done)
7176
}()
7277

@@ -82,7 +87,7 @@ func (r *runner) Kill() error {
8287
// Wait for our process to die before we return or hard kill after 3 sec
8388
select {
8489
case <-time.After(3 * time.Second):
85-
if err := r.command.Process.Kill(); err != nil {
90+
if err := r.command.Process.Kill(); err != nil && err.Error() != errFinished.Error() {
8691
return fmt.Errorf("failed to kill: %v", err)
8792
}
8893
case <-done:
@@ -128,6 +133,7 @@ func (r *runner) runBin() error {
128133
// wait for exit errors
129134
go func() {
130135
r.errors <- r.command.Wait()
136+
r.end <- true
131137
}()
132138

133139
return nil

runner_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"bytes"
5+
"os"
56
"path/filepath"
67
"runtime"
78
"testing"
@@ -33,3 +34,21 @@ func TestRunnerSuccessRun(t *testing.T) {
3334
assert.Equal(t, "Gaper\n", stdout.String())
3435
}
3536
}
37+
38+
func TestRunnerSuccessKill(t *testing.T) {
39+
bin := filepath.Join("testdata", "print-gaper")
40+
if runtime.GOOS == OSWindows {
41+
bin += ".bat"
42+
}
43+
44+
runner := NewRunner(os.Stdout, os.Stderr, bin, nil)
45+
46+
_, err := runner.Run()
47+
assert.Nil(t, err, "error running binary")
48+
49+
err = runner.Kill()
50+
assert.Nil(t, err, "error killing program")
51+
52+
errCmd := <-runner.Errors()
53+
assert.NotNil(t, errCmd, "kill program")
54+
}

testdata/build-failure/main.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package main
2+
3+
// nolint
4+
func main() error {
5+
}

testdata/hidden-test/.hiden-file

Whitespace-only changes.

testdata/hidden-test/.hiden-folder/.gitkeep

Whitespace-only changes.

testdata/print-gaper

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
#!/usr/bin/env bash
2+
sleep 2
23
echo "Gaper"

0 commit comments

Comments
 (0)