Skip to content

Commit c3f9c80

Browse files
Michael KlimushynPark Sung Min
Michael Klimushyn
authored and
Park Sung Min
committed
[sensors] Documentation and test improvements (flutter#2272)
- Add missing dartdoc coverage and expand on existing documentation. - Add an analyzer warning for this package so that public doc coverage doesn't regress. - Improve unit test coverage. - Expand on the existing README.
1 parent 1cdbe27 commit c3f9c80

File tree

8 files changed

+154
-39
lines changed

8 files changed

+154
-39
lines changed

packages/sensors/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.4.1+3
2+
3+
* Improve documentation and add unit test coverage.
4+
15
## 0.4.1+2
26

37
* Remove AndroidX warnings.

packages/sensors/README.md

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,22 @@ A Flutter plugin to access the accelerometer and gyroscope sensors.
55

66
## Usage
77

8-
To use this plugin, add `sensors` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/).
8+
To use this plugin, add `sensors` as a [dependency in your pubspec.yaml
9+
file](https://flutter.io/platform-plugins/).
10+
11+
This will expose three classes of sensor events, through three different
12+
streams.
13+
14+
- `AccelerometerEvent`s describe the velocity of the device, including the
15+
effects of gravity. Put simply, you can use accelerometer readings to tell if
16+
the device is moving in a particular direction.
17+
- `UserAccelerometerEvent`s also describe the velocity of the device, but don't
18+
include gravity. They can also be thought of as just the user's affect on the
19+
device.
20+
- `GyroscopeEvent`s describe the rotation of the device.
21+
22+
Each of these is exposed through a `BroadcastStream`: `accelerometerEvents`,
23+
`userAccelerometerEvents`, and `gyroscopeEvents`, respectively.
924

1025

1126
### Example
@@ -14,10 +29,21 @@ To use this plugin, add `sensors` as a [dependency in your pubspec.yaml file](ht
1429
import 'package:sensors/sensors.dart';
1530
1631
accelerometerEvents.listen((AccelerometerEvent event) {
17-
// Do something with the event.
32+
print(event);
1833
});
34+
// [AccelerometerEvent (x: 0.0, y: 9.8, z: 0.0)]
35+
36+
userAccelerometerEvents.listen((AccelerometerEvent event) {
37+
print(event);
38+
});
39+
// [UserAccelerometerEvent (x: 0.0, y: 0.0, z: 0.0)]
1940
2041
gyroscopeEvents.listen((GyroscopeEvent event) {
21-
// Do something with the event.
42+
print(event);
2243
});
23-
```
44+
// [GyroscopeEvent (x: 0.0, y: 0.0, z: 0.0)]
45+
46+
```
47+
48+
Also see the `example` subdirectory for an example application that uses the
49+
sensor data.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# This exists to add a lint for missing API docs just on this specific package,
2+
# since not all packages have coverage for all their public members yet and
3+
# adding it in would be non-trivial. `public_member_api_docs` should be applied
4+
# to new packages going forward, and ideally the main `analysis_options.yaml`
5+
# file as soon as possible.
6+
7+
include: ../../analysis_options.yaml
8+
9+
linter:
10+
rules:
11+
- public_member_api_docs

packages/sensors/example/lib/main.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
// ignore_for_file: public_member_api_docs
6+
57
import 'dart:async';
68
import 'package:flutter/material.dart';
79
import 'package:sensors/sensors.dart';

packages/sensors/example/lib/snake.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
// ignore_for_file: public_member_api_docs
6+
57
import 'dart:async';
68
import 'dart:math' as math;
79

packages/sensors/lib/sensors.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,48 +14,95 @@ const EventChannel _userAccelerometerEventChannel =
1414
const EventChannel _gyroscopeEventChannel =
1515
EventChannel('plugins.flutter.io/sensors/gyroscope');
1616

17+
/// Discrete reading from an accelerometer. Accelerometers measure the velocity
18+
/// of the device. Note that these readings include the effects of gravity. Put
19+
/// simply, you can use accelerometer readings to tell if the device is moving in
20+
/// a particular direction.
1721
class AccelerometerEvent {
22+
/// Contructs an instance with the given [x], [y], and [z] values.
1823
AccelerometerEvent(this.x, this.y, this.z);
1924

2025
/// Acceleration force along the x axis (including gravity) measured in m/s^2.
26+
///
27+
/// When the device is held upright facing the user, positive values mean the
28+
/// device is moving to the right and negative mean it is moving to the left.
2129
final double x;
2230

2331
/// Acceleration force along the y axis (including gravity) measured in m/s^2.
32+
///
33+
/// When the device is held upright facing the user, positive values mean the
34+
/// device is moving towards the sky and negative mean it is moving towards
35+
/// the ground.
2436
final double y;
2537

2638
/// Acceleration force along the z axis (including gravity) measured in m/s^2.
39+
///
40+
/// This uses a right-handed coordinate system. So when the device is held
41+
/// upright and facing the user, positive values mean the device is moving
42+
/// towards the user and negative mean it is moving away from them.
2743
final double z;
2844

2945
@override
3046
String toString() => '[AccelerometerEvent (x: $x, y: $y, z: $z)]';
3147
}
3248

49+
/// Discrete reading from a gyroscope. Gyroscopes measure the rate or rotation of
50+
/// the device in 3D space.
3351
class GyroscopeEvent {
52+
/// Contructs an instance with the given [x], [y], and [z] values.
3453
GyroscopeEvent(this.x, this.y, this.z);
3554

3655
/// Rate of rotation around the x axis measured in rad/s.
56+
///
57+
/// When the device is held upright, this can also be thought of as describing
58+
/// "pitch". The top of the device will tilt towards or away from the
59+
/// user as this value changes.
3760
final double x;
3861

3962
/// Rate of rotation around the y axis measured in rad/s.
63+
///
64+
/// When the device is held upright, this can also be thought of as describing
65+
/// "yaw". The lengthwise edge of the device will rotate towards or away from
66+
/// the user as this value changes.
4067
final double y;
4168

4269
/// Rate of rotation around the z axis measured in rad/s.
70+
///
71+
/// When the device is held upright, this can also be thought of as describing
72+
/// "roll". When this changes the face of the device should remain facing
73+
/// forward, but the orientation will change from portrait to landscape and so
74+
/// on.
4375
final double z;
4476

4577
@override
4678
String toString() => '[GyroscopeEvent (x: $x, y: $y, z: $z)]';
4779
}
4880

81+
/// Like [AccelerometerEvent], this is a discrete reading from an accelerometer
82+
/// and measures the velocity of the device. However, unlike
83+
/// [AccelerometerEvent], this event does not include the effects of gravity.
4984
class UserAccelerometerEvent {
85+
/// Contructs an instance with the given [x], [y], and [z] values.
5086
UserAccelerometerEvent(this.x, this.y, this.z);
5187

5288
/// Acceleration force along the x axis (excluding gravity) measured in m/s^2.
89+
///
90+
/// When the device is held upright facing the user, positive values mean the
91+
/// device is moving to the right and negative mean it is moving to the left.
5392
final double x;
5493

5594
/// Acceleration force along the y axis (excluding gravity) measured in m/s^2.
95+
///
96+
/// When the device is held upright facing the user, positive values mean the
97+
/// device is moving towards the sky and negative mean it is moving towards
98+
/// the ground.
5699
final double y;
57100

58101
/// Acceleration force along the z axis (excluding gravity) measured in m/s^2.
102+
///
103+
/// This uses a right-handed coordinate system. So when the device is held
104+
/// upright and facing the user, positive values mean the device is moving
105+
/// towards the user and negative mean it is moving away from them.
59106
final double z;
60107

61108
@override

packages/sensors/pubspec.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Flutter plugin for accessing the Android and iOS accelerometer and
33
gyroscope sensors.
44
author: Flutter Team <[email protected]>
55
homepage: https://github.com/flutter/plugins/tree/master/packages/sensors
6-
version: 0.4.1+2
6+
version: 0.4.1+3
77

88
flutter:
99
plugin:
@@ -20,6 +20,7 @@ dev_dependencies:
2020
flutter_test:
2121
sdk: flutter
2222
e2e: ^0.2.0
23+
mockito: ^4.1.1
2324

2425
environment:
2526
sdk: ">=2.0.0-dev.28.0 <3.0.0"

packages/sensors/test/sensors_test.dart

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import 'dart:async';
65
import 'dart:typed_data';
76

87
import 'package:flutter/services.dart';
@@ -16,44 +15,67 @@ void main() {
1615
test('$accelerometerEvents are streamed', () async {
1716
const String channelName = 'plugins.flutter.io/sensors/accelerometer';
1817
const List<double> sensorData = <double>[1.0, 2.0, 3.0];
18+
_initializeFakeSensorChannel(channelName, sensorData);
1919

20-
const StandardMethodCodec standardMethod = StandardMethodCodec();
21-
22-
void emitEvent(ByteData event) {
23-
// TODO(hterkelsen): Remove this when defaultBinaryMessages is in stable.
24-
// https://github.com/flutter/flutter/issues/33446
25-
// ignore: deprecated_member_use
26-
BinaryMessages.handlePlatformMessage(
27-
channelName,
28-
event,
29-
(ByteData reply) {},
30-
);
31-
}
20+
final AccelerometerEvent event = await accelerometerEvents.first;
21+
22+
expect(event.x, sensorData[0]);
23+
expect(event.y, sensorData[1]);
24+
expect(event.z, sensorData[2]);
25+
});
26+
27+
test('$gyroscopeEvents are streamed', () async {
28+
const String channelName = 'plugins.flutter.io/sensors/gyroscope';
29+
const List<double> sensorData = <double>[3.0, 4.0, 5.0];
30+
_initializeFakeSensorChannel(channelName, sensorData);
31+
32+
final GyroscopeEvent event = await gyroscopeEvents.first;
33+
34+
expect(event.x, sensorData[0]);
35+
expect(event.y, sensorData[1]);
36+
expect(event.z, sensorData[2]);
37+
});
38+
39+
test('$userAccelerometerEvents are streamed', () async {
40+
const String channelName = 'plugins.flutter.io/sensors/user_accel';
41+
const List<double> sensorData = <double>[6.0, 7.0, 8.0];
42+
_initializeFakeSensorChannel(channelName, sensorData);
3243

33-
bool isCanceled = false;
44+
final UserAccelerometerEvent event = await userAccelerometerEvents.first;
45+
46+
expect(event.x, sensorData[0]);
47+
expect(event.y, sensorData[1]);
48+
expect(event.z, sensorData[2]);
49+
});
50+
}
51+
52+
void _initializeFakeSensorChannel(String channelName, List<double> sensorData) {
53+
const StandardMethodCodec standardMethod = StandardMethodCodec();
54+
55+
void _emitEvent(ByteData event) {
3456
// TODO(hterkelsen): Remove this when defaultBinaryMessages is in stable.
3557
// https://github.com/flutter/flutter/issues/33446
3658
// ignore: deprecated_member_use
37-
BinaryMessages.setMockMessageHandler(channelName, (ByteData message) async {
38-
final MethodCall methodCall = standardMethod.decodeMethodCall(message);
39-
if (methodCall.method == 'listen') {
40-
emitEvent(standardMethod.encodeSuccessEnvelope(sensorData));
41-
emitEvent(null);
42-
return standardMethod.encodeSuccessEnvelope(null);
43-
} else if (methodCall.method == 'cancel') {
44-
isCanceled = true;
45-
return standardMethod.encodeSuccessEnvelope(null);
46-
} else {
47-
fail('Expected listen or cancel');
48-
}
49-
});
50-
51-
final AccelerometerEvent event = await accelerometerEvents.first;
52-
expect(event.x, 1.0);
53-
expect(event.y, 2.0);
54-
expect(event.z, 3.0);
59+
BinaryMessages.handlePlatformMessage(
60+
channelName,
61+
event,
62+
(ByteData reply) {},
63+
);
64+
}
5565

56-
await Future<void>.delayed(Duration.zero);
57-
expect(isCanceled, isTrue);
66+
// TODO(hterkelsen): Remove this when defaultBinaryMessages is in stable.
67+
// https://github.com/flutter/flutter/issues/33446
68+
// ignore: deprecated_member_use
69+
BinaryMessages.setMockMessageHandler(channelName, (ByteData message) async {
70+
final MethodCall methodCall = standardMethod.decodeMethodCall(message);
71+
if (methodCall.method == 'listen') {
72+
_emitEvent(standardMethod.encodeSuccessEnvelope(sensorData));
73+
_emitEvent(null);
74+
return standardMethod.encodeSuccessEnvelope(null);
75+
} else if (methodCall.method == 'cancel') {
76+
return standardMethod.encodeSuccessEnvelope(null);
77+
} else {
78+
fail('Expected listen or cancel');
79+
}
5880
});
5981
}

0 commit comments

Comments
 (0)