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

Unified Diff: pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart

Issue 2824233002: Complete for-statement (Closed)
Patch Set: Replace empty with synthetic Created 3 years, 8 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
« no previous file with comments | « pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
diff --git a/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart b/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
index 1b99cfed2f6992a0819587c184cf7ad930e2e456..e6d4077c69988fc975ead13829195c295242767c 100644
--- a/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
+++ b/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
@@ -14,17 +14,84 @@ import '../../../abstract_single_unit.dart';
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(StatementCompletionTest);
+ defineReflectiveTests(_DoCompletionTest);
+ defineReflectiveTests(_ForCompletionTest);
+ defineReflectiveTests(_IfCompletionTest);
+ defineReflectiveTests(_SimpleCompletionTest);
+ defineReflectiveTests(_WhileCompletionTest);
});
}
-@reflectiveTest
class StatementCompletionTest extends AbstractSingleUnitTest {
SourceChange change;
bool get enableNewAnalysisDriver => true;
- test_completeDoEmptyCondition() async {
+ int _after(String source, String match) =>
+ source.indexOf(match) + match.length;
+
+ int _afterLast(String source, String match) =>
+ source.lastIndexOf(match) + match.length;
+
+ 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('////', ''));
+ 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) async {
+ driver.changeFile(testFile);
+ AnalysisResult result = await driver.getResult(testFile);
+ StatementCompletionContext context = new StatementCompletionContext(
+ testFile,
+ result.lineInfo,
+ offset,
+ testUnit,
+ testUnitElement,
+ result.errors);
+ StatementCompletionProcessor processor =
+ new StatementCompletionProcessor(context);
+ StatementCompletion completion = await processor.compute();
+ change = completion.change;
+ }
+
+ _prepareCompletion(String search, String sourceCode,
+ {bool atStart: false, bool atEnd: false, int delta: 0}) async {
+ testCode = sourceCode.replaceAll('////', '');
+ int offset = findOffset(search);
+ if (atStart) {
+ delta = 0;
+ } else if (atEnd) {
+ delta = search.length;
+ }
+ await _prepareCompletionAt(offset + delta, testCode);
+ }
+
+ _prepareCompletionAt(int offset, String sourceCode) async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit(sourceCode);
+ await _computeCompletion(offset);
+ }
+}
+
+@reflectiveTest
+class _DoCompletionTest extends StatementCompletionTest {
+ test_emptyCondition() async {
await _prepareCompletion(
'while ()',
'''
@@ -42,10 +109,10 @@ main() {
} while ();
}
''',
- (s) => s.indexOf('while (') + 'while ('.length);
+ (s) => _after(s, 'while ('));
}
- test_completeDoKeywordOnly() async {
+ test_keywordOnly() async {
await _prepareCompletion(
'do',
'''
@@ -63,10 +130,10 @@ main() {
} while ();
}
''',
- (s) => s.indexOf('while (') + 'while ('.length);
+ (s) => _after(s, 'while ('));
}
- test_completeDoNoBody() async {
+ test_noBody() async {
await _prepareCompletion(
'do',
'''
@@ -85,10 +152,10 @@ main() {
} while ();
}
''',
- (s) => s.indexOf('while (') + 'while ('.length);
+ (s) => _after(s, 'while ('));
}
- test_completeDoNoCondition() async {
+ test_noCondition() async {
await _prepareCompletion(
'while',
'''
@@ -106,10 +173,10 @@ main() {
} while ();
}
''',
- (s) => s.indexOf('while (') + 'while ('.length);
+ (s) => _after(s, 'while ('));
}
- test_completeDoNoWhile() async {
+ test_noWhile() async {
await _prepareCompletion(
'}',
'''
@@ -127,10 +194,163 @@ main() {
} while ();
}
''',
- (s) => s.indexOf('while (') + 'while ('.length);
+ (s) => _after(s, 'while ('));
+ }
+}
+
+@reflectiveTest
+class _ForCompletionTest extends StatementCompletionTest {
+ test_emptyCondition() async {
+ await _prepareCompletion(
+ '}',
+ '''
+main() {
+ for (int i = 0;) {
+ }
+}
+''',
+ atEnd: true);
+ _assertHasChange(
+ 'Complete for-statement',
+ '''
+main() {
+ for (int i = 0; ) {
+ }
+}
+''',
+ (s) => _after(s, '0; '));
+ }
+
+ test_emptyInitializers() async {
+ await _prepareCompletion(
+ '}',
+ '''
+main() {
+ for () {
+ }
+}
+''',
+ atEnd: true);
+ _assertHasChange(
+ 'Complete for-statement',
+ '''
+main() {
+ for () {
+ }
+}
+''',
+ (s) => _after(s, 'for ('));
+ }
+
+ test_emptyInitializersEmptyCondition() async {
+ await _prepareCompletion(
+ '}',
+ '''
+main() {
+ for (;/**/) {
+ }
+}
+''',
+ atEnd: true);
+ _assertHasChange(
+ 'Complete for-statement',
+ '''
+main() {
+ for (;/**/) {
+ }
+}
+''',
+ (s) => _after(s, '/**/'));
}
- test_completeIfAfterCondition_BAD() async {
+ test_emptyParts() async {
+ await _prepareCompletion(
+ ';)',
+ '''
+main() {
+ for (;;)
+}
+''',
+ atEnd: true);
+ _assertHasChange(
+ 'Complete for-statement',
+ '''
+main() {
+ for (;;) {
+ ////
+ }
+}
+''',
+ (s) => _after(s, ' '));
+ }
+
+ test_emptyUpdaters() async {
+ await _prepareCompletion(
+ '}',
+ '''
+main() {
+ for (int i = 0; i < 10 /**/) {
+ }
+}
+''',
+ atEnd: true);
+ _assertHasChange(
+ 'Complete for-statement',
+ '''
+main() {
+ for (int i = 0; i < 10 /**/; ) {
+ }
+}
+''',
+ (s) => _after(s, '10 /**/; '));
+ }
+
+ test_keywordOnly() async {
+ await _prepareCompletion(
+ 'for',
+ '''
+main() {
+ for
+}
+''',
+ atEnd: true);
+ _assertHasChange(
+ 'Complete for-statement',
+ '''
+main() {
+ for () {
+ ////
+ }
+}
+''',
+ (s) => _after(s, 'for ('));
+ }
+
+ test_missingLeftSeparator() async {
+ await _prepareCompletion(
+ '}',
+ '''
+main() {
+ for (int i = 0) {
+ }
+}
+''',
+ atEnd: true);
+ _assertHasChange(
+ 'Complete for-statement',
+ '''
+main() {
+ for (int i = 0; ) {
+ }
+}
+''',
+ (s) => _after(s, '0; '));
+ }
+}
+
+@reflectiveTest
+class _IfCompletionTest extends StatementCompletionTest {
+ test_afterCondition_BAD() async {
// TODO(messick): Fix the code to make this like test_completeIfWithCondition.
// Recap: Finding the node at the selectionOffset returns the block, not the
// if-statement. Need to understand if that only happens when the if-statement
@@ -153,10 +373,10 @@ main() {
}
}
''',
- (s) => s.indexOf('if (true) ') + 'if (true) '.length);
+ (s) => _after(s, 'if (true) '));
}
- test_completeIfEmptyCondition() async {
+ test_emptyCondition() async {
await _prepareCompletion(
'if ()',
'''
@@ -174,10 +394,10 @@ main() {
}
}
''',
- (s) => s.indexOf('if (') + 'if ('.length);
+ (s) => _after(s, 'if ('));
}
- test_completeIfKeywordOnly() async {
+ test_keywordOnly() async {
await _prepareCompletion(
'if',
'''
@@ -195,10 +415,10 @@ main() {
}
}
''',
- (s) => s.indexOf('if (') + 'if ('.length);
+ (s) => _after(s, 'if ('));
}
- test_completeIfWithCondition() async {
+ test_withCondition() async {
await _prepareCompletion(
'if (tr', // Trigger completion from within expression.
'''
@@ -216,10 +436,10 @@ main() {
}
}
''',
- (s) => s.indexOf(' ') + ' '.length);
+ (s) => _after(s, ' '));
}
- test_completeIfWithElse_BAD() async {
+ test_withElse_BAD() async {
await _prepareCompletion(
'if ()',
'''
@@ -239,10 +459,10 @@ main() {
}
}
''',
- (s) => s.indexOf('if ()') + 'if ()'.length);
+ (s) => _after(s, 'if ()'));
}
- test_completeIfWithinEmptyCondition() async {
+ test_withinEmptyCondition() async {
await _prepareCompletion(
'if (',
'''
@@ -260,31 +480,13 @@ main() {
}
}
''',
- (s) => s.indexOf('if (') + 'if ('.length);
+ (s) => _after(s, 'if ('));
}
-
- test_completeWhileKeywordOnly() async {
- await _prepareCompletion(
- 'while',
- '''
-main() {
- while ////
}
-''',
- atEnd: true);
- _assertHasChange(
- 'Complete while-statement',
- '''
-main() {
- while () {
- ////
- }
-}
-''',
- (s) => s.indexOf('while (') + 'while ('.length);
- }
- test_simpleEnter() async {
+@reflectiveTest
+class _SimpleCompletionTest extends StatementCompletionTest {
+ test_enter() async {
await _prepareCompletion(
'v = 1;',
'''
@@ -303,7 +505,7 @@ main() {
''');
}
- test_simpleSemicolon() async {
+ test_semicolon() async {
await _prepareCompletion(
'v = 1',
'''
@@ -320,61 +522,37 @@ main() {
////
}
''',
- (s) => s.lastIndexOf(' ') + ' '.length);
- }
-
- 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('////', ''));
- 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) async {
- driver.changeFile(testFile);
- AnalysisResult result = await driver.getResult(testFile);
- StatementCompletionContext context = new StatementCompletionContext(
- testFile,
- result.lineInfo,
- offset,
- testUnit,
- testUnitElement,
- result.errors);
- StatementCompletionProcessor processor =
- new StatementCompletionProcessor(context);
- StatementCompletion completion = await processor.compute();
- change = completion.change;
+ (s) => _afterLast(s, ' '));
}
+}
- _prepareCompletion(String search, String sourceCode,
- {bool atStart: false, bool atEnd: false, int delta: 0}) async {
- testCode = sourceCode.replaceAll('////', '');
- int offset = findOffset(search);
- if (atStart) {
- delta = 0;
- } else if (atEnd) {
- delta = search.length;
- }
- await _prepareCompletionAt(offset + delta, testCode);
+@reflectiveTest
+class _WhileCompletionTest extends StatementCompletionTest {
+ /*
+ The implementation of completion for while-statements is shared with
+ if-statements. Here we check that the wrapper for while-statements
+ functions as expected. The individual test cases are covered by the
+ _IfCompletionTest tests. If the implementation changes then the same
+ set of tests defined for if-statements should be duplicated here.
+ */
+ test_keywordOnly() async {
+ await _prepareCompletion(
+ 'while',
+ '''
+main() {
+ while ////
+}
+''',
+ atEnd: true);
+ _assertHasChange(
+ 'Complete while-statement',
+ '''
+main() {
+ while () {
+ ////
}
-
- _prepareCompletionAt(int offset, String sourceCode) async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit(sourceCode);
- await _computeCompletion(offset);
+}
+''',
+ (s) => _after(s, 'while ('));
}
}
« no previous file with comments | « pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698