From d44bcef8cf61db75fe62c0adb37b25381ba1e943 Mon Sep 17 00:00:00 2001 From: beeth0ven Date: Tue, 5 Jul 2022 11:10:58 +0800 Subject: [PATCH] add `scope.get` --- .../errors/scope_value_not_exposed_error.dart | 13 ++++ lib/src/scopes/scope_methods/scope_get.dart | 10 +++ lib/src/scopes/scopes.dart | 1 + test/scopes/scope_methods/scope_get_test.dart | 78 +++++++++++++++++++ test/scopes/scopes_test.dart | 2 + 5 files changed, 104 insertions(+) create mode 100644 lib/src/scopes/errors/scope_value_not_exposed_error.dart create mode 100644 test/scopes/scope_methods/scope_get_test.dart diff --git a/lib/src/scopes/errors/scope_value_not_exposed_error.dart b/lib/src/scopes/errors/scope_value_not_exposed_error.dart new file mode 100644 index 0000000..e279f87 --- /dev/null +++ b/lib/src/scopes/errors/scope_value_not_exposed_error.dart @@ -0,0 +1,13 @@ + +class ScopeValueNotExposedError extends Error { + + ScopeValueNotExposedError(Object? name): _name = name; + + final Object? _name; + + @override + String toString() { + final header = _name == null ? '$T' : '$T $_name'; + return '`$header` is not exposed in current scope'; + } +} diff --git a/lib/src/scopes/scope_methods/scope_get.dart b/lib/src/scopes/scope_methods/scope_get.dart index 2892bb1..141c1a6 100644 --- a/lib/src/scopes/scope_methods/scope_get.dart +++ b/lib/src/scopes/scope_methods/scope_get.dart @@ -1,3 +1,4 @@ +import '../errors/scope_value_not_exposed_error.dart'; abstract class ScopeGet { T? getOrNull({ @@ -7,3 +8,12 @@ abstract class ScopeGet { Object? name, }); } + +extension ScopeGetX on ScopeGet { + + T get({ + Object? name, + }) => has(name: name) + ? getOrNull(name: name) as T + : throw ScopeValueNotExposedError(name); +} diff --git a/lib/src/scopes/scopes.dart b/lib/src/scopes/scopes.dart index 2d0bddd..fd3a8ff 100644 --- a/lib/src/scopes/scopes.dart +++ b/lib/src/scopes/scopes.dart @@ -1,5 +1,6 @@ export 'configurables/configurable.dart'; +export 'errors/scope_value_not_exposed_error.dart'; export 'scope_methods/scope_get.dart'; export 'scope_methods/scope_expose.dart'; export 'scope_methods/scope_push.dart'; diff --git a/test/scopes/scope_methods/scope_get_test.dart b/test/scopes/scope_methods/scope_get_test.dart new file mode 100644 index 0000000..e339f6e --- /dev/null +++ b/test/scopes/scope_methods/scope_get_test.dart @@ -0,0 +1,78 @@ +import 'package:test/test.dart'; +import 'package:scopes/scopes.dart'; + +import '../../toolbox/mock_configurable.dart'; + +void main() { + + test('`scope.get` return value if value exposed', () async { + + final scope = await Scope.root([ + MockConfigurable((scope) { + scope.expose(expose: () => 'a'); + }), + ]); + + final value = scope.get(); + + expect(value, 'a'); + + }); + + test('`scope.get` throws if value not exposed', () async { + + final scope = await Scope.root([]); + + expect( + () { + scope.get(); + }, + throwsA( + isA>() + .having( + (error) => '$error', + 'description', + contains('`String` is not exposed in current scope'), + ), + ) + ); + + }); + + test('`scope.get` return value if value exposed with name', () async { + + final scope = await Scope.root([ + MockConfigurable((scope) { + scope.expose( + name: 'state', + expose: () => 'a', + ); + }), + ]); + + final value = scope.get(name: 'state'); + + expect(value, 'a'); + + }); + + test('`scope.get` throws if value not exposed with name', () async { + + final scope = await Scope.root([]); + + expect( + () { + scope.get(name: 'state'); + }, + throwsA( + isA>() + .having( + (error) => '$error', + 'description', + contains('`String state` is not exposed in current scope'), + ), + ) + ); + + }); +} diff --git a/test/scopes/scopes_test.dart b/test/scopes/scopes_test.dart index 22aaf88..68f1a01 100644 --- a/test/scopes/scopes_test.dart +++ b/test/scopes/scopes_test.dart @@ -1,10 +1,12 @@ import 'scope_methods/disposable_test.dart' as disposable_test; +import 'scope_methods/scope_get_test.dart' as scope_get_test; import 'scope_methods/scope_push_test.dart' as scope_push_test; import 'scopes/scope_test.dart' as scope_test; void main() { disposable_test.main(); + scope_get_test.main(); scope_push_test.main(); scope_test.main(); }