package org.netbeans.gradle.project.output;
import java.io.IOException;
import org.junit.Test;
import static org.junit.Assert.*;
public class IOTabMaintainerTest {
private static IOTabMaintainer<Integer, Tab> create() {
return new IOTabMaintainer<>(new IOTabFactory<Tab>() {
@Override
public Tab create(String caption) {
return new Tab(caption);
}
});
}
@Test
public void testReturnsSameTabAfterClose() throws IOException {
IOTabMaintainer<Integer, Tab> maintainer = create();
String caption = "my-tab";
Tab originalTab;
try (IOTabRef<Tab> tabRef = maintainer.getTab(1, caption)) {
originalTab = tabRef.getTab();
}
assertTrue("Must be closed.", originalTab.isClosedForNow());
assertEquals(caption, originalTab.caption);
IOTabRef<Tab> tabRef2 = maintainer.getTab(1, caption);
assertSame(originalTab, tabRef2.getTab());
}
@Test
public void testReturnsDifferentTabForDifferentKeys() throws IOException {
IOTabMaintainer<Integer, Tab> maintainer = create();
Tab tab1;
IOTabRef<Tab> tabRef2;
Tab tab2;
try (IOTabRef<Tab> tabRef1 = maintainer.getTab(1, "tab1")) {
tab1 = tabRef1.getTab();
tabRef2 = maintainer.getTab(2, "tab2");
tab2 = tabRef2.getTab();
}
tabRef2.close();
Tab tab3;
try (IOTabRef<Tab> tabRef3 = maintainer.getTab(3, "tab3")) {
tab3 = tabRef3.getTab();
}
assertEquals("tab1", tab1.caption);
assertEquals("tab2", tab2.caption);
assertEquals("tab3", tab3.caption);
}
@Test
public void testDoesNotReturnClosedTab() throws IOException {
IOTabMaintainer<Integer, Tab> maintainer = create();
Tab tab1;
try (IOTabRef<Tab> tabRef1 = maintainer.getTab(1, "tab1")) {
tab1 = tabRef1.getTab();
}
tab1.destroy();
IOTabRef<Tab> tabRef2 = maintainer.getTab(1, "tab2");
Tab tab2 = tabRef2.getTab();
assertEquals("tab1", tab1.caption);
assertEquals("tab2", tab2.caption);
assertNotSame(tab1, tab2);
}
@Test
public void testMultipleConcurrentTabsAddIndexes() {
IOTabMaintainer<Integer, Tab> maintainer = create();
IOTabRef<Tab> tabRef1 = maintainer.getTab(1, "tab1");
IOTabRef<Tab> tabRef2 = maintainer.getTab(1, "tab1");
IOTabRef<Tab> tabRef3 = maintainer.getTab(1, "tab1");
assertEquals("tab1", tabRef1.getTab().caption);
assertEquals("tab1 #2", tabRef2.getTab().caption);
assertEquals("tab1 #3", tabRef3.getTab().caption);
}
@Test
public void testLowestIndexIsUsedWhenThereAreMultipleOpen1() throws IOException {
IOTabMaintainer<Integer, Tab> maintainer = create();
IOTabRef<Tab> tabRef1 = maintainer.getTab(1, "tab1");
IOTabRef<Tab> tabRef2 = maintainer.getTab(1, "tab1");
IOTabRef<Tab> tabRef3 = maintainer.getTab(1, "tab1");
tabRef1.close();
tabRef2.close();
tabRef3.close();
tabRef1 = maintainer.getTab(1, "XXX");
assertEquals("tab1", tabRef1.getTab().caption);
tabRef2 = maintainer.getTab(1, "XXX");
assertEquals("tab1 #2", tabRef2.getTab().caption);
tabRef3 = maintainer.getTab(1, "XXX");
assertEquals("tab1 #3", tabRef3.getTab().caption);
}
@Test
public void testLowestIndexIsUsedWhenThereAreMultipleOpen2() throws IOException {
IOTabMaintainer<Integer, Tab> maintainer = create();
IOTabRef<Tab> tabRef1 = maintainer.getTab(1, "tab1");
IOTabRef<Tab> tabRef2 = maintainer.getTab(1, "tab1");
IOTabRef<Tab> tabRef3 = maintainer.getTab(1, "tab1");
tabRef3.close();
tabRef2.close();
tabRef1.close();
tabRef1 = maintainer.getTab(1, "XXX");
assertEquals("tab1", tabRef1.getTab().caption);
tabRef2 = maintainer.getTab(1, "XXX");
assertEquals("tab1 #2", tabRef2.getTab().caption);
tabRef3 = maintainer.getTab(1, "XXX");
assertEquals("tab1 #3", tabRef3.getTab().caption);
}
@Test
public void testCloseIsIdempotent() throws IOException {
IOTabMaintainer<Integer, Tab> maintainer = create();
IOTabRef<Tab> tabRef1 = maintainer.getTab(1, "tab1");
for (int i = 0; i < 5; i++) {
tabRef1.close();
}
tabRef1 = maintainer.getTab(1, "tab1");
assertEquals("tab1", tabRef1.getTab().caption);
IOTabRef<Tab> tabRef2 = maintainer.getTab(1, "tab1");
assertEquals("tab1 #2", tabRef2.getTab().caption);
}
private static final class Tab implements IOTabDef {
public final String caption;
private volatile boolean destroyed;
private volatile boolean closed;
public Tab(String caption) {
this.caption = caption;
this.destroyed = false;
this.closed = false;
}
void destroy() {
this.destroyed = true;
}
boolean isClosedForNow() {
return closed;
}
@Override
public void close() throws IOException {
this.closed = true;
}
@Override
public boolean isDestroyed() {
return destroyed;
}
@Override
public String toString() {
return "Tab{" + "caption=" + caption + ", closed for now: " + closed + ", destroyed=" + destroyed + '}';
}
}
}