@@ -2,6 +2,9 @@ defmodule Expert.CodeIntelligence.Completion.BuilderTest do
22 alias Expert.CodeIntelligence.Completion.SortScope
33 alias Forge.Ast
44 alias Forge.Ast.Env
5+ alias Forge.Document
6+ alias Forge.Document.Position
7+ alias Forge.Protocol.Convertible
58 alias GenLSP.Structures.CompletionItem
69
710 use ExUnit.Case , async: true
@@ -82,4 +85,46 @@ defmodule Expert.CodeIntelligence.Completion.BuilderTest do
8285 |> snippet ( "" , label: "" )
8386 end
8487 end
88+
89+ describe "non-ascii line range clamp" do
90+ test "plain_text clamps start_char >= 1 and serializes on non-ASCII line" do
91+ doc = Document . new ( "file:///builder_test.ex" , "⚠️ hello" , 0 )
92+ pos = Position . new ( doc , 1 , 1 )
93+
94+ env = % Env { document: doc , position: pos , prefix: "a" }
95+
96+ item = plain_text ( env , "X" , label: "X" )
97+
98+ assert { :ok , lsp_text_edit_or_list } = Convertible . to_lsp ( item . text_edit )
99+
100+ lsp_edits = List . wrap ( lsp_text_edit_or_list )
101+
102+ refute Enum . empty? ( lsp_edits )
103+
104+ for % { range: % { start: % { character: start_ch } , end: % { character: end_ch } } } <- lsp_edits do
105+ assert start_ch == 0
106+ assert end_ch == 0
107+ end
108+ end
109+
110+ test "snippet clamps start_char >= 1 and serializes on non-ASCII line" do
111+ doc = Document . new ( "file:///builder_test.ex" , "⚠️ hello" , 0 )
112+ pos = Position . new ( doc , 1 , 1 )
113+
114+ env = % Env { document: doc , position: pos , prefix: "a" }
115+
116+ item = snippet ( env , "X$0" , label: "X" )
117+
118+ assert { :ok , lsp_text_edit_or_list } = Convertible . to_lsp ( item . text_edit )
119+
120+ lsp_edits = List . wrap ( lsp_text_edit_or_list )
121+
122+ refute Enum . empty? ( lsp_edits )
123+
124+ for % { range: % { start: % { character: start_ch } , end: % { character: end_ch } } } <- lsp_edits do
125+ assert start_ch == 0
126+ assert end_ch == 0
127+ end
128+ end
129+ end
85130end
0 commit comments