mockgres 0.0.22

An in-memory database that replicates a reasonable subset of Postgres functionality to make unit tests that rely on a database to run.
Documentation
mod common;

use tokio_postgres::Row;

#[tokio::test(flavor = "multi_thread")]
async fn default_nulls_last_for_asc_first_for_desc() {
    let ctx = common::start().await;

    ctx.client
        .execute("create table t(x int4)", &[])
        .await
        .expect("create");

    // constants for insert: 2, null, 1
    ctx.client
        .execute("insert into t values (2),(null),(1)", &[])
        .await
        .expect("insert");

    // asc: nulls last
    let asc_rows: Vec<Row> = ctx
        .client
        .query("select x from t order by 1 asc", &[])
        .await
        .expect("asc ok");
    let asc_vals: Vec<Option<i32>> = asc_rows
        .iter()
        .map(|r| r.get::<_, Option<i32>>(0))
        .collect();
    assert_eq!(asc_vals, vec![Some(1), Some(2), None]);

    // desc: nulls first
    let desc_rows: Vec<Row> = ctx
        .client
        .query("select x from t order by 1 desc", &[])
        .await
        .expect("desc ok");
    let desc_vals: Vec<Option<i32>> = desc_rows
        .iter()
        .map(|r| r.get::<_, Option<i32>>(0))
        .collect();
    assert_eq!(desc_vals, vec![None, Some(2), Some(1)]);

    let _ = ctx.shutdown.send(());
}

#[tokio::test(flavor = "multi_thread")]
async fn explicit_nulls_first_last_respected() {
    let ctx = common::start().await;

    ctx.client
        .execute("create table null_orders(txt text, flag bool)", &[])
        .await
        .expect("create table");
    ctx.client
        .execute(
            "insert into null_orders values
                ('b', true),
                (null, null),
                ('a', false)",
            &[],
        )
        .await
        .expect("insert rows");

    let txt_vals: Vec<Option<String>> = ctx
        .client
        .query(
            "select txt from null_orders order by txt asc nulls first",
            &[],
        )
        .await
        .expect("txt nulls first")
        .into_iter()
        .map(|row| row.get(0))
        .collect();
    assert_eq!(
        txt_vals,
        vec![None, Some("a".to_string()), Some("b".to_string())]
    );

    let flag_vals: Vec<Option<bool>> = ctx
        .client
        .query(
            "select flag from null_orders order by flag desc nulls last",
            &[],
        )
        .await
        .expect("flag nulls last")
        .into_iter()
        .map(|row| row.get(0))
        .collect();
    assert_eq!(flag_vals, vec![Some(true), Some(false), None]);

    let _ = ctx.shutdown.send(());
}