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
02b10801
Unverified
Commit
02b10801
authored
May 21, 2020
by
Dan Field
Committed by
GitHub
May 21, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Functionality to check handlers set on platform channels (#57696)
parent
cdef6779
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
145 additions
and
20 deletions
+145
-20
binary_messenger.dart
packages/flutter/lib/src/services/binary_messenger.dart
+18
-3
binding.dart
packages/flutter/lib/src/services/binding.dart
+6
-0
platform_channel.dart
packages/flutter/lib/src/services/platform_channel.dart
+22
-1
autofill_test.dart
packages/flutter/test/services/autofill_test.dart
+6
-0
default_binary_messenger_test.dart
.../flutter/test/services/default_binary_messenger_test.dart
+22
-0
platform_channel_test.dart
packages/flutter/test/services/platform_channel_test.dart
+28
-1
text_input_test.dart
packages/flutter/test/services/text_input_test.dart
+7
-0
binding.dart
packages/flutter_test/lib/src/binding.dart
+10
-0
test_text_input.dart
packages/flutter_test/lib/src/test_text_input.dart
+16
-13
plugin_registry.dart
packages/flutter_web_plugins/lib/src/plugin_registry.dart
+10
-2
No files found.
packages/flutter/lib/src/services/binary_messenger.dart
View file @
02b10801
...
...
@@ -41,20 +41,35 @@ abstract class BinaryMessenger {
/// argument.
///
/// The handler's return value, if non-null, is sent as a response, unencoded.
void
setMessageHandler
(
String
channel
,
Future
<
ByteData
>
handler
(
ByteData
message
));
void
setMessageHandler
(
String
channel
,
MessageHandler
handler
);
/// Returns true if the `handler` argument matches the `handler` previously
/// passed to [setMessageHandler].
///
/// This method is useful for tests or test harnesses that want to assert the
/// handler for the vspecified channel has not been altered by a previous test.
bool
checkMessageHandler
(
String
channel
,
MessageHandler
handler
);
/// Set a mock callback for intercepting messages from the [send] method on
/// this class, on the given channel, without decoding them.
///
/// The given callback will replace the currently registered mock callback for
/// that channel, if any. To remove the mock handler, pass null as the
///
[handler]
argument.
///
`handler`
argument.
///
/// The handler's return value, if non-null, is used as a response, unencoded.
///
/// This is intended for testing. Messages intercepted in this manner are not
/// sent to platform plugins.
void
setMockMessageHandler
(
String
channel
,
Future
<
ByteData
>
handler
(
ByteData
message
));
void
setMockMessageHandler
(
String
channel
,
MessageHandler
handler
);
/// Returns true if the `handler` argument matches the `handler` previously
/// passed to [setMockMessageHandler].
///
/// This method is useful for tests or test harnesses that want to assert the
/// mock handler for the specified channel has not been altered by a previous
/// test.
bool
checkMockMessageHandler
(
String
channel
,
MessageHandler
handler
);
}
/// The default instance of [BinaryMessenger].
...
...
packages/flutter/lib/src/services/binding.dart
View file @
02b10801
...
...
@@ -293,6 +293,9 @@ class _DefaultBinaryMessenger extends BinaryMessenger {
});
}
@override
bool
checkMessageHandler
(
String
channel
,
MessageHandler
handler
)
=>
_handlers
[
channel
]
==
handler
;
@override
void
setMockMessageHandler
(
String
channel
,
MessageHandler
handler
)
{
if
(
handler
==
null
)
...
...
@@ -300,4 +303,7 @@ class _DefaultBinaryMessenger extends BinaryMessenger {
else
_mockHandlers
[
channel
]
=
handler
;
}
@override
bool
checkMockMessageHandler
(
String
channel
,
MessageHandler
handler
)
=>
_mockHandlers
[
channel
]
==
handler
;
}
packages/flutter/lib/src/services/platform_channel.dart
View file @
02b10801
...
...
@@ -98,6 +98,9 @@ class BasicMessageChannel<T> {
}
}
Expando
<
Object
>
_methodChannelHandlers
=
Expando
<
Object
>();
Expando
<
Object
>
_methodChannelMockHandlers
=
Expando
<
Object
>();
/// A named channel for communicating with platform plugins using asynchronous
/// method calls.
///
...
...
@@ -372,12 +375,22 @@ class MethodChannel {
/// similarly to what happens if no method call handler has been set.
/// Any other exception results in an error envelope being sent.
void
setMethodCallHandler
(
Future
<
dynamic
>
handler
(
MethodCall
call
))
{
_methodChannelHandlers
[
this
]
=
handler
;
binaryMessenger
.
setMessageHandler
(
name
,
handler
==
null
?
null
:
(
ByteData
message
)
=>
_handleAsMethodCall
(
message
,
handler
),
handler
==
null
?
null
:
(
ByteData
message
)
=>
_handleAsMethodCall
(
message
,
handler
),
);
}
/// Returns true if the `handler` argument matches the `handler` previously
/// passed to [setMethodCallHandler].
///
/// This method is useful for tests or test harnesses that want to assert the
/// handler for the specified channel has not been altered by a previous test.
bool
checkMethodCallHandler
(
Future
<
dynamic
>
handler
(
MethodCall
call
))
=>
_methodChannelHandlers
[
this
]
==
handler
;
/// Sets a mock callback for intercepting method invocations on this channel.
///
/// The given callback will replace the currently registered mock callback for
...
...
@@ -397,12 +410,20 @@ class MethodChannel {
/// [MethodCodec.encodeSuccessEnvelope], to act as if platform plugin had
/// returned that value.
void
setMockMethodCallHandler
(
Future
<
dynamic
>
handler
(
MethodCall
call
))
{
_methodChannelMockHandlers
[
this
]
=
handler
;
binaryMessenger
.
setMockMessageHandler
(
name
,
handler
==
null
?
null
:
(
ByteData
message
)
=>
_handleAsMethodCall
(
message
,
handler
),
);
}
/// Returns true if the `handler` argument matches the `handler` previously
/// passed to [setMockMethodCallHandler].
///
/// This method is useful for tests or test harnesses that want to assert the
/// handler for the specified channel has not been altered by a previous test.
bool
checkMockMethodCallHandler
(
Future
<
dynamic
>
handler
(
MethodCall
call
))
=>
_methodChannelMockHandlers
[
this
]
==
handler
;
Future
<
ByteData
>
_handleAsMethodCall
(
ByteData
message
,
Future
<
dynamic
>
handler
(
MethodCall
call
))
async
{
final
MethodCall
call
=
codec
.
decodeMethodCall
(
message
);
try
{
...
...
packages/flutter/test/services/autofill_test.dart
View file @
02b10801
...
...
@@ -211,9 +211,15 @@ class FakeTextChannel implements MethodChannel {
incoming
=
handler
;
}
@override
bool
checkMethodCallHandler
(
Future
<
void
>
Function
(
MethodCall
call
)
handler
)
=>
throw
UnimplementedError
();
@override
void
setMockMethodCallHandler
(
Future
<
void
>
Function
(
MethodCall
call
)
handler
)
=>
throw
UnimplementedError
();
@override
bool
checkMockMethodCallHandler
(
Future
<
void
>
Function
(
MethodCall
call
)
handler
)
=>
throw
UnimplementedError
();
void
validateOutgoingMethodCalls
(
List
<
MethodCall
>
calls
)
{
expect
(
outgoingCalls
.
length
,
calls
.
length
);
bool
hasError
=
false
;
...
...
packages/flutter/test/services/default_binary_messenger_test.dart
View file @
02b10801
...
...
@@ -34,4 +34,26 @@ void main() {
});
expect
(
count
,
equals
(
1
));
});
test
(
'can check the handler'
,
()
{
Future
<
ByteData
>
handler
(
ByteData
call
)
=>
Future
<
ByteData
>.
value
(
null
);
final
BinaryMessenger
messenger
=
ServicesBinding
.
instance
.
defaultBinaryMessenger
;
expect
(
messenger
.
checkMessageHandler
(
'test_channel'
,
null
),
true
);
expect
(
messenger
.
checkMessageHandler
(
'test_channel'
,
handler
),
false
);
messenger
.
setMessageHandler
(
'test_channel'
,
handler
);
expect
(
messenger
.
checkMessageHandler
(
'test_channel'
,
handler
),
true
);
messenger
.
setMessageHandler
(
'test_channel'
,
null
);
});
test
(
'can check the mock handler'
,
()
{
Future
<
ByteData
>
handler
(
ByteData
call
)
=>
Future
<
ByteData
>.
value
(
null
);
final
BinaryMessenger
messenger
=
ServicesBinding
.
instance
.
defaultBinaryMessenger
;
expect
(
messenger
.
checkMockMessageHandler
(
'test_channel'
,
null
),
true
);
expect
(
messenger
.
checkMockMessageHandler
(
'test_channel'
,
handler
),
false
);
messenger
.
setMockMessageHandler
(
'test_channel'
,
handler
);
expect
(
messenger
.
checkMockMessageHandler
(
'test_channel'
,
handler
),
true
);
messenger
.
setMockMessageHandler
(
'test_channel'
,
null
);
});
}
packages/flutter/test/services/platform_channel_test.dart
View file @
02b10801
...
...
@@ -58,6 +58,7 @@ void main() {
final
String
result
=
await
channel
.
invokeMethod
(
'sayHello'
,
'hello'
);
expect
(
result
,
equals
(
'hello world'
));
});
test
(
'can invoke list method and get result'
,
()
async
{
ServicesBinding
.
instance
.
defaultBinaryMessenger
.
setMockMessageHandler
(
'ch7'
,
...
...
@@ -89,7 +90,6 @@ void main() {
expect
(
await
channel
.
invokeListMethod
<
String
>(
'sayHello'
,
'hello'
),
null
);
});
test
(
'can invoke map method and get result'
,
()
async
{
ServicesBinding
.
instance
.
defaultBinaryMessenger
.
setMockMessageHandler
(
'ch7'
,
...
...
@@ -143,6 +143,7 @@ void main() {
fail
(
'PlatformException expected'
);
}
});
test
(
'can invoke unimplemented method'
,
()
async
{
ServicesBinding
.
instance
.
defaultBinaryMessenger
.
setMockMessageHandler
(
'ch7'
,
...
...
@@ -158,6 +159,7 @@ void main() {
fail
(
'MissingPluginException expected'
);
}
});
test
(
'can invoke unimplemented method (optional)'
,
()
async
{
ServicesBinding
.
instance
.
defaultBinaryMessenger
.
setMockMessageHandler
(
'ch8'
,
...
...
@@ -166,6 +168,7 @@ void main() {
final
String
result
=
await
optionalMethodChannel
.
invokeMethod
<
String
>(
'sayHello'
,
'hello'
);
expect
(
result
,
isNull
);
});
test
(
'can handle method call with no registered plugin'
,
()
async
{
channel
.
setMethodCallHandler
(
null
);
final
ByteData
call
=
jsonMethod
.
encodeMethodCall
(
const
MethodCall
(
'sayHello'
,
'hello'
));
...
...
@@ -175,6 +178,7 @@ void main() {
});
expect
(
envelope
,
isNull
);
});
test
(
'can handle method call of unimplemented method'
,
()
async
{
channel
.
setMethodCallHandler
((
MethodCall
call
)
async
{
throw
MissingPluginException
();
...
...
@@ -186,6 +190,7 @@ void main() {
});
expect
(
envelope
,
isNull
);
});
test
(
'can handle method call with successful result'
,
()
async
{
channel
.
setMethodCallHandler
((
MethodCall
call
)
async
=>
'
${call.arguments}
, world'
);
final
ByteData
call
=
jsonMethod
.
encodeMethodCall
(
const
MethodCall
(
'sayHello'
,
'hello'
));
...
...
@@ -195,6 +200,7 @@ void main() {
});
expect
(
jsonMethod
.
decodeEnvelope
(
envelope
),
equals
(
'hello, world'
));
});
test
(
'can handle method call with expressive error result'
,
()
async
{
channel
.
setMethodCallHandler
((
MethodCall
call
)
async
{
throw
PlatformException
(
code:
'bad'
,
message:
'sayHello failed'
,
details:
null
);
...
...
@@ -214,6 +220,7 @@ void main() {
fail
(
'PlatformException expected'
);
}
});
test
(
'can handle method call with other error result'
,
()
async
{
channel
.
setMethodCallHandler
((
MethodCall
call
)
async
{
throw
ArgumentError
(
'bad'
);
...
...
@@ -233,6 +240,26 @@ void main() {
fail
(
'PlatformException expected'
);
}
});
test
(
'can check the handler'
,
()
{
Future
<
dynamic
>
handler
(
MethodCall
call
)
=>
Future
<
dynamic
>.
value
(
null
);
const
MethodChannel
channel
=
MethodChannel
(
'test_handler'
);
expect
(
channel
.
checkMethodCallHandler
(
null
),
true
);
expect
(
channel
.
checkMethodCallHandler
(
handler
),
false
);
channel
.
setMethodCallHandler
(
handler
);
expect
(
channel
.
checkMethodCallHandler
(
handler
),
true
);
});
test
(
'can check the mock handler'
,
()
{
Future
<
dynamic
>
handler
(
MethodCall
call
)
=>
Future
<
dynamic
>.
value
(
null
);
const
MethodChannel
channel
=
MethodChannel
(
'test_handler'
);
expect
(
channel
.
checkMockMethodCallHandler
(
null
),
true
);
expect
(
channel
.
checkMockMethodCallHandler
(
handler
),
false
);
channel
.
setMockMethodCallHandler
(
handler
);
expect
(
channel
.
checkMockMethodCallHandler
(
handler
),
true
);
});
});
group
(
'EventChannel'
,
()
{
const
MessageCodec
<
dynamic
>
jsonMessage
=
JSONMessageCodec
();
...
...
packages/flutter/test/services/text_input_test.dart
View file @
02b10801
...
...
@@ -266,9 +266,16 @@ class FakeTextChannel implements MethodChannel {
incoming
=
handler
;
}
@override
bool
checkMethodCallHandler
(
Future
<
void
>
Function
(
MethodCall
call
)
handler
)
=>
throw
UnimplementedError
();
@override
void
setMockMethodCallHandler
(
Future
<
void
>
Function
(
MethodCall
call
)
handler
)
=>
throw
UnimplementedError
();
@override
bool
checkMockMethodCallHandler
(
Future
<
void
>
Function
(
MethodCall
call
)
handler
)
=>
throw
UnimplementedError
();
void
validateOutgoingMethodCalls
(
List
<
MethodCall
>
calls
)
{
expect
(
outgoingCalls
.
length
,
calls
.
length
);
bool
hasError
=
false
;
...
...
packages/flutter_test/lib/src/binding.dart
View file @
02b10801
...
...
@@ -134,10 +134,20 @@ class TestDefaultBinaryMessenger extends BinaryMessenger {
delegate
.
setMessageHandler
(
channel
,
handler
);
}
@override
bool
checkMessageHandler
(
String
channel
,
MessageHandler
handler
)
{
return
delegate
.
checkMessageHandler
(
channel
,
handler
);
}
@override
void
setMockMessageHandler
(
String
channel
,
MessageHandler
handler
)
{
delegate
.
setMockMessageHandler
(
channel
,
handler
);
}
@override
bool
checkMockMessageHandler
(
String
channel
,
MessageHandler
handler
)
{
return
delegate
.
checkMockMessageHandler
(
channel
,
handler
);
}
}
/// Base class for bindings used by widgets library tests.
...
...
packages/flutter_test/lib/src/test_text_input.dart
View file @
02b10801
...
...
@@ -52,20 +52,14 @@ class TestTextInput {
register
();
}
/// Installs this object as a mock handler for [SystemChannels.textInput].
void
register
()
{
SystemChannels
.
textInput
.
setMockMethodCallHandler
(
_handleTextInputCall
);
_isRegistered
=
true
;
}
void
register
()
=>
SystemChannels
.
textInput
.
setMockMethodCallHandler
(
_handleTextInputCall
);
/// Removes this object as a mock handler for [SystemChannels.textInput].
///
/// After calling this method, the channel will exchange messages with the
/// Flutter engine. Use this with [FlutterDriver] tests that need to display
/// on-screen keyboard provided by the operating system.
void
unregister
()
{
SystemChannels
.
textInput
.
setMockMethodCallHandler
(
null
);
_isRegistered
=
false
;
}
void
unregister
()
=>
SystemChannels
.
textInput
.
setMockMethodCallHandler
(
null
);
/// Log for method calls.
///
...
...
@@ -76,12 +70,13 @@ class TestTextInput {
/// Whether this [TestTextInput] is registered with [SystemChannels.textInput].
///
/// Use [register] and [unregister] methods to control this value.
// TODO(dnfield): This is unreliable. https://github.com/flutter/flutter/issues/47180
bool
get
isRegistered
=>
_isRegistered
;
bool
_isRegistered
=
false
;
bool
get
isRegistered
=>
SystemChannels
.
textInput
.
checkMockMethodCallHandler
(
_handleTextInputCall
);
/// Whether there are any active clients listening to text input.
bool
get
hasAnyClients
=>
_client
>
0
;
bool
get
hasAnyClients
{
assert
(
isRegistered
);
return
_client
>
0
;
}
int
_client
=
0
;
...
...
@@ -122,11 +117,15 @@ class TestTextInput {
}
/// Whether the onscreen keyboard is visible to the user.
bool
get
isVisible
=>
_isVisible
;
bool
get
isVisible
{
assert
(
isRegistered
);
return
_isVisible
;
}
bool
_isVisible
=
false
;
/// Simulates the user changing the [TextEditingValue] to the given value.
void
updateEditingValue
(
TextEditingValue
value
)
{
assert
(
isRegistered
);
// Not using the `expect` function because in the case of a FlutterDriver
// test this code does not run in a package:test test zone.
if
(
_client
==
0
)
...
...
@@ -149,6 +148,7 @@ class TestTextInput {
/// - User pressed the home button and sent the application to background.
/// - User closed the virtual keyboard.
void
closeConnection
()
{
assert
(
isRegistered
);
// Not using the `expect` function because in the case of a FlutterDriver
// test this code does not run in a package:test test zone.
if
(
_client
==
0
)
...
...
@@ -167,6 +167,7 @@ class TestTextInput {
/// Simulates the user typing the given text.
void
enterText
(
String
text
)
{
assert
(
isRegistered
);
updateEditingValue
(
TextEditingValue
(
text:
text
,
));
...
...
@@ -176,6 +177,7 @@ class TestTextInput {
/// Does not check that the [TextInputAction] performed is an acceptable one
/// based on the `inputAction` [setClientArgs].
Future
<
void
>
receiveAction
(
TextInputAction
action
)
async
{
assert
(
isRegistered
);
return
TestAsyncUtils
.
guard
(()
{
// Not using the `expect` function because in the case of a FlutterDriver
// test this code does not run in a package:test test zone.
...
...
@@ -215,6 +217,7 @@ class TestTextInput {
/// Simulates the user hiding the onscreen keyboard.
void
hide
()
{
assert
(
isRegistered
);
_isVisible
=
false
;
}
}
packages/flutter_web_plugins/lib/src/plugin_registry.dart
View file @
02b10801
...
...
@@ -118,8 +118,7 @@ class _PlatformBinaryMessenger extends BinaryMessenger {
}
@override
void
setMessageHandler
(
String
channel
,
Future
<
ByteData
>
Function
(
ByteData
message
)
handler
)
{
void
setMessageHandler
(
String
channel
,
MessageHandler
handler
)
{
if
(
handler
==
null
)
_handlers
.
remove
(
channel
);
else
...
...
@@ -129,12 +128,21 @@ class _PlatformBinaryMessenger extends BinaryMessenger {
});
}
@override
bool
checkMessageHandler
(
String
channel
,
MessageHandler
handler
)
=>
_handlers
[
channel
]
==
handler
;
@override
void
setMockMessageHandler
(
String
channel
,
Future
<
ByteData
>
Function
(
ByteData
message
)
handler
)
{
throw
FlutterError
(
'Setting mock handlers is not supported on the platform side.'
);
}
@override
bool
checkMockMessageHandler
(
String
channel
,
MessageHandler
handler
)
{
throw
FlutterError
(
'Setting mock handlers is not supported on the platform side.'
);
}
}
/// The default [BinaryMessenger] for Flutter Web plugins.
...
...
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