Skip to content
This repository has been archived by the owner on Aug 29, 2022. It is now read-only.

Commit

Permalink
Use nhatthm/consoledog
Browse files Browse the repository at this point in the history
  • Loading branch information
nhatthm committed Apr 19, 2021
1 parent 24324e6 commit 1419700
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 71 deletions.
5 changes: 3 additions & 2 deletions features/bootstrap/godog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ func TestIntegration(t *testing.T) {
t.Skip(`Missing "-godog" flag, skipping integration test.`)
}

m := surveydog.New()
p := NewPrompt()
m := surveydog.New(t).
WithStarter(p.WithStdio)

RunSuite(t, "..", func(_ *testing.T, ctx *godog.ScenarioContext) {
m.RegisterContext(t, ctx, p.WithStdio)
m.RegisterContext(ctx)
p.RegisterContext(ctx)
})
}
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ require (
github.com/Netflix/go-expect v0.0.0-20201125194554-85d881c3777e
github.com/creack/pty v1.1.11 // indirect
github.com/cucumber/godog v0.11.0
github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c
github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c // indirect
github.com/kr/pty v1.1.8 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/nhatthm/consoledog v0.1.3
github.com/nhatthm/surveyexpect v0.3.0
github.com/stretchr/testify v1.7.0
golang.org/x/text v0.3.6 // indirect
Expand Down
5 changes: 4 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nhatthm/consoledog v0.1.3 h1:udYv6qO79JC5KcXy8iPS+iB92XaZGUbUocBjpsRIrG0=
github.com/nhatthm/consoledog v0.1.3/go.mod h1:Zb1FInjsGiXmWYCEUE4NWCf4nR9LgVT/TGkpgCTiFOM=
github.com/nhatthm/surveyexpect v0.3.0 h1:DZBEY67ynBlwDa/hqq5ZVw2vW2oUqY7DChmWEEJiBGY=
github.com/nhatthm/surveyexpect v0.3.0/go.mod h1:KlX6gIkfmduh8f6WP1FyAbJHOzj0nGLgOJ/3gjDLu2A=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
Expand Down Expand Up @@ -233,8 +235,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc h1:+q90ECDSAQirdykUN6sPEiBXBsp8Csjcca8Oy7bgLTA=
golang.org/x/crypto v0.0.0-20210415154028-4f45737414dc/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down
74 changes: 57 additions & 17 deletions manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,51 @@ import (
"time"

"github.com/AlecAivazis/survey/v2/terminal"
"github.com/Netflix/go-expect"
"github.com/cucumber/godog"
"github.com/nhatthm/consoledog"
"github.com/nhatthm/surveyexpect"
"github.com/stretchr/testify/assert"
)

// Starter is a callback when survey starts.
type Starter func(sc *godog.Scenario, stdio terminal.Stdio)

// Manager is a wrapper around *surveyexpect.Survey to make it run with cucumber/godog.
type Manager struct {
console *consoledog.Manager
surveys map[string]*Survey
current string

mu sync.Mutex
starters []Starter

test surveyexpect.TestingT
mu sync.Mutex

options []surveyexpect.ExpectOption
}

// RegisterContext register the survey to a *godog.ScenarioContext.
func (m *Manager) RegisterContext(t surveyexpect.TestingT, ctx *godog.ScenarioContext, listeners ...func(sc *godog.Scenario, stdio terminal.Stdio)) {
func (m *Manager) registerConsole(ctx *godog.ScenarioContext) {
if m.console != nil {
return
}

console := consoledog.New(m.test)
m.attach(console)

// Manage state.
ctx.BeforeScenario(func(sc *godog.Scenario) {
m.beforeScenario(t, sc, listeners...)
console.NewConsole(sc)
})

ctx.AfterScenario(func(sc *godog.Scenario, _ error) {
m.afterScenario(t, sc)
console.CloseConsole(sc)
})
}

// RegisterContext register the survey to a *godog.ScenarioContext.
func (m *Manager) RegisterContext(ctx *godog.ScenarioContext) {
m.registerConsole(ctx)

// Confirm prompt
ctx.Step(`(?:(?:get)|(?:see))s? a(?:nother)? confirm prompt "([^"]*)".* answers? yes`, m.expectConfirmYes)
Expand All @@ -45,34 +65,33 @@ func (m *Manager) RegisterContext(t surveyexpect.TestingT, ctx *godog.ScenarioCo
ctx.Step(`(?:(?:get)|(?:see))s? a(?:nother)? password prompt "([^"]*)".* asks? for help and sees? "([^"]*)"`, m.expectPasswordHelp)
}

// Stdio returns terminal.Stdio of the current survey.
func (m *Manager) Stdio() terminal.Stdio {
return m.survey().Stdio()
}

func (m *Manager) beforeScenario(t surveyexpect.TestingT, sc *godog.Scenario, listeners ...func(sc *godog.Scenario, stdio terminal.Stdio)) {
func (m *Manager) start(sc *godog.Scenario, console *expect.Console) {
m.mu.Lock()
defer m.mu.Unlock()

s := NewSurvey(t, m.options...).Start(sc.Name)
s := NewSurvey(m.test, m.options...).Start(console)

m.current = sc.Id
m.surveys[m.current] = s

for _, l := range listeners {
l(sc, s.Stdio())
for _, start := range m.starters {
start(sc, terminal.Stdio{
In: console.Tty(),
Out: console.Tty(),
Err: console.Tty(),
})
}
}

func (m *Manager) afterScenario(t surveyexpect.TestingT, sc *godog.Scenario) {
func (m *Manager) close(sc *godog.Scenario) {
m.mu.Lock()
defer m.mu.Unlock()

if s := m.surveys[sc.Id]; s != nil {
s.Close()
delete(m.surveys, sc.Id)

assert.NoError(t, m.expectationsWereMet(sc.Name, s))
assert.NoError(m.test, m.expectationsWereMet(sc.Name, s))
}

m.current = ""
Expand Down Expand Up @@ -146,10 +165,31 @@ func (m *Manager) expectationsWereMet(scenario string, s *Survey) error {
return fmt.Errorf("in scenario %q, %w", scenario, err)
}

func (m *Manager) attach(console *consoledog.Manager) *consoledog.Manager {
return console.
WithStarter(m.start).
WithCloser(m.close)
}

// WithConsole sets console manager.
func (m *Manager) WithConsole(console *consoledog.Manager) *Manager {
m.console = m.attach(console)

return m
}

// WithStarter adds a mew Starter to Manager.
func (m *Manager) WithStarter(s Starter) *Manager {
m.starters = append(m.starters, s)

return m
}

// New initiates a new *surveydog.Manager.
func New(options ...surveyexpect.ExpectOption) *Manager {
func New(t surveyexpect.TestingT, options ...surveyexpect.ExpectOption) *Manager {
return &Manager{
surveys: make(map[string]*Survey),
options: options,
test: t,
}
}
8 changes: 5 additions & 3 deletions manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"time"

"github.com/cucumber/godog"
"github.com/nhatthm/consoledog"
"github.com/nhatthm/surveyexpect"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -57,16 +58,17 @@ func TestManager_ExpectationsWereNotMet(t *testing.T) {
t.Parallel()

testingT := T()
s := New()
c := consoledog.New(testingT)
s := New(testingT).WithConsole(c)
sc := &godog.Scenario{Id: "42", Name: "ExpectationsWereNotMet"}

s.beforeScenario(testingT, sc)
c.NewConsole(sc)

assert.Nil(t, s.expectPasswordAnswer("Enter password:", "password"))

<-time.After(50 * time.Millisecond)

s.afterScenario(testingT, sc)
s.close(sc)

expectedError := `in scenario "ExpectationsWereNotMet", there are remaining expectations that were not met:\
[\t\s]*Type : Password\
Expand Down
49 changes: 2 additions & 47 deletions survey.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,13 @@ import (
"errors"
"sync"

"github.com/AlecAivazis/survey/v2/terminal"
"github.com/Netflix/go-expect"
"github.com/hinshun/vt10x"
"github.com/nhatthm/surveyexpect"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// Survey is a wrapper around *surveyexpect.Survey to make it run with cucumber/godog.
type Survey struct {
*surveyexpect.Survey
console surveyexpect.Console
output *surveyexpect.Buffer
state *vt10x.State

test surveyexpect.TestingT
mu sync.Mutex
Expand Down Expand Up @@ -57,18 +50,6 @@ func (s *Survey) closeDoneChan() {
}
}

// Stdio returns terminal.Stdio from surveyexpect.Console.
func (s *Survey) Stdio() terminal.Stdio {
s.mu.Lock()
defer s.mu.Unlock()

return terminal.Stdio{
In: s.console.Tty(),
Out: s.console.Tty(),
Err: s.console.Tty(),
}
}

// Expect runs an expectation against a given console.
func (s *Survey) Expect(c surveyexpect.Console) error {
for {
Expand All @@ -86,22 +67,9 @@ func (s *Survey) Expect(c surveyexpect.Console) error {
}

// Start starts a new survey.
func (s *Survey) Start(scenario string) *Survey {
s.mu.Lock()
defer s.mu.Unlock()

s.test.Logf("Scenario: %s\n", scenario)

s.output = new(surveyexpect.Buffer)

console, state, err := vt10x.NewVT10XConsole(expect.WithStdout(s.output))
require.NoError(s.test, err)

s.console = console
s.state = state

func (s *Survey) Start(console surveyexpect.Console) *Survey {
go func() {
assert.NoError(s.test, s.Expect(s.console))
assert.NoError(s.test, s.Expect(console))
}()

return s
Expand All @@ -110,19 +78,6 @@ func (s *Survey) Start(scenario string) *Survey {
// Close notifies other parties and close the survey.
func (s *Survey) Close() {
s.closeDoneChan()

s.mu.Lock()
defer s.mu.Unlock()

s.test.Logf("Raw output: %q\n", s.output.String())

// Dump the terminal's screen.
s.test.Logf("State: \n%s\n", expect.StripTrailingEmptyLines(s.state.String()))
s.test.Log()

s.console = nil
s.state = nil
s.output = nil
}

// NewSurvey creates a new survey.
Expand Down

0 comments on commit 1419700

Please # to comment.