Merge pull request #113 from dart-lang/3.2.0
prep for publishing 3.2.0
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 545d5cc..a0480da 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -2,6 +2,6 @@
strong-mode: true
linter:
rules:
- #- annotate_overrides
+ - annotate_overrides
- empty_constructor_bodies
- empty_statements
diff --git a/changelog.md b/changelog.md
index 2a74305..ac47b61 100644
--- a/changelog.md
+++ b/changelog.md
@@ -4,6 +4,7 @@
- expose the `Analytics.applicationName` and `Analytics.applicationVersion`
properties
- make it easier for clients to extend the `AnalyticsIO` class
+- allow for custom parameters when sending a screenView
## 3.1.1
- make Analytics.clientId available immediately
diff --git a/lib/src/usage_impl.dart b/lib/src/usage_impl.dart
index e8e10d2..c0b9ae5 100644
--- a/lib/src/usage_impl.dart
+++ b/lib/src/usage_impl.dart
@@ -60,8 +60,11 @@
static const String _defaultAnalyticsUrl =
'https://www.google-analytics.com/collect';
+ @override
final String trackingId;
+ @override
final String applicationName;
+ @override
final String applicationVersion;
final PersistentProperties properties;
@@ -72,6 +75,7 @@
final List<Future> _futures = [];
+ @override
AnalyticsOpt analyticsOpt = AnalyticsOpt.optOut;
String _url;
@@ -91,6 +95,7 @@
bool _firstRun;
+ @override
bool get firstRun {
if (_firstRun == null) {
_firstRun = properties['firstRun'] == null;
@@ -103,9 +108,7 @@
return _firstRun;
}
- /**
- * Will analytics data be sent?
- */
+ @override
bool get enabled {
bool optIn = analyticsOpt == AnalyticsOpt.optIn;
return optIn
@@ -113,13 +116,12 @@
: properties['enabled'] != false;
}
- /**
- * Enable or disable sending of analytics data.
- */
+ @override
set enabled(bool value) {
properties['enabled'] = value;
}
+ @override
Future sendScreenView(String viewName, {Map<String, String> parameters}) {
Map<String, dynamic> args = {'cd': viewName};
if (parameters != null) {
@@ -128,8 +130,9 @@
return _sendPayload('screenview', args);
}
- Future sendEvent(String category, String action, {String label, int value,
- Map<String, String> parameters}) {
+ @override
+ Future sendEvent(String category, String action,
+ {String label, int value, Map<String, String> parameters}) {
Map<String, dynamic> args = {'ec': category, 'ea': action};
if (label != null) args['el'] = label;
if (value != null) args['ev'] = value;
@@ -139,11 +142,13 @@
return _sendPayload('event', args);
}
+ @override
Future sendSocial(String network, String action, String target) {
Map<String, dynamic> args = {'sn': network, 'sa': action, 'st': target};
return _sendPayload('social', args);
}
+ @override
Future sendTiming(String variableName, int time,
{String category, String label}) {
Map<String, dynamic> args = {'utv': variableName, 'utt': time};
@@ -152,12 +157,14 @@
return _sendPayload('timing', args);
}
+ @override
AnalyticsTimer startTimer(String variableName,
{String category, String label}) {
return new AnalyticsTimer(this, variableName,
category: category, label: label);
}
+ @override
Future sendException(String description, {bool fatal}) {
// We trim exceptions to a max length; google analytics will apply it's own
// truncation, likely around 150 chars or so.
@@ -181,8 +188,10 @@
return _sendPayload('exception', args);
}
+ @override
dynamic getSessionValue(String param) => _variableMap[param];
+ @override
void setSessionValue(String param, dynamic value) {
if (value == null) {
_variableMap.remove(param);
@@ -191,8 +200,10 @@
}
}
+ @override
Stream<Map<String, dynamic>> get onSend => _sendController.stream;
+ @override
Future waitForLastPing({Duration timeout}) {
Future f = Future.wait(_futures).catchError((e) => null);
diff --git a/lib/src/usage_impl_html.dart b/lib/src/usage_impl_html.dart
index 6861db7..0072dc3 100644
--- a/lib/src/usage_impl_html.dart
+++ b/lib/src/usage_impl_html.dart
@@ -35,6 +35,7 @@
HtmlPostHandler({Function this.mockRequestor});
+ @override
Future sendPost(String url, Map<String, dynamic> parameters) {
int viewportWidth = document.documentElement.clientWidth;
int viewportHeight = document.documentElement.clientHeight;
@@ -59,8 +60,10 @@
_map = JSON.decode(str);
}
+ @override
dynamic operator [](String key) => _map[key];
+ @override
void operator []=(String key, dynamic value) {
if (value == null) {
_map.remove(key);
@@ -71,5 +74,6 @@
window.localStorage[name] = JSON.encode(_map);
}
+ @override
void syncSettings() {}
}
diff --git a/lib/src/usage_impl_io.dart b/lib/src/usage_impl_io.dart
index ad87e91..9ad366a 100644
--- a/lib/src/usage_impl_io.dart
+++ b/lib/src/usage_impl_io.dart
@@ -79,6 +79,7 @@
IOPostHandler({HttpClient this.mockClient}) : _userAgent = _createUserAgent();
+ @override
Future sendPost(String url, Map<String, dynamic> parameters) async {
String data = postEncode(parameters);
@@ -120,8 +121,10 @@
syncSettings();
}
+ @override
dynamic operator [](String key) => _map[key];
+ @override
void operator []=(String key, dynamic value) {
if (value == null && !_map.containsKey(key)) return;
if (_map[key] == value) return;
@@ -137,6 +140,7 @@
} catch (_) {}
}
+ @override
void syncSettings() {
try {
String contents = _file.readAsStringSync();
diff --git a/lib/usage.dart b/lib/usage.dart
index d516172..52e9f46 100644
--- a/lib/usage.dart
+++ b/lib/usage.dart
@@ -83,7 +83,7 @@
/**
* Sends a screen view hit to Google Analytics.
- *
+ *
* [parameters] can be any analytics key/value pair. Useful
* for custom dimensions, etc.
*/
@@ -92,12 +92,12 @@
/**
* Sends an Event hit to Google Analytics. [label] specifies the event label.
* [value] specifies the event value. Values must be non-negative.
- *
+ *
* [parameters] can be any analytics key/value pair. Useful
* for custom dimensions, etc.
*/
- Future sendEvent(String category, String action, {String label, int value,
- Map<String, String> parameters});
+ Future sendEvent(String category, String action,
+ {String label, int value, Map<String, String> parameters});
/**
* Sends a Social hit to Google Analytics. [network] specifies the social
@@ -225,8 +225,11 @@
* stand-in for that will never ping the GA server, or as a mock in test code.
*/
class AnalyticsMock implements Analytics {
+ @override
String get trackingId => 'UA-0';
+ @override
String get applicationName => 'mock-app';
+ @override
String get applicationVersion => '1.0.0';
final bool logCalls;
@@ -243,35 +246,40 @@
*/
AnalyticsMock([this.logCalls = false]);
+ @override
bool get firstRun => false;
+ @override
AnalyticsOpt analyticsOpt = AnalyticsOpt.optOut;
+ @override
bool enabled = true;
@override
String get clientId => '00000000-0000-4000-0000-000000000000';
+ @override
Future sendScreenView(String viewName, {Map<String, String> parameters}) {
parameters ??= <String, String>{};
parameters['viewName'] = viewName;
return _log('screenView', parameters);
}
- Future sendEvent(String category, String action, {String label, int value,
- Map<String, String> parameters}) {
+ @override
+ Future sendEvent(String category, String action,
+ {String label, int value, Map<String, String> parameters}) {
parameters ??= <String, String>{};
- return _log('event', {
- 'category': category,
- 'action': action,
- 'label': label,
- 'value': value
- }..addAll(parameters));
+ return _log(
+ 'event',
+ {'category': category, 'action': action, 'label': label, 'value': value}
+ ..addAll(parameters));
}
+ @override
Future sendSocial(String network, String action, String target) =>
_log('social', {'network': network, 'action': action, 'target': target});
+ @override
Future sendTiming(String variableName, int time,
{String category, String label}) {
return _log('timing', {
@@ -282,21 +290,27 @@
});
}
+ @override
AnalyticsTimer startTimer(String variableName,
{String category, String label}) {
return new AnalyticsTimer(this, variableName,
category: category, label: label);
}
+ @override
Future sendException(String description, {bool fatal}) =>
_log('exception', {'description': description, 'fatal': fatal});
+ @override
dynamic getSessionValue(String param) => null;
+ @override
void setSessionValue(String param, dynamic value) {}
+ @override
Stream<Map<String, dynamic>> get onSend => _sendController.stream;
+ @override
Future waitForLastPing({Duration timeout}) => new Future.value();
Future _log(String hitType, Map m) {
diff --git a/readme.md b/readme.md
index c9a92c7..6d216e8 100644
--- a/readme.md
+++ b/readme.md
@@ -112,9 +112,7 @@
## Contributing
-Run the tests with `pub run test`.
-
-Analyze the code with `dartanalyzer lib/*.dart test/*.dart`.
+Test can be run using `pub run test`.
## Issues and bugs
diff --git a/test/src/common.dart b/test/src/common.dart
index 4ce7b17..2ace7eb 100644
--- a/test/src/common.dart
+++ b/test/src/common.dart
@@ -34,18 +34,22 @@
if (props != null) this.props.addAll(props);
}
+ @override
dynamic operator [](String key) => props[key];
+ @override
void operator []=(String key, dynamic value) {
props[key] = value;
}
+ @override
void syncSettings() {}
}
class MockPostHandler extends PostHandler {
List<Map<String, dynamic>> sentValues = [];
+ @override
Future sendPost(String url, Map<String, dynamic> parameters) {
sentValues.add(parameters);
diff --git a/test/usage_impl_io_test.dart b/test/usage_impl_io_test.dart
index bce9d03..8889077 100644
--- a/test/usage_impl_io_test.dart
+++ b/test/usage_impl_io_test.dart
@@ -52,39 +52,52 @@
}
class MockHttpClient implements HttpClient {
+ @override
String userAgent;
int sendCount = 0;
int writeCount = 0;
bool closed = false;
+
+ @override
Future<HttpClientRequest> postUrl(Uri url) {
return new Future.value(new MockHttpClientRequest(this));
}
+ @override
noSuchMethod(Invocation invocation) {}
}
class MockHttpClientRequest implements HttpClientRequest {
final MockHttpClient client;
+
MockHttpClientRequest(this.client);
+
+ @override
void write(Object obj) {
client.writeCount++;
}
+ @override
Future<HttpClientResponse> close() {
client.closed = true;
return new Future.value(new MockHttpClientResponse(client));
}
+ @override
noSuchMethod(Invocation invocation) {}
}
class MockHttpClientResponse implements HttpClientResponse {
final MockHttpClient client;
+
MockHttpClientResponse(this.client);
+
+ @override
Future/*<E>*/ drain/*<E>*/([/*=E*/ futureValue]) {
client.sendCount++;
return new Future.value();
}
+ @override
noSuchMethod(Invocation invocation) {}
}
diff --git a/test/usage_test.dart b/test/usage_test.dart
index 9d2a4e0..37500a9 100644
--- a/test/usage_test.dart
+++ b/test/usage_test.dart
@@ -16,7 +16,8 @@
mock.sendScreenView('main');
mock.sendScreenView('withParameters', parameters: {'cd1': 'custom'});
mock.sendEvent('files', 'save');
- mock.sendEvent('eventWithParameters', 'save', parameters: {'cd1': 'custom'});
+ mock.sendEvent('eventWithParameters', 'save',
+ parameters: {'cd1': 'custom'});
mock.sendSocial('g+', 'plus', 'userid');
mock.sendTiming('compile', 123);
mock.startTimer('compile').finish();