Skip to content
Browse files

Improved testing

  • Loading branch information...
1 parent 2a7e77b commit 5f8324e06d13a1c9ef4ad2340413052d57fe96ee @robfig committed Jun 9, 2013
Showing with 39 additions and 88 deletions.
  1. +5 −12 controller.go
  2. +34 −76 invoker_test.go
View
17 controller.go
@@ -232,9 +232,7 @@ func (c *Controller) SetAction(controllerName, methodName string) error {
}
// This is a helper that initializes (zeros) a new app controller value.
-// Generally, everything is set to its zero value, except:
-// 1. Embedded controller pointers are newed up.
-// 2. The revel.Controller embedded type is set to the value provided.
+// Specifically, it sets all *revel.Controller embedded types to the provided controller.
// Returns a value representing a pointer to the new app controller.
func initNewAppController(appControllerType *ControllerType, c *Controller) reflect.Value {
var (
@@ -249,9 +247,8 @@ func initNewAppController(appControllerType *ControllerType, c *Controller) refl
}
func findControllers(appControllerType reflect.Type) (indexes [][]int) {
- // It might be a multi-level embedding, so we have to create new controllers
- // at every level of the hierarchy. To find the controllers, we follow every
- // anonymous field, using depth-first search.
+ // It might be a multi-level embedding. To find the controllers, we follow
+ // every anonymous field, using breadth-first search.
type nodeType struct {
val reflect.Value
index []int
@@ -288,12 +285,8 @@ func findControllers(appControllerType reflect.Type) (indexes [][]int) {
continue
}
- // Else, add it to the queue, after instantiating (if necessary).
- if fieldValue.Kind() == reflect.Ptr {
- INFO.Println("WARNING: Pointer detected")
- fieldValue.Set(reflect.New(fieldType.Elem()))
- }
- queue = append(queue, nodeType{fieldValue, append(append([]int{}, node.index...), i)})
+ queue = append(queue,
+ nodeType{fieldValue, append(append([]int{}, node.index...), i)})
}
}
return
View
110 invoker_test.go
@@ -12,40 +12,32 @@ import (
type P struct{ *Controller }
type PN struct{ P }
-type PP struct{ *P }
type PNN struct{ PN }
-type PPN struct{ PP }
-type PNP struct{ *PN }
-type PPP struct{ *PP }
// Embedded via two paths
type P2 struct{ *Controller }
type PP2 struct {
*Controller // Need to embed this explicitly to avoid duplicate selector.
P
P2
+ PNN
}
-var GENERATIONS = [][]interface{}{
- {P{}},
- {PN{}, PP{}},
- {PNN{}, PPN{}, PNP{}, PPP{}},
-}
+var GENERATIONS = []interface{}{P{}, PN{}, PNN{}}
func TestFindControllers(t *testing.T) {
controllers = make(map[string]*ControllerType)
RegisterController((*P)(nil), nil)
RegisterController((*PN)(nil), nil)
- RegisterController((*PP)(nil), nil)
RegisterController((*PNN)(nil), nil)
RegisterController((*PP2)(nil), nil)
+ // Test construction of indexes to each *Controller
checkSearchResults(t, P{}, [][]int{{0}})
checkSearchResults(t, PN{}, [][]int{{0, 0}})
- // checkSearchResults(t, PP{}, [][]int{{0, 0}}) // maybe not
checkSearchResults(t, PNN{}, [][]int{{0, 0, 0}})
- checkSearchResults(t, PP2{}, [][]int{{0}, {1, 0}, {2, 0}})
+ checkSearchResults(t, PP2{}, [][]int{{0}, {1, 0}, {2, 0}, {3, 0, 0, 0}})
}
func checkSearchResults(t *testing.T, obj interface{}, expected [][]int) {
@@ -55,70 +47,36 @@ func checkSearchResults(t *testing.T, obj interface{}, expected [][]int) {
}
}
-// // This test constructs a bunch of hypothetical app controllers, and verifies
-// // that the embedded Controller field was set correctly.
-// func TestNewAppController(t *testing.T) {
-// controller := &Controller{Name: "Test"}
-// for gen, structs := range GENERATIONS {
-// for _, st := range structs {
-// typ := reflect.TypeOf(st)
-// val := initNewAppController(typ, controller)
-
-// // Drill into the embedded fields to get to the Controller.
-// for i := 0; i < gen+1; i++ {
-// if val.Kind() == reflect.Ptr {
-// val = val.Elem()
-// }
-// val = val.Field(0)
-// }
-
-// var name string
-// if val.Type().Kind() == reflect.Ptr {
-// name = val.Interface().(*Controller).Name
-// } else {
-// name = val.Interface().(Controller).Name
-// }
-
-// if name != "Test" {
-// t.Error("Fail: " + typ.String())
-// }
-// }
-// }
-// }
-
-// // // Since the test machinery that goes through all the structs is non-trivial,
-// // have one redundant test that covers just one complicated case but is dead
-// // simple.
-// func TestNewAppController2(t *testing.T) {
-// val := initNewAppController(reflect.TypeOf(PNP{}), &Controller{Name: "Test"})
-// pnp := val.Interface().(*PNP)
-// if pnp.PN.P.Controller.Name != "Test" {
-// t.Error("PNP not initialized.")
-// }
-// if pnp.Controller.Name != "Test" {
-// t.Error("PNP promotion not working.")
-// }
-// }
-
-// func TestMultiEmbedding(t *testing.T) {
-// val := initNewAppController(reflect.TypeOf(PP2{}), &Controller{Name: "Test"})
-// pp2 := val.Interface().(*PP2)
-// if pp2.P.Controller.Name != "Test" {
-// t.Error("P not initialized.")
-// }
-
-// if pp2.P2.Controller.Name != "Test" {
-// t.Error("P2 not initialized.")
-// }
-
-// if pp2.Controller.Name != "Test" {
-// t.Error("PP2 promotion not working.")
-// }
-
-// if pp2.P.Controller != pp2.P2.Controller || pp2.Controller != pp2.P.Controller {
-// t.Error("Controllers not pointing to the same thing.")
-// }
-// }
+func TestSetAction(t *testing.T) {
+ controllers = make(map[string]*ControllerType)
+ RegisterController((*P)(nil), []*MethodType{{Name: "Method"}})
+ RegisterController((*PNN)(nil), []*MethodType{{Name: "Method"}})
+ RegisterController((*PP2)(nil), []*MethodType{{Name: "Method"}})
+
+ // Test that all *revel.Controllers are initialized.
+ c := &Controller{Name: "Test"}
+ if err := c.SetAction("P", "Method"); err != nil {
+ t.Error(err)
+ } else if c.AppController.(*P).Controller != c {
+ t.Errorf("P not initialized")
+ }
+
+ if err := c.SetAction("PNN", "Method"); err != nil {
+ t.Error(err)
+ } else if c.AppController.(*PNN).Controller != c {
+ t.Errorf("PNN not initialized")
+ }
+
+ // PP2 has 4 different slots for *Controller.
+ if err := c.SetAction("PP2", "Method"); err != nil {
+ t.Error(err)
+ } else if pp2 := c.AppController.(*PP2); pp2.Controller != c ||
+ pp2.P.Controller != c ||
+ pp2.P2.Controller != c ||
+ pp2.PNN.Controller != c {
+ t.Errorf("PP2 not initialized")
+ }
+}
func BenchmarkSetAction(b *testing.B) {
type Mixin1 struct {

0 comments on commit 5f8324e

Please sign in to comment.
Something went wrong with that request. Please try again.