cue: add tests for manually created builtins

fixes bug with JSON encoding

Change-Id: I3f4ed6daf0985cb90a2f5738abc74be6fdf29a57
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2326
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cue/builtin_test.go b/cue/builtin_test.go
index 83cd80d..a560b08 100644
--- a/cue/builtin_test.go
+++ b/cue/builtin_test.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"math/big"
 	"strings"
 	"testing"
 )
@@ -31,6 +32,11 @@
 			[]string{fmt.Sprintf("(%s)", expr)},
 		}}
 	}
+	hexToDec := func(s string) string {
+		var x big.Int
+		x.SetString(s, 16)
+		return x.String()
+	}
 	testCases := []struct {
 		instances []*bimport
 		emit      string
@@ -128,6 +134,66 @@
 	}, {
 		testExpr(`or([])`),
 		`_|_(builtin:or:empty or)`,
+	}, {
+		test("encoding/csv", `csv.Encode([[1,2,3],[4,5],[7,8,9]])`),
+		`"1,2,3\n4,5\n7,8,9\n"`,
+	}, {
+		test("encoding/csv", `csv.Encode([["a", "b"], ["c"]])`),
+		`"a,b\nc\n"`,
+	}, {
+		test("encoding/json", `json.Valid("1")`),
+		`true`,
+	}, {
+		test("encoding/json", `json.Compact("[1, 2]")`),
+		`"[1,2]"`,
+	}, {
+		test("encoding/json", `json.Indent(#"{"a": 1, "b": 2}"#, "", "  ")`),
+		`"{\n  \"a\": 1,\n  \"b\": 2\n}"`,
+	}, {
+		test("encoding/json", `json.Unmarshal("1")`),
+		`1`,
+	}, {
+		test("encoding/json", `json.MarshalStream([{a: 1}, {b: 2}])`),
+		`"{\"a\":1}\n{\"b\":2}\n"`,
+	}, {
+		test("encoding/yaml", `yaml.MarshalStream([{a: 1}, {b: 2}])`),
+		`"a: 1\n---\nb: 2\n"`,
+	}, {
+		test("strings", `strings.ToCamel("AlphaBeta")`),
+		`"alphaBeta"`,
+	}, {
+		test("strings", `strings.ToTitle("alpha")`),
+		`"Alpha"`,
+	}, {
+		test("math/bits", `bits.And(0x10000000000000F0E, 0xF0F7)`), `6`,
+	}, {
+		test("math/bits", `bits.Or(0x100000000000000F0, 0x0F)`),
+		hexToDec("100000000000000FF"),
+	}, {
+		test("math/bits", `bits.Xor(0x10000000000000F0F, 0xFF0)`),
+		hexToDec("100000000000000FF"),
+	}, {
+		test("math/bits", `bits.Xor(0xFF0, 0x10000000000000F0F)`),
+		hexToDec("100000000000000FF"),
+	}, {
+		test("math/bits", `bits.Clear(0xF, 0x100000000000008)`), `7`,
+	}, {
+		test("math/bits", `bits.Clear(0x1000000000000000008, 0xF)`),
+		hexToDec("1000000000000000000"),
+	}, {
+		test("text/tabwriter", `tabwriter.Write("""
+			a\tb\tc
+			aaa\tbb\tvv
+			""")`),
+		`"a   b  c\naaa bb vv"`,
+	}, {
+		test("text/tabwriter", `tabwriter.Write([
+				"a\tb\tc",
+				"aaa\tbb\tvv"])`),
+		`"a   b  c\naaa bb vv\n"`,
+	}, {
+		test("text/template", `template.Execute("{{.}}-{{.}}", "foo")`),
+		`"foo-foo"`,
 	}}
 	for _, tc := range testCases {
 		t.Run("", func(t *testing.T) {
diff --git a/cue/go.go b/cue/go.go
index a577772..9e97e52 100644
--- a/cue/go.go
+++ b/cue/go.go
@@ -24,6 +24,7 @@
 	"strings"
 	"sync"
 
+	"cuelang.org/go/cue/ast"
 	"cuelang.org/go/cue/parser"
 	"cuelang.org/go/cue/token"
 	"cuelang.org/go/internal"
@@ -194,6 +195,10 @@
 		// null by default, but may still be set: *null | _.
 		return makeNullable(&top{src.base()}).(evaluated)
 
+	case ast.Expr:
+		x := newVisitorCtx(ctx, nil, nil, nil)
+		return ctx.manifest(x.walk(v))
+
 	case *big.Int:
 		n := newNum(src, intKind)
 		n.v.Coeff.Set(v)