Beispiel #1
0
func TestImports(t *testing.T) {
	g := NewGenWriter()

	pkg := typewriter.NewPackage("dummy", "SomePackage")

	typ := typewriter.Type{
		Package: pkg,
		Name:    "SomeType",
		Tags: typewriter.Tags{
			{
				Name:  "projections",
				Items: []string{"int"},
			},
		},
	}

	g.Validate(typ)
	imports := g.Imports(typ)

	if !importSliceContains(imports, "errors") {
		t.Errorf("imports should include 'errors'")
	}

	if len(imports) > 1 {
		t.Errorf("imports should only include 'errors'")
	}

	// not easy to devise a test for Sort, since it requires the unexported typewriter.Type.ordered
}
Beispiel #2
0
func TestWriteHeader(t *testing.T) {
	var b bytes.Buffer

	g := NewGenWriter()

	pkg := typewriter.NewPackage("dummy", "SomePackage")

	typ := typewriter.Type{
		Package: pkg,
		Name:    "SomeType",
		Tags: typewriter.Tags{
			{
				Name:  "methods",
				Items: []string{"All"},
			}, // subset to ensure no Sort
		},
	}

	g.Validate(typ)
	g.WriteHeader(&b, typ)

	if strings.Contains(b.String(), "Copyright") {
		t.Errorf("should not contain license info if no sort; got:\n%s", b.String())
	}

	var b2 bytes.Buffer

	typ2 := typewriter.Type{
		Package: pkg,
		Name:    "SomeType",
		Tags:    typewriter.Tags{}, // default includes sort
	}

	g.Validate(typ2)
	g.WriteHeader(&b2, typ2)

	if !strings.Contains(b2.String(), "Copyright") {
		t.Errorf("should contain license info if sort; got:\n%s", b2.String())
	}
}
Beispiel #3
0
func TestWrite(t *testing.T) {
	pkg := typewriter.NewPackage("dummy", "SomePackage")

	typs := []typewriter.Type{
		{
			Package: pkg,
			Name:    "FirstType",
			Tags:    typewriter.Tags{}, // simple default
		},
		{
			Package: pkg,
			Name:    "SecondType",
			Tags: typewriter.Tags{
				{
					Name:  "projections",
					Items: []string{"int", "string"}, // with projections
				},
			},
		},
		{
			Package: pkg,
			Name:    "ThirdType",
			Tags: typewriter.Tags{
				{
					Name:  "methods",
					Items: []string{"All", "Any"}, // subsetted
				},
			},
		},
		{
			Package: pkg,
			Name:    "FourthType",
			Tags: typewriter.Tags{
				{
					Name:  "methods",
					Items: []string{"All", "Any"}, // subsetted
				},
				{
					Name:  "projections",
					Items: []string{"int", "string"}, // and projections
				},
			},
		},
		{
			Package: pkg,
			Name:    "FifthType",
			Tags: typewriter.Tags{
				{
					Name:    "methods",
					Items:   []string{"Count", "Where"},
					Negated: true,
				},
			},
		},
	}

	for _, typ := range typs {
		var b bytes.Buffer

		g := NewGenWriter()

		g.Validate(typ)
		b.WriteString(fmt.Sprintf("package %s\n", pkg.Name()))
		g.WriteBody(&b, typ)

		src := b.String()

		fset := token.NewFileSet()
		_, err := parser.ParseFile(fset, "testwrite.go", src, 0)

		if err != nil {
			t.Errorf(err.Error())
		}
	}
}
Beispiel #4
0
func TestValidate(t *testing.T) {
	g := NewGenWriter()

	pkg := typewriter.NewPackage("dummy", "SomePackage")

	typ := typewriter.Type{
		Package: pkg,
		Name:    "SomeType",
		Tags:    typewriter.Tags{},
	}

	if g.validated[typ.String()] {
		t.Errorf("type should not show having been validated yet")
	}

	if err := g.ensureValidation(typ); err == nil {
		t.Errorf("ensure validation should return err prior to validation")
	}

	valid, err := g.Validate(typ)

	if !valid || err != nil {
		t.Errorf("type should be valid")
	}

	if !g.validated[typ.String()] {
		t.Errorf("type should show having been validated")
	}

	if err := g.ensureValidation(typ); err != nil {
		t.Errorf("ensure validation should not return err after validation")
	}

	if _, ok := g.models[typ.String()]; !ok {
		t.Errorf("type should appear in g.models")
	}

	if m := g.models[typ.String()]; len(m.methods) == 0 {
		t.Errorf("model without tags should have methods")
	}

	if m := g.models[typ.String()]; len(m.projections) != 0 {
		t.Errorf("model without tags should have no projections")
	}

	typ2 := typewriter.Type{
		Package: pkg,
		Name:    "SomeType2",
		Tags: typewriter.Tags{
			typewriter.Tag{
				Name:  "projections",
				Items: []string{"int", "string"},
			},
		},
	}

	valid2, err2 := g.Validate(typ2)

	if !valid2 || err2 != nil {
		t.Errorf("type should be valid")
	}

	if m := g.models[typ2.String()]; len(m.projections) == 0 {
		t.Errorf("model with projections tag should have projections")
	}

	typ3 := typewriter.Type{
		Package: pkg,
		Name:    "SomeType3",
		Tags: typewriter.Tags{
			typewriter.Tag{
				Name:  "projections",
				Items: []string{"int", "Foo"},
			},
		},
	}

	valid3, err3 := g.Validate(typ3)

	if valid3 {
		t.Errorf("type with unknown projection type should be invalid")
	}

	if err3 == nil {
		t.Errorf("type with unknown projection should return error")
	}

	if !strings.Contains(err3.Error(), "Foo") {
		t.Errorf("type with unknown projection type should mention the unknown projection type; got %v", err3)
	}

	if !strings.Contains(err3.Error(), typ3.Name) {
		t.Errorf("type with unknown projection type should mention the type on which it was declared; got %v", err3)
	}

	if m := g.models[typ2.String()]; len(m.projections) == 0 {
		t.Errorf("model with projections tag should have projections")
	}

	typ4 := typewriter.Type{
		Package: pkg,
		Name:    "SomeType4",
		Tags: typewriter.Tags{
			typewriter.Tag{
				Name:  "methods",
				Items: []string{"All", "Foo"},
			},
		},
	}

	valid4, err4 := g.Validate(typ4)

	if valid4 {
		t.Errorf("type with unknown method should be invalid")
	}

	if err4 == nil {
		t.Errorf("type with unknown method should return error")
	}

	if !strings.Contains(err4.Error(), "Foo") {
		t.Errorf("type with unknown method should mention the unknown projection type; got %v", err4)
	}

	if !strings.Contains(err4.Error(), typ4.Name) {
		t.Errorf("type with unknown method should mention the type on which it was declared; got %v", err4)
	}
}
Beispiel #5
0
func TestValidate(t *testing.T) {
	g := NewContainerWriter()

	pkg := typewriter.NewPackage("dummy", "SomePackage")

	typ := typewriter.Type{
		Package: pkg,
		Name:    "SomeType",
		Tags:    typewriter.Tags{},
	}

	write, err := g.Validate(typ)

	if write {
		t.Errorf("no 'containers' tag should not write")
	}

	if err != nil {
		t.Error(err)
	}

	typ2 := typewriter.Type{
		Package: pkg,
		Name:    "SomeType2",
		Tags: typewriter.Tags{
			typewriter.Tag{
				Name:  "containers",
				Items: []string{},
			},
		},
	}

	write2, err2 := g.Validate(typ2)

	if write2 {
		t.Errorf("empty 'containers' tag should not write")
	}

	if err2 != nil {
		t.Error(err)
	}

	typ3 := typewriter.Type{
		Package: pkg,
		Name:    "SomeType3",
		Tags: typewriter.Tags{
			typewriter.Tag{
				Name:  "containers",
				Items: []string{"List", "Foo"},
			},
		},
	}

	write3, err3 := g.Validate(typ3)

	if !write3 {
		t.Errorf("'containers' tag with List should write (and ignore others)")
	}

	if err3 != nil {
		t.Error(err)
	}
}
Beispiel #6
0
func TestEvaluateTags(t *testing.T) {
	typ := typewriter.Type{
		Name:    "TestType",
		Package: typewriter.NewPackage("dummy", "TestPackage"),
	}

	typ.Tags = typewriter.Tags{}

	standardMethods1, projectionMethods1, err1 := evaluateTags(typ)

	if err1 != nil {
		t.Errorf("empty methods should be ok, instead got '%v'", err1)
	}

	if len(standardMethods1) != len(standardTemplates.GetAllKeys()) {
		t.Errorf("standard methods should default to all")
	}

	if len(projectionMethods1) != 0 {
		t.Errorf("projection methods without projected type should be none, instead got %v", projectionMethods1)
	}

	typ.Tags = typewriter.Tags{
		{
			Name:  "methods",
			Items: []string{"Count", "Where"},
		},
	}

	standardMethods2, projectionMethods2, err2 := evaluateTags(typ)

	if err2 != nil {
		t.Errorf("empty methods should be ok, instead got %v", err2)
	}

	if len(standardMethods2) != 2 {
		t.Errorf("standard methods should be parsed")
	}

	if len(projectionMethods2) != 0 {
		t.Errorf("projection methods without projected typs should be none")
	}

	typ.Tags = typewriter.Tags{
		{
			Name:  "methods",
			Items: []string{"Count", "Unknown"},
		},
	}

	standardMethods3, projectionMethods3, err3 := evaluateTags(typ)

	if err3 == nil {
		t.Errorf("unknown method should be error")
	}

	if len(standardMethods3) != 1 {
		t.Errorf("standard methods (except unknown) should be 1, got %v", len(standardMethods3))
	}

	if len(projectionMethods3) != 0 {
		t.Errorf("projection methods without projected types should be none")
	}

	typ.Tags = typewriter.Tags{
		{
			Name:  "projections",
			Items: []string{"SomeType"},
		},
	}

	standardMethods4, projectionMethods4, err4 := evaluateTags(typ)

	if err4 != nil {
		t.Errorf("projected types without subsetted methods should be ok, instead got: '%v'", err4)
	}

	if len(standardMethods4) != len(standardTemplates.GetAllKeys()) {
		t.Errorf("standard methods should default to all")
	}

	if len(projectionMethods4) != len(projectionTemplates.GetAllKeys()) {
		t.Errorf("projection methods should default to all in presence of projected types")
	}

	typ.Tags = typewriter.Tags{
		{
			Name:  "methods",
			Items: []string{"GroupBy"},
		},
		{
			Name:  "projections",
			Items: []string{"SomeType"},
		},
	}

	standardMethods5, projectionMethods5, err5 := evaluateTags(typ)

	if err5 != nil {
		t.Errorf("projected types with subsetted methods should be ok, instead got: '%v'", err5)
	}

	if len(standardMethods5) != 0 {
		t.Errorf("standard methods should be none")
	}

	if len(projectionMethods5) != 1 {
		t.Errorf("projection methods should be subsetted")
	}

	typ.Tags = typewriter.Tags{
		{
			Name: "methods",
		},
	}

	standardMethods6, projectionMethods6, err6 := evaluateTags(typ)

	if err6 != nil {
		t.Errorf("empty subsetted methods should be ok, instead got: '%v'", err6)
	}

	if len(standardMethods6) != 0 {
		t.Errorf("standard methods should be empty when the tag is empty")
	}

	if len(projectionMethods6) != 0 {
		t.Errorf("projection methods should be none")
	}

	typ.Tags = typewriter.Tags{
		{
			Name:    "methods",
			Items:   []string{"Sort", "Any"},
			Negated: true,
		},
	}

	standardMethods7, projectionMethods7, err7 := evaluateTags(typ)

	if err7 != nil {
		t.Errorf("subsetted methods should be ok, instead got: '%v'", err7)
	}

	expected7 := []string{"All", "Count", "Distinct", "DistinctBy", "Each", "First", "IsSorted", "IsSortedBy", "IsSortedByDesc", "IsSortedDesc", "Max", "MaxBy", "Min", "MinBy", "Single", "SortBy", "SortByDesc", "SortDesc", "Where"}
	if !sliceEqual(standardMethods7, expected7) {
		t.Errorf("standard methods should be negatively subsetted, expected %v, got %v", expected7, standardMethods7)
	}

	if len(projectionMethods7) != 0 {
		t.Errorf("projection methods should be none")
	}

	typ.Tags = typewriter.Tags{
		{
			Name:    "methods",
			Items:   []string{"Sort", "Where", "GroupBy"},
			Negated: true,
		},
		{
			Name:  "projections",
			Items: []string{"int"},
		},
	}

	standardMethods8, projectionMethods8, err8 := evaluateTags(typ)

	if err8 != nil {
		t.Errorf("subsetted methods should be ok, instead got: '%v'", err8)
	}

	expectedStd8 := []string{"All", "Any", "Count", "Distinct", "DistinctBy", "Each", "First", "IsSorted", "IsSortedBy", "IsSortedByDesc", "IsSortedDesc", "Max", "MaxBy", "Min", "MinBy", "Single", "SortBy", "SortByDesc", "SortDesc"}
	if !sliceEqual(standardMethods8, expectedStd8) {
		t.Errorf("standard methods should be negatively subsetted, expected %v, got %v", expectedStd8, standardMethods8)
	}

	expectedPrj8 := []string{"Aggregate", "Average", "Max", "Min", "Select", "Sum"}
	if !sliceEqual(projectionMethods8, expectedPrj8) {
		t.Errorf("projection methods should be negatively subsetted, expected %v, got %v", expectedPrj8, projectionMethods8)
	}
}