testexec: support both simple sequence and script mode.
commit 73c1a4a4edab6b6ca91113b5637efcc8431ba913 · parent b64e21b1ab
· browse this tree
Eric Myhre, 2021-09-21 17:25:59 UTC
And a method which does either of them. (Moderately helpful if you have a file with both kinds of fixture in the file; but will become even more relevant when doing the "then-" stuff, in case you want to mix modes.)
diff --git a/testexec/testexec.go b/testexec/testexec.go index 8d673fd..976753a 100644 --- a/testexec/testexec.go +++ b/testexec/testexec.go @@ -131,13 +131,36 @@ func (tcfg *Tester) init() { // As an edge case, note that if that an exitcode hunk is absent, but a nonzero exitcode is encountered, // the test will still be failed, even though in patch regen mode most assertions are usually skipped. func (tcfg Tester) TestSequence(t *testing.T, data testmark.DirEnt) { + tcfg.test(t, data, true, false) +} + +func (tcfg Tester) TestScript(t *testing.T, data testmark.DirEnt) { + tcfg.test(t, data, false, true) +} + +func (tcfg Tester) Test(t *testing.T, data testmark.DirEnt) { + tcfg.test(t, data, true, true) +} + +func (tcfg Tester) test(t *testing.T, data testmark.DirEnt, allowExec, allowScript bool) { t.Helper() tcfg.init() - sequenceHunk, exists := data.Children["sequence"] - if !exists { + sequenceHunk, sequenceMode := data.Children["sequence"] + scriptHunk, scriptMode := data.Children["script"] + if !sequenceMode && !scriptMode { return } + if sequenceMode && scriptMode { + t.Logf("warning: dir %q contained both a 'script' and a 'sequence' hunk, which is nonsensical", data.Name) + t.SkipNow() + } + if sequenceMode && !allowExec { + t.Skipf("found sequence hunk but the test framework was invoked without permission to run those") + } + if scriptMode && !allowScript { + t.Skipf("found sequence hunk but the test framework was invoked without permission to run those") + } if *testmark.Regen && tcfg.Patches == nil { t.Logf("warning: testmark.regen mode engaged, but there is no patch accumulator available here") t.Skipf("nothing to do if requested to regenerate test fixtures but have nowhere to put data") @@ -163,22 +186,12 @@ func (tcfg Tester) TestSequence(t *testing.T, data testmark.DirEnt) { } var exitcode int - // Loop over the lines in the sequence. - lines := bytes.Split(sequenceHunk.Hunk.Body, []byte{'\n'}) - for _, line := range lines { - args := strings.Fields(string(line)) - if len(args) < 1 { - continue - } - - var err error - exitcode, err = tcfg.ExecFn(args, bytes.NewReader(nil), stdout, stderr) - if err != nil { - t.Fatalf("execution failed: %s", err) - } - if exitcode != 0 { - break // TODO: it's probably still an error if that happens before the end? - } + // Do the thing. + switch { + case sequenceMode: + exitcode = tcfg.doSequence(t, sequenceHunk.Hunk, stdout, stderr) + case scriptMode: + exitcode = tcfg.doScript(t, scriptHunk.Hunk, stdout, stderr) } // Okay, comparisons time. @@ -226,16 +239,35 @@ func (tcfg Tester) TestSequence(t *testing.T, data testmark.DirEnt) { }) // TODO: look for "then-*" dirs. -} -func (tcfg Tester) TestScript(t *testing.T, data testmark.DirEnt) { - panic("not yet implemented") } -func (tcfg Tester) Test(t *testing.T, data testmark.DirEnt) { - panic("not yet implemented") -} +func (tcfg Tester) doSequence(t *testing.T, hunk *testmark.Hunk, stdout, stderr io.Writer) (exitcode int) { + // Loop over the lines in the sequence. + lines := bytes.Split(hunk.Body, []byte{'\n'}) + for _, line := range lines { + args := strings.Fields(string(line)) + if len(args) < 1 { + continue + } -// Not yet defined how these will nest. ISTM if you specify one or the other, it shouldn't become willing to switch when it goes deeper into then-trees. + var err error + exitcode, err = tcfg.ExecFn(args, bytes.NewReader(nil), stdout, stderr) + if err != nil { + t.Fatalf("execution failed: %s", err) + } + if exitcode != 0 { + break // TODO: it's probably still an error if that happens before the end? + } + } + return +} -// Not yet defined if these should complain loudly if they _don't_ find something that matches. I think being able to shrug is useful; otherwise that check will often get offloaded to callers. +func (tcfg Tester) doScript(t *testing.T, hunk *testmark.Hunk, stdout, stderr io.Writer) (exitcode int) { + var err error + exitcode, err = tcfg.ScriptFn(string(hunk.Body), bytes.NewReader(nil), stdout, stderr) + if err != nil { + t.Fatalf("execution failed: %s", err) + } + return +}