Skip to content

Commit

Permalink
Merge pull request #1 from grahamsmith/tests
Browse files Browse the repository at this point in the history
Tests & Linting
  • Loading branch information
grahamsmith authored Aug 19, 2021
2 parents f1c052d + 9110b47 commit b828f2a
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 52 deletions.
11 changes: 11 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
include: package:lint/analysis_options.yaml

analyzer:
exclude:
- "example/lib/generated_plugin_registrant.dart"
errors:
todo: ignore

linter:
rules:
constant_identifier_names: false
6 changes: 3 additions & 3 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class MyApp extends StatelessWidget {
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title, required this.analytics}) : super(key: key);
const MyHomePage({Key? key, required this.title, required this.analytics}) : super(key: key);

final String title;
final AnalyticsX analytics;
Expand Down Expand Up @@ -54,7 +54,7 @@ class _MyHomePageState extends State<MyHomePage> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
const Text(
'You have pushed the button this many times:',
),
Text(
Expand All @@ -67,7 +67,7 @@ class _MyHomePageState extends State<MyHomePage> {
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
Expand Down
9 changes: 8 additions & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
lint:
dependency: "direct dev"
description:
name: lint
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
matcher:
dependency: transitive
description:
Expand Down Expand Up @@ -246,5 +253,5 @@ packages:
source: hosted
version: "2.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
dart: ">=2.13.0 <3.0.0"
flutter: ">=1.17.0"
7 changes: 2 additions & 5 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,14 @@ environment:
dependencies:
analyticsx:
path: ../
cupertino_icons: ^1.0.2
flutter:
sdk: flutter


# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2

dev_dependencies:
flutter_test:
sdk: flutter
lint: ^1.6.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
Expand Down
4 changes: 1 addition & 3 deletions lib/analytics_vendor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import 'package:analyticsx/analytics_action.dart';
abstract class AnalyticsVendor {
final String id;

final List<Type> supportedActions;

AnalyticsVendor(this.id, this.supportedActions);
AnalyticsVendor(this.id);

void init();
void handleAction(AnalyticsAction action);
Expand Down
59 changes: 26 additions & 33 deletions lib/analytics_x.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,48 @@ library analytics_x;
import 'package:analyticsx/analytics_action.dart';
import 'package:analyticsx/analytics_vendor.dart';

const ALL = const ['all'];
const ALL = ['all'];

class AnalyticsX {
late List<AnalyticsVendor> vendors;
static final AnalyticsX _instance = AnalyticsX._internal();
final List<AnalyticsVendor> _vendors = [];

void init(List<AnalyticsVendor> vendors) {
vendors.addAll(vendors);
for (var vendor in vendors) {
vendor.init();
}
factory AnalyticsX() {
return _instance;
}

void invokeAction(AnalyticsAction action, [List<String> vendorIds = ALL]) {
List<AnalyticsVendor> vendorsToUse = _filterVendors(vendorIds);
AnalyticsX._internal();

for (var vendor in vendorsToUse) {
if (canHandleAction(vendor, action)) {
vendor.handleAction(action);
}
void init(List<AnalyticsVendor> vendors) {
final newVendors = List.from(vendors).toSet().difference(_vendors.toSet()).toList();
if (newVendors.isEmpty) {
return;
}
}

bool canHandleAction(AnalyticsVendor vendor, AnalyticsAction action) {
for (var supportedAction in vendor.supportedActions) {
if (supportedAction == action.runtimeType) {
return true;
}
for (final vendor in newVendors) {
vendor.init();
}

return false;
_vendors.addAll(List.from(newVendors));
}

// void trackEvent(String event, Map<String, String> properties, [List<String> vendorIds = ALL]) {
// List<AnalyticsVendor> vendorsToUse = _filterVendors(vendorIds);
//
// for (var vendor in vendorsToUse) {
// if (vendor is AnalyticsEventProvider) {
// AnalyticsEventProvider analyticsEventProvider = vendor as AnalyticsEventProvider;
//
// analyticsEventProvider.trackEvent(event, properties);
// }
// }
// }
void invokeAction(AnalyticsAction action, [List<String> vendorIds = ALL]) {
final List<AnalyticsVendor> vendorsToUse = _filterVendors(vendorIds);

for (final vendor in vendorsToUse) {
vendor.handleAction(action);
}
}

List<AnalyticsVendor> _filterVendors(List<String> vendorIds) {
return vendorIds == ALL ? vendors : _getVendorsById(vendorIds);
return vendorIds == ALL ? _vendors : _getVendorsById(vendorIds);
}

List<AnalyticsVendor> _getVendorsById(List<String> ids) {
return vendors.where((element) => ids.contains(element.id)).toList();
return _vendors.where((element) => ids.contains(element.id)).toList();
}

void uninit() {
_vendors.clear();
}
}
8 changes: 2 additions & 6 deletions lib/vendors/firebase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,16 @@ import 'package:analyticsx/analytics_action.dart';
import 'package:analyticsx/analytics_vendor.dart';
import 'package:firebase_analytics/firebase_analytics.dart';

class Firebase implements AnalyticsVendor {
class Firebase extends AnalyticsVendor {
static FirebaseAnalytics analytics = FirebaseAnalytics();

@override
String get id => 'Firebase';
Firebase() : super('Firebase');

@override
void init() {
//nothing for Firebase;
}

@override
List<Type> get supportedActions => [TrackEvent, SetScreen];

@override
void handleAction(AnalyticsAction action) {
if (action is TrackEvent) {
Expand Down
9 changes: 8 additions & 1 deletion pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
lint:
dependency: "direct dev"
description:
name: lint
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
matcher:
dependency: transitive
description:
Expand Down Expand Up @@ -232,5 +239,5 @@ packages:
source: hosted
version: "2.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
dart: ">=2.13.0 <3.0.0"
flutter: ">=1.17.0"
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
lint: ^1.6.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
Expand Down
95 changes: 95 additions & 0 deletions test/analytics_x_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import 'package:analyticsx/analytics_action.dart';
import 'package:analyticsx/analytics_vendor.dart';
import 'package:analyticsx/analytics_x.dart';
import 'package:flutter_test/flutter_test.dart';

class FakeAction extends AnalyticsAction {
final String fakeProperty;
FakeAction(this.fakeProperty);
}

class FakeVendor extends AnalyticsVendor {
FakeVendor() : super('Dummy');
FakeVendor.withVendorId(String vendorId) : super(vendorId);

int initWasCalledXTimes = 0;
int handleActionWasCalledXTimes = 0;
List<String> handleActionWasCalledWith = [];

@override
void handleAction(AnalyticsAction action) {
handleActionWasCalledXTimes++;
if (action is FakeAction) {
handleActionWasCalledWith.add(action.fakeProperty);
}
}

@override
void init() {
initWasCalledXTimes++;
}
}

class FakeVendor2 extends FakeVendor {
FakeVendor2() : super.withVendorId('Dummy2');
}

void main() {
late FakeVendor fakeVendor;
late AnalyticsX ax;

setUp(() {
fakeVendor = FakeVendor();
ax = AnalyticsX();
});

tearDown(() {
ax.uninit();
});

test('AnalyticsX is (probably) a singleton', () {
// Whilst identical(..) proves that both variables reference the same object, you can't definitively prove that it's
// a singleton this way, since two identical strings are optimised to use the same reference
final ax2 = AnalyticsX();
expect(identical(ax, ax2), true);
});

test('Vendor init is called once when Analytics init is called once', () {
ax.init([fakeVendor]);
expect(fakeVendor.initWasCalledXTimes, 1);
});

test('Vendor init is called once when Analytics init is called twice', () {
ax.init([fakeVendor]);
ax.init([fakeVendor]);
expect(fakeVendor.initWasCalledXTimes, 1);
});

test('First vendor init is not called again when Analytics init is called with second vendor', () {
ax.init([fakeVendor]);
final fakeVendor2 = FakeVendor2();
ax.init([fakeVendor2]);
expect(fakeVendor.initWasCalledXTimes, 1);
});

test('Second vendor init is called when Analytics init is called with second vendor', () {
ax.init([fakeVendor]);
final fakeVendor2 = FakeVendor2();
ax.init([fakeVendor2]);
expect(fakeVendor2.initWasCalledXTimes, 1);
});

test('Vendor handleAction is called once when invokeAction is called once', () {
ax.init([fakeVendor]);
ax.invokeAction(FakeAction("potato"));
expect(fakeVendor.handleActionWasCalledXTimes, 1);
});

test('Correct vendor handleActions are called when invokeAction is called with vendorIds', () {
final fakeVendor2 = FakeVendor2();
ax.init([fakeVendor, fakeVendor2]);
ax.invokeAction(FakeAction("potato"), [fakeVendor2.id]);
expect(fakeVendor.handleActionWasCalledXTimes, 0);
expect(fakeVendor2.handleActionWasCalledXTimes, 1);
});
}

0 comments on commit b828f2a

Please sign in to comment.