| /* |
| * 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); |
| } |
| } |