Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(434)

Unified Diff: pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart

Issue 2917943002: Postfix completion (Closed)
Patch Set: Make .try work on entire lines Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
diff --git a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..e9c4fef9951d2481639ef47277c17b32272a83ec
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
@@ -0,0 +1,863 @@
+// Copyright (c) 2017, 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/src/protocol_server.dart';
+import 'package:analysis_server/src/services/completion/postfix/postfix_completion.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../abstract_single_unit.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(_AssertTest);
+ defineReflectiveTests(_ForTest);
+ defineReflectiveTests(_NegateTest);
+ defineReflectiveTests(_IfTest);
+ defineReflectiveTests(_NotNullTest);
+ defineReflectiveTests(_ParenTest);
+ defineReflectiveTests(_ReturnTest);
+ defineReflectiveTests(_SwitchTest);
+ defineReflectiveTests(_TryTest);
+ defineReflectiveTests(_WhileTest);
+ });
+}
+
+class PostfixCompletionTest extends AbstractSingleUnitTest {
+ SourceChange change;
+
+ void _assertHasChange(String message, String expectedCode, [Function cmp]) {
+ if (change.message == message) {
+ if (!change.edits.isEmpty) {
+ String resultCode =
+ SourceEdit.applySequence(testCode, change.edits[0].edits);
+ expect(resultCode, expectedCode.replaceAll('/*caret*/', ''));
+ if (cmp != null) {
+ int offset = cmp(resultCode);
+ expect(change.selection.offset, offset);
+ }
+ } else {
+ if (cmp != null) {
+ int offset = cmp(testCode);
+ expect(change.selection.offset, offset);
+ }
+ }
+ return;
+ }
+ fail("Expected to find |$message| but got: " + change.message);
+ }
+
+ _computeCompletion(int offset, String key) async {
+ driver.changeFile(testFile);
+ AnalysisResult result = await driver.getResult(testFile);
+ PostfixCompletionContext context = new PostfixCompletionContext(
+ testFile,
+ result.lineInfo,
+ offset,
+ key,
+ result.driver,
+ testUnit,
+ testUnitElement,
+ result.errors);
+ PostfixCompletionProcessor processor =
+ new PostfixCompletionProcessor(context);
+ bool isApplicable = await processor.isApplicable();
+ if (!isApplicable) {
+ fail("Postfix completion not applicable at given location");
+ }
+ PostfixCompletion completion = await processor.compute();
+ change = completion.change;
+ }
+
+ _prepareCompletion(String key, String sourceCode) async {
+ testCode = sourceCode.replaceAll('////', '');
+ int offset = findOffset(key);
+ testCode = testCode.replaceFirst(key, '', offset);
+ await _prepareCompletionAt(offset, key, testCode);
+ }
+
+ _prepareCompletionAt(int offset, String key, String sourceCode) async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit(sourceCode);
+ await _computeCompletion(offset, key);
+ }
+}
+
+@reflectiveTest
+class _AssertTest extends PostfixCompletionTest {
+ test_assert() async {
+ await _prepareCompletion(
+ '.assert',
+ '''
+f(bool expr) {
+ expr.assert
+}
+''');
+ _assertHasChange(
+ 'Expand .assert',
+ '''
+f(bool expr) {
+ assert(expr);
+}
+''');
+ }
+
+ test_assertFunc() async {
+ await _prepareCompletion(
+ '.assert',
+ '''
+f() {
+ () => true.assert
+}
+''');
+ _assertHasChange(
+ 'Expand .assert',
+ '''
+f() {
+ assert(() => true);
+}
+''');
+ }
+
+ @failingTest
+ test_assertFunc_invalid() async {
+ await _prepareCompletion(
+ '.assert',
+ '''
+f() {
+ () => null.assert
+}
+''');
+ }
+
+ test_assertFuncCmp() async {
+ await _prepareCompletion(
+ '.assert',
+ '''
+f(int x, int y) {
+ () => x + 3 > y + 4.assert
+}
+''');
+ _assertHasChange(
+ 'Expand .assert',
+ '''
+f(int x, int y) {
+ assert(() => x + 3 > y + 4);
+}
+''');
+ }
+}
+
+@reflectiveTest
+class _ForTest extends PostfixCompletionTest {
+ @failingTest
+ test_for_invalid() async {
+ await _prepareCompletion(
+ '.for',
+ '''
+f() {
+ {}.for
+}
+''');
+ }
+
+ test_forEmptyDynamic() async {
+ await _prepareCompletion(
+ '.for',
+ '''
+f() {
+ [].for
+}
+''');
+ _assertHasChange(
+ 'Expand .for',
+ '''
+f() {
+ for (var value in []) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ test_forEmptyString() async {
+ await _prepareCompletion(
+ '.for',
+ '''
+f() {
+ <String>[].for
+}
+''');
+ _assertHasChange(
+ 'Expand .for',
+ '''
+f() {
+ for (var value in <String>[]) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ test_fori() async {
+ await _prepareCompletion(
+ '.fori',
+ '''
+f() {
+ 100.fori
+}
+''');
+ _assertHasChange(
+ 'Expand .fori',
+ '''
+f() {
+ for (int i = 0; i < 100; i++) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ @failingTest
+ test_fori_invalid() async {
+ await _prepareCompletion(
+ '.fori',
+ '''
+f() {
+ [].fori
+}
+''');
+ }
+
+ test_forIntList() async {
+ await _prepareCompletion(
+ '.for',
+ '''
+f() {
+ [1,2,3].for
+}
+''');
+ _assertHasChange(
+ 'Expand .for',
+ '''
+f() {
+ for (var value in [1,2,3]) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ test_foriVar() async {
+ await _prepareCompletion(
+ '.fori',
+ '''
+f() {
+ var n = 100;
+ n.fori
+}
+''');
+ _assertHasChange(
+ 'Expand .fori',
+ '''
+f() {
+ var n = 100;
+ for (int i = 0; i < n; i++) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ test_iterList() async {
+ await _prepareCompletion(
+ '.iter',
+ '''
+f() {
+ [1,2,3].iter
+}
+''');
+ _assertHasChange(
+ 'Expand .iter',
+ '''
+f() {
+ for (var value in [1,2,3]) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ test_iterName() async {
+ await _prepareCompletion(
+ '.iter',
+ '''
+f() {
+ var value = [1,2,3];
+ value.iter
+}
+''');
+ _assertHasChange(
+ 'Expand .iter',
+ '''
+f() {
+ var value = [1,2,3];
+ for (var value1 in value) {
+ /*caret*/
+ }
+}
+''');
+ }
+}
+
+@reflectiveTest
+class _IfTest extends PostfixCompletionTest {
+ test_Else() async {
+ await _prepareCompletion(
+ '.else',
+ '''
+f(bool val) {
+ val.else
+}
+''');
+ _assertHasChange(
+ 'Expand .else',
+ '''
+f(bool val) {
+ if (!val) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ test_if() async {
+ await _prepareCompletion(
+ '.if',
+ '''
+f() {
+ 3 < 4.if
+}
+''');
+ _assertHasChange(
+ 'Expand .if',
+ '''
+f() {
+ if (3 < 4) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ @failingTest
+ test_if_invalid() async {
+ await _prepareCompletion(
+ '.if',
+ '''
+f(List expr) {
+ expr.if
+}
+''');
+ }
+
+ test_ifDynamic() async {
+ await _prepareCompletion(
+ '.if',
+ '''
+f(expr) {
+ expr.if
+}
+''');
+ _assertHasChange(
+ 'Expand .if',
+ '''
+f(expr) {
+ if (expr) {
+ /*caret*/
+ }
+}
+''');
+ }
+}
+
+@reflectiveTest
+class _NegateTest extends PostfixCompletionTest {
+ test_negate() async {
+ await _prepareCompletion(
+ '.not',
+ '''
+f(expr) {
+ if (expr.not)
+}
+''');
+ _assertHasChange(
+ 'Expand .not',
+ '''
+f(expr) {
+ if (!expr)
+}
+''');
+ }
+
+ @failingTest
+ test_negate_invalid() async {
+ await _prepareCompletion(
+ '.not',
+ '''
+f(int expr) {
+ if (expr.not)
+}
+''');
+ }
+
+ test_negateCascade() async {
+ await _prepareCompletion(
+ '.not',
+ '''
+f(expr) {
+ if (expr..a..b..c.not)
+}
+''');
+ _assertHasChange(
+ 'Expand .not',
+ '''
+f(expr) {
+ if (!expr..a..b..c)
+}
+''');
+ }
+
+ test_negateExpr() async {
+ await _prepareCompletion(
+ '.not',
+ '''
+f(int i, int j) {
+ if (i + 3 < j - 4.not)
+}
+''');
+ _assertHasChange(
+ 'Expand .not',
+ '''
+f(int i, int j) {
+ if (i + 3 >= j - 4)
+}
+''');
+ }
+
+ test_negateProperty() async {
+ await _prepareCompletion(
+ '.not',
+ '''
+f(expr) {
+ if (expr.a.b.c.not)
+}
+''');
+ _assertHasChange(
+ 'Expand .not',
+ '''
+f(expr) {
+ if (!expr.a.b.c)
+}
+''');
+ }
+
+ test_notFalse() async {
+ await _prepareCompletion(
+ '!',
+ '''
+f() {
+ if (false!)
+}
+''');
+ _assertHasChange(
+ 'Expand !',
+ '''
+f() {
+ if (true)
+}
+''');
+ }
+
+ test_notFunc() async {
+ await _prepareCompletion(
+ '.not',
+ '''
+bool f() {
+ if (f().not)
+}
+''');
+ _assertHasChange(
+ 'Expand .not',
+ '''
+bool f() {
+ if (!f())
+}
+''');
+ }
+
+ test_notTrue() async {
+ await _prepareCompletion(
+ '.not',
+ '''
+f() {
+ if (true.not)
+}
+''');
+ _assertHasChange(
+ 'Expand .not',
+ '''
+f() {
+ if (false)
+}
+''');
+ }
+}
+
+@reflectiveTest
+class _NotNullTest extends PostfixCompletionTest {
+ test_nn() async {
+ await _prepareCompletion(
+ '.nn',
+ '''
+f(expr) {
+ var list = [1,2,3];
+ list.nn
+}
+''');
+ _assertHasChange(
+ 'Expand .nn',
+ '''
+f(expr) {
+ var list = [1,2,3];
+ if (list != null) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ @failingTest
+ test_nn_invalid() async {
+ await _prepareCompletion(
+ '.nn',
+ '''
+f(expr) {
+ var list = [1,2,3];
+}.nn
+''');
+ }
+
+ test_nnDynamic() async {
+ await _prepareCompletion(
+ '.nn',
+ '''
+f(expr) {
+ expr.nn
+}
+''');
+ _assertHasChange(
+ 'Expand .nn',
+ '''
+f(expr) {
+ if (expr != null) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ test_notnull() async {
+ await _prepareCompletion(
+ '.notnull',
+ '''
+f(expr) {
+ var list = [1,2,3];
+ list.notnull
+}
+''');
+ _assertHasChange(
+ 'Expand .notnull',
+ '''
+f(expr) {
+ var list = [1,2,3];
+ if (list != null) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ test_null() async {
+ await _prepareCompletion(
+ '.null',
+ '''
+f(expr) {
+ var list = [1,2,3];
+ list.null
+}
+''');
+ _assertHasChange(
+ 'Expand .null',
+ '''
+f(expr) {
+ var list = [1,2,3];
+ if (list == null) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ test_nullnn() async {
+ await _prepareCompletion(
+ '.nn',
+ '''
+f() {
+ null.nn
+}
+''');
+ _assertHasChange(
+ 'Expand .nn',
+ '''
+f() {
+ if (false) {
+ /*caret*/
+ }
+}
+''');
+ }
+
+ test_nullnull() async {
+ await _prepareCompletion(
+ '.null',
+ '''
+f() {
+ null.null
+}
+''');
+ _assertHasChange(
+ 'Expand .null',
+ '''
+f() {
+ if (true) {
+ /*caret*/
+ }
+}
+''');
+ }
+}
+
+@reflectiveTest
+class _ParenTest extends PostfixCompletionTest {
+ test_paren() async {
+ await _prepareCompletion(
+ '.par',
+ '''
+f(expr) {
+ expr.par
+}
+''');
+ _assertHasChange(
+ 'Expand .par',
+ '''
+f(expr) {
+ (expr)
+}
+''');
+ }
+}
+
+@reflectiveTest
+class _ReturnTest extends PostfixCompletionTest {
+ test_return() async {
+ await _prepareCompletion(
+ '.return',
+ '''
+f(expr) {
+ expr.return
+}
+''');
+ _assertHasChange(
+ 'Expand .return',
+ '''
+f(expr) {
+ return expr;
+}
+''');
+ }
+}
+
+@reflectiveTest
+class _SwitchTest extends PostfixCompletionTest {
+ test_return() async {
+ await _prepareCompletion(
+ '.switch',
+ '''
+f(expr) {
+ expr.switch
+}
+''');
+ _assertHasChange(
+ 'Expand .switch',
+ '''
+f(expr) {
+ switch (expr) {
+ /*caret*/
+ }
+}
+''');
+ }
+}
+
+@reflectiveTest
+class _TryTest extends PostfixCompletionTest {
+ test_try() async {
+ await _prepareCompletion(
+ '.try',
+ '''
+f() {
+ var x = 1.try
+}
+''');
+ _assertHasChange(
+ 'Expand .try',
+ '''
+f() {
+ try {
+ var x = 1/*caret*/
+ } catch (e, s) {
+ print(s);
+ }
+}
+''');
+ }
+
+ @failingTest
+ test_try_invalid() async {
+ // The semicolon is fine; this fails because of the do-statement.
+ await _prepareCompletion(
+ '.try',
+ '''
+f() {
+ do {} while (true);.try
+}
+''');
+ }
+
+ test_tryMultiline() async {
+ await _prepareCompletion(
+ '.try',
+ '''
+f(arg) {
+ arg
+ ..first
+ ..second
+ ..third
+ ..fourth.try
+}
+''');
+ _assertHasChange(
+ 'Expand .try',
+ '''
+f(arg) {
+ try {
+ arg
+ ..first
+ ..second
+ ..third
+ ..fourth/*caret*/
+ } catch (e, s) {
+ print(s);
+ }
+}
+''');
+ }
+
+ test_tryon() async {
+ await _prepareCompletion(
+ '.tryon',
+ '''
+f() {
+ var x = 1.tryon
+}
+''');
+ _assertHasChange(
+ 'Expand .tryon',
+ '''
+f() {
+ try {
+ var x = 1/*caret*/
+ } on Exception catch (e, s) {
+ print(s);
+ }
+}
+''');
+ }
+
+ test_tryonThrowStatement() async {
+ await _prepareCompletion(
+ '.tryon',
+ '''
+f() {
+ throw 'error';.tryon
+}
+''');
+ _assertHasChange(
+ 'Expand .tryon',
+ '''
+f() {
+ try {
+ throw 'error';/*caret*/
+ } on String catch (e, s) {
+ print(s);
+ }
+}
+''');
+ }
+
+ test_tryonThrowString() async {
+ await _prepareCompletion(
+ '.tryon',
+ '''
+f() {
+ throw 'error'.tryon
+}
+''');
+ _assertHasChange(
+ 'Expand .tryon',
+ '''
+f() {
+ try {
+ throw 'error'/*caret*/
+ } on String catch (e, s) {
+ print(s);
+ }
+}
+''');
+ }
+}
+
+@reflectiveTest
+class _WhileTest extends PostfixCompletionTest {
+ test_while() async {
+ await _prepareCompletion(
+ '.while',
+ '''
+f(expr) {
+ expr.while
+}
+''');
+ _assertHasChange(
+ 'Expand .while',
+ '''
+f(expr) {
+ while (expr) {
+ /*caret*/
+ }
+}
+''');
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698