Skip to main content

mz_deploy/project/ir/
unit_test.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10//! IR representation of a parsed `EXECUTE UNIT TEST` statement.
11//!
12//! The compiler stores the parsed test definition on the project graph;
13//! validation and SQL lowering happen later in the test runner (see
14//! `cli::commands::test::lower`).
15
16/// Represents a parsed unit test definition.
17#[derive(Debug, Clone)]
18pub struct UnitTest {
19    /// Name of the test (e.g., "test_flippers")
20    pub name: String,
21    /// Fully qualified name of the target view being tested
22    pub target_view: String,
23    /// Optional timestamp for mz_now() during test execution
24    pub at_time: Option<String>,
25    /// Mock views to create for dependencies
26    pub mocks: Vec<MockView>,
27    /// Expected results definition
28    pub expected: ExpectedResult,
29}
30
31impl UnitTest {
32    /// Convert an ExecuteUnitTestStatement from the AST into a UnitTest.
33    pub fn from_execute_statement(
34        stmt: &mz_sql_parser::ast::ExecuteUnitTestStatement<mz_sql_parser::ast::Raw>,
35    ) -> Self {
36        use mz_sql_parser::ast::display::{AstDisplay, FormatMode};
37
38        let name = stmt.name.to_string();
39        let target_view = stmt.target.to_ast_string(FormatMode::Simple);
40
41        let at_time = stmt
42            .at_time
43            .as_ref()
44            .map(|expr| expr.to_ast_string(FormatMode::Simple));
45
46        let mocks = stmt
47            .mocks
48            .iter()
49            .map(|mock| {
50                let fqn = mock.name.to_ast_string(FormatMode::Simple);
51                let columns = mock
52                    .columns
53                    .iter()
54                    .map(|col| {
55                        (
56                            col.name.to_string(),
57                            col.data_type.to_ast_string(FormatMode::Simple),
58                        )
59                    })
60                    .collect();
61                let query = mock.query.to_ast_string(FormatMode::Simple);
62                MockView {
63                    fqn,
64                    columns,
65                    query,
66                }
67            })
68            .collect();
69
70        let expected = ExpectedResult {
71            columns: stmt
72                .expected
73                .columns
74                .iter()
75                .map(|col| {
76                    (
77                        col.name.to_string(),
78                        col.data_type.to_ast_string(FormatMode::Simple),
79                    )
80                })
81                .collect(),
82            query: stmt.expected.query.to_ast_string(FormatMode::Simple),
83        };
84
85        UnitTest {
86            name,
87            target_view,
88            at_time,
89            mocks,
90            expected,
91        }
92    }
93}
94
95/// A mock view definition that replaces a real dependency.
96#[derive(Debug, Clone)]
97pub struct MockView {
98    /// Fully qualified name (e.g., "materialize.public.flipper_activity")
99    pub fqn: String,
100    /// Column definitions as (name, type) pairs
101    pub columns: Vec<(String, String)>,
102    /// SQL query body (the part after AS)
103    pub query: String,
104}
105
106/// Expected results for the test.
107#[derive(Debug, Clone)]
108pub struct ExpectedResult {
109    /// Column definitions as (name, type) pairs
110    pub columns: Vec<(String, String)>,
111    /// SQL query body (the part after AS)
112    pub query: String,
113}