/*
* Copyright 2013 the original author or 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 org.powermock.core.testlisteners;
import org.junit.AfterClass;
import org.junit.Test;
import org.powermock.core.testlisteners.GlobalNotificationBuildSupport.Callback;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* The design of this test-class does only allow it to be run once per JVM
* (or more accurately "per classloader", in case the test-class is redefined
* by different classloaders in some sort of test suite),
* because it will test some class instantiation, which can only occur one per
* class.
*/
@SuppressWarnings({"SameParameterValue", "ResultOfMethodCallIgnored"})
public class GlobalNotificationBuildSupportTest {
static boolean initiationOfNormalClassIsUnderWay;
static final Callback mockCallback = mock(Callback.class);
@SuppressWarnings("SameParameterValue")
static class NormalClass {
static {
initiationOfNormalClassIsUnderWay = true;
GlobalNotificationBuildSupport.testClassInitiated(NormalClass.class);
}
NormalClass(String dummy) {
GlobalNotificationBuildSupport.testInstanceCreated(this);
}
public NormalClass() {
this("dummy");
GlobalNotificationBuildSupport.testInstanceCreated(this);
}
}
@SuppressWarnings("SameParameterValue")
static class SubClass extends NormalClass {
public SubClass() {
super("dummy");
}
public SubClass(String dummy) {
}
}
private String nestedClassName(String localName) {
return GlobalNotificationBuildSupportTest.class.getName() + "$" + localName;
}
private void assertNotificationOf(NormalClass normalInstance) {
verify(mockCallback).testInstanceCreated(normalInstance);
verifyNoMoreInteractions(mockCallback);
}
@Test
public void normalClassCreation() {
// Given
assertFalse("Initiation of NormalClass must not yet have commenced",
initiationOfNormalClassIsUnderWay);
GlobalNotificationBuildSupport.prepareTestSuite(
nestedClassName("NormalClass"), mockCallback);
/* Nothing must have happened so far ... */
verifyNoMoreInteractions(mockCallback);
// When
final NormalClass normalInstance = new NormalClass();
// Then verify life-cycle callbacks on NormalClass
verify(mockCallback).suiteClassInitiated(NormalClass.class);
// Then notifications of created instances are expected ...
assertNotificationOf(normalInstance);
assertNotificationOf(new NormalClass());
assertNotificationOf(new NormalClass());
assertNotificationOf(new NormalClass("dummy"));
assertNotificationOf(new SubClass("dummy"));
assertNotificationOf(new NormalClass("dummy"));
assertNotificationOf(new SubClass("dummy"));
assertNotificationOf(new NormalClass());
// Tear-down
GlobalNotificationBuildSupport.closeTestSuite(NormalClass.class);
new NormalClass("dummy").toString();
new SubClass().hashCode();
verifyNoMoreInteractions(mockCallback); // Creation should no longer have any affect
}
/**
* Tests some ConcurrentHashMap functionality that
* {@link GlobalNotificationBuildSupport#closePendingTestSuites(Callback)}
* depends on.
*/
@Test
public void removeAllFromConcurrentHashMap() {
ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<String, Object>();
final Object value = new Object();
map.put("foo", value);
map.put("bar", value);
assertEquals("Size of concurrent hashmap", 2, map.size());
Collection<?> valueToRemove = java.util.Collections.singleton(value);
map.values().removeAll(valueToRemove);
assertEquals("Size of concurrent hashmap after removal of values",
0, map.size());
}
@AfterClass
public static void closeTestSuite() {
GlobalNotificationBuildSupport.closeTestSuite(NormalClass.class);
GlobalNotificationBuildSupport.closePendingTestSuites(mockCallback);
}
}