Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: add Scope class
  • Loading branch information
marandaneto committed Oct 13, 2020
commit 43109b3db5bca151348383751352f078b67c2278
2 changes: 2 additions & 0 deletions dart/lib/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
export 'src/client.dart';
export 'src/protocol.dart';
export 'src/version.dart';
export 'src/scope.dart';
export 'src/sentry_options.dart';
80 changes: 80 additions & 0 deletions dart/lib/src/scope.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import 'dart:collection';

import 'protocol.dart';
import 'sentry_options.dart';

/// Scope data to be sent with the event
class Scope {
/// How important this event is.
SeverityLevel level;

/// The name of the transaction which generated this event,
/// for example, the route name: `"/users/<username>/"`.
String transaction;

/// Information about the current user.
User user;

/// Used to deduplicate events by grouping ones with the same fingerprint
/// together.
///
/// Example:
///
/// // A completely custom fingerprint:
/// var custom = ['foo', 'bar', 'baz'];
List<String> fingerprint;

/// List of breadcrumbs for this scope.
///
/// See also:
/// * https://docs.sentry.io/enriching-error-data/breadcrumbs/?platform=javascript
final Queue<Breadcrumb> _breadcrumbs = Queue();

/// Unmodifiable List of breadcrumbs
List<Breadcrumb> get breadcrumbs => List.unmodifiable(_breadcrumbs);

/// Name/value pairs that events can be searched by.
final Map<String, String> tags = {};

/// Arbitrary name/value pairs attached to the scope.
///
/// Sentry.io docs do not talk about restrictions on the values, other than
/// they must be JSON-serializable.
final Map<String, dynamic> extra = {};

// TODO: eventProcessors, Contexts, BeforeBreadcrumbCallback, Breadcrumb hint, clome

final SentryOptions _options;

Scope(this._options) : assert(_options != null, 'SentryOptions is required');

/// Adds a breadcrumb to the breadcrumbs queue
void addBreadcrumb(Breadcrumb breadcrumb) {
assert(breadcrumb != null, "Breadcrumb can't be null");

if (_breadcrumbs.length >= _options.maxBreadcrumbs &&
_breadcrumbs.isNotEmpty) {
_breadcrumbs.removeFirst();
}
if (_options.maxBreadcrumbs == 0) {
return;
}
_breadcrumbs.add(breadcrumb);
}

/// Clear all the breadcrumbs
void clearBreadcrumbs() {
_breadcrumbs.clear();
}

/// Resets the Scope to its default state
void clear() {
clearBreadcrumbs();
level = null;
transaction = null;
user = null;
fingerprint = null;
tags.clear();
extra.clear();
}
}
5 changes: 5 additions & 0 deletions dart/lib/src/sentry_options.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// Sentry SDK options
class SentryOptions {
/// This variable controls the total amount of breadcrumbs that should be captured Default is 100
int maxBreadcrumbs = 100;
}
2 changes: 1 addition & 1 deletion dart/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dependencies:
uuid: ^2.0.0

dev_dependencies:
mockito: ^4.1.2
mockito: ^4.1.1
pedantic: ^1.9.2
test: ^1.15.4
yaml: ^2.2.1
Expand Down
238 changes: 238 additions & 0 deletions dart/test/scope_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
import 'package:sentry/sentry.dart';
import 'package:test/test.dart';

void main() {
final fixture = Fixture();

test('sets $SeverityLevel', () {
final sut = fixture.getSut();

sut.level = SeverityLevel.debug;

expect(
sut.level,
SeverityLevel.debug,
);
});

test('sets transaction', () {
final sut = fixture.getSut();

sut.transaction = 'test';

expect(
sut.transaction,
'test',
);
});

test('sets $User', () {
final sut = fixture.getSut();

final user = User(id: 'test');
sut.user = user;

expect(
sut.user,
user,
);
});

test('sets fingerprint', () {
final sut = fixture.getSut();

final fingerprints = ['test'];
sut.fingerprint = fingerprints;

expect(
sut.fingerprint,
fingerprints,
);
});

test('adds $Breadcrumb', () {
final sut = fixture.getSut();

final breadcrumb = Breadcrumb('test log', DateTime.utc(2019));
sut.addBreadcrumb(breadcrumb);

expect(
sut.breadcrumbs.last,
breadcrumb,
);
});

test('respects max $Breadcrumb', () {
final maxBreadcrumbs = 2;
final sut = fixture.getSut(maxBreadcrumbs: maxBreadcrumbs);

final breadcrumb1 = Breadcrumb('test log', DateTime.utc(2019));
final breadcrumb2 = Breadcrumb('test log', DateTime.utc(2019));
final breadcrumb3 = Breadcrumb('test log', DateTime.utc(2019));
sut.addBreadcrumb(breadcrumb1);
sut.addBreadcrumb(breadcrumb2);
sut.addBreadcrumb(breadcrumb3);

expect(
sut.breadcrumbs.length,
maxBreadcrumbs,
);
});

test('rotates $Breadcrumb', () {
final sut = fixture.getSut(maxBreadcrumbs: 2);

final breadcrumb1 = Breadcrumb('test log', DateTime.utc(2019));
final breadcrumb2 = Breadcrumb('test log', DateTime.utc(2019));
final breadcrumb3 = Breadcrumb('test log', DateTime.utc(2019));
sut.addBreadcrumb(breadcrumb1);
sut.addBreadcrumb(breadcrumb2);
sut.addBreadcrumb(breadcrumb3);

expect(
sut.breadcrumbs.first,
breadcrumb2,
);

expect(
sut.breadcrumbs.last,
breadcrumb3,
);
});

test('empty $Breadcrumb list', () {
final maxBreadcrumbs = 0;
final sut = fixture.getSut(maxBreadcrumbs: maxBreadcrumbs);

final breadcrumb1 = Breadcrumb('test log', DateTime.utc(2019));
sut.addBreadcrumb(breadcrumb1);

expect(
sut.breadcrumbs.length,
maxBreadcrumbs,
);
});

test('clears $Breadcrumb list', () {
final sut = fixture.getSut();

final breadcrumb1 = Breadcrumb('test log', DateTime.utc(2019));
sut.addBreadcrumb(breadcrumb1);
sut.clear();

expect(
sut.breadcrumbs.length,
0,
);
});

test('sets tag', () {
final sut = fixture.getSut();

sut.tags['test'] = 'test';

expect(
sut.tags['test'],
'test',
);
});

test('removes tag', () {
final sut = fixture.getSut();

sut.tags['test'] = 'test';
sut.tags.remove('test');

expect(
sut.tags['test'],
null,
);
});

test('sets extra', () {
final sut = fixture.getSut();

sut.extra['test'] = 'test';

expect(
sut.extra['test'],
'test',
);
});

test('removes extra', () {
final sut = fixture.getSut();

sut.extra['test'] = 'test';
sut.extra.remove('test');

expect(
sut.extra['test'],
null,
);
});

test('clears $Scope', () {
final sut = fixture.getSut();

final breadcrumb1 = Breadcrumb('test log', DateTime.utc(2019));
sut.addBreadcrumb(breadcrumb1);

sut.level = SeverityLevel.debug;
sut.transaction = 'test';

final user = User(id: 'test');
sut.user = user;

final fingerprints = ['test'];
sut.fingerprint = fingerprints;

sut.tags['test'] = 'test';
sut.extra['test'] = 'test';

sut.clear();

expect(
sut.breadcrumbs.length,
0,
);

expect(
sut.level,
null,
);

expect(
sut.transaction,
null,
);

expect(
sut.user,
null,
);

expect(
sut.fingerprint,
null,
);

expect(
sut.tags.length,
0,
);

expect(
sut.extra.length,
0,
);
});
}

class Fixture {
Scope getSut({int maxBreadcrumbs = 100}) {
final options = SentryOptions();
options.maxBreadcrumbs = maxBreadcrumbs;
return Scope(options);
}
}