cuelang.org/go@v0.10.1/internal/core/export/self_test.go (about)

     1  // Copyright 2022 CUE Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package export_test
    16  
    17  import (
    18  	"bytes"
    19  	"strings"
    20  	"testing"
    21  
    22  	"cuelang.org/go/cue"
    23  	"cuelang.org/go/cue/ast"
    24  	"cuelang.org/go/cue/build"
    25  	"cuelang.org/go/cue/cuecontext"
    26  	"cuelang.org/go/cue/errors"
    27  	"cuelang.org/go/cue/format"
    28  	"cuelang.org/go/internal/core/export"
    29  	"cuelang.org/go/internal/cuetdtest"
    30  	"cuelang.org/go/internal/cuetxtar"
    31  	"cuelang.org/go/internal/diff"
    32  	"cuelang.org/go/internal/types"
    33  	"golang.org/x/tools/txtar"
    34  )
    35  
    36  func TestSelfContained(t *testing.T) {
    37  	test := cuetxtar.TxTarTest{
    38  		Name: "self",
    39  		Root: "./testdata/selfcontained",
    40  
    41  		Matrix: cuetdtest.FullMatrix,
    42  
    43  		ToDo: map[string]string{
    44  			"self-v3/selfcontained/errors":                     "reordering",
    45  			"self-v3/selfcontained/import":                     `wa: reference "_hidden_567475F3" not found:`,
    46  			"self-v3/selfcontained/splitcomprehension":         "reference not found",
    47  			"self-v3-noshare/selfcontained/splitcomprehension": "reference not found",
    48  		},
    49  	}
    50  
    51  	test.Run(t, func(t *cuetxtar.Test) {
    52  		r := t.Context()
    53  
    54  		a := t.Instances()
    55  
    56  		v := buildFile(t.T, r, a[0])
    57  
    58  		p, ok := t.Value("path")
    59  		if ok {
    60  			v = v.LookupPath(cue.ParsePath(p))
    61  		}
    62  
    63  		var tValue types.Value
    64  		v.Core(&tValue)
    65  
    66  		self := *export.All
    67  		self.SelfContained = true
    68  
    69  		w := t.Writer("default")
    70  
    71  		test := func() {
    72  			file, errs := self.Def(tValue.R, "", tValue.V)
    73  
    74  			errors.Print(w, errs, nil)
    75  			_, _ = w.Write(formatNode(t.T, file))
    76  
    77  			vf := patch(t.T, r, t.Archive, file)
    78  			doDiff(t.T, v, vf)
    79  
    80  			v = v.Unify(vf)
    81  			doDiff(t.T, v, vf)
    82  		}
    83  		test()
    84  
    85  		if _, ok := t.Value("inlineImports"); ok {
    86  			w = t.Writer("expand_imports")
    87  			self.InlineImports = true
    88  			test()
    89  		}
    90  	})
    91  }
    92  
    93  func buildFile(t *testing.T, r *cue.Context, b *build.Instance) cue.Value {
    94  	t.Helper()
    95  	v := r.BuildInstance(b)
    96  	if err := v.Err(); err != nil {
    97  		t.Fatal(errors.Details(err, nil))
    98  	}
    99  	return v
   100  }
   101  
   102  // patch replaces the package at the root of the Archive with the given CUE
   103  // file.
   104  func patch(t *testing.T, r *cue.Context, orig *txtar.Archive, f *ast.File) cue.Value {
   105  	a := *orig
   106  	a.Files = make([]txtar.File, len(a.Files))
   107  	copy(a.Files, orig.Files)
   108  
   109  	k := 0
   110  	for _, f := range a.Files {
   111  		if strings.HasSuffix(f.Name, ".cue") && !strings.ContainsRune(f.Name, '/') {
   112  			continue
   113  		}
   114  		a.Files[k] = f
   115  		k++
   116  	}
   117  	b, err := format.Node(f)
   118  	if err != nil {
   119  		t.Error(err)
   120  	}
   121  
   122  	a.Files = append(a.Files, txtar.File{
   123  		Name: "in.cue",
   124  		Data: b,
   125  	})
   126  
   127  	instance := cuetxtar.Load(&a, t.TempDir())[0]
   128  	if instance.Err != nil {
   129  		t.Fatal(instance.Err)
   130  	}
   131  
   132  	vn := buildFile(t, r, instance)
   133  	if err := vn.Err(); err != nil {
   134  		t.Fatal(err)
   135  	}
   136  	return vn
   137  }
   138  
   139  func doDiff(t *testing.T, v, w cue.Value) {
   140  	var bb bytes.Buffer
   141  	p := diff.Schema
   142  	p.SkipHidden = true
   143  	d, script := p.Diff(v, w)
   144  	if d != diff.Identity {
   145  		diff.Print(&bb, script)
   146  		t.Error(bb.String())
   147  	}
   148  }
   149  
   150  // TestSC is for debugging purposes. Do not delete.
   151  func TestSC(t *testing.T) {
   152  	in := `
   153  -- cue.mod/module.cue --
   154  module: "mod.test/a"
   155  language: version: "v0.9.0"
   156  -- in.cue --
   157  	`
   158  	if strings.HasSuffix(strings.TrimSpace(in), ".cue --") {
   159  		t.Skip()
   160  	}
   161  
   162  	a := txtar.Parse([]byte(in))
   163  	instance := cuetxtar.Load(a, t.TempDir())[0]
   164  	if instance.Err != nil {
   165  		t.Fatal(instance.Err)
   166  	}
   167  
   168  	r := cuecontext.New()
   169  
   170  	v := buildFile(t, r, instance)
   171  
   172  	// v = v.LookupPath(cue.ParsePath("a.b"))
   173  
   174  	var tValue types.Value
   175  	v.Core(&tValue)
   176  	self := export.All
   177  	self.SelfContained = true
   178  	self.InlineImports = true
   179  
   180  	file, errs := self.Def(tValue.R, "", tValue.V)
   181  	if errs != nil {
   182  		t.Fatal(errs)
   183  	}
   184  
   185  	b, _ := format.Node(file)
   186  	t.Error(string(b))
   187  
   188  	vf := patch(t, r, a, file)
   189  	doDiff(t, v, vf)
   190  }