Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
c8b3c9b7
Unverified
Commit
c8b3c9b7
authored
Sep 30, 2019
by
Jonah Williams
Committed by
GitHub
Sep 30, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use IOOverrides to allow inject file system, write test, find bug (#40066)
parent
45f3c8d0
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
231 additions
and
34 deletions
+231
-34
io.dart
packages/flutter_tools/lib/src/base/io.dart
+5
-4
web_compilation_delegate.dart
..._tools/lib/src/build_runner/web_compilation_delegate.dart
+12
-7
io_test.dart
packages/flutter_tools/test/general.shard/base/io_test.dart
+51
-12
multiroot_asset_reader_test.dart
...neral.shard/build_runner/multiroot_asset_reader_test.dart
+27
-11
io.dart
packages/flutter_tools/test/src/io.dart
+136
-0
No files found.
packages/flutter_tools/lib/src/base/io.dart
View file @
c8b3c9b7
...
...
@@ -26,7 +26,8 @@
/// increase the API surface that we have to test in Flutter tools, and the APIs
/// in `dart:io` can sometimes be hard to use in tests.
import
'dart:async'
;
import
'dart:io'
as
io
show
exit
,
IOSink
,
Process
,
ProcessInfo
,
ProcessSignal
,
stderr
,
stdin
,
Stdout
,
stdout
;
import
'dart:io'
as
io
show
exit
,
IOSink
,
Process
,
ProcessInfo
,
ProcessSignal
,
stderr
,
stdin
,
Stdout
,
stdout
;
import
'package:meta/meta.dart'
;
...
...
@@ -38,10 +39,10 @@ export 'dart:io'
show
BytesBuilder
,
CompressionOptions
,
// Directory NO! Use `file_system.dart`
// Directory
,
NO! Use `file_system.dart`
exitCode
,
// File NO! Use `file_system.dart`
// FileSystemEntity NO! Use `file_system.dart`
// File
,
NO! Use `file_system.dart`
// FileSystemEntity
,
NO! Use `file_system.dart`
gzip
,
HandshakeException
,
HttpClient
,
...
...
packages/flutter_tools/lib/src/build_runner/web_compilation_delegate.dart
View file @
c8b3c9b7
...
...
@@ -125,20 +125,20 @@ class MultirootFileBasedAssetReader extends core.FileBasedAssetReader {
@override
Stream
<
AssetId
>
findAssets
(
Glob
glob
,
{
String
package
})
async
*
{
if
(
package
==
null
||
packageGraph
.
root
.
name
==
package
)
{
final
String
generatedRoot
=
fs
.
path
.
join
(
generatedDirectory
.
path
,
packageGraph
.
root
.
name
);
await
for
(
io
.
FileSystemEntity
entity
in
glob
.
list
(
followLinks:
true
,
root:
packageGraph
.
root
.
path
))
{
if
(
entity
is
io
.
File
&&
_isNotHidden
(
entity
))
{
if
(
entity
is
io
.
File
&&
_isNotHidden
(
entity
)
&&
!
fs
.
path
.
isWithin
(
generatedRoot
,
entity
.
path
)
)
{
yield
_fileToAssetId
(
entity
,
packageGraph
.
root
);
}
}
final
String
generatedRoot
=
fs
.
path
.
join
(
generatedDirectory
.
path
,
packageGraph
.
root
.
name
,
);
if
(!
fs
.
isDirectorySync
(
generatedRoot
))
{
return
;
}
await
for
(
io
.
FileSystemEntity
entity
in
glob
.
list
(
followLinks:
true
,
root:
generatedRoot
))
{
if
(
entity
is
io
.
File
&&
_isNotHidden
(
entity
))
{
yield
_fileToAssetId
(
entity
,
packageGraph
.
root
,
generatedRoot
);
yield
_fileToAssetId
(
entity
,
packageGraph
.
root
,
fs
.
path
.
relative
(
generatedRoot
),
true
);
}
}
return
;
...
...
@@ -161,9 +161,14 @@ class MultirootFileBasedAssetReader extends core.FileBasedAssetReader {
}
/// Creates an [AssetId] for [file], which is a part of [packageNode].
AssetId
_fileToAssetId
(
io
.
File
file
,
core
.
PackageNode
packageNode
,
[
String
root
])
{
AssetId
_fileToAssetId
(
io
.
File
file
,
core
.
PackageNode
packageNode
,
[
String
root
,
bool
generated
=
false
])
{
final
String
filePath
=
path
.
normalize
(
file
.
absolute
.
path
);
final
String
relativePath
=
path
.
relative
(
filePath
,
from:
root
??
packageNode
.
path
);
String
relativePath
;
if
(
generated
)
{
relativePath
=
filePath
.
substring
(
root
.
length
+
2
);
}
else
{
relativePath
=
path
.
relative
(
filePath
,
from:
packageNode
.
path
);
}
return
AssetId
(
packageNode
.
name
,
relativePath
);
}
}
packages/flutter_tools/test/general.shard/base/io_test.dart
View file @
c8b3c9b7
...
...
@@ -5,16 +5,56 @@
import
'dart:async'
;
import
'dart:io'
as
io
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/io.dart'
;
import
'package:mockito/mockito.dart'
;
import
'../../src/common.dart'
;
import
'../../src/context.dart'
;
import
'../../src/io.dart'
;
void
main
(
)
{
group
(
'ProcessSignal'
,
()
{
test
(
'IOOverrides can inject a memory file system'
,
()
async
{
final
MemoryFileSystem
memoryFileSystem
=
MemoryFileSystem
();
final
FlutterIOOverrides
flutterIOOverrides
=
FlutterIOOverrides
(
fileSystem:
memoryFileSystem
);
await
io
.
IOOverrides
.
runWithIOOverrides
(()
async
{
// statics delegate correctly.
expect
(
io
.
FileSystemEntity
.
isWatchSupported
,
memoryFileSystem
.
isWatchSupported
);
expect
(
io
.
Directory
.
systemTemp
.
path
,
memoryFileSystem
.
systemTempDirectory
.
path
);
testUsingContext
(
'signals are properly delegated'
,
()
async
{
// can create and write to files/directories sync.
final
io
.
File
file
=
io
.
File
(
'abc'
);
file
.
writeAsStringSync
(
'def'
);
final
io
.
Directory
directory
=
io
.
Directory
(
'foobar'
);
directory
.
createSync
();
expect
(
memoryFileSystem
.
file
(
'abc'
).
existsSync
(),
true
);
expect
(
memoryFileSystem
.
file
(
'abc'
).
readAsStringSync
(),
'def'
);
expect
(
memoryFileSystem
.
directory
(
'foobar'
).
existsSync
(),
true
);
// can create and write to files/directories async.
final
io
.
File
fileB
=
io
.
File
(
'xyz'
);
await
fileB
.
writeAsString
(
'def'
);
final
io
.
Directory
directoryB
=
io
.
Directory
(
'barfoo'
);
await
directoryB
.
create
();
expect
(
memoryFileSystem
.
file
(
'xyz'
).
existsSync
(),
true
);
expect
(
memoryFileSystem
.
file
(
'xyz'
).
readAsStringSync
(),
'def'
);
expect
(
memoryFileSystem
.
directory
(
'barfoo'
).
existsSync
(),
true
);
// Links
final
io
.
Link
linkA
=
io
.
Link
(
'hhh'
);
final
io
.
Link
linkB
=
io
.
Link
(
'ggg'
);
io
.
File
(
'jjj'
).
createSync
();
io
.
File
(
'lll'
).
createSync
();
await
linkA
.
create
(
'jjj'
);
linkB
.
createSync
(
'lll'
);
expect
(
await
memoryFileSystem
.
link
(
'hhh'
).
resolveSymbolicLinks
(),
await
linkA
.
resolveSymbolicLinks
());
expect
(
memoryFileSystem
.
link
(
'ggg'
).
resolveSymbolicLinksSync
(),
linkB
.
resolveSymbolicLinksSync
());
},
flutterIOOverrides
);
});
testUsingContext
(
'ProcessSignal signals are properly delegated'
,
()
async
{
final
MockIoProcessSignal
mockSignal
=
MockIoProcessSignal
();
final
ProcessSignal
signalUnderTest
=
ProcessSignal
(
mockSignal
);
final
StreamController
<
io
.
ProcessSignal
>
controller
=
StreamController
<
io
.
ProcessSignal
>();
...
...
@@ -25,10 +65,9 @@ void main() {
expect
(
signalUnderTest
,
await
signalUnderTest
.
watch
().
first
);
});
testUsingContext
(
'
toString() works'
,
()
async
{
testUsingContext
(
'ProcessSignal
toString() works'
,
()
async
{
expect
(
io
.
ProcessSignal
.
sigint
.
toString
(),
ProcessSignal
.
SIGINT
.
toString
());
});
});
}
class
MockIoProcessSignal
extends
Mock
implements
io
.
ProcessSignal
{}
packages/flutter_tools/test/general.shard/build_runner/multiroot_asset_reader_test.dart
View file @
c8b3c9b7
...
...
@@ -3,13 +3,16 @@
// found in the LICENSE file.
import
'dart:convert'
;
import
'dart:io'
;
import
'package:build/build.dart'
;
import
'package:build_runner_core/build_runner_core.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/build_runner/web_compilation_delegate.dart'
;
import
'package:glob/glob.dart'
;
import
'../../src/common.dart'
;
import
'../../src/io.dart'
;
import
'../../src/testbed.dart'
;
void
main
(
)
{
...
...
@@ -34,17 +37,30 @@ void main() {
});
test
(
'Can find assets from the generated directory'
,
()
=>
testbed
.
run
(()
async
{
await
IOOverrides
.
runWithIOOverrides
(()
async
{
final
MultirootFileBasedAssetReader
reader
=
MultirootFileBasedAssetReader
(
packageGraph
,
fs
.
directory
(
fs
.
path
.
join
(
'.dart_tool'
,
'build'
,
'generated'
)),
fs
.
directory
(
fs
.
path
.
join
(
'.dart_tool'
,
'build'
,
'generated'
))
);
// Note: we can't read from the regular directory because the default
// asset reader uses the regular file system.
expect
(
await
reader
.
canRead
(
AssetId
(
'foobar'
,
'lib/bar.dart'
)),
true
);
expect
(
await
reader
.
canRead
(
AssetId
(
'foobar'
,
'lib/main.dart'
)),
true
);
expect
(
await
reader
.
readAsString
(
AssetId
(
'foobar'
,
'lib/bar.dart'
)),
'bar'
);
expect
(
await
reader
.
readAsString
(
AssetId
(
'foobar'
,
'lib/main.dart'
)),
'main'
);
expect
(
await
reader
.
readAsBytes
(
AssetId
(
'foobar'
,
'lib/bar.dart'
)),
utf8
.
encode
(
'bar'
));
}));
expect
(
await
reader
.
readAsBytes
(
AssetId
(
'foobar'
,
'lib/main.dart'
)),
utf8
.
encode
(
'main'
));
expect
(
await
reader
.
findAssets
(
Glob
(
'**'
)).
toList
(),
unorderedEquals
(<
AssetId
>[
AssetId
(
'foobar'
,
'pubspec.yaml'
),
AssetId
(
'foobar'
,
'lib/bar.dart'
),
AssetId
(
'foobar'
,
'lib/main.dart'
),
]));
},
FlutterIOOverrides
(
fileSystem:
fs
));
// Some component of either dart:io or build_runner normalizes file uris
// into file paths for windows. This doesn't seem to work with IOOverrides
// leaving all filepaths on windows with forward slashes.
}),
skip:
Platform
.
isWindows
);
});
}
...
...
packages/flutter_tools/test/src/io.dart
0 → 100644
View file @
c8b3c9b7
// Copyright 2019 The Chromium 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
show
IOOverrides
,
Directory
,
File
,
Link
;
import
'package:flutter_tools/src/base/file_system.dart'
;
/// An [IOOverrides] that can delegate to [FileSystem] implementation if provided.
///
/// Does not override any of the socket facilities.
///
/// Do not provide a [LocalFileSystem] as a delegate. Since internally this calls
/// out to `dart:io` classes, it will result in a stack overflow error as the
/// IOOverrides and LocalFileSystem call eachother endlessly.
///
/// The only safe delegate types are those that do not call out to `dart:io`,
/// like the [MemoryFileSystem].
class
FlutterIOOverrides
extends
io
.
IOOverrides
{
FlutterIOOverrides
({
FileSystem
fileSystem
})
:
_fileSystemDelegate
=
fileSystem
;
final
FileSystem
_fileSystemDelegate
;
@override
io
.
Directory
createDirectory
(
String
path
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
createDirectory
(
path
);
}
return
_fileSystemDelegate
.
directory
(
path
);
}
@override
io
.
File
createFile
(
String
path
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
createFile
(
path
);
}
return
_fileSystemDelegate
.
file
(
path
);
}
@override
io
.
Link
createLink
(
String
path
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
createLink
(
path
);
}
return
_fileSystemDelegate
.
link
(
path
);
}
@override
Stream
<
FileSystemEvent
>
fsWatch
(
String
path
,
int
events
,
bool
recursive
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
fsWatch
(
path
,
events
,
recursive
);
}
return
_fileSystemDelegate
.
file
(
path
).
watch
(
events:
events
,
recursive:
recursive
);
}
@override
bool
fsWatchIsSupported
()
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
fsWatchIsSupported
();
}
return
_fileSystemDelegate
.
isWatchSupported
;
}
@override
Future
<
FileSystemEntityType
>
fseGetType
(
String
path
,
bool
followLinks
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
fseGetType
(
path
,
followLinks
);
}
return
_fileSystemDelegate
.
type
(
path
,
followLinks:
followLinks
??
true
);
}
@override
FileSystemEntityType
fseGetTypeSync
(
String
path
,
bool
followLinks
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
fseGetTypeSync
(
path
,
followLinks
);
}
return
_fileSystemDelegate
.
typeSync
(
path
,
followLinks:
followLinks
??
true
);
}
@override
Future
<
bool
>
fseIdentical
(
String
path1
,
String
path2
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
fseIdentical
(
path1
,
path2
);
}
return
_fileSystemDelegate
.
identical
(
path1
,
path2
);
}
@override
bool
fseIdenticalSync
(
String
path1
,
String
path2
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
fseIdenticalSync
(
path1
,
path2
);
}
return
_fileSystemDelegate
.
identicalSync
(
path1
,
path2
);
}
@override
io
.
Directory
getCurrentDirectory
()
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
getCurrentDirectory
();
}
return
_fileSystemDelegate
.
currentDirectory
;
}
@override
io
.
Directory
getSystemTempDirectory
()
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
getSystemTempDirectory
();
}
return
_fileSystemDelegate
.
systemTempDirectory
;
}
@override
void
setCurrentDirectory
(
String
path
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
setCurrentDirectory
(
path
);
}
_fileSystemDelegate
.
currentDirectory
=
path
;
}
@override
Future
<
FileStat
>
stat
(
String
path
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
stat
(
path
);
}
return
_fileSystemDelegate
.
stat
(
path
);
}
@override
FileStat
statSync
(
String
path
)
{
if
(
_fileSystemDelegate
==
null
)
{
return
super
.
statSync
(
path
);
}
return
_fileSystemDelegate
.
statSync
(
path
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment