github.com/mattn/anko@v0.1.10/ast/astutil/walk_test.go (about)

     1  package astutil
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/mattn/anko/ast"
     9  	"github.com/mattn/anko/parser"
    10  )
    11  
    12  const (
    13  	goodSrc string = `
    14  var fmt = import("fmt")
    15  
    16  a = "1"
    17  b = 2
    18  m = {}
    19  func testA(arg1, arg2, arg3) {
    20  	v, ok = m["foo"]
    21  	return "A" + arg1 + arg2 + arg3
    22  }
    23  
    24  func Main(arg1) {
    25  	fmt.Println("enter Main")
    26  	b = testA(1, 2, 3) + Tester()
    27  
    28  	if b == 0 {
    29  		fmt.Println("b is 0")
    30  	} else if b == 1 {
    31  		fmt.Println("b is 1")
    32  	} else {
    33  		fmt.Println("b is other")
    34  	}
    35  
    36  	switch arg1 {
    37  	case 0:
    38  		fmt.Println("arg0 is 0")
    39  	case 1:
    40  		fmt.Println("arg0 is 1")
    41  	default:
    42  		fmt.Println("arg0 is other")
    43  	}
    44  
    45  	try {
    46  		throw "WTF!"
    47  	} catch e {
    48  		fmt.Println(e)
    49  	}
    50  
    51  	for n = 0; n < 3; n++ {
    52  		if n < 2 {
    53  			continue
    54  		}
    55  		fmt.Println(n)
    56  	}
    57  
    58  	for n in [1, 2, 3, 4, 5] {
    59  		fmt.Println(n)
    60  		if n > 3 {
    61  			break
    62  		}
    63  	}
    64  
    65  	n = 0
    66  	for n < 3 {
    67  		n++
    68  	}
    69  
    70  	a = {"foo": "bar"}
    71  	a.foo = "baz"
    72  	if a["foo"] == "zoo" {
    73  		fmt.Println("foo is zoo")
    74  	}
    75  	fmt.Println(a["foo"] == "zoo" ? "zoo" : "baz")
    76  
    77  	c = make(chan int64)
    78  
    79  	go func() {
    80  	  c <- 1
    81  	  c <- 2
    82  	  c <- 3
    83  	}()
    84  
    85  	println(<-c)
    86  	println(<-c)
    87  	println(<-c)
    88  
    89  	v = make([]int, 3)
    90  	fmt.Println("sizeof v is ", len(v))
    91  
    92  	x = 1
    93  	y = (&x)
    94  	*y = 2
    95  	fmt.Println(x)
    96  
    97  	x, y = !x, 2
    98  	fmt.Println(x, y)
    99  
   100  	x = new(string)
   101  	fmt.Println(x)
   102  
   103  	var f = func() {
   104  		return "foo"
   105  	}
   106  	x = f()[0:1]
   107  	y = f()[0]
   108  	fmt.Println(x == y ? true : false)
   109  }
   110  
   111  func Tester() {
   112  	return "YES"
   113  }
   114  
   115  func testLen() {
   116  	return len("test")
   117  }
   118  
   119  fmt.Println(Main(1))
   120  `
   121  )
   122  
   123  func TestWalk(t *testing.T) {
   124  	stmts, err := parser.ParseSrc(goodSrc)
   125  	if err != nil {
   126  		t.Fatal(err)
   127  	}
   128  	var mainFound bool
   129  	var lenFound bool
   130  	err = Walk(stmts, func(e interface{}) error {
   131  		switch exp := e.(type) {
   132  		case *ast.CallExpr:
   133  			switch exp.Name {
   134  			case `testA`:
   135  				if len(exp.SubExprs) != 3 {
   136  					return errors.New("invalid parameter count")
   137  				}
   138  			case `Main`:
   139  				if len(exp.SubExprs) != 1 {
   140  					return errors.New("invalid parameter count")
   141  				}
   142  			case `Tester`:
   143  				if len(exp.SubExprs) != 0 {
   144  					return errors.New("invalid parameter count")
   145  				}
   146  			}
   147  		case *ast.FuncExpr:
   148  			if !mainFound && exp.Name == `Main` {
   149  				mainFound = true
   150  			} else if mainFound && exp.Name == `Main` {
   151  				return errors.New("Main redefined")
   152  			}
   153  		case *ast.LenExpr:
   154  			lenFound = true
   155  		}
   156  		return nil
   157  	})
   158  	if err != nil {
   159  		t.Fatal(err)
   160  	}
   161  	if !mainFound {
   162  		t.Fatal("Main not found")
   163  	}
   164  	if !lenFound {
   165  		t.Fatal("len not found")
   166  	}
   167  }
   168  
   169  func Example_astWalk() {
   170  	src := `
   171  var fmt = import("fmt")
   172  
   173  func TestFunc(arg1, arg2, arg3) {
   174  	return (arg1 + arg2) * arg3
   175  }
   176  
   177  func Main() {
   178  	return TestFunc(1, 2, 3) + BuiltinFuncX(1, 2, 3)
   179  }
   180  
   181  fmt.Println(Main())
   182  	`
   183  	stmts, err := parser.ParseSrc(src)
   184  	if err != nil {
   185  		fmt.Println("ERROR: ", err)
   186  		return
   187  	}
   188  	var mainFound bool
   189  	err = Walk(stmts, func(e interface{}) error {
   190  		switch e := e.(type) {
   191  		case *ast.CallExpr:
   192  			//check if the BuiltinFuncX is getting the right number of args
   193  			if e.Name == `BuiltinFuncX` && len(e.SubExprs) != 3 {
   194  				return errors.New("invalid number of arguments to BuiltinFuncX")
   195  			}
   196  		case *ast.FuncExpr:
   197  			if !mainFound && e.Name == `Main` {
   198  				if len(e.Params) != 0 {
   199  					return errors.New("Too many args to main")
   200  				}
   201  				mainFound = true
   202  			} else if mainFound && e.Name == `Main` {
   203  				return errors.New("Main redefined")
   204  			}
   205  		}
   206  		return nil
   207  	})
   208  	if err != nil {
   209  		fmt.Println("ERROR: ", err)
   210  		return
   211  	}
   212  	if !mainFound {
   213  		fmt.Println("ERROR: Main not found")
   214  	}
   215  }
   216  
   217  func TestBadCode(t *testing.T) {
   218  	var codes = []string{
   219  		`const 1 = 2`,
   220  		`a["foo"] = 2, 3`,
   221  		`if a, 2 {}`,
   222  		`if break {}`,
   223  		`if a { else }`,
   224  		`if a { } else foo { }`,
   225  		`try a { } else { }`,
   226  		`try { } catch 1, 2 { }`,
   227  		`throw 1, 2`,
   228  		`for.true`,
   229  		`switch { var }`,
   230  		`case { var }`,
   231  		`v, ok = { "foo": "bar" }[const 1]`,
   232  	}
   233  	for _, code := range codes {
   234  		_, err := parser.ParseSrc(code)
   235  		if err == nil {
   236  			t.Fatalf("code %q should fail", code)
   237  		}
   238  	}
   239  }