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
28c3b558
Commit
28c3b558
authored
Dec 14, 2015
by
Eric Seidel
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #917 from eseidelGoogle/instrument
Split out Instrumentation logic from WidgetTester
parents
0f9d8bc2
3053c0ad
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
182 additions
and
159 deletions
+182
-159
instrumentation.dart
packages/flutter_test/lib/src/instrumentation.dart
+172
-0
widget_tester.dart
packages/flutter_test/lib/src/widget_tester.dart
+10
-159
No files found.
packages/flutter_test/lib/src/instrumentation.dart
0 → 100644
View file @
28c3b558
// Copyright 2015 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:ui'
as
ui
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'test_pointer.dart'
;
typedef
Point
SizeToPointFunction
(
Size
size
);
/// Helper class for flutter tests providing event dispatch.
///
/// This class provides hooks for accessing the rendering tree and dispatching
/// fake tap/drag/etc. events.
class
Instrumentation
{
Instrumentation
()
:
binding
=
WidgetFlutterBinding
.
ensureInitialized
();
final
WidgetFlutterBinding
binding
;
// TODO(ianh): This should not be O(N) hidden behind a getter!
List
<
Layer
>
_layers
(
Layer
layer
)
{
List
<
Layer
>
result
=
<
Layer
>[
layer
];
if
(
layer
is
ContainerLayer
)
{
ContainerLayer
root
=
layer
;
Layer
child
=
root
.
firstChild
;
while
(
child
!=
null
)
{
result
.
addAll
(
_layers
(
child
));
child
=
child
.
nextSibling
;
}
}
return
result
;
}
List
<
Layer
>
get
layers
=>
_layers
(
binding
.
renderView
.
layer
);
void
walkElements
(
ElementVisitor
visitor
)
{
void
walk
(
Element
element
)
{
visitor
(
element
);
element
.
visitChildren
(
walk
);
}
binding
.
renderViewElement
.
visitChildren
(
walk
);
}
Element
findElement
(
bool
predicate
(
Element
element
))
{
try
{
walkElements
((
Element
element
)
{
if
(
predicate
(
element
))
throw
element
;
});
}
on
Element
catch
(
e
)
{
return
e
;
}
return
null
;
}
Element
findElementByKey
(
Key
key
)
{
return
findElement
((
Element
element
)
=>
element
.
widget
.
key
==
key
);
}
Element
findText
(
String
text
)
{
return
findElement
((
Element
element
)
{
return
element
.
widget
is
Text
&&
element
.
widget
.
data
==
text
;
});
}
State
findStateOfType
(
Type
type
)
{
StatefulComponentElement
element
=
findElement
((
Element
element
)
{
return
element
is
StatefulComponentElement
&&
element
.
state
.
runtimeType
==
type
;
});
return
element
?.
state
;
}
State
findStateByConfig
(
Widget
config
)
{
StatefulComponentElement
element
=
findElement
((
Element
element
)
{
return
element
is
StatefulComponentElement
&&
element
.
state
.
config
==
config
;
});
return
element
?.
state
;
}
Point
getCenter
(
Element
element
)
{
return
_getElementPoint
(
element
,
(
Size
size
)
=>
size
.
center
(
Point
.
origin
));
}
Point
getTopLeft
(
Element
element
)
{
return
_getElementPoint
(
element
,
(
_
)
=>
Point
.
origin
);
}
Point
getTopRight
(
Element
element
)
{
return
_getElementPoint
(
element
,
(
Size
size
)
=>
size
.
topRight
(
Point
.
origin
));
}
Point
getBottomLeft
(
Element
element
)
{
return
_getElementPoint
(
element
,
(
Size
size
)
=>
size
.
bottomLeft
(
Point
.
origin
));
}
Point
getBottomRight
(
Element
element
)
{
return
_getElementPoint
(
element
,
(
Size
size
)
=>
size
.
bottomRight
(
Point
.
origin
));
}
Point
_getElementPoint
(
Element
element
,
SizeToPointFunction
sizeToPoint
)
{
assert
(
element
!=
null
);
RenderBox
box
=
element
.
renderObject
as
RenderBox
;
assert
(
box
!=
null
);
return
box
.
localToGlobal
(
sizeToPoint
(
box
.
size
));
}
void
tap
(
Element
element
,
{
int
pointer:
1
})
{
tapAt
(
getCenter
(
element
),
pointer:
pointer
);
}
void
tapAt
(
Point
location
,
{
int
pointer:
1
})
{
HitTestResult
result
=
_hitTest
(
location
);
TestPointer
p
=
new
TestPointer
(
pointer
);
_dispatchEvent
(
p
.
down
(
location
),
result
);
_dispatchEvent
(
p
.
up
(),
result
);
}
void
fling
(
Element
element
,
Offset
offset
,
double
velocity
,
{
int
pointer:
1
})
{
flingFrom
(
getCenter
(
element
),
offset
,
velocity
,
pointer:
pointer
);
}
void
flingFrom
(
Point
startLocation
,
Offset
offset
,
double
velocity
,
{
int
pointer:
1
})
{
assert
(
offset
.
distance
>
0.0
);
assert
(
velocity
!=
0.0
);
// velocity is pixels/second
final
TestPointer
p
=
new
TestPointer
(
pointer
);
final
HitTestResult
result
=
_hitTest
(
startLocation
);
const
int
kMoveCount
=
50
;
// Needs to be >= kHistorySize, see _LeastSquaresVelocityTrackerStrategy
final
double
timeStampDelta
=
1000.0
*
offset
.
distance
/
(
kMoveCount
*
velocity
);
double
timeStamp
=
0.0
;
_dispatchEvent
(
p
.
down
(
startLocation
,
timeStamp:
new
Duration
(
milliseconds:
timeStamp
.
round
())),
result
);
for
(
int
i
=
0
;
i
<
kMoveCount
;
i
++)
{
final
Point
location
=
startLocation
+
Offset
.
lerp
(
Offset
.
zero
,
offset
,
i
/
kMoveCount
);
_dispatchEvent
(
p
.
move
(
location
,
timeStamp:
new
Duration
(
milliseconds:
timeStamp
.
round
())),
result
);
timeStamp
+=
timeStampDelta
;
}
_dispatchEvent
(
p
.
up
(
timeStamp:
new
Duration
(
milliseconds:
timeStamp
.
round
())),
result
);
}
void
scroll
(
Element
element
,
Offset
offset
,
{
int
pointer:
1
})
{
scrollAt
(
getCenter
(
element
),
offset
,
pointer:
pointer
);
}
void
scrollAt
(
Point
startLocation
,
Offset
offset
,
{
int
pointer:
1
})
{
Point
endLocation
=
startLocation
+
offset
;
TestPointer
p
=
new
TestPointer
(
pointer
);
// Events for the entire press-drag-release gesture are dispatched
// to the widgets "hit" by the pointer down event.
HitTestResult
result
=
_hitTest
(
startLocation
);
_dispatchEvent
(
p
.
down
(
startLocation
),
result
);
_dispatchEvent
(
p
.
move
(
endLocation
),
result
);
_dispatchEvent
(
p
.
up
(),
result
);
}
void
dispatchEvent
(
PointerEvent
event
,
Point
location
)
{
_dispatchEvent
(
event
,
_hitTest
(
location
));
}
HitTestResult
_hitTest
(
Point
location
)
{
HitTestResult
result
=
new
HitTestResult
();
binding
.
hitTest
(
result
,
location
);
return
result
;
}
void
_dispatchEvent
(
PointerEvent
event
,
HitTestResult
result
)
{
binding
.
dispatchEvent
(
event
,
result
);
}
}
packages/flutter_test/lib/src/widget_tester.dart
View file @
28c3b558
...
@@ -4,28 +4,28 @@
...
@@ -4,28 +4,28 @@
import
'dart:ui'
as
ui
;
import
'dart:ui'
as
ui
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/scheduler.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:quiver/testing/async.dart'
;
import
'package:quiver/testing/async.dart'
;
import
'package:quiver/time.dart'
;
import
'package:quiver/time.dart'
;
import
'package:flutter/scheduler.dart'
;
import
'package:flutter/widgets.dart'
;
import
'
test_pointer
.dart'
;
import
'
instrumentation
.dart'
;
typedef
Point
SizeToPointFunction
(
Size
size
);
class
WidgetTester
{
/// Helper class for fluter tests providing fake async.
///
/// This class extends Instrumentation to also abstract away the beginFrame
/// and async/clock access to allow writing tests which depend on the passage
/// of time without actually moving the clock forward.
class
WidgetTester
extends
Instrumentation
{
WidgetTester
.
_
(
FakeAsync
async
)
WidgetTester
.
_
(
FakeAsync
async
)
:
binding
=
WidgetFlutterBinding
.
ensureInitialized
(),
:
async
=
async
,
async
=
async
,
clock
=
async
.
getClock
(
new
DateTime
.
utc
(
2015
,
1
,
1
))
{
clock
=
async
.
getClock
(
new
DateTime
.
utc
(
2015
,
1
,
1
))
{
timeDilation
=
1.0
;
timeDilation
=
1.0
;
ui
.
window
.
onBeginFrame
=
null
;
ui
.
window
.
onBeginFrame
=
null
;
runApp
(
new
ErrorWidget
());
// flush out the last build entirely
runApp
(
new
ErrorWidget
());
// flush out the last build entirely
}
}
final
WidgetFlutterBinding
binding
;
final
FakeAsync
async
;
final
FakeAsync
async
;
final
Clock
clock
;
final
Clock
clock
;
...
@@ -48,155 +48,6 @@ class WidgetTester {
...
@@ -48,155 +48,6 @@ class WidgetTester {
);
);
async
.
flushMicrotasks
();
async
.
flushMicrotasks
();
}
}
List
<
Layer
>
_layers
(
Layer
layer
)
{
List
<
Layer
>
result
=
<
Layer
>[
layer
];
if
(
layer
is
ContainerLayer
)
{
ContainerLayer
root
=
layer
;
Layer
child
=
root
.
firstChild
;
while
(
child
!=
null
)
{
result
.
addAll
(
_layers
(
child
));
child
=
child
.
nextSibling
;
}
}
return
result
;
}
List
<
Layer
>
get
layers
=>
_layers
(
binding
.
renderView
.
layer
);
void
walkElements
(
ElementVisitor
visitor
)
{
void
walk
(
Element
element
)
{
visitor
(
element
);
element
.
visitChildren
(
walk
);
}
binding
.
renderViewElement
.
visitChildren
(
walk
);
}
Element
findElement
(
bool
predicate
(
Element
element
))
{
try
{
walkElements
((
Element
element
)
{
if
(
predicate
(
element
))
throw
element
;
});
}
on
Element
catch
(
e
)
{
return
e
;
}
return
null
;
}
Element
findElementByKey
(
Key
key
)
{
return
findElement
((
Element
element
)
=>
element
.
widget
.
key
==
key
);
}
Element
findText
(
String
text
)
{
return
findElement
((
Element
element
)
{
return
element
.
widget
is
Text
&&
element
.
widget
.
data
==
text
;
});
}
State
findStateOfType
(
Type
type
)
{
StatefulComponentElement
element
=
findElement
((
Element
element
)
{
return
element
is
StatefulComponentElement
&&
element
.
state
.
runtimeType
==
type
;
});
return
element
?.
state
;
}
State
findStateByConfig
(
Widget
config
)
{
StatefulComponentElement
element
=
findElement
((
Element
element
)
{
return
element
is
StatefulComponentElement
&&
element
.
state
.
config
==
config
;
});
return
element
?.
state
;
}
Point
getCenter
(
Element
element
)
{
return
_getElementPoint
(
element
,
(
Size
size
)
=>
size
.
center
(
Point
.
origin
));
}
Point
getTopLeft
(
Element
element
)
{
return
_getElementPoint
(
element
,
(
_
)
=>
Point
.
origin
);
}
Point
getTopRight
(
Element
element
)
{
return
_getElementPoint
(
element
,
(
Size
size
)
=>
size
.
topRight
(
Point
.
origin
));
}
Point
getBottomLeft
(
Element
element
)
{
return
_getElementPoint
(
element
,
(
Size
size
)
=>
size
.
bottomLeft
(
Point
.
origin
));
}
Point
getBottomRight
(
Element
element
)
{
return
_getElementPoint
(
element
,
(
Size
size
)
=>
size
.
bottomRight
(
Point
.
origin
));
}
Point
_getElementPoint
(
Element
element
,
SizeToPointFunction
sizeToPoint
)
{
assert
(
element
!=
null
);
RenderBox
box
=
element
.
renderObject
as
RenderBox
;
assert
(
box
!=
null
);
return
box
.
localToGlobal
(
sizeToPoint
(
box
.
size
));
}
void
tap
(
Element
element
,
{
int
pointer:
1
})
{
tapAt
(
getCenter
(
element
),
pointer:
pointer
);
}
void
tapAt
(
Point
location
,
{
int
pointer:
1
})
{
HitTestResult
result
=
_hitTest
(
location
);
TestPointer
p
=
new
TestPointer
(
pointer
);
_dispatchEvent
(
p
.
down
(
location
),
result
);
_dispatchEvent
(
p
.
up
(),
result
);
}
void
fling
(
Element
element
,
Offset
offset
,
double
velocity
,
{
int
pointer:
1
})
{
flingFrom
(
getCenter
(
element
),
offset
,
velocity
,
pointer:
pointer
);
}
void
flingFrom
(
Point
startLocation
,
Offset
offset
,
double
velocity
,
{
int
pointer:
1
})
{
assert
(
offset
.
distance
>
0.0
);
assert
(
velocity
!=
0.0
);
// velocity is pixels/second
final
TestPointer
p
=
new
TestPointer
(
pointer
);
final
HitTestResult
result
=
_hitTest
(
startLocation
);
const
int
kMoveCount
=
50
;
// Needs to be >= kHistorySize, see _LeastSquaresVelocityTrackerStrategy
final
double
timeStampDelta
=
1000.0
*
offset
.
distance
/
(
kMoveCount
*
velocity
);
double
timeStamp
=
0.0
;
_dispatchEvent
(
p
.
down
(
startLocation
,
timeStamp:
new
Duration
(
milliseconds:
timeStamp
.
round
())),
result
);
for
(
int
i
=
0
;
i
<
kMoveCount
;
i
++)
{
final
Point
location
=
startLocation
+
Offset
.
lerp
(
Offset
.
zero
,
offset
,
i
/
kMoveCount
);
_dispatchEvent
(
p
.
move
(
location
,
timeStamp:
new
Duration
(
milliseconds:
timeStamp
.
round
())),
result
);
timeStamp
+=
timeStampDelta
;
}
_dispatchEvent
(
p
.
up
(
timeStamp:
new
Duration
(
milliseconds:
timeStamp
.
round
())),
result
);
}
void
scroll
(
Element
element
,
Offset
offset
,
{
int
pointer:
1
})
{
scrollAt
(
getCenter
(
element
),
offset
,
pointer:
pointer
);
}
void
scrollAt
(
Point
startLocation
,
Offset
offset
,
{
int
pointer:
1
})
{
Point
endLocation
=
startLocation
+
offset
;
TestPointer
p
=
new
TestPointer
(
pointer
);
// Events for the entire press-drag-release gesture are dispatched
// to the widgets "hit" by the pointer down event.
HitTestResult
result
=
_hitTest
(
startLocation
);
_dispatchEvent
(
p
.
down
(
startLocation
),
result
);
_dispatchEvent
(
p
.
move
(
endLocation
),
result
);
_dispatchEvent
(
p
.
up
(),
result
);
}
void
dispatchEvent
(
PointerEvent
event
,
Point
location
)
{
_dispatchEvent
(
event
,
_hitTest
(
location
));
}
HitTestResult
_hitTest
(
Point
location
)
{
HitTestResult
result
=
new
HitTestResult
();
binding
.
hitTest
(
result
,
location
);
return
result
;
}
void
_dispatchEvent
(
PointerEvent
event
,
HitTestResult
result
)
{
binding
.
dispatchEvent
(
event
,
result
);
}
}
}
void
testWidgets
(
callback
(
WidgetTester
tester
))
{
void
testWidgets
(
callback
(
WidgetTester
tester
))
{
...
...
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