github.com/NeowayLabs/nash@v0.2.2-0.20200127205349-a227041ffd50/internal/sh/functions_test.go (about)

     1  package sh_test
     2  
     3  import "testing"
     4  
     5  func TestFunctionsClosures(t *testing.T) {
     6  	for _, test := range []execTestCase{
     7  		{
     8  			desc: "simpleClosure",
     9  			code: `
    10  				fn func(a) {
    11  					fn closure() {
    12  						print($a)
    13  					}
    14  					return $closure
    15  				}
    16  
    17  				var x <= func("1")
    18  				var y <= func("2")
    19  				$x()
    20  				$y()
    21  			`,
    22  			expectedStdout: "12",
    23  		},
    24  		{
    25  			desc: "eachCallCreatesNewVar",
    26  			code: `
    27  				fn func() {
    28  					var a = ()
    29  					fn add(elem) {
    30  						a <= append($a, $elem)
    31  						print("a:%s,",$a)
    32  					}
    33  					return $add
    34  				}
    35  
    36  				var add <= func()
    37  				$add("1")
    38  				$add("3")
    39  				$add("5")
    40  			`,
    41  			expectedStdout: "a:1,a:1 3,a:1 3 5,",
    42  		},
    43  		{
    44  			desc: "adder example",
    45  			code: `
    46  fn makeAdder(x) {
    47      fn add(y) {
    48          var ret <= expr $x "+" $y
    49          return $ret
    50      }
    51      return $add
    52  }
    53  
    54  var add1 <= makeAdder("1")
    55  var add5 <= makeAdder("5")
    56  var add1000 <= makeAdder("1000")
    57  
    58  print("%s\n", add5("5"))
    59  print("%s\n", add5("10"))
    60  print("%s\n", add1("10"))
    61  print("%s\n", add1("2"))
    62  print("%s\n", add1000("50"))
    63  print("%s\n", add1000("100"))
    64  print("%s\n", add1("10"))
    65  `,
    66  			expectedStdout: `10
    67  15
    68  11
    69  3
    70  1050
    71  1100
    72  11
    73  `,
    74  		},
    75  		{
    76  			desc: "logger",
    77  			code: `fn getlogger(prefix) {
    78      fn log(fmt, args...) {
    79          print($prefix+$fmt+"\n", $args...)
    80      }
    81  
    82      return $log
    83  }
    84  
    85  var info <= getlogger("[info] ")
    86  var error <= getlogger("[error] ")
    87  var warn <= getlogger("[warn] ")
    88  
    89  $info("nuke initialized successfully")
    90  $warn("temperature above anormal circunstances: %s°", "870")
    91  $error("about to explode...")
    92  `,
    93  			expectedStdout: `[info] nuke initialized successfully
    94  [warn] temperature above anormal circunstances: 870°
    95  [error] about to explode...
    96  `,
    97  		},
    98  	} {
    99  		t.Run(test.desc, func(t *testing.T) {
   100  			testExec(t, test)
   101  		})
   102  	}
   103  }
   104  
   105  func TestFunctionsVariables(t *testing.T) {
   106  	for _, test := range []execTestCase{
   107  		{
   108  			desc: "fn stored only as vars",
   109  			code: `
   110  				fn func(a) {
   111  					echo -n "hello"
   112  				}
   113  
   114  				func = "teste"
   115  				echo -n $func
   116  				func()
   117  			`,
   118  			expectedStdout: "teste",
   119  			expectedErr:    "<interactive>:8:4: Identifier 'func' is not a function",
   120  		},
   121  	} {
   122  		t.Run(test.desc, func(t *testing.T) {
   123  			testExec(t, test)
   124  		})
   125  	}
   126  }
   127  
   128  func TestFunctionsStateless(t *testing.T) {
   129  	for _, test := range []execTestCase{
   130  		{
   131  			desc: "functions have no shared state",
   132  			code: `fn iter(first, last, func) {
   133     var sequence <= seq $first $last
   134     var range <= split($sequence, "\n")
   135     for i in $range {
   136         $func($i)
   137     }
   138  }
   139  
   140  fn create_vm(index) {
   141  	echo "create_vm: "+$index
   142  	iter("1", "3", $create_disk)
   143  }
   144  
   145  fn create_disk(index) {
   146  	echo "create_disk: " + $index
   147  }
   148  
   149  iter("1", "2", $create_vm)
   150  `,
   151  			expectedStdout: `create_vm: 1
   152  create_disk: 1
   153  create_disk: 2
   154  create_disk: 3
   155  create_vm: 2
   156  create_disk: 1
   157  create_disk: 2
   158  create_disk: 3
   159  `,
   160  		},
   161  	} {
   162  		t.Run(test.desc, func(t *testing.T) {
   163  			testExec(t, test)
   164  		})
   165  	}
   166  }