From 6e9709ce00dbfb2eb5e04308643c2db6c1bc4bb2 Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Sat, 20 Dec 2025 11:24:34 -0500 Subject: [PATCH] parser: use annotate-snippets in parser errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit instead of: ``` ERROR@124: unexpected trailing comma ``` we now show ``` error[syntax-error]: unexpected trailing comma ╭▸ 4 │ array['a', 'b', 'c',] as y, ╰╴ ━ ``` which should make debugging test errors a little easier --- Cargo.lock | 1 + crates/squawk_parser/Cargo.toml | 1 + ...tests__alter_foreign_data_wrapper_err.snap | 5 +- .../snapshots/tests__alter_sequence_err.snap | 5 +- .../snapshots/tests__alter_server_err.snap | 5 +- .../snapshots/tests__alter_table_err.snap | 35 ++++- .../tests/snapshots/tests__copy_err.snap | 10 +- .../snapshots/tests__create_function_err.snap | 24 ++- .../snapshots/tests__create_index_err.snap | 5 +- .../snapshots/tests__create_table_err.snap | 67 ++++++-- .../snapshots/tests__drop_database_err.snap | 5 +- .../snapshots/tests__drop_table_err.snap | 10 +- .../tests/snapshots/tests__insert_err.snap | 25 ++- .../tests/snapshots/tests__prepare_err.snap | 10 +- .../tests/snapshots/tests__reindex_err.snap | 10 +- .../snapshots/tests__select_cte_err.snap | 30 +++- .../tests/snapshots/tests__select_err.snap | 145 ++++++++++++++---- .../tests/snapshots/tests__update_err.snap | 10 +- .../tests/snapshots/tests__vacuum_err.snap | 10 +- .../tests/snapshots/tests__values_err.snap | 15 +- crates/squawk_parser/tests/tests.rs | 31 +++- 21 files changed, 368 insertions(+), 91 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54cab5d1..3af00dd1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1915,6 +1915,7 @@ dependencies = [ name = "squawk-parser" version = "2.33.2" dependencies = [ + "annotate-snippets", "camino", "dir-test", "drop_bomb", diff --git a/crates/squawk_parser/Cargo.toml b/crates/squawk_parser/Cargo.toml index 521cae1e..d5938943 100644 --- a/crates/squawk_parser/Cargo.toml +++ b/crates/squawk_parser/Cargo.toml @@ -24,6 +24,7 @@ dir-test.workspace = true camino.workspace = true pg_query.workspace = true xshell.workspace = true +annotate-snippets.workspace = true [lints] workspace = true diff --git a/crates/squawk_parser/tests/snapshots/tests__alter_foreign_data_wrapper_err.snap b/crates/squawk_parser/tests/snapshots/tests__alter_foreign_data_wrapper_err.snap index 6c8043d9..039eba0c 100644 --- a/crates/squawk_parser/tests/snapshots/tests__alter_foreign_data_wrapper_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__alter_foreign_data_wrapper_err.snap @@ -19,4 +19,7 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@46: Missing alter foreign data wrapper option or action. +error[syntax-error]: Missing alter foreign data wrapper option or action. + ╭▸ +2 │ alter foreign data wrapper w; + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__alter_sequence_err.snap b/crates/squawk_parser/tests/snapshots/tests__alter_sequence_err.snap index a22cabfb..75b98b8d 100644 --- a/crates/squawk_parser/tests/snapshots/tests__alter_sequence_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__alter_sequence_err.snap @@ -17,4 +17,7 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@34: expected ALTER SEQUENCE option +error[syntax-error]: expected ALTER SEQUENCE option + ╭▸ +2 │ alter sequence s; + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__alter_server_err.snap b/crates/squawk_parser/tests/snapshots/tests__alter_server_err.snap index 8ae235f1..1ce500bf 100644 --- a/crates/squawk_parser/tests/snapshots/tests__alter_server_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__alter_server_err.snap @@ -15,4 +15,7 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@32: expected ALTER SERVER option +error[syntax-error]: expected ALTER SERVER option + ╭▸ +2 │ alter server s; + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__alter_table_err.snap b/crates/squawk_parser/tests/snapshots/tests__alter_table_err.snap index 5fa220d2..37080ba0 100644 --- a/crates/squawk_parser/tests/snapshots/tests__alter_table_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__alter_table_err.snap @@ -210,10 +210,31 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@23: expected command, found ADD_KW -ERROR@27: expected command, found COLUMN_KW -ERROR@34: expected command, found IDENT -ERROR@38: expected command, found BOOLEAN_KW -ERROR@175: missing comma -ERROR@505: expected COMMA -ERROR@570: unexpected comma +error[syntax-error]: expected command, found ADD_KW + ╭▸ +2 │ add column foo boolean; + ╰╴━ +error[syntax-error]: expected command, found COLUMN_KW + ╭▸ +2 │ add column foo boolean; + ╰╴ ━ +error[syntax-error]: expected command, found IDENT + ╭▸ +2 │ add column foo boolean; + ╰╴ ━ +error[syntax-error]: expected command, found BOOLEAN_KW + ╭▸ +2 │ add column foo boolean; + ╰╴ ━ +error[syntax-error]: missing comma + ╭▸ +8 │ validate constraint foo validate constraint b ; + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +16 │ alter c set (a b = 1); + ╰╴ ━ +error[syntax-error]: unexpected comma + ╭▸ +20 │ alter c set (a, , b = 1); + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__copy_err.snap b/crates/squawk_parser/tests/snapshots/tests__copy_err.snap index d3af7acb..59a9c5eb 100644 --- a/crates/squawk_parser/tests/snapshots/tests__copy_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__copy_err.snap @@ -43,5 +43,11 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@36: expected COMMA -ERROR@79: expected COMMA +error[syntax-error]: expected COMMA + ╭▸ +2 │ copy x (i y) from '/tmp/input.file' (on_error ignore log_verbosity verbose); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +2 │ copy x (i y) from '/tmp/input.file' (on_error ignore log_verbosity verbose); + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__create_function_err.snap b/crates/squawk_parser/tests/snapshots/tests__create_function_err.snap index 87d242a6..58dbe804 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_function_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_function_err.snap @@ -129,7 +129,23 @@ SOURCE_FILE FUNCTION_KW "function" WHITESPACE "\n\n" --- -ERROR@58: expected COMMA -ERROR@121: expected COMMA -ERROR@249: expected path name -ERROR@249: expected param list +error[syntax-error]: expected COMMA + ╭▸ +3 │ returns table (a text b int) + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +6 │ create function foo(arg float = 1 int4 = 4) + ╰╴ ━ +error[syntax-error]: expected path name + ╭▸ +13 │ create function + │ ┏━━━━━━━━━━━━━━━━┛ +14 │ ┃ + ╰╴┗━┛ +error[syntax-error]: expected param list + ╭▸ +13 │ create function + │ ┏━━━━━━━━━━━━━━━━┛ +14 │ ┃ + ╰╴┗━┛ diff --git a/crates/squawk_parser/tests/snapshots/tests__create_index_err.snap b/crates/squawk_parser/tests/snapshots/tests__create_index_err.snap index 37c746d6..45bf5ad6 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_index_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_index_err.snap @@ -44,4 +44,7 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@51: expected COMMA +error[syntax-error]: expected COMMA + ╭▸ +2 │ create index i on t (a nulls first b nulls first); + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__create_table_err.snap b/crates/squawk_parser/tests/snapshots/tests__create_table_err.snap index 5e0de8df..0fb733c5 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_table_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_table_err.snap @@ -673,16 +673,57 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@39: expected path name -ERROR@143: unexpected trailing comma -ERROR@197: unexpected comma -ERROR@198: unexpected comma -ERROR@199: unexpected comma -ERROR@200: unexpected comma -ERROR@201: unexpected comma -ERROR@1011: expected COMMA -ERROR@1032: expected COMMA -ERROR@1116: expected COMMA -ERROR@1119: expected COMMA -ERROR@1226: expected COMMA -ERROR@1268: expected SEMICOLON +error[syntax-error]: expected path name + ╭▸ +2 │ create table ( + ╰╴ ━ +error[syntax-error]: unexpected trailing comma + ╭▸ +10 │ create table t (a text,); + ╰╴ ━ +error[syntax-error]: unexpected comma + ╭▸ +13 │ create table t (,,,,,); + ╰╴ ━ +error[syntax-error]: unexpected comma + ╭▸ +13 │ create table t (,,,,,); + ╰╴ ━ +error[syntax-error]: unexpected comma + ╭▸ +13 │ create table t (,,,,,); + ╰╴ ━ +error[syntax-error]: unexpected comma + ╭▸ +13 │ create table t (,,,,,); + ╰╴ ━ +error[syntax-error]: unexpected comma + ╭▸ +13 │ create table t (,,,,,); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +51 │ for values from ('2024-01-01' 1) to ('2024-04-01' 5); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +51 │ for values from ('2024-01-01' 1) to ('2024-04-01' 5); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +55 │ for values in (1 2 3); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +55 │ for values in (1 2 3); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +61 │ exclude using btree ( a with buzz.> b with <) + ╰╴ ━ +error[syntax-error]: expected SEMICOLON + ╭▸ +66 │ ) + │ ┏━━┛ +67 │ ┃ -- ^ missing semi + ╰╴┗━┛ diff --git a/crates/squawk_parser/tests/snapshots/tests__drop_database_err.snap b/crates/squawk_parser/tests/snapshots/tests__drop_database_err.snap index 066e844a..a586fa99 100644 --- a/crates/squawk_parser/tests/snapshots/tests__drop_database_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__drop_database_err.snap @@ -25,4 +25,7 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@45: expected COMMA +error[syntax-error]: expected COMMA + ╭▸ +2 │ drop database d with ( force force ); + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__drop_table_err.snap b/crates/squawk_parser/tests/snapshots/tests__drop_table_err.snap index 3c8f5618..b38c1bf1 100644 --- a/crates/squawk_parser/tests/snapshots/tests__drop_table_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__drop_table_err.snap @@ -54,5 +54,11 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@36: expected COMMA -ERROR@86: unexpected comma, expected a name +error[syntax-error]: expected COMMA + ╭▸ +2 │ drop table foo, bar buzz cascade; + ╰╴ ━ +error[syntax-error]: unexpected comma, expected a name + ╭▸ +5 │ drop table foo, , buzz cascade; + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__insert_err.snap b/crates/squawk_parser/tests/snapshots/tests__insert_err.snap index f3ca7a90..50a5a2ee 100644 --- a/crates/squawk_parser/tests/snapshots/tests__insert_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__insert_err.snap @@ -176,8 +176,23 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@51: expected COMMA -ERROR@168: missing column -ERROR@170: unexpected trailing comma -ERROR@301: expected COMMA -ERROR@304: unexpected trailing comma +error[syntax-error]: expected COMMA + ╭▸ +2 │ insert into t (a, b c) + ╰╴ ━ +error[syntax-error]: missing column + ╭▸ +7 │ insert into t (a,,c,) + ╰╴ ━ +error[syntax-error]: unexpected trailing comma + ╭▸ +7 │ insert into t (a,,c,) + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +13 │ values (4, 5 6,) + ╰╴ ━ +error[syntax-error]: unexpected trailing comma + ╭▸ +13 │ values (4, 5 6,) + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__prepare_err.snap b/crates/squawk_parser/tests/snapshots/tests__prepare_err.snap index 6c80e12f..79700222 100644 --- a/crates/squawk_parser/tests/snapshots/tests__prepare_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__prepare_err.snap @@ -78,5 +78,11 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@38: expected COMMA -ERROR@44: expected COMMA +error[syntax-error]: expected COMMA + ╭▸ +2 │ PREPARE fooplan (int text bool, numeric) AS + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +2 │ PREPARE fooplan (int text bool, numeric) AS + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__reindex_err.snap b/crates/squawk_parser/tests/snapshots/tests__reindex_err.snap index 08e3be68..cbf54962 100644 --- a/crates/squawk_parser/tests/snapshots/tests__reindex_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__reindex_err.snap @@ -28,5 +28,11 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@39: expected COMMA -ERROR@47: expected COMMA +error[syntax-error]: expected COMMA + ╭▸ +2 │ reindex (concurrently verbose tablespace t) index i; + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +2 │ reindex (concurrently verbose tablespace t) index i; + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap b/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap index fbe3111f..2c8bde7b 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap @@ -333,9 +333,27 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@24: unexpected comma -ERROR@140: unexpected comma, expected a column name -ERROR@270: expected COMMA -ERROR@357: missing comma -ERROR@492: missing comma -ERROR@645: unexpected comma +error[syntax-error]: unexpected comma + ╭▸ +3 │ ), -- <--- extra comma! + ╰╴ ━ +error[syntax-error]: unexpected comma, expected a column name + ╭▸ +8 │ search depth first by a, , c set ordercol + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +13 │ search depth first by a, b c set ordercol + ╰╴ ━ +error[syntax-error]: missing comma + ╭▸ +19 │ ) -- <-- missing a comma + ╰╴ ━ +error[syntax-error]: missing comma + ╭▸ +29 │ ) -- <-- missing a comma + ╰╴ ━ +error[syntax-error]: unexpected comma + ╭▸ +38 │ ), -- <-- extra comma + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__select_err.snap b/crates/squawk_parser/tests/snapshots/tests__select_err.snap index 28b2beb0..ce53c218 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_err.snap @@ -699,32 +699,119 @@ SOURCE_FILE COMMA "," WHITESPACE "\n" --- -ERROR@124: unexpected trailing comma -ERROR@153: unexpected trailing comma -ERROR@213: unexpected trailing comma -ERROR@248: missing comma -ERROR@378: expected COMMA -ERROR@494: expected COMMA -ERROR@496: expected COMMA -ERROR@533: expected COMMA -ERROR@535: expected COMMA -ERROR@583: expected COMMA -ERROR@586: expected COMMA -ERROR@663: unexpected trailing comma -ERROR@695: expected expression -ERROR@696: expected expression -ERROR@697: expected expression -ERROR@698: expected expression -ERROR@821: missing comma -ERROR@860: expected COMMA -ERROR@898: unexpected comma -ERROR@939: unexpected trailing comma -ERROR@1009: expected COMMA -ERROR@1047: unexpected comma -ERROR@1079: unexpected trailing comma -ERROR@1203: expected SEMICOLON -ERROR@1236: unexpected trailing comma -ERROR@1296: expected an expression, found END_KW -ERROR@1345: expected an expression, found THEN_KW -ERROR@1415: expected an expression, found END_KW -ERROR@1455: unexpected trailing comma +error[syntax-error]: unexpected trailing comma + ╭▸ +4 │ array['a', 'b', 'c',] as y, + ╰╴ ━ +error[syntax-error]: unexpected trailing comma + ╭▸ +5 │ 'hello world' as z, + ╰╴ ━ +error[syntax-error]: unexpected trailing comma + ╭▸ +9 │ select * from t as u(a,); + ╰╴ ━ +error[syntax-error]: missing comma + ╭▸ +12 │ select a, b c d, e from t; + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +17 │ SELECT DISTINCT ON (a b) a, b, c + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +22 │ select * from t group by rollup (1 2 3); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +22 │ select * from t group by rollup (1 2 3); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +23 │ select * from t group by cube (1 2 3); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +23 │ select * from t group by cube (1 2 3); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +25 │ group by grouping sets((1 2) grouping sets((), grouping sets(()))); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +25 │ group by grouping sets((1 2) grouping sets((), grouping sets(()))); + ╰╴ ━ +error[syntax-error]: unexpected trailing comma + ╭▸ +28 │ select f(1,); + ╰╴ ━ +error[syntax-error]: expected expression + ╭▸ +31 │ select f(a,,,,,); + ╰╴ ━ +error[syntax-error]: expected expression + ╭▸ +31 │ select f(a,,,,,); + ╰╴ ━ +error[syntax-error]: expected expression + ╭▸ +31 │ select f(a,,,,,); + ╰╴ ━ +error[syntax-error]: expected expression + ╭▸ +31 │ select f(a,,,,,); + ╰╴ ━ +error[syntax-error]: missing comma + ╭▸ +37 │ select numeric 1234; + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +40 │ select array[1 2,3]; + ╰╴ ━ +error[syntax-error]: unexpected comma + ╭▸ +42 │ select array[1, ,3]; + ╰╴ ━ +error[syntax-error]: unexpected trailing comma + ╭▸ +44 │ select array[1,2,3,]; + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +47 │ select cast(x as varchar(100 200)); + ╰╴ ━ +error[syntax-error]: unexpected comma + ╭▸ +48 │ select cast(x as varchar(100, , 200)); + ╰╴ ━ +error[syntax-error]: unexpected trailing comma + ╭▸ +49 │ select cast(x as t(a, b,)); + ╰╴ ━ +error[syntax-error]: expected SEMICOLON + ╭▸ +53 │ select select; + ╰╴ ━ +error[syntax-error]: unexpected trailing comma + ╭▸ +56 │ select a, from t; + ╰╴ ━ +error[syntax-error]: expected an expression, found END_KW + ╭▸ +59 │ select case when 1 then end; + ╰╴ ━ +error[syntax-error]: expected an expression, found THEN_KW + ╭▸ +62 │ select case when then x end; + ╰╴ ━ +error[syntax-error]: expected an expression, found END_KW + ╭▸ +65 │ select case when 1 then 2 else end; + ╰╴ ━ +error[syntax-error]: unexpected trailing comma + ╭▸ +68 │ select 1, + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__update_err.snap b/crates/squawk_parser/tests/snapshots/tests__update_err.snap index 851e452b..d50e341d 100644 --- a/crates/squawk_parser/tests/snapshots/tests__update_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__update_err.snap @@ -84,5 +84,11 @@ SOURCE_FILE COMMENT "-- ^ missing comma" WHITESPACE "\n" --- -ERROR@15: expected COMMA -ERROR@79: expected COMMA +error[syntax-error]: expected COMMA + ╭▸ +1 │ update t set (j k) = (1, 2); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +4 │ update t set a = 1 b = 2; + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__vacuum_err.snap b/crates/squawk_parser/tests/snapshots/tests__vacuum_err.snap index ddca3753..4b1eae8b 100644 --- a/crates/squawk_parser/tests/snapshots/tests__vacuum_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__vacuum_err.snap @@ -28,5 +28,11 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@35: expected COMMA -ERROR@49: expected COMMA +error[syntax-error]: expected COMMA + ╭▸ +2 │ vacuum (full analyze false skip_locked true); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +2 │ vacuum (full analyze false skip_locked true); + ╰╴ ━ diff --git a/crates/squawk_parser/tests/snapshots/tests__values_err.snap b/crates/squawk_parser/tests/snapshots/tests__values_err.snap index 6b125d6d..b7facad4 100644 --- a/crates/squawk_parser/tests/snapshots/tests__values_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__values_err.snap @@ -48,6 +48,15 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n" --- -ERROR@66: unexpected trailing comma -ERROR@68: expected COMMA -ERROR@120: expected L_PAREN +error[syntax-error]: unexpected trailing comma + ╭▸ +3 │ values (1,) (1); + ╰╴ ━ +error[syntax-error]: expected COMMA + ╭▸ +3 │ values (1,) (1); + ╰╴ ━ +error[syntax-error]: expected L_PAREN + ╭▸ +6 │ values (1),, (2); + ╰╴ ━ diff --git a/crates/squawk_parser/tests/tests.rs b/crates/squawk_parser/tests/tests.rs index 8b48511d..b1afb547 100644 --- a/crates/squawk_parser/tests/tests.rs +++ b/crates/squawk_parser/tests/tests.rs @@ -1,4 +1,5 @@ // based on https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/tests.rs +use annotate_snippets::{AnnotationKind, Level, Renderer, Snippet, renderer::DecorStyle}; use camino::Utf8Path; use dir_test::{Fixture, dir_test}; use insta::{assert_snapshot, with_settings}; @@ -137,8 +138,7 @@ fn parse_text(text: &str) -> (String, Vec) { } squawk_parser::StrStep::Error { msg, pos } => { assert!(depth > 0); - let err = "ERROR"; - errors.push(format!("{err}@{pos}: {msg}\n")); + errors.push((pos, msg.to_string())); } }); assert_eq!( @@ -151,15 +151,32 @@ fn parse_text(text: &str) -> (String, Vec) { for (token, msg) in lexed.errors() { let pos = lexed.text_start(token); - let err = "ERROR"; - errors.push(format!("{err}@{pos}: {msg}\n")); + errors.push((pos, msg.to_string())); } if !errors.is_empty() { + errors.sort_by_key(|(pos, _)| *pos); + buf.push_str("---\n"); - for e in &errors { - buf.push_str(e); + + let renderer = Renderer::plain().decor_style(DecorStyle::Unicode); + + for (pos, msg) in &errors { + let group = Level::ERROR.primary_title(msg).id("syntax-error").element( + Snippet::source(text) + .fold(true) + .annotation(AnnotationKind::Primary.span(*pos..*pos + 1)), + ); + let rendered = renderer.render(&[group]).to_string(); + + buf.push_str(&rendered); + buf.push('\n'); } } - (buf, errors) + + let error_vec = errors + .iter() + .map(|(pos, msg)| format!("ERROR@{pos}: {msg}\n")) + .collect(); + (buf, error_vec) }