blob: 5c5d8aa768b9efc7e0af79f7c192f6b4de1fa59f [file] [log] [blame]
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'server_abstract.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(FileModificationTest);
});
}
@reflectiveTest
class FileModificationTest extends AbstractLspAnalysisServerTest {
test_change_badPosition() async {
final contents = '';
await initialize();
await openFile(mainFileUri, contents);
// Since this is a notification and not a request, the server cannot
// respond with an error, but instead sends a ShowMessage notification
// to alert the user to something failing.
final error = await expectErrorNotification<ShowMessageParams>(() async {
await changeFile(222, mainFileUri, [
new TextDocumentContentChangeEvent(
new Range(new Position(999, 999), new Position(999, 999)),
null,
' ',
)
]);
});
expect(error.message, contains('Invalid line'));
}
test_change_fullContents() async {
final initialContent = 'int a = 1;';
final updatedContent = 'int a = 2;';
await initialize();
await openFile(mainFileUri, initialContent);
await replaceFile(222, mainFileUri, updatedContent);
expect(_getOverlay(mainFilePath), equals(updatedContent));
final documentVersion = server.getVersionedDocumentIdentifier(mainFilePath);
expect(documentVersion.version, equals(222));
}
test_change_incremental() async {
final initialContent = '0123456789\n0123456789';
final expectedUpdatedContent = '0123456789\n01234 89';
await initialize();
await openFile(mainFileUri, initialContent);
await changeFile(222, mainFileUri, [
// Replace line1:5-1:8 with spaces.
new TextDocumentContentChangeEvent(
new Range(new Position(1, 5), new Position(1, 8)),
null,
' ',
)
]);
expect(_getOverlay(mainFilePath), equals(expectedUpdatedContent));
final documentVersion = server.getVersionedDocumentIdentifier(mainFilePath);
expect(documentVersion.version, equals(222));
}
test_change_unopenedFile() async {
// It's not valid for a client to send a request to modify a file that it
// has not opened, but Visual Studio has done it in the past so we should
// ensure it generates an obvious error that the user can understand.
final simpleEdit = new TextDocumentContentChangeEvent(
new Range(new Position(1, 1), new Position(1, 1)),
null,
'test',
);
await initialize();
final notificationParams = await expectErrorNotification<ShowMessageParams>(
() => changeFile(222, mainFileUri, [simpleEdit]),
);
expect(notificationParams, isNotNull);
expect(
notificationParams.message,
allOf(
contains('because the file was not previously opened'),
contains(mainFilePath),
),
);
}
test_close() async {
final initialContent = 'int a = 1;';
final updatedContent = 'int a = 2;';
await initialize();
await openFile(mainFileUri, initialContent);
await replaceFile(222, mainFileUri, updatedContent);
await closeFile(mainFileUri);
expect(_getOverlay(mainFilePath), isNull);
// When we close a file, we expect the version in the versioned identifier to
// return to `null`.
final documentVersion = server.getVersionedDocumentIdentifier(mainFilePath);
expect(documentVersion.version, isNull);
}
test_open() async {
const testContent = 'CONTENT';
await initialize();
expect(_getOverlay(mainFilePath), isNull);
await openFile(mainFileUri, testContent, version: 2);
expect(_getOverlay(mainFilePath), equals(testContent));
// The version for a file that's just been opened (and never modified) is
// `null` (this means the contents match what's on disk).
final documentVersion = server.getVersionedDocumentIdentifier(mainFilePath);
expect(documentVersion.version, 2);
}
test_open_invalidPath() async {
await initialize();
final notificationParams = await expectErrorNotification<ShowMessageParams>(
() => openFile(new Uri.http('localhost', 'not-a-file'), ''),
);
expect(notificationParams, isNotNull);
expect(
notificationParams.message,
contains('URI was not a valid file:// URI'),
);
}
String _getOverlay(String path) {
if (server.resourceProvider.hasOverlay(path)) {
return server.resourceProvider.getFile(path).readAsStringSync();
}
return null;
}
}