@@ -829,5 +829,164 @@ describe('Language Service', () => {
829829 const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
830830 expect ( diagnostics ) . toEqual ( [ ] ) ;
831831 } ) ;
832+
833+ // Extended diagnostics tests for syntax errors
834+ // These tests verify that parser errors are properly converted to diagnostics
835+ describe ( 'syntax error diagnostics' , ( ) => {
836+ it ( 'should detect unclosed string literal with double quotes' , ( ) => {
837+ const text = '"hello world' ;
838+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
839+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
840+
841+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
842+ // Parser reports this as 'Unknown character' since unclosed string is not tokenized
843+ const stringDiag = diagnostics . find ( d => d . message . includes ( 'Unknown character' ) ) ;
844+ expect ( stringDiag ) . toBeDefined ( ) ;
845+ expect ( stringDiag ?. severity ) . toBe ( DiagnosticSeverity . Error ) ;
846+ } ) ;
847+
848+ it ( 'should detect unclosed string literal with single quotes' , ( ) => {
849+ const text = "'hello world" ;
850+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
851+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
852+
853+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
854+ // Parser reports this as 'Unknown character' since unclosed string is not tokenized
855+ const stringDiag = diagnostics . find ( d => d . message . includes ( 'Unknown character' ) ) ;
856+ expect ( stringDiag ) . toBeDefined ( ) ;
857+ } ) ;
858+
859+ it ( 'should detect unclosed parenthesis' , ( ) => {
860+ const text = '(1 + 2' ;
861+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
862+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
863+
864+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
865+ // Parser expects closing parenthesis
866+ const parenDiag = diagnostics . find ( d => d . message . includes ( 'Expected )' ) ) ;
867+ expect ( parenDiag ) . toBeDefined ( ) ;
868+ } ) ;
869+
870+ it ( 'should detect unclosed bracket' , ( ) => {
871+ const text = '[1, 2, 3' ;
872+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
873+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
874+
875+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
876+ // Parser reports unexpected end of input
877+ const bracketDiag = diagnostics . find ( d => d . message . includes ( 'Unexpected token' ) ) ;
878+ expect ( bracketDiag ) . toBeDefined ( ) ;
879+ } ) ;
880+
881+ it ( 'should detect unclosed brace' , ( ) => {
882+ const text = '{a: 1, b: 2' ;
883+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
884+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
885+
886+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
887+ // Parser reports invalid object definition
888+ const braceDiag = diagnostics . find ( d => d . message . includes ( 'invalid object definition' ) ) ;
889+ expect ( braceDiag ) . toBeDefined ( ) ;
890+ } ) ;
891+
892+ it ( 'should detect unexpected closing parenthesis' , ( ) => {
893+ const text = '1 + 2)' ;
894+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
895+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
896+
897+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
898+ // Parser expects EOF but found )
899+ const parenDiag = diagnostics . find ( d => d . message . includes ( 'Expected EOF' ) ) ;
900+ expect ( parenDiag ) . toBeDefined ( ) ;
901+ } ) ;
902+
903+ it ( 'should detect unexpected closing bracket' , ( ) => {
904+ const text = '1 + 2]' ;
905+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
906+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
907+
908+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
909+ // Parser expects EOF but found ]
910+ const bracketDiag = diagnostics . find ( d => d . message . includes ( 'Expected EOF' ) ) ;
911+ expect ( bracketDiag ) . toBeDefined ( ) ;
912+ } ) ;
913+
914+ it ( 'should detect unexpected closing brace' , ( ) => {
915+ const text = '1 + 2}' ;
916+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
917+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
918+
919+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
920+ // Parser expects EOF but found }
921+ const braceDiag = diagnostics . find ( d => d . message . includes ( 'Expected EOF' ) ) ;
922+ expect ( braceDiag ) . toBeDefined ( ) ;
923+ } ) ;
924+
925+ it ( 'should detect unclosed comment' , ( ) => {
926+ const text = '1 + /* this is a comment 2' ;
927+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
928+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
929+
930+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
931+ // Parser reports unexpected end of input
932+ const commentDiag = diagnostics . find ( d => d . message . includes ( 'Unexpected token' ) ) ;
933+ expect ( commentDiag ) . toBeDefined ( ) ;
934+ } ) ;
935+
936+ it ( 'should detect unknown character' , ( ) => {
937+ const text = '1 @ 2' ;
938+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
939+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
940+
941+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
942+ const unknownCharDiag = diagnostics . find ( d => d . message . includes ( 'Unknown character' ) ) ;
943+ expect ( unknownCharDiag ) . toBeDefined ( ) ;
944+ } ) ;
945+
946+ it ( 'should not report errors for valid closed strings' , ( ) => {
947+ const text = '"hello" + "world"' ;
948+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
949+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
950+ expect ( diagnostics ) . toEqual ( [ ] ) ;
951+ } ) ;
952+
953+ it ( 'should not report errors for valid closed brackets' , ( ) => {
954+ const text = '(1 + 2) * [3, 4][0]' ;
955+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
956+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
957+ expect ( diagnostics ) . toEqual ( [ ] ) ;
958+ } ) ;
959+
960+ it ( 'should not report errors for valid closed comments' , ( ) => {
961+ const text = '1 + /* comment */ 2' ;
962+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
963+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
964+ expect ( diagnostics ) . toEqual ( [ ] ) ;
965+ } ) ;
966+
967+ it ( 'should handle nested brackets correctly' , ( ) => {
968+ const text = '((1 + 2) * (3 + 4))' ;
969+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
970+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
971+ expect ( diagnostics ) . toEqual ( [ ] ) ;
972+ } ) ;
973+
974+ it ( 'should handle escaped quotes in strings' , ( ) => {
975+ const text = '"hello \\"world\\""' ;
976+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
977+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
978+ expect ( diagnostics ) . toEqual ( [ ] ) ;
979+ } ) ;
980+
981+ it ( 'should detect syntax errors in complex expressions' , ( ) => {
982+ const text = '(1 + "unclosed' ;
983+ const doc = TextDocument . create ( 'file://test' , 'plaintext' , 1 , text ) ;
984+ const diagnostics = ls . getDiagnostics ( { textDocument : doc } ) ;
985+
986+ // Parser will report the first error it encounters (unknown character for unclosed string)
987+ expect ( diagnostics . length ) . toBeGreaterThanOrEqual ( 1 ) ;
988+ expect ( diagnostics [ 0 ] . severity ) . toBe ( DiagnosticSeverity . Error ) ;
989+ } ) ;
990+ } ) ;
832991 } ) ;
833992} ) ;
0 commit comments