diff --git a/.gitignore b/.gitignore index 9d532b1..b5546ba 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ *.ipr *.iws .idea/ +coverage/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line @@ -30,6 +31,7 @@ .pub-cache/ .pub/ /build/ +pubspec.lock # Web related lib/generated_plugin_registrant.dart diff --git a/lib/src/mock_data_snapshot.dart b/lib/src/mock_data_snapshot.dart index 00ce378..e1e382d 100644 --- a/lib/src/mock_data_snapshot.dart +++ b/lib/src/mock_data_snapshot.dart @@ -2,10 +2,20 @@ import 'package:firebase_database/firebase_database.dart'; import 'package:mockito/mockito.dart'; class MockDataSnapshot extends Mock implements DataSnapshot { + final DatabaseReference _ref; final dynamic _value; - MockDataSnapshot(this._value); + MockDataSnapshot(this._ref, this._value); + + @override + String? get key => _ref.key; + + @override + DatabaseReference get ref => _ref; @override dynamic get value => _value; + + @override + bool get exists => _value != null; } diff --git a/lib/src/mock_database_reference.dart b/lib/src/mock_database_reference.dart index de979cf..2f371b5 100644 --- a/lib/src/mock_database_reference.dart +++ b/lib/src/mock_database_reference.dart @@ -7,10 +7,13 @@ import 'mock_firebase_database.dart'; class MockDatabaseReference extends Mock implements DatabaseReference { var _nodePath = '/'; + // ignore: prefer_final_fields - static Map? _persitedData = {}; + static Map? _persistedData = {}; Map? _volatileData = {}; + MockDatabaseReference(); + MockDatabaseReference._(nodePath, [this._volatileData]) { _nodePath += nodePath; } @@ -22,18 +25,26 @@ class MockDatabaseReference extends Mock implements DatabaseReference { Map? get _data { if (MockFirebaseDatabase.persistData) { - return _persitedData; + return _persistedData; } return _volatileData; } set _data(data) { if (MockFirebaseDatabase.persistData) { - _persitedData = data; + _persistedData = data; } else return _volatileData = data; } + @override + String? get key { + if (_nodePath == '/') { + return null; + } + return _nodePath.substring(1, _nodePath.length - 1).split('/').last; + } + @override String get path => _nodePath; @@ -122,11 +133,7 @@ class MockDatabaseReference extends Mock implements DatabaseReference { ); } - @override - - /// __WARNING!__ For now only the DatabaseEventType.value event is supported. - Future once( - [DatabaseEventType eventType = DatabaseEventType.value]) { + dynamic _getCurrentData() { var tempData = _data; // remove start and end slashes. var nodePath = _nodePath.substring(1, _nodePath.length - 1); @@ -143,21 +150,37 @@ class MockDatabaseReference extends Mock implements DatabaseReference { } } } - return Future.value( - MockDatabaseEvent(MockDataSnapshot(tempData![nodePath]))); + + return tempData![nodePath]; + } + + @override + + /// __WARNING!__ For now only the DatabaseEventType.value event is supported. + Future once( + [DatabaseEventType eventType = DatabaseEventType.value]) { + var tempData = _getCurrentData(); + return Future.value(MockDatabaseEvent(MockDataSnapshot(this, tempData))); + } + + @override + Future get() { + var tempData = _getCurrentData(); + return Future.value(MockDataSnapshot(this, tempData)); } } class _Int { int value; + _Int(this.value); + _Int increment() { ++value; return this; } } - // Map _makeSupportGenericValue(Map data) { // var _dataWithGenericValue = {'__generic_mock_data_value__': Object()}; // _dataWithGenericValue.addAll(data); diff --git a/lib/src/mock_firebase_database.dart b/lib/src/mock_firebase_database.dart index 372a8f9..94e1987 100644 --- a/lib/src/mock_firebase_database.dart +++ b/lib/src/mock_firebase_database.dart @@ -20,7 +20,7 @@ class MockFirebaseDatabase extends Mock implements FirebaseDatabase { // ignore: unused_field static bool _persistData = true; //Todo support non persistence. - static void setDataPersistanceEnabled({bool ennabled = true}) { - _persistData = ennabled; + static void setDataPersistenceEnabled({bool enabled = true}) { + _persistData = enabled; } } diff --git a/pubspec.lock b/pubspec.lock deleted file mode 100644 index f1afa3c..0000000 --- a/pubspec.lock +++ /dev/null @@ -1,369 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - url: "https://pub.dartlang.org" - source: hosted - version: "41.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.0" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.1" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.8.2" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - build: - dependency: transitive - description: - name: build - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.0" - built_collection: - dependency: transitive - description: - name: built_collection - url: "https://pub.dartlang.org" - source: hosted - version: "5.1.1" - built_value: - dependency: transitive - description: - name: built_value - url: "https://pub.dartlang.org" - source: hosted - version: "8.4.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - code_builder: - dependency: transitive - description: - name: code_builder - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.0" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.16.0" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - dart_style: - dependency: transitive - description: - name: dart_style - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.2" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "1.19.2" - firebase_core_platform_interface: - dependency: "direct main" - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.4.3" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - firebase_database: - dependency: "direct main" - description: - name: firebase_database - url: "https://pub.dartlang.org" - source: hosted - version: "9.0.19" - firebase_database_platform_interface: - dependency: transitive - description: - name: firebase_database_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.1+11" - firebase_database_web: - dependency: transitive - description: - name: firebase_database_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.1" - fixnum: - dependency: transitive - description: - name: fixnum - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - glob: - dependency: transitive - description: - name: glob - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.4" - lints: - dependency: transitive - description: - name: lints - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - logging: - dependency: transitive - description: - name: logging - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.11" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.4" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - mockito: - dependency: "direct dev" - description: - name: mockito - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - package_config: - dependency: transitive - description: - name: package_config - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" - pub_semver: - dependency: transitive - description: - name: pub_semver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_gen: - dependency: transitive - description: - name: source_gen - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.2" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.2" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.9" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" - watcher: - dependency: transitive - description: - name: watcher - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - yaml: - dependency: transitive - description: - name: yaml - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.1" -sdks: - dart: ">=2.17.0 <3.0.0" - flutter: ">=1.20.0" diff --git a/test/mock_data_snapshot_test.dart b/test/mock_data_snapshot_test.dart new file mode 100644 index 0000000..381b880 --- /dev/null +++ b/test/mock_data_snapshot_test.dart @@ -0,0 +1,23 @@ +import 'package:firebase_database/firebase_database.dart'; +import 'package:firebase_database_mocks/src/mock_data_snapshot.dart'; +import 'package:firebase_database_mocks/src/mock_database_reference.dart'; +import 'package:firebase_database_mocks/src/set_up_mocks.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + late MockDatabaseReference databaseReference; + late DatabaseReference reference; + setUp(() { + setupFirebaseMocks(); + databaseReference = MockDatabaseReference(); + reference = databaseReference.child('foo/bar'); + }); + + test('Should return reference that was used for creation', () { + expect(MockDataSnapshot(reference, null).ref, equals(reference)); + }); + + test('Should return key that is the same as in reference', () { + expect(MockDataSnapshot(reference, null).key, equals(reference.key)); + }); +} \ No newline at end of file diff --git a/test/mock_database_reference_test.dart b/test/mock_database_reference_test.dart index fe369aa..44c4383 100644 --- a/test/mock_database_reference_test.dart +++ b/test/mock_database_reference_test.dart @@ -67,6 +67,11 @@ void main() { isNull, ); }); + test('Should set exists based on whether data exists at given path', () async { + await databaseReference.child('existing_path').set('value'); + expect((await databaseReference.child('existing_path').get()).exists, isTrue); + expect((await databaseReference.child('foobar').get()).exists, isFalse); + }); group('Should return null when a nonexistent path that', () { test('starts with existent node path is given', () async { @@ -206,11 +211,11 @@ void main() { group('Data persistence : ', () { tearDown(() { - MockFirebaseDatabase.setDataPersistanceEnabled(ennabled: true); + MockFirebaseDatabase.setDataPersistenceEnabled(enabled: true); }); test('Should persist data while test running', () async { - MockFirebaseDatabase.setDataPersistanceEnabled(ennabled: true); + MockFirebaseDatabase.setDataPersistenceEnabled(enabled: true); MockDatabaseReference? _databaseReference = MockDatabaseReference(); await _databaseReference.child('test1').set('value1'); await _databaseReference.child('test2/test2').set('value2'); @@ -236,7 +241,7 @@ void main() { ); }); test('Should not persist data', () async { - MockFirebaseDatabase.setDataPersistanceEnabled(ennabled: false); + MockFirebaseDatabase.setDataPersistenceEnabled(enabled: false); await databaseReference.child('test_').set('snapshot.value'); expect( (await databaseReference.child('test_').once()).snapshot.value, @@ -261,6 +266,18 @@ void main() { expect((await stream.first).snapshot.value, equals('StreamVal')); }); + group('Node key', () { + test('Should return null for root reference', () { + expect(databaseReference.key, isNull); + }); + + test('Should return last part of path as key', () { + expect(databaseReference.child('foo').key, equals('foo')); + expect(databaseReference.child('foo/bar').key, equals('bar')); + expect(databaseReference.child('foo/bar/baz').key, equals('baz')); + }); + }); + // Todo implement all dataSnapshot, dbReference and fbDatabase getters and setters if possible. // test(