diff --git a/lib/get_it_impl.dart b/lib/get_it_impl.dart index a19b830..d63d48d 100644 --- a/lib/get_it_impl.dart +++ b/lib/get_it_impl.dart @@ -1474,18 +1474,21 @@ class _GetItImplementation implements GetIt { } String? poppedScopeName; _Scope nextScopeToPop = _currentScope; - do { + bool somethingWasPopped = false; + + while (nextScopeToPop.name != _baseScopeName && + hasScope(scopeName) && + (nextScopeToPop.name != scopeName || inclusive)) { poppedScopeName = nextScopeToPop.name; await dropScope(poppedScopeName!); + somethingWasPopped = true; nextScopeToPop = _scopes.lastWhere((x) => x.isPopping == false); - if (nextScopeToPop.name == _baseScopeName) { - return true; - } - } while (hasScope(scopeName) && inclusive - ? (poppedScopeName != scopeName) - : (nextScopeToPop.name != scopeName)); - onScopeChanged?.call(false); - return true; + } + + if (somethingWasPopped) { + onScopeChanged?.call(false); + } + return somethingWasPopped; } /// Disposes all registered factories and singletons in the provided scope diff --git a/test/scope_test.dart b/test/scope_test.dart index 7971550..e89f430 100644 --- a/test/scope_test.dart +++ b/test/scope_test.dart @@ -330,6 +330,7 @@ void main() { expect(isShadowed, false); expect(shadowingObject, shadowingInstance); }); + test('popscope', () async { final getIt = GetIt.instance; constructorCounter = 0; @@ -362,63 +363,92 @@ void main() { ); }); - test('popscopeuntil inclusive=true', () async { + test('popScopesTill inclusive=true', () async { final getIt = GetIt.instance; constructorCounter = 0; getIt.registerSingleton(TestClass('Basescope')); getIt.pushNewScope(scopeName: 'Level1'); - - getIt.registerSingleton(TestClass('2. scope')); + getIt.registerSingleton(TestClass('1. scope')); getIt.pushNewScope(scopeName: 'Level2'); + getIt.registerSingleton(TestClass('2. scope')); + getIt.pushNewScope(scopeName: 'Level3'); getIt.registerSingleton(TestClass('3. scope')); + expect(getIt.get().id, '3. scope'); - final instanceTestClassScope3 = getIt.get(); - - expect(instanceTestClassScope3.id, '3. scope'); + await getIt.popScopesTill('Level2'); - await getIt.popScopesTill('Level1'); - - final instanceTestClassScope1 = getIt.get(); - - expect(instanceTestClassScope1.id, 'Basescope'); + expect(getIt.get().id, '1. scope'); expect( () => getIt.get(), throwsStateError, ); }); - test('popscopeuntil inclusive=false', () async { + + test('popScopesTill inclusive=false', () async { final getIt = GetIt.instance; constructorCounter = 0; getIt.registerSingleton(TestClass('Basescope')); getIt.pushNewScope(scopeName: 'Level1'); - - getIt.registerSingleton(TestClass('2. scope')); + getIt.registerSingleton(TestClass('1. scope')); getIt.pushNewScope(scopeName: 'Level2'); + getIt.registerSingleton(TestClass('2. scope')); + getIt.pushNewScope(scopeName: 'Level3'); getIt.registerSingleton(TestClass('3. scope')); + expect(getIt.get().id, '3. scope'); - final instanceTestClassScope3 = getIt.get(); - - expect(instanceTestClassScope3.id, '3. scope'); + await getIt.popScopesTill('Level2', inclusive: false); - await getIt.popScopesTill('Level1', inclusive: false); - - final instanceTestClassScope1 = getIt.get(); - - expect(instanceTestClassScope1.id, '2. scope'); + expect(getIt.get().id, '2. scope'); expect( () => getIt.get(), throwsStateError, ); }); + test('popScopesTill invalid scope', () async { + final getIt = GetIt.instance; + + getIt.pushNewScope(scopeName: 'Level1'); + getIt.pushNewScope(scopeName: 'Level2'); + getIt.pushNewScope(scopeName: 'Level3'); + + expect(getIt.hasScope('Level1'), isTrue); + expect(getIt.hasScope('Level2'), isTrue); + expect(getIt.hasScope('Level3'), isTrue); + + await getIt.popScopesTill('Level4'); + + expect(getIt.hasScope('Level1'), isTrue); + expect(getIt.hasScope('Level2'), isTrue); + expect(getIt.hasScope('Level3'), isTrue); + }); + + test('popScopesTill inclusive=false top scope', () async { + final getIt = GetIt.instance; + + getIt.pushNewScope(scopeName: 'Level1'); + getIt.pushNewScope(scopeName: 'Level2'); + getIt.pushNewScope(scopeName: 'Level3'); + + expect(getIt.hasScope('Level1'), isTrue); + expect(getIt.hasScope('Level2'), isTrue); + expect(getIt.hasScope('Level3'), isTrue); + + await getIt.popScopesTill('Level3', inclusive: false); + + expect(getIt.hasScope('Level1'), isTrue); + expect(getIt.hasScope('Level2'), isTrue); + expect(getIt.hasScope('Level3'), isTrue); + }); + test('popscope with destructors', () async { final getIt = GetIt.instance; @@ -446,6 +476,7 @@ void main() { expect(disposeCounter, 3); }); + test('popscope with destructors', () async { final getIt = GetIt.instance;