jev(row, q [, threshold]) (contract SQL surface): true when the
Noul probability is at least the threshold, taken from the argument,
then jev.threshold, then 0.5. It is evaluated by the jev scan and
shares its judgments, and the cache, with jev_prob.
Answers 0.3, 0.6, 0.9 and 0.5 about tickets 1 to 4.
26async fn ids(client: &tokio_postgres::Client, sql: &str) -> Vec<i32> { 27 client.query(sql, &[]).await.unwrap().iter().map(|r| r.get(0)).collect() 28} 29 30#[tokio::test(flavor = "multi_thread")] 31async fn argument_then_setting_then_half() { 32 let mock = graded().await; 33 let (_pg, client) = jev_instance(&mock).await; 34 client 35 .batch_execute("INSERT INTO tickets VALUES (2, 'b'), (3, 'c'), (4, 'd')") 36 .await 37 .unwrap(); 38 let urgent = "SELECT id FROM tickets t WHERE jev(t, 'Urgent?') ORDER BY id"; 39 40 // Neither: 0.5, and a probability equal to it passes. 41 assert_eq!(ids(&client, urgent).await, [2, 3, 4]); 42 43 // The setting. 44 client.batch_execute("SET jev.threshold = 0.7").await.unwrap(); 45 assert_eq!(ids(&client, urgent).await, [3]); 46 47 // The argument, over the setting, both lower and higher. 48 assert_eq!(ids(&client, "SELECT id FROM tickets t WHERE jev(t, 'Urgent?', 0.2) ORDER BY id").await, [1, 2, 3, 4]); 49 assert_eq!(ids(&client, "SELECT id FROM tickets t WHERE jev(t, 'Urgent?', 0.95) ORDER BY id").await, [] as [i32; 0]); 50 51 // RESET falls back to 0.5. 52 client.batch_execute("RESET jev.threshold").await.unwrap(); 53 assert_eq!(ids(&client, urgent).await, [2, 3, 4]); 54 55 // In the select list, beside jev_prob, one judgment per row. 56 let rows = client 57 .query("SELECT id, jev(t, 'Urgent?', 0.55), jev_prob(t, 'Urgent?') FROM tickets t ORDER BY id", &[]) 58 .await 59 .unwrap(); 60 let got: Vec<(i32, bool, f64)> = rows.iter().map(|r| (r.get(0), r.get(1), r.get(2))).collect(); 61 assert_eq!(got, [(1, false, 0.3), (2, true, 0.6), (3, true, 0.9), (4, false, 0.5)]); 62 63 // Every statement after the first was answered from the cache: the 64 // threshold is applied to the stored probability, not asked. 65 assert_eq!(mock.requests().len(), 4); 66} 67 68#[tokio::test(flavor = "multi_thread")] 69async fn thresholds_outside_zero_to_one_are_refused() { 70 let mock = graded().await; 71 let (_pg, client) = jev_instance(&mock).await; 72 73 let err = client.batch_execute("SET jev.threshold = 1.5").await.expect_err("refused"); 74 assert_eq!(err.as_db_error().expect("an ERROR").code(), &SqlState::INVALID_PARAMETER_VALUE); 75 76 let err = client 77 .query("SELECT id FROM tickets t WHERE jev(t, 'Urgent?', 2)", &[]) 78 .await 79 .expect_err("refused"); 80 assert_eq!(err.as_db_error().expect("an ERROR").code(), &SqlState::INVALID_PARAMETER_VALUE); 81 assert!(mock.requests().is_empty(), "refused before sending"); 82}