this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

internal/cuetxtar: improve docs

The documentation for this foundational part of CUE's testing
wasn't very comprehensive, and also had not entirely been
updated to take account of API changes.

This CL updates the doc comments to be (hopefully!) more
complete and consistent.

It also removes the `TxTarTest.Update` field which was redundant
with the `CUE_UPDATE` environment variable and was set to the
same value whereever it was currently used, so this change should
have no material effect.

Signed-off-by: Roger Peppe <rogpeppe@gmail.com>
Change-Id: I1f94c0e81c90c3774c4203621521c4ab6e0ed56e
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/541030
Reviewed-by: Paul Jolly <paul@myitcv.io>
Unity-Result: CUEcueckoo <cueckoo@cuelang.org>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>

+106 -87
+2 -4
cue/ast/astutil/resolve_test.go
··· 22 22 23 23 "cuelang.org/go/cue/ast" 24 24 "cuelang.org/go/internal/astinternal" 25 - "cuelang.org/go/internal/cuetest" 26 25 "cuelang.org/go/internal/cuetxtar" 27 26 ) 28 27 29 28 func TestResolve(t *testing.T) { 30 29 test := cuetxtar.TxTarTest{ 31 - Root: "./testdata/resolve", 32 - Name: "resolve", 33 - Update: cuetest.UpdateGoldenFiles, 30 + Root: "./testdata/resolve", 31 + Name: "resolve", 34 32 } 35 33 36 34 test.Run(t, func(t *cuetxtar.Test) {
+2 -4
encoding/protobuf/jsonpb/decoder_test.go
··· 27 27 "cuelang.org/go/encoding/json" 28 28 "cuelang.org/go/encoding/protobuf/jsonpb" 29 29 "cuelang.org/go/encoding/yaml" 30 - "cuelang.org/go/internal/cuetest" 31 30 "cuelang.org/go/internal/cuetxtar" 32 31 ) 33 32 34 33 func TestParse(t *testing.T) { 35 34 test := cuetxtar.TxTarTest{ 36 - Root: "./testdata/decoder", 37 - Name: "jsonpb", 38 - Update: cuetest.UpdateGoldenFiles, 35 + Root: "./testdata/decoder", 36 + Name: "jsonpb", 39 37 } 40 38 41 39 r := cue.Runtime{}
+2 -4
encoding/protobuf/jsonpb/encoder_test.go
··· 23 23 "cuelang.org/go/cue/format" 24 24 "cuelang.org/go/cue/parser" 25 25 "cuelang.org/go/encoding/protobuf/jsonpb" 26 - "cuelang.org/go/internal/cuetest" 27 26 "cuelang.org/go/internal/cuetxtar" 28 27 ) 29 28 30 29 func TestEncoder(t *testing.T) { 31 30 test := cuetxtar.TxTarTest{ 32 - Root: "./testdata/encoder", 33 - Name: "jsonpb", 34 - Update: cuetest.UpdateGoldenFiles, 31 + Root: "./testdata/encoder", 32 + Name: "jsonpb", 35 33 } 36 34 37 35 r := cue.Runtime{}
+2 -4
encoding/protobuf/textproto/decoder_test.go
··· 23 23 "cuelang.org/go/cue/errors" 24 24 "cuelang.org/go/cue/format" 25 25 "cuelang.org/go/encoding/protobuf/textproto" 26 - "cuelang.org/go/internal/cuetest" 27 26 "cuelang.org/go/internal/cuetxtar" 28 27 ) 29 28 30 29 func TestParse(t *testing.T) { 31 30 test := cuetxtar.TxTarTest{ 32 - Root: "./testdata/decoder", 33 - Name: "decode", 34 - Update: cuetest.UpdateGoldenFiles, 31 + Root: "./testdata/decoder", 32 + Name: "decode", 35 33 } 36 34 37 35 r := cue.Runtime{}
+2 -4
encoding/protobuf/textproto/encoder_test.go
··· 21 21 "cuelang.org/go/cue" 22 22 "cuelang.org/go/cue/errors" 23 23 "cuelang.org/go/encoding/protobuf/textproto" 24 - "cuelang.org/go/internal/cuetest" 25 24 "cuelang.org/go/internal/cuetxtar" 26 25 ) 27 26 28 27 func TestEncode(t *testing.T) { 29 28 test := cuetxtar.TxTarTest{ 30 - Root: "./testdata/encoder", 31 - Name: "encode", 32 - Update: cuetest.UpdateGoldenFiles, 29 + Root: "./testdata/encoder", 30 + Name: "encode", 33 31 } 34 32 35 33 r := cue.Runtime{}
+4 -6
internal/core/adt/eval_test.go
··· 29 29 "cuelang.org/go/internal/core/eval" 30 30 "cuelang.org/go/internal/core/runtime" 31 31 "cuelang.org/go/internal/core/validate" 32 - "cuelang.org/go/internal/cuetest" 33 32 "cuelang.org/go/internal/cuetxtar" 34 33 _ "cuelang.org/go/pkg" 35 34 ) ··· 40 39 41 40 func TestEval(t *testing.T) { 42 41 test := cuetxtar.TxTarTest{ 43 - Root: "../../../cue/testdata", 44 - Name: "eval", 45 - Update: cuetest.UpdateGoldenFiles, 46 - Skip: alwaysSkip, 47 - ToDo: needFix, 42 + Root: "../../../cue/testdata", 43 + Name: "eval", 44 + Skip: alwaysSkip, 45 + ToDo: needFix, 48 46 } 49 47 50 48 if *todo {
+4 -6
internal/core/compile/compile_test.go
··· 25 25 "cuelang.org/go/internal/core/compile" 26 26 "cuelang.org/go/internal/core/debug" 27 27 "cuelang.org/go/internal/core/runtime" 28 - "cuelang.org/go/internal/cuetest" 29 28 "cuelang.org/go/internal/cuetxtar" 30 29 ) 31 30 ··· 35 34 36 35 func TestCompile(t *testing.T) { 37 36 test := cuetxtar.TxTarTest{ 38 - Root: "../../../cue/testdata/", 39 - Name: "compile", 40 - Update: cuetest.UpdateGoldenFiles, 41 - Skip: alwaysSkip, 42 - ToDo: needFix, 37 + Root: "../../../cue/testdata/", 38 + Name: "compile", 39 + Skip: alwaysSkip, 40 + ToDo: needFix, 43 41 } 44 42 45 43 if *todo {
+2 -4
internal/core/dep/dep_test.go
··· 24 24 "cuelang.org/go/internal/core/debug" 25 25 "cuelang.org/go/internal/core/dep" 26 26 "cuelang.org/go/internal/core/eval" 27 - "cuelang.org/go/internal/cuetest" 28 27 "cuelang.org/go/internal/cuetxtar" 29 28 "cuelang.org/go/internal/value" 30 29 ) 31 30 32 31 func TestVisit(t *testing.T) { 33 32 test := cuetxtar.TxTarTest{ 34 - Root: "./testdata", 35 - Name: "dependencies", 36 - Update: cuetest.UpdateGoldenFiles, 33 + Root: "./testdata", 34 + Name: "dependencies", 37 35 } 38 36 39 37 test.Run(t, func(t *cuetxtar.Test) {
+2 -4
internal/core/export/export_test.go
··· 31 31 "cuelang.org/go/internal/core/eval" 32 32 "cuelang.org/go/internal/core/export" 33 33 "cuelang.org/go/internal/core/runtime" 34 - "cuelang.org/go/internal/cuetest" 35 34 "cuelang.org/go/internal/cuetxtar" 36 35 "cuelang.org/go/internal/value" 37 36 "golang.org/x/tools/txtar" ··· 39 38 40 39 func TestDefinition(t *testing.T) { 41 40 test := cuetxtar.TxTarTest{ 42 - Root: "./testdata/main", 43 - Name: "definition", 44 - Update: cuetest.UpdateGoldenFiles, 41 + Root: "./testdata/main", 42 + Name: "definition", 45 43 } 46 44 47 45 r := runtime.New()
+2 -4
internal/core/export/extract_test.go
··· 23 23 "cuelang.org/go/internal/core/eval" 24 24 "cuelang.org/go/internal/core/export" 25 25 "cuelang.org/go/internal/core/runtime" 26 - "cuelang.org/go/internal/cuetest" 27 26 "cuelang.org/go/internal/cuetxtar" 28 27 ) 29 28 30 29 func TestExtract(t *testing.T) { 31 30 test := cuetxtar.TxTarTest{ 32 - Root: "./testdata/main", 33 - Name: "doc", 34 - Update: cuetest.UpdateGoldenFiles, 31 + Root: "./testdata/main", 32 + Name: "doc", 35 33 } 36 34 37 35 r := runtime.New()
+1 -3
internal/core/export/self_test.go
··· 29 29 "cuelang.org/go/cue/format" 30 30 "cuelang.org/go/internal/core/adt" 31 31 "cuelang.org/go/internal/core/export" 32 - "cuelang.org/go/internal/cuetest" 33 32 "cuelang.org/go/internal/cuetxtar" 34 33 "cuelang.org/go/internal/diff" 35 34 "cuelang.org/go/internal/types" ··· 38 37 39 38 func TestSelfContained(t *testing.T) { 40 39 test := cuetxtar.TxTarTest{ 41 - Root: "./testdata/selfcontained", 42 - Update: cuetest.UpdateGoldenFiles, 40 + Root: "./testdata/selfcontained", 43 41 } 44 42 45 43 r := cuecontext.New()
+3 -5
internal/core/export/value_test.go
··· 25 25 "cuelang.org/go/internal/core/eval" 26 26 "cuelang.org/go/internal/core/export" 27 27 "cuelang.org/go/internal/core/runtime" 28 - "cuelang.org/go/internal/cuetest" 29 28 "cuelang.org/go/internal/cuetxtar" 30 29 "golang.org/x/tools/txtar" 31 30 ) ··· 36 35 37 36 func TestValue(t *testing.T) { 38 37 test := cuetxtar.TxTarTest{ 39 - Root: "./testdata/main", 40 - Name: "value", 41 - Update: cuetest.UpdateGoldenFiles, 42 - Skip: exclude, 38 + Root: "./testdata/main", 39 + Name: "value", 40 + Skip: exclude, 43 41 } 44 42 45 43 r := runtime.New()
+1
internal/cuetest/cuetest.go
··· 65 65 66 66 // FormatTxtar ensures that .cue files in txtar test archives are well 67 67 // formatted, updating the archive as required prior to running a test. 68 + // It is controlled by setting CUE_FORMAT_TXTAR to a non-empty string like "true". 68 69 var FormatTxtar = os.Getenv(envFormatTxtar) != "" 69 70 70 71 // Condition adds support for CUE-specific testscript conditions within
+71 -23
internal/cuetxtar/txtar.go
··· 38 38 ) 39 39 40 40 // A TxTarTest represents a test run that process all CUE tests in the txtar 41 - // format rooted in a given directory. 41 + // format rooted in a given directory. See the [Test] documentation for 42 + // more details. 42 43 type TxTarTest struct { 43 44 // Run TxTarTest on this directory. 44 45 Root string ··· 49 50 // TODO: by default derive from the current base directory name. 50 51 Name string 51 52 52 - // If Update is true, TestTxTar will update the out/Name file if it differs 53 - // from the original input. The user must set the output in Gold for this 54 - // to be detected. 55 - Update bool 56 - 57 - // Skip is a map of tests to skip to their skip message. 53 + // Skip is a map of tests to skip; the key is the test name; the value is the 54 + // skip message. 58 55 Skip map[string]string 59 56 60 57 // ToDo is a map of tests that should be skipped now, but should be fixed. ··· 63 60 64 61 // A Test represents a single test based on a .txtar file. 65 62 // 66 - // A Test embeds *testing.T and should be used to report errors. 63 + // A Test embeds *[testing.T] and should be used to report errors. 64 + // 65 + // Entries within the txtar file define CUE files (available via the 66 + // ValidInstances and RawInstances methods) and expected output 67 + // (or "golden") files (names starting with "out/\(testname)"). The "main" golden 68 + // file is "out/\(testname)" itself, used when [Test] is used directly as an [io.Writer] 69 + // and with [Test.WriteFile]. 70 + // 71 + // When the test function has returned, output written with [Test.Write], [Test.Writer] 72 + // and friends is checked against the expected output files. 73 + // 74 + // A txtar file can define test-specific tags and values in the comment section. 75 + // These are available via the [Test.HasTag] and [Test.Value] methods. 76 + // The #skip tag causes a [Test] to be skipped. 77 + // The #noformat tag causes the $CUE_FORMAT_TXTAR value 78 + // to be ignored. 67 79 // 68 - // A Test also embeds a *bytes.Buffer which is used to report test results, 69 - // which are compared against the golden file for the test in the TxTar archive. 70 - // If the test fails and the update flag is set to true, the Archive will be 71 - // updated and written to disk. 80 + // If the output differs and $CUE_UPDATE is non-empty, the txtar file will be 81 + // updated and written to disk with the actual output data replacing the 82 + // out files. 83 + // 84 + // If $CUE_FORMAT_TXTAR is non-empty, any CUE files in the txtar 85 + // file will be updated to be properly formatted, unless the #noformat 86 + // tag is present. 72 87 type Test struct { 73 88 // Allow Test to be used as a T. 74 89 *testing.T ··· 85 100 hasGold bool 86 101 } 87 102 103 + // Write implements [io.Writer] by writing to the output for the test, 104 + // which will be tested against the main golden file. 88 105 func (t *Test) Write(b []byte) (n int, err error) { 89 106 if t.buf == nil { 90 107 t.buf = &bytes.Buffer{} ··· 98 115 buf *bytes.Buffer 99 116 } 100 117 118 + // HasTag reports whether the tag with the given key is defined 119 + // for the current test. A tag x is defined by a line in the comment 120 + // section of the txtar file like: 121 + // 122 + // #x 101 123 func (t *Test) HasTag(key string) bool { 102 124 prefix := []byte("#" + key) 103 125 s := bufio.NewScanner(bytes.NewReader(t.Archive.Comment)) ··· 110 132 return false 111 133 } 112 134 135 + // Value returns the value for the given key for this test and 136 + // reports whether it was defined. 137 + // 138 + // A value is defined by a line in the comment section of the txtar 139 + // file like: 140 + // 141 + // #key: value 142 + // 143 + // White space is trimmed from the value before returning. 113 144 func (t *Test) Value(key string) (value string, ok bool) { 114 145 prefix := []byte("#" + key + ":") 115 146 s := bufio.NewScanner(bytes.NewReader(t.Archive.Comment)) ··· 123 154 } 124 155 125 156 // Bool searches for a line starting with #key: value in the comment and 126 - // returns true if the key exists and the value is true. 157 + // reports whether the key exists and its value is true. 127 158 func (t *Test) Bool(key string) bool { 128 159 s, ok := t.Value(key) 129 160 return ok && s == "true" ··· 139 170 return filepath.ToSlash(rel) 140 171 } 141 172 142 - // WriteErrors writes strings and 173 + // WriteErrors writes the full list of errors in err to the test output. 143 174 func (t *Test) WriteErrors(err errors.Error) { 144 175 if err != nil { 145 176 errors.Print(t, err, &errors.Config{ ··· 149 180 } 150 181 } 151 182 152 - // Write file in a directory. 183 + // WriteFile formats f and writes it to the main output, 184 + // prefixed by a line of the form: 185 + // 186 + // == name 187 + // 188 + // where name is the base name of f.Filename. 153 189 func (t *Test) WriteFile(f *ast.File) { 154 190 // TODO: use FileWriter instead in separate CL. 155 191 fmt.Fprintln(t, "==", filepath.Base(f.Filename)) 156 192 _, _ = t.Write(formatNode(t.T, f)) 157 193 } 158 194 159 - // Writer returns a Writer with the given name. 195 + // Writer returns a Writer with the given name. Data written will 196 + // be checked against the file with name "out/\(testName)/\(name)" 197 + // in the txtar file. If name is empty, data will be written to the test 198 + // output and checked against "out/\(testName)". 160 199 func (t *Test) Writer(name string) io.Writer { 161 200 switch name { 162 201 case "": ··· 191 230 return b 192 231 } 193 232 194 - // ValidInstances returns the valid instances for this .txtar file or skips the 233 + // Instance returns the single instance representing the 234 + // top directory in the txtar file. 235 + func (t *Test) Instance() *build.Instance { 236 + return t.ValidInstances()[0] 237 + } 238 + 239 + // Instances returns the valid instances for this .txtar file or skips the 195 240 // test if there is an error loading the instances. 196 241 func (t *Test) ValidInstances(args ...string) []*build.Instance { 197 242 t.Helper() ··· 216 261 217 262 // Load loads the intstances of a txtar file. By default, it only loads 218 263 // files in the root directory. Relative files in the archive are given an 219 - // absolution location by prefixing it with dir. 264 + // absolute location by prefixing it with dir. 220 265 func Load(a *txtar.Archive, dir string, args ...string) []*build.Instance { 221 266 auto := len(args) == 0 222 267 overlay := map[string]load.Source{} ··· 235 280 return load.Instances(args, cfg) 236 281 } 237 282 238 - // Run runs tests defined in txtar files in root or its subdirectories. 239 - // Only tests for which an `old/name` test output file exists are run. 283 + // Run runs tests defined in txtar files in x.Root or its subdirectories. 284 + // 285 + // The function f is called for each such txtar file. See the [Test] documentation 286 + // for more details. 240 287 func (x *TxTarTest) Run(t *testing.T, f func(tc *Test)) { 241 288 t.Helper() 242 289 ··· 288 335 289 336 for i, f := range a.Files { 290 337 291 - // TODO: not entirely correct. 292 - if strings.HasPrefix(f.Name, tc.prefix) { 338 + if strings.HasPrefix(f.Name, tc.prefix) && (f.Name == tc.prefix || f.Name[len(tc.prefix)] == '/') { 339 + // It's either "\(tc.prefix)" or "\(tc.prefix)/..." but not some other name 340 + // that happens to start with tc.prefix. 293 341 tc.hasGold = true 294 342 } 295 343 ··· 329 377 continue 330 378 } 331 379 332 - if x.Update || cuetest.UpdateGoldenFiles { 380 + if cuetest.UpdateGoldenFiles { 333 381 update = true 334 382 gold.Data = result 335 383 continue
+2 -4
tools/fix/fixall_test.go
··· 19 19 "testing" 20 20 21 21 "cuelang.org/go/cue/format" 22 - "cuelang.org/go/internal/cuetest" 23 22 "cuelang.org/go/internal/cuetxtar" 24 23 ) 25 24 ··· 27 26 t.Skip() 28 27 29 28 test := cuetxtar.TxTarTest{ 30 - Root: "./testdata", 31 - Name: "fixmod", 32 - Update: cuetest.UpdateGoldenFiles, 29 + Root: "./testdata", 30 + Name: "fixmod", 33 31 } 34 32 35 33 test.Run(t, func(t *cuetxtar.Test) {
+2 -4
tools/flow/flow_test.go
··· 29 29 "cuelang.org/go/cue/errors" 30 30 "cuelang.org/go/cue/format" 31 31 "cuelang.org/go/cue/stats" 32 - "cuelang.org/go/internal/cuetest" 33 32 "cuelang.org/go/internal/cuetxtar" 34 33 "cuelang.org/go/tools/flow" 35 34 ) ··· 38 37 // their dependencies. 39 38 func TestFlow(t *testing.T) { 40 39 test := cuetxtar.TxTarTest{ 41 - Root: "./testdata", 42 - Name: "run", 43 - Update: cuetest.UpdateGoldenFiles, 40 + Root: "./testdata", 41 + Name: "run", 44 42 } 45 43 46 44 test.Run(t, func(t *cuetxtar.Test) {
+2 -4
tools/trim/trim_test.go
··· 23 23 "cuelang.org/go/cue/errors" 24 24 "cuelang.org/go/cue/format" 25 25 "cuelang.org/go/cue/parser" 26 - "cuelang.org/go/internal/cuetest" 27 26 "cuelang.org/go/internal/cuetxtar" 28 27 "golang.org/x/tools/txtar" 29 28 ) ··· 278 277 279 278 func TestData(t *testing.T) { 280 279 test := cuetxtar.TxTarTest{ 281 - Root: "./testdata", 282 - Name: "trim", 283 - Update: cuetest.UpdateGoldenFiles, 280 + Root: "./testdata", 281 + Name: "trim", 284 282 } 285 283 286 284 test.Run(t, func(t *cuetxtar.Test) {