Skip to main content

toasty_driver_integration_suite/tests/
index_custom_name.rs

1use crate::prelude::*;
2
3/// `#[index(name = "...", ...)]` overrides the auto-generated index name
4/// in the DB schema, and the index is still usable for queries.
5#[driver_test]
6pub async fn index_custom_name_overrides_default(t: &mut Test) -> Result<()> {
7    #[derive(Debug, toasty::Model)]
8    #[index(name = "tournament_region_idx", tournament_id, region)]
9    struct Match {
10        #[key]
11        id: String,
12        tournament_id: String,
13        region: String,
14    }
15
16    let mut db = t.setup_db(models!(Match)).await;
17
18    // Schema carries the user-provided name (not the auto-generated form).
19    let table = &db.schema().db.tables[0];
20    let custom_idx = table
21        .indices
22        .iter()
23        .find(|i| !i.primary_key)
24        .expect("non-PK index should exist");
25    assert_eq!(custom_idx.name, "tournament_region_idx");
26
27    // The auto-generated form must NOT be present.
28    assert!(
29        !table
30            .indices
31            .iter()
32            .any(|i| i.name == "index_matches_by_tournament_id_and_region"),
33        "auto-generated name should not coexist with the custom name"
34    );
35
36    toasty::create!(Match::[
37        { id: "m1", tournament_id: "WINTER2024", region: "NA-EAST" },
38        { id: "m2", tournament_id: "WINTER2024", region: "EU-WEST" },
39    ])
40    .exec(&mut db)
41    .await?;
42
43    let matches: Vec<Match> = Match::filter_by_tournament_id("WINTER2024")
44        .exec(&mut db)
45        .await?;
46    assert_eq!(matches.len(), 2);
47
48    Ok(())
49}
50
51/// Without `name = "..."`, the schema builder still produces the
52/// auto-generated `index_<table>_by_<cols>` form. Sanity check that the
53/// custom-name path doesn't accidentally suppress all auto-naming.
54#[driver_test]
55pub async fn index_custom_name_default_unchanged(t: &mut Test) -> Result<()> {
56    #[derive(Debug, toasty::Model)]
57    #[index(category)]
58    struct Product {
59        #[key]
60        id: String,
61        category: String,
62    }
63
64    let db = t.setup_db(models!(Product)).await;
65    let table = &db.schema().db.tables[0];
66
67    let auto_idx = table
68        .indices
69        .iter()
70        .find(|i| !i.primary_key)
71        .expect("non-PK index should exist");
72    // Suite prefixes the table name; assert the structural form, not the literal.
73    assert!(
74        auto_idx.name.starts_with("index_") && auto_idx.name.ends_with("_by_category"),
75        "expected auto-generated `index_<table>_by_category`, got: {}",
76        auto_idx.name
77    );
78
79    Ok(())
80}
81
82/// `#[key(name = "...", ...)]` records the custom name on the primary-key
83/// index in the DB schema. SQL backends emit primary keys inline today, so
84/// this verifies the schema-internal wiring rather than DDL output.
85#[driver_test]
86pub async fn key_custom_name_recorded_on_pk_index(t: &mut Test) -> Result<()> {
87    #[derive(Debug, toasty::Model)]
88    #[key(name = "player_pk", partition = team, local = name)]
89    struct Player {
90        team: String,
91        name: String,
92    }
93
94    let db = t.setup_db(models!(Player)).await;
95    let table = &db.schema().db.tables[0];
96
97    let pk_index = table
98        .indices
99        .iter()
100        .find(|i| i.primary_key)
101        .expect("PK index should exist");
102    assert_eq!(pk_index.name, "player_pk");
103
104    Ok(())
105}