@@ -105,4 +105,70 @@ mod tests {
105105 " ;
106106 assert_eq ! ( std:: str :: from_utf8( & buffer) . unwrap( ) , expected) ;
107107 }
108+
109+ #[ test]
110+ fn test_apply_edits_multibyte_utf8 ( ) {
111+ // Source contains multi-byte characters:
112+ // - Immediately preceding `unsafe`: `/*前*/`
113+ // - Immediately following `{`: `/*后*/`
114+ // - Immediately before `}`: `/*前*/`
115+ let source = "
116+ fn safe() {}
117+ /// ```lean
118+ /// ```
119+ /*前*/unsafe fn foo() {/*后*/
120+ let x = '中';
121+ /*前*/}
122+ " ;
123+ let mut items = Vec :: new ( ) ;
124+ crate :: parse:: scan_compilation_unit ( source, |_src, res| items. push ( res) ) ;
125+
126+ // Find the unsafe function (should be the first item, as safe() is skipped)
127+ let item = items. into_iter ( ) . find ( |i| {
128+ if let Ok ( ParsedLeanItem { item : ParsedItem :: Fn ( f) , .. } ) = i {
129+ f. sig . ident == "foo"
130+ } else {
131+ false
132+ }
133+ } ) . unwrap ( ) . unwrap ( ) ;
134+
135+ let mut edits = Vec :: new ( ) ;
136+ append_edits ( & item, & mut edits) ;
137+
138+ let mut buffer = source. as_bytes ( ) . to_vec ( ) ;
139+ apply_edits ( & mut buffer, & edits) ;
140+
141+ // Expected whitespace lengths:
142+ // Line 1: ` /*前*/unsafe fn foo() {/*后*/`
143+ // - Indent: 12 spaces
144+ // - `/*前*/`: 7 bytes (preserved)
145+ // - `unsafe`: 6 bytes -> 6 spaces
146+ // - ` fn foo() {`: 9 bytes (preserved)
147+ // - `/*后*/`: 7 bytes -> 7 spaces
148+ //
149+ // Line 2: ` let x = '中';`
150+ // - Indent: 16 spaces -> 16 spaces
151+ // - `let x = '中';`: 14 bytes -> 14 spaces
152+ // `let` (3) + ` ` (1) + `x` (1) + ` ` (1) + `=` (1) + ` ` (1) + `'` (1) + `中` (3) + `'` (1) + `;` (1) = 14
153+ // Total: 30 spaces
154+ //
155+ // Line 3: ` /*前*/}`
156+ // - Indent 12 spaces -> 12 spaces
157+ // - `/*前*/`: 7 bytes -> 7 spaces
158+ // - `}`: 1 byte (preserved)
159+ // Total: 19 spaces + `}`
160+
161+ let line_with_unsafe = " /*前*/ fn foo() { " ;
162+ let line_body = " " . repeat ( 30 ) ;
163+ let line_end = format ! ( "{}}}" , " " . repeat( 19 ) ) ;
164+
165+ let expected = format ! (
166+ "\n fn safe() {{}}\n /// ```lean\n /// ```\n {}\n {}\n {}\n " ,
167+ line_with_unsafe,
168+ line_body,
169+ line_end
170+ ) ;
171+
172+ assert_eq ! ( std:: str :: from_utf8( & buffer) . unwrap( ) , expected) ;
173+ }
108174}
0 commit comments