v / vlib / v2 / ast / flat_prepend_to_for_body_test.v
95 lines · 84 sloc · 3.25 KB · f3c5760b8838272e4789c38a1be9e03f9ceac351
Raw
1// Copyright (c) 2026 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module ast
5
6// Tests for `FlatBuilder.prepend_to_for_body`. The ForStmt analog of s154's
7// `prepend_to_fn_body`. Body-stmt encoding differs: ForStmt encodes body
8// stmts as INLINE edges starting at index 3 (no list child), so this
9// primitive rebuilds the for's edge list directly rather than rebuilding a
10// stmts-list child node.
11
12fn make_for_body_assert_stmt(value string) Stmt {
13 return Stmt(AssertStmt{
14 expr: Expr(BasicLiteral{
15 kind: .number
16 value: value
17 })
18 })
19}
20
21// Build a stmt_for via the legacy add_stmt path so the test exercises the
22// same encoding that real callsites produce.
23fn build_for_stmt(body_stmts []Stmt) (FlatBuilder, FlatNodeId) {
24 mut b := new_flat_builder()
25 for_stmt := Stmt(ForStmt{
26 init: Stmt(EmptyStmt{})
27 cond: Expr(BasicLiteral{
28 kind: .number
29 value: '1'
30 })
31 stmts: body_stmts
32 })
33 for_id := b.emit_stmt(for_stmt)
34 return b, for_id
35}
36
37fn ref_sig_for_body(body_stmts []Stmt) string {
38 mut b, for_id := build_for_stmt(body_stmts)
39 return b.flat.subtree_signature(for_id)
40}
41
42fn sub_sig_for_prepend(initial_body []Stmt, extra_values []string) string {
43 mut b, for_id := build_for_stmt(initial_body)
44 mut extra_ids := []FlatNodeId{}
45 for v in extra_values {
46 extra_ids << b.emit_stmt(make_for_body_assert_stmt(v))
47 }
48 new_for_id := b.prepend_to_for_body(for_id, extra_ids)
49 return b.flat.subtree_signature(new_for_id)
50}
51
52fn test_prepend_to_for_body_signature_matches_reference() {
53 ref_sig := ref_sig_for_body([make_for_body_assert_stmt('99'),
54 make_for_body_assert_stmt('1')])
55 sub_sig := sub_sig_for_prepend([make_for_body_assert_stmt('1')], ['99'])
56 assert ref_sig == sub_sig
57}
58
59fn test_prepend_to_for_body_zero_extras_returns_existing_id() {
60 mut b, for_id := build_for_stmt([make_for_body_assert_stmt('1')])
61 returned_id := b.prepend_to_for_body(for_id, [])
62 assert returned_id == for_id
63}
64
65fn test_prepend_to_for_body_invalid_id_returns_invalid() {
66 mut b := new_flat_builder()
67 extra_id := b.emit_stmt(make_for_body_assert_stmt('99'))
68 returned_id := b.prepend_to_for_body(FlatNodeId(-1), [extra_id])
69 assert returned_id == invalid_flat_node_id
70}
71
72fn test_prepend_to_for_body_non_for_kind_returns_invalid() {
73 mut b := new_flat_builder()
74 // stmt_assert is not stmt_for — kind check must reject it.
75 assert_id := b.emit_stmt(make_for_body_assert_stmt('1'))
76 extra_id := b.emit_stmt(make_for_body_assert_stmt('99'))
77 returned_id := b.prepend_to_for_body(assert_id, [extra_id])
78 assert returned_id == invalid_flat_node_id
79}
80
81fn test_prepend_to_for_body_empty_original_body() {
82 // ForStmt with no body stmts at all — extras become the entire new body.
83 ref_sig := ref_sig_for_body([make_for_body_assert_stmt('99')])
84 sub_sig := sub_sig_for_prepend([]Stmt{}, ['99'])
85 assert ref_sig == sub_sig
86}
87
88fn test_prepend_to_for_body_preserves_existing_body_order() {
89 // Two existing body stmts + one prepended; order must be [extra, b1, b2].
90 ref_sig := ref_sig_for_body([make_for_body_assert_stmt('99'),
91 make_for_body_assert_stmt('1'), make_for_body_assert_stmt('2')])
92 sub_sig := sub_sig_for_prepend([make_for_body_assert_stmt('1'),
93 make_for_body_assert_stmt('2')], ['99'])
94 assert ref_sig == sub_sig
95}
96