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/php5" "github.com/z7zmey/php-parser/php7" ) 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 := `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"}}}, ArgumentList: &node.ArgumentList{ 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"}}, ArgumentList: &node.ArgumentList{ 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"}, ArgumentList: &node.ArgumentList{ 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"}, ArgumentList: &node.ArgumentList{ 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"}, ArgumentList: &node.ArgumentList{ 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"}}}, ArgumentList: &node.ArgumentList{ 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 */", ArgumentList: &node.ArgumentList{ 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"}}}, }, }, Stmts: []node.Node{}, }, }, }, }, } php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php") php7parser.Parse() actual := php7parser.GetRootNode() assertEqual(t, expected, actual) } func TestPhp5ArgumentNode(t *testing.T) { src := `bar($a, ...$b); foo::bar($a, ...$b); $foo::bar($a, ...$b); new foo($a, ...$b); ` expected := &stmt.StmtList{ Stmts: []node.Node{ &stmt.Expression{ Expr: &expr.FunctionCall{ Function: &name.Name{Parts: []node.Node{&name.NamePart{Value: "foo"}}}, ArgumentList: &node.ArgumentList{ 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"}}, ArgumentList: &node.ArgumentList{ 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"}, ArgumentList: &node.ArgumentList{ 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"}, ArgumentList: &node.ArgumentList{ 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"}, ArgumentList: &node.ArgumentList{ 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"}}}, ArgumentList: &node.ArgumentList{ 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"}}}, }, }, }, }, }, } php5parser := php5.NewParser(bytes.NewBufferString(src), "test.php") php5parser.Parse() actual := php5parser.GetRootNode() assertEqual(t, expected, actual) } func TestPhp7ParameterNode(t *testing.T) { src := `