|
28 | 28 | ">=", |
29 | 29 | "<=", |
30 | 30 | "..", |
| 31 | + "??", |
31 | 32 | "+", |
32 | 33 | "-", |
33 | 34 | "*", |
@@ -218,7 +219,12 @@ func memberNode(depth int) string { |
218 | 219 | } |
219 | 220 |
|
220 | 221 | func unaryNode(depth int) string { |
221 | | - return random([]string{"-", "!", "not"}) |
| 222 | + op := random([]string{"-", "!", "not"}) |
| 223 | + // Use a simple formatting to ensure valid unary expression syntax |
| 224 | + if op == "not" { |
| 225 | + return fmt.Sprintf("not %v", node(depth-1)) |
| 226 | + } |
| 227 | + return fmt.Sprintf("%s%v", op, node(depth-1)) |
222 | 228 | } |
223 | 229 |
|
224 | 230 | func binaryNode(depth int) string { |
@@ -364,9 +370,31 @@ func sequenceNode(depth int) string { |
364 | 370 | } |
365 | 371 |
|
366 | 372 | func variableNode(depth int) string { |
367 | | - e := node(depth - 1) |
368 | | - if !strings.Contains(e, "foobar") { |
369 | | - return "~!@" |
| 373 | + // Generate 1-3 variable declarations with diverse names and then make sure |
| 374 | + // at least one of them is used in the final expression. |
| 375 | + namesPool := []string{"x", "y", "z", "foo", "bar", "foobar", "tmp"} |
| 376 | + nDecls := oneOf(list[int]{ |
| 377 | + {1, 60}, |
| 378 | + {2, 30}, |
| 379 | + {3, 10}, |
| 380 | + }) |
| 381 | + |
| 382 | + var decls []string |
| 383 | + var chosen []string |
| 384 | + for i := 0; i < nDecls; i++ { |
| 385 | + name := random(namesPool) |
| 386 | + chosen = append(chosen, name) |
| 387 | + decls = append(decls, fmt.Sprintf("let %s = %v", name, node(depth-1))) |
370 | 388 | } |
371 | | - return fmt.Sprintf("let foobar = %v; %v", node(depth-1), e) |
| 389 | + |
| 390 | + // Build a usage expression that references declared vars to guarantee coverage. |
| 391 | + use := oneOf(list[string]{ |
| 392 | + {chosen[0], 50}, |
| 393 | + {fmt.Sprintf("%s + %v", chosen[0], node(depth-1)), 30}, |
| 394 | + {fmt.Sprintf("%v + %s", node(depth-1), chosen[0]), 30}, |
| 395 | + {fmt.Sprintf("if %v { %s } else { %v }", node(depth-1), chosen[0], node(depth-1)), 20}, |
| 396 | + {fmt.Sprintf("%s ? %v : %v", chosen[0], node(depth-1), node(depth-1)), 10}, |
| 397 | + }) |
| 398 | + |
| 399 | + return fmt.Sprintf("%s; %s", strings.Join(decls, "; "), use) |
372 | 400 | } |
0 commit comments