OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library test.services.completion.statement; |
| 6 |
| 7 import 'package:analysis_server/src/protocol_server.dart'; |
| 8 import 'package:analysis_server/src/services/completion/statement/statement_comp
letion.dart'; |
| 9 import 'package:analyzer/src/dart/analysis/driver.dart'; |
| 10 import 'package:test/test.dart'; |
| 11 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 12 |
| 13 import '../../../abstract_single_unit.dart'; |
| 14 |
| 15 main() { |
| 16 defineReflectiveSuite(() { |
| 17 defineReflectiveTests(StatementCompletionTest); |
| 18 }); |
| 19 } |
| 20 |
| 21 @reflectiveTest |
| 22 class StatementCompletionTest extends AbstractSingleUnitTest { |
| 23 SourceChange change; |
| 24 |
| 25 bool get enableNewAnalysisDriver => true; |
| 26 |
| 27 test_completeIfEmptyCondition() async { |
| 28 await _prepareCompletion( |
| 29 'if ()', |
| 30 ''' |
| 31 main() { |
| 32 if () |
| 33 } |
| 34 ''', |
| 35 atEnd: true); |
| 36 _assertHasChange( |
| 37 'Complete if-statement', |
| 38 ''' |
| 39 main() { |
| 40 if () { |
| 41 //// |
| 42 } |
| 43 } |
| 44 ''', |
| 45 (s) => s.indexOf('if (') + 'if ('.length); |
| 46 } |
| 47 |
| 48 test_completeIfKeywordOnly() async { |
| 49 await _prepareCompletion( |
| 50 'if', |
| 51 ''' |
| 52 main() { |
| 53 if //// |
| 54 } |
| 55 ''', |
| 56 atEnd: true); |
| 57 _assertHasChange( |
| 58 'Complete if-statement', |
| 59 ''' |
| 60 main() { |
| 61 if () { |
| 62 //// |
| 63 } |
| 64 } |
| 65 ''', |
| 66 (s) => s.indexOf('if (') + 'if ('.length); |
| 67 } |
| 68 |
| 69 test_completeIfWithCondition() async { |
| 70 await _prepareCompletion( |
| 71 'if (tr', // Trigger completion from within expression. |
| 72 ''' |
| 73 main() { |
| 74 if (true) |
| 75 } |
| 76 ''', |
| 77 atEnd: true); |
| 78 _assertHasChange( |
| 79 'Complete if-statement', |
| 80 ''' |
| 81 main() { |
| 82 if (true) { |
| 83 //// |
| 84 } |
| 85 } |
| 86 ''', |
| 87 (s) => s.indexOf(' ') + ' '.length); |
| 88 } |
| 89 |
| 90 test_completeIfAfterCondition_BAD() async { |
| 91 // TODO(messick): Fix the code to make this like test_completeIfWithConditio
n. |
| 92 // Recap: Finding the node at the selectionOffset returns the block, not the |
| 93 // if-statement. Need to understand if that only happens when the if-stateme
nt |
| 94 // is the only statement in the block, or perhaps first or last? And what |
| 95 // happens when it is in the middle of other statements? |
| 96 await _prepareCompletion( |
| 97 'if (true) ', // Trigger completion after space. |
| 98 ''' |
| 99 main() { |
| 100 if (true) //// |
| 101 } |
| 102 ''', |
| 103 atEnd: true); |
| 104 _assertHasChange( |
| 105 // Note: This is not what we want. |
| 106 'Insert a newline at the end of the current line', |
| 107 ''' |
| 108 main() { |
| 109 if (true) //// |
| 110 } |
| 111 } |
| 112 ''', |
| 113 (s) => s.indexOf('if (true) ') + 'if (true) '.length); |
| 114 } |
| 115 |
| 116 test_completeIfWithElse_BAD() async { |
| 117 await _prepareCompletion( |
| 118 'if ()', |
| 119 ''' |
| 120 main() { |
| 121 if () |
| 122 else |
| 123 } |
| 124 ''', |
| 125 atEnd: true); |
| 126 _assertHasChange( |
| 127 // Note: if-statement completion should not trigger. |
| 128 'Insert a newline at the end of the current line', |
| 129 ''' |
| 130 main() { |
| 131 if () |
| 132 else |
| 133 } |
| 134 } |
| 135 ''', |
| 136 (s) => s.indexOf('if ()') + 'if ()'.length); |
| 137 } |
| 138 |
| 139 test_completeIfWithinEmptyCondition() async { |
| 140 await _prepareCompletion( |
| 141 'if (', |
| 142 ''' |
| 143 main() { |
| 144 if () |
| 145 } |
| 146 ''', |
| 147 atEnd: true); |
| 148 _assertHasChange( |
| 149 'Complete if-statement', |
| 150 ''' |
| 151 main() { |
| 152 if () { |
| 153 //// |
| 154 } |
| 155 } |
| 156 ''', |
| 157 (s) => s.indexOf('if (') + 'if ('.length); |
| 158 } |
| 159 |
| 160 test_completeWhileKeywordOnly() async { |
| 161 await _prepareCompletion( |
| 162 'while', |
| 163 ''' |
| 164 main() { |
| 165 while //// |
| 166 } |
| 167 ''', |
| 168 atEnd: true); |
| 169 _assertHasChange( |
| 170 'Complete while-statement', |
| 171 ''' |
| 172 main() { |
| 173 while () { |
| 174 //// |
| 175 } |
| 176 } |
| 177 ''', |
| 178 (s) => s.indexOf('while (') + 'while ('.length); |
| 179 } |
| 180 |
| 181 test_simpleEnter() async { |
| 182 await _prepareCompletion( |
| 183 'v = 1;', |
| 184 ''' |
| 185 main() { |
| 186 int v = 1; |
| 187 } |
| 188 ''', |
| 189 atEnd: true); |
| 190 _assertHasChange( |
| 191 'Insert a newline at the end of the current line', |
| 192 ''' |
| 193 main() { |
| 194 int v = 1; |
| 195 //// |
| 196 } |
| 197 '''); |
| 198 } |
| 199 |
| 200 test_simpleSemicolon() async { |
| 201 await _prepareCompletion( |
| 202 'v = 1', |
| 203 ''' |
| 204 main() { |
| 205 int v = 1 |
| 206 } |
| 207 ''', |
| 208 atEnd: true); |
| 209 _assertHasChange( |
| 210 'Add a semicolon and newline', |
| 211 ''' |
| 212 main() { |
| 213 int v = 1; |
| 214 //// |
| 215 } |
| 216 ''', |
| 217 (s) => s.lastIndexOf(' ') + ' '.length); |
| 218 } |
| 219 |
| 220 void _assertHasChange(String message, String expectedCode, [Function cmp]) { |
| 221 if (change.message == message) { |
| 222 if (!change.edits.isEmpty) { |
| 223 String resultCode = |
| 224 SourceEdit.applySequence(testCode, change.edits[0].edits); |
| 225 expect(resultCode, expectedCode.replaceAll('////', '')); |
| 226 if (cmp != null) { |
| 227 int offset = cmp(resultCode); |
| 228 expect(change.selection.offset, offset); |
| 229 } |
| 230 } else { |
| 231 if (cmp != null) { |
| 232 int offset = cmp(testCode); |
| 233 expect(change.selection.offset, offset); |
| 234 } |
| 235 } |
| 236 return; |
| 237 } |
| 238 fail("Expected to find |$message| but got: " + change.message); |
| 239 } |
| 240 |
| 241 _computeCompletion(int offset) async { |
| 242 driver.changeFile(testFile); |
| 243 AnalysisResult result = await driver.getResult(testFile); |
| 244 StatementCompletionContext context = new StatementCompletionContext( |
| 245 testFile, |
| 246 result.lineInfo, |
| 247 offset, |
| 248 testUnit, |
| 249 testUnitElement, |
| 250 result.errors); |
| 251 StatementCompletionProcessor processor = |
| 252 new StatementCompletionProcessor(context); |
| 253 StatementCompletion completion = await processor.compute(); |
| 254 change = completion.change; |
| 255 } |
| 256 |
| 257 _prepareCompletion(String search, String sourceCode, |
| 258 {bool atStart: false, bool atEnd: false, int delta: 0}) async { |
| 259 testCode = sourceCode.replaceAll('////', ''); |
| 260 int offset = findOffset(search); |
| 261 if (atStart) { |
| 262 delta = 0; |
| 263 } else if (atEnd) { |
| 264 delta = search.length; |
| 265 } |
| 266 await _prepareCompletionAt(offset + delta, testCode); |
| 267 } |
| 268 |
| 269 _prepareCompletionAt(int offset, String sourceCode) async { |
| 270 verifyNoTestUnitErrors = false; |
| 271 await resolveTestUnit(sourceCode); |
| 272 await _computeCompletion(offset); |
| 273 } |
| 274 } |
OLD | NEW |