add node_tests
This commit is contained in:
parent
621c18ba27
commit
6d90e1258f
204
node/node_test.go
Normal file
204
node/node_test.go
Normal file
@ -0,0 +1,204 @@
|
||||
package node_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/z7zmey/php-parser/node/name"
|
||||
|
||||
"github.com/z7zmey/php-parser/node/expr"
|
||||
|
||||
"github.com/kylelemons/godebug/pretty"
|
||||
"github.com/z7zmey/php-parser/node"
|
||||
"github.com/z7zmey/php-parser/node/stmt"
|
||||
"github.com/z7zmey/php-parser/parser"
|
||||
)
|
||||
|
||||
func assertEqual(t *testing.T, expected interface{}, actual interface{}) {
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
diff := pretty.Compare(expected, actual)
|
||||
|
||||
if diff != "" {
|
||||
t.Errorf("diff: (-expected +actual)\n%s", diff)
|
||||
} else {
|
||||
t.Errorf("expected and actual are not equal\n")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestIdentifier(t *testing.T) {
|
||||
src := `<? $foo;`
|
||||
|
||||
expected := &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{
|
||||
Expr: &expr.Variable{
|
||||
VarName: &node.Identifier{Value: "$foo"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
actual, _, _ := parser.Parse(bytes.NewBufferString(src), "test.php")
|
||||
|
||||
assertEqual(t, expected, actual)
|
||||
}
|
||||
|
||||
func TestArgumentNode(t *testing.T) {
|
||||
src := `<?
|
||||
foo($a, ...$b);
|
||||
$foo($a, ...$b);
|
||||
$foo->bar($a, ...$b);
|
||||
foo::bar($a, ...$b);
|
||||
$foo::bar($a, ...$b);
|
||||
new foo($a, ...$b);
|
||||
/** anonymous class */
|
||||
new class ($a, ...$b) {};
|
||||
`
|
||||
|
||||
expected := &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{
|
||||
Expr: &expr.FunctionCall{
|
||||
Function: &name.Name{Parts: []node.Node{&name.NamePart{Value: "foo"}}},
|
||||
Arguments: []node.Node{
|
||||
&node.Argument{Variadic: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$a"}}},
|
||||
&node.Argument{Variadic: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$b"}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
&stmt.Expression{
|
||||
Expr: &expr.FunctionCall{
|
||||
Function: &expr.Variable{VarName: &node.Identifier{Value: "$foo"}},
|
||||
Arguments: []node.Node{
|
||||
&node.Argument{Variadic: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$a"}}},
|
||||
&node.Argument{Variadic: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$b"}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
&stmt.Expression{
|
||||
Expr: &expr.MethodCall{
|
||||
Variable: &expr.Variable{VarName: &node.Identifier{Value: "$foo"}},
|
||||
Method: &node.Identifier{Value: "bar"},
|
||||
Arguments: []node.Node{
|
||||
&node.Argument{Variadic: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$a"}}},
|
||||
&node.Argument{Variadic: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$b"}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
&stmt.Expression{
|
||||
Expr: &expr.StaticCall{
|
||||
Class: &name.Name{Parts: []node.Node{&name.NamePart{Value: "foo"}}},
|
||||
Call: &node.Identifier{Value: "bar"},
|
||||
Arguments: []node.Node{
|
||||
&node.Argument{Variadic: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$a"}}},
|
||||
&node.Argument{Variadic: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$b"}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
&stmt.Expression{
|
||||
Expr: &expr.StaticCall{
|
||||
Class: &expr.Variable{VarName: &node.Identifier{Value: "$foo"}},
|
||||
Call: &node.Identifier{Value: "bar"},
|
||||
Arguments: []node.Node{
|
||||
&node.Argument{Variadic: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$a"}}},
|
||||
&node.Argument{Variadic: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$b"}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
&stmt.Expression{
|
||||
Expr: &expr.New{
|
||||
Class: &name.Name{Parts: []node.Node{&name.NamePart{Value: "foo"}}},
|
||||
Arguments: []node.Node{
|
||||
&node.Argument{Variadic: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$a"}}},
|
||||
&node.Argument{Variadic: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$b"}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
&stmt.Expression{
|
||||
Expr: &expr.New{
|
||||
Class: &stmt.Class{
|
||||
PhpDocComment: "/** anonymous class */",
|
||||
Args: []node.Node{
|
||||
&node.Argument{Variadic: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$a"}}},
|
||||
&node.Argument{Variadic: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "$b"}}},
|
||||
},
|
||||
Stmts: []node.Node{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
actual, _, _ := parser.Parse(bytes.NewBufferString(src), "test.php")
|
||||
|
||||
assertEqual(t, expected, actual)
|
||||
}
|
||||
func TestParameterNode(t *testing.T) {
|
||||
src := `<?
|
||||
function foo(?bar $bar=null, baz &...$baz) {}
|
||||
class foo {public function foo(?bar $bar=null, baz &...$baz) {}}
|
||||
function(?bar $bar=null, baz &...$baz) {};
|
||||
static function(?bar $bar=null, baz &...$baz) {};
|
||||
`
|
||||
|
||||
expectedParams := []node.Node{
|
||||
&node.Parameter{
|
||||
ByRef: false,
|
||||
Variadic: false,
|
||||
VariableType: &node.Nullable{Expr: &name.Name{Parts: []node.Node{&name.NamePart{Value: "bar"}}}},
|
||||
Variable: &expr.Variable{VarName: &node.Identifier{Value: "$bar"}},
|
||||
DefaultValue: &expr.ConstFetch{Constant: &name.Name{Parts: []node.Node{&name.NamePart{Value: "null"}}}},
|
||||
},
|
||||
&node.Parameter{
|
||||
ByRef: true,
|
||||
Variadic: true,
|
||||
VariableType: &name.Name{Parts: []node.Node{&name.NamePart{Value: "baz"}}},
|
||||
Variable: &expr.Variable{VarName: &node.Identifier{Value: "$baz"}},
|
||||
},
|
||||
}
|
||||
|
||||
expected := &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Function{
|
||||
ReturnsRef: false,
|
||||
PhpDocComment: "",
|
||||
FunctionName: &node.Identifier{Value: "foo"},
|
||||
Params: expectedParams,
|
||||
Stmts: []node.Node{},
|
||||
},
|
||||
&stmt.Class{
|
||||
ClassName: &node.Identifier{Value: "foo"},
|
||||
Stmts: []node.Node{
|
||||
&stmt.ClassMethod{
|
||||
MethodName: &node.Identifier{Value: "foo"},
|
||||
Modifiers: []node.Node{&node.Identifier{Value: "public"}},
|
||||
Params: expectedParams,
|
||||
Stmts: []node.Node{},
|
||||
},
|
||||
},
|
||||
},
|
||||
&stmt.Expression{
|
||||
Expr: &expr.Closure{
|
||||
Params: expectedParams,
|
||||
Uses: []node.Node{},
|
||||
Stmts: []node.Node{},
|
||||
},
|
||||
},
|
||||
&stmt.Expression{
|
||||
Expr: &expr.Closure{
|
||||
Static: true,
|
||||
Params: expectedParams,
|
||||
Uses: []node.Node{},
|
||||
Stmts: []node.Node{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
actual, _, _ := parser.Parse(bytes.NewBufferString(src), "test.php")
|
||||
|
||||
assertEqual(t, expected, actual)
|
||||
}
|
@ -9,19 +9,19 @@ type Class struct {
|
||||
PhpDocComment string
|
||||
ClassName node.Node
|
||||
Modifiers []node.Node
|
||||
args []node.Node
|
||||
Args []node.Node
|
||||
Extends node.Node
|
||||
Implements []node.Node
|
||||
Stmts []node.Node
|
||||
}
|
||||
|
||||
// NewClass node constuctor
|
||||
func NewClass(ClassName node.Node, Modifiers []node.Node, args []node.Node, Extends node.Node, Implements []node.Node, Stmts []node.Node, PhpDocComment string) *Class {
|
||||
func NewClass(ClassName node.Node, Modifiers []node.Node, Args []node.Node, Extends node.Node, Implements []node.Node, Stmts []node.Node, PhpDocComment string) *Class {
|
||||
return &Class{
|
||||
PhpDocComment,
|
||||
ClassName,
|
||||
Modifiers,
|
||||
args,
|
||||
Args,
|
||||
Extends,
|
||||
Implements,
|
||||
Stmts,
|
||||
@ -56,9 +56,9 @@ func (n *Class) Walk(v node.Visitor) {
|
||||
}
|
||||
}
|
||||
|
||||
if n.args != nil {
|
||||
vv := v.GetChildrenVisitor("args")
|
||||
for _, nn := range n.args {
|
||||
if n.Args != nil {
|
||||
vv := v.GetChildrenVisitor("Args")
|
||||
for _, nn := range n.Args {
|
||||
if nn != nil {
|
||||
nn.Walk(vv)
|
||||
}
|
||||
|
102
node/visitor_test.go
Normal file
102
node/visitor_test.go
Normal file
@ -0,0 +1,102 @@
|
||||
package node_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/z7zmey/php-parser/node/scalar"
|
||||
|
||||
"github.com/z7zmey/php-parser/node/expr"
|
||||
|
||||
"github.com/kylelemons/godebug/pretty"
|
||||
"github.com/z7zmey/php-parser/node"
|
||||
)
|
||||
|
||||
var nodesToTest = []struct {
|
||||
node node.Node // node
|
||||
expectedVisitedKeys []string // visited keys
|
||||
expectedAttributes map[string]interface{}
|
||||
}{
|
||||
{
|
||||
&node.Identifier{Value: "foo"},
|
||||
[]string{},
|
||||
map[string]interface{}{"Value": "foo"},
|
||||
},
|
||||
{
|
||||
&node.Nullable{Expr: &expr.Variable{VarName: &node.Identifier{Value: "foo"}}},
|
||||
[]string{"Expr"},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
&node.Argument{Variadic: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "foo"}}},
|
||||
[]string{"Expr"},
|
||||
map[string]interface{}{"Variadic": true},
|
||||
},
|
||||
{
|
||||
&node.Parameter{
|
||||
ByRef: false,
|
||||
Variadic: true,
|
||||
VariableType: &node.Identifier{Value: "foo"},
|
||||
Variable: &expr.Variable{VarName: &node.Identifier{Value: "bar"}},
|
||||
DefaultValue: &scalar.Lnumber{Value: "0"},
|
||||
},
|
||||
[]string{"VariableType", "Variable", "DefaultValue"},
|
||||
map[string]interface{}{"ByRef": false, "Variadic": true},
|
||||
},
|
||||
}
|
||||
|
||||
type visitorMock struct {
|
||||
visitChildren bool
|
||||
visitedKeys []string
|
||||
}
|
||||
|
||||
func (v *visitorMock) EnterNode(n node.Node) bool { return v.visitChildren }
|
||||
func (v *visitorMock) GetChildrenVisitor(key string) node.Visitor {
|
||||
v.visitedKeys = append(v.visitedKeys, key)
|
||||
return &visitorMock{v.visitChildren, nil}
|
||||
}
|
||||
func (v *visitorMock) LeaveNode(n node.Node) {}
|
||||
|
||||
func TestNameVisitorDisableChildren(t *testing.T) {
|
||||
for _, tt := range nodesToTest {
|
||||
v := &visitorMock{false, nil}
|
||||
tt.node.Walk(v)
|
||||
|
||||
expected := []string{}
|
||||
actual := v.visitedKeys
|
||||
|
||||
diff := pretty.Compare(expected, actual)
|
||||
if diff != "" {
|
||||
t.Errorf("%s diff: (-expected +actual)\n%s", reflect.TypeOf(tt.node), diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNameVisitor(t *testing.T) {
|
||||
for _, tt := range nodesToTest {
|
||||
v := &visitorMock{true, nil}
|
||||
tt.node.Walk(v)
|
||||
|
||||
expected := tt.expectedVisitedKeys
|
||||
actual := v.visitedKeys
|
||||
|
||||
diff := pretty.Compare(expected, actual)
|
||||
if diff != "" {
|
||||
t.Errorf("%s diff: (-expected +actual)\n%s", reflect.TypeOf(tt.node), diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test Attributes()
|
||||
|
||||
func TestNameAttributes(t *testing.T) {
|
||||
for _, tt := range nodesToTest {
|
||||
expected := tt.expectedAttributes
|
||||
actual := tt.node.Attributes()
|
||||
|
||||
diff := pretty.Compare(expected, actual)
|
||||
if diff != "" {
|
||||
t.Errorf("%s diff: (-expected +actual)\n%s", reflect.TypeOf(tt.node), diff)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user