-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlambda_paren_block_test.go
More file actions
108 lines (101 loc) · 2.98 KB
/
Copy pathlambda_paren_block_test.go
File metadata and controls
108 lines (101 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package parser
import (
"testing"
"github.com/go-ruby-parser/parser/ast"
)
// A stabby lambda accepts unparenthesized parameters: `->x { }`, `-> ctx { }`,
// `->a, b { }`, `-> message do … end`, `->x, y=1 { }`.
func TestStabbyLambdaUnparenthesizedParams(t *testing.T) {
cases := []struct {
src string
params []string
}{
{`->x { x }`, []string{"x"}},
{`-> ctx { ctx }`, []string{"ctx"}},
{`->a, b { a + b }`, []string{"a", "b"}},
{`-> message do message end`, []string{"message"}},
{`->x, y=1 { x }`, []string{"x", "y"}},
{`-> data { queue << data }`, []string{"data"}},
}
for _, c := range cases {
prog, err := Parse(c.src)
if err != nil {
t.Fatalf("Parse(%q) error: %v", c.src, err)
}
call := prog.Body[0].(*ast.Call)
if call.Name != "lambda" || call.Block == nil {
t.Fatalf("%q: expected lambda call with block, got %#v", c.src, call)
}
if len(call.Block.Params) != len(c.params) {
t.Fatalf("%q: params=%v, want %v", c.src, call.Block.Params, c.params)
}
for i, p := range c.params {
if call.Block.Params[i] != p {
t.Fatalf("%q: param %d=%q, want %q", c.src, i, call.Block.Params[i], p)
}
}
}
}
// Keyword parameters are accepted in block/lambda parameter lists.
func TestBlockKeywordParams(t *testing.T) {
for _, src := range []string{
`[1].each { |a, b:| a }`,
`foo do |channel, count: nil, timeout: 5| 1 end`,
`m { |k:| k }`,
`->a, k: 1 { a }`,
} {
if _, err := Parse(src); err != nil {
t.Fatalf("Parse(%q) error: %v", src, err)
}
}
}
// A keyword block param is recorded with a trailing-colon sentinel name.
func TestBlockKeywordParamShape(t *testing.T) {
prog, err := Parse(`[1].each { |a, b:, c: 5| a }`)
if err != nil {
t.Fatalf("Parse error: %v", err)
}
call := prog.Body[0].(*ast.Call)
want := []string{"a", "b:", "c:"}
if len(call.Block.Params) != len(want) {
t.Fatalf("params=%v, want %v", call.Block.Params, want)
}
for i, w := range want {
if call.Block.Params[i] != w {
t.Fatalf("param %d=%q, want %q", i, call.Block.Params[i], w)
}
}
}
// A parenthesised group accepts trailing modifiers and statement sequences,
// evaluating to its last expression.
func TestModifierAndSequenceInParens(t *testing.T) {
for _, src := range []string{
`(expr if cond)`,
`(x if y) || z`,
`(a; b)`,
`x = (a = 1; a + 1)`,
`(do_it unless skip)`,
} {
if _, err := Parse(src); err != nil {
t.Fatalf("Parse(%q) error: %v", src, err)
}
}
}
// A multi-statement parenthesised group becomes a Begin whose value is its last
// statement; a single-statement group returns that statement directly.
func TestParenGroupShape(t *testing.T) {
prog, err := Parse(`(a; b)`)
if err != nil {
t.Fatalf("Parse error: %v", err)
}
if _, ok := prog.Body[0].(*ast.Begin); !ok {
t.Fatalf("expected *ast.Begin for (a; b), got %T", prog.Body[0])
}
prog, err = Parse(`(1)`)
if err != nil {
t.Fatalf("Parse error: %v", err)
}
if _, ok := prog.Body[0].(*ast.IntLit); !ok {
t.Fatalf("expected *ast.IntLit for (1), got %T", prog.Body[0])
}
}