Skip to content

Commit

Permalink
make run command work a little better, start breaking up script into …
Browse files Browse the repository at this point in the history
…more files
  • Loading branch information
verdverm committed Jun 12, 2020
1 parent 4d097cb commit 6ae9314
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 199 deletions.
2 changes: 1 addition & 1 deletion cmd/hof/cmd/run.go
Expand Up @@ -85,4 +85,4 @@ func init() {
RunCmd.SetHelpFunc(thelp)
RunCmd.SetUsageFunc(tusage)

}
}
6 changes: 6 additions & 0 deletions lib/ops/run.go
Expand Up @@ -23,6 +23,12 @@ var (

func RunRunFromArgs(args []string) error {

defer func() {
if r := recover(); r != nil {
// fmt.Println("Recovered in f", r)
}
}()

var cueFiles, hlsFiles, tbdFiles []string
for _, a := range args {
switch filepath.Ext(a) {
Expand Down
73 changes: 73 additions & 0 deletions script/env.go
@@ -0,0 +1,73 @@
package script

import (
"fmt"
"strings"
)

// Env holds the environment to use at the start of a test script invocation.
type Env struct {
// WorkDir holds the path to the root directory of the
// extracted files.
WorkDir string
// Vars holds the initial set environment variables that will be passed to the
// testscript commands.
Vars []string
// Cd holds the initial current working directory.
Cd string
// Values holds a map of arbitrary values for use by custom
// testscript commands. This enables Setup to pass arbitrary
// values (not just strings) through to custom commands.
Values map[interface{}]interface{}

ts *Script
}

// Value returns a value from Env.Values, or nil if no
// value was set by Setup.
func (ts *Script) Value(key interface{}) interface{} {
return ts.values[key]
}

// Defer arranges for f to be called at the end
// of the test. If Defer is called multiple times, the
// defers are executed in reverse order (similar
// to Go's defer statement)
func (e *Env) Defer(f func()) {
e.ts.Defer(f)
}

// Getenv retrieves the value of the environment variable named by the key. It
// returns the value, which will be empty if the variable is not present.
func (e *Env) Getenv(key string) string {
key = envvarname(key)
for i := len(e.Vars) - 1; i >= 0; i-- {
if pair := strings.SplitN(e.Vars[i], "=", 2); len(pair) == 2 && envvarname(pair[0]) == key {
return pair[1]
}
}
return ""
}

// Setenv sets the value of the environment variable named by the key. It
// panics if key is invalid.
func (e *Env) Setenv(key, value string) {
if key == "" || strings.IndexByte(key, '=') != -1 {
panic(fmt.Errorf("invalid environment variable key %q", key))
}
e.Vars = append(e.Vars, key+"="+value)
}

// T returns the t argument passed to the current test by the T.Run method.
// Note that if the tests were started by calling Run,
// the returned value will implement testing.TB.
// Note that, despite that, the underlying value will not be of type
// *testing.T because *testing.T does not implement T.
//
// If Cleanup is called on the returned value, the function will run
// after any functions passed to Env.Defer.
func (e *Env) T() T {
return e.ts.t
}


12 changes: 12 additions & 0 deletions script/funcs.go
@@ -0,0 +1,12 @@
package script

import (
"fmt"
)


func callCue(ts Script, args[]string) error {
fmt.Println("cue helper not implemented yet")
return nil
}

91 changes: 91 additions & 0 deletions script/params.go
@@ -0,0 +1,91 @@
package script

// Params holds parameters for a call to Run.
type Params struct {
// Mode is the top level operation mode for script
// It can be "test" or "run" to control how scripts are isolated (or not)
Mode string

// Dir holds the name of the directory holding the scripts.
// All files in the directory with a .hls suffix will be considered
// as test scripts. By default the current directory is used.
// Dir is interpreted relative to the current test directory.
Dir string

// Glob holds the patter to match, defaults to '*.hls'
Glob string

// Setup is called, if not nil, to complete any setup required
// for a test. The WorkDir and Vars fields will have already
// been initialized and all the files extracted into WorkDir,
// and Cd will be the same as WorkDir.
// The Setup function may modify Vars and Cd as it wishes.
Setup func(*Env) error

// Condition is called, if not nil, to determine whether a particular
// condition is true. It's called only for conditions not in the
// standard set, and may be nil.
Condition func(cond string) (bool, error)

// Cmds holds a map of commands available to the script.
// It will only be consulted for commands not part of the standard set.
Cmds map[string]func(ts *Script, neg int, args []string)

// Funcs holds a map of functions available to the script.
// These work like exec and use 'call' instead.
// Use these to facilitate code coverage (exec does not capture this).
Funcs map[string]func(ts *Script, args []string) error

// TestWork specifies that working directories should be
// left intact for later inspection.
TestWork bool

// WorkdirRoot specifies the directory within which scripts' work
// directories will be created. Setting WorkdirRoot implies TestWork=true.
// If empty, the work directories will be created inside
// $GOTMPDIR/go-test-script*, where $GOTMPDIR defaults to os.TempDir().
WorkdirRoot string

// IgnoreMissedCoverage specifies that if coverage information
// is being generated (with the -test.coverprofile flag) and a subcommand
// function passed to RunMain fails to generate coverage information
// (for example because the function invoked os.Exit), then the
// error will be ignored.
IgnoreMissedCoverage bool

// UpdateScripts specifies that if a `cmp` command fails and
// its first argument is `stdout` or `stderr` and its second argument
// refers to a file inside the testscript file, the command will succeed
// and the testscript file will be updated to reflect the actual output.
//
// The content will be quoted with txtar.Quote if needed;
// a manual change will be needed if it is not unquoted in the
// script.
UpdateScripts bool

// Line prefix which indicates a new phase
// defaults to "#"
PhasePrefix string

// Comment prefix for a line
// defaults to "~"
CommentPrefix string
}

func paramDefaults(p Params) Params {
if p.Mode == "" {
p.Mode = "test"
}
if p.Glob == "" {
p.Glob = "*.hls"
}
if p.PhasePrefix == "" {
p.PhasePrefix = "###"
}
if p.CommentPrefix == "" {
p.CommentPrefix = "#"
}

return p
}

2 changes: 1 addition & 1 deletion script/runner.go
Expand Up @@ -15,7 +15,7 @@ type Runner struct {
}

func (r Runner) Skip(is ...interface{}) {
panic(skipRun)
// panic(skipRun)
}

func (r Runner) Fatal(is ...interface{}) {
Expand Down
154 changes: 0 additions & 154 deletions script/script.go
Expand Up @@ -42,143 +42,6 @@ var execCache par.Cache
// poke at the test file tree afterward.
var testWork = flag.Bool("testwork", false, "")

// Env holds the environment to use at the start of a test script invocation.
type Env struct {
// WorkDir holds the path to the root directory of the
// extracted files.
WorkDir string
// Vars holds the initial set environment variables that will be passed to the
// testscript commands.
Vars []string
// Cd holds the initial current working directory.
Cd string
// Values holds a map of arbitrary values for use by custom
// testscript commands. This enables Setup to pass arbitrary
// values (not just strings) through to custom commands.
Values map[interface{}]interface{}

ts *Script
}

// Value returns a value from Env.Values, or nil if no
// value was set by Setup.
func (ts *Script) Value(key interface{}) interface{} {
return ts.values[key]
}

// Defer arranges for f to be called at the end
// of the test. If Defer is called multiple times, the
// defers are executed in reverse order (similar
// to Go's defer statement)
func (e *Env) Defer(f func()) {
e.ts.Defer(f)
}

// Getenv retrieves the value of the environment variable named by the key. It
// returns the value, which will be empty if the variable is not present.
func (e *Env) Getenv(key string) string {
key = envvarname(key)
for i := len(e.Vars) - 1; i >= 0; i-- {
if pair := strings.SplitN(e.Vars[i], "=", 2); len(pair) == 2 && envvarname(pair[0]) == key {
return pair[1]
}
}
return ""
}

// Setenv sets the value of the environment variable named by the key. It
// panics if key is invalid.
func (e *Env) Setenv(key, value string) {
if key == "" || strings.IndexByte(key, '=') != -1 {
panic(fmt.Errorf("invalid environment variable key %q", key))
}
e.Vars = append(e.Vars, key+"="+value)
}

// T returns the t argument passed to the current test by the T.Run method.
// Note that if the tests were started by calling Run,
// the returned value will implement testing.TB.
// Note that, despite that, the underlying value will not be of type
// *testing.T because *testing.T does not implement T.
//
// If Cleanup is called on the returned value, the function will run
// after any functions passed to Env.Defer.
func (e *Env) T() T {
return e.ts.t
}

// Params holds parameters for a call to Run.
type Params struct {
// Mode is the top level operation mode for script
// It can be "test" or "run" to control how scripts are isolated (or not)
Mode string

// Dir holds the name of the directory holding the scripts.
// All files in the directory with a .hls suffix will be considered
// as test scripts. By default the current directory is used.
// Dir is interpreted relative to the current test directory.
Dir string

// Glob holds the patter to match, defaults to '*.hls'
Glob string

// Setup is called, if not nil, to complete any setup required
// for a test. The WorkDir and Vars fields will have already
// been initialized and all the files extracted into WorkDir,
// and Cd will be the same as WorkDir.
// The Setup function may modify Vars and Cd as it wishes.
Setup func(*Env) error

// Condition is called, if not nil, to determine whether a particular
// condition is true. It's called only for conditions not in the
// standard set, and may be nil.
Condition func(cond string) (bool, error)

// Cmds holds a map of commands available to the script.
// It will only be consulted for commands not part of the standard set.
Cmds map[string]func(ts *Script, neg int, args []string)

// Funcs holds a map of functions available to the script.
// These work like exec and use 'call' instead.
// Use these to facilitate code coverage (exec does not capture this).
Funcs map[string]func(ts *Script, args []string) error

// TestWork specifies that working directories should be
// left intact for later inspection.
TestWork bool

// WorkdirRoot specifies the directory within which scripts' work
// directories will be created. Setting WorkdirRoot implies TestWork=true.
// If empty, the work directories will be created inside
// $GOTMPDIR/go-test-script*, where $GOTMPDIR defaults to os.TempDir().
WorkdirRoot string

// IgnoreMissedCoverage specifies that if coverage information
// is being generated (with the -test.coverprofile flag) and a subcommand
// function passed to RunMain fails to generate coverage information
// (for example because the function invoked os.Exit), then the
// error will be ignored.
IgnoreMissedCoverage bool

// UpdateScripts specifies that if a `cmp` command fails and
// its first argument is `stdout` or `stderr` and its second argument
// refers to a file inside the testscript file, the command will succeed
// and the testscript file will be updated to reflect the actual output.
//
// The content will be quoted with txtar.Quote if needed;
// a manual change will be needed if it is not unquoted in the
// script.
UpdateScripts bool

// Line prefix which indicates a new phase
// defaults to "#"
PhasePrefix string

// Comment prefix for a line
// defaults to "~"
CommentPrefix string
}

// RunDir runs the tests in the given directory. All files in dir with a ".hls"
// are considered to be test files.
func Run(t *testing.T, p Params) {
Expand Down Expand Up @@ -213,23 +76,6 @@ func (t tshim) Verbose() bool {
return testing.Verbose()
}

func paramDefaults(p Params) Params {
if p.Mode == "" {
p.Mode = "test"
}
if p.Glob == "" {
p.Glob = "*.hls"
}
if p.PhasePrefix == "" {
p.PhasePrefix = "###"
}
if p.CommentPrefix == "" {
p.CommentPrefix = "#"
}

return p
}

// RunT is like Run but uses an interface type instead of the concrete *testing.T
// type to make it possible to use testscript functionality outside of go test.
func RunT(t T, p Params) {
Expand Down

0 comments on commit 6ae9314

Please sign in to comment.