/* * Copyright (C) 2010 The Guava Authors * * 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.google.common.testing; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import com.google.common.annotations.GwtCompatible; import junit.framework.TestCase; import org.junit.Test; /** * @author Luiz-Otavio "Z" Zorzella */ @GwtCompatible public class TearDownStackTest extends TestCase { private TearDownStack tearDownStack = new TearDownStack(); @Test public void testSingleTearDown() throws Exception { final TearDownStack stack = buildTearDownStack(); final SimpleTearDown tearDown = new SimpleTearDown(); stack.addTearDown(tearDown); assertEquals(false, tearDown.ran); stack.runTearDown(); assertEquals("tearDown should have run", true, tearDown.ran); } @Test public void testMultipleTearDownsHappenInOrder() throws Exception { final TearDownStack stack = buildTearDownStack(); final SimpleTearDown tearDownOne = new SimpleTearDown(); stack.addTearDown(tearDownOne); final Callback callback = new Callback() { @Override public void run() { assertEquals("tearDownTwo should have been run before tearDownOne", false, tearDownOne.ran); } }; final SimpleTearDown tearDownTwo = new SimpleTearDown(callback); stack.addTearDown(tearDownTwo); assertEquals(false, tearDownOne.ran); assertEquals(false, tearDownTwo.ran); stack.runTearDown(); assertEquals("tearDownOne should have run", true, tearDownOne.ran); assertEquals("tearDownTwo should have run", true, tearDownTwo.ran); } @Test public void testThrowingTearDown() throws Exception { final TearDownStack stack = buildTearDownStack(); final ThrowingTearDown tearDownOne = new ThrowingTearDown("one"); stack.addTearDown(tearDownOne); final ThrowingTearDown tearDownTwo = new ThrowingTearDown("two"); stack.addTearDown(tearDownTwo); assertEquals(false, tearDownOne.ran); assertEquals(false, tearDownTwo.ran); try { stack.runTearDown(); fail("runTearDown should have thrown an exception"); } catch (ClusterException expected) { assertEquals("two", expected.getCause().getMessage()); } catch (RuntimeException e) { throw new RuntimeException( "A ClusterException should have been thrown, rather than a " + e.getClass().getName(), e); } assertEquals(true, tearDownOne.ran); assertEquals(true, tearDownTwo.ran); } @Override public final void runBare() throws Throwable { try { setUp(); runTest(); } finally { tearDown(); } } @Override protected void tearDown() { tearDownStack.runTearDown(); } /** * Builds a {@link TearDownStack} that makes sure it's clear by the end of * this test. */ private TearDownStack buildTearDownStack() { final TearDownStack result = new TearDownStack(); tearDownStack.addTearDown(new TearDown() { @Override public void tearDown() throws Exception { assertEquals( "The test should have cleared the stack (say, by virtue of running runTearDown)", 0, result.stack.size()); } }); return result; } private static final class ThrowingTearDown implements TearDown { private final String id; boolean ran = false; ThrowingTearDown(String id) { this.id = id; } @Override public void tearDown() throws Exception { ran = true; throw new RuntimeException(id); } } private static final class SimpleTearDown implements TearDown { boolean ran = false; Callback callback = null; public SimpleTearDown() {} public SimpleTearDown(Callback callback) { this.callback = callback; } @Override public void tearDown() throws Exception { if (callback != null) { callback.run(); } ran = true; } } private interface Callback { void run(); } }