1 /* 2 * Copyright (C) 2010 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.testing; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.fail; 21 22 import com.google.common.annotations.GwtCompatible; 23 24 import junit.framework.TestCase; 25 26 import org.junit.Test; 27 28 /** 29 * @author Luiz-Otavio "Z" Zorzella 30 */ 31 @GwtCompatible 32 public class TearDownStackTest extends TestCase { 33 34 private TearDownStack tearDownStack = new TearDownStack(); 35 36 @Test testSingleTearDown()37 public void testSingleTearDown() throws Exception { 38 final TearDownStack stack = buildTearDownStack(); 39 40 final SimpleTearDown tearDown = new SimpleTearDown(); 41 stack.addTearDown(tearDown); 42 43 assertEquals(false, tearDown.ran); 44 45 stack.runTearDown(); 46 47 assertEquals("tearDown should have run", true, tearDown.ran); 48 } 49 50 @Test testMultipleTearDownsHappenInOrder()51 public void testMultipleTearDownsHappenInOrder() throws Exception { 52 final TearDownStack stack = buildTearDownStack(); 53 54 final SimpleTearDown tearDownOne = new SimpleTearDown(); 55 stack.addTearDown(tearDownOne); 56 57 final Callback callback = new Callback() { 58 @Override 59 public void run() { 60 assertEquals("tearDownTwo should have been run before tearDownOne", 61 false, tearDownOne.ran); 62 } 63 }; 64 65 final SimpleTearDown tearDownTwo = new SimpleTearDown(callback); 66 stack.addTearDown(tearDownTwo); 67 68 assertEquals(false, tearDownOne.ran); 69 assertEquals(false, tearDownTwo.ran); 70 71 stack.runTearDown(); 72 73 assertEquals("tearDownOne should have run", true, tearDownOne.ran); 74 assertEquals("tearDownTwo should have run", true, tearDownTwo.ran); 75 } 76 77 @Test testThrowingTearDown()78 public void testThrowingTearDown() throws Exception { 79 final TearDownStack stack = buildTearDownStack(); 80 81 final ThrowingTearDown tearDownOne = new ThrowingTearDown("one"); 82 stack.addTearDown(tearDownOne); 83 84 final ThrowingTearDown tearDownTwo = new ThrowingTearDown("two"); 85 stack.addTearDown(tearDownTwo); 86 87 assertEquals(false, tearDownOne.ran); 88 assertEquals(false, tearDownTwo.ran); 89 90 try { 91 stack.runTearDown(); 92 fail("runTearDown should have thrown an exception"); 93 } catch (ClusterException expected) { 94 assertEquals("two", expected.getCause().getMessage()); 95 } catch (RuntimeException e) { 96 throw new RuntimeException( 97 "A ClusterException should have been thrown, rather than a " + e.getClass().getName(), e); 98 } 99 100 assertEquals(true, tearDownOne.ran); 101 assertEquals(true, tearDownTwo.ran); 102 } 103 runBare()104 @Override public final void runBare() throws Throwable { 105 try { 106 setUp(); 107 runTest(); 108 } finally { 109 tearDown(); 110 } 111 } 112 tearDown()113 @Override protected void tearDown() { 114 tearDownStack.runTearDown(); 115 } 116 117 /** 118 * Builds a {@link TearDownStack} that makes sure it's clear by the end of 119 * this test. 120 */ buildTearDownStack()121 private TearDownStack buildTearDownStack() { 122 final TearDownStack result = new TearDownStack(); 123 tearDownStack.addTearDown(new TearDown() { 124 125 @Override 126 public void tearDown() throws Exception { 127 assertEquals( 128 "The test should have cleared the stack (say, by virtue of running runTearDown)", 129 0, result.stack.size()); 130 } 131 }); 132 return result; 133 } 134 135 private static final class ThrowingTearDown implements TearDown { 136 137 private final String id; 138 boolean ran = false; 139 ThrowingTearDown(String id)140 ThrowingTearDown(String id) { 141 this.id = id; 142 } 143 144 @Override tearDown()145 public void tearDown() throws Exception { 146 ran = true; 147 throw new RuntimeException(id); 148 } 149 } 150 151 private static final class SimpleTearDown implements TearDown { 152 153 boolean ran = false; 154 Callback callback = null; 155 SimpleTearDown()156 public SimpleTearDown() {} 157 SimpleTearDown(Callback callback)158 public SimpleTearDown(Callback callback) { 159 this.callback = callback; 160 } 161 162 @Override tearDown()163 public void tearDown() throws Exception { 164 if (callback != null) { 165 callback.run(); 166 } 167 ran = true; 168 } 169 } 170 171 private interface Callback { run()172 void run(); 173 } 174 } 175