| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer_cli.test.driver; | 5 library analyzer_cli.test.driver; |
| 6 | 6 |
| 7 import 'dart:io'; | 7 import 'dart:io'; |
| 8 | 8 |
| 9 import 'package:analyzer/plugin/options.dart'; | 9 import 'package:analyzer/plugin/options.dart'; |
| 10 import 'package:analyzer/source/analysis_options_provider.dart'; | 10 import 'package:analyzer/source/analysis_options_provider.dart'; |
| 11 import 'package:analyzer/source/error_processor.dart'; |
| 11 import 'package:analyzer/src/generated/engine.dart'; | 12 import 'package:analyzer/src/generated/engine.dart'; |
| 12 import 'package:analyzer/src/generated/error.dart'; | 13 import 'package:analyzer/src/generated/error.dart'; |
| 13 import 'package:analyzer/src/generated/source.dart'; | 14 import 'package:analyzer/src/generated/source.dart'; |
| 14 import 'package:analyzer/src/plugin/plugin_configuration.dart'; | 15 import 'package:analyzer/src/plugin/plugin_configuration.dart'; |
| 15 import 'package:analyzer/src/services/lint.dart'; | 16 import 'package:analyzer/src/services/lint.dart'; |
| 16 import 'package:analyzer_cli/src/bootloader.dart'; | 17 import 'package:analyzer_cli/src/bootloader.dart'; |
| 17 import 'package:analyzer_cli/src/driver.dart'; | 18 import 'package:analyzer_cli/src/driver.dart'; |
| 18 import 'package:analyzer_cli/src/options.dart'; | 19 import 'package:analyzer_cli/src/options.dart'; |
| 19 import 'package:path/path.dart' as path; | 20 import 'package:path/path.dart' as path; |
| 20 import 'package:plugin/plugin.dart'; | 21 import 'package:plugin/plugin.dart'; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 driver.start([ | 63 driver.start([ |
| 63 '--options', | 64 '--options', |
| 64 path.join(testDirectory, 'data/test_options.yaml'), | 65 path.join(testDirectory, 'data/test_options.yaml'), |
| 65 path.join(testDirectory, 'data/test_file.dart') | 66 path.join(testDirectory, 'data/test_file.dart') |
| 66 ]); | 67 ]); |
| 67 expect(processor.options['test_plugin'], isNotNull); | 68 expect(processor.options['test_plugin'], isNotNull); |
| 68 expect(processor.exception, isNull); | 69 expect(processor.exception, isNull); |
| 69 }); | 70 }); |
| 70 }); | 71 }); |
| 71 | 72 |
| 72 //TODO(pq): refactor to NOT set actual error codes to play nice with bots | |
| 73 group('exit codes', () { | 73 group('exit codes', () { |
| 74 test('fatal hints', () { | 74 test('fatal hints', () { |
| 75 drive('data/file_with_hint.dart', args: ['--fatal-hints']); | 75 drive('data/file_with_hint.dart', args: ['--fatal-hints']); |
| 76 expect(exitCode, 3); | 76 expect(exitCode, 3); |
| 77 }); | 77 }); |
| 78 | 78 |
| 79 test('not fatal hints', () { | 79 test('not fatal hints', () { |
| 80 drive('data/file_with_hint.dart'); | 80 drive('data/file_with_hint.dart'); |
| 81 expect(exitCode, 0); | 81 expect(exitCode, 0); |
| 82 }); | 82 }); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 expect(containsLintRuleEntry(options), true); | 221 expect(containsLintRuleEntry(options), true); |
| 222 options = parseOptions(''' | 222 options = parseOptions(''' |
| 223 linter: | 223 linter: |
| 224 # rules: | 224 # rules: |
| 225 # - foo | 225 # - foo |
| 226 '''); | 226 '''); |
| 227 expect(containsLintRuleEntry(options), false); | 227 expect(containsLintRuleEntry(options), false); |
| 228 }); | 228 }); |
| 229 | 229 |
| 230 group('options processing', () { | 230 group('options processing', () { |
| 231 // Shared driver command. | 231 group('basic config', () { |
| 232 var doDrive = () => drive('data/options_tests_project/test_file.dart', | 232 // Shared driver command. |
| 233 options: 'data/options_tests_project/.analysis_options'); | 233 var doDrive = () => drive('data/options_tests_project/test_file.dart', |
| 234 options: 'data/options_tests_project/.analysis_options'); |
| 234 | 235 |
| 235 group('error filters', () { | |
| 236 test('filters', () { | 236 test('filters', () { |
| 237 doDrive(); | 237 doDrive(); |
| 238 var processors = | 238 expect(processors, hasLength(3)); |
| 239 driver.context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS); | |
| 240 expect(processors, hasLength(1)); | |
| 241 | 239 |
| 240 // unused_local_variable: ignore |
| 242 var unused_local_variable = new AnalysisError( | 241 var unused_local_variable = new AnalysisError( |
| 243 new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [ | 242 new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [ |
| 244 ['x'] | 243 ['x'] |
| 245 ]); | 244 ]); |
| 245 expect(processorFor(unused_local_variable).severity, isNull); |
| 246 | 246 |
| 247 var unusedLocalVariable = | 247 // missing_return: error |
| 248 processors.firstWhere((p) => p.appliesTo(unused_local_variable)); | 248 var missing_return = new AnalysisError( |
| 249 expect(unusedLocalVariable.severity, isNull); | 249 new TestSource(), 0, 1, HintCode.MISSING_RETURN, [ |
| 250 ['x'] |
| 251 ]); |
| 252 expect(processorFor(missing_return).severity, ErrorSeverity.ERROR); |
| 253 expect( |
| 254 outSink.toString(), |
| 255 contains( |
| 256 "[error] This function declares a return type of 'int'")); |
| 257 expect(outSink.toString(), |
| 258 contains("1 error and 1 warning found.")); |
| 250 }); | 259 }); |
| 251 | 260 |
| 252 test('language config', () { | 261 test('language', () { |
| 253 doDrive(); | 262 doDrive(); |
| 254 expect(driver.context.analysisOptions.enableSuperMixins, isTrue); | 263 expect(driver.context.analysisOptions.enableSuperMixins, isTrue); |
| 255 }); | 264 }); |
| 256 }); | 265 }); |
| 266 |
| 267 group('with flags', () { |
| 268 // Shared driver command. |
| 269 var doDrive = () => drive('data/options_tests_project/test_file.dart', |
| 270 args: ['--fatal-warnings'], |
| 271 options: 'data/options_tests_project/.analysis_options'); |
| 272 |
| 273 test('override fatal warning', () { |
| 274 doDrive(); |
| 275 // missing_return: error |
| 276 var undefined_function = new AnalysisError(new TestSource(), 0, 1, |
| 277 StaticTypeWarningCode.UNDEFINED_FUNCTION, [ |
| 278 ['x'] |
| 279 ]); |
| 280 expect( |
| 281 processorFor(undefined_function).severity, ErrorSeverity.WARNING); |
| 282 // Should not be made fatal by `--fatal-warnings`. |
| 283 expect(outSink.toString(), |
| 284 contains("[warning] The function 'baz' is not defined")); |
| 285 expect(outSink.toString(), |
| 286 contains("1 error and 1 warning found.")); |
| 287 }); |
| 288 }); |
| 257 }); | 289 }); |
| 258 | 290 |
| 259 //TODO(pq): fix to be bot-friendly (sdk#25258). | 291 //TODO(pq): fix to be bot-friendly (sdk#25258). |
| 260 // group('in temp directory', () { | 292 // group('in temp directory', () { |
| 261 // Directory savedCurrentDirectory; | 293 // Directory savedCurrentDirectory; |
| 262 // Directory tempDir; | 294 // Directory tempDir; |
| 263 // setUp(() { | 295 // setUp(() { |
| 264 // // Call base setUp. | 296 // // Call base setUp. |
| 265 // _setUp(); | 297 // _setUp(); |
| 266 // savedCurrentDirectory = Directory.current; | 298 // savedCurrentDirectory = Directory.current; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 }); | 401 }); |
| 370 }); | 402 }); |
| 371 }); | 403 }); |
| 372 } | 404 } |
| 373 | 405 |
| 374 const emptyOptionsFile = 'data/empty_options.yaml'; | 406 const emptyOptionsFile = 'data/empty_options.yaml'; |
| 375 | 407 |
| 376 /// Shared driver. | 408 /// Shared driver. |
| 377 Driver driver; | 409 Driver driver; |
| 378 | 410 |
| 411 List<ErrorProcessor> get processors => |
| 412 driver.context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS); |
| 413 |
| 414 ErrorProcessor processorFor(AnalysisError error) => |
| 415 processors.firstWhere((p) => p.appliesTo(error)); |
| 416 |
| 379 /// Start a driver for the given [source], optionally providing additional | 417 /// Start a driver for the given [source], optionally providing additional |
| 380 /// [args] and an [options] file path. The value of [options] defaults to | 418 /// [args] and an [options] file path. The value of [options] defaults to |
| 381 /// an empty options file to avoid unwanted configuration from an otherwise | 419 /// an empty options file to avoid unwanted configuration from an otherwise |
| 382 /// discovered options file. | 420 /// discovered options file. |
| 383 void drive(String source, | 421 void drive(String source, |
| 384 {String options: emptyOptionsFile, List<String> args: const <String>[]}) { | 422 {String options: emptyOptionsFile, List<String> args: const <String>[]}) { |
| 385 driver = new Driver(); | 423 driver = new Driver(); |
| 386 var cmd = [ | 424 var cmd = [ |
| 387 '--options', | 425 '--options', |
| 388 path.join(testDirectory, options), | 426 path.join(testDirectory, options), |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 this.options = options; | 465 this.options = options; |
| 428 } | 466 } |
| 429 } | 467 } |
| 430 | 468 |
| 431 class TestSource implements Source { | 469 class TestSource implements Source { |
| 432 TestSource(); | 470 TestSource(); |
| 433 | 471 |
| 434 @override | 472 @override |
| 435 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 473 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
| 436 } | 474 } |
| OLD | NEW |