Skip to content

Commit

Permalink
Merge pull request #52 from /issues/50-tests
Browse files Browse the repository at this point in the history
Pass method signature to allow determining if vararg send should be used
  • Loading branch information
dkocher authored Feb 19, 2025
2 parents fe0eb0c + 9c3fecd commit 511adc8
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 17 deletions.
15 changes: 10 additions & 5 deletions rococoa/rococoa-core/src/main/java/org/rococoa/Rococoa.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.rococoa;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import net.bytebuddy.ByteBuddy;
Expand Down Expand Up @@ -53,13 +54,17 @@ public abstract class Rococoa {
public static <T extends ObjCClass> T createClass(String ocClassName, Class<T> type) {
return wrap(Foundation.getClass(ocClassName), type, false);
}

/**
* Create a Java NSObject representing an instance of the Objective-C class
* ocClassName. The Objective-C instance is created by calling the static
* factory method named ocMethodName, passing args.
*/
public static <T extends ObjCObject> T create(String ocClassName, Class<T> javaClass, String ocMethodName, Object... args) {
return create(ocClassName, javaClass, null, ocMethodName, args);
}

public static <T extends ObjCObject> T create(String ocClassName, Class<T> javaClass, Method method, String ocMethodName, Object... args) {
boolean weOwnObject = Foundation.selectorNameMeansWeOwnReturnedObject(ocMethodName);

// If we don't own the object we know that it has been autorelease'd
Expand All @@ -68,7 +73,7 @@ public static <T extends ObjCObject> T create(String ocClassName, Class<T> javaC
// Objects that we own (because they were created with 'alloc' or 'new')
// have not been autorelease'd, so we don't retain them.
boolean retain = !weOwnObject;
return create(ocClassName, javaClass, ocMethodName, retain, args);
return create(ocClassName, javaClass, method, ocMethodName, retain, args);
}

/**
Expand All @@ -79,16 +84,16 @@ public static <T extends ObjCObject> T create(String ocClassName, Class<T> javaC
return create(ocClassName, javaClass, "new");
}

private static <T extends ObjCObject> T create(String ocClassName, Class<T> javaClass,
String ocFactoryName,
private static <T extends ObjCObject> T create(String ocClassName, Class<T> javaClass, Method method,
String ocFactoryName,
boolean retain,
Object... args) {
if (logging.isLoggable(Level.FINEST)) {
logging.finest(String.format("creating [%s (%s)].%s(%s)",
ocClassName, javaClass.getName(), ocFactoryName, new VarArgsUnpacker(args)));
}
ID ocClass = Foundation.getClass(ocClassName);
ID ocInstance = Foundation.send(ocClass, ocFactoryName, ID.class, args);
ID ocInstance = Foundation.send(ocClass, ocFactoryName, ID.class, method, args);
CFIndex initialRetainCount = Foundation.cfGetRetainCount(ocInstance);
T result = wrap(ocInstance, javaClass, retain);
checkRetainCount(ocInstance, retain ? initialRetainCount.intValue() + 1 : initialRetainCount.intValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public abstract class NSArray extends NSObject {

public static final _Class CLASS = Rococoa.createClass("NSArray", _Class.class); //$NON-NLS-1$
public interface _Class extends ObjCClass {
NSArray arrayWithObject(NSObject anObject);
/**
* @param objects Contents and then a trailing null
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.rococoa;

import org.junit.Ignore;
import org.junit.Test;
import org.rococoa.cocoa.foundation.*;
import org.rococoa.test.RococoaTestCase;
Expand All @@ -34,17 +33,26 @@ public class RococoaObjectOwnershipTest extends RococoaTestCase {
public static boolean shouldNotBeInPool = false;

@Test
public void directFactoryMethodsReturnsYieldsPooledObject() {
public void directFactoryMethodsReturnsYieldsPooledObject() throws Exception {
check(shouldBeInPool,
new Factory() {
public NSArray create() {
return Rococoa.create("NSArray", NSArray.class, "arrayWithObjects:", NSNumber.CLASS.numberWithInt(0));
public NSArray create() throws Exception {
return Rococoa.create("NSArray", NSArray.class,
NSArray._Class.class.getMethod("arrayWithObjects", NSObject[].class),
"arrayWithObjects:", NSNumber.CLASS.numberWithInt(0));
}
});
check(shouldBeInPool,
new Factory() {
public NSArray create() throws Exception {
return Rococoa.create("NSArray", NSArray.class,
"arrayWithObject:", NSNumber.CLASS.numberWithInt(0));
}
});
}

@Test
public void factoryMethodOnClassYieldsPooledObject() {
public void factoryMethodOnClassYieldsPooledObject() throws Exception {
check(shouldBeInPool,
new Factory() {
public NSArray create() {
Expand All @@ -54,8 +62,7 @@ public NSArray create() {
}

@Test
@Ignore
public void createYieldsNonPooledObject() {
public void createYieldsNonPooledObject() throws Exception {
check(shouldNotBeInPool,
new Factory() {
public NSDate create() {
Expand All @@ -65,8 +72,7 @@ public NSDate create() {
}

@Test
@Ignore
public void newYieldsNonPooledObject() {
public void newYieldsNonPooledObject() throws Exception {
// calling new on an NSClass results in a NOT autorelease'd object
check(shouldNotBeInPool,
new Factory() {
Expand All @@ -77,7 +83,7 @@ public NSArray create() {
}

@Test
public void allocYieldsNonPooledObject() {
public void allocYieldsNonPooledObject() throws Exception {
// calling alloc on an NSClass results in a NOT autorelease'd object
check(shouldNotBeInPool,
new Factory() {
Expand All @@ -89,10 +95,10 @@ public NSObject create() {
}

private interface Factory {
NSObject create();
NSObject create() throws Exception;
}

private void check(boolean expectedAutorelease, Factory factory) {
private void check(boolean expectedAutorelease, Factory factory) throws Exception {
int expectedInitialRetainCount = expectedAutorelease ? 2 : 1;
// that will decrease the count IF it was pooled
int expectedFinalRetainCount = expectedAutorelease ?
Expand Down

0 comments on commit 511adc8

Please sign in to comment.