| /* |
| * Copyright 2000-2009 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.openapi.util; |
| |
| import com.intellij.openapi.Disposable; |
| import junit.framework.TestCase; |
| import org.jetbrains.annotations.NonNls; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| public class DisposerTest extends TestCase { |
| |
| private MyDisposable myRoot; |
| |
| private MyDisposable myFolder1; |
| private MyDisposable myFolder2; |
| |
| private MyDisposable myLeaf1; |
| private MyDisposable myLeaf2; |
| |
| private final List<MyDisposable> myDisposedObjects = new ArrayList<MyDisposable>(); |
| |
| @NonNls private final List<String> myDisposeActions = new ArrayList<String>(); |
| |
| @Override |
| protected void setUp() throws Exception { |
| //if(!Disposer.getTree().isEmpty()) { |
| // Disposer.assertIsEmpty(); |
| // fail("Clean leftovers from previous tests"); |
| // Disposer.getTree().clearAll(); |
| //} |
| myRoot = new MyDisposable("root"); |
| |
| myFolder1 = new MyDisposable("folder1"); |
| myFolder2 = new MyDisposable("folder2"); |
| |
| myLeaf1 = new MyDisposable("leaf1"); |
| myLeaf2 = new MyDisposable("leaf2"); |
| |
| myDisposeActions.clear(); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| Disposer.dispose(myRoot); |
| //assertTrue(Disposer.getTree().isEmpty()); |
| super.tearDown(); |
| } |
| |
| public void testDisposalAndAbsenceOfReferences() throws Exception { |
| Disposer.register(myRoot, myFolder1); |
| Disposer.register(myRoot, myFolder2); |
| Disposer.register(myFolder1, myLeaf1); |
| |
| Disposer.dispose(myFolder1); |
| assertFalse(myRoot.isDisposed()); |
| assertDisposed(myFolder1); |
| assertDisposed(myLeaf1); |
| assertFalse(myFolder2.isDisposed()); |
| |
| Disposer.dispose(myRoot); |
| assertDisposed(myRoot); |
| assertDisposed(myFolder2); |
| |
| Disposer.dispose(myLeaf1); |
| } |
| |
| public void testDisposalOrder() throws Exception { |
| Disposer.register(myRoot, myFolder1); |
| Disposer.register(myFolder1, myLeaf1); |
| Disposer.register(myRoot, myFolder2); |
| |
| Disposer.dispose(myRoot); |
| |
| List<MyDisposable> expected = new ArrayList<MyDisposable>(); |
| expected.add(myFolder2); |
| expected.add(myLeaf1); |
| expected.add(myFolder1); |
| expected.add(myRoot); |
| |
| assertEquals(expected, myDisposedObjects); |
| } |
| |
| public void testDirectCallOfDisposable() throws Exception { |
| SelDisposable selfDisposable = new SelDisposable("root"); |
| Disposer.register(myRoot, selfDisposable); |
| Disposer.register(selfDisposable, myFolder1); |
| Disposer.register(myFolder1, myFolder2); |
| |
| selfDisposable.dispose(); |
| |
| assertDisposed(selfDisposable); |
| assertDisposed(myFolder1); |
| assertDisposed(myFolder2); |
| |
| assertEquals(0, Disposer.getTree().getNodesInExecution().size()); |
| } |
| |
| public void testDirectCallOfUnregisteredSelfDisposable() throws Exception { |
| SelDisposable selfDisposable = new SelDisposable("root"); |
| selfDisposable.dispose(); |
| } |
| |
| public void testDisposeAndReplace() throws Exception { |
| Disposer.register(myRoot, myFolder1); |
| |
| Disposer.disposeChildAndReplace(myFolder1, myFolder2); |
| assertDisposed(myFolder1); |
| |
| Disposer.dispose(myRoot); |
| assertDisposed(myRoot); |
| assertDisposed(myFolder2); |
| } |
| |
| public void testPostponedParentRegistration() throws Exception { |
| Disposer.register(myFolder1, myLeaf1); |
| Disposer.register(myLeaf1, myLeaf2); |
| Disposer.register(myRoot, myFolder1); |
| |
| |
| Disposer.dispose(myRoot); |
| |
| assertDisposed(myRoot); |
| assertDisposed(myFolder1); |
| assertDisposed(myLeaf1); |
| assertDisposed(myLeaf2); |
| } |
| |
| public void testDisposalOfParentless() throws Throwable { |
| Disposer.register(myFolder1, myLeaf1); |
| Disposer.register(myFolder1, myFolder2); |
| Disposer.register(myFolder2, myLeaf2); |
| |
| Disposer.dispose(myFolder1); |
| |
| assertDisposed(myFolder1); |
| assertDisposed(myFolder2); |
| assertDisposed(myLeaf1); |
| assertDisposed(myLeaf2); |
| } |
| |
| public void testDisposalOfParentess2() throws Throwable { |
| Disposer.register(myFolder1, myLeaf1); |
| Disposer.register(myFolder2, myLeaf2); |
| Disposer.register(myFolder1, myFolder2); |
| |
| Disposer.dispose(myFolder1); |
| |
| assertDisposed(myFolder1); |
| assertDisposed(myFolder2); |
| assertDisposed(myLeaf1); |
| assertDisposed(myLeaf2); |
| } |
| |
| public void testOverrideParentDisposable() throws Exception { |
| Disposer.register(myFolder1, myLeaf1); |
| Disposer.register(myFolder2, myFolder1); |
| Disposer.register(myRoot, myFolder1); |
| |
| Disposer.dispose(myFolder2); |
| |
| assertDisposed(myFolder2); |
| assertFalse(myLeaf1.isDisposed()); |
| assertFalse(myFolder1.isDisposed()); |
| |
| Disposer.dispose(myRoot); |
| assertDisposed(myFolder1); |
| assertDisposed(myLeaf1); |
| } |
| |
| public void testDisposableParentNotify() throws Exception { |
| MyParentDisposable root = new MyParentDisposable("root"); |
| Disposer.register(root, myFolder1); |
| |
| MyParentDisposable sub = new MyParentDisposable("subFolder"); |
| Disposer.register(myFolder1, sub); |
| |
| Disposer.register(sub, myLeaf1); |
| |
| Disposer.dispose(root); |
| |
| |
| @NonNls ArrayList<String> expected = new ArrayList<String>(); |
| expected.add("beforeDispose: root"); |
| expected.add("beforeDispose: subFolder"); |
| expected.add("dispose: leaf1"); |
| expected.add("dispose: subFolder"); |
| expected.add("dispose: folder1"); |
| expected.add("dispose: root"); |
| |
| |
| assertEquals(toString(expected), toString(myDisposeActions)); |
| } |
| |
| |
| private void assertDisposed(MyDisposable disposable) { |
| assertTrue(disposable.isDisposed()); |
| assertFalse(disposable.toString(), Disposer.getTree().containsKey(disposable)); |
| |
| Disposer.getTree().assertNoReferenceKeptInTree(disposable); |
| } |
| |
| private class MyDisposable implements Disposable { |
| |
| private boolean myDisposed = false; |
| protected String myName; |
| |
| public MyDisposable(@NonNls String aName) { |
| myName = aName; |
| } |
| |
| @Override |
| public void dispose() { |
| myDisposed = true; |
| myDisposedObjects.add(this); |
| myDisposeActions.add("dispose: " + myName); |
| } |
| |
| public boolean isDisposed() { |
| return myDisposed; |
| } |
| |
| public String toString() { |
| return myName; |
| } |
| } |
| |
| private class MyParentDisposable extends MyDisposable implements Disposable.Parent { |
| private MyParentDisposable(@NonNls final String aName) { |
| super(aName); |
| } |
| |
| @Override |
| public void beforeTreeDispose() { |
| myDisposeActions.add("beforeDispose: " + myName); |
| } |
| } |
| |
| private class SelDisposable extends MyDisposable { |
| public SelDisposable(@NonNls String aName) { |
| super(aName); |
| } |
| |
| @Override |
| public void dispose() { |
| Disposer.dispose(this); |
| super.dispose(); |
| } |
| } |
| |
| private static String toString(List<String> list) { |
| StringBuilder result = new StringBuilder(); |
| |
| for (int i = 0; i < list.size(); i++) { |
| String each = list.get(i); |
| result.append(each); |
| if (i < list.size() - 1) { |
| result.append("\n"); |
| } |
| } |
| |
| return result.toString(); |
| } |
| } |