blob: bfe91440d2bca56a997d056347527e219aca866c [file] [log] [blame]
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.jobjc;
import com.apple.jobjc.Coder.IDCoder;
import com.apple.jobjc.Coder.VoidCoder;
import com.apple.jobjc.Invoke.MsgSend;
import com.apple.jobjc.Invoke.MsgSendSuper;
import com.apple.jobjc.PrimitiveCoder.DoubleCoder;
import com.apple.jobjc.PrimitiveCoder.FloatCoder;
import com.apple.jobjc.PrimitiveCoder.SIntCoder;
import com.apple.jobjc.PrimitiveCoder.SLongLongCoder;
import com.apple.jobjc.foundation.NSObject;
import com.apple.jobjc.foundation.NSObjectClass;
import com.apple.jobjc.foundation.NSPoint;
import com.apple.jobjc.foundation.NSString;
public class SubclassingTest extends PooledTestCase{
JObjCRuntime runtime;
NativeArgumentBuffer ctx;
@Override public void setUp() throws Exception{
super.setUp();
this.runtime = JObjCRuntime.getInstance();
this.ctx = runtime.getThreadLocalState();
runtime.registerUserClass(MyObject.class, MyObjectClass.class);
}
public void testClass(){
final MyObjectClass cls = new MyObjectClass(runtime);
assertEquals(MyObject.class.getSimpleName(), UnsafeRuntimeAccess.getClassNameFor(cls));
}
public void testInst(){
final MyObjectClass cls = new MyObjectClass(runtime);
final MyObject instObj = cls.alloc();
final MyObject retrievedObj = Subclassing.getJObjectFromIVar(UnsafeRuntimeAccess.getObjPtr(instObj));
assertTrue(instObj == retrievedObj);
}
public void testVoidVoidMethod(){
final MyObject instObj = new MyObjectClass(runtime).alloc();
assertEquals(0, instObj.myMethodHits);
MsgSend sel = new MsgSend(runtime, "myMethod", VoidCoder.INST);
sel.init(ctx, instObj);
sel.invoke(ctx);
assertEquals(1, instObj.myMethodHits);
}
public void testMsgSendSuper(){
final MyObjectClass cls = new MyObjectClass(runtime);
final MyObject obj = ((MyObject) cls.alloc()).init();
// direct descr
assertEquals("foo", Utils.get().strings().javaString(obj.description()));
// indirect (from native) descr
{
MsgSend msgSend = new MsgSend(runtime, "description", IDCoder.INST);
msgSend.init(ctx, obj);
msgSend.invoke(ctx);
assertEquals("foo", Utils.get().strings().javaString((NSString) IDCoder.INST.pop(ctx)));
}
// indirect (from native) descr
{
MsgSendSuper msgSendSuper = new MsgSendSuper(runtime, "description", IDCoder.INST);
msgSendSuper.init(ctx, obj, cls);
msgSendSuper.invoke(ctx);
assertEquals("foo", Utils.get().strings().javaString((NSString) IDCoder.INST.pop(ctx)));
}
// nso descr
{
MsgSendSuper msgSendSuper = new MsgSendSuper(runtime, "description", IDCoder.INST);
msgSendSuper.init(ctx, obj, JObjC.getInstance().Foundation().NSObject());
msgSendSuper.invoke(ctx);
final NSString nsod = (NSString) IDCoder.INST.pop(ctx);
String jde = Utils.get().strings().javaString(nsod);
assertEquals(jde.substring(0, 9), "<MyObject");
}
}
public void testPerformSelector(){
final MyObject instObj = new MyObjectClass(runtime).alloc();
assertEquals(0, instObj.myMethodHits);
instObj.performSelector(new SEL("myMethod"));
assertEquals(1, instObj.myMethodHits);
instObj.performSelectorOnMainThread_withObject_waitUntilDone(
new SEL("myMethod"), null, true);
assertEquals(2, instObj.myMethodHits);
}
public void testVoidIntMethod(){
final MyObject instObj = new MyObjectClass(runtime).alloc();
MsgSend sel2 = new MsgSend(runtime, "intMethod", SIntCoder.INST);
sel2.init(ctx, instObj);
sel2.invoke(ctx);
int ret = SIntCoder.INST.popInt(ctx);
assertEquals(3, ret);
}
public void testStructStructMethod(){
final MyObject instObj = new MyObjectClass(runtime).alloc();
NSPoint p = JObjC.getInstance().Foundation().NSMakePoint(3, 3);
MsgSend sel2 = new MsgSend(runtime, "doubleIt:", p.getCoder(), p.getCoder());
sel2.init(ctx, instObj);
p.getCoder().push(ctx, p);
sel2.invoke(ctx, p);
assertEquals(6.0, p.x());
}
public void testNSStringNSStringMethod(){
final MyObject instObj = new MyObjectClass(runtime).alloc();
final NSString orig = Utils.get().strings().nsString("foobar");
final String expected = "foobarfoobarfoobar";
final MsgSend sel = new MsgSend(runtime, "stringTimesThree:", IDCoder.INST, IDCoder.INST);
sel.init(ctx, instObj);
IDCoder.INST.push(ctx, orig);
sel.invoke(ctx);
NSString ret = (NSString) IDCoder.INST.pop(ctx);
assertEquals(expected, Utils.get().strings().javaString(ret));
}
public void testDoubleIntLongMethod(){
final MyObject instObj = new MyObjectClass(runtime).alloc();
final int arg1 = 3;
final long arg2 = 4;
final float arg3 = 5.5F;
final double expected = 12.5D;
final MsgSend sel = new MsgSend(runtime, "add:and:and:", DoubleCoder.INST,
SIntCoder.INST, SLongLongCoder.INST, FloatCoder.INST);
sel.init(ctx, instObj);
SIntCoder.INST.push(ctx, arg1);
SLongLongCoder.INST.push(ctx, arg2);
FloatCoder.INST.push(ctx, arg3);
sel.invoke(ctx);
final double ret = DoubleCoder.INST.pop(ctx);
assertEquals(expected, ret);
}
public static void main(String[] args){
junit.textui.TestRunner.run(SubclassingTest.class);
}
}
class MyObject extends NSObject{
public MyObject(long objPtr, JObjCRuntime runtime) {
super(objPtr, runtime);
}
public int myMethodHits = 0;
public void myMethod(){
myMethodHits++;
}
public int intMethod(){
return 3;
}
public NSString stringTimesThree(NSString nss){
int count = 3;
String jss = Utils.get().strings().javaString(nss);
String js2 = "";
while(count-- > 0)
js2 += jss;
return Utils.get().strings().nsString(js2);
}
public double add_and_and(int a, long b, float c){
return a + b + c;
}
public NSPoint doubleIt(NSPoint p){
System.out.println("Doubling NSPoint(" + p.x() + ", " + p.y() + ").");
p.setX(p.x() * 2);
p.setY(p.y() * 2);
return p;
}
@Override public NSString description(){
return Utils.get().strings().nsString("foo");
}
}
class MyObjectClass extends NSObjectClass{
protected MyObjectClass(String name, JObjCRuntime runtime) {
super(name, runtime);
}
public MyObjectClass(JObjCRuntime runtime){
this("MyObject", runtime);
}
}