194 lines
5.0 KiB
Go
194 lines
5.0 KiB
Go
![]() |
// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved.
|
||
|
// Revel Framework source code and usage is governed by a MIT style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package harness
|
||
|
|
||
|
import (
|
||
|
"go/ast"
|
||
|
"go/parser"
|
||
|
"go/token"
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/revel/revel"
|
||
|
)
|
||
|
|
||
|
const validationKeysSource = `
|
||
|
package test
|
||
|
|
||
|
func (c *Application) testFunc(a, b int, user models.User) revel.Result {
|
||
|
// Line 5
|
||
|
c.Validation.Required(a)
|
||
|
c.Validation.Required(a).Message("Error message")
|
||
|
c.Validation.Required(a).
|
||
|
Message("Error message")
|
||
|
|
||
|
// Line 11
|
||
|
c.Validation.Required(user.Name)
|
||
|
c.Validation.Required(user.Name).Message("Error message")
|
||
|
|
||
|
// Line 15
|
||
|
c.Validation.MinSize(b, 12)
|
||
|
c.Validation.MinSize(b, 12).Message("Error message")
|
||
|
c.Validation.MinSize(b,
|
||
|
12)
|
||
|
|
||
|
// Line 21
|
||
|
c.Validation.Required(b == 5)
|
||
|
}
|
||
|
|
||
|
func (m Model) Validate(v *revel.Validation) {
|
||
|
// Line 26
|
||
|
v.Required(m.name)
|
||
|
v.Required(m.name == "something").
|
||
|
Message("Error Message")
|
||
|
v.Required(!m.bool)
|
||
|
}
|
||
|
`
|
||
|
|
||
|
var expectedValidationKeys = []map[int]string{
|
||
|
{
|
||
|
6: "a",
|
||
|
7: "a",
|
||
|
8: "a",
|
||
|
12: "user.Name",
|
||
|
13: "user.Name",
|
||
|
16: "b",
|
||
|
17: "b",
|
||
|
19: "b",
|
||
|
22: "b",
|
||
|
}, {
|
||
|
27: "m.name",
|
||
|
28: "m.name",
|
||
|
30: "m.bool",
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// This tests the recording of line number to validation key of the preceeding
|
||
|
// example source.
|
||
|
func TestGetValidationKeys(t *testing.T) {
|
||
|
fset := token.NewFileSet()
|
||
|
|
||
|
file, err := parser.ParseFile(fset, "validationKeysSource", validationKeysSource, 0)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if len(file.Decls) != 2 {
|
||
|
t.Fatal("Expected 2 decl in the source, found", len(file.Decls))
|
||
|
}
|
||
|
|
||
|
for i, decl := range file.Decls {
|
||
|
lineKeys := getValidationKeys(fset, decl.(*ast.FuncDecl), map[string]string{"revel": revel.RevelImportPath})
|
||
|
for k, v := range expectedValidationKeys[i] {
|
||
|
if lineKeys[k] != v {
|
||
|
t.Errorf("Not found - %d: %v - Actual Map: %v", k, v, lineKeys)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if len(lineKeys) != len(expectedValidationKeys[i]) {
|
||
|
t.Error("Validation key map not the same size as expected:", lineKeys)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var TypeExprs = map[string]TypeExpr{
|
||
|
"int": {"int", "", 0, true},
|
||
|
"*int": {"*int", "", 1, true},
|
||
|
"[]int": {"[]int", "", 2, true},
|
||
|
"...int": {"[]int", "", 2, true},
|
||
|
"[]*int": {"[]*int", "", 3, true},
|
||
|
"...*int": {"[]*int", "", 3, true},
|
||
|
"MyType": {"MyType", "pkg", 0, true},
|
||
|
"*MyType": {"*MyType", "pkg", 1, true},
|
||
|
"[]MyType": {"[]MyType", "pkg", 2, true},
|
||
|
"...MyType": {"[]MyType", "pkg", 2, true},
|
||
|
"[]*MyType": {"[]*MyType", "pkg", 3, true},
|
||
|
"...*MyType": {"[]*MyType", "pkg", 3, true},
|
||
|
}
|
||
|
|
||
|
func TestTypeExpr(t *testing.T) {
|
||
|
for typeStr, expected := range TypeExprs {
|
||
|
// Handle arrays and ... myself, since ParseExpr() does not.
|
||
|
array := strings.HasPrefix(typeStr, "[]")
|
||
|
if array {
|
||
|
typeStr = typeStr[2:]
|
||
|
}
|
||
|
|
||
|
ellipsis := strings.HasPrefix(typeStr, "...")
|
||
|
if ellipsis {
|
||
|
typeStr = typeStr[3:]
|
||
|
}
|
||
|
|
||
|
expr, err := parser.ParseExpr(typeStr)
|
||
|
if err != nil {
|
||
|
t.Error("Failed to parse test expr:", typeStr)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if array {
|
||
|
expr = &ast.ArrayType{Lbrack: expr.Pos(), Len: nil, Elt: expr}
|
||
|
}
|
||
|
if ellipsis {
|
||
|
expr = &ast.Ellipsis{Ellipsis: expr.Pos(), Elt: expr}
|
||
|
}
|
||
|
|
||
|
actual := NewTypeExpr("pkg", expr)
|
||
|
if !reflect.DeepEqual(expected, actual) {
|
||
|
t.Error("Fail, expected", expected, ", was", actual)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestProcessBookingSource(t *testing.T) {
|
||
|
revel.Init("prod", "github.com/revel/examples/booking", "")
|
||
|
sourceInfo, err := ProcessSource([]string{revel.AppPath})
|
||
|
if err != nil {
|
||
|
t.Fatal("Failed to process booking source with error:", err)
|
||
|
}
|
||
|
|
||
|
controllerPackage := "github.com/revel/examples/booking/app/controllers"
|
||
|
expectedControllerSpecs := []*TypeInfo{
|
||
|
{"GorpController", controllerPackage, "controllers", nil, nil},
|
||
|
{"Application", controllerPackage, "controllers", nil, nil},
|
||
|
{"Hotels", controllerPackage, "controllers", nil, nil},
|
||
|
}
|
||
|
if len(sourceInfo.ControllerSpecs()) != len(expectedControllerSpecs) {
|
||
|
t.Errorf("Unexpected number of controllers found. Expected %d, Found %d",
|
||
|
len(expectedControllerSpecs), len(sourceInfo.ControllerSpecs()))
|
||
|
}
|
||
|
|
||
|
NEXT_TEST:
|
||
|
for _, expected := range expectedControllerSpecs {
|
||
|
for _, actual := range sourceInfo.ControllerSpecs() {
|
||
|
if actual.StructName == expected.StructName {
|
||
|
if actual.ImportPath != expected.ImportPath {
|
||
|
t.Errorf("%s expected to have import path %s, actual %s",
|
||
|
actual.StructName, expected.ImportPath, actual.ImportPath)
|
||
|
}
|
||
|
if actual.PackageName != expected.PackageName {
|
||
|
t.Errorf("%s expected to have package name %s, actual %s",
|
||
|
actual.StructName, expected.PackageName, actual.PackageName)
|
||
|
}
|
||
|
continue NEXT_TEST
|
||
|
}
|
||
|
}
|
||
|
t.Errorf("Expected to find controller %s, but did not. Actuals: %s",
|
||
|
expected.StructName, sourceInfo.ControllerSpecs())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func BenchmarkProcessBookingSource(b *testing.B) {
|
||
|
revel.Init("", "github.com/revel/examples/booking", "")
|
||
|
revel.GetRootLogHandler().Disable()
|
||
|
b.ResetTimer()
|
||
|
|
||
|
for i := 0; i < b.N; i++ {
|
||
|
_, err := ProcessSource(revel.CodePaths)
|
||
|
if err != nil {
|
||
|
b.Error("Unexpected error:", err)
|
||
|
}
|
||
|
}
|
||
|
}
|