rusqlite_snapshot_testing/
lib.rs

1// SPDX-License-Identifier: MPL-2.0
2// Copyright Clément Joly and contributors.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
8#![cfg_attr(docsrs, feature(doc_auto_cfg))]
9// The doc is extracted from the README.md file at build time
10#![doc = include_str!(concat!(env!("OUT_DIR"), "/readme_for_rustdoc.md"))]
11
12use rusqlite::{params, Connection};
13
14// Serialize for snapshotting
15pub fn read_all_rows(conn: &Connection, table: &str) -> tabled::Table {
16    use rusqlite::types::Value;
17    use tabled::builder::Builder;
18    use tabled::settings::{Panel, Style};
19
20    let query = format!("SELECT * FROM {table}");
21    let mut stmt = conn.prepare(&query).unwrap();
22    let count = stmt.column_count();
23
24    let mut table = Builder::default();
25    table.push_record(
26        stmt.column_names()
27            .into_iter()
28            .map(|s| s.to_string())
29            .collect::<Vec<_>>(),
30    );
31    stmt.query(params![])
32        .unwrap()
33        .mapped(|row| {
34            Ok((0..count)
35                .into_iter()
36                .map(|i| format!("{:?}", row.get_unwrap::<_, Value>(i)))
37                .collect::<Vec<_>>())
38        })
39        .for_each(|s| table.push_record(s.unwrap()));
40
41    let mut table = table.build();
42    table.with(Style::psql()).with(Panel::header(query));
43    table
44}
45
46// TODO Whole database, only schema, data truncation, transform some of the data like insta
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    use rusqlite::Connection;
53
54    #[test]
55    fn basic_feature() {
56        let conn = Connection::open_in_memory().unwrap();
57        conn.execute("CREATE TABLE friend (name, year_of_birth INTEGER);", ())
58            .unwrap();
59
60        insta::assert_snapshot!("empty_table", read_all_rows(&conn, "friend"));
61
62        let mut stmt = conn
63            .prepare("INSERT INTO friend (name, year_of_birth) VALUES (?1, ?2)")
64            .unwrap();
65        for (year, name) in &[
66            ("alice", 1977),
67            ("bob", 1987),
68            ("charlie", 2000),
69            ("daphne", 1950),
70            ("eve", 1984),
71        ] {
72            stmt.execute((name, year)).unwrap();
73        }
74        insta::assert_snapshot!("with_data", read_all_rows(&conn, "friend"));
75        // Insert a record of a different type, it’ll be captured in the snapshot
76        stmt.execute((1337, 2013)).unwrap();
77        insta::assert_snapshot!(
78            "with_data_of_inconsistent_types",
79            read_all_rows(&conn, "friend")
80        );
81    }
82}