Skip to content

Commit 894b70a

Browse files
committed
Tests for TextDocument
1 parent 72f621b commit 894b70a

File tree

2 files changed

+288
-0
lines changed

2 files changed

+288
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
import 'package:lsp_server/lsp_server.dart' as lsp;
2+
import 'package:sass_language_services/sass_language_services.dart';
3+
import 'package:test/test.dart';
4+
5+
import '../position_utils.dart';
6+
7+
TextDocument createDocument(String content) {
8+
return TextDocument(Uri.parse('test://hello/world'), 'text', 0, content);
9+
}
10+
11+
lsp.Either2<lsp.TextDocumentContentChangeEvent1,
12+
lsp.TextDocumentContentChangeEvent2> updateFull(String text) {
13+
return lsp.Either2.t2(lsp.TextDocumentContentChangeEvent2(text: text));
14+
}
15+
16+
lsp.Either2<lsp.TextDocumentContentChangeEvent1,
17+
lsp.TextDocumentContentChangeEvent2>
18+
updateIncremental(String text, lsp.Range range) {
19+
return lsp.Either2.t2(lsp.TextDocumentContentChangeEvent2(text: text));
20+
}
21+
22+
lsp.Range forSubstring(TextDocument document, String substring) {
23+
var i = document.getText().indexOf(substring);
24+
return lsp.Range(
25+
start: document.positionAt(i),
26+
end: document.positionAt(i + substring.length),
27+
);
28+
}
29+
30+
lsp.Range afterSubstring(TextDocument document, String substring) {
31+
var i = document.getText().indexOf(substring);
32+
var pos = document.positionAt(i);
33+
return lsp.Range(start: pos, end: pos);
34+
}
35+
36+
lsp.TextEdit insert(String text, lsp.Position at) {
37+
return lsp.TextEdit(newText: text, range: lsp.Range(start: at, end: at));
38+
}
39+
40+
lsp.TextEdit replace(String text, lsp.Range range) {
41+
return lsp.TextEdit(newText: text, range: range);
42+
}
43+
44+
lsp.TextEdit delete(lsp.Range range) {
45+
return lsp.TextEdit(newText: '', range: range);
46+
}
47+
48+
void main() {
49+
group('lines, offsets and positions', () {
50+
test('empty content', () {
51+
var document = createDocument('');
52+
53+
expect(document.lineCount, equals(1));
54+
expect(document.offsetAt(position(0, 0)), equals(0));
55+
56+
var pos = document.positionAt(0);
57+
expect(pos.line, equals(0));
58+
expect(pos.character, equals(0));
59+
});
60+
61+
test('single line', () {
62+
var content = 'Hello World';
63+
var document = createDocument(content);
64+
expect(document.lineCount, equals(1));
65+
66+
for (var i = 0; i < content.length; i++) {
67+
expect(document.offsetAt(position(0, i)), equals(i));
68+
var pos = document.positionAt(i);
69+
expect(pos.line, equals(0));
70+
expect(pos.character, equals(i));
71+
}
72+
});
73+
74+
test('multiple lines', () {
75+
var content = '''abcde
76+
fghij
77+
klmno
78+
''';
79+
var document = createDocument(content);
80+
expect(document.lineCount, equals(4));
81+
82+
for (var i = 0; i < content.length; i++) {
83+
var line = (i / 6).floor();
84+
var char = i % 6;
85+
expect(document.offsetAt(position(line, char)), equals(i));
86+
87+
var pos = document.positionAt(i);
88+
expect(pos.line, equals(line));
89+
expect(pos.character, equals(char));
90+
}
91+
92+
// Out of bounds.
93+
expect(document.offsetAt(position(3, 0)), content.length);
94+
expect(document.offsetAt(position(3, 1)), content.length);
95+
96+
var pos = document.positionAt(18);
97+
expect(pos.line, equals(3));
98+
expect(pos.character, equals(0));
99+
100+
pos = document.positionAt(19);
101+
expect(pos.line, equals(3));
102+
expect(pos.character, equals(0));
103+
});
104+
105+
test('starts with newline', () {
106+
var content = '\nABCDE';
107+
var document = createDocument(content);
108+
expect(document.lineCount, equals(2));
109+
});
110+
111+
test('newline characters', () {
112+
var document = createDocument('\rABCDE');
113+
expect(document.lineCount, equals(2));
114+
document = createDocument('\nABCDE');
115+
expect(document.lineCount, equals(2));
116+
117+
document = createDocument('\r\nABCDE');
118+
expect(document.lineCount, equals(2));
119+
120+
document = createDocument('\n\nABCDE');
121+
expect(document.lineCount, equals(3));
122+
123+
document = createDocument('\r\rABCDE');
124+
expect(document.lineCount, equals(3));
125+
126+
document = createDocument('\n\rABCDE');
127+
expect(document.lineCount, equals(3));
128+
});
129+
130+
test('getText', () {
131+
var content = 'abcde\nfghij\nklmno';
132+
var document = createDocument(content);
133+
expect(document.getText(), equals(content));
134+
135+
expect(
136+
document.getText(range: range(0, 0, 0, 5)),
137+
equals('asdf'),
138+
);
139+
expect(
140+
document.getText(range: range(0, 4, 1, 1)),
141+
equals('e\nf'),
142+
);
143+
});
144+
145+
test('invalid input at beginning of file', () {
146+
var document = createDocument('asdf');
147+
expect(document.offsetAt(position(-1, 0)), 0);
148+
expect(document.offsetAt(position(0, -1)), 0);
149+
150+
var pos = document.positionAt(-1);
151+
expect(pos.line, equals(0));
152+
expect(pos.character, equals(0));
153+
});
154+
155+
test('invalid input at end of file', () {
156+
var document = createDocument('asdf');
157+
expect(document.offsetAt(position(1, 1)), 4);
158+
159+
var pos = document.positionAt(8);
160+
expect(pos.line, equals(0));
161+
expect(pos.character, equals(4));
162+
});
163+
164+
test('invalid input at beginning of line', () {
165+
var document = createDocument('a\ns\nd\r\nf');
166+
expect(document.offsetAt(position(0, -1)), 0);
167+
expect(document.offsetAt(position(1, -1)), 2);
168+
expect(document.offsetAt(position(2, -1)), 4);
169+
expect(document.offsetAt(position(3, -1)), 7);
170+
});
171+
172+
test('invalid input at end of line', () {
173+
var document = createDocument('a\ns\nd\r\nf');
174+
expect(document.offsetAt(position(0, 10)), 1);
175+
expect(document.offsetAt(position(1, 10)), 3);
176+
expect(document.offsetAt(position(2, 2)), 5);
177+
expect(document.offsetAt(position(2, 3)), 5);
178+
expect(document.offsetAt(position(2, 10)), 5);
179+
expect(document.offsetAt(position(3, 10)), 8);
180+
181+
var pos = document.positionAt(6);
182+
expect(pos.line, equals(2));
183+
expect(pos.character, equals(1));
184+
});
185+
});
186+
187+
group('full updates', () {
188+
test('one full update', () {
189+
var document = createDocument('asdfqwer');
190+
document.update([updateFull('hjklyuio')], 1);
191+
expect(document.version, equals(1));
192+
expect(document.getText(), equals('hjklyuio'));
193+
});
194+
195+
test('several full updates', () {
196+
var document = createDocument('asdfqwer');
197+
document.update([updateFull('hjklyuio'), updateFull('12345')], 2);
198+
expect(document.version, equals(2));
199+
expect(document.getText(), equals('12345'));
200+
});
201+
});
202+
203+
group('incremental updates', () {
204+
void checkLineNumbers(TextDocument document) {
205+
// Assuming \n.
206+
var text = document.getText();
207+
var characters = text.split('');
208+
var expected = 0;
209+
for (var i = 0; i < text.length; i++) {
210+
expect(document.positionAt(i).line, expected);
211+
if (characters[i] == '\n') {
212+
expected += 1;
213+
}
214+
}
215+
expect(document.positionAt(text.length), equals(expected));
216+
}
217+
218+
test('incrementally removing content', () {});
219+
});
220+
221+
group('applyEdits', () {
222+
test('inserts', () {
223+
var input = createDocument('asdfasdfasdf');
224+
expect(
225+
input.applyEdits([insert('Hello', position(0, 0))]),
226+
equals('Helloasdfasdfasdf'),
227+
);
228+
expect(
229+
input.applyEdits([insert('Hello', position(0, 1))]),
230+
equals('aHellosdfasdfasdf'),
231+
);
232+
expect(
233+
input.applyEdits([
234+
insert('Hello', position(0, 1)),
235+
insert('World', position(0, 1)),
236+
]),
237+
equals('aHelloWorldsdfasdfasdf'),
238+
);
239+
expect(
240+
input.applyEdits([
241+
insert('Mint', position(0, 2)),
242+
insert('Hello', position(0, 1)),
243+
insert('World', position(0, 1)),
244+
insert('Jams', position(0, 2)),
245+
insert('Casiopea', position(0, 2)),
246+
]),
247+
equals('aHelloWorldsMintJamsCasiopeadfasdfasdf'),
248+
);
249+
});
250+
251+
test('replace', () {
252+
var input = createDocument('0123456789');
253+
expect(
254+
input.applyEdits([replace('Hello', range(0, 3, 0, 5))]),
255+
equals('012Hello56789'),
256+
);
257+
expect(
258+
input.applyEdits([
259+
replace('Hello', range(0, 3, 0, 5)),
260+
replace('World', range(0, 5, 0, 7)),
261+
]),
262+
equals('012HelloWorld789'),
263+
);
264+
});
265+
266+
test('mix', () {
267+
var input = createDocument('0123456789');
268+
expect(
269+
input.applyEdits([
270+
insert('Jams', position(0, 6)),
271+
replace('Mint', range(0, 3, 0, 6)),
272+
]),
273+
equals('012MintJams6789'),
274+
);
275+
});
276+
});
277+
}

pkgs/sass_language_services/test/position_utils.dart

+11
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,14 @@ import 'package:lsp_server/lsp_server.dart' as lsp;
33
lsp.Position at({required int line, required int char}) {
44
return lsp.Position(character: char, line: line);
55
}
6+
7+
lsp.Position position(int line, int char) {
8+
return at(line: line, char: char);
9+
}
10+
11+
lsp.Range range(int startLine, int startChar, int endLine, int endChar) {
12+
return lsp.Range(
13+
start: at(line: startLine, char: startChar),
14+
end: at(line: startLine, char: startChar),
15+
);
16+
}

0 commit comments

Comments
 (0)