Increase test coverage (#19)

* Increase test coverage for smug.go

* Add context struct

* Test commander_test.go

* Test commander_test.go
master
Ivan 3 years ago committed by GitHub
parent 2a6aec6ce7
commit fb9a652eef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

1
.gitignore vendored

@ -1 +1,2 @@
coverage.out
dist/

@ -1,2 +1,9 @@
build:
go build -o smug *.go
test:
go test .
coverage:
go test -coverprofile=coverage.out
go tool cover -html=coverage.out

@ -0,0 +1,88 @@
package main
import (
"bytes"
"fmt"
"log"
"os"
"os/exec"
"strings"
"testing"
)
func TestMain(m *testing.M) {
switch os.Getenv("TEST_MAIN") {
case "":
os.Exit(m.Run())
case "echo":
fmt.Println(strings.Join(os.Args[1:], " "))
case "exit":
os.Exit(42)
}
}
func TestExec(t *testing.T) {
logger := log.New(bytes.NewBuffer([]byte{}), "", 0)
commander := DefaultCommander{logger}
cmd := exec.Command(os.Args[0], "42")
cmd.Env = append(os.Environ(), "TEST_MAIN=echo")
output, err := commander.Exec(cmd)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
if output != "42" {
t.Errorf("expected 42, got %q", output)
}
}
func TestExecError(t *testing.T) {
logger := log.New(bytes.NewBuffer([]byte{}), "", 0)
commander := DefaultCommander{logger}
cmd := exec.Command(os.Args[0], "42")
cmd.Env = append(os.Environ(), "TEST_MAIN=exit")
_, err := commander.Exec(cmd)
if err == nil {
t.Errorf("expected error")
}
got := cmd.ProcessState.ExitCode()
if got != 42 {
t.Errorf("expected %d, got %d", 42, got)
}
}
func TestExecSilently(t *testing.T) {
logger := log.New(bytes.NewBuffer([]byte{}), "", 0)
commander := DefaultCommander{logger}
cmd := exec.Command(os.Args[0], "42")
cmd.Env = append(os.Environ(), "TEST_MAIN=echo")
err := commander.ExecSilently(cmd)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
}
func TestExecSilentlyError(t *testing.T) {
logger := log.New(bytes.NewBuffer([]byte{}), "", 0)
commander := DefaultCommander{logger}
cmd := exec.Command(os.Args[0], "42")
cmd.Env = append(os.Environ(), "TEST_MAIN=exit")
err := commander.ExecSilently(cmd)
if err == nil {
t.Errorf("expected error")
}
got := cmd.ProcessState.ExitCode()
if got != 42 {
t.Errorf("expected %d, got %d", 42, got)
}
}

@ -0,0 +1,12 @@
package main
import "os"
type Context struct {
InsideTmuxSession bool
}
func CreateContext() *Context {
insideTmuxSession := os.Getenv("TERM") == "screen"
return &Context{insideTmuxSession}
}

@ -48,6 +48,8 @@ func main() {
tmux := Tmux{commander}
smug := Smug{tmux, commander}
context := CreateContext()
switch options.Command {
case "start":
if len(options.Windows) == 0 {
@ -55,10 +57,10 @@ func main() {
} else {
fmt.Println("Starting new windows...")
}
err = smug.Start(*config, options.Windows, options.Attach)
err = smug.Start(*config, options, *context)
if err != nil {
fmt.Println("Oops, an error occurred! Rolling back...")
smug.Stop(*config, options.Windows)
smug.Stop(*config, options, *context)
}
case "stop":
if len(options.Windows) == 0 {
@ -66,7 +68,7 @@ func main() {
} else {
fmt.Println("Killing windows...")
}
err = smug.Stop(*config, options.Windows)
err = smug.Stop(*config, options, *context)
default:
err = fmt.Errorf("Unknown command %q", options.Command)
}

@ -37,7 +37,6 @@ type Smug struct {
func (smug Smug) execShellCommands(commands []string, path string) error {
for _, c := range commands {
cmd := exec.Command("/bin/sh", "-c", c)
cmd.Dir = path
@ -49,19 +48,18 @@ func (smug Smug) execShellCommands(commands []string, path string) error {
return nil
}
func (smug Smug) switchOrAttach(ses string, windows []string, attach bool) error {
insideTmuxSession := os.Getenv("TERM") == "screen"
func (smug Smug) switchOrAttach(sessionName string, attach bool, insideTmuxSession bool) error {
if insideTmuxSession && attach {
return smug.tmux.SwitchClient(ses)
return smug.tmux.SwitchClient(sessionName)
} else if !insideTmuxSession {
return smug.tmux.Attach(ses, os.Stdin, os.Stdout, os.Stderr)
return smug.tmux.Attach(sessionName, os.Stdin, os.Stdout, os.Stderr)
}
return nil
}
func (smug Smug) Stop(config Config, windows []string) error {
func (smug Smug) Stop(config Config, options Options, context Context) error {
windows := options.Windows
if len(windows) == 0 {
sessionRoot := ExpandPath(config.Root)
err := smug.execShellCommands(config.Stop, sessionRoot)
@ -82,15 +80,16 @@ func (smug Smug) Stop(config Config, windows []string) error {
return nil
}
func (smug Smug) Start(config Config, windows []string, attach bool) error {
var ses string
var err error
func (smug Smug) Start(config Config, options Options, context Context) error {
sessionName := config.Session + ":"
sessionExists := smug.tmux.SessionExists(sessionName)
sessionRoot := ExpandPath(config.Root)
sessionExists := smug.tmux.SessionExists(config.Session)
windows := options.Windows
attach := options.Attach
if !sessionExists {
err = smug.execShellCommands(config.BeforeStart, sessionRoot)
err := smug.execShellCommands(config.BeforeStart, sessionRoot)
if err != nil {
return err
}
@ -102,16 +101,12 @@ func (smug Smug) Start(config Config, windows []string, attach bool) error {
defaultWindowName = config.Windows[0].Name
}
ses, err = smug.tmux.NewSession(config.Session, sessionRoot, defaultWindowName)
_, err = smug.tmux.NewSession(strings.Replace(sessionName, ":", "", 1), sessionRoot, defaultWindowName)
if err != nil {
return err
}
} else {
ses = config.Session + ":"
if len(windows) == 0 {
smug.switchOrAttach(ses, windows, attach)
return nil
}
} else if len(windows) == 0 {
return smug.switchOrAttach(sessionName, attach, context.InsideTmuxSession)
}
for wIndex, w := range config.Windows {
@ -124,16 +119,16 @@ func (smug Smug) Start(config Config, windows []string, attach bool) error {
windowRoot = filepath.Join(sessionRoot, w.Root)
}
window := ses + w.Name
window := sessionName + w.Name
if (!sessionExists && wIndex > 0 && len(windows) == 0) || (sessionExists && len(windows) > 0) {
_, err = smug.tmux.NewWindow(ses, w.Name, windowRoot)
_, err := smug.tmux.NewWindow(sessionName, w.Name, windowRoot)
if err != nil {
return err
}
}
for _, c := range w.Commands {
err = smug.tmux.SendKeys(window, c)
err := smug.tmux.SendKeys(window, c)
if err != nil {
return err
}
@ -145,7 +140,7 @@ func (smug Smug) Start(config Config, windows []string, attach bool) error {
paneRoot = filepath.Join(windowRoot, p.Root)
}
_, err = smug.tmux.SplitWindow(window, p.Type, paneRoot, p.Commands)
_, err := smug.tmux.SplitWindow(window, p.Type, paneRoot, p.Commands)
if err != nil {
return err
}
@ -156,14 +151,14 @@ func (smug Smug) Start(config Config, windows []string, attach bool) error {
layout = EvenHorizontal
}
_, err = smug.tmux.SelectLayout(ses+w.Name, layout)
_, err := smug.tmux.SelectLayout(sessionName+w.Name, layout)
if err != nil {
return err
}
}
if len(windows) == 0 {
smug.switchOrAttach(ses, windows, attach)
return smug.switchOrAttach(sessionName, attach, context.InsideTmuxSession)
}
return nil

@ -8,10 +8,12 @@ import (
)
var testTable = []struct {
config Config
startCommands []string
stopCommands []string
windows []string
config Config
options Options
context Context
startCommands []string
stopCommands []string
commanderOutput string
}{
{
Config{
@ -19,8 +21,12 @@ var testTable = []struct {
Root: "root",
BeforeStart: []string{"command1", "command2"},
},
Options{
Windows: []string{},
},
Context{},
[]string{
"tmux has-session -t ses",
"tmux has-session -t ses:",
"/bin/sh -c command1",
"/bin/sh -c command2",
"tmux new -Pd -s ses -n -c root",
@ -29,7 +35,7 @@ var testTable = []struct {
[]string{
"tmux kill-session -t ses",
},
[]string{},
"xyz",
},
{
Config{
@ -57,8 +63,10 @@ var testTable = []struct {
"stop2 -d --foo=bar",
},
},
Options{},
Context{},
[]string{
"tmux has-session -t ses",
"tmux has-session -t ses:",
"tmux new -Pd -s ses -n win1 -c root",
"tmux split-window -Pd -t ses:win1 -c root -h",
"tmux select-layout -t ses:win1 main-horizontal",
@ -69,7 +77,7 @@ var testTable = []struct {
"/bin/sh -c stop2 -d --foo=bar",
"tmux kill-session -t ses",
},
[]string{},
"xyz",
},
{
Config{
@ -86,17 +94,19 @@ var testTable = []struct {
},
},
},
Options{
Windows: []string{"win2"},
},
Context{},
[]string{
"tmux has-session -t ses",
"tmux has-session -t ses:",
"tmux new -Pd -s ses -n win2 -c root",
"tmux select-layout -t ses:win2 even-horizontal",
},
[]string{
"tmux kill-window -t ses:win2",
},
[]string{
"win2",
},
"xyz",
},
{
Config{
@ -115,8 +125,12 @@ var testTable = []struct {
},
},
},
Options{
Windows: []string{},
},
Context{},
[]string{
"tmux has-session -t ses",
"tmux has-session -t ses:",
"tmux new -Pd -s ses -n win1 -c root",
"tmux send-keys -t ses:win1 command1 Enter",
"tmux send-keys -t ses:win1 command2 Enter",
@ -130,18 +144,86 @@ var testTable = []struct {
[]string{
"tmux kill-session -t ses",
},
[]string{},
"xyz",
},
{
Config{
Session: "ses",
Root: "root",
BeforeStart: []string{"command1", "command2"},
},
Options{},
Context{},
[]string{
"tmux has-session -t ses:",
"tmux attach -d -t ses:",
},
[]string{
"tmux kill-session -t ses",
},
"",
},
{
Config{
Session: "ses",
Root: "root",
},
Options{Attach: true},
Context{InsideTmuxSession: true},
[]string{
"tmux has-session -t ses:",
"tmux new -Pd -s ses -n -c root",
"tmux switch-client -t ses:",
},
[]string{
"tmux kill-session -t ses",
},
"xyz",
},
{
Config{
Session: "ses",
Root: "root",
},
Options{Attach: false},
Context{InsideTmuxSession: true},
[]string{
"tmux has-session -t ses:",
"tmux new -Pd -s ses -n -c root",
},
[]string{
"tmux kill-session -t ses",
},
"xyz",
},
{
Config{
Session: "ses",
Root: "root",
},
Options{Attach: true},
Context{InsideTmuxSession: true},
[]string{
"tmux has-session -t ses:",
"tmux switch-client -t ses:",
},
[]string{
"tmux kill-session -t ses",
},
"",
},
}
type MockCommander struct {
Commands []string
Commands []string
DefaultOutput string
}
func (c *MockCommander) Exec(cmd *exec.Cmd) (string, error) {
c.Commands = append(c.Commands, strings.Join(cmd.Args, " "))
return "ses:", nil
return c.DefaultOutput, nil
}
func (c *MockCommander) ExecSilently(cmd *exec.Cmd) error {
@ -153,11 +235,11 @@ func TestStartSession(t *testing.T) {
for _, params := range testTable {
t.Run("test start session", func(t *testing.T) {
commander := &MockCommander{}
commander := &MockCommander{[]string{}, params.commanderOutput}
tmux := Tmux{commander}
smug := Smug{tmux, commander}
err := smug.Start(params.config, params.windows, false)
err := smug.Start(params.config, params.options, params.context)
if err != nil {
t.Fatalf("error %v", err)
}
@ -168,11 +250,11 @@ func TestStartSession(t *testing.T) {
})
t.Run("test stop session", func(t *testing.T) {
commander := &MockCommander{}
commander := &MockCommander{[]string{}, params.commanderOutput}
tmux := Tmux{commander}
smug := Smug{tmux, commander}
err := smug.Stop(params.config, params.windows)
err := smug.Stop(params.config, params.options, params.context)
if err != nil {
t.Fatalf("error %v", err)
}

@ -3,7 +3,6 @@ package main
import (
"os"
"os/exec"
"strings"
)
const (
@ -105,17 +104,6 @@ func (tmux Tmux) StopSession(target string) (string, error) {
return tmux.commander.Exec(cmd)
}
func (tmux Tmux) ListWindows(target string) ([]string, error) {
cmd := exec.Command("tmux", "list-windows", "-t", target, "-F", "#{window_index}")
output, err := tmux.commander.Exec(cmd)
if err != nil {
return []string{}, err
}
return strings.Split(output, "\n"), nil
}
func (tmux Tmux) SwitchClient(target string) error {
cmd := exec.Command("tmux", "switch-client", "-t", target)
return tmux.commander.ExecSilently(cmd)

Loading…
Cancel
Save