From ecaf6ce5bb7111f4fee17ebe45eb55f9d337c0fa Mon Sep 17 00:00:00 2001 From: lovasoa Date: Mon, 24 Nov 2025 23:44:45 +0100 Subject: [PATCH 1/5] simplify SQL test files - Simplified SQL test files by removing unnecessary components and restructuring queries to focus on expected vs actual results. - Updated the request handling in `run_sql_test` to differentiate between JSON and HTML responses based on test file content. - Enhanced error handling and assertions for both JSON and HTML responses to improve test reliability and clarity. - Removed redundant code and improved readability in the test execution flow. --- tests/common/mod.rs | 31 ++- tests/server_timing/mod.rs | 4 +- .../it_works_basic_auth_password.sql | 6 +- .../it_works_basic_auth_username.sql | 6 +- .../sql_test_files/it_works_coalesce_eval.sql | 6 +- .../it_works_concat_str_in_pseudofunction.sql | 20 +- tests/sql_test_files/it_works_cookie.sql | 6 +- tests/sql_test_files/it_works_decimal.sql | 9 +- .../it_works_fetch_with_meta_error.sql | 6 +- .../it_works_fetch_with_meta_simple.sql | 9 +- .../it_works_hash_password_null.sql | 4 +- tests/sql_test_files/it_works_header.sql | 6 +- tests/sql_test_files/it_works_headers.sql | 5 +- tests/sql_test_files/it_works_link.sql | 6 +- tests/sql_test_files/it_works_link_null.sql | 6 +- .../it_works_nested_sqlpage_functions.sql | 6 +- .../it_works_postgres_cast_syntax.sql | 8 +- .../sql_test_files/it_works_query_string.sql | 12 +- .../sql_test_files/it_works_random_string.sql | 6 +- .../it_works_set_variable_func.sql | 9 +- .../it_works_set_variable_func_null.sql | 8 +- .../it_works_set_variable_func_replace.sql | 8 +- .../it_works_set_variable_large_integer.sql | 9 +- ...t_works_set_variable_to_other_variable.sql | 7 +- tests/sql_test_files/it_works_sqrt.sql | 10 +- tests/sql_test_files/mod.rs | 252 ++++++++++-------- 26 files changed, 194 insertions(+), 271 deletions(-) diff --git a/tests/common/mod.rs b/tests/common/mod.rs index e7ca2e3b..35db34e6 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -53,25 +53,34 @@ pub async fn req_path( main_handler(req).await } -pub async fn srv_req_path_with_app_data( +const REQ_TIMEOUT: Duration = Duration::from_secs(8); +pub async fn req_path_with_app_data( path: impl AsRef, app_data: Data, -) -> actix_web::dev::ServiceRequest { - test::TestRequest::get() - .uri(path.as_ref()) - .app_data(app_data) - .insert_header(("cookie", "test_cook=123")) - .insert_header(("authorization", "Basic dGVzdDp0ZXN0")) // test:test - .to_srv_request() +) -> anyhow::Result { + req_path_with_app_data_and_accept(path, app_data, header::Accept::html()).await } -const REQ_TIMEOUT: Duration = Duration::from_secs(8); -pub async fn req_path_with_app_data( +pub async fn req_path_with_app_data_json( path: impl AsRef, app_data: Data, +) -> anyhow::Result { + req_path_with_app_data_and_accept(path, app_data, header::Accept::json()).await +} + +async fn req_path_with_app_data_and_accept( + path: impl AsRef, + app_data: Data, + accept: header::Accept, ) -> anyhow::Result { let path = path.as_ref(); - let req = srv_req_path_with_app_data(path, app_data).await; + let req = test::TestRequest::get() + .uri(path) + .app_data(app_data) + .insert_header(("cookie", "test_cook=123")) + .insert_header(("authorization", "Basic dGVzdDp0ZXN0")) + .insert_header(accept) + .to_srv_request(); let resp = tokio::time::timeout(REQ_TIMEOUT, main_handler(req)) .await .map_err(|e| anyhow::anyhow!("Request to {path} timed out: {e}"))? diff --git a/tests/server_timing/mod.rs b/tests/server_timing/mod.rs index 1cbb752c..d380c7e5 100644 --- a/tests/server_timing/mod.rs +++ b/tests/server_timing/mod.rs @@ -32,7 +32,7 @@ async fn test_server_timing_enabled_in_development() -> actix_web::Result<()> { let app_data = make_app_data_from_config(config).await; let req = crate::common::get_request_to_with_data( - "/tests/sql_test_files/it_works_sqrt.sql", + "/tests/sql_test_files/it_works_postgres_cast_syntax.sql", app_data, ) .await? @@ -72,7 +72,7 @@ async fn test_server_timing_enabled_in_development() -> actix_web::Result<()> { #[actix_web::test] async fn test_server_timing_format() -> actix_web::Result<()> { - let req = get_request_to("/tests/sql_test_files/it_works_sqrt.sql") + let req = get_request_to("/tests/sql_test_files/it_works_postgres_cast_syntax.sql") .await? .to_srv_request(); let resp = main_handler(req).await?; diff --git a/tests/sql_test_files/it_works_basic_auth_password.sql b/tests/sql_test_files/it_works_basic_auth_password.sql index 7397cdd0..9bded9cd 100644 --- a/tests/sql_test_files/it_works_basic_auth_password.sql +++ b/tests/sql_test_files/it_works_basic_auth_password.sql @@ -1,5 +1 @@ -select 'text' as component, - case sqlpage.basic_auth_password() - when 'test' then 'It works !' - else 'error: ' || coalesce(sqlpage.basic_auth_password(), 'NULL') - end as contents; \ No newline at end of file +select 'test' as expected, sqlpage.basic_auth_password() as actual; diff --git a/tests/sql_test_files/it_works_basic_auth_username.sql b/tests/sql_test_files/it_works_basic_auth_username.sql index 6dd61057..f32170d1 100644 --- a/tests/sql_test_files/it_works_basic_auth_username.sql +++ b/tests/sql_test_files/it_works_basic_auth_username.sql @@ -1,5 +1 @@ -select 'text' as component, - case sqlpage.basic_auth_username() - when 'test' then 'It works !' - else 'error: ' || coalesce(sqlpage.basic_auth_username(), 'NULL') - end as contents; \ No newline at end of file +select 'test' as expected, sqlpage.basic_auth_username() as actual; diff --git a/tests/sql_test_files/it_works_coalesce_eval.sql b/tests/sql_test_files/it_works_coalesce_eval.sql index 2870313f..4f455e5b 100644 --- a/tests/sql_test_files/it_works_coalesce_eval.sql +++ b/tests/sql_test_files/it_works_coalesce_eval.sql @@ -1,5 +1 @@ -select 'text' as component, - case sqlpage.link(coalesce($i_do_not_exist, 'https://example.com')) - when 'https://example.com' then 'It works !' - else 'error: ' || coalesce(sqlpage.link(coalesce($i_do_not_exist, 'https://example.com')), 'NULL') - end AS contents; \ No newline at end of file +select 'https://example.com' as expected, sqlpage.link(coalesce($i_do_not_exist, 'https://example.com')) as actual; diff --git a/tests/sql_test_files/it_works_concat_str_in_pseudofunction.sql b/tests/sql_test_files/it_works_concat_str_in_pseudofunction.sql index 1e1804a9..a07b15c9 100644 --- a/tests/sql_test_files/it_works_concat_str_in_pseudofunction.sql +++ b/tests/sql_test_files/it_works_concat_str_in_pseudofunction.sql @@ -1,17 +1,3 @@ -select 'text' as component, - 'With "||": ' || - CASE sqlpage.url_encode('/' || $x) - WHEN '%2F1' THEN 'It works !' - ELSE 'Error: "/1" should be urlencoded to "%2F1"' - END - || ' | With CONCAT: ' || - CASE sqlpage.url_encode(CONCAT('/', $x)) -- $x is set to '1' in the test - WHEN '%2F1' THEN 'With CONCAT: It works !' - ELSE 'Error: "/1" should be urlencoded to "%2F1"' - END - || ' | With a null value: ' || - CASE COALESCE(sqlpage.url_encode(CONCAT('/', $thisisnull)), 'expected') - WHEN 'expected' THEN 'With a null value: It works !' - ELSE 'Error: a null value concatenated with "/" should be null, and urlencoded to NULL' - END - AS contents; \ No newline at end of file +select '%2F1' as expected, sqlpage.url_encode('/' || $x) as actual; +select '%2F1' as expected, sqlpage.url_encode(CONCAT('/', $x)) as actual; +select 'NULL' as expected, coalesce(sqlpage.url_encode(CONCAT('/', $thisisnull)), 'NULL') as actual; diff --git a/tests/sql_test_files/it_works_cookie.sql b/tests/sql_test_files/it_works_cookie.sql index 89ff3bda..4e7275ee 100644 --- a/tests/sql_test_files/it_works_cookie.sql +++ b/tests/sql_test_files/it_works_cookie.sql @@ -1,5 +1 @@ -select 'text' as component, - case sqlpage.cookie('test_cook') - when '123' then 'It works !' - else 'error: ' || coalesce(sqlpage.cookie('test_cook'), 'NULL') - end AS contents; \ No newline at end of file +select '123' as expected, sqlpage.cookie('test_cook') as actual; diff --git a/tests/sql_test_files/it_works_decimal.sql b/tests/sql_test_files/it_works_decimal.sql index 6a1bd595..8b8cb82f 100644 --- a/tests/sql_test_files/it_works_decimal.sql +++ b/tests/sql_test_files/it_works_decimal.sql @@ -1,7 +1,2 @@ -set my_decimal = CAST(0.47 AS DECIMAL(3,2)); - -select 'text' as component, - case $my_decimal - when '0.47' then 'It works !' - else 'error: ' || coalesce($my_decimal, 'NULL') - end AS contents; \ No newline at end of file +set result = CAST(0.47 AS DECIMAL(3,2)); +select '0.47' as expected, $result as actual; diff --git a/tests/sql_test_files/it_works_fetch_with_meta_error.sql b/tests/sql_test_files/it_works_fetch_with_meta_error.sql index 721797fb..2910ae62 100644 --- a/tests/sql_test_files/it_works_fetch_with_meta_error.sql +++ b/tests/sql_test_files/it_works_fetch_with_meta_error.sql @@ -1,7 +1,3 @@ set res = sqlpage.fetch_with_meta('http://not-a-real-url'); -select 'text' as component, - case - when $res LIKE '%"error":"Request failed%' then 'It works !' - else CONCAT('Error! Got: ', $res) - end as contents; \ No newline at end of file +select '"error":"Request failed' as expected_contains, $res as actual; diff --git a/tests/sql_test_files/it_works_fetch_with_meta_simple.sql b/tests/sql_test_files/it_works_fetch_with_meta_simple.sql index ef1d6e73..4f4ab11f 100644 --- a/tests/sql_test_files/it_works_fetch_with_meta_simple.sql +++ b/tests/sql_test_files/it_works_fetch_with_meta_simple.sql @@ -8,8 +8,7 @@ set fetch_req = '{ }'; set res = sqlpage.fetch_with_meta($fetch_req); -select 'text' as component, - case - when $res LIKE '%"status":200%' AND $res LIKE '%"headers":{%' AND $res LIKE '%"body":"%' then 'It works !' - else 'Error! Got: ' || $res - end as contents; \ No newline at end of file +select '"status":200' as expected_contains, + '"headers":{' as expected_contains, + '"body":"' as expected_contains, + $res as actual; diff --git a/tests/sql_test_files/it_works_hash_password_null.sql b/tests/sql_test_files/it_works_hash_password_null.sql index 9c52f351..4755eff7 100644 --- a/tests/sql_test_files/it_works_hash_password_null.sql +++ b/tests/sql_test_files/it_works_hash_password_null.sql @@ -1,3 +1 @@ -SELECT 'text' as component, - case when sqlpage.hash_password(null) is null then 'It works !' else 'Error !' end - as contents; +select 'NULL' as expected, coalesce(sqlpage.hash_password(null), 'NULL') as actual; diff --git a/tests/sql_test_files/it_works_header.sql b/tests/sql_test_files/it_works_header.sql index 987d5879..50cbac97 100644 --- a/tests/sql_test_files/it_works_header.sql +++ b/tests/sql_test_files/it_works_header.sql @@ -1,5 +1 @@ -select 'text' as component, - case sqlpage.header('cookie') - when 'test_cook=123' then 'It works !' - else 'error: ' || coalesce(sqlpage.header('cookie'), 'NULL') - end AS contents; \ No newline at end of file +select 'test_cook=123' as expected, sqlpage.header('cookie') as actual; diff --git a/tests/sql_test_files/it_works_headers.sql b/tests/sql_test_files/it_works_headers.sql index c1984b1c..01ce101c 100644 --- a/tests/sql_test_files/it_works_headers.sql +++ b/tests/sql_test_files/it_works_headers.sql @@ -1,4 +1 @@ -select 'text' as component, - case when sqlpage.headers() LIKE '%"cookie":"test_cook=123"%' then 'It works !' - else 'error: ' || sqlpage.headers() - end AS contents; \ No newline at end of file +select '"cookie":"test_cook=123"' as expected_contains, sqlpage.headers() as actual; diff --git a/tests/sql_test_files/it_works_link.sql b/tests/sql_test_files/it_works_link.sql index fd4bbb27..47ca6003 100644 --- a/tests/sql_test_files/it_works_link.sql +++ b/tests/sql_test_files/it_works_link.sql @@ -1,5 +1 @@ -select 'text' as component, - case sqlpage.link('test.sql', json_object('x', 123)) - when 'test.sql?x=123' then 'It works !' - else 'error: ' || coalesce(sqlpage.link('test.sql', json_object('x', 123)), 'NULL') - end AS contents; \ No newline at end of file +select 'test.sql?x=123' as expected, sqlpage.link('test.sql', json_object('x', 123)) as actual; diff --git a/tests/sql_test_files/it_works_link_null.sql b/tests/sql_test_files/it_works_link_null.sql index 0b3a7de3..4c7b82da 100644 --- a/tests/sql_test_files/it_works_link_null.sql +++ b/tests/sql_test_files/it_works_link_null.sql @@ -1,5 +1 @@ -select 'text' as component, - case sqlpage.link('test.sql', json_object('x', null)) - when 'test.sql' then 'It works !' - else 'error: ' || coalesce(sqlpage.link('test.sql', json_object('x', null)), 'NULL') - end AS contents; +select 'test.sql' as expected, sqlpage.link('test.sql', json_object('x', null)) as actual; diff --git a/tests/sql_test_files/it_works_nested_sqlpage_functions.sql b/tests/sql_test_files/it_works_nested_sqlpage_functions.sql index a1e299ad..49eeb48e 100644 --- a/tests/sql_test_files/it_works_nested_sqlpage_functions.sql +++ b/tests/sql_test_files/it_works_nested_sqlpage_functions.sql @@ -1,5 +1 @@ -select 'text' as component, - case sqlpage.url_encode(sqlpage.read_file_as_text('tests/it_works.txt')) - when 'It%20works%20%21' then 'It works !' - else 'Error! Nested sqlpage functions are not working as expected.' - end as contents; +select 'It%20works%20%21' as expected, sqlpage.url_encode(sqlpage.read_file_as_text('tests/it_works.txt')) as actual; diff --git a/tests/sql_test_files/it_works_postgres_cast_syntax.sql b/tests/sql_test_files/it_works_postgres_cast_syntax.sql index 6244aa9e..53ce2ff8 100644 --- a/tests/sql_test_files/it_works_postgres_cast_syntax.sql +++ b/tests/sql_test_files/it_works_postgres_cast_syntax.sql @@ -1,7 +1 @@ --- the syntax $x::int is supported only in PostgreSQL --- but for consistency with other databases, sqlpage supports this syntax everywher () -SELECT 'text' as component, - case $x::decimal + 1 - when 2 then 'It works !' - else 'Error !' - end as contents; +select 2 as expected, $x::decimal + 1 as actual; diff --git a/tests/sql_test_files/it_works_query_string.sql b/tests/sql_test_files/it_works_query_string.sql index cfe5f36b..c7624f09 100644 --- a/tests/sql_test_files/it_works_query_string.sql +++ b/tests/sql_test_files/it_works_query_string.sql @@ -1,11 +1 @@ -set actual = sqlpage.link('', sqlpage.variables('get')); -set expected = '?x=1'; -SELECT - 'text' AS component, - CASE $actual - WHEN $expected THEN - 'It works !' - ELSE - 'Expected ' || COALESCE($expected, 'null') || ' but got ' || COALESCE($actual, 'null') - END AS contents -; \ No newline at end of file +select '?x=1' as expected, sqlpage.link('', sqlpage.variables('get')) as actual; diff --git a/tests/sql_test_files/it_works_random_string.sql b/tests/sql_test_files/it_works_random_string.sql index 54d7e09b..e187c573 100644 --- a/tests/sql_test_files/it_works_random_string.sql +++ b/tests/sql_test_files/it_works_random_string.sql @@ -1,5 +1 @@ -select 'text' as component, - case when sqlpage.random_string(0) = '' -- with 0 as a parameter, the function becomes deterministic ;) - then 'It works !' - else 'Error ! sqlpage.random_string(5) = ' || sqlpage.random_string(5) - end as contents; \ No newline at end of file +select '' as expected, sqlpage.random_string(0) as actual; diff --git a/tests/sql_test_files/it_works_set_variable_func.sql b/tests/sql_test_files/it_works_set_variable_func.sql index b3b2771a..d0fc5abc 100644 --- a/tests/sql_test_files/it_works_set_variable_func.sql +++ b/tests/sql_test_files/it_works_set_variable_func.sql @@ -1,7 +1,2 @@ -set url = sqlpage.set_variable('y', '2'); - -select 'text' as component, - case $url - when '?x=1&y=2' THEN 'It works !' - else 'It failed ! Expected ?x=1&y=2 but got ' || coalesce($url, 'NULL') - end as contents; \ No newline at end of file +set result = sqlpage.set_variable('y', '2'); +select '?x=1&y=2' as expected, $result as actual; diff --git a/tests/sql_test_files/it_works_set_variable_func_null.sql b/tests/sql_test_files/it_works_set_variable_func_null.sql index 21800dc4..8cf9a2b5 100644 --- a/tests/sql_test_files/it_works_set_variable_func_null.sql +++ b/tests/sql_test_files/it_works_set_variable_func_null.sql @@ -1,6 +1,2 @@ -set url = sqlpage.set_variable('x', null); -select 'text' as component, - case $url - when '?' THEN 'It works !' - else 'It failed ! Expected "?" but got ' || coalesce('"' || $url || '"', 'NULL') - end as contents; +set result = sqlpage.set_variable('x', null); +select '?' as expected, $result as actual; diff --git a/tests/sql_test_files/it_works_set_variable_func_replace.sql b/tests/sql_test_files/it_works_set_variable_func_replace.sql index 6d71a44b..859e280c 100644 --- a/tests/sql_test_files/it_works_set_variable_func_replace.sql +++ b/tests/sql_test_files/it_works_set_variable_func_replace.sql @@ -1,6 +1,2 @@ -set url = sqlpage.set_variable('x', '2'); -select 'text' as component, - case $url - when '?x=2' THEN 'It works !' - else 'It failed ! Expected ?x=2 but got ' || $url - end as contents; +set result = sqlpage.set_variable('x', '2'); +select '?x=2' as expected, $result as actual; diff --git a/tests/sql_test_files/it_works_set_variable_large_integer.sql b/tests/sql_test_files/it_works_set_variable_large_integer.sql index 859f89db..0c839afd 100644 --- a/tests/sql_test_files/it_works_set_variable_large_integer.sql +++ b/tests/sql_test_files/it_works_set_variable_large_integer.sql @@ -1,7 +1,2 @@ -SET test_stored_number = 123456789123456789123456789; -select 'text' as component, - case $test_stored_number - when '123456789123456789123456789' then 'It works !' - else 'It failed ! Expected 123456789123456789123456789 but got ' || COALESCE($test_stored_number, 'NULL') - end -AS contents; \ No newline at end of file +SET result = 123456789123456789123456789; +select '123456789123456789123456789' as expected, $result as actual; diff --git a/tests/sql_test_files/it_works_set_variable_to_other_variable.sql b/tests/sql_test_files/it_works_set_variable_to_other_variable.sql index 5c277a9e..e6c8a52c 100644 --- a/tests/sql_test_files/it_works_set_variable_to_other_variable.sql +++ b/tests/sql_test_files/it_works_set_variable_to_other_variable.sql @@ -1,9 +1,4 @@ SET x = 42; SET y = $x; SET z = $y; -select 'text' as component, - case $z - when '42' then 'It works !' - else 'It failed ! Expected 42 but got ' || COALESCE($z, 'NULL') - end -AS contents; \ No newline at end of file +select '42' as expected, $z as actual; diff --git a/tests/sql_test_files/it_works_sqrt.sql b/tests/sql_test_files/it_works_sqrt.sql index f13063e2..c8c00bb9 100644 --- a/tests/sql_test_files/it_works_sqrt.sql +++ b/tests/sql_test_files/it_works_sqrt.sql @@ -1,8 +1,2 @@ -set number_three = sqrt(9.0); - -select 'text' as component, - case $number_three - when '3.0' then 'It works !' - when '3' then 'It works !' - else 'error: ' || coalesce($number_three, 'NULL') - end AS contents; +set result = sqrt(9.0); +select '3' as expected, '3.0' as expected, $result as actual; diff --git a/tests/sql_test_files/mod.rs b/tests/sql_test_files/mod.rs index 8635a20d..af081d88 100644 --- a/tests/sql_test_files/mod.rs +++ b/tests/sql_test_files/mod.rs @@ -9,177 +9,201 @@ async fn run_all_sql_test_files() { let app_data = crate::common::make_app_data().await; let test_files = get_sql_test_files(); - // Create a shutdown channel for the echo server let (shutdown_tx, shutdown_rx) = oneshot::channel(); - // Start echo server once for all tests let (echo_handle, port) = crate::common::start_echo_server(shutdown_rx); - - // Wait for echo server to be ready wait_for_echo_server(port).await; for test_file in test_files { - let test_result = run_sql_test(&test_file, &app_data, &echo_handle, port).await; - assert_test_result(test_result, &test_file); + run_sql_test(&test_file, &app_data, &echo_handle, port).await; } - // Signal the echo server to shut down let _ = shutdown_tx.send(()); - // Wait for echo server to complete after all tests with a timeout - match tokio::time::timeout(Duration::from_secs(2), echo_handle).await { - Ok(_) => (), - Err(_) => panic!("Echo server did not shut down within 2 seconds"), - } + let _ = tokio::time::timeout(Duration::from_secs(2), echo_handle).await; } async fn wait_for_echo_server(port: u16) { let client = awc::Client::default(); let start = std::time::Instant::now(); - let timeout = Duration::from_secs(5); - - while start.elapsed() < timeout { - match client.get(format!("http://localhost:{port}/")).send().await { - Ok(_) => return, - Err(_) => { - tokio::time::sleep(Duration::from_millis(100)).await; - continue; - } + while start.elapsed() < Duration::from_secs(5) { + if client + .get(format!("http://localhost:{port}/")) + .send() + .await + .is_ok() + { + return; } + tokio::time::sleep(Duration::from_millis(100)).await; } - panic!("Echo server did not become ready within 5 seconds"); + panic!("Echo server did not become ready"); } fn get_sql_test_files() -> Vec { - let path = std::path::Path::new("tests/sql_test_files"); - std::fs::read_dir(path) + std::fs::read_dir("tests/sql_test_files") .unwrap() - .filter_map(|entry| { - let entry = entry.ok()?; - let path = entry.path(); - if path.extension()? == "sql" { - Some(path) - } else { - None - } + .filter_map(|e| { + let path = e.ok()?.path(); + (path.extension()? == "sql").then_some(path) }) .collect() } -use std::fmt::Write; - -#[derive(Debug)] -enum TestResult { - Success(String), - Skipped(String), -} - async fn run_sql_test( test_file: &std::path::Path, app_data: &actix_web::web::Data, _echo_handle: &JoinHandle<()>, port: u16, -) -> anyhow::Result { +) { let test_file_path = test_file.to_string_lossy().replace('\\', "/"); let stem = test_file.file_stem().unwrap().to_str().unwrap(); - let app_state = app_data.get_ref(); - let db = &app_state.db; - let db_type = format!("{:?}", db.info.database_type).to_lowercase(); - + let db_type = format!("{:?}", app_data.db.info.database_type).to_lowercase(); if stem.contains(&format!("_no{db_type}")) { - return Ok(TestResult::Skipped(format!( - "Test skipped for database type: {db_type}" - ))); + println!("Skipped {}: {}", test_file.display(), db_type); + return; } let mut query_params = "x=1".to_string(); if test_file_path.contains("fetch") { - write!(query_params, "&echo_port={port}").unwrap(); + query_params.push_str(&format!("&echo_port={port}")); } let req_str = format!("/{test_file_path}?{query_params}"); - let resp = tokio::time::timeout( - Duration::from_secs(5), - crate::common::req_path_with_app_data(&req_str, app_data.clone()), - ) + let use_json = std::fs::read_to_string(test_file) + .unwrap_or_default() + .contains(" actual"); + + let resp = tokio::time::timeout(Duration::from_secs(5), async { + if use_json { + crate::common::req_path_with_app_data_json(&req_str, app_data.clone()).await + } else { + crate::common::req_path_with_app_data(&req_str, app_data.clone()).await + } + }) .await - .map_err(|e| anyhow::anyhow!("Test request timed out after 5 seconds: {}", e))??; + .unwrap_or_else(|_| panic!("Test timeout: {}", test_file.display())) + .unwrap_or_else(|e| panic!("Request failed: {}: {}", test_file.display(), e)); + + let body = String::from_utf8(test::read_body(resp).await.to_vec()) + .unwrap_or_else(|_| panic!("Invalid UTF-8: {}", test_file.display())); - let body = test::read_body(resp).await; - Ok(TestResult::Success(String::from_utf8(body.to_vec())?)) + if use_json { + assert_json_test(&body, test_file); + } else { + assert_html_test(&body, test_file, stem); + } } -fn assert_test_result(result: anyhow::Result, test_file: &std::path::Path) { - match result { - Ok(TestResult::Skipped(reason)) => { - println!("⏭️ Skipped {}: {}", test_file.display(), reason); +fn assert_json_test(body: &str, test_file: &std::path::Path) { + let rows: Vec = serde_json::from_str(body) + .unwrap_or_else(|_| panic!("Invalid JSON: {}", test_file.display())); + + assert!( + !rows.is_empty(), + "No rows returned: {}", + test_file.display() + ); + + for row in rows { + let obj = match row.as_object() { + Some(o) => o, + None => continue, + }; + + let actual = obj + .get("actual") + .map(json_to_string) + .unwrap_or_else(|| "NULL".to_string()); + + let expected: Vec = obj + .get("expected") + .map(|v| match v { + serde_json::Value::Array(arr) => arr.iter().map(json_to_string).collect(), + _ => vec![json_to_string(v)], + }) + .unwrap_or_default(); + + let expected_contains: Vec = obj + .get("expected_contains") + .map(|v| match v { + serde_json::Value::Array(arr) => arr.iter().map(json_to_string).collect(), + _ => vec![json_to_string(v)], + }) + .unwrap_or_default(); + + if expected.is_empty() && expected_contains.is_empty() { + continue; } - Ok(TestResult::Success(body)) => { - assert_html_response(&body, test_file); - let lowercase_body = body.to_lowercase(); - let stem = test_file.file_stem().unwrap().to_str().unwrap().to_string(); - - if stem.starts_with("it_works") { - assert_it_works_tests(&body, &lowercase_body, test_file); - } else if stem.starts_with("error_") { - assert_error_tests(&stem, &lowercase_body, test_file); + + let exact_ok = expected.is_empty() || expected.iter().any(|e| e == &actual); + let contains_ok = + expected_contains.is_empty() || expected_contains.iter().all(|e| actual.contains(e)); + + if !exact_ok || !contains_ok { + let mut msg = format!("Test failed: {}\n", test_file.display()); + if !expected.is_empty() { + msg.push_str(&format!("Expected: {}\n", expected.join(" or "))); + } + if !expected_contains.is_empty() { + msg.push_str(&format!( + "Expected to contain: {}\n", + expected_contains.join(", ") + )); } + msg.push_str(&format!("Actual: {}\n", actual)); + panic!("{}", msg); } - Err(e) => panic!("Failed to get response for {}: {}", test_file.display(), e), } } -fn assert_html_response(body: &str, test_file: &std::path::Path) { +fn assert_html_test(body: &str, test_file: &std::path::Path, stem: &str) { assert!( body.starts_with(""), - "Response to {} is not HTML", + "Not HTML: {}", test_file.display() ); -} -fn assert_it_works_tests(body: &str, lowercase_body: &str, test_file: &std::path::Path) { - if body.contains("") { - let error_desc = body - .split("") - .nth(1) - .and_then(|s| s.split("").next()) - .unwrap_or("Unknown error"); - panic!( - "\n\n❌ TEST FAILED: {} ❌\n\nFull Response:\n{}\n\nError Description: {}\n", - test_file.display(), - error_desc, - body + if stem.starts_with("it_works") { + if let Some(error) = extract_error(body) { + panic!("Error in {}: {}", test_file.display(), error); + } + assert!( + body.contains("It works !"), + "Should contain 'It works !': {}", + test_file.display() + ); + assert!( + !body.to_lowercase().contains("error"), + "Unexpected error: {}", + test_file.display() + ); + } else if stem.starts_with("error_") { + let expected = stem.strip_prefix("error_").unwrap().replace('_', " "); + assert!( + body.to_lowercase().contains(&expected.to_lowercase()), + "Should contain '{}': {}", + expected, + test_file.display() ); } +} - assert!( - body.contains("It works !"), - "{body}\n❌ Error in file {test_file:?} ❌\nShould contain: 'It works !'", - ); - assert!( - !lowercase_body.contains("error"), - "{}\n{}\nexpected to not contain: error", - test_file.display(), - body - ); +fn extract_error(body: &str) -> Option { + body.split("") + .nth(1)? + .split("") + .next() + .map(str::trim) + .filter(|s| !s.is_empty()) + .map(String::from) } -fn assert_error_tests(stem: &str, lowercase_body: &str, test_file: &std::path::Path) { - let expected_error = stem - .strip_prefix("error_") - .unwrap() - .replace('_', " ") - .to_lowercase(); - assert!( - lowercase_body.contains(&expected_error), - "{}\n{}\nexpected to contain: {}", - test_file.display(), - lowercase_body, - expected_error - ); - assert!( - lowercase_body.contains("error"), - "{}\n{}\nexpected to contain: error", - test_file.display(), - lowercase_body - ); +fn json_to_string(v: &serde_json::Value) -> String { + match v { + serde_json::Value::Null => "NULL".to_string(), + serde_json::Value::String(s) => s.clone(), + serde_json::Value::Number(n) => n.to_string(), + serde_json::Value::Bool(b) => b.to_string(), + _ => v.to_string(), + } } From f5b880515e23182f52f1cfe4339bd28f9a2ea554 Mon Sep 17 00:00:00 2001 From: lovasoa Date: Tue, 25 Nov 2025 00:26:34 +0100 Subject: [PATCH 2/5] move more tests to the new expected/actual format --- tests/core/mod.rs | 11 +++-- tests/core/select_temp_t.sql | 2 +- tests/data_formats/mod.rs | 16 +++++-- tests/server_timing/mod.rs | 6 +-- tests/sql_test_files/README.md | 26 +++++----- ...s_function_arguments_are_not_supported.sql | 0 ..._used_after_data_has_already_been_sent.sql | 0 .../error_failed_to_import_the_csv.sql | 0 ...rror_invalid_json_in_dynamic_component.sql | 0 .../error_single_shell_per_page.sql | 0 ...ic_component_requires_a_property_named.sql | 0 .../error_too_many_nested_inclusions.sql | 4 ++ .../error_unknown_field.sql | 0 ...umns_component_json_nomssql_nopostgres.sql | 0 ...works_deeply_nested_dynamic_components.sql | 0 .../it_works_default_component.sql | 0 .../it_works_download_base64.sql | 0 .../it_works_download_raw.sql | 0 .../it_works_dynamic_nested.sql | 0 .../it_works_dynamic_repeated_properties.sql | 0 .../it_works_dynamic_run_sql_include.sql | 2 + .../it_works_dynamic_shell.sql | 0 .../it_works_dynamic_toplevel.sql | 0 .../it_works_log.sql | 0 .../it_works_markdown_in_table.sql | 0 .../component_rendering/it_works_run_sql.sql | 2 + .../it_works_run_sql_from_database.sql | 0 .../it_works_run_sql_variable_access.sql | 0 .../it_works_shell_search.sql | 0 .../it_works_simple.sql | 0 ...mp_table_accessible_in_run_sql_nomssql.sql | 0 .../it_works_text_markdown.sql | 0 .../it_works_text_unsafe_markdown.sql | 0 .../it_works_without_a_shell.sql | 0 .../it_works_basic_auth_password.sql | 0 .../it_works_basic_auth_username.sql | 0 .../{ => data}/it_works_case_variables.sql | 4 +- .../data/it_works_client_ip.sql | 2 + .../{ => data}/it_works_coalesce_eval.sql | 0 .../it_works_concat_str_in_pseudofunction.sql | 0 .../{ => data}/it_works_cookie.sql | 0 .../{ => data}/it_works_create_table.sql | 3 +- .../{ => data}/it_works_decimal.sql | 0 .../it_works_delayed_function_call.sql | 4 +- .../data/it_works_env_var_empty.sql | 2 + tests/sql_test_files/data/it_works_exec.sql | 2 + .../data/it_works_fetch_base64.sql | 6 +++ .../data/it_works_fetch_hex.sql | 6 +++ .../it_works_fetch_native_json_array_impl.sql | 10 +--- .../{ => data}/it_works_fetch_post.sql | 10 +--- .../data/it_works_fetch_simple.sql | 4 ++ .../it_works_fetch_with_meta_error.sql | 0 .../it_works_fetch_with_meta_simple.sql | 0 .../data/it_works_hash_password.sql | 2 + .../it_works_hash_password_null.sql | 0 .../{ => data}/it_works_header.sql | 0 .../{ => data}/it_works_headers.sql | 0 .../data/it_works_hmac_base64.sql | 2 + .../data/it_works_hmac_default.sql | 2 + .../data/it_works_hmac_sha256.sql | 2 + .../data/it_works_hmac_sha512.sql | 2 + .../data/it_works_hmac_shopify_webhook.sql | 7 +++ .../data/it_works_immutable_variables.sql | 10 ++++ .../{ => data}/it_works_link.sql | 0 .../{ => data}/it_works_link_null.sql | 0 .../{ => data}/it_works_lower.sql | 3 +- .../it_works_nested_sqlpage_functions.sql | 0 tests/sql_test_files/data/it_works_path.sql | 2 + .../it_works_postgres_cast_syntax.sql | 0 .../sql_test_files/data/it_works_protocol.sql | 2 + .../{ => data}/it_works_query_string.sql | 0 .../{ => data}/it_works_random_string.sql | 0 .../data/it_works_read_file_as_data_url.sql | 3 ++ .../data/it_works_read_file_as_text.sql | 2 + .../data/it_works_request_method.sql | 3 ++ .../sql_test_files/data/it_works_set_case.sql | 2 + .../data/it_works_set_variable.sql | 3 ++ .../{ => data}/it_works_set_variable_func.sql | 0 .../it_works_set_variable_func_null.sql | 0 .../it_works_set_variable_func_replace.sql | 0 .../it_works_set_variable_large_integer.sql | 0 .../data/it_works_set_variable_numeric.sql | 3 ++ .../data/it_works_set_variable_to_null.sql | 3 ++ ...t_works_set_variable_to_other_variable.sql | 0 ...works_set_variable_to_sqlpage_function.sql | 3 ++ ..._set_variable_to_sqlpage_post_function.sql | 3 ++ .../data/it_works_sqlite_unicode_upper.sql | 3 ++ .../{ => data}/it_works_sqrt.sql | 0 .../data/it_works_uploaded_file_is_null.sql | 3 ++ .../data/it_works_url_encode.sql | 2 + .../{ => data}/it_works_varchar_nomysql.sql | 3 +- .../data/it_works_variables_function.sql | 2 + ..._works_variables_function_get_and_post.sql | 2 + .../error_too_many_nested_inclusions.sql | 4 -- tests/sql_test_files/it_works_client_ip.sql | 4 -- .../it_works_dynamic_run_sql_include.sql | 1 - .../sql_test_files/it_works_env_var_empty.sql | 1 - tests/sql_test_files/it_works_exec.sql | 1 - .../sql_test_files/it_works_fetch_base64.sql | 9 ---- tests/sql_test_files/it_works_fetch_hex.sql | 9 ---- .../sql_test_files/it_works_fetch_simple.sql | 7 --- .../sql_test_files/it_works_hash_password.sql | 1 - tests/sql_test_files/it_works_hmac_base64.sql | 6 --- .../sql_test_files/it_works_hmac_default.sql | 5 -- tests/sql_test_files/it_works_hmac_sha256.sql | 5 -- tests/sql_test_files/it_works_hmac_sha512.sql | 5 -- .../it_works_hmac_shopify_webhook.sql | 15 ------ .../it_works_immutable_variables.sql | 31 ------------ tests/sql_test_files/it_works_path.sql | 6 --- tests/sql_test_files/it_works_protocol.sql | 6 --- .../it_works_read_file_as_data_url.sql | 12 ----- .../it_works_read_file_as_text.sql | 1 - .../it_works_request_method.sql | 12 ----- tests/sql_test_files/it_works_run_sql.sql | 1 - tests/sql_test_files/it_works_set_case.sql | 2 - .../sql_test_files/it_works_set_variable.sql | 2 - .../it_works_set_variable_numeric.sql | 9 ---- .../it_works_set_variable_to_null.sql | 9 ---- ...works_set_variable_to_sqlpage_function.sql | 7 --- ..._set_variable_to_sqlpage_post_function.sql | 7 --- .../it_works_sqlite_unicode_upper.sql | 6 --- .../it_works_uploaded_file_is_null.sql | 7 --- tests/sql_test_files/it_works_url_encode.sql | 6 --- .../it_works_variables_function.sql | 6 --- ..._works_variables_function_get_and_post.sql | 6 --- tests/sql_test_files/mod.rs | 48 +++++++++++++++---- tests/sql_test_files/select_temp_t.sql | 2 +- tests/transactions/mod.rs | 8 ++-- 128 files changed, 193 insertions(+), 270 deletions(-) rename tests/sql_test_files/{ => component_rendering}/error_arbitrary_SQL_expressions_as_function_arguments_are_not_supported.sql (100%) rename tests/sql_test_files/{ => component_rendering}/error_cookie_component_cannot_be_used_after_data_has_already_been_sent.sql (100%) rename tests/sql_test_files/{ => component_rendering}/error_failed_to_import_the_csv.sql (100%) rename tests/sql_test_files/{ => component_rendering}/error_invalid_json_in_dynamic_component.sql (100%) rename tests/sql_test_files/{ => component_rendering}/error_single_shell_per_page.sql (100%) rename tests/sql_test_files/{ => component_rendering}/error_the_dynamic_component_requires_a_property_named.sql (100%) create mode 100644 tests/sql_test_files/component_rendering/error_too_many_nested_inclusions.sql rename tests/sql_test_files/{ => component_rendering}/error_unknown_field.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_columns_component_json_nomssql_nopostgres.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_deeply_nested_dynamic_components.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_default_component.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_download_base64.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_download_raw.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_dynamic_nested.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_dynamic_repeated_properties.sql (100%) create mode 100644 tests/sql_test_files/component_rendering/it_works_dynamic_run_sql_include.sql rename tests/sql_test_files/{ => component_rendering}/it_works_dynamic_shell.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_dynamic_toplevel.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_log.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_markdown_in_table.sql (100%) create mode 100644 tests/sql_test_files/component_rendering/it_works_run_sql.sql rename tests/sql_test_files/{ => component_rendering}/it_works_run_sql_from_database.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_run_sql_variable_access.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_shell_search.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_simple.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_temp_table_accessible_in_run_sql_nomssql.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_text_markdown.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_text_unsafe_markdown.sql (100%) rename tests/sql_test_files/{ => component_rendering}/it_works_without_a_shell.sql (100%) rename tests/sql_test_files/{ => data}/it_works_basic_auth_password.sql (100%) rename tests/sql_test_files/{ => data}/it_works_basic_auth_username.sql (100%) rename tests/sql_test_files/{ => data}/it_works_case_variables.sql (80%) create mode 100644 tests/sql_test_files/data/it_works_client_ip.sql rename tests/sql_test_files/{ => data}/it_works_coalesce_eval.sql (100%) rename tests/sql_test_files/{ => data}/it_works_concat_str_in_pseudofunction.sql (100%) rename tests/sql_test_files/{ => data}/it_works_cookie.sql (100%) rename tests/sql_test_files/{ => data}/it_works_create_table.sql (65%) rename tests/sql_test_files/{ => data}/it_works_decimal.sql (100%) rename tests/sql_test_files/{ => data}/it_works_delayed_function_call.sql (59%) create mode 100644 tests/sql_test_files/data/it_works_env_var_empty.sql create mode 100644 tests/sql_test_files/data/it_works_exec.sql create mode 100644 tests/sql_test_files/data/it_works_fetch_base64.sql create mode 100644 tests/sql_test_files/data/it_works_fetch_hex.sql rename tests/sql_test_files/{ => data}/it_works_fetch_native_json_array_impl.sql (70%) rename tests/sql_test_files/{ => data}/it_works_fetch_post.sql (66%) create mode 100644 tests/sql_test_files/data/it_works_fetch_simple.sql rename tests/sql_test_files/{ => data}/it_works_fetch_with_meta_error.sql (100%) rename tests/sql_test_files/{ => data}/it_works_fetch_with_meta_simple.sql (100%) create mode 100644 tests/sql_test_files/data/it_works_hash_password.sql rename tests/sql_test_files/{ => data}/it_works_hash_password_null.sql (100%) rename tests/sql_test_files/{ => data}/it_works_header.sql (100%) rename tests/sql_test_files/{ => data}/it_works_headers.sql (100%) create mode 100644 tests/sql_test_files/data/it_works_hmac_base64.sql create mode 100644 tests/sql_test_files/data/it_works_hmac_default.sql create mode 100644 tests/sql_test_files/data/it_works_hmac_sha256.sql create mode 100644 tests/sql_test_files/data/it_works_hmac_sha512.sql create mode 100644 tests/sql_test_files/data/it_works_hmac_shopify_webhook.sql create mode 100644 tests/sql_test_files/data/it_works_immutable_variables.sql rename tests/sql_test_files/{ => data}/it_works_link.sql (100%) rename tests/sql_test_files/{ => data}/it_works_link_null.sql (100%) rename tests/sql_test_files/{ => data}/it_works_lower.sql (58%) rename tests/sql_test_files/{ => data}/it_works_nested_sqlpage_functions.sql (100%) create mode 100644 tests/sql_test_files/data/it_works_path.sql rename tests/sql_test_files/{ => data}/it_works_postgres_cast_syntax.sql (100%) create mode 100644 tests/sql_test_files/data/it_works_protocol.sql rename tests/sql_test_files/{ => data}/it_works_query_string.sql (100%) rename tests/sql_test_files/{ => data}/it_works_random_string.sql (100%) create mode 100644 tests/sql_test_files/data/it_works_read_file_as_data_url.sql create mode 100644 tests/sql_test_files/data/it_works_read_file_as_text.sql create mode 100644 tests/sql_test_files/data/it_works_request_method.sql create mode 100644 tests/sql_test_files/data/it_works_set_case.sql create mode 100644 tests/sql_test_files/data/it_works_set_variable.sql rename tests/sql_test_files/{ => data}/it_works_set_variable_func.sql (100%) rename tests/sql_test_files/{ => data}/it_works_set_variable_func_null.sql (100%) rename tests/sql_test_files/{ => data}/it_works_set_variable_func_replace.sql (100%) rename tests/sql_test_files/{ => data}/it_works_set_variable_large_integer.sql (100%) create mode 100644 tests/sql_test_files/data/it_works_set_variable_numeric.sql create mode 100644 tests/sql_test_files/data/it_works_set_variable_to_null.sql rename tests/sql_test_files/{ => data}/it_works_set_variable_to_other_variable.sql (100%) create mode 100644 tests/sql_test_files/data/it_works_set_variable_to_sqlpage_function.sql create mode 100644 tests/sql_test_files/data/it_works_set_variable_to_sqlpage_post_function.sql create mode 100644 tests/sql_test_files/data/it_works_sqlite_unicode_upper.sql rename tests/sql_test_files/{ => data}/it_works_sqrt.sql (100%) create mode 100644 tests/sql_test_files/data/it_works_uploaded_file_is_null.sql create mode 100644 tests/sql_test_files/data/it_works_url_encode.sql rename tests/sql_test_files/{ => data}/it_works_varchar_nomysql.sql (50%) create mode 100644 tests/sql_test_files/data/it_works_variables_function.sql create mode 100644 tests/sql_test_files/data/it_works_variables_function_get_and_post.sql delete mode 100644 tests/sql_test_files/error_too_many_nested_inclusions.sql delete mode 100644 tests/sql_test_files/it_works_client_ip.sql delete mode 100644 tests/sql_test_files/it_works_dynamic_run_sql_include.sql delete mode 100644 tests/sql_test_files/it_works_env_var_empty.sql delete mode 100644 tests/sql_test_files/it_works_exec.sql delete mode 100644 tests/sql_test_files/it_works_fetch_base64.sql delete mode 100644 tests/sql_test_files/it_works_fetch_hex.sql delete mode 100644 tests/sql_test_files/it_works_fetch_simple.sql delete mode 100644 tests/sql_test_files/it_works_hash_password.sql delete mode 100644 tests/sql_test_files/it_works_hmac_base64.sql delete mode 100644 tests/sql_test_files/it_works_hmac_default.sql delete mode 100644 tests/sql_test_files/it_works_hmac_sha256.sql delete mode 100644 tests/sql_test_files/it_works_hmac_sha512.sql delete mode 100644 tests/sql_test_files/it_works_hmac_shopify_webhook.sql delete mode 100644 tests/sql_test_files/it_works_immutable_variables.sql delete mode 100644 tests/sql_test_files/it_works_path.sql delete mode 100644 tests/sql_test_files/it_works_protocol.sql delete mode 100644 tests/sql_test_files/it_works_read_file_as_data_url.sql delete mode 100644 tests/sql_test_files/it_works_read_file_as_text.sql delete mode 100644 tests/sql_test_files/it_works_request_method.sql delete mode 100644 tests/sql_test_files/it_works_run_sql.sql delete mode 100644 tests/sql_test_files/it_works_set_case.sql delete mode 100644 tests/sql_test_files/it_works_set_variable.sql delete mode 100644 tests/sql_test_files/it_works_set_variable_numeric.sql delete mode 100644 tests/sql_test_files/it_works_set_variable_to_null.sql delete mode 100644 tests/sql_test_files/it_works_set_variable_to_sqlpage_function.sql delete mode 100644 tests/sql_test_files/it_works_set_variable_to_sqlpage_post_function.sql delete mode 100644 tests/sql_test_files/it_works_sqlite_unicode_upper.sql delete mode 100644 tests/sql_test_files/it_works_uploaded_file_is_null.sql delete mode 100644 tests/sql_test_files/it_works_url_encode.sql delete mode 100644 tests/sql_test_files/it_works_variables_function.sql delete mode 100644 tests/sql_test_files/it_works_variables_function_get_and_post.sql diff --git a/tests/core/mod.rs b/tests/core/mod.rs index 70f552e4..155db764 100644 --- a/tests/core/mod.rs +++ b/tests/core/mod.rs @@ -88,7 +88,7 @@ async fn test_routing_with_prefix() { let app_data = actix_web::web::Data::new(state); let resp = req_path_with_app_data( - "/prefix/tests/sql_test_files/it_works_simple.sql", + "/prefix/tests/sql_test_files/component_rendering/it_works_simple.sql", app_data.clone(), ) .await @@ -121,9 +121,12 @@ async fn test_routing_with_prefix() { .to_string(); assert!(resp.to_lowercase().contains("forbidden"), "{resp}"); - let resp = req_path_with_app_data("/tests/sql_test_files/it_works_simple.sql", app_data) - .await - .unwrap(); + let resp = req_path_with_app_data( + "/tests/sql_test_files/component_rendering/it_works_simple.sql", + app_data, + ) + .await + .unwrap(); assert_eq!(resp.status(), StatusCode::MOVED_PERMANENTLY); let location = resp .headers() diff --git a/tests/core/select_temp_t.sql b/tests/core/select_temp_t.sql index ec74c193..2626f436 100644 --- a/tests/core/select_temp_t.sql +++ b/tests/core/select_temp_t.sql @@ -1,2 +1,2 @@ --- see tests/sql_test_files/it_works_temp_table_accessible_in_run_sql.sql +-- see tests/sql_test_files/component_rendering/it_works_temp_table_accessible_in_run_sql_nomssql.sql select 'text' as component, x as contents from temp_t; \ No newline at end of file diff --git a/tests/data_formats/mod.rs b/tests/data_formats/mod.rs index 1416f0f0..5f9b8d39 100644 --- a/tests/data_formats/mod.rs +++ b/tests/data_formats/mod.rs @@ -96,7 +96,7 @@ async fn test_json_columns() { #[actix_web::test] async fn test_accept_json_returns_json_array() -> actix_web::Result<()> { let resp = req_with_accept( - "/tests/sql_test_files/it_works_simple.sql", + "/tests/sql_test_files/component_rendering/it_works_simple.sql", "application/json", ) .await?; @@ -117,7 +117,7 @@ async fn test_accept_json_returns_json_array() -> actix_web::Result<()> { #[actix_web::test] async fn test_accept_ndjson_returns_jsonlines() -> actix_web::Result<()> { let resp = req_with_accept( - "/tests/sql_test_files/it_works_simple.sql", + "/tests/sql_test_files/component_rendering/it_works_simple.sql", "application/x-ndjson", ) .await?; @@ -143,7 +143,11 @@ async fn test_accept_ndjson_returns_jsonlines() -> actix_web::Result<()> { #[actix_web::test] async fn test_accept_html_returns_html() -> actix_web::Result<()> { - let resp = req_with_accept("/tests/sql_test_files/it_works_simple.sql", "text/html").await?; + let resp = req_with_accept( + "/tests/sql_test_files/component_rendering/it_works_simple.sql", + "text/html", + ) + .await?; assert_eq!(resp.status(), StatusCode::OK); assert_eq!( resp.headers().get(header::CONTENT_TYPE).unwrap(), @@ -156,7 +160,11 @@ async fn test_accept_html_returns_html() -> actix_web::Result<()> { #[actix_web::test] async fn test_accept_wildcard_returns_html() -> actix_web::Result<()> { - let resp = req_with_accept("/tests/sql_test_files/it_works_simple.sql", "*/*").await?; + let resp = req_with_accept( + "/tests/sql_test_files/component_rendering/it_works_simple.sql", + "*/*", + ) + .await?; assert_eq!(resp.status(), StatusCode::OK); assert_eq!( resp.headers().get(header::CONTENT_TYPE).unwrap(), diff --git a/tests/server_timing/mod.rs b/tests/server_timing/mod.rs index d380c7e5..05d07757 100644 --- a/tests/server_timing/mod.rs +++ b/tests/server_timing/mod.rs @@ -10,7 +10,7 @@ async fn test_server_timing_disabled_in_production() -> actix_web::Result<()> { let app_data = make_app_data_from_config(config).await; let req = crate::common::get_request_to_with_data( - "/tests/sql_test_files/it_works_simple.sql", + "/tests/sql_test_files/component_rendering/it_works_simple.sql", app_data, ) .await? @@ -32,7 +32,7 @@ async fn test_server_timing_enabled_in_development() -> actix_web::Result<()> { let app_data = make_app_data_from_config(config).await; let req = crate::common::get_request_to_with_data( - "/tests/sql_test_files/it_works_postgres_cast_syntax.sql", + "/tests/sql_test_files/data/it_works_postgres_cast_syntax.sql", app_data, ) .await? @@ -72,7 +72,7 @@ async fn test_server_timing_enabled_in_development() -> actix_web::Result<()> { #[actix_web::test] async fn test_server_timing_format() -> actix_web::Result<()> { - let req = get_request_to("/tests/sql_test_files/it_works_postgres_cast_syntax.sql") + let req = get_request_to("/tests/sql_test_files/data/it_works_postgres_cast_syntax.sql") .await? .to_srv_request(); let resp = main_handler(req).await?; diff --git a/tests/sql_test_files/README.md b/tests/sql_test_files/README.md index a3447f4e..51b1acea 100644 --- a/tests/sql_test_files/README.md +++ b/tests/sql_test_files/README.md @@ -1,16 +1,18 @@ -The sql files in this folder are all tested automatically. +The sql files in this folder are all tested automatically. They are organized in +two subdirectories: -## `it_works_` files +## `component_rendering/` -Files with names starting with `it_works` should all -return a page that contains the text "It works !" and does not contain the -text "error" (case insensitive) when executed. +Files that depend on SQLPage's HTML rendering (components, shells, redirects, +etc.). `it_works_` files in this directory must render a page that contains the +text "It works !" and no occurrence of the word "error" (case insensitive). +`error_` files should return a page containing the word "error" and the rest of +the file name. Files may include `nosqlite`, `nomssql`, `nopostgres` or +`nomysql` in their name to skip incompatible backends. -If a file name contains `nosqlite`, `nomssql`, `nopostgres` or `nomysql`, then -the test will be ignored when running against the corresponding database. -This allows using syntax that is not supported on all databases in some tests. +## `data/` -## `error_` files - -Files with names starting with `error` should all return a page that contains -the text "error" and the rest of the file name when executed. \ No newline at end of file +Files that only validate data-processing functions should live here. They must +return rows with an `actual` column plus either `expected` (exact match) or +`expected_contains` (substring match). Tests in this directory are fetched as +JSON and validated row by row. \ No newline at end of file diff --git a/tests/sql_test_files/error_arbitrary_SQL_expressions_as_function_arguments_are_not_supported.sql b/tests/sql_test_files/component_rendering/error_arbitrary_SQL_expressions_as_function_arguments_are_not_supported.sql similarity index 100% rename from tests/sql_test_files/error_arbitrary_SQL_expressions_as_function_arguments_are_not_supported.sql rename to tests/sql_test_files/component_rendering/error_arbitrary_SQL_expressions_as_function_arguments_are_not_supported.sql diff --git a/tests/sql_test_files/error_cookie_component_cannot_be_used_after_data_has_already_been_sent.sql b/tests/sql_test_files/component_rendering/error_cookie_component_cannot_be_used_after_data_has_already_been_sent.sql similarity index 100% rename from tests/sql_test_files/error_cookie_component_cannot_be_used_after_data_has_already_been_sent.sql rename to tests/sql_test_files/component_rendering/error_cookie_component_cannot_be_used_after_data_has_already_been_sent.sql diff --git a/tests/sql_test_files/error_failed_to_import_the_csv.sql b/tests/sql_test_files/component_rendering/error_failed_to_import_the_csv.sql similarity index 100% rename from tests/sql_test_files/error_failed_to_import_the_csv.sql rename to tests/sql_test_files/component_rendering/error_failed_to_import_the_csv.sql diff --git a/tests/sql_test_files/error_invalid_json_in_dynamic_component.sql b/tests/sql_test_files/component_rendering/error_invalid_json_in_dynamic_component.sql similarity index 100% rename from tests/sql_test_files/error_invalid_json_in_dynamic_component.sql rename to tests/sql_test_files/component_rendering/error_invalid_json_in_dynamic_component.sql diff --git a/tests/sql_test_files/error_single_shell_per_page.sql b/tests/sql_test_files/component_rendering/error_single_shell_per_page.sql similarity index 100% rename from tests/sql_test_files/error_single_shell_per_page.sql rename to tests/sql_test_files/component_rendering/error_single_shell_per_page.sql diff --git a/tests/sql_test_files/error_the_dynamic_component_requires_a_property_named.sql b/tests/sql_test_files/component_rendering/error_the_dynamic_component_requires_a_property_named.sql similarity index 100% rename from tests/sql_test_files/error_the_dynamic_component_requires_a_property_named.sql rename to tests/sql_test_files/component_rendering/error_the_dynamic_component_requires_a_property_named.sql diff --git a/tests/sql_test_files/component_rendering/error_too_many_nested_inclusions.sql b/tests/sql_test_files/component_rendering/error_too_many_nested_inclusions.sql new file mode 100644 index 00000000..c35c0322 --- /dev/null +++ b/tests/sql_test_files/component_rendering/error_too_many_nested_inclusions.sql @@ -0,0 +1,4 @@ +select 'debug' as component, + sqlpage.run_sql( + 'tests/sql_test_files/component_rendering/error_too_many_nested_inclusions.sql' + ) as contents; \ No newline at end of file diff --git a/tests/sql_test_files/error_unknown_field.sql b/tests/sql_test_files/component_rendering/error_unknown_field.sql similarity index 100% rename from tests/sql_test_files/error_unknown_field.sql rename to tests/sql_test_files/component_rendering/error_unknown_field.sql diff --git a/tests/sql_test_files/it_works_columns_component_json_nomssql_nopostgres.sql b/tests/sql_test_files/component_rendering/it_works_columns_component_json_nomssql_nopostgres.sql similarity index 100% rename from tests/sql_test_files/it_works_columns_component_json_nomssql_nopostgres.sql rename to tests/sql_test_files/component_rendering/it_works_columns_component_json_nomssql_nopostgres.sql diff --git a/tests/sql_test_files/it_works_deeply_nested_dynamic_components.sql b/tests/sql_test_files/component_rendering/it_works_deeply_nested_dynamic_components.sql similarity index 100% rename from tests/sql_test_files/it_works_deeply_nested_dynamic_components.sql rename to tests/sql_test_files/component_rendering/it_works_deeply_nested_dynamic_components.sql diff --git a/tests/sql_test_files/it_works_default_component.sql b/tests/sql_test_files/component_rendering/it_works_default_component.sql similarity index 100% rename from tests/sql_test_files/it_works_default_component.sql rename to tests/sql_test_files/component_rendering/it_works_default_component.sql diff --git a/tests/sql_test_files/it_works_download_base64.sql b/tests/sql_test_files/component_rendering/it_works_download_base64.sql similarity index 100% rename from tests/sql_test_files/it_works_download_base64.sql rename to tests/sql_test_files/component_rendering/it_works_download_base64.sql diff --git a/tests/sql_test_files/it_works_download_raw.sql b/tests/sql_test_files/component_rendering/it_works_download_raw.sql similarity index 100% rename from tests/sql_test_files/it_works_download_raw.sql rename to tests/sql_test_files/component_rendering/it_works_download_raw.sql diff --git a/tests/sql_test_files/it_works_dynamic_nested.sql b/tests/sql_test_files/component_rendering/it_works_dynamic_nested.sql similarity index 100% rename from tests/sql_test_files/it_works_dynamic_nested.sql rename to tests/sql_test_files/component_rendering/it_works_dynamic_nested.sql diff --git a/tests/sql_test_files/it_works_dynamic_repeated_properties.sql b/tests/sql_test_files/component_rendering/it_works_dynamic_repeated_properties.sql similarity index 100% rename from tests/sql_test_files/it_works_dynamic_repeated_properties.sql rename to tests/sql_test_files/component_rendering/it_works_dynamic_repeated_properties.sql diff --git a/tests/sql_test_files/component_rendering/it_works_dynamic_run_sql_include.sql b/tests/sql_test_files/component_rendering/it_works_dynamic_run_sql_include.sql new file mode 100644 index 00000000..d4fd9fde --- /dev/null +++ b/tests/sql_test_files/component_rendering/it_works_dynamic_run_sql_include.sql @@ -0,0 +1,2 @@ +select 'dynamic' as component, + sqlpage.run_sql('tests/sql_test_files/component_rendering/it_works_dynamic_shell.sql') as properties; diff --git a/tests/sql_test_files/it_works_dynamic_shell.sql b/tests/sql_test_files/component_rendering/it_works_dynamic_shell.sql similarity index 100% rename from tests/sql_test_files/it_works_dynamic_shell.sql rename to tests/sql_test_files/component_rendering/it_works_dynamic_shell.sql diff --git a/tests/sql_test_files/it_works_dynamic_toplevel.sql b/tests/sql_test_files/component_rendering/it_works_dynamic_toplevel.sql similarity index 100% rename from tests/sql_test_files/it_works_dynamic_toplevel.sql rename to tests/sql_test_files/component_rendering/it_works_dynamic_toplevel.sql diff --git a/tests/sql_test_files/it_works_log.sql b/tests/sql_test_files/component_rendering/it_works_log.sql similarity index 100% rename from tests/sql_test_files/it_works_log.sql rename to tests/sql_test_files/component_rendering/it_works_log.sql diff --git a/tests/sql_test_files/it_works_markdown_in_table.sql b/tests/sql_test_files/component_rendering/it_works_markdown_in_table.sql similarity index 100% rename from tests/sql_test_files/it_works_markdown_in_table.sql rename to tests/sql_test_files/component_rendering/it_works_markdown_in_table.sql diff --git a/tests/sql_test_files/component_rendering/it_works_run_sql.sql b/tests/sql_test_files/component_rendering/it_works_run_sql.sql new file mode 100644 index 00000000..434f146a --- /dev/null +++ b/tests/sql_test_files/component_rendering/it_works_run_sql.sql @@ -0,0 +1,2 @@ +select 'dynamic' as component, + sqlpage.run_sql('tests/sql_test_files/component_rendering/it_works_simple.sql') as properties; diff --git a/tests/sql_test_files/it_works_run_sql_from_database.sql b/tests/sql_test_files/component_rendering/it_works_run_sql_from_database.sql similarity index 100% rename from tests/sql_test_files/it_works_run_sql_from_database.sql rename to tests/sql_test_files/component_rendering/it_works_run_sql_from_database.sql diff --git a/tests/sql_test_files/it_works_run_sql_variable_access.sql b/tests/sql_test_files/component_rendering/it_works_run_sql_variable_access.sql similarity index 100% rename from tests/sql_test_files/it_works_run_sql_variable_access.sql rename to tests/sql_test_files/component_rendering/it_works_run_sql_variable_access.sql diff --git a/tests/sql_test_files/it_works_shell_search.sql b/tests/sql_test_files/component_rendering/it_works_shell_search.sql similarity index 100% rename from tests/sql_test_files/it_works_shell_search.sql rename to tests/sql_test_files/component_rendering/it_works_shell_search.sql diff --git a/tests/sql_test_files/it_works_simple.sql b/tests/sql_test_files/component_rendering/it_works_simple.sql similarity index 100% rename from tests/sql_test_files/it_works_simple.sql rename to tests/sql_test_files/component_rendering/it_works_simple.sql diff --git a/tests/sql_test_files/it_works_temp_table_accessible_in_run_sql_nomssql.sql b/tests/sql_test_files/component_rendering/it_works_temp_table_accessible_in_run_sql_nomssql.sql similarity index 100% rename from tests/sql_test_files/it_works_temp_table_accessible_in_run_sql_nomssql.sql rename to tests/sql_test_files/component_rendering/it_works_temp_table_accessible_in_run_sql_nomssql.sql diff --git a/tests/sql_test_files/it_works_text_markdown.sql b/tests/sql_test_files/component_rendering/it_works_text_markdown.sql similarity index 100% rename from tests/sql_test_files/it_works_text_markdown.sql rename to tests/sql_test_files/component_rendering/it_works_text_markdown.sql diff --git a/tests/sql_test_files/it_works_text_unsafe_markdown.sql b/tests/sql_test_files/component_rendering/it_works_text_unsafe_markdown.sql similarity index 100% rename from tests/sql_test_files/it_works_text_unsafe_markdown.sql rename to tests/sql_test_files/component_rendering/it_works_text_unsafe_markdown.sql diff --git a/tests/sql_test_files/it_works_without_a_shell.sql b/tests/sql_test_files/component_rendering/it_works_without_a_shell.sql similarity index 100% rename from tests/sql_test_files/it_works_without_a_shell.sql rename to tests/sql_test_files/component_rendering/it_works_without_a_shell.sql diff --git a/tests/sql_test_files/it_works_basic_auth_password.sql b/tests/sql_test_files/data/it_works_basic_auth_password.sql similarity index 100% rename from tests/sql_test_files/it_works_basic_auth_password.sql rename to tests/sql_test_files/data/it_works_basic_auth_password.sql diff --git a/tests/sql_test_files/it_works_basic_auth_username.sql b/tests/sql_test_files/data/it_works_basic_auth_username.sql similarity index 100% rename from tests/sql_test_files/it_works_basic_auth_username.sql rename to tests/sql_test_files/data/it_works_basic_auth_username.sql diff --git a/tests/sql_test_files/it_works_case_variables.sql b/tests/sql_test_files/data/it_works_case_variables.sql similarity index 80% rename from tests/sql_test_files/it_works_case_variables.sql rename to tests/sql_test_files/data/it_works_case_variables.sql index 44d68510..7733ac01 100644 --- a/tests/sql_test_files/it_works_case_variables.sql +++ b/tests/sql_test_files/data/it_works_case_variables.sql @@ -3,8 +3,8 @@ set success = 'It works !'; set failure = 'You should never see this'; -select 'text' as component, +select 'It works !' as expected, case $success when $success then $success when $failure then $failure - end AS contents; \ No newline at end of file + end as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_client_ip.sql b/tests/sql_test_files/data/it_works_client_ip.sql new file mode 100644 index 00000000..918f8663 --- /dev/null +++ b/tests/sql_test_files/data/it_works_client_ip.sql @@ -0,0 +1,2 @@ +select 'NULL' as expected, + coalesce(sqlpage.client_ip(), 'NULL') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_coalesce_eval.sql b/tests/sql_test_files/data/it_works_coalesce_eval.sql similarity index 100% rename from tests/sql_test_files/it_works_coalesce_eval.sql rename to tests/sql_test_files/data/it_works_coalesce_eval.sql diff --git a/tests/sql_test_files/it_works_concat_str_in_pseudofunction.sql b/tests/sql_test_files/data/it_works_concat_str_in_pseudofunction.sql similarity index 100% rename from tests/sql_test_files/it_works_concat_str_in_pseudofunction.sql rename to tests/sql_test_files/data/it_works_concat_str_in_pseudofunction.sql diff --git a/tests/sql_test_files/it_works_cookie.sql b/tests/sql_test_files/data/it_works_cookie.sql similarity index 100% rename from tests/sql_test_files/it_works_cookie.sql rename to tests/sql_test_files/data/it_works_cookie.sql diff --git a/tests/sql_test_files/it_works_create_table.sql b/tests/sql_test_files/data/it_works_create_table.sql similarity index 65% rename from tests/sql_test_files/it_works_create_table.sql rename to tests/sql_test_files/data/it_works_create_table.sql index e3ec8f39..1bfb3ecb 100644 --- a/tests/sql_test_files/it_works_create_table.sql +++ b/tests/sql_test_files/data/it_works_create_table.sql @@ -3,5 +3,4 @@ create table my_tmp_store(x varchar(100)); insert into my_tmp_store(x) values ('It works !'); -select 'card' as component; -select x as description from my_tmp_store; \ No newline at end of file +select 'It works !' as expected, x as actual from my_tmp_store; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_decimal.sql b/tests/sql_test_files/data/it_works_decimal.sql similarity index 100% rename from tests/sql_test_files/it_works_decimal.sql rename to tests/sql_test_files/data/it_works_decimal.sql diff --git a/tests/sql_test_files/it_works_delayed_function_call.sql b/tests/sql_test_files/data/it_works_delayed_function_call.sql similarity index 59% rename from tests/sql_test_files/it_works_delayed_function_call.sql rename to tests/sql_test_files/data/it_works_delayed_function_call.sql index 30a9db51..57c15660 100644 --- a/tests/sql_test_files/it_works_delayed_function_call.sql +++ b/tests/sql_test_files/data/it_works_delayed_function_call.sql @@ -1,4 +1,6 @@ drop table if exists files_to_read; create table files_to_read(filepath varchar(100)); insert into files_to_read(filepath) values ('tests/it_works.txt'); -select 'text' as component, sqlpage.read_file_as_text(filepath) as contents from files_to_read; +select 'It works !' as expected, + sqlpage.read_file_as_text(filepath) as actual +from files_to_read; diff --git a/tests/sql_test_files/data/it_works_env_var_empty.sql b/tests/sql_test_files/data/it_works_env_var_empty.sql new file mode 100644 index 00000000..bd120ca3 --- /dev/null +++ b/tests/sql_test_files/data/it_works_env_var_empty.sql @@ -0,0 +1,2 @@ +select 'NULL' as expected, + coalesce(sqlpage.environment_variable('I_DO_NOT_EXIST'), 'NULL') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_exec.sql b/tests/sql_test_files/data/it_works_exec.sql new file mode 100644 index 00000000..cd04a5a4 --- /dev/null +++ b/tests/sql_test_files/data/it_works_exec.sql @@ -0,0 +1,2 @@ +select 'It works !' as expected_contains, + sqlpage.exec('echo', 'It', $thisisnull, 'works', '!') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_fetch_base64.sql b/tests/sql_test_files/data/it_works_fetch_base64.sql new file mode 100644 index 00000000..8bda27e4 --- /dev/null +++ b/tests/sql_test_files/data/it_works_fetch_base64.sql @@ -0,0 +1,6 @@ +set res = sqlpage.fetch('{ + "url": "http://localhost:' || $echo_port || '/hello_world", + "response_encoding": "base64" +}'); +select 'R0VUIC9oZWxsb193b3Js' as expected_contains, + $res as actual; diff --git a/tests/sql_test_files/data/it_works_fetch_hex.sql b/tests/sql_test_files/data/it_works_fetch_hex.sql new file mode 100644 index 00000000..f4eb1286 --- /dev/null +++ b/tests/sql_test_files/data/it_works_fetch_hex.sql @@ -0,0 +1,6 @@ +set res = sqlpage.fetch('{ + "url": "http://localhost:' || $echo_port || '/hello_world", + "response_encoding": "hex" +}'); +select '474554202f68656c6c6f5f776f726c64' as expected_contains, + $res as actual; diff --git a/tests/sql_test_files/it_works_fetch_native_json_array_impl.sql b/tests/sql_test_files/data/it_works_fetch_native_json_array_impl.sql similarity index 70% rename from tests/sql_test_files/it_works_fetch_native_json_array_impl.sql rename to tests/sql_test_files/data/it_works_fetch_native_json_array_impl.sql index 6e2c6e49..f98c56d9 100644 --- a/tests/sql_test_files/it_works_fetch_native_json_array_impl.sql +++ b/tests/sql_test_files/data/it_works_fetch_native_json_array_impl.sql @@ -6,11 +6,5 @@ set res = sqlpage.fetch(json_object( 'body', json_array('hello', 'world') )); set expected = 'POST /post|accept-encoding: br, gzip, deflate, zstd|content-length: 17|content-type: application/json|host: localhost:' || $echo_port || '|user-agent: sqlpage|x-custom: 1|["hello","world"]'; -select 'text' as component, - case $res - when $expected then 'It works !' - else 'It failed ! Expected: -' || $expected || ' -Got: -' || $res - end as contents; \ No newline at end of file +select $expected as expected, + $res as actual; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_fetch_post.sql b/tests/sql_test_files/data/it_works_fetch_post.sql similarity index 66% rename from tests/sql_test_files/it_works_fetch_post.sql rename to tests/sql_test_files/data/it_works_fetch_post.sql index 0503ec28..6c4c8bdb 100644 --- a/tests/sql_test_files/it_works_fetch_post.sql +++ b/tests/sql_test_files/data/it_works_fetch_post.sql @@ -2,11 +2,5 @@ set url = 'http://localhost:' || $echo_port || '/post'; set fetch_request = '{"method": "POST", "url": "' || $url || '", "headers": {"x-custom": "1"}, "body": {"hello": "world"}}'; set res = sqlpage.fetch($fetch_request); set expected = 'POST /post|accept-encoding: br, gzip, deflate, zstd|content-length: 18|content-type: application/json|host: localhost:' || $echo_port || '|user-agent: sqlpage|x-custom: 1|{"hello": "world"}'; -select 'text' as component, - case $res - when $expected then 'It works !' - else 'It failed ! Expected: -' || COALESCE($expected, 'null') || ' -Got: -' || COALESCE($res, 'null') - end as contents; \ No newline at end of file +select $expected as expected, + $res as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_fetch_simple.sql b/tests/sql_test_files/data/it_works_fetch_simple.sql new file mode 100644 index 00000000..3dd3f4d5 --- /dev/null +++ b/tests/sql_test_files/data/it_works_fetch_simple.sql @@ -0,0 +1,4 @@ +set url = 'http://localhost:' || $echo_port || '/hello_world'; +set res = sqlpage.fetch($url); +select 'GET /hello_world' as expected_contains, + $res as actual; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_fetch_with_meta_error.sql b/tests/sql_test_files/data/it_works_fetch_with_meta_error.sql similarity index 100% rename from tests/sql_test_files/it_works_fetch_with_meta_error.sql rename to tests/sql_test_files/data/it_works_fetch_with_meta_error.sql diff --git a/tests/sql_test_files/it_works_fetch_with_meta_simple.sql b/tests/sql_test_files/data/it_works_fetch_with_meta_simple.sql similarity index 100% rename from tests/sql_test_files/it_works_fetch_with_meta_simple.sql rename to tests/sql_test_files/data/it_works_fetch_with_meta_simple.sql diff --git a/tests/sql_test_files/data/it_works_hash_password.sql b/tests/sql_test_files/data/it_works_hash_password.sql new file mode 100644 index 00000000..42a9b40a --- /dev/null +++ b/tests/sql_test_files/data/it_works_hash_password.sql @@ -0,0 +1,2 @@ +select '$argon2id$' as expected_contains, + coalesce(sqlpage.hash_password($x), 'NULL') as actual; diff --git a/tests/sql_test_files/it_works_hash_password_null.sql b/tests/sql_test_files/data/it_works_hash_password_null.sql similarity index 100% rename from tests/sql_test_files/it_works_hash_password_null.sql rename to tests/sql_test_files/data/it_works_hash_password_null.sql diff --git a/tests/sql_test_files/it_works_header.sql b/tests/sql_test_files/data/it_works_header.sql similarity index 100% rename from tests/sql_test_files/it_works_header.sql rename to tests/sql_test_files/data/it_works_header.sql diff --git a/tests/sql_test_files/it_works_headers.sql b/tests/sql_test_files/data/it_works_headers.sql similarity index 100% rename from tests/sql_test_files/it_works_headers.sql rename to tests/sql_test_files/data/it_works_headers.sql diff --git a/tests/sql_test_files/data/it_works_hmac_base64.sql b/tests/sql_test_files/data/it_works_hmac_base64.sql new file mode 100644 index 00000000..d68a1c18 --- /dev/null +++ b/tests/sql_test_files/data/it_works_hmac_base64.sql @@ -0,0 +1,2 @@ +select '97yD9DBThCSxMpjmqm+xQ+9NWaFJRhdZl0edvC0aPNg=' as expected, + sqlpage.hmac('The quick brown fox jumps over the lazy dog', 'key', 'sha256-base64') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_hmac_default.sql b/tests/sql_test_files/data/it_works_hmac_default.sql new file mode 100644 index 00000000..f3420316 --- /dev/null +++ b/tests/sql_test_files/data/it_works_hmac_default.sql @@ -0,0 +1,2 @@ +select sqlpage.hmac('test data', 'test key', 'sha256') as expected, + sqlpage.hmac('test data', 'test key') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_hmac_sha256.sql b/tests/sql_test_files/data/it_works_hmac_sha256.sql new file mode 100644 index 00000000..f104bd8e --- /dev/null +++ b/tests/sql_test_files/data/it_works_hmac_sha256.sql @@ -0,0 +1,2 @@ +select 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8' as expected, + sqlpage.hmac('The quick brown fox jumps over the lazy dog', 'key', 'sha256') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_hmac_sha512.sql b/tests/sql_test_files/data/it_works_hmac_sha512.sql new file mode 100644 index 00000000..837f642e --- /dev/null +++ b/tests/sql_test_files/data/it_works_hmac_sha512.sql @@ -0,0 +1,2 @@ +select 'b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a' as expected, + sqlpage.hmac('The quick brown fox jumps over the lazy dog', 'key', 'sha512') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_hmac_shopify_webhook.sql b/tests/sql_test_files/data/it_works_hmac_shopify_webhook.sql new file mode 100644 index 00000000..552cccb9 --- /dev/null +++ b/tests/sql_test_files/data/it_works_hmac_shopify_webhook.sql @@ -0,0 +1,7 @@ +-- Test Shopify webhook HMAC validation with base64 output +select 'QNyObTlKbMx2qDlPF/ZOZcBqg5OgPg+2oky3zldc0Gw=' as expected, + sqlpage.hmac( + '{"id":1234567890,"email":"customer@example.com","total_price":"123.45"}', + 'test-webhook-secret', + 'sha256-base64' + ) as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_immutable_variables.sql b/tests/sql_test_files/data/it_works_immutable_variables.sql new file mode 100644 index 00000000..2fe3285c --- /dev/null +++ b/tests/sql_test_files/data/it_works_immutable_variables.sql @@ -0,0 +1,10 @@ +set x = 'set_value'; +set set_only = 'only_in_set'; + +select 'set_value' as expected, $x as actual; +select 'only_in_set' as expected, $set_only as actual; +select '{"x":"1"}' as expected, sqlpage.variables('get') as actual; +select '"x":"set_value"' as expected_contains, sqlpage.variables('set') as actual; +select '"set_only":"only_in_set"' as expected_contains, sqlpage.variables('set') as actual; +select '"x":"set_value"' as expected_contains, sqlpage.variables() as actual; +select '"set_only":"only_in_set"' as expected_contains, sqlpage.variables() as actual; diff --git a/tests/sql_test_files/it_works_link.sql b/tests/sql_test_files/data/it_works_link.sql similarity index 100% rename from tests/sql_test_files/it_works_link.sql rename to tests/sql_test_files/data/it_works_link.sql diff --git a/tests/sql_test_files/it_works_link_null.sql b/tests/sql_test_files/data/it_works_link_null.sql similarity index 100% rename from tests/sql_test_files/it_works_link_null.sql rename to tests/sql_test_files/data/it_works_link_null.sql diff --git a/tests/sql_test_files/it_works_lower.sql b/tests/sql_test_files/data/it_works_lower.sql similarity index 58% rename from tests/sql_test_files/it_works_lower.sql rename to tests/sql_test_files/data/it_works_lower.sql index 5ddfde56..9ce03244 100644 --- a/tests/sql_test_files/it_works_lower.sql +++ b/tests/sql_test_files/data/it_works_lower.sql @@ -1,3 +1,4 @@ -- in SQLite, we provide our own unicode-aware lower function -- see https://github.com/sqlpage/SQLPage/issues/452 -select 'text' as component, COALESCE(lower(NULL), 'It works !') AS contents; \ No newline at end of file +select 'It works !' as expected, + coalesce(lower(NULL), 'It works !') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_nested_sqlpage_functions.sql b/tests/sql_test_files/data/it_works_nested_sqlpage_functions.sql similarity index 100% rename from tests/sql_test_files/it_works_nested_sqlpage_functions.sql rename to tests/sql_test_files/data/it_works_nested_sqlpage_functions.sql diff --git a/tests/sql_test_files/data/it_works_path.sql b/tests/sql_test_files/data/it_works_path.sql new file mode 100644 index 00000000..23d4cc7e --- /dev/null +++ b/tests/sql_test_files/data/it_works_path.sql @@ -0,0 +1,2 @@ +select '/tests/sql_test_files/data/it_works_path.sql' as expected, + sqlpage.path() as actual; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_postgres_cast_syntax.sql b/tests/sql_test_files/data/it_works_postgres_cast_syntax.sql similarity index 100% rename from tests/sql_test_files/it_works_postgres_cast_syntax.sql rename to tests/sql_test_files/data/it_works_postgres_cast_syntax.sql diff --git a/tests/sql_test_files/data/it_works_protocol.sql b/tests/sql_test_files/data/it_works_protocol.sql new file mode 100644 index 00000000..ae6bbad7 --- /dev/null +++ b/tests/sql_test_files/data/it_works_protocol.sql @@ -0,0 +1,2 @@ +select 'http' as expected, + sqlpage.protocol() as actual; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_query_string.sql b/tests/sql_test_files/data/it_works_query_string.sql similarity index 100% rename from tests/sql_test_files/it_works_query_string.sql rename to tests/sql_test_files/data/it_works_query_string.sql diff --git a/tests/sql_test_files/it_works_random_string.sql b/tests/sql_test_files/data/it_works_random_string.sql similarity index 100% rename from tests/sql_test_files/it_works_random_string.sql rename to tests/sql_test_files/data/it_works_random_string.sql diff --git a/tests/sql_test_files/data/it_works_read_file_as_data_url.sql b/tests/sql_test_files/data/it_works_read_file_as_data_url.sql new file mode 100644 index 00000000..9aecf721 --- /dev/null +++ b/tests/sql_test_files/data/it_works_read_file_as_data_url.sql @@ -0,0 +1,3 @@ +set actual = sqlpage.read_file_as_data_url('tests/it_works.txt'); +select 'data:text/plain;base64,SXQgd29ya3MgIQ==' as expected, + coalesce($actual, 'NULL') as actual; diff --git a/tests/sql_test_files/data/it_works_read_file_as_text.sql b/tests/sql_test_files/data/it_works_read_file_as_text.sql new file mode 100644 index 00000000..bfb135b8 --- /dev/null +++ b/tests/sql_test_files/data/it_works_read_file_as_text.sql @@ -0,0 +1,2 @@ +select 'It works !' as expected, + sqlpage.read_file_as_text('tests/it_works.txt') as actual; diff --git a/tests/sql_test_files/data/it_works_request_method.sql b/tests/sql_test_files/data/it_works_request_method.sql new file mode 100644 index 00000000..fffb1337 --- /dev/null +++ b/tests/sql_test_files/data/it_works_request_method.sql @@ -0,0 +1,3 @@ +set actual = sqlpage.request_method(); +select 'GET' as expected, + coalesce($actual, 'NULL') as actual; diff --git a/tests/sql_test_files/data/it_works_set_case.sql b/tests/sql_test_files/data/it_works_set_case.sql new file mode 100644 index 00000000..8c573abc --- /dev/null +++ b/tests/sql_test_files/data/it_works_set_case.sql @@ -0,0 +1,2 @@ +set msg = case when 1=1 then 'It works !' else 'It failed !' end; +select 'It works !' as expected, $msg as actual; diff --git a/tests/sql_test_files/data/it_works_set_variable.sql b/tests/sql_test_files/data/it_works_set_variable.sql new file mode 100644 index 00000000..ba1bafe3 --- /dev/null +++ b/tests/sql_test_files/data/it_works_set_variable.sql @@ -0,0 +1,3 @@ +set what_does_it_do = 'wo' || 'rks'; +select 'It works !' as expected, + 'It ' || $what_does_it_do || ' !' as actual; diff --git a/tests/sql_test_files/it_works_set_variable_func.sql b/tests/sql_test_files/data/it_works_set_variable_func.sql similarity index 100% rename from tests/sql_test_files/it_works_set_variable_func.sql rename to tests/sql_test_files/data/it_works_set_variable_func.sql diff --git a/tests/sql_test_files/it_works_set_variable_func_null.sql b/tests/sql_test_files/data/it_works_set_variable_func_null.sql similarity index 100% rename from tests/sql_test_files/it_works_set_variable_func_null.sql rename to tests/sql_test_files/data/it_works_set_variable_func_null.sql diff --git a/tests/sql_test_files/it_works_set_variable_func_replace.sql b/tests/sql_test_files/data/it_works_set_variable_func_replace.sql similarity index 100% rename from tests/sql_test_files/it_works_set_variable_func_replace.sql rename to tests/sql_test_files/data/it_works_set_variable_func_replace.sql diff --git a/tests/sql_test_files/it_works_set_variable_large_integer.sql b/tests/sql_test_files/data/it_works_set_variable_large_integer.sql similarity index 100% rename from tests/sql_test_files/it_works_set_variable_large_integer.sql rename to tests/sql_test_files/data/it_works_set_variable_large_integer.sql diff --git a/tests/sql_test_files/data/it_works_set_variable_numeric.sql b/tests/sql_test_files/data/it_works_set_variable_numeric.sql new file mode 100644 index 00000000..60d25fbb --- /dev/null +++ b/tests/sql_test_files/data/it_works_set_variable_numeric.sql @@ -0,0 +1,3 @@ +set two = 2; +select '2' as expected, + $two as actual; diff --git a/tests/sql_test_files/data/it_works_set_variable_to_null.sql b/tests/sql_test_files/data/it_works_set_variable_to_null.sql new file mode 100644 index 00000000..24a8d818 --- /dev/null +++ b/tests/sql_test_files/data/it_works_set_variable_to_null.sql @@ -0,0 +1,3 @@ +set i_am_null = NULL; +select 'NULL' as expected, + coalesce($i_am_null, 'NULL') as actual; diff --git a/tests/sql_test_files/it_works_set_variable_to_other_variable.sql b/tests/sql_test_files/data/it_works_set_variable_to_other_variable.sql similarity index 100% rename from tests/sql_test_files/it_works_set_variable_to_other_variable.sql rename to tests/sql_test_files/data/it_works_set_variable_to_other_variable.sql diff --git a/tests/sql_test_files/data/it_works_set_variable_to_sqlpage_function.sql b/tests/sql_test_files/data/it_works_set_variable_to_sqlpage_function.sql new file mode 100644 index 00000000..7fc0c515 --- /dev/null +++ b/tests/sql_test_files/data/it_works_set_variable_to_sqlpage_function.sql @@ -0,0 +1,3 @@ +set my_var = sqlpage.url_encode(' '); +select '%20' as expected, + $my_var as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_set_variable_to_sqlpage_post_function.sql b/tests/sql_test_files/data/it_works_set_variable_to_sqlpage_post_function.sql new file mode 100644 index 00000000..56ee3578 --- /dev/null +++ b/tests/sql_test_files/data/it_works_set_variable_to_sqlpage_post_function.sql @@ -0,0 +1,3 @@ +set my_var = sqlpage.url_encode(UPPER('a')); +select 'A' as expected, + $my_var as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_sqlite_unicode_upper.sql b/tests/sql_test_files/data/it_works_sqlite_unicode_upper.sql new file mode 100644 index 00000000..a6fb751c --- /dev/null +++ b/tests/sql_test_files/data/it_works_sqlite_unicode_upper.sql @@ -0,0 +1,3 @@ +-- Checks that the UPPER function is working correctly with unicode characters. +select 'É' as expected, + UPPER('é') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_sqrt.sql b/tests/sql_test_files/data/it_works_sqrt.sql similarity index 100% rename from tests/sql_test_files/it_works_sqrt.sql rename to tests/sql_test_files/data/it_works_sqrt.sql diff --git a/tests/sql_test_files/data/it_works_uploaded_file_is_null.sql b/tests/sql_test_files/data/it_works_uploaded_file_is_null.sql new file mode 100644 index 00000000..68d223d4 --- /dev/null +++ b/tests/sql_test_files/data/it_works_uploaded_file_is_null.sql @@ -0,0 +1,3 @@ +set actual = sqlpage.uploaded_file_path('my_file'); +select 'NULL' as expected, + coalesce($actual, 'NULL') as actual; diff --git a/tests/sql_test_files/data/it_works_url_encode.sql b/tests/sql_test_files/data/it_works_url_encode.sql new file mode 100644 index 00000000..9ced88b4 --- /dev/null +++ b/tests/sql_test_files/data/it_works_url_encode.sql @@ -0,0 +1,2 @@ +select '%2F' as expected, + sqlpage.url_encode('/') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_varchar_nomysql.sql b/tests/sql_test_files/data/it_works_varchar_nomysql.sql similarity index 50% rename from tests/sql_test_files/it_works_varchar_nomysql.sql rename to tests/sql_test_files/data/it_works_varchar_nomysql.sql index 8bb4ba72..34716bf7 100644 --- a/tests/sql_test_files/it_works_varchar_nomysql.sql +++ b/tests/sql_test_files/data/it_works_varchar_nomysql.sql @@ -1,3 +1,4 @@ -- syntax is valid in SQLite, PostgreSQL and SQLServer -- no cast as varchar in MySQL -select 'text' as component, CAST('It works !' as varchar(100)) as contents; +select 'It works !' as expected, + CAST('It works !' as varchar(100)) as actual; diff --git a/tests/sql_test_files/data/it_works_variables_function.sql b/tests/sql_test_files/data/it_works_variables_function.sql new file mode 100644 index 00000000..36d9f48c --- /dev/null +++ b/tests/sql_test_files/data/it_works_variables_function.sql @@ -0,0 +1,2 @@ +select '{"x":"1"}' as expected, + sqlpage.variables('get') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_variables_function_get_and_post.sql b/tests/sql_test_files/data/it_works_variables_function_get_and_post.sql new file mode 100644 index 00000000..b134c098 --- /dev/null +++ b/tests/sql_test_files/data/it_works_variables_function_get_and_post.sql @@ -0,0 +1,2 @@ +select '{"x":"1"}' as expected, + sqlpage.variables() as actual; \ No newline at end of file diff --git a/tests/sql_test_files/error_too_many_nested_inclusions.sql b/tests/sql_test_files/error_too_many_nested_inclusions.sql deleted file mode 100644 index a021bada..00000000 --- a/tests/sql_test_files/error_too_many_nested_inclusions.sql +++ /dev/null @@ -1,4 +0,0 @@ -select 'debug' as component, - sqlpage.run_sql( - 'tests/sql_test_files/error_too_many_nested_inclusions.sql' - ) as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_client_ip.sql b/tests/sql_test_files/it_works_client_ip.sql deleted file mode 100644 index 78ba8f30..00000000 --- a/tests/sql_test_files/it_works_client_ip.sql +++ /dev/null @@ -1,4 +0,0 @@ -select 'text' as component, - case when sqlpage.client_ip() is null then 'It works !' - else 'It failed ! Got: ' || sqlpage.client_ip() - end as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_dynamic_run_sql_include.sql b/tests/sql_test_files/it_works_dynamic_run_sql_include.sql deleted file mode 100644 index d4c3679f..00000000 --- a/tests/sql_test_files/it_works_dynamic_run_sql_include.sql +++ /dev/null @@ -1 +0,0 @@ -select 'dynamic' as component, sqlpage.run_sql('tests/sql_test_files/it_works_dynamic_shell.sql') as properties; diff --git a/tests/sql_test_files/it_works_env_var_empty.sql b/tests/sql_test_files/it_works_env_var_empty.sql deleted file mode 100644 index c45c7ca2..00000000 --- a/tests/sql_test_files/it_works_env_var_empty.sql +++ /dev/null @@ -1 +0,0 @@ -select 'text' as component, coalesce(sqlpage.environment_variable('I_DO_NOT_EXIST'), 'It works !') as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_exec.sql b/tests/sql_test_files/it_works_exec.sql deleted file mode 100644 index 7a8ccfa5..00000000 --- a/tests/sql_test_files/it_works_exec.sql +++ /dev/null @@ -1 +0,0 @@ -select 'text' as component, sqlpage.exec('echo', 'It', $thisisnull, 'works', '!') as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_fetch_base64.sql b/tests/sql_test_files/it_works_fetch_base64.sql deleted file mode 100644 index f5127005..00000000 --- a/tests/sql_test_files/it_works_fetch_base64.sql +++ /dev/null @@ -1,9 +0,0 @@ -set res = sqlpage.fetch('{ - "url": "http://localhost:' || $echo_port || '/hello_world", - "response_encoding": "base64" -}'); -select 'text' as component, - case - when $res LIKE 'R0VUIC9oZWxsb193b3Js%' then 'It works !' - else 'It failed ! Got: ' || $res - end as contents; diff --git a/tests/sql_test_files/it_works_fetch_hex.sql b/tests/sql_test_files/it_works_fetch_hex.sql deleted file mode 100644 index ea300435..00000000 --- a/tests/sql_test_files/it_works_fetch_hex.sql +++ /dev/null @@ -1,9 +0,0 @@ -set res = sqlpage.fetch('{ - "url": "http://localhost:' || $echo_port || '/hello_world", - "response_encoding": "hex" -}'); -select 'text' as component, - case - when $res LIKE '474554202f68656c6c6f5f776f726c64%' then 'It works !' - else 'It failed ! Got: ' || $res - end as contents; diff --git a/tests/sql_test_files/it_works_fetch_simple.sql b/tests/sql_test_files/it_works_fetch_simple.sql deleted file mode 100644 index 1984e7a2..00000000 --- a/tests/sql_test_files/it_works_fetch_simple.sql +++ /dev/null @@ -1,7 +0,0 @@ -set url = 'http://localhost:' || $echo_port || '/hello_world'; -set res = sqlpage.fetch($url); -select 'text' as component, - case - when $res LIKE 'GET /hello_world%' then 'It works !' - else 'It failed ! Got: ' || $res - end as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_hash_password.sql b/tests/sql_test_files/it_works_hash_password.sql deleted file mode 100644 index 4e431519..00000000 --- a/tests/sql_test_files/it_works_hash_password.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT 'text' as component, 'It works ! The hashed password is: ' || sqlpage.hash_password($x) as contents; diff --git a/tests/sql_test_files/it_works_hmac_base64.sql b/tests/sql_test_files/it_works_hmac_base64.sql deleted file mode 100644 index 32132cb6..00000000 --- a/tests/sql_test_files/it_works_hmac_base64.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Test HMAC with base64 output format --- Redirect if hash doesn't match expected value -SELECT 'redirect' as component, '/error.sql' as link -WHERE sqlpage.hmac('The quick brown fox jumps over the lazy dog', 'key', 'sha256-base64') != '97yD9DBThCSxMpjmqm+xQ+9NWaFJRhdZl0edvC0aPNg='; - -SELECT 'text' as component, 'It works ! HMAC SHA-256 base64 output is correct' as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_hmac_default.sql b/tests/sql_test_files/it_works_hmac_default.sql deleted file mode 100644 index df93da49..00000000 --- a/tests/sql_test_files/it_works_hmac_default.sql +++ /dev/null @@ -1,5 +0,0 @@ --- Redirect if default algorithm doesn't match sha256 -SELECT 'redirect' as component, '/error.sql' as link -WHERE sqlpage.hmac('test data', 'test key') != sqlpage.hmac('test data', 'test key', 'sha256'); - -SELECT 'text' as component, 'It works ! HMAC default algorithm is SHA-256' as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_hmac_sha256.sql b/tests/sql_test_files/it_works_hmac_sha256.sql deleted file mode 100644 index 35334387..00000000 --- a/tests/sql_test_files/it_works_hmac_sha256.sql +++ /dev/null @@ -1,5 +0,0 @@ --- Redirect if hash doesn't match expected value -SELECT 'redirect' as component, '/error.sql' as link -WHERE sqlpage.hmac('The quick brown fox jumps over the lazy dog', 'key', 'sha256') != 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8'; - -SELECT 'text' as component, 'It works ! HMAC SHA-256 hash is correct' as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_hmac_sha512.sql b/tests/sql_test_files/it_works_hmac_sha512.sql deleted file mode 100644 index 0b6ad9e1..00000000 --- a/tests/sql_test_files/it_works_hmac_sha512.sql +++ /dev/null @@ -1,5 +0,0 @@ --- Redirect if hash doesn't match expected value -SELECT 'redirect' as component, '/error.sql' as link -WHERE sqlpage.hmac('The quick brown fox jumps over the lazy dog', 'key', 'sha512') != 'b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a'; - -SELECT 'text' as component, 'It works ! HMAC SHA-512 hash is correct' as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_hmac_shopify_webhook.sql b/tests/sql_test_files/it_works_hmac_shopify_webhook.sql deleted file mode 100644 index 909ee8a2..00000000 --- a/tests/sql_test_files/it_works_hmac_shopify_webhook.sql +++ /dev/null @@ -1,15 +0,0 @@ --- Test Shopify webhook HMAC validation with base64 output --- Shopify sends webhook body and HMAC signature in X-Shopify-Hmac-SHA256 header (base64 format) - --- Redirect to error if signature doesn't match (proper pattern) -SELECT 'redirect' as component, - '/error.sql?msg=invalid_signature' as link -WHERE sqlpage.hmac( - '{"id":1234567890,"email":"customer@example.com","total_price":"123.45"}', - 'test-webhook-secret', - 'sha256-base64' -) != 'QNyObTlKbMx2qDlPF/ZOZcBqg5OgPg+2oky3zldc0Gw='; - --- If we reach here, signature is valid -SELECT 'text' as component, - 'It works ! Shopify webhook signature verified (base64 format)' as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_immutable_variables.sql b/tests/sql_test_files/it_works_immutable_variables.sql deleted file mode 100644 index 11b5d459..00000000 --- a/tests/sql_test_files/it_works_immutable_variables.sql +++ /dev/null @@ -1,31 +0,0 @@ -SET x = 'set_value'; -SET set_only = 'only_in_set'; - -SELECT 'text' AS component; - -SELECT CASE - WHEN $x = 'set_value' THEN 'It works !' - WHEN $x = '1' THEN 'FAIL: SET variable should shadow URL param' - ELSE 'FAIL: Unexpected value for $x: ' || COALESCE($x, 'NULL') -END AS contents; - -SELECT CASE - WHEN $set_only = 'only_in_set' THEN 'It works !' - ELSE 'FAIL: SET-only variable not found' -END AS contents; - -SELECT CASE - WHEN sqlpage.variables('get') = '{"x":"1"}' THEN 'It works !' - ELSE 'FAIL: variables(''get'') should return only URL parameters, got: ' || sqlpage.variables('get') -END AS contents; - -SELECT CASE - WHEN sqlpage.variables('set') = '{"x":"set_value","set_only":"only_in_set"}' THEN 'It works !' - ELSE 'FAIL: variables(''set'') should return only SET variables, got: ' || sqlpage.variables('set') -END AS contents; - -SELECT CASE - WHEN sqlpage.variables() = '{"x":"set_value","set_only":"only_in_set"}' THEN 'It works !' - ELSE 'FAIL: variables() should merge all with SET taking precedence, got: ' || sqlpage.variables() -END AS contents; - diff --git a/tests/sql_test_files/it_works_path.sql b/tests/sql_test_files/it_works_path.sql deleted file mode 100644 index 3bf81d68..00000000 --- a/tests/sql_test_files/it_works_path.sql +++ /dev/null @@ -1,6 +0,0 @@ -select 'text' as component, - CASE sqlpage.path() - WHEN '/tests/sql_test_files/it_works_path.sql' THEN 'It works !' - ELSE 'It failed ! Expected "/tests/sql_test_files/it_works_path.sql", got "' || sqlpage.path() || '"".' - END - AS contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_protocol.sql b/tests/sql_test_files/it_works_protocol.sql deleted file mode 100644 index 1355975b..00000000 --- a/tests/sql_test_files/it_works_protocol.sql +++ /dev/null @@ -1,6 +0,0 @@ -select 'text' as component, - CASE sqlpage.protocol() - WHEN 'http' THEN 'It works !' - ELSE 'It failed ! Expected "http", got "' || sqlpage.protocol() || '"".' - END - AS contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_read_file_as_data_url.sql b/tests/sql_test_files/it_works_read_file_as_data_url.sql deleted file mode 100644 index 21985d7b..00000000 --- a/tests/sql_test_files/it_works_read_file_as_data_url.sql +++ /dev/null @@ -1,12 +0,0 @@ -set actual = sqlpage.read_file_as_data_url('tests/it_works.txt') -set expected = 'data:text/plain;base64,SXQgd29ya3MgIQ=='; - -select 'text' as component, - case $actual - when $expected - then 'It works !' - else - 'Failed. - Expected: ' || $expected || - 'Got: ' || $actual - end as contents; diff --git a/tests/sql_test_files/it_works_read_file_as_text.sql b/tests/sql_test_files/it_works_read_file_as_text.sql deleted file mode 100644 index 18c980e2..00000000 --- a/tests/sql_test_files/it_works_read_file_as_text.sql +++ /dev/null @@ -1 +0,0 @@ -select 'text' as component, sqlpage.read_file_as_text('tests/it_works.txt') as contents; diff --git a/tests/sql_test_files/it_works_request_method.sql b/tests/sql_test_files/it_works_request_method.sql deleted file mode 100644 index e798189b..00000000 --- a/tests/sql_test_files/it_works_request_method.sql +++ /dev/null @@ -1,12 +0,0 @@ -set actual = sqlpage.request_method() -set expected = 'GET'; - -select 'text' as component, - case $actual - when $expected - then 'It works !' - else - 'Failed. - Expected: ' || $expected || - 'Got: ' || $actual - end as contents; diff --git a/tests/sql_test_files/it_works_run_sql.sql b/tests/sql_test_files/it_works_run_sql.sql deleted file mode 100644 index d7c830d8..00000000 --- a/tests/sql_test_files/it_works_run_sql.sql +++ /dev/null @@ -1 +0,0 @@ -select 'dynamic' as component, sqlpage.run_sql('tests/sql_test_files/it_works_simple.sql') as properties; diff --git a/tests/sql_test_files/it_works_set_case.sql b/tests/sql_test_files/it_works_set_case.sql deleted file mode 100644 index c948de0d..00000000 --- a/tests/sql_test_files/it_works_set_case.sql +++ /dev/null @@ -1,2 +0,0 @@ -SET msg = case when 1=1 then 'It works !' else 'It failed !' end; -select 'text' as component, $msg AS contents; diff --git a/tests/sql_test_files/it_works_set_variable.sql b/tests/sql_test_files/it_works_set_variable.sql deleted file mode 100644 index e9ac8286..00000000 --- a/tests/sql_test_files/it_works_set_variable.sql +++ /dev/null @@ -1,2 +0,0 @@ -set what_does_it_do = 'wo' || 'rks'; -select 'text' as component, 'It ' || $what_does_it_do || ' !' as contents; diff --git a/tests/sql_test_files/it_works_set_variable_numeric.sql b/tests/sql_test_files/it_works_set_variable_numeric.sql deleted file mode 100644 index ae392824..00000000 --- a/tests/sql_test_files/it_works_set_variable_numeric.sql +++ /dev/null @@ -1,9 +0,0 @@ -set two = 2; -select 'text' as component, - CASE - WHEN $two = '2' -- All variables are strings - THEN - 'It works !' - ELSE - 'error: expected "2", got: ' || COALESCE($two, 'null') - END as contents; diff --git a/tests/sql_test_files/it_works_set_variable_to_null.sql b/tests/sql_test_files/it_works_set_variable_to_null.sql deleted file mode 100644 index e2435dfc..00000000 --- a/tests/sql_test_files/it_works_set_variable_to_null.sql +++ /dev/null @@ -1,9 +0,0 @@ -set i_am_null = NULL; -select 'text' as component, - CASE - WHEN $i_am_null IS NULL - THEN - 'It works !' - ELSE - 'error: expected null, got: ' || $i_am_null - END as contents; diff --git a/tests/sql_test_files/it_works_set_variable_to_sqlpage_function.sql b/tests/sql_test_files/it_works_set_variable_to_sqlpage_function.sql deleted file mode 100644 index 96186502..00000000 --- a/tests/sql_test_files/it_works_set_variable_to_sqlpage_function.sql +++ /dev/null @@ -1,7 +0,0 @@ -set my_var = sqlpage.url_encode(' '); -select 'text' as component, - CASE $my_var - WHEN '%20' THEN 'It works !' - ELSE 'It failed !' - END - AS contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_set_variable_to_sqlpage_post_function.sql b/tests/sql_test_files/it_works_set_variable_to_sqlpage_post_function.sql deleted file mode 100644 index 87f6d85f..00000000 --- a/tests/sql_test_files/it_works_set_variable_to_sqlpage_post_function.sql +++ /dev/null @@ -1,7 +0,0 @@ -set my_var = sqlpage.url_encode(UPPER('a')); -select 'text' as component, - CASE $my_var - WHEN 'A' THEN 'It works !' - ELSE 'It failed !' - END - AS contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_sqlite_unicode_upper.sql b/tests/sql_test_files/it_works_sqlite_unicode_upper.sql deleted file mode 100644 index 182bbe23..00000000 --- a/tests/sql_test_files/it_works_sqlite_unicode_upper.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Checks that the UPPER function is working correctly with unicode characters. -select 'text' as component, - case - when UPPER('é') = 'É' then 'It works !' - else 'It failed ! Expected É, got ' || UPPER('é') || '.' - end as contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_uploaded_file_is_null.sql b/tests/sql_test_files/it_works_uploaded_file_is_null.sql deleted file mode 100644 index cf3ba9d5..00000000 --- a/tests/sql_test_files/it_works_uploaded_file_is_null.sql +++ /dev/null @@ -1,7 +0,0 @@ --- checks that sqlpage.uploaded_file_path returns null when there is no uploaded_file -set actual = sqlpage.uploaded_file_path('my_file'); -select 'text' as component, - case when $actual is null - then 'It works !' - else 'Failed. Expected: null. Got: ' || $actual - end as contents; diff --git a/tests/sql_test_files/it_works_url_encode.sql b/tests/sql_test_files/it_works_url_encode.sql deleted file mode 100644 index 679129e1..00000000 --- a/tests/sql_test_files/it_works_url_encode.sql +++ /dev/null @@ -1,6 +0,0 @@ -select 'text' as component, - CASE sqlpage.url_encode('/') - WHEN '%2F' THEN 'It works !' - ELSE 'It failed !' - END - AS contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_variables_function.sql b/tests/sql_test_files/it_works_variables_function.sql deleted file mode 100644 index d7497205..00000000 --- a/tests/sql_test_files/it_works_variables_function.sql +++ /dev/null @@ -1,6 +0,0 @@ -select 'text' as component, - CASE sqlpage.variables('get') - WHEN '{"x":"1"}' THEN 'It works !' - ELSE 'It failed ! Expected {"x":"1"}, got ' || sqlpage.variables('get') - END - AS contents; \ No newline at end of file diff --git a/tests/sql_test_files/it_works_variables_function_get_and_post.sql b/tests/sql_test_files/it_works_variables_function_get_and_post.sql deleted file mode 100644 index 0217d9ef..00000000 --- a/tests/sql_test_files/it_works_variables_function_get_and_post.sql +++ /dev/null @@ -1,6 +0,0 @@ -select 'text' as component, - CASE sqlpage.variables() - WHEN '{"x":"1"}' THEN 'It works !' - ELSE 'It failed ! Expected {"x":"1"}, got ' || sqlpage.variables() - END - AS contents; \ No newline at end of file diff --git a/tests/sql_test_files/mod.rs b/tests/sql_test_files/mod.rs index af081d88..e2a9c252 100644 --- a/tests/sql_test_files/mod.rs +++ b/tests/sql_test_files/mod.rs @@ -7,7 +7,7 @@ use tokio::task::JoinHandle; #[actix_web::test] async fn run_all_sql_test_files() { let app_data = crate::common::make_app_data().await; - let test_files = get_sql_test_files(); + let test_files = get_sql_test_cases(); let (shutdown_tx, shutdown_rx) = oneshot::channel(); let (echo_handle, port) = crate::common::start_echo_server(shutdown_rx); @@ -38,22 +38,50 @@ async fn wait_for_echo_server(port: u16) { panic!("Echo server did not become ready"); } -fn get_sql_test_files() -> Vec { - std::fs::read_dir("tests/sql_test_files") +#[derive(Clone, Copy)] +enum SqlTestFormat { + Html, + Json, +} + +struct SqlTestCase { + path: std::path::PathBuf, + format: SqlTestFormat, +} + +fn get_sql_test_cases() -> Vec { + let mut tests = Vec::new(); + tests.extend(read_sql_tests_in_dir( + "tests/sql_test_files/component_rendering", + SqlTestFormat::Html, + )); + tests.extend(read_sql_tests_in_dir( + "tests/sql_test_files/data", + SqlTestFormat::Json, + )); + tests +} + +fn read_sql_tests_in_dir(dir: &str, format: SqlTestFormat) -> Vec { + std::fs::read_dir(dir) .unwrap() .filter_map(|e| { let path = e.ok()?.path(); - (path.extension()? == "sql").then_some(path) + if path.is_dir() || path.extension()? != "sql" { + return None; + } + Some(SqlTestCase { path, format }) }) .collect() } async fn run_sql_test( - test_file: &std::path::Path, + test_case: &SqlTestCase, app_data: &actix_web::web::Data, _echo_handle: &JoinHandle<()>, port: u16, ) { + let test_file = &test_case.path; let test_file_path = test_file.to_string_lossy().replace('\\', "/"); let stem = test_file.file_stem().unwrap().to_str().unwrap(); @@ -69,9 +97,7 @@ async fn run_sql_test( } let req_str = format!("/{test_file_path}?{query_params}"); - let use_json = std::fs::read_to_string(test_file) - .unwrap_or_default() - .contains(" actual"); + let use_json = matches!(test_case.format, SqlTestFormat::Json); let resp = tokio::time::timeout(Duration::from_secs(5), async { if use_json { @@ -132,7 +158,11 @@ fn assert_json_test(body: &str, test_file: &std::path::Path) { .unwrap_or_default(); if expected.is_empty() && expected_contains.is_empty() { - continue; + panic!( + "No expected values found in {}: {}", + test_file.display(), + row + ); } let exact_ok = expected.is_empty() || expected.iter().any(|e| e == &actual); diff --git a/tests/sql_test_files/select_temp_t.sql b/tests/sql_test_files/select_temp_t.sql index 3e8f2d90..ff25e2da 100644 --- a/tests/sql_test_files/select_temp_t.sql +++ b/tests/sql_test_files/select_temp_t.sql @@ -1,2 +1,2 @@ --- see tests/sql_test_files/it_works_temp_table_accessible_in_run_sql.sql +-- see tests/sql_test_files/component_rendering/it_works_temp_table_accessible_in_run_sql_nomssql.sql select 'text' as component, x as contents from temp_t; \ No newline at end of file diff --git a/tests/transactions/mod.rs b/tests/transactions/mod.rs index 835df0d6..37759729 100644 --- a/tests/transactions/mod.rs +++ b/tests/transactions/mod.rs @@ -46,7 +46,7 @@ async fn test_failed_copy_followed_by_query() -> actix_web::Result<()> { let app_data = make_app_data().await; let big_csv = "col1,col2\nval1,val2\n".repeat(1000); let req = get_request_to_with_data( - "/tests/sql_test_files/error_failed_to_import_the_csv.sql", + "/tests/sql_test_files/component_rendering/error_failed_to_import_the_csv.sql", app_data.clone(), ) .await? @@ -79,9 +79,9 @@ async fn test_failed_copy_followed_by_query() -> actix_web::Result<()> { } // Now make other requests to verify the connection is still usable for path in [ - "/tests/sql_test_files/it_works_lower.sql", - "/tests/sql_test_files/it_works_simple.sql", - "/tests/sql_test_files/it_works_path.sql", + "/tests/sql_test_files/component_rendering/it_works_simple.sql", + "/tests/sql_test_files/component_rendering/it_works_text_markdown.sql", + "/tests/sql_test_files/component_rendering/it_works_text_unsafe_markdown.sql", ] { let req = get_request_to_with_data(path, app_data.clone()) .await? From a102ae150f2277317a115a6c3f75136f6e921699 Mon Sep 17 00:00:00 2001 From: lovasoa Date: Tue, 25 Nov 2025 00:49:19 +0100 Subject: [PATCH 3/5] migrate more tests to the expected/actual format - Changed references in various test files to point to the new `simple.sql` instead of the outdated `it_works_simple.sql`. - Removed several obsolete SQL test files that are no longer needed, streamlining the test suite. - Updated assertions and request paths in the test cases to reflect the new structure and improve clarity. --- tests/core/mod.rs | 4 +- tests/core/select_temp_t.sql | 2 +- tests/data_formats/mod.rs | 8 ++-- tests/server_timing/mod.rs | 6 +-- tests/sql_test_files/README.md | 10 ++--- ...mns_component_json_nomssql_nopostgres.sql} | 0 ...l => deeply_nested_dynamic_components.sql} | 0 ...lt_component.sql => default_component.sql} | 0 ...ownload_base64.sql => download_base64.sql} | 0 ...orks_download_raw.sql => download_raw.sql} | 0 ..._dynamic_nested.sql => dynamic_nested.sql} | 0 ...es.sql => dynamic_repeated_properties.sql} | 0 .../dynamic_run_sql_include.sql | 2 + ...ks_dynamic_shell.sql => dynamic_shell.sql} | 0 ...amic_toplevel.sql => dynamic_toplevel.sql} | 0 .../it_works_dynamic_run_sql_include.sql | 2 - .../component_rendering/it_works_run_sql.sql | 2 - .../{it_works_log.sql => log.sql} | 0 ...own_in_table.sql => markdown_in_table.sql} | 0 .../component_rendering/run_sql.sql | 2 + ...database.sql => run_sql_from_database.sql} | 0 ...access.sql => run_sql_variable_access.sql} | 0 ...orks_shell_search.sql => shell_search.sql} | 0 .../{it_works_simple.sql => simple.sql} | 0 ...p_table_accessible_in_run_sql_nomssql.sql} | 0 ...ks_text_markdown.sql => text_markdown.sql} | 0 ..._markdown.sql => text_unsafe_markdown.sql} | 0 ...ithout_a_shell.sql => without_a_shell.sql} | 0 ...h_password.sql => basic_auth_password.sql} | 0 ...h_username.sql => basic_auth_username.sql} | 0 ..._case_variables.sql => case_variables.sql} | 0 tests/sql_test_files/data/client_ip.sql | 2 + ...ks_coalesce_eval.sql => coalesce_eval.sql} | 0 ...n.sql => concat_str_in_pseudofunction.sql} | 2 +- .../data/{it_works_cookie.sql => cookie.sql} | 0 ...orks_create_table.sql => create_table.sql} | 0 .../{it_works_decimal.sql => decimal.sql} | 0 ...ion_call.sql => delayed_function_call.sql} | 0 tests/sql_test_files/data/env_var_empty.sql | 2 + .../data/{it_works_exec.sql => exec.sql} | 0 ...orks_fetch_base64.sql => fetch_base64.sql} | 0 .../{it_works_fetch_hex.sql => fetch_hex.sql} | 0 ...l.sql => fetch_native_json_array_impl.sql} | 0 ...it_works_fetch_post.sql => fetch_post.sql} | 0 ...orks_fetch_simple.sql => fetch_simple.sql} | 0 ...ta_error.sql => fetch_with_meta_error.sql} | 0 ..._simple.sql => fetch_with_meta_simple.sql} | 0 ...ks_hash_password.sql => hash_password.sql} | 0 .../data/hash_password_null.sql | 1 + .../data/{it_works_header.sql => header.sql} | 0 .../{it_works_headers.sql => headers.sql} | 0 ..._works_hmac_base64.sql => hmac_base64.sql} | 0 ...orks_hmac_default.sql => hmac_default.sql} | 0 ..._works_hmac_sha256.sql => hmac_sha256.sql} | 0 ..._works_hmac_sha512.sql => hmac_sha512.sql} | 0 ...y_webhook.sql => hmac_shopify_webhook.sql} | 0 ..._variables.sql => immutable_variables.sql} | 0 .../data/it_works_client_ip.sql | 2 - .../data/it_works_env_var_empty.sql | 2 - .../data/it_works_hash_password_null.sql | 1 - tests/sql_test_files/data/it_works_path.sql | 2 - .../data/it_works_set_variable_to_null.sql | 3 -- tests/sql_test_files/data/it_works_sqrt.sql | 2 - .../data/it_works_uploaded_file_is_null.sql | 3 -- .../data/{it_works_link.sql => link.sql} | 0 .../{it_works_link_null.sql => link_null.sql} | 0 .../data/{it_works_lower.sql => lower.sql} | 0 ...tions.sql => nested_sqlpage_functions.sql} | 0 tests/sql_test_files/data/path.sql | 2 + ...st_syntax.sql => postgres_cast_syntax.sql} | 0 .../{it_works_protocol.sql => protocol.sql} | 0 ...orks_query_string.sql => query_string.sql} | 0 ...ks_random_string.sql => random_string.sql} | 0 ...data_url.sql => read_file_as_data_url.sql} | 0 ...file_as_text.sql => read_file_as_text.sql} | 0 ..._request_method.sql => request_method.sql} | 0 .../{it_works_set_case.sql => set_case.sql} | 0 ...orks_set_variable.sql => set_variable.sql} | 0 ...ariable_func.sql => set_variable_func.sql} | 0 ...nc_null.sql => set_variable_func_null.sql} | 0 ...lace.sql => set_variable_func_replace.sql} | 0 ...ger.sql => set_variable_large_integer.sql} | 0 ...e_numeric.sql => set_variable_numeric.sql} | 0 .../data/set_variable_to_null.sql | 3 ++ ...sql => set_variable_to_other_variable.sql} | 0 ...l => set_variable_to_sqlpage_function.sql} | 0 ...set_variable_to_sqlpage_post_function.sql} | 0 ...ode_upper.sql => sqlite_unicode_upper.sql} | 0 tests/sql_test_files/data/sqrt.sql | 2 + .../data/uploaded_file_is_null.sql | 2 + ...it_works_url_encode.sql => url_encode.sql} | 0 ...archar_nomysql.sql => varchar_nomysql.sql} | 0 ...es_function.sql => variables_function.sql} | 0 ...ql => variables_function_get_and_post.sql} | 0 tests/sql_test_files/mod.rs | 38 ++++++++++--------- tests/sql_test_files/select_temp_t.sql | 2 +- tests/transactions/mod.rs | 6 +-- 97 files changed, 58 insertions(+), 57 deletions(-) rename tests/sql_test_files/component_rendering/{it_works_columns_component_json_nomssql_nopostgres.sql => columns_component_json_nomssql_nopostgres.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_deeply_nested_dynamic_components.sql => deeply_nested_dynamic_components.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_default_component.sql => default_component.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_download_base64.sql => download_base64.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_download_raw.sql => download_raw.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_dynamic_nested.sql => dynamic_nested.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_dynamic_repeated_properties.sql => dynamic_repeated_properties.sql} (100%) create mode 100644 tests/sql_test_files/component_rendering/dynamic_run_sql_include.sql rename tests/sql_test_files/component_rendering/{it_works_dynamic_shell.sql => dynamic_shell.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_dynamic_toplevel.sql => dynamic_toplevel.sql} (100%) delete mode 100644 tests/sql_test_files/component_rendering/it_works_dynamic_run_sql_include.sql delete mode 100644 tests/sql_test_files/component_rendering/it_works_run_sql.sql rename tests/sql_test_files/component_rendering/{it_works_log.sql => log.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_markdown_in_table.sql => markdown_in_table.sql} (100%) create mode 100644 tests/sql_test_files/component_rendering/run_sql.sql rename tests/sql_test_files/component_rendering/{it_works_run_sql_from_database.sql => run_sql_from_database.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_run_sql_variable_access.sql => run_sql_variable_access.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_shell_search.sql => shell_search.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_simple.sql => simple.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_temp_table_accessible_in_run_sql_nomssql.sql => temp_table_accessible_in_run_sql_nomssql.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_text_markdown.sql => text_markdown.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_text_unsafe_markdown.sql => text_unsafe_markdown.sql} (100%) rename tests/sql_test_files/component_rendering/{it_works_without_a_shell.sql => without_a_shell.sql} (100%) rename tests/sql_test_files/data/{it_works_basic_auth_password.sql => basic_auth_password.sql} (100%) rename tests/sql_test_files/data/{it_works_basic_auth_username.sql => basic_auth_username.sql} (100%) rename tests/sql_test_files/data/{it_works_case_variables.sql => case_variables.sql} (100%) create mode 100644 tests/sql_test_files/data/client_ip.sql rename tests/sql_test_files/data/{it_works_coalesce_eval.sql => coalesce_eval.sql} (100%) rename tests/sql_test_files/data/{it_works_concat_str_in_pseudofunction.sql => concat_str_in_pseudofunction.sql} (58%) rename tests/sql_test_files/data/{it_works_cookie.sql => cookie.sql} (100%) rename tests/sql_test_files/data/{it_works_create_table.sql => create_table.sql} (100%) rename tests/sql_test_files/data/{it_works_decimal.sql => decimal.sql} (100%) rename tests/sql_test_files/data/{it_works_delayed_function_call.sql => delayed_function_call.sql} (100%) create mode 100644 tests/sql_test_files/data/env_var_empty.sql rename tests/sql_test_files/data/{it_works_exec.sql => exec.sql} (100%) rename tests/sql_test_files/data/{it_works_fetch_base64.sql => fetch_base64.sql} (100%) rename tests/sql_test_files/data/{it_works_fetch_hex.sql => fetch_hex.sql} (100%) rename tests/sql_test_files/data/{it_works_fetch_native_json_array_impl.sql => fetch_native_json_array_impl.sql} (100%) rename tests/sql_test_files/data/{it_works_fetch_post.sql => fetch_post.sql} (100%) rename tests/sql_test_files/data/{it_works_fetch_simple.sql => fetch_simple.sql} (100%) rename tests/sql_test_files/data/{it_works_fetch_with_meta_error.sql => fetch_with_meta_error.sql} (100%) rename tests/sql_test_files/data/{it_works_fetch_with_meta_simple.sql => fetch_with_meta_simple.sql} (100%) rename tests/sql_test_files/data/{it_works_hash_password.sql => hash_password.sql} (100%) create mode 100644 tests/sql_test_files/data/hash_password_null.sql rename tests/sql_test_files/data/{it_works_header.sql => header.sql} (100%) rename tests/sql_test_files/data/{it_works_headers.sql => headers.sql} (100%) rename tests/sql_test_files/data/{it_works_hmac_base64.sql => hmac_base64.sql} (100%) rename tests/sql_test_files/data/{it_works_hmac_default.sql => hmac_default.sql} (100%) rename tests/sql_test_files/data/{it_works_hmac_sha256.sql => hmac_sha256.sql} (100%) rename tests/sql_test_files/data/{it_works_hmac_sha512.sql => hmac_sha512.sql} (100%) rename tests/sql_test_files/data/{it_works_hmac_shopify_webhook.sql => hmac_shopify_webhook.sql} (100%) rename tests/sql_test_files/data/{it_works_immutable_variables.sql => immutable_variables.sql} (100%) delete mode 100644 tests/sql_test_files/data/it_works_client_ip.sql delete mode 100644 tests/sql_test_files/data/it_works_env_var_empty.sql delete mode 100644 tests/sql_test_files/data/it_works_hash_password_null.sql delete mode 100644 tests/sql_test_files/data/it_works_path.sql delete mode 100644 tests/sql_test_files/data/it_works_set_variable_to_null.sql delete mode 100644 tests/sql_test_files/data/it_works_sqrt.sql delete mode 100644 tests/sql_test_files/data/it_works_uploaded_file_is_null.sql rename tests/sql_test_files/data/{it_works_link.sql => link.sql} (100%) rename tests/sql_test_files/data/{it_works_link_null.sql => link_null.sql} (100%) rename tests/sql_test_files/data/{it_works_lower.sql => lower.sql} (100%) rename tests/sql_test_files/data/{it_works_nested_sqlpage_functions.sql => nested_sqlpage_functions.sql} (100%) create mode 100644 tests/sql_test_files/data/path.sql rename tests/sql_test_files/data/{it_works_postgres_cast_syntax.sql => postgres_cast_syntax.sql} (100%) rename tests/sql_test_files/data/{it_works_protocol.sql => protocol.sql} (100%) rename tests/sql_test_files/data/{it_works_query_string.sql => query_string.sql} (100%) rename tests/sql_test_files/data/{it_works_random_string.sql => random_string.sql} (100%) rename tests/sql_test_files/data/{it_works_read_file_as_data_url.sql => read_file_as_data_url.sql} (100%) rename tests/sql_test_files/data/{it_works_read_file_as_text.sql => read_file_as_text.sql} (100%) rename tests/sql_test_files/data/{it_works_request_method.sql => request_method.sql} (100%) rename tests/sql_test_files/data/{it_works_set_case.sql => set_case.sql} (100%) rename tests/sql_test_files/data/{it_works_set_variable.sql => set_variable.sql} (100%) rename tests/sql_test_files/data/{it_works_set_variable_func.sql => set_variable_func.sql} (100%) rename tests/sql_test_files/data/{it_works_set_variable_func_null.sql => set_variable_func_null.sql} (100%) rename tests/sql_test_files/data/{it_works_set_variable_func_replace.sql => set_variable_func_replace.sql} (100%) rename tests/sql_test_files/data/{it_works_set_variable_large_integer.sql => set_variable_large_integer.sql} (100%) rename tests/sql_test_files/data/{it_works_set_variable_numeric.sql => set_variable_numeric.sql} (100%) create mode 100644 tests/sql_test_files/data/set_variable_to_null.sql rename tests/sql_test_files/data/{it_works_set_variable_to_other_variable.sql => set_variable_to_other_variable.sql} (100%) rename tests/sql_test_files/data/{it_works_set_variable_to_sqlpage_function.sql => set_variable_to_sqlpage_function.sql} (100%) rename tests/sql_test_files/data/{it_works_set_variable_to_sqlpage_post_function.sql => set_variable_to_sqlpage_post_function.sql} (100%) rename tests/sql_test_files/data/{it_works_sqlite_unicode_upper.sql => sqlite_unicode_upper.sql} (100%) create mode 100644 tests/sql_test_files/data/sqrt.sql create mode 100644 tests/sql_test_files/data/uploaded_file_is_null.sql rename tests/sql_test_files/data/{it_works_url_encode.sql => url_encode.sql} (100%) rename tests/sql_test_files/data/{it_works_varchar_nomysql.sql => varchar_nomysql.sql} (100%) rename tests/sql_test_files/data/{it_works_variables_function.sql => variables_function.sql} (100%) rename tests/sql_test_files/data/{it_works_variables_function_get_and_post.sql => variables_function_get_and_post.sql} (100%) diff --git a/tests/core/mod.rs b/tests/core/mod.rs index 155db764..25efc764 100644 --- a/tests/core/mod.rs +++ b/tests/core/mod.rs @@ -88,7 +88,7 @@ async fn test_routing_with_prefix() { let app_data = actix_web::web::Data::new(state); let resp = req_path_with_app_data( - "/prefix/tests/sql_test_files/component_rendering/it_works_simple.sql", + "/prefix/tests/sql_test_files/component_rendering/simple.sql", app_data.clone(), ) .await @@ -122,7 +122,7 @@ async fn test_routing_with_prefix() { assert!(resp.to_lowercase().contains("forbidden"), "{resp}"); let resp = req_path_with_app_data( - "/tests/sql_test_files/component_rendering/it_works_simple.sql", + "/tests/sql_test_files/component_rendering/simple.sql", app_data, ) .await diff --git a/tests/core/select_temp_t.sql b/tests/core/select_temp_t.sql index 2626f436..aed09336 100644 --- a/tests/core/select_temp_t.sql +++ b/tests/core/select_temp_t.sql @@ -1,2 +1,2 @@ --- see tests/sql_test_files/component_rendering/it_works_temp_table_accessible_in_run_sql_nomssql.sql +-- see tests/sql_test_files/component_rendering/temp_table_accessible_in_run_sql_nomssql.sql select 'text' as component, x as contents from temp_t; \ No newline at end of file diff --git a/tests/data_formats/mod.rs b/tests/data_formats/mod.rs index 5f9b8d39..c195d554 100644 --- a/tests/data_formats/mod.rs +++ b/tests/data_formats/mod.rs @@ -96,7 +96,7 @@ async fn test_json_columns() { #[actix_web::test] async fn test_accept_json_returns_json_array() -> actix_web::Result<()> { let resp = req_with_accept( - "/tests/sql_test_files/component_rendering/it_works_simple.sql", + "/tests/sql_test_files/component_rendering/simple.sql", "application/json", ) .await?; @@ -117,7 +117,7 @@ async fn test_accept_json_returns_json_array() -> actix_web::Result<()> { #[actix_web::test] async fn test_accept_ndjson_returns_jsonlines() -> actix_web::Result<()> { let resp = req_with_accept( - "/tests/sql_test_files/component_rendering/it_works_simple.sql", + "/tests/sql_test_files/component_rendering/simple.sql", "application/x-ndjson", ) .await?; @@ -144,7 +144,7 @@ async fn test_accept_ndjson_returns_jsonlines() -> actix_web::Result<()> { #[actix_web::test] async fn test_accept_html_returns_html() -> actix_web::Result<()> { let resp = req_with_accept( - "/tests/sql_test_files/component_rendering/it_works_simple.sql", + "/tests/sql_test_files/component_rendering/simple.sql", "text/html", ) .await?; @@ -161,7 +161,7 @@ async fn test_accept_html_returns_html() -> actix_web::Result<()> { #[actix_web::test] async fn test_accept_wildcard_returns_html() -> actix_web::Result<()> { let resp = req_with_accept( - "/tests/sql_test_files/component_rendering/it_works_simple.sql", + "/tests/sql_test_files/component_rendering/simple.sql", "*/*", ) .await?; diff --git a/tests/server_timing/mod.rs b/tests/server_timing/mod.rs index 05d07757..6d0a42fa 100644 --- a/tests/server_timing/mod.rs +++ b/tests/server_timing/mod.rs @@ -10,7 +10,7 @@ async fn test_server_timing_disabled_in_production() -> actix_web::Result<()> { let app_data = make_app_data_from_config(config).await; let req = crate::common::get_request_to_with_data( - "/tests/sql_test_files/component_rendering/it_works_simple.sql", + "/tests/sql_test_files/component_rendering/simple.sql", app_data, ) .await? @@ -32,7 +32,7 @@ async fn test_server_timing_enabled_in_development() -> actix_web::Result<()> { let app_data = make_app_data_from_config(config).await; let req = crate::common::get_request_to_with_data( - "/tests/sql_test_files/data/it_works_postgres_cast_syntax.sql", + "/tests/sql_test_files/data/postgres_cast_syntax.sql", app_data, ) .await? @@ -72,7 +72,7 @@ async fn test_server_timing_enabled_in_development() -> actix_web::Result<()> { #[actix_web::test] async fn test_server_timing_format() -> actix_web::Result<()> { - let req = get_request_to("/tests/sql_test_files/data/it_works_postgres_cast_syntax.sql") + let req = get_request_to("/tests/sql_test_files/data/postgres_cast_syntax.sql") .await? .to_srv_request(); let resp = main_handler(req).await?; diff --git a/tests/sql_test_files/README.md b/tests/sql_test_files/README.md index 51b1acea..f28b3722 100644 --- a/tests/sql_test_files/README.md +++ b/tests/sql_test_files/README.md @@ -4,11 +4,11 @@ two subdirectories: ## `component_rendering/` Files that depend on SQLPage's HTML rendering (components, shells, redirects, -etc.). `it_works_` files in this directory must render a page that contains the -text "It works !" and no occurrence of the word "error" (case insensitive). -`error_` files should return a page containing the word "error" and the rest of -the file name. Files may include `nosqlite`, `nomssql`, `nopostgres` or -`nomysql` in their name to skip incompatible backends. +etc.). Every file that does not start with `error_` must render a page that +contains the text "It works !" and no occurrence of the word "error" (case +insensitive). `error_` files should return a page containing the word "error" +and the rest of the file name. Files may include `nosqlite`, `nomssql`, +`nopostgres` or `nomysql` in their name to skip incompatible backends. ## `data/` diff --git a/tests/sql_test_files/component_rendering/it_works_columns_component_json_nomssql_nopostgres.sql b/tests/sql_test_files/component_rendering/columns_component_json_nomssql_nopostgres.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_columns_component_json_nomssql_nopostgres.sql rename to tests/sql_test_files/component_rendering/columns_component_json_nomssql_nopostgres.sql diff --git a/tests/sql_test_files/component_rendering/it_works_deeply_nested_dynamic_components.sql b/tests/sql_test_files/component_rendering/deeply_nested_dynamic_components.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_deeply_nested_dynamic_components.sql rename to tests/sql_test_files/component_rendering/deeply_nested_dynamic_components.sql diff --git a/tests/sql_test_files/component_rendering/it_works_default_component.sql b/tests/sql_test_files/component_rendering/default_component.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_default_component.sql rename to tests/sql_test_files/component_rendering/default_component.sql diff --git a/tests/sql_test_files/component_rendering/it_works_download_base64.sql b/tests/sql_test_files/component_rendering/download_base64.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_download_base64.sql rename to tests/sql_test_files/component_rendering/download_base64.sql diff --git a/tests/sql_test_files/component_rendering/it_works_download_raw.sql b/tests/sql_test_files/component_rendering/download_raw.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_download_raw.sql rename to tests/sql_test_files/component_rendering/download_raw.sql diff --git a/tests/sql_test_files/component_rendering/it_works_dynamic_nested.sql b/tests/sql_test_files/component_rendering/dynamic_nested.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_dynamic_nested.sql rename to tests/sql_test_files/component_rendering/dynamic_nested.sql diff --git a/tests/sql_test_files/component_rendering/it_works_dynamic_repeated_properties.sql b/tests/sql_test_files/component_rendering/dynamic_repeated_properties.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_dynamic_repeated_properties.sql rename to tests/sql_test_files/component_rendering/dynamic_repeated_properties.sql diff --git a/tests/sql_test_files/component_rendering/dynamic_run_sql_include.sql b/tests/sql_test_files/component_rendering/dynamic_run_sql_include.sql new file mode 100644 index 00000000..c834e1f0 --- /dev/null +++ b/tests/sql_test_files/component_rendering/dynamic_run_sql_include.sql @@ -0,0 +1,2 @@ +select 'dynamic' as component, + sqlpage.run_sql('tests/sql_test_files/component_rendering/dynamic_shell.sql') as properties; diff --git a/tests/sql_test_files/component_rendering/it_works_dynamic_shell.sql b/tests/sql_test_files/component_rendering/dynamic_shell.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_dynamic_shell.sql rename to tests/sql_test_files/component_rendering/dynamic_shell.sql diff --git a/tests/sql_test_files/component_rendering/it_works_dynamic_toplevel.sql b/tests/sql_test_files/component_rendering/dynamic_toplevel.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_dynamic_toplevel.sql rename to tests/sql_test_files/component_rendering/dynamic_toplevel.sql diff --git a/tests/sql_test_files/component_rendering/it_works_dynamic_run_sql_include.sql b/tests/sql_test_files/component_rendering/it_works_dynamic_run_sql_include.sql deleted file mode 100644 index d4fd9fde..00000000 --- a/tests/sql_test_files/component_rendering/it_works_dynamic_run_sql_include.sql +++ /dev/null @@ -1,2 +0,0 @@ -select 'dynamic' as component, - sqlpage.run_sql('tests/sql_test_files/component_rendering/it_works_dynamic_shell.sql') as properties; diff --git a/tests/sql_test_files/component_rendering/it_works_run_sql.sql b/tests/sql_test_files/component_rendering/it_works_run_sql.sql deleted file mode 100644 index 434f146a..00000000 --- a/tests/sql_test_files/component_rendering/it_works_run_sql.sql +++ /dev/null @@ -1,2 +0,0 @@ -select 'dynamic' as component, - sqlpage.run_sql('tests/sql_test_files/component_rendering/it_works_simple.sql') as properties; diff --git a/tests/sql_test_files/component_rendering/it_works_log.sql b/tests/sql_test_files/component_rendering/log.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_log.sql rename to tests/sql_test_files/component_rendering/log.sql diff --git a/tests/sql_test_files/component_rendering/it_works_markdown_in_table.sql b/tests/sql_test_files/component_rendering/markdown_in_table.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_markdown_in_table.sql rename to tests/sql_test_files/component_rendering/markdown_in_table.sql diff --git a/tests/sql_test_files/component_rendering/run_sql.sql b/tests/sql_test_files/component_rendering/run_sql.sql new file mode 100644 index 00000000..420b306a --- /dev/null +++ b/tests/sql_test_files/component_rendering/run_sql.sql @@ -0,0 +1,2 @@ +select 'dynamic' as component, + sqlpage.run_sql('tests/sql_test_files/component_rendering/simple.sql') as properties; diff --git a/tests/sql_test_files/component_rendering/it_works_run_sql_from_database.sql b/tests/sql_test_files/component_rendering/run_sql_from_database.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_run_sql_from_database.sql rename to tests/sql_test_files/component_rendering/run_sql_from_database.sql diff --git a/tests/sql_test_files/component_rendering/it_works_run_sql_variable_access.sql b/tests/sql_test_files/component_rendering/run_sql_variable_access.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_run_sql_variable_access.sql rename to tests/sql_test_files/component_rendering/run_sql_variable_access.sql diff --git a/tests/sql_test_files/component_rendering/it_works_shell_search.sql b/tests/sql_test_files/component_rendering/shell_search.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_shell_search.sql rename to tests/sql_test_files/component_rendering/shell_search.sql diff --git a/tests/sql_test_files/component_rendering/it_works_simple.sql b/tests/sql_test_files/component_rendering/simple.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_simple.sql rename to tests/sql_test_files/component_rendering/simple.sql diff --git a/tests/sql_test_files/component_rendering/it_works_temp_table_accessible_in_run_sql_nomssql.sql b/tests/sql_test_files/component_rendering/temp_table_accessible_in_run_sql_nomssql.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_temp_table_accessible_in_run_sql_nomssql.sql rename to tests/sql_test_files/component_rendering/temp_table_accessible_in_run_sql_nomssql.sql diff --git a/tests/sql_test_files/component_rendering/it_works_text_markdown.sql b/tests/sql_test_files/component_rendering/text_markdown.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_text_markdown.sql rename to tests/sql_test_files/component_rendering/text_markdown.sql diff --git a/tests/sql_test_files/component_rendering/it_works_text_unsafe_markdown.sql b/tests/sql_test_files/component_rendering/text_unsafe_markdown.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_text_unsafe_markdown.sql rename to tests/sql_test_files/component_rendering/text_unsafe_markdown.sql diff --git a/tests/sql_test_files/component_rendering/it_works_without_a_shell.sql b/tests/sql_test_files/component_rendering/without_a_shell.sql similarity index 100% rename from tests/sql_test_files/component_rendering/it_works_without_a_shell.sql rename to tests/sql_test_files/component_rendering/without_a_shell.sql diff --git a/tests/sql_test_files/data/it_works_basic_auth_password.sql b/tests/sql_test_files/data/basic_auth_password.sql similarity index 100% rename from tests/sql_test_files/data/it_works_basic_auth_password.sql rename to tests/sql_test_files/data/basic_auth_password.sql diff --git a/tests/sql_test_files/data/it_works_basic_auth_username.sql b/tests/sql_test_files/data/basic_auth_username.sql similarity index 100% rename from tests/sql_test_files/data/it_works_basic_auth_username.sql rename to tests/sql_test_files/data/basic_auth_username.sql diff --git a/tests/sql_test_files/data/it_works_case_variables.sql b/tests/sql_test_files/data/case_variables.sql similarity index 100% rename from tests/sql_test_files/data/it_works_case_variables.sql rename to tests/sql_test_files/data/case_variables.sql diff --git a/tests/sql_test_files/data/client_ip.sql b/tests/sql_test_files/data/client_ip.sql new file mode 100644 index 00000000..ac1996e7 --- /dev/null +++ b/tests/sql_test_files/data/client_ip.sql @@ -0,0 +1,2 @@ +select NULL as expected, + sqlpage.client_ip() as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_coalesce_eval.sql b/tests/sql_test_files/data/coalesce_eval.sql similarity index 100% rename from tests/sql_test_files/data/it_works_coalesce_eval.sql rename to tests/sql_test_files/data/coalesce_eval.sql diff --git a/tests/sql_test_files/data/it_works_concat_str_in_pseudofunction.sql b/tests/sql_test_files/data/concat_str_in_pseudofunction.sql similarity index 58% rename from tests/sql_test_files/data/it_works_concat_str_in_pseudofunction.sql rename to tests/sql_test_files/data/concat_str_in_pseudofunction.sql index a07b15c9..724e44b1 100644 --- a/tests/sql_test_files/data/it_works_concat_str_in_pseudofunction.sql +++ b/tests/sql_test_files/data/concat_str_in_pseudofunction.sql @@ -1,3 +1,3 @@ select '%2F1' as expected, sqlpage.url_encode('/' || $x) as actual; select '%2F1' as expected, sqlpage.url_encode(CONCAT('/', $x)) as actual; -select 'NULL' as expected, coalesce(sqlpage.url_encode(CONCAT('/', $thisisnull)), 'NULL') as actual; +select NULL as expected, sqlpage.url_encode(CONCAT('/', $thisisnull)) as actual; diff --git a/tests/sql_test_files/data/it_works_cookie.sql b/tests/sql_test_files/data/cookie.sql similarity index 100% rename from tests/sql_test_files/data/it_works_cookie.sql rename to tests/sql_test_files/data/cookie.sql diff --git a/tests/sql_test_files/data/it_works_create_table.sql b/tests/sql_test_files/data/create_table.sql similarity index 100% rename from tests/sql_test_files/data/it_works_create_table.sql rename to tests/sql_test_files/data/create_table.sql diff --git a/tests/sql_test_files/data/it_works_decimal.sql b/tests/sql_test_files/data/decimal.sql similarity index 100% rename from tests/sql_test_files/data/it_works_decimal.sql rename to tests/sql_test_files/data/decimal.sql diff --git a/tests/sql_test_files/data/it_works_delayed_function_call.sql b/tests/sql_test_files/data/delayed_function_call.sql similarity index 100% rename from tests/sql_test_files/data/it_works_delayed_function_call.sql rename to tests/sql_test_files/data/delayed_function_call.sql diff --git a/tests/sql_test_files/data/env_var_empty.sql b/tests/sql_test_files/data/env_var_empty.sql new file mode 100644 index 00000000..a5c7e39b --- /dev/null +++ b/tests/sql_test_files/data/env_var_empty.sql @@ -0,0 +1,2 @@ +select NULL as expected, + sqlpage.environment_variable('I_DO_NOT_EXIST') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_exec.sql b/tests/sql_test_files/data/exec.sql similarity index 100% rename from tests/sql_test_files/data/it_works_exec.sql rename to tests/sql_test_files/data/exec.sql diff --git a/tests/sql_test_files/data/it_works_fetch_base64.sql b/tests/sql_test_files/data/fetch_base64.sql similarity index 100% rename from tests/sql_test_files/data/it_works_fetch_base64.sql rename to tests/sql_test_files/data/fetch_base64.sql diff --git a/tests/sql_test_files/data/it_works_fetch_hex.sql b/tests/sql_test_files/data/fetch_hex.sql similarity index 100% rename from tests/sql_test_files/data/it_works_fetch_hex.sql rename to tests/sql_test_files/data/fetch_hex.sql diff --git a/tests/sql_test_files/data/it_works_fetch_native_json_array_impl.sql b/tests/sql_test_files/data/fetch_native_json_array_impl.sql similarity index 100% rename from tests/sql_test_files/data/it_works_fetch_native_json_array_impl.sql rename to tests/sql_test_files/data/fetch_native_json_array_impl.sql diff --git a/tests/sql_test_files/data/it_works_fetch_post.sql b/tests/sql_test_files/data/fetch_post.sql similarity index 100% rename from tests/sql_test_files/data/it_works_fetch_post.sql rename to tests/sql_test_files/data/fetch_post.sql diff --git a/tests/sql_test_files/data/it_works_fetch_simple.sql b/tests/sql_test_files/data/fetch_simple.sql similarity index 100% rename from tests/sql_test_files/data/it_works_fetch_simple.sql rename to tests/sql_test_files/data/fetch_simple.sql diff --git a/tests/sql_test_files/data/it_works_fetch_with_meta_error.sql b/tests/sql_test_files/data/fetch_with_meta_error.sql similarity index 100% rename from tests/sql_test_files/data/it_works_fetch_with_meta_error.sql rename to tests/sql_test_files/data/fetch_with_meta_error.sql diff --git a/tests/sql_test_files/data/it_works_fetch_with_meta_simple.sql b/tests/sql_test_files/data/fetch_with_meta_simple.sql similarity index 100% rename from tests/sql_test_files/data/it_works_fetch_with_meta_simple.sql rename to tests/sql_test_files/data/fetch_with_meta_simple.sql diff --git a/tests/sql_test_files/data/it_works_hash_password.sql b/tests/sql_test_files/data/hash_password.sql similarity index 100% rename from tests/sql_test_files/data/it_works_hash_password.sql rename to tests/sql_test_files/data/hash_password.sql diff --git a/tests/sql_test_files/data/hash_password_null.sql b/tests/sql_test_files/data/hash_password_null.sql new file mode 100644 index 00000000..c39826e1 --- /dev/null +++ b/tests/sql_test_files/data/hash_password_null.sql @@ -0,0 +1 @@ +select NULL as expected, sqlpage.hash_password(null) as actual; diff --git a/tests/sql_test_files/data/it_works_header.sql b/tests/sql_test_files/data/header.sql similarity index 100% rename from tests/sql_test_files/data/it_works_header.sql rename to tests/sql_test_files/data/header.sql diff --git a/tests/sql_test_files/data/it_works_headers.sql b/tests/sql_test_files/data/headers.sql similarity index 100% rename from tests/sql_test_files/data/it_works_headers.sql rename to tests/sql_test_files/data/headers.sql diff --git a/tests/sql_test_files/data/it_works_hmac_base64.sql b/tests/sql_test_files/data/hmac_base64.sql similarity index 100% rename from tests/sql_test_files/data/it_works_hmac_base64.sql rename to tests/sql_test_files/data/hmac_base64.sql diff --git a/tests/sql_test_files/data/it_works_hmac_default.sql b/tests/sql_test_files/data/hmac_default.sql similarity index 100% rename from tests/sql_test_files/data/it_works_hmac_default.sql rename to tests/sql_test_files/data/hmac_default.sql diff --git a/tests/sql_test_files/data/it_works_hmac_sha256.sql b/tests/sql_test_files/data/hmac_sha256.sql similarity index 100% rename from tests/sql_test_files/data/it_works_hmac_sha256.sql rename to tests/sql_test_files/data/hmac_sha256.sql diff --git a/tests/sql_test_files/data/it_works_hmac_sha512.sql b/tests/sql_test_files/data/hmac_sha512.sql similarity index 100% rename from tests/sql_test_files/data/it_works_hmac_sha512.sql rename to tests/sql_test_files/data/hmac_sha512.sql diff --git a/tests/sql_test_files/data/it_works_hmac_shopify_webhook.sql b/tests/sql_test_files/data/hmac_shopify_webhook.sql similarity index 100% rename from tests/sql_test_files/data/it_works_hmac_shopify_webhook.sql rename to tests/sql_test_files/data/hmac_shopify_webhook.sql diff --git a/tests/sql_test_files/data/it_works_immutable_variables.sql b/tests/sql_test_files/data/immutable_variables.sql similarity index 100% rename from tests/sql_test_files/data/it_works_immutable_variables.sql rename to tests/sql_test_files/data/immutable_variables.sql diff --git a/tests/sql_test_files/data/it_works_client_ip.sql b/tests/sql_test_files/data/it_works_client_ip.sql deleted file mode 100644 index 918f8663..00000000 --- a/tests/sql_test_files/data/it_works_client_ip.sql +++ /dev/null @@ -1,2 +0,0 @@ -select 'NULL' as expected, - coalesce(sqlpage.client_ip(), 'NULL') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_env_var_empty.sql b/tests/sql_test_files/data/it_works_env_var_empty.sql deleted file mode 100644 index bd120ca3..00000000 --- a/tests/sql_test_files/data/it_works_env_var_empty.sql +++ /dev/null @@ -1,2 +0,0 @@ -select 'NULL' as expected, - coalesce(sqlpage.environment_variable('I_DO_NOT_EXIST'), 'NULL') as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_hash_password_null.sql b/tests/sql_test_files/data/it_works_hash_password_null.sql deleted file mode 100644 index 4755eff7..00000000 --- a/tests/sql_test_files/data/it_works_hash_password_null.sql +++ /dev/null @@ -1 +0,0 @@ -select 'NULL' as expected, coalesce(sqlpage.hash_password(null), 'NULL') as actual; diff --git a/tests/sql_test_files/data/it_works_path.sql b/tests/sql_test_files/data/it_works_path.sql deleted file mode 100644 index 23d4cc7e..00000000 --- a/tests/sql_test_files/data/it_works_path.sql +++ /dev/null @@ -1,2 +0,0 @@ -select '/tests/sql_test_files/data/it_works_path.sql' as expected, - sqlpage.path() as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_set_variable_to_null.sql b/tests/sql_test_files/data/it_works_set_variable_to_null.sql deleted file mode 100644 index 24a8d818..00000000 --- a/tests/sql_test_files/data/it_works_set_variable_to_null.sql +++ /dev/null @@ -1,3 +0,0 @@ -set i_am_null = NULL; -select 'NULL' as expected, - coalesce($i_am_null, 'NULL') as actual; diff --git a/tests/sql_test_files/data/it_works_sqrt.sql b/tests/sql_test_files/data/it_works_sqrt.sql deleted file mode 100644 index c8c00bb9..00000000 --- a/tests/sql_test_files/data/it_works_sqrt.sql +++ /dev/null @@ -1,2 +0,0 @@ -set result = sqrt(9.0); -select '3' as expected, '3.0' as expected, $result as actual; diff --git a/tests/sql_test_files/data/it_works_uploaded_file_is_null.sql b/tests/sql_test_files/data/it_works_uploaded_file_is_null.sql deleted file mode 100644 index 68d223d4..00000000 --- a/tests/sql_test_files/data/it_works_uploaded_file_is_null.sql +++ /dev/null @@ -1,3 +0,0 @@ -set actual = sqlpage.uploaded_file_path('my_file'); -select 'NULL' as expected, - coalesce($actual, 'NULL') as actual; diff --git a/tests/sql_test_files/data/it_works_link.sql b/tests/sql_test_files/data/link.sql similarity index 100% rename from tests/sql_test_files/data/it_works_link.sql rename to tests/sql_test_files/data/link.sql diff --git a/tests/sql_test_files/data/it_works_link_null.sql b/tests/sql_test_files/data/link_null.sql similarity index 100% rename from tests/sql_test_files/data/it_works_link_null.sql rename to tests/sql_test_files/data/link_null.sql diff --git a/tests/sql_test_files/data/it_works_lower.sql b/tests/sql_test_files/data/lower.sql similarity index 100% rename from tests/sql_test_files/data/it_works_lower.sql rename to tests/sql_test_files/data/lower.sql diff --git a/tests/sql_test_files/data/it_works_nested_sqlpage_functions.sql b/tests/sql_test_files/data/nested_sqlpage_functions.sql similarity index 100% rename from tests/sql_test_files/data/it_works_nested_sqlpage_functions.sql rename to tests/sql_test_files/data/nested_sqlpage_functions.sql diff --git a/tests/sql_test_files/data/path.sql b/tests/sql_test_files/data/path.sql new file mode 100644 index 00000000..31cb614a --- /dev/null +++ b/tests/sql_test_files/data/path.sql @@ -0,0 +1,2 @@ +select '/tests/sql_test_files/data/path.sql' as expected, + sqlpage.path() as actual; \ No newline at end of file diff --git a/tests/sql_test_files/data/it_works_postgres_cast_syntax.sql b/tests/sql_test_files/data/postgres_cast_syntax.sql similarity index 100% rename from tests/sql_test_files/data/it_works_postgres_cast_syntax.sql rename to tests/sql_test_files/data/postgres_cast_syntax.sql diff --git a/tests/sql_test_files/data/it_works_protocol.sql b/tests/sql_test_files/data/protocol.sql similarity index 100% rename from tests/sql_test_files/data/it_works_protocol.sql rename to tests/sql_test_files/data/protocol.sql diff --git a/tests/sql_test_files/data/it_works_query_string.sql b/tests/sql_test_files/data/query_string.sql similarity index 100% rename from tests/sql_test_files/data/it_works_query_string.sql rename to tests/sql_test_files/data/query_string.sql diff --git a/tests/sql_test_files/data/it_works_random_string.sql b/tests/sql_test_files/data/random_string.sql similarity index 100% rename from tests/sql_test_files/data/it_works_random_string.sql rename to tests/sql_test_files/data/random_string.sql diff --git a/tests/sql_test_files/data/it_works_read_file_as_data_url.sql b/tests/sql_test_files/data/read_file_as_data_url.sql similarity index 100% rename from tests/sql_test_files/data/it_works_read_file_as_data_url.sql rename to tests/sql_test_files/data/read_file_as_data_url.sql diff --git a/tests/sql_test_files/data/it_works_read_file_as_text.sql b/tests/sql_test_files/data/read_file_as_text.sql similarity index 100% rename from tests/sql_test_files/data/it_works_read_file_as_text.sql rename to tests/sql_test_files/data/read_file_as_text.sql diff --git a/tests/sql_test_files/data/it_works_request_method.sql b/tests/sql_test_files/data/request_method.sql similarity index 100% rename from tests/sql_test_files/data/it_works_request_method.sql rename to tests/sql_test_files/data/request_method.sql diff --git a/tests/sql_test_files/data/it_works_set_case.sql b/tests/sql_test_files/data/set_case.sql similarity index 100% rename from tests/sql_test_files/data/it_works_set_case.sql rename to tests/sql_test_files/data/set_case.sql diff --git a/tests/sql_test_files/data/it_works_set_variable.sql b/tests/sql_test_files/data/set_variable.sql similarity index 100% rename from tests/sql_test_files/data/it_works_set_variable.sql rename to tests/sql_test_files/data/set_variable.sql diff --git a/tests/sql_test_files/data/it_works_set_variable_func.sql b/tests/sql_test_files/data/set_variable_func.sql similarity index 100% rename from tests/sql_test_files/data/it_works_set_variable_func.sql rename to tests/sql_test_files/data/set_variable_func.sql diff --git a/tests/sql_test_files/data/it_works_set_variable_func_null.sql b/tests/sql_test_files/data/set_variable_func_null.sql similarity index 100% rename from tests/sql_test_files/data/it_works_set_variable_func_null.sql rename to tests/sql_test_files/data/set_variable_func_null.sql diff --git a/tests/sql_test_files/data/it_works_set_variable_func_replace.sql b/tests/sql_test_files/data/set_variable_func_replace.sql similarity index 100% rename from tests/sql_test_files/data/it_works_set_variable_func_replace.sql rename to tests/sql_test_files/data/set_variable_func_replace.sql diff --git a/tests/sql_test_files/data/it_works_set_variable_large_integer.sql b/tests/sql_test_files/data/set_variable_large_integer.sql similarity index 100% rename from tests/sql_test_files/data/it_works_set_variable_large_integer.sql rename to tests/sql_test_files/data/set_variable_large_integer.sql diff --git a/tests/sql_test_files/data/it_works_set_variable_numeric.sql b/tests/sql_test_files/data/set_variable_numeric.sql similarity index 100% rename from tests/sql_test_files/data/it_works_set_variable_numeric.sql rename to tests/sql_test_files/data/set_variable_numeric.sql diff --git a/tests/sql_test_files/data/set_variable_to_null.sql b/tests/sql_test_files/data/set_variable_to_null.sql new file mode 100644 index 00000000..505b9991 --- /dev/null +++ b/tests/sql_test_files/data/set_variable_to_null.sql @@ -0,0 +1,3 @@ +set i_am_null = NULL; +select NULL as expected, + $i_am_null as actual; diff --git a/tests/sql_test_files/data/it_works_set_variable_to_other_variable.sql b/tests/sql_test_files/data/set_variable_to_other_variable.sql similarity index 100% rename from tests/sql_test_files/data/it_works_set_variable_to_other_variable.sql rename to tests/sql_test_files/data/set_variable_to_other_variable.sql diff --git a/tests/sql_test_files/data/it_works_set_variable_to_sqlpage_function.sql b/tests/sql_test_files/data/set_variable_to_sqlpage_function.sql similarity index 100% rename from tests/sql_test_files/data/it_works_set_variable_to_sqlpage_function.sql rename to tests/sql_test_files/data/set_variable_to_sqlpage_function.sql diff --git a/tests/sql_test_files/data/it_works_set_variable_to_sqlpage_post_function.sql b/tests/sql_test_files/data/set_variable_to_sqlpage_post_function.sql similarity index 100% rename from tests/sql_test_files/data/it_works_set_variable_to_sqlpage_post_function.sql rename to tests/sql_test_files/data/set_variable_to_sqlpage_post_function.sql diff --git a/tests/sql_test_files/data/it_works_sqlite_unicode_upper.sql b/tests/sql_test_files/data/sqlite_unicode_upper.sql similarity index 100% rename from tests/sql_test_files/data/it_works_sqlite_unicode_upper.sql rename to tests/sql_test_files/data/sqlite_unicode_upper.sql diff --git a/tests/sql_test_files/data/sqrt.sql b/tests/sql_test_files/data/sqrt.sql new file mode 100644 index 00000000..3dd2ade5 --- /dev/null +++ b/tests/sql_test_files/data/sqrt.sql @@ -0,0 +1,2 @@ +set result = sqrt(9.0); +select 3 as expected, cast($result as integer) as actual; diff --git a/tests/sql_test_files/data/uploaded_file_is_null.sql b/tests/sql_test_files/data/uploaded_file_is_null.sql new file mode 100644 index 00000000..86fcc53a --- /dev/null +++ b/tests/sql_test_files/data/uploaded_file_is_null.sql @@ -0,0 +1,2 @@ +set actual = sqlpage.uploaded_file_path('my_file'); +select null as expected, $actual as actual; diff --git a/tests/sql_test_files/data/it_works_url_encode.sql b/tests/sql_test_files/data/url_encode.sql similarity index 100% rename from tests/sql_test_files/data/it_works_url_encode.sql rename to tests/sql_test_files/data/url_encode.sql diff --git a/tests/sql_test_files/data/it_works_varchar_nomysql.sql b/tests/sql_test_files/data/varchar_nomysql.sql similarity index 100% rename from tests/sql_test_files/data/it_works_varchar_nomysql.sql rename to tests/sql_test_files/data/varchar_nomysql.sql diff --git a/tests/sql_test_files/data/it_works_variables_function.sql b/tests/sql_test_files/data/variables_function.sql similarity index 100% rename from tests/sql_test_files/data/it_works_variables_function.sql rename to tests/sql_test_files/data/variables_function.sql diff --git a/tests/sql_test_files/data/it_works_variables_function_get_and_post.sql b/tests/sql_test_files/data/variables_function_get_and_post.sql similarity index 100% rename from tests/sql_test_files/data/it_works_variables_function_get_and_post.sql rename to tests/sql_test_files/data/variables_function_get_and_post.sql diff --git a/tests/sql_test_files/mod.rs b/tests/sql_test_files/mod.rs index e2a9c252..df259e94 100644 --- a/tests/sql_test_files/mod.rs +++ b/tests/sql_test_files/mod.rs @@ -138,14 +138,15 @@ fn assert_json_test(body: &str, test_file: &std::path::Path) { let actual = obj .get("actual") - .map(json_to_string) - .unwrap_or_else(|| "NULL".to_string()); + .cloned() + .unwrap_or(serde_json::Value::Null); + let actual_str = json_to_string(&actual); - let expected: Vec = obj + let expected: Vec = obj .get("expected") .map(|v| match v { - serde_json::Value::Array(arr) => arr.iter().map(json_to_string).collect(), - _ => vec![json_to_string(v)], + serde_json::Value::Array(arr) => arr.clone(), + _ => vec![v.clone()], }) .unwrap_or_default(); @@ -166,13 +167,14 @@ fn assert_json_test(body: &str, test_file: &std::path::Path) { } let exact_ok = expected.is_empty() || expected.iter().any(|e| e == &actual); - let contains_ok = - expected_contains.is_empty() || expected_contains.iter().all(|e| actual.contains(e)); + let contains_ok = expected_contains.is_empty() + || expected_contains.iter().all(|e| actual_str.contains(e)); if !exact_ok || !contains_ok { let mut msg = format!("Test failed: {}\n", test_file.display()); if !expected.is_empty() { - msg.push_str(&format!("Expected: {}\n", expected.join(" or "))); + let expected_strs: Vec = expected.iter().map(|d| d.to_string()).collect(); + msg.push_str(&format!("Expected: {}\n", expected_strs.join(" or "))); } if !expected_contains.is_empty() { msg.push_str(&format!( @@ -180,7 +182,7 @@ fn assert_json_test(body: &str, test_file: &std::path::Path) { expected_contains.join(", ") )); } - msg.push_str(&format!("Actual: {}\n", actual)); + msg.push_str(&format!("Actual: {}\n", actual)); panic!("{}", msg); } } @@ -193,7 +195,15 @@ fn assert_html_test(body: &str, test_file: &std::path::Path, stem: &str) { test_file.display() ); - if stem.starts_with("it_works") { + if stem.starts_with("error_") { + let expected = stem.strip_prefix("error_").unwrap().replace('_', " "); + assert!( + body.to_lowercase().contains(&expected.to_lowercase()), + "Should contain '{}': {}", + expected, + test_file.display() + ); + } else { if let Some(error) = extract_error(body) { panic!("Error in {}: {}", test_file.display(), error); } @@ -207,14 +217,6 @@ fn assert_html_test(body: &str, test_file: &std::path::Path, stem: &str) { "Unexpected error: {}", test_file.display() ); - } else if stem.starts_with("error_") { - let expected = stem.strip_prefix("error_").unwrap().replace('_', " "); - assert!( - body.to_lowercase().contains(&expected.to_lowercase()), - "Should contain '{}': {}", - expected, - test_file.display() - ); } } diff --git a/tests/sql_test_files/select_temp_t.sql b/tests/sql_test_files/select_temp_t.sql index ff25e2da..e94287b7 100644 --- a/tests/sql_test_files/select_temp_t.sql +++ b/tests/sql_test_files/select_temp_t.sql @@ -1,2 +1,2 @@ --- see tests/sql_test_files/component_rendering/it_works_temp_table_accessible_in_run_sql_nomssql.sql +-- see tests/sql_test_files/component_rendering/temp_table_accessible_in_run_sql_nomssql.sql select 'text' as component, x as contents from temp_t; \ No newline at end of file diff --git a/tests/transactions/mod.rs b/tests/transactions/mod.rs index 37759729..dc9e7417 100644 --- a/tests/transactions/mod.rs +++ b/tests/transactions/mod.rs @@ -79,9 +79,9 @@ async fn test_failed_copy_followed_by_query() -> actix_web::Result<()> { } // Now make other requests to verify the connection is still usable for path in [ - "/tests/sql_test_files/component_rendering/it_works_simple.sql", - "/tests/sql_test_files/component_rendering/it_works_text_markdown.sql", - "/tests/sql_test_files/component_rendering/it_works_text_unsafe_markdown.sql", + "/tests/sql_test_files/component_rendering/simple.sql", + "/tests/sql_test_files/component_rendering/text_markdown.sql", + "/tests/sql_test_files/component_rendering/text_unsafe_markdown.sql", ] { let req = get_request_to_with_data(path, app_data.clone()) .await? From 065b6b976d0582c02dec8af4eca021b10c9c5f3d Mon Sep 17 00:00:00 2001 From: lovasoa Date: Tue, 25 Nov 2025 11:47:19 +0100 Subject: [PATCH 4/5] Enhance error handling in SQL tests and update SQL syntax - Added a new function `format_error` to improve error reporting in SQL test assertions, capturing detailed error descriptions and backtraces. - Updated SQL syntax in `sqrt.sql` to use `INT` instead of `integer` for consistency with SQL standards. --- tests/sql_test_files/data/sqrt.sql | 2 +- tests/sql_test_files/mod.rs | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/sql_test_files/data/sqrt.sql b/tests/sql_test_files/data/sqrt.sql index 3dd2ade5..f66c6408 100644 --- a/tests/sql_test_files/data/sqrt.sql +++ b/tests/sql_test_files/data/sqrt.sql @@ -1,2 +1,2 @@ set result = sqrt(9.0); -select 3 as expected, cast($result as integer) as actual; +select 3 as expected, cast($result as INT) as actual; diff --git a/tests/sql_test_files/mod.rs b/tests/sql_test_files/mod.rs index df259e94..a3b21e34 100644 --- a/tests/sql_test_files/mod.rs +++ b/tests/sql_test_files/mod.rs @@ -120,6 +120,24 @@ async fn run_sql_test( } } +fn format_error(obj: &serde_json::Map) -> Option { + if obj.get("component").and_then(|v| v.as_str()) != Some("error") { + return None; + } + let mut msg = String::new(); + if let Some(desc) = obj.get("description").and_then(|v| v.as_str()) { + msg.push_str(desc); + } + if let Some(bt) = obj.get("backtrace").and_then(|v| v.as_array()) { + for frame in bt { + if let Some(s) = frame.as_str() { + msg.push_str(&format!("\n {}", s)); + } + } + } + Some(msg) +} + fn assert_json_test(body: &str, test_file: &std::path::Path) { let rows: Vec = serde_json::from_str(body) .unwrap_or_else(|_| panic!("Invalid JSON: {}", test_file.display())); @@ -136,6 +154,10 @@ fn assert_json_test(body: &str, test_file: &std::path::Path) { None => continue, }; + if let Some(err) = format_error(obj) { + panic!("Error in {}:\n{}", test_file.display(), err); + } + let actual = obj .get("actual") .cloned() From 10334d32490909ce15168b4a51857b91a37b1e24 Mon Sep 17 00:00:00 2001 From: lovasoa Date: Wed, 26 Nov 2025 00:36:25 +0100 Subject: [PATCH 5/5] sqrt test --- tests/sql_test_files/data/sqrt.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sql_test_files/data/sqrt.sql b/tests/sql_test_files/data/sqrt.sql index f66c6408..921a46fc 100644 --- a/tests/sql_test_files/data/sqrt.sql +++ b/tests/sql_test_files/data/sqrt.sql @@ -1,2 +1,2 @@ set result = sqrt(9.0); -select 3 as expected, cast($result as INT) as actual; +select CAST(3.0 AS FLOAT) as expected, cast($result as FLOAT) as actual;