@@ -354,4 +354,123 @@ private void doOpen() throws IOException {
354354 params .setTextDocument (getTextDocumentItem ());
355355 textDocumentService .didOpen (params );
356356 }
357+
358+ // Tests for getOffset method
359+
360+ @ Test
361+ void getOffset_emptyContent () {
362+ // Empty content should return 0 for any position
363+ assertThat (BSLTextDocumentService .getOffset ("" , 0 , 0 )).isZero ();
364+ assertThat (BSLTextDocumentService .getOffset ("" , 0 , 5 )).isZero ();
365+ assertThat (BSLTextDocumentService .getOffset ("" , 1 , 0 )).isZero ();
366+ assertThat (BSLTextDocumentService .getOffset ("" , 5 , 10 )).isZero ();
367+ }
368+
369+ @ Test
370+ void getOffset_singleLineContent () {
371+ var content = "Hello, World!" ;
372+ // Line 0 with various character positions
373+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 0 )).isZero ();
374+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 5 )).isEqualTo (5 );
375+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 13 )).isEqualTo (13 );
376+ // Character position beyond line length should be capped
377+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 100 )).isEqualTo (13 );
378+ // Line beyond content should return end of content
379+ assertThat (BSLTextDocumentService .getOffset (content , 1 , 0 )).isEqualTo (13 );
380+ }
381+
382+ @ Test
383+ void getOffset_multiLineWithLF () {
384+ var content = "Line1\n Line2\n Line3" ;
385+ // Line 0
386+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 0 )).isZero ();
387+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 3 )).isEqualTo (3 );
388+ // Line 1 starts at position 6 (after "Line1\n")
389+ assertThat (BSLTextDocumentService .getOffset (content , 1 , 0 )).isEqualTo (6 );
390+ assertThat (BSLTextDocumentService .getOffset (content , 1 , 3 )).isEqualTo (9 );
391+ // Line 2 starts at position 12 (after "Line1\nLine2\n")
392+ assertThat (BSLTextDocumentService .getOffset (content , 2 , 0 )).isEqualTo (12 );
393+ assertThat (BSLTextDocumentService .getOffset (content , 2 , 5 )).isEqualTo (17 );
394+ // Line beyond content
395+ assertThat (BSLTextDocumentService .getOffset (content , 3 , 0 )).isEqualTo (17 );
396+ }
397+
398+ @ Test
399+ void getOffset_multiLineWithCRLF () {
400+ var content = "Line1\r \n Line2\r \n Line3" ;
401+ // Line 0
402+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 0 )).isZero ();
403+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 3 )).isEqualTo (3 );
404+ // Line 1 starts at position 7 (after "Line1\r\n")
405+ assertThat (BSLTextDocumentService .getOffset (content , 1 , 0 )).isEqualTo (7 );
406+ assertThat (BSLTextDocumentService .getOffset (content , 1 , 3 )).isEqualTo (10 );
407+ // Line 2 starts at position 14 (after "Line1\r\nLine2\r\n")
408+ assertThat (BSLTextDocumentService .getOffset (content , 2 , 0 )).isEqualTo (14 );
409+ assertThat (BSLTextDocumentService .getOffset (content , 2 , 5 )).isEqualTo (19 );
410+ }
411+
412+ @ Test
413+ void getOffset_multiLineWithCR () {
414+ var content = "Line1\r Line2\r Line3" ;
415+ // Line 0
416+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 0 )).isZero ();
417+ // Line 1 starts at position 6 (after "Line1\r")
418+ assertThat (BSLTextDocumentService .getOffset (content , 1 , 0 )).isEqualTo (6 );
419+ // Line 2 starts at position 12 (after "Line1\rLine2\r")
420+ assertThat (BSLTextDocumentService .getOffset (content , 2 , 0 )).isEqualTo (12 );
421+ }
422+
423+ @ Test
424+ void getOffset_onlyLineBreaks () {
425+ // Content with only LF line breaks
426+ var lfOnly = "\n \n \n " ;
427+ assertThat (BSLTextDocumentService .getOffset (lfOnly , 0 , 0 )).isZero ();
428+ assertThat (BSLTextDocumentService .getOffset (lfOnly , 1 , 0 )).isEqualTo (1 );
429+ assertThat (BSLTextDocumentService .getOffset (lfOnly , 2 , 0 )).isEqualTo (2 );
430+ assertThat (BSLTextDocumentService .getOffset (lfOnly , 3 , 0 )).isEqualTo (3 );
431+ assertThat (BSLTextDocumentService .getOffset (lfOnly , 4 , 0 )).isEqualTo (3 );
432+
433+ // Content with only CRLF line breaks
434+ var crlfOnly = "\r \n \r \n " ;
435+ assertThat (BSLTextDocumentService .getOffset (crlfOnly , 0 , 0 )).isZero ();
436+ assertThat (BSLTextDocumentService .getOffset (crlfOnly , 1 , 0 )).isEqualTo (2 );
437+ assertThat (BSLTextDocumentService .getOffset (crlfOnly , 2 , 0 )).isEqualTo (4 );
438+ assertThat (BSLTextDocumentService .getOffset (crlfOnly , 3 , 0 )).isEqualTo (4 );
439+ }
440+
441+ @ Test
442+ void getOffset_characterBeyondLineLength () {
443+ var content = "AB\n CD\n EF" ;
444+ // Line 0 has length 2, character 10 should be capped to content length
445+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 10 )).isEqualTo (8 );
446+ // Line 1 starts at 3, character 10 would be 13, capped to 8
447+ assertThat (BSLTextDocumentService .getOffset (content , 1 , 10 )).isEqualTo (8 );
448+ // Line 2 starts at 6, character 10 would be 16, capped to 8
449+ assertThat (BSLTextDocumentService .getOffset (content , 2 , 10 )).isEqualTo (8 );
450+ }
451+
452+ @ Test
453+ void getOffset_lineBeyondDocumentLength () {
454+ var content = "Only one line" ;
455+ // Line 0 exists
456+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 0 )).isZero ();
457+ // Lines 1, 5, 100 don't exist, should return end of content
458+ assertThat (BSLTextDocumentService .getOffset (content , 1 , 0 )).isEqualTo (13 );
459+ assertThat (BSLTextDocumentService .getOffset (content , 5 , 0 )).isEqualTo (13 );
460+ assertThat (BSLTextDocumentService .getOffset (content , 100 , 0 )).isEqualTo (13 );
461+ }
462+
463+ @ Test
464+ void getOffset_mixedLineEndings () {
465+ // Mixed: LF, then CRLF, then CR
466+ var content = "A\n B\r \n C\r D" ;
467+ // Line 0: starts at 0
468+ assertThat (BSLTextDocumentService .getOffset (content , 0 , 0 )).isZero ();
469+ // Line 1: starts at 2 (after "A\n")
470+ assertThat (BSLTextDocumentService .getOffset (content , 1 , 0 )).isEqualTo (2 );
471+ // Line 2: starts at 5 (after "A\nB\r\n")
472+ assertThat (BSLTextDocumentService .getOffset (content , 2 , 0 )).isEqualTo (5 );
473+ // Line 3: starts at 7 (after "A\nB\r\nC\r")
474+ assertThat (BSLTextDocumentService .getOffset (content , 3 , 0 )).isEqualTo (7 );
475+ }
357476}
0 commit comments