@@ -1667,6 +1667,10 @@ describe('ngMock', function() {
16671667 it ( 'should create mock application root' , inject ( function ( $rootElement ) {
16681668 expect ( $rootElement . text ( ) ) . toEqual ( '' ) ;
16691669 } ) ) ;
1670+
1671+ it ( 'should attach the `$injector` to `$rootElement`' , inject ( function ( $injector , $rootElement ) {
1672+ expect ( $rootElement . injector ( ) ) . toBe ( $injector ) ;
1673+ } ) ) ;
16701674 } ) ;
16711675
16721676
@@ -2404,9 +2408,122 @@ describe('ngMockE2E', function() {
24042408 } ) ;
24052409} ) ;
24062410
2411+
24072412describe ( 'make sure that we can create an injector outside of tests' , function ( ) {
24082413 //since some libraries create custom injectors outside of tests,
24092414 //we want to make sure that this is not breaking the internals of
24102415 //how we manage annotated function cleanup during tests. See #10967
24112416 angular . injector ( [ function ( $injector ) { } ] ) ;
24122417} ) ;
2418+
2419+
2420+ describe ( '`afterEach` clean-up' , function ( ) {
2421+ describe ( 'undecorated `$rootElement`' , function ( ) {
2422+ var prevRootElement ;
2423+ var prevCleanDataSpy ;
2424+
2425+
2426+ it ( 'should set up spies so the next test can verify `$rootElement` was cleaned up' , function ( ) {
2427+ module ( function ( $provide ) {
2428+ $provide . decorator ( '$rootElement' , function ( $delegate ) {
2429+ prevRootElement = $delegate ;
2430+
2431+ // Spy on `angular.element.cleanData()`, so the next test can verify
2432+ // that it has been called as necessary
2433+ prevCleanDataSpy = spyOn ( angular . element , 'cleanData' ) . andCallThrough ( ) ;
2434+
2435+ return $delegate ;
2436+ } ) ;
2437+ } ) ;
2438+
2439+ // Inject the `$rootElement` to ensure it has been created
2440+ inject ( function ( $rootElement ) {
2441+ expect ( $rootElement . injector ( ) ) . toBeDefined ( ) ;
2442+ } ) ;
2443+ } ) ;
2444+
2445+
2446+ it ( 'should clean up `$rootElement` after each test' , function ( ) {
2447+ // One call is made by `testabilityPatch`'s `dealoc()`
2448+ // We want to verify the subsequent call, made by `angular-mocks`
2449+ expect ( prevCleanDataSpy . callCount ) . toBe ( 2 ) ;
2450+
2451+ var cleanUpNodes = prevCleanDataSpy . calls [ 1 ] . args [ 0 ] ;
2452+ expect ( cleanUpNodes . length ) . toBe ( 1 ) ;
2453+ expect ( cleanUpNodes [ 0 ] ) . toBe ( prevRootElement [ 0 ] ) ;
2454+ } ) ;
2455+ } ) ;
2456+
2457+
2458+ describe ( 'decorated `$rootElement`' , function ( ) {
2459+ var prevOriginalRootElement ;
2460+ var prevRootElement ;
2461+ var prevCleanDataSpy ;
2462+
2463+
2464+ it ( 'should set up spies so the next text can verify `$rootElement` was cleaned up' , function ( ) {
2465+ module ( function ( $provide ) {
2466+ $provide . decorator ( '$rootElement' , function ( $delegate ) {
2467+ prevOriginalRootElement = $delegate ;
2468+
2469+ // Mock `$rootElement` to be able to verify that the correct object is cleaned up
2470+ prevRootElement = angular . element ( '<div></div>' ) ;
2471+
2472+ // Spy on `angular.element.cleanData()`, so the next test can verify
2473+ // that it has been called as necessary
2474+ prevCleanDataSpy = spyOn ( angular . element , 'cleanData' ) . andCallThrough ( ) ;
2475+
2476+ return prevRootElement ;
2477+ } ) ;
2478+ } ) ;
2479+
2480+ // Inject the `$rootElement` to ensure it has been created
2481+ inject ( function ( $rootElement ) {
2482+ expect ( $rootElement ) . toBe ( prevRootElement ) ;
2483+ expect ( prevOriginalRootElement . injector ( ) ) . toBeDefined ( ) ;
2484+ expect ( prevRootElement . injector ( ) ) . toBeUndefined ( ) ;
2485+
2486+ // If we don't clean up `prevOriginalRootElement`-related data now, `testabilityPatch` will
2487+ // complain about a memory leak, because it doesn't clean up after the original
2488+ // `$rootElement`
2489+ // This is a false alarm, because `angular-mocks` would have cleaned up in a subsequent
2490+ // `afterEach` block
2491+ prevOriginalRootElement . removeData ( ) ;
2492+ } ) ;
2493+ } ) ;
2494+
2495+
2496+ it ( 'should clean up `$rootElement` (both original and decorated) after each test' , function ( ) {
2497+ // One call is made by `testabilityPatch`'s `dealoc()`
2498+ // We want to verify the subsequent call, made by `angular-mocks`
2499+ expect ( prevCleanDataSpy . callCount ) . toBe ( 2 ) ;
2500+
2501+ var cleanUpNodes = prevCleanDataSpy . calls [ 1 ] . args [ 0 ] ;
2502+ expect ( cleanUpNodes . length ) . toBe ( 2 ) ;
2503+ expect ( cleanUpNodes [ 0 ] ) . toBe ( prevOriginalRootElement [ 0 ] ) ;
2504+ expect ( cleanUpNodes [ 1 ] ) . toBe ( prevRootElement [ 0 ] ) ;
2505+ } ) ;
2506+ } ) ;
2507+
2508+
2509+ describe ( 'uninstantiated or falsy `$rootElement`' , function ( ) {
2510+ it ( 'should not break if `$rootElement` was never instantiated' , function ( ) {
2511+ // Just an empty test to verify that `angular-mocks` doesn't break,
2512+ // when trying to clean up `$rootElement`, if `$rootElement` was never injected in the test
2513+ // (and thus never instantiated/created)
2514+
2515+ // Ensure the `$injector` is created - if there is no `$injector`, no clean-up takes places
2516+ inject ( function ( ) { } ) ;
2517+ } ) ;
2518+
2519+
2520+ it ( 'should not break if the decorated `$rootElement` is falsy (e.g. `null`)' , function ( ) {
2521+ module ( function ( $provide ) {
2522+ $provide . value ( '$rootElement' , null ) ;
2523+ } ) ;
2524+
2525+ // Ensure the `$injector` is created - if there is no `$injector`, no clean-up takes places
2526+ inject ( function ( ) { } ) ;
2527+ } ) ;
2528+ } ) ;
2529+ } ) ;
0 commit comments