// Copyright (c) 2019, 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:analyzer_plugin/protocol/protocol_common.dart' as plugin; import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import 'server_abstract.dart'; void main() { defineReflectiveSuite(() { defineReflectiveTests(FoldingTest); }); } @reflectiveTest class FoldingTest extends AbstractLspAnalysisServerTest { Future test_class() async { final content = ''' class MyClass2 {[[ // Class content ]]} '''; final range1 = rangeFromMarkers(content); final expectedRegions = [ FoldingRange( startLine: range1.start.line, startCharacter: range1.start.character, endLine: range1.end.line, endCharacter: range1.end.character, ) ]; await initialize(); await openFile(mainFileUri, withoutMarkers(content)); final regions = await getFoldingRegions(mainFileUri); expect(regions, unorderedEquals(expectedRegions)); } Future test_comments() async { final content = ''' /// This is a comment[[ /// that spans many lines]] class MyClass2 {} '''; final range1 = rangeFromMarkers(content); final expectedRegions = [ FoldingRange( startLine: range1.start.line, startCharacter: range1.start.character, endLine: range1.end.line, endCharacter: range1.end.character, kind: FoldingRangeKind.Comment, ) ]; await initialize(); await openFile(mainFileUri, withoutMarkers(content)); final regions = await getFoldingRegions(mainFileUri); expect(regions, unorderedEquals(expectedRegions)); } Future test_doLoop() async { final content = ''' f(int i) { do {[[ print('with statements');]] } while (i == 0) do {[[ // only comments]] } while (i == 0) // empty do { } while (i == 0) // no body do; } '''; final ranges = rangesFromMarkers(content); final expectedRegions = ranges .map((range) => FoldingRange( startLine: range.start.line, startCharacter: range.start.character, endLine: range.end.line, endCharacter: range.end.character, )) .toList(); await initialize(); await openFile(mainFileUri, withoutMarkers(content)); final regions = await getFoldingRegions(mainFileUri); expect(regions, containsAll(expectedRegions)); } Future test_fromPlugins_dartFile() async { final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.dart'); final pluginAnalyzedUri = Uri.file(pluginAnalyzedFilePath); const content = ''' // [[contributed by fake plugin]] class AnnotatedDartClass {[[ // content of dart class, contributed by server ]]} '''; final ranges = rangesFromMarkers(content); final withoutMarkers = withoutRangeMarkers(content); newFile(pluginAnalyzedFilePath); await initialize(); await openFile(pluginAnalyzedUri, withoutMarkers); final pluginResult = plugin.AnalysisFoldingParams( pluginAnalyzedFilePath, [plugin.FoldingRegion(plugin.FoldingKind.DIRECTIVES, 7, 26)], ); configureTestPlugin(notification: pluginResult.toNotification()); final res = await getFoldingRegions(pluginAnalyzedUri); expect( res, unorderedEquals([ _toFoldingRange(ranges[0], FoldingRangeKind.Imports), _toFoldingRange(ranges[1], null), ]), ); } Future test_fromPlugins_nonDartFile() async { final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.sql'); final pluginAnalyzedUri = Uri.file(pluginAnalyzedFilePath); const content = ''' CREATE TABLE foo( [[-- some columns]] ); '''; final withoutMarkers = withoutRangeMarkers(content); newFile(pluginAnalyzedFilePath, content: withoutMarkers); await initialize(); await openFile(pluginAnalyzedUri, withoutMarkers); final pluginResult = plugin.AnalysisFoldingParams( pluginAnalyzedFilePath, [plugin.FoldingRegion(plugin.FoldingKind.CLASS_BODY, 33, 15)], ); configureTestPlugin(notification: pluginResult.toNotification()); final res = await getFoldingRegions(pluginAnalyzedUri); final expectedRange = rangeFromMarkers(content); expect(res, [_toFoldingRange(expectedRange, null)]); } Future test_headersImportsComments() async { final content = ''' // Copyright some year by some people[[ // See LICENCE etc.]] import[[ 'dart:io'; import 'dart:async';]] /// This is not the file header[[ /// It's just a comment]] main() {} '''; final ranges = rangesFromMarkers(content); final expectedRegions = [ _toFoldingRange(ranges[0], FoldingRangeKind.Comment), _toFoldingRange(ranges[1], FoldingRangeKind.Imports), _toFoldingRange(ranges[2], FoldingRangeKind.Comment), ]; await initialize(); await openFile(mainFileUri, withoutMarkers(content)); final regions = await getFoldingRegions(mainFileUri); expect(regions, unorderedEquals(expectedRegions)); } Future test_ifElseElseIf() async { final content = ''' f(int i) { if (i == 0) {[[ // only // comments]] } else if (i == 1) {[[ print('statements');]] } else if (i == 2) { } else {[[ // else // comments]] } } '''; final ranges = rangesFromMarkers(content); final expectedRegions = ranges .map((range) => FoldingRange( startLine: range.start.line, startCharacter: range.start.character, endLine: range.end.line, endCharacter: range.end.character, )) .toList(); await initialize(); await openFile(mainFileUri, withoutMarkers(content)); final regions = await getFoldingRegions(mainFileUri); expect(regions, containsAll(expectedRegions)); } Future test_nonDartFile() async { await initialize(); await openFile(pubspecFileUri, simplePubspecContent); final regions = await getFoldingRegions(pubspecFileUri); expect(regions, isEmpty); } Future test_whileLoop() async { final content = ''' f(int i) { while (i == 0) {[[ print('with statements');]] } while (i == 0) {[[ // only comments]] } // empty while (i == 0) { } // no body while (i == 0); } '''; final ranges = rangesFromMarkers(content); final expectedRegions = ranges .map((range) => FoldingRange( startLine: range.start.line, startCharacter: range.start.character, endLine: range.end.line, endCharacter: range.end.character, )) .toList(); await initialize(); await openFile(mainFileUri, withoutMarkers(content)); final regions = await getFoldingRegions(mainFileUri); expect(regions, containsAll(expectedRegions)); } FoldingRange _toFoldingRange(Range range, FoldingRangeKind? kind) { return FoldingRange( startLine: range.start.line, startCharacter: range.start.character, endLine: range.end.line, endCharacter: range.end.character, kind: kind, ); } }