File: transcripts_test.go

package info (click to toggle)
elvish 0.21.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,372 kB
  • sloc: javascript: 236; sh: 130; python: 104; makefile: 88; xml: 9
file content (118 lines) | stat: -rw-r--r-- 2,646 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package prog_test

import (
	"embed"
	"errors"
	"fmt"
	"os"
	"testing"

	"src.elv.sh/pkg/eval"
	"src.elv.sh/pkg/eval/evaltest"
	"src.elv.sh/pkg/prog"
	"src.elv.sh/pkg/prog/progtest"
)

//go:embed *.elvts
var transcripts embed.FS

func TestTranscripts(t *testing.T) {
	evaltest.TestTranscriptsInFS(t, transcripts,
		"show-deprecation-level-in-global", func(ev *eval.Evaler) {
			ev.ExtendGlobal(eval.BuildNs().AddGoFn(
				"show-deprecation-level",
				func() int { return prog.DeprecationLevel }))
		},
		"program-makers-in-global", func(ev *eval.Evaler) {
			ev.ExtendGlobal(eval.BuildNs().
				AddGoFn("program-to-fn", programToFn).
				AddGoFn("composite", prog.Composite).
				AddGoFn("make-program", makeProgram).
				// Error constructors
				AddGoFn("next-program", nextProgram).
				AddGoFn("exit-error", func(i int) any { return prog.Exit(i) }).
				AddGoFn("bad-usage", func(s string) any { return prog.BadUsage(s) }))
		})
}

func programToFn(p prog.Program) eval.Callable {
	return eval.NewGoFn("test-program", progtest.ProgramAsGoFn(p))
}

type makeProgramOpts struct {
	WriteStdout string
	CustomFlag  bool
	SharedFlags bool
	ReturnErr   any
}

func (makeProgramOpts) SetDefaultOptions() {}

func makeProgram(opts makeProgramOpts) prog.Program {
	var returnErr error
	switch e := opts.ReturnErr.(type) {
	case error:
		returnErr = e
	case string:
		returnErr = errors.New(e)
	case nil:
		// Do nothing
	default:
		panic("&return-err should be error or string")
	}
	return &testProgram{
		writeStdout: opts.WriteStdout,
		customFlag:  opts.CustomFlag,
		sharedFlags: opts.SharedFlags,
		returnErr:   returnErr,
	}
}

func nextProgram(cleanupPrint ...string) any {
	switch len(cleanupPrint) {
	case 0:
		return prog.NextProgram()
	case 1:
		return prog.NextProgram(func(fds [3]*os.File) {
			fds[1].WriteString(cleanupPrint[0])
		})
	default:
		panic("next-program takes 0 or 1 argument")
	}
}

type testProgram struct {
	writeStdout string
	customFlag  bool
	sharedFlags bool
	returnErr   error

	flag        string
	daemonPaths *prog.DaemonPaths
	json        *bool
}

func (p *testProgram) RegisterFlags(f *prog.FlagSet) {
	if p.customFlag {
		f.StringVar(&p.flag, "flag", "default", "a flag")
	}
	if p.sharedFlags {
		p.daemonPaths = f.DaemonPaths()
		p.json = f.JSON()
	}
}

func (p *testProgram) Run(fds [3]*os.File, args []string) error {
	if p.returnErr != nil {
		return p.returnErr
	}
	fds[1].WriteString(p.writeStdout)
	if p.customFlag {
		fmt.Fprintf(fds[1], "-flag %s\n", p.flag)
	}
	if p.sharedFlags {
		fmt.Fprintf(fds[1], "-sock %s -db %s -json %v\n",
			p.daemonPaths.Sock, p.daemonPaths.DB, *p.json)
	}
	return nil
}