cuelang.org/go@v0.13.0/encoding/jsonschema/structbuilder_test.go (about)

     1  package jsonschema
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/go-quicktest/qt"
     8  
     9  	"cuelang.org/go/cue"
    10  	"cuelang.org/go/cue/ast"
    11  	"cuelang.org/go/cue/ast/astutil"
    12  	"cuelang.org/go/cue/format"
    13  	"cuelang.org/go/cue/token"
    14  	"cuelang.org/go/internal"
    15  )
    16  
    17  func TestStructBuilderShadowedRef(t *testing.T) {
    18  	var b structBuilder
    19  	ref, err := b.getRef(cue.ParsePath("#foo.bar.baz"))
    20  	qt.Assert(t, qt.IsNil(err))
    21  	ok := b.put(cue.ParsePath("#foo.bar.baz"), ast.NewString("hello"), nil)
    22  	qt.Assert(t, qt.IsTrue(ok))
    23  	ok = b.put(cue.ParsePath("#bar.#foo.xxx"), ref, nil)
    24  	qt.Assert(t, qt.IsTrue(ok))
    25  	assertStructBuilderSyntax(t, &b, `#bar: #foo: xxx: #foo_1.bar.baz
    26  
    27  #foo_1=#foo: bar: baz: "hello"
    28  `)
    29  }
    30  
    31  func TestStructBuilderSelfRef(t *testing.T) {
    32  	var b structBuilder
    33  	ref, err := b.getRef(cue.Path{})
    34  	qt.Assert(t, qt.IsNil(err))
    35  	ok := b.put(cue.Path{}, ast.NewStruct(ast.NewIdent("next"), token.OPTION, ref), nil)
    36  	qt.Assert(t, qt.IsTrue(ok))
    37  	assertStructBuilderSyntax(t, &b, `
    38  _schema
    39  _schema: {
    40  	next?: _schema
    41  }
    42  `)
    43  }
    44  
    45  func TestStructBuilderEntryInsideValue(t *testing.T) {
    46  	var b structBuilder
    47  	ok := b.put(cue.ParsePath("#foo"), ast.NewString("hello"), internal.NewComment(true, "foo comment"))
    48  	qt.Assert(t, qt.IsTrue(ok))
    49  	ok = b.put(cue.ParsePath("#foo.#bar.#baz"), ast.NewString("goodbye"), internal.NewComment(true, "baz comment"))
    50  	qt.Assert(t, qt.IsTrue(ok))
    51  	assertStructBuilderSyntax(t, &b, `
    52  // foo comment
    53  #foo: {
    54  	"hello"
    55  
    56  	// baz comment
    57  	#bar: #baz: "goodbye"
    58  }
    59  `)
    60  }
    61  
    62  func TestStructBuilderNonIdentifierStringNode(t *testing.T) {
    63  	var b structBuilder
    64  	ref, err := b.getRef(cue.ParsePath(`#foo."a b".baz`))
    65  	qt.Assert(t, qt.IsNil(err))
    66  	ok := b.put(cue.ParsePath(`#foo."a b".baz`), ast.NewString("hello"), nil)
    67  	qt.Assert(t, qt.IsTrue(ok))
    68  	ok = b.put(cue.ParsePath("#bar.#foo.xxx"), ref, nil)
    69  	qt.Assert(t, qt.IsTrue(ok))
    70  	assertStructBuilderSyntax(t, &b, `
    71  #bar: #foo: xxx: #foo_1."a b".baz
    72  
    73  #foo_1=#foo: "a b": baz: "hello"
    74  `)
    75  }
    76  
    77  func TestStructBuilderNonIdentifierStringNodeAtRoot(t *testing.T) {
    78  	var b structBuilder
    79  	_, err := b.getRef(cue.ParsePath(`"a b".baz`))
    80  	qt.Assert(t, qt.ErrorMatches(err, `initial element of path "\\"a b\\"\.baz" must be expressed as an identifier`))
    81  }
    82  
    83  func TestStructBuilderRedefinition(t *testing.T) {
    84  	var b structBuilder
    85  	ok := b.put(cue.ParsePath(`a.b.c`), ast.NewString("hello"), nil)
    86  	qt.Assert(t, qt.IsTrue(ok))
    87  	ok = b.put(cue.ParsePath(`a.b.c`), ast.NewString("hello"), nil)
    88  	qt.Assert(t, qt.IsFalse(ok))
    89  }
    90  
    91  func TestStructBuilderNonPresentNodeOmittedFromSyntax(t *testing.T) {
    92  	var b structBuilder
    93  	_, err := b.getRef(cue.ParsePath(`b.c`))
    94  	qt.Assert(t, qt.IsNil(err))
    95  	_, err = b.getRef(cue.ParsePath(`a.c.d`))
    96  	qt.Assert(t, qt.IsNil(err))
    97  	ok := b.put(cue.ParsePath(`a.b`), ast.NewString("hello"), nil)
    98  	qt.Assert(t, qt.IsTrue(ok))
    99  	assertStructBuilderSyntax(t, &b, `a: b: "hello"`)
   100  }
   101  
   102  func assertStructBuilderSyntax(t *testing.T, b *structBuilder, want string) {
   103  	f, err := b.syntax()
   104  	qt.Assert(t, qt.IsNil(err))
   105  	err = astutil.Sanitize(f)
   106  	qt.Assert(t, qt.IsNil(err))
   107  	data, err := format.Node(f)
   108  	qt.Assert(t, qt.IsNil(err))
   109  	qt.Assert(t, qt.Equals(strings.TrimSpace(string(data)), strings.TrimSpace(want)))
   110  }