// Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:io' as io; import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/multi_root_file_system.dart'; import '../../src/common.dart'; void setupFileSystem({ required MemoryFileSystem fs, required List directories, required List files, }) { for (final directory in directories) { fs.directory(directory).createSync(recursive: true); } for (final file in files) { fs.file(file).writeAsStringSync('Content: $file'); } } void main() { group('Posix style', () { runTest(FileSystemStyle.posix); }); group('Windows style', () { runTest(FileSystemStyle.windows); }); } void runTest(FileSystemStyle style) { final sep = style == FileSystemStyle.windows ? r'\' : '/'; final root = style == FileSystemStyle.windows ? r'C:\' : '/'; final rootUri = style == FileSystemStyle.windows ? 'C:/' : ''; late MultiRootFileSystem fs; setUp(() { final memory = MemoryFileSystem(style: style); setupFileSystem( fs: memory, directories: [ '${root}foo${sep}subdir', '${root}bar', '${root}bar${sep}bar_subdir', '${root}other${sep}directory', ], files: [ '${root}foo${sep}only_in_foo', '${root}foo${sep}in_both', '${root}foo${sep}subdir${sep}in_subdir', '${root}bar${sep}only_in_bar', '${root}bar${sep}in_both', '${root}bar${sep}bar_subdir${sep}in_subdir', '${root}other${sep}directory${sep}file', ], ); fs = MultiRootFileSystem( delegate: memory, scheme: 'scheme', roots: ['${root}foo$sep', '${root}bar'], ); }); testWithoutContext('file inside root', () { final File file = fs.file('${root}foo${sep}only_in_foo'); expect(file.readAsStringSync(), 'Content: ${root}foo${sep}only_in_foo'); expect(file.path, '${root}foo${sep}only_in_foo'); expect(file.uri, Uri.parse('scheme:///only_in_foo')); }); testWithoutContext('file inside second root', () { final File file = fs.file('${root}bar${sep}only_in_bar'); expect(file.readAsStringSync(), 'Content: ${root}bar${sep}only_in_bar'); expect(file.path, '${root}bar${sep}only_in_bar'); expect(file.uri, Uri.parse('scheme:///only_in_bar')); }); testWithoutContext('file outside root', () { final File file = fs.file('${root}other${sep}directory${sep}file'); expect(file.readAsStringSync(), 'Content: ${root}other${sep}directory${sep}file'); expect(file.path, '${root}other${sep}directory${sep}file'); expect(file.uri, Uri.parse('file:///${rootUri}other/directory/file')); }); testWithoutContext('file with file system scheme', () { final File file = fs.file('scheme:///only_in_foo'); expect(file.readAsStringSync(), 'Content: ${root}foo${sep}only_in_foo'); expect(file.path, '${root}foo${sep}only_in_foo'); expect(file.uri, Uri.parse('scheme:///only_in_foo')); }); testWithoutContext('file with file system scheme URI', () { final File file = fs.file(Uri.parse('scheme:///only_in_foo')); expect(file.readAsStringSync(), 'Content: ${root}foo${sep}only_in_foo'); expect(file.path, '${root}foo${sep}only_in_foo'); expect(file.uri, Uri.parse('scheme:///only_in_foo')); }); testWithoutContext('file in second root with file system scheme', () { final File file = fs.file('scheme:///only_in_bar'); expect(file.readAsStringSync(), 'Content: ${root}bar${sep}only_in_bar'); expect(file.path, '${root}bar${sep}only_in_bar'); expect(file.uri, Uri.parse('scheme:///only_in_bar')); }); testWithoutContext('file in second root with file system scheme URI', () { final File file = fs.file(Uri.parse('scheme:///only_in_bar')); expect(file.readAsStringSync(), 'Content: ${root}bar${sep}only_in_bar'); expect(file.path, '${root}bar${sep}only_in_bar'); expect(file.uri, Uri.parse('scheme:///only_in_bar')); }); testWithoutContext('file in both roots', () { final File file = fs.file(Uri.parse('scheme:///in_both')); expect(file.readAsStringSync(), 'Content: ${root}foo${sep}in_both'); expect(file.path, '${root}foo${sep}in_both'); expect(file.uri, Uri.parse('scheme:///in_both')); }); testWithoutContext('file with scheme in subdirectory', () { final File file = fs.file(Uri.parse('scheme:///subdir/in_subdir')); expect(file.readAsStringSync(), 'Content: ${root}foo${sep}subdir${sep}in_subdir'); expect(file.path, '${root}foo${sep}subdir${sep}in_subdir'); expect(file.uri, Uri.parse('scheme:///subdir/in_subdir')); }); testWithoutContext('file in second root with scheme in subdirectory', () { final File file = fs.file(Uri.parse('scheme:///bar_subdir/in_subdir')); expect(file.readAsStringSync(), 'Content: ${root}bar${sep}bar_subdir${sep}in_subdir'); expect(file.path, '${root}bar${sep}bar_subdir${sep}in_subdir'); expect(file.uri, Uri.parse('scheme:///bar_subdir/in_subdir')); }); testWithoutContext('non-existent file with scheme', () { final File file = fs.file(Uri.parse('scheme:///not_exist')); expect(file.uri, Uri.parse('scheme:///not_exist')); expect(file.path, '${root}foo${sep}not_exist'); }); testWithoutContext('stat', () async { expect((await fs.stat('${root}foo${sep}only_in_foo')).type, io.FileSystemEntityType.file); expect((await fs.stat('scheme:///only_in_foo')).type, io.FileSystemEntityType.file); expect(fs.statSync('${root}foo${sep}only_in_foo').type, io.FileSystemEntityType.file); expect(fs.statSync('scheme:///only_in_foo').type, io.FileSystemEntityType.file); }); testWithoutContext('type', () async { expect(await fs.type('${root}foo${sep}only_in_foo'), io.FileSystemEntityType.file); expect(await fs.type('scheme:///only_in_foo'), io.FileSystemEntityType.file); expect(await fs.type('${root}foo${sep}subdir'), io.FileSystemEntityType.directory); expect(await fs.type('scheme:///subdir'), io.FileSystemEntityType.directory); expect(await fs.type('${root}foo${sep}not_found'), io.FileSystemEntityType.notFound); expect(await fs.type('scheme:///not_found'), io.FileSystemEntityType.notFound); expect(fs.typeSync('${root}foo${sep}only_in_foo'), io.FileSystemEntityType.file); expect(fs.typeSync('scheme:///only_in_foo'), io.FileSystemEntityType.file); expect(fs.typeSync('${root}foo${sep}subdir'), io.FileSystemEntityType.directory); expect(fs.typeSync('scheme:///subdir'), io.FileSystemEntityType.directory); expect(fs.typeSync('${root}foo${sep}not_found'), io.FileSystemEntityType.notFound); expect(fs.typeSync('scheme:///not_found'), io.FileSystemEntityType.notFound); }); testWithoutContext('identical', () async { expect(await fs.identical('${root}foo${sep}in_both', '${root}foo${sep}in_both'), true); expect(await fs.identical('${root}foo${sep}in_both', 'scheme:///in_both'), true); expect(await fs.identical('${root}foo${sep}in_both', 'scheme:///in_both'), true); expect(await fs.identical('${root}bar${sep}in_both', 'scheme:///in_both'), false); expect(fs.identicalSync('${root}foo${sep}in_both', '${root}foo${sep}in_both'), true); expect(fs.identicalSync('${root}foo${sep}in_both', 'scheme:///in_both'), true); expect(fs.identicalSync('${root}foo${sep}in_both', 'scheme:///in_both'), true); expect(fs.identicalSync('${root}bar${sep}in_both', 'scheme:///in_both'), false); }); }