func testTypeAlias(t *testing.T, cb *tests.ContextBuilder) { source, err := ext.InitialiseAndGenerate(t, cb, "alias", map[string]string{ "a.json": ` { "type": "system:type", "id": "a", "native": "string", "alias": { "type": "json:@string" } }`, "b.json": ` { "type": "system:type", "id": "b", "native": "string", "alias": { "type": "system:@string" } }`, "c.json": ` { "type": "system:type", "id": "c", "native": "array", "alias": { "type": "system:@array", "items": { "type": "json:@string" } } }`, "d.json": ` { "type": "system:type", "id": "d", "native": "array", "alias": { "type": "system:@array", "items": { "type": "system:@string" } } }`, }) require.NoError(t, err) assert.Contains(t, source, "type A string") assert.Contains(t, source, "type B system.String") assert.Contains(t, source, "type C []string") assert.Contains(t, source, "type D []*system.String") }
func TestBuilder(t *testing.T) { g := New("a.b/c") b, err := g.Build() require.NoError(t, err) assert.Equal(t, "package c\n", string(b)) g.buffer.Reset() g.Imports.Anonymous("e.f/g") b, err = g.Build() require.NoError(t, err) assert.Equal(t, "package c\n\nimport (\n\t_ \"e.f/g\"\n)\n", string(b)) g.buffer.Reset() alias := g.Imports.Add("h.i/j") assert.Equal(t, "j", alias) b, err = g.Build() require.NoError(t, err) assert.Equal(t, "package c\n\nimport (\n\t_ \"e.f/g\"\n\t\"h.i/j\"\n)\n", string(b)) g.buffer.Reset() g.SetPackageComment("comment") g.SetIntroComment("intro") g.Print("var ") g.Println("foo string") g.Printf("var bar int\n%s", "var baz bool") g.Println("") g.Println("func foo() {") g.PrintFunctionCall("k.l/m", "n", "o", "p") g.Println("") g.PrintMethodCall("a", "b", "c", "d") g.Println("}") b, err = g.Build() require.NoError(t, err) assert.Contains(t, string(b), `// comment package c // intro import ( _ "e.f/g" "h.i/j" "k.l/m" ) var foo string var bar int var baz bool func foo() { m.n(o, p) a.b(c, d) } `) g.Print("dfskjsdf") _, err = g.Build() assert.IsError(t, err, "CRBYOUOHPG") // Error formatting source }
func TestInt(t *testing.T) { cb := tests.New() defer cb.Cleanup() _, err := runKe(cb, "a", map[string]string{ "gallery.yaml": ` type: system:type id: gallery fields: images: type: system:@map items: type: "@photo" rules: - selector: "{photo} .width" type: system:@int minimum: 800`, "rectangle.yaml": ` type: system:type id: rectangle fields: width: type: system:@int height: type: system:@int`, "photo.yaml": ` type: system:type id: photo fields: size: type: "@rectangle"`, "faces.yaml": ` type: gallery id: faces images: foo: type: photo size: type: rectangle width: 500 height: 500`, }) assert.Error(t, err) assert.Contains(t, err.Error(), "Minimum: value 500 must not be less than 800") }
func TestGenerateAll(t *testing.T) { cb := tests.Context("a.b/c").Wg().Sempty().Jsystem().TempGopath(true) defer cb.Cleanup() pathA, dirA := cb.TempPackage("a", map[string]string{ "a.yml": ` id: a type: system:type fields: a: type: system:@string`, }) err := GenerateAll(cb.Ctx(), pathA, map[string]bool{}) assert.IsError(t, err, "XMVXECGDOX") cb.Path(pathA).Sauto(parser.Parse) done := map[string]bool{pathA: true} err = GenerateAll(cb.Ctx(), pathA, done) require.NoError(t, err) assert.Equal(t, 1, len(done)) err = GenerateAll(cb.Ctx(), pathA, map[string]bool{}) require.NoError(t, err) b, err := ioutil.ReadFile(filepath.Join(dirA, "generated.go")) require.NoError(t, err) assert.Contains(t, string(b), "type A struct") pathB, _ := cb.TempPackage("b", map[string]string{ "pkg.yml": ` type: system:package aliases: {"a": "` + pathA + `"}`, "b.yml": ` id: b type: system:type fields: a: type: system:@string`, }) cb.Path(pathB).Sauto(parser.Parse) err = GenerateAll(cb.Ctx(), pathB, map[string]bool{}) require.NoError(t, err) }
func TestRules(t *testing.T) { cb := tests.New() defer cb.Cleanup() _, err := runKe(cb, "a", map[string]string{ "gallery.yaml": ` type: system:type id: gallery fields: str: type: system:@string rules: - selector: ":root" type: system:@string equal: foo`, "faces.yaml": ` type: gallery id: faces str: foo`, }) require.NoError(t, err) _, err = runKe(cb, "b", map[string]string{ "gallery.yaml": ` type: system:type id: gallery fields: str: type: system:@string rules: - selector: ":root" type: system:@string equal: foo`, "faces.yaml": ` type: gallery id: faces str: bar`, }) assert.Error(t, err) assert.Contains(t, err.Error(), "Equal: value \"bar\" must equal 'foo'") }
func TestGenerate_path(t *testing.T) { cb := tests.New().TempGopath(true) defer cb.Cleanup() path, dir := cb.TempPackage("z", map[string]string{ "a.json": `{"type": "system:type", "id": "a", "fields": {"a": {"type": "system:@string"}}}`, }) cb.Path(path).Dir(dir).Cmd().Wg().Jsystem().Sauto(parser.Parse) err := Generate(cb.Ctx(), cb.Env()) require.NoError(t, err) genBytes, err := ioutil.ReadFile(filepath.Join(dir, "generated.go")) require.NoError(t, err) assert.Contains(t, string(genBytes), "package z\n") }
func TestEditor(t *testing.T) { cb := tests.Context("a.b/c").Alias("g", "d.e/f") b, err := Editor(cb.Ctx(), cb.Env()) require.NoError(t, err) assert.Contains(t, string(b), `package main import ( _ "a.b/c" _ "d.e/f" "fmt" "kego.io/editor/client" _ "kego.io/system" ) func main() { if err := client.Start(); err != nil { fmt.Println(err.Error()) } } `) }
func TestSelector(t *testing.T) { cb := tests.New() defer cb.Cleanup() _, err := runKe(cb, "a", map[string]string{ "gallery.yaml": ` type: system:type id: gallery fields: images: type: system:@map items: type: "@photo" rules: - selector: ".protocol" type: system:@string equal: https`, "photo.yaml": ` type: system:type id: photo fields: protocol: type: system:@string default: http optional: true`, "faces.yaml": ` type: gallery id: faces images: foo: type: photo protocol: http`, }) assert.Error(t, err) assert.Contains(t, err.Error(), "Equal: value \"http\" must equal 'https'") }
func testTypeCollection(t *testing.T, cb *tests.ContextBuilder) { source, err := ext.InitialiseAndGenerate(t, cb, "collections", map[string]string{ "a.json": ` { "type": "system:type", "id": "a", "fields": { "a": { "type": "system:@array", "items": { "type": "json:@string" } }, "b": { "type": "system:@array", "items": { "type": "system:@string" } }, "c": { "type": "system:@array", "items": { "type": "system:@package" } }, "d": { "type": "system:@array", "items": { "type": "system:@string", "interface": true } } } }`, "b.json": ` { "type": "system:type", "id": "b", "native": "string", "alias": { "type": "json:@string" } }`, "c.json": ` { "type": "system:type", "id": "c", "native": "string", "alias": { "type": "system:@string" } }`, "d.json": ` { "type": "system:type", "id": "d", "native": "string", "alias": { "type": "json:@string" } }`, }) require.NoError(t, err) assert.Contains(t, source, "A []string") assert.Contains(t, source, "B []*system.String") assert.Contains(t, source, "C []*system.Package") assert.Contains(t, source, "D []system.StringInterface") }
func TestRun(t *testing.T) { cb := tests.New().RealGopath() defer cb.Cleanup() path, dir := cb.TempPackage("d", map[string]string{ "a.yaml": ` type: system:type id: a fields: b: type: system:@string max-length: 5`, "d.go": `package d`, }) cb.Path(path).Dir(dir).Jauto().Wg().Sauto(parser.Parse) env := envctx.FromContext(cb.Ctx()) err := Generate(cb.Ctx(), env) require.NoError(t, err) b, err := ioutil.ReadFile(filepath.Join(dir, "generated.go")) require.NoError(t, err) assert.Contains(t, string(b), `pkg.Init(`) assert.Contains(t, string(b), `func() interface{} { return new(A) },`) assert.Contains(t, string(b), `func() interface{} { return new(ARule) },`) assert.Contains(t, string(b), `func() reflect.Type { return reflect.TypeOf((*AInterface)(nil)).Elem() },`) assert.Contains(t, string(b), fmt.Sprintf("%v", env.Hash)) err = RunValidateCommand(cb.Ctx()) require.NoError(t, err) file1, err := os.Stat(filepath.Join(dir, ".localke", "validate")) require.NoError(t, err) time1 := file1.ModTime() err = RunValidateCommand(cb.Ctx()) require.NoError(t, err) cb.TempFile("c.yaml", ` type: a id: c b: foo`) err = RunValidateCommand(cb.Ctx()) require.NoError(t, err) // should not rebuild validate command file2, err := os.Stat(filepath.Join(dir, ".localke", "validate")) require.NoError(t, err) time2 := file2.ModTime() assert.Equal(t, time1, time2) cb.TempFile("e.yaml", ` type: a id: e b: tooolong`) err = RunValidateCommand(cb.Ctx()) assert.IsError(t, err, "KFNIOHWCBT") assert.HasError(t, err, "ETWHPXTUVB") cb.TempFile("f.yaml", ` type: system:type id: f fields: a: type: system:@string`) // This loads the new system.Type into the system cache cb.Sauto(parser.Parse) // This generates a new generated.go err = Generate(cb.Ctx(), env) require.NoError(t, err) // This will re-run the build, but still return the validation error err = RunValidateCommand(cb.Ctx()) assert.IsError(t, err, "KFNIOHWCBT") assert.HasError(t, err, "ETWHPXTUVB") cb.RemoveTempFile("e.yaml") cb.TempFile("h.yaml", ` type: system:type id: h fields: a: type: system:@string`) // This loads the new system.Type into the system cache cb.Sauto(parser.Parse) // This generates a new generated.go err = Generate(cb.Ctx(), env) require.NoError(t, err) // This will re-run the build, but not return the validation error err = RunValidateCommand(cb.Ctx()) require.NoError(t, err) // should rebuild validate command file3, err := os.Stat(filepath.Join(dir, ".localke", "validate")) require.NoError(t, err) time3 := file3.ModTime() assert.NotEqual(t, time1, time3) cb.TempFile("g.yaml", ` type: system:type id: g fields: a: type: system:@string`) // We add a new type, but we haven't generated the struct, so it will fail with hash changed err = runValidateCommand(cb.Ctx(), false, false) assert.IsError(t, err, "DTTHRRJSSF") err = os.Remove(filepath.Join(dir, ".localke", "validate")) require.NoError(t, err) _, err = os.Stat(filepath.Join(dir, ".localke", "validate")) assert.True(t, os.IsNotExist(err)) err = runValidateCommand(cb.Ctx(), false, false) assert.IsError(t, err, "DTTHRRJSSF") _, ok := kerr.Source(err).(*os.PathError) assert.True(t, ok) }
func TestValidateMain(t *testing.T) { cb := tests.New().TempGopath(true) defer cb.Cleanup() dir := cb.SetTemp("kego.io/system") cb.Path("kego.io/system").Dir(dir).Jempty().Sempty() cancelled := false cancel := func() { cancelled = true } logged := "" log := func(message string) { logged = message } interrupt := make(chan os.Signal, 1) exitStatus := validateMain(cb.Ctx(), cancel, log, interrupt) assert.Equal(t, 1, exitStatus) assert.False(t, cancelled) assert.Contains(t, logged, "NHXWLPHCHL") logged = "" cb.Jauto().Sauto(parser.Parse) exitStatus = validateMain(cb.Ctx(), cancel, log, interrupt) assert.Equal(t, 0, exitStatus) assert.False(t, cancelled) assert.Equal(t, logged, "") cb.TempFile("a.yaml", ` type: type id: a`) cb.Sauto(parser.Parse) exitStatus = validateMain(cb.Ctx(), cancel, log, interrupt) assert.Equal(t, 3, exitStatus) assert.False(t, cancelled) assert.Equal(t, logged, "") cb.RemoveTempFile("a.yaml"). TempFile("a.yaml", ` type: "@string" id: a max-length: 1 min-length: 2`). Sauto(parser.Parse) exitStatus = validateMain(cb.Ctx(), cancel, log, interrupt) assert.Equal(t, 4, exitStatus) assert.False(t, cancelled) assert.Equal(t, logged, "a: MaxLength 1 must not be less than MinLength 2") logged = "" cb.RemoveTempFile("a.yaml").Sauto(parser.Parse).TempFile("b.yaml", `%`) exitStatus = validateMain(cb.Ctx(), cancel, log, interrupt) assert.Equal(t, 1, exitStatus) assert.False(t, cancelled) assert.Contains(t, logged, "IHSVWAUAYW") }