package de.deepamehta.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
public class JavaAPITest {
private Logger logger = Logger.getLogger(getClass().getName());
// ---
@Test
public void asListWithNullArgument() {
try {
List l = Arrays.asList(null);
fail();
} catch (NullPointerException e) {
}
// => asList can't take a null argument
}
@Test
public void asListWithNoArguments() {
List l = Arrays.asList();
assertSame(0, l.size());
}
// ---
@Test
public void split() {
String[] a = "abc=123".split("=");
assertSame(2, a.length);
}
@Test
public void splitWithTrailingEmpty() {
String[] a = "abc=".split("=");
assertSame(1, a.length);
}
@Test
public void splitWithTrailingEmptyAndLimit() {
String[] a = "abc=".split("=", 2);
assertSame(2, a.length);
assertEquals("", a[1]);
}
/*
TestClass has a overloaded method, one with a parameter baseclass, one with a parameter subclass.
In both test cases we create a parameter object of the *subclass*.
The difference is whether the holding variable is declared as of the base type, or the sub type.
--> Result: if the parameter object is declared as base-type the base method is invoked!
--> Method overloading involves NO dynamic dispatch! The method to be invoked is determined at **compile time**.
*/
class TestClass {
String hi(PBC param) {
return "base";
}
String hi(PSC param) {
return "sub";
}
}
@Test
public void methodOverloading1() {
TestClass t = new TestClass();
PBC p = new PSC();
String res = t.hi(p);
assertSame("base", res);
}
@Test
public void methodOverloading2() {
TestClass t = new TestClass();
PSC p = new PSC();
String res = t.hi(p);
assertSame("sub", res);
}
/*
SubClass overrides a method from the BaseClass.
In both test cases we create a *subclass* instance.
The difference is whether the holding variable is declared as of the base type, or the sub type.
--> Result: always the subclass's method is invoked.
--> Method overriding involves dynamic dispatch. The method to be invoked is determined at **runtime**.
*/
class BaseClass {
String hi() {
return "base";
}
}
class SubClass extends BaseClass {
String hi() {
return "sub";
}
}
@Test
public void methodOverriding1() {
BaseClass o = new SubClass();
String res = o.hi();
assertSame("sub", res);
}
@Test
public void methodOverriding2() {
SubClass o = new SubClass();
String res = o.hi();
assertSame("sub", res);
}
/*
The subclass (SC) overrides a method from the baseclass (BC) with an subclassed parameter.
In all 4 test cases we create a *subclass* instance and a *parameter subclass* instance.
The difference is whether the holding variables are declared as of the respective base types, or the sub types.
--> Result: the subclass's method is only invoked if *both* variables are declared as of the sub types.
*/
// base class
class BC {
String hi(PBC param) {
return "base";
}
}
// subclass
class SC extends BC {
String hi(PSC param) {
return "sub";
}
}
@Test
public void missingMultipleDispatch1() {
BC o = new SC();
PBC p = new PSC();
String res = o.hi(p);
assertSame("base", res);
}
@Test
public void missingMultipleDispatch2() {
BC o = new SC();
PSC p = new PSC();
String res = o.hi(p);
assertSame("base", res);
}
@Test
public void missingMultipleDispatch3() {
SC o = new SC();
PBC p = new PSC();
String res = o.hi(p);
assertSame("base", res);
}
@Test
public void missingMultipleDispatch4() {
SC o = new SC();
PSC p = new PSC();
String res = o.hi(p);
assertSame("sub", res);
}
}
// ---
// parameter base class
class PBC {
}
// parameter subclass
class PSC extends PBC {
}