Skip to content

Commit

Permalink
[analysis_server] Add tests for unversioned documents for EditableArg…
Browse files Browse the repository at this point in the history
…uments

The legacy protocol does not currently version documents, so this adds some additional tests for that.

The tests are in the Legacy class and not the shared class because in LSP versions are not optional for opening/changing documents (they are optional in some of the other APIs, but not for open/change).

Change-Id: I7e75b813025b3f67ed143e1b3a8b717224bfa80f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/404820
Commit-Queue: Brian Wilkerson <[email protected]>
Reviewed-by: Brian Wilkerson <[email protected]>
Reviewed-by: Phil Quitslund <[email protected]>
  • Loading branch information
DanTup authored and Commit Queue committed Jan 17, 2025
1 parent 7f5fc25 commit 95f0052
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,32 @@ abstract class SharedLspOverLegacyTest extends LspOverLegacyTest

@override
Future<void> openFile(Uri uri, String content, {int version = 1}) async {
// TODO(dantup): Add version here when legacy protocol supports.
await addOverlay(fromUri(uri), content);
}

/// Opens a file content without providing a version number.
///
/// This method should be used only for specifically testing unversioned
/// changes and [openFile] used by default since going forwards, we expect
/// all clients to start providing version numbers.
Future<void> openFileUnversioned(Uri uri, String content) async {
await addOverlay(fromUri(uri), content);
}

@override
Future<void> replaceFile(int newVersion, Uri uri, String content) async {
// TODO(dantup): Add version here when legacy protocol supports.
// For legacy, we can use addOverlay to replace the whole file.
await addOverlay(fromUri(uri), content);
}

/// Replaces a file content without providing a version number.
///
/// This method should be used only for specifically testing unversioned
/// changes and [replaceFile] used by default since going forwards, we expect
/// all clients to start providing version numbers.
Future<void> replaceFileUnversioned(Uri uri, String content) async {
// For legacy, we can use addOverlay to replace the whole file.
await addOverlay(fromUri(uri), content);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
// 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.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../shared/shared_editable_arguments_tests.dart';
import '../utils/test_code_extensions.dart';
import 'abstract_lsp_over_legacy.dart';

void main() {
Expand All @@ -31,19 +34,85 @@ class EditableArgumentsTest extends SharedLspOverLegacyTest
writeTestPackageConfig(flutter: true);
}

/// Over the legacy protocol, document versions are optional so we must also
/// support this.
test_textDocument_unversioned() async {
var result = await getEditableArgumentsFor('''
class MyWidget extends StatelessWidget {
const MyWidget(String a1);
@override
Widget build(BuildContext context) => MyW^idget('value1');
}
''', open: openFileUnversioned);

// Verify initial content has no version.
expect(
result!.textDocument,
isA<OptionalVersionedTextDocumentIdentifier>()
.having((td) => td.uri, 'uri', testFileUri)
.having((td) => td.version, 'version', isNull),
);

// Update the content.
await replaceFileUnversioned(testFileUri, '${code.code}\n// extra comment');

// Verify new results have no version.
result = await getEditableArguments(testFileUri, code.position.position);
expect(
result!.textDocument,
isA<OptionalVersionedTextDocumentIdentifier>()
.having((td) => td.uri, 'uri', testFileUri)
.having((td) => td.version, 'version', isNull),
);
}

/// Over the legacy protocol, document versions are optional so we must also
/// support this.
test_textDocument_unversioned_closedFile() async {
var result = await getEditableArgumentsFor('''
class MyWidget extends StatelessWidget {
const MyWidget(String a1);
@override
Widget build(BuildContext context) => MyW^idget('value1');
}
''', open: openFileUnversioned);

// Verify initial content has no version.
expect(
result!.textDocument,
isA<OptionalVersionedTextDocumentIdentifier>()
.having((td) => td.uri, 'uri', testFileUri)
.having((td) => td.version, 'version', isNull),
);

// Close the file.
await closeFile(testFileUri);

// Verify new results have no version.
result = await getEditableArguments(testFileUri, code.position.position);
expect(
result!.textDocument,
isA<OptionalVersionedTextDocumentIdentifier>()
.having((td) => td.uri, 'uri', testFileUri)
.having((td) => td.version, 'version', isNull),
);
}

@override
@FailingTest(reason: 'Document versions not currently supported for legacy')
test_textDocument_closedFile() {
test_textDocument_versioned() {
// TODO(dantup): Implement support for version numbers in the legacy
// protocol.
return super.test_textDocument_closedFile();
return super.test_textDocument_versioned();
}

@override
@FailingTest(reason: 'Document versions not currently supported for legacy')
test_textDocument_versions() {
test_textDocument_versioned_closedFile() {
// TODO(dantup): Implement support for version numbers in the legacy
// protocol.
return super.test_textDocument_versions();
return super.test_textDocument_versioned_closedFile();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@ mixin SharedEditableArgumentsTests
/// Initializes the server with [content] and fetches editable arguments.
Future<EditableArguments?> getEditableArgumentsFor(
String content, {
bool open = true,
Future<void> Function(Uri, String)? open,
}) async {
// Default to the standart openFile function if we weren't overridden.
open ??= openFile;

code = TestCode.parse('''
import 'package:flutter/widgets.dart';
$content
''');
createFile(testFilePath, code.code);
await initializeServer();
if (open) {
await openFile(testFileUri, code.code);
}
await open(testFileUri, code.code);
await currentAnalysis;
return await getEditableArguments(testFileUri, code.position.position);
}
Expand Down Expand Up @@ -755,57 +756,57 @@ class MyWidget extends StatelessWidget {
);
}

test_textDocument_closedFile() async {
test_textDocument_unopenedFile() async {
var result = await getEditableArgumentsFor('''
class MyWidget extends StatelessWidget {
const MyWidget(String a1);
@override
Widget build(BuildContext context) => MyW^idget('value1');
}
''');
''', open: (_, _) async {});

// Verify initial content of 1.
expect(
result!.textDocument,
isA<VersionedTextDocumentIdentifier>()
.having((td) => td.uri, 'uri', testFileUri)
.having((td) => td.version, 'version', 1),
);

// Close the file.
await closeFile(testFileUri);

// Verify new results have null version.
result = await getEditableArguments(testFileUri, code.position.position);
// Verify null version for unopened file.
expect(
result!.textDocument,
isA<OptionalVersionedTextDocumentIdentifier>()
.having((td) => td.uri, 'uri', testFileUri)
.having((td) => td.version, 'version', isNull),
.having((td) => td.version, 'version', null),
);
}

test_textDocument_unopenedFile() async {
test_textDocument_versioned() async {
var result = await getEditableArgumentsFor('''
class MyWidget extends StatelessWidget {
const MyWidget(String a1);
@override
Widget build(BuildContext context) => MyW^idget('value1');
}
''', open: false);
''');

// Verify null version for unopened file.
// Verify initial content of 1.
expect(
result!.textDocument,
isA<OptionalVersionedTextDocumentIdentifier>()
isA<VersionedTextDocumentIdentifier>()
.having((td) => td.uri, 'uri', testFileUri)
.having((td) => td.version, 'version', null),
.having((td) => td.version, 'version', 1),
);

// Update the content to v5.
await replaceFile(5, testFileUri, '${code.code}\n// extra comment');

// Verify new results have version 5.
result = await getEditableArguments(testFileUri, code.position.position);
expect(
result!.textDocument,
isA<VersionedTextDocumentIdentifier>()
.having((td) => td.uri, 'uri', testFileUri)
.having((td) => td.version, 'version', 5),
);
}

test_textDocument_versions() async {
test_textDocument_versioned_closedFile() async {
var result = await getEditableArgumentsFor('''
class MyWidget extends StatelessWidget {
const MyWidget(String a1);
Expand All @@ -823,16 +824,16 @@ class MyWidget extends StatelessWidget {
.having((td) => td.version, 'version', 1),
);

// Update the content to v5.
await replaceFile(5, testFileUri, '${code.code}\n// extra comment');
// Close the file.
await closeFile(testFileUri);

// Verify new results have version 5.
// Verify new results have null version.
result = await getEditableArguments(testFileUri, code.position.position);
expect(
result!.textDocument,
isA<VersionedTextDocumentIdentifier>()
isA<OptionalVersionedTextDocumentIdentifier>()
.having((td) => td.uri, 'uri', testFileUri)
.having((td) => td.version, 'version', 5),
.having((td) => td.version, 'version', isNull),
);
}

Expand Down

0 comments on commit 95f0052

Please sign in to comment.