| // Copyright (c) 2024, 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:dart_style/src/analysis_options/analysis_options_file.dart'; |
| import 'package:dart_style/src/testing/test_file_system.dart'; |
| import 'package:test/test.dart'; |
| |
| import '../utils.dart'; |
| |
| void main() { |
| group('findAnalysisOptions()', () { |
| test('returns an empty map if no analysis options is found', () async { |
| var testFS = TestFileSystem(); |
| var options = await findAnalysisOptions( |
| testFS, |
| TestFileSystemPath('dir|sub'), |
| ); |
| expect(options, isEmpty); |
| }); |
| |
| test('finds a file in the given directory', () async { |
| var testFS = TestFileSystem({ |
| 'dir|analysis_options.yaml': analysisOptions(pageWidth: 100), |
| }); |
| |
| var options = await findAnalysisOptions( |
| testFS, |
| TestFileSystemPath('dir'), |
| ); |
| expect(_pageWidth(options), equals(100)); |
| }); |
| |
| test('stops at the nearest analysis options file', () async { |
| var testFS = TestFileSystem({ |
| 'dir|analysis_options.yaml': analysisOptions(pageWidth: 120), |
| 'dir|sub|analysis_options.yaml': analysisOptions(pageWidth: 100), |
| }); |
| |
| var options = await findAnalysisOptions( |
| testFS, |
| TestFileSystemPath('dir|sub'), |
| ); |
| expect(_pageWidth(options), equals(100)); |
| }); |
| |
| test('uses the nearest file even if it doesn\'t have the ' |
| 'setting', () async { |
| var testFS = TestFileSystem({ |
| 'dir|analysis_options.yaml': analysisOptions(pageWidth: 120), |
| 'dir|sub|analysis_options.yaml': analysisOptions( |
| other: {'other': 'stuff'}, |
| ), |
| }); |
| |
| var options = await findAnalysisOptions( |
| testFS, |
| TestFileSystemPath('dir|sub'), |
| ); |
| expect(_pageWidth(options), isNull); |
| }); |
| }); |
| |
| group('readAnalysisOptionsOptions()', () { |
| test('reads an analysis options file', () async { |
| var testFS = TestFileSystem({ |
| 'file.yaml': analysisOptions(pageWidth: 120), |
| }); |
| |
| var options = await readAnalysisOptions( |
| testFS, |
| TestFileSystemPath('file.yaml'), |
| ); |
| expect(_pageWidth(options), 120); |
| }); |
| |
| test('yields an empty map if the file isn\'t a YAML map', () async { |
| var testFS = TestFileSystem({'file.yaml': '123'}); |
| var options = await readAnalysisOptions( |
| testFS, |
| TestFileSystemPath('file.yaml'), |
| ); |
| expect(options, isA<Map>()); |
| expect(options, isEmpty); |
| }); |
| |
| test('merges included files', () async { |
| var testFS = TestFileSystem({ |
| 'dir|a.yaml': analysisOptions( |
| include: 'b.yaml', |
| other: { |
| 'a': 'from a', |
| 'ab': 'from a', |
| 'ac': 'from a', |
| 'abc': 'from a', |
| 'ad': 'from a', |
| }, |
| ), |
| 'dir|b.yaml': analysisOptions( |
| include: ['c.yaml', 'd.yaml'], |
| other: { |
| 'ab': 'from b', |
| 'abc': 'from b', |
| 'b': 'from b', |
| 'bc': 'from b', |
| 'bd': 'from b', |
| }, |
| ), |
| 'dir|c.yaml': analysisOptions( |
| other: { |
| 'ac': 'from c', |
| 'abc': 'from c', |
| 'bc': 'from c', |
| 'c': 'from c', |
| 'cd': 'from c', |
| }, |
| ), |
| 'dir|d.yaml': analysisOptions( |
| other: {'ad': 'from d', 'bd': 'from d', 'cd': 'from d'}, |
| ), |
| }); |
| |
| var options = await readAnalysisOptions( |
| testFS, |
| TestFileSystemPath('dir|a.yaml'), |
| ); |
| expect(options['a'], 'from a'); |
| expect(options['ab'], 'from a'); |
| expect(options['ac'], 'from a'); |
| expect(options['ad'], 'from a'); |
| expect(options['abc'], 'from a'); |
| expect(options['b'], 'from b'); |
| expect(options['bc'], 'from b'); |
| expect(options['bd'], 'from b'); |
| expect(options['c'], 'from c'); |
| expect(options['cd'], 'from d'); |
| }); |
| |
| test('removes the include key after merging', () async { |
| var testFS = TestFileSystem({ |
| 'dir|main.yaml': analysisOptions(pageWidth: 120, include: 'a.yaml'), |
| 'dir|a.yaml': analysisOptions(other: {'a': 123}), |
| }); |
| |
| var options = await readAnalysisOptions( |
| testFS, |
| TestFileSystemPath('dir|main.yaml'), |
| ); |
| expect(options['include'], isNull); |
| }); |
| |
| test('locates includes relative to the parent directory', () async { |
| var testFS = TestFileSystem({ |
| 'dir|a.yaml': analysisOptions( |
| include: 'sub|b.yaml', |
| other: {'a': 'from a'}, |
| ), |
| 'dir|sub|b.yaml': analysisOptions( |
| include: 'more|c.yaml', |
| other: {'b': 'from b'}, |
| ), |
| 'dir|sub|more|c.yaml': analysisOptions(other: {'c': 'from c'}), |
| }); |
| |
| var options = await readAnalysisOptions( |
| testFS, |
| TestFileSystemPath('dir|a.yaml'), |
| ); |
| expect(options['a'], 'from a'); |
| expect(options['b'], 'from b'); |
| expect(options['c'], 'from c'); |
| }); |
| |
| test('resolves "package:" includes', () async { |
| var testFS = TestFileSystem({ |
| 'dir|a.yaml': analysisOptions( |
| include: 'package:b/b_options.yaml', |
| other: {'a': 'from a'}, |
| ), |
| '|b|b_options.yaml': analysisOptions( |
| include: 'package:c/c_options.yaml', |
| other: {'b': 'from b'}, |
| ), |
| '|c|c_options.yaml': analysisOptions(other: {'c': 'from c'}), |
| }); |
| |
| Future<String?> resolve(Uri packageUri) async { |
| return '|${packageUri.pathSegments.join('|')}'; |
| } |
| |
| var options = await readAnalysisOptions( |
| testFS, |
| TestFileSystemPath('dir|a.yaml'), |
| resolvePackageUri: resolve, |
| ); |
| expect(options['a'], 'from a'); |
| expect(options['b'], 'from b'); |
| expect(options['c'], 'from c'); |
| }); |
| |
| test('throws on a "package:" include with no package resolver', () async { |
| var testFS = TestFileSystem({ |
| 'options.yaml': analysisOptions(include: 'package:foo/options.yaml'), |
| }); |
| |
| expect( |
| readAnalysisOptions(testFS, TestFileSystemPath('options.yaml')), |
| throwsA(isA<PackageResolutionException>()), |
| ); |
| }); |
| |
| test('throws on a "package:" resolution failure', () async { |
| var testFS = TestFileSystem({ |
| 'options.yaml': analysisOptions(include: 'package:foo/options.yaml'), |
| }); |
| |
| // A resolver that always fails. |
| Future<String?> failingResolver(Uri uri) async => null; |
| |
| expect( |
| readAnalysisOptions( |
| testFS, |
| TestFileSystemPath('options.yaml'), |
| resolvePackageUri: failingResolver, |
| ), |
| throwsA(isA<PackageResolutionException>()), |
| ); |
| }); |
| }); |
| } |
| |
| /// Reads the `formatter/page_width` key from [options] if present and returns |
| /// it or `null` if not found. |
| Object? _pageWidth(AnalysisOptions options) => |
| (options['formatter'] as Map<Object?, Object?>?)?['page_width']; |