github.com/kolbycrouch/elvish@v0.14.1-0.20210614162631-215b9ac1c423/pkg/eval/builtin_fn_flow_test.go (about)

     1  package eval_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	. "src.elv.sh/pkg/eval"
     7  
     8  	. "src.elv.sh/pkg/eval/evaltest"
     9  	"src.elv.sh/pkg/eval/vals"
    10  )
    11  
    12  func TestRunParallel(t *testing.T) {
    13  	Test(t,
    14  		That(`run-parallel { put lorem } { echo ipsum }`).
    15  			Puts("lorem").Prints("ipsum\n"),
    16  	)
    17  }
    18  
    19  func TestEach(t *testing.T) {
    20  	Test(t,
    21  		That(`put 1 233 | each $put~`).Puts("1", "233"),
    22  		That(`echo "1\n233" | each $put~`).Puts("1", "233"),
    23  		That(`echo "1\r\n233" | each $put~`).Puts("1", "233"),
    24  		That(`each $put~ [1 233]`).Puts("1", "233"),
    25  		That(`range 10 | each [x]{ if (== $x 4) { break }; put $x }`).
    26  			Puts(0, 1, 2, 3),
    27  		That(`range 10 | each [x]{ if (== $x 4) { fail haha }; put $x }`).
    28  			Puts(0, 1, 2, 3).Throws(AnyError),
    29  		// TODO(xiaq): Test that "each" does not close the stdin.
    30  	)
    31  }
    32  
    33  func TestPeach(t *testing.T) {
    34  	// Testing the `peach` builtin is a challenge since, by definition, the order of execution is
    35  	// undefined.
    36  	Test(t,
    37  		// Verify the output has the expected values when sorted.
    38  		That(`range 5 | peach [x]{ * 2 $x } | order`).Puts(0, 2, 4, 6, 8),
    39  		// Verify that successive runs produce the output in different order. This test can
    40  		// theoretically suffer false positives but the vast majority of the time this will produce
    41  		// the expected output in the first iteration. The probability it will produce the same
    42  		// order of output in 100 iterations is effectively zero.
    43  		That(`
    44  			fn f { range 100 | peach $put~ | put [(all)] }
    45  			var x = (f)
    46  			for _ [(range 100)] {
    47  				var y = (f)
    48  				if (not-eq $x $y) {
    49  					put $true
    50  					break
    51  				}
    52  			}
    53  		`).Puts(true),
    54  		// Verify that exceptions are propagated.
    55  		That(`peach [x]{ fail $x } [a]`).
    56  			Throws(FailError{"a"}, "fail $x ", "peach [x]{ fail $x } [a]"),
    57  		// Verify that `break` works by terminating the `peach` before the entire sequence is
    58  		// consumed.
    59  		That(`
    60  			var tot = 0
    61  			range 1 101 |
    62  				peach [x]{ if (== 50 $x) { break } else { put $x } } |
    63  				< (+ (all)) (+ (range 1 101))
    64  		`).Puts(true),
    65  	)
    66  }
    67  
    68  func TestFail(t *testing.T) {
    69  	Test(t,
    70  		That("fail haha").Throws(FailError{"haha"}, "fail haha"),
    71  		That("fn f { fail haha }", "fail ?(f)").Throws(
    72  			FailError{"haha"}, "fail haha ", "f"),
    73  		That("fail []").Throws(
    74  			FailError{vals.EmptyList}, "fail []"),
    75  		That("put ?(fail 1)[reason][type]").Puts("fail"),
    76  		That("put ?(fail 1)[reason][content]").Puts("1"),
    77  	)
    78  }
    79  
    80  func TestReturn(t *testing.T) {
    81  	Test(t,
    82  		That("return").Throws(Return),
    83  		// Use of return inside fn is tested in TestFn
    84  	)
    85  }