Skip to content

Commit

Permalink
Fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
0x4a616e committed Nov 21, 2020
1 parent 24c99d7 commit 4412e69
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 24 deletions.
63 changes: 49 additions & 14 deletions src/main/java/de/jangassen/jfa/FoundationProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,26 @@
import java.lang.reflect.Parameter;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static de.jangassen.jfa.foundation.Foundation.getObjcClass;

public class FoundationProxy implements InvocationHandler {
private final ID id;
private static final String EQUALS = "equals";
private static final String HASH_CODE = "hashCode";
private static final String TO_STRING = "toString";
private static final String DESCRIPTION = "description";

private final ID id;

public static <T extends NSObject> T alloc(Class<T> clazz) {
ID instance = Foundation.invoke(getObjcClass(clazz.getSimpleName()), "alloc");
return invokeStatic(clazz, "alloc");
}

public static <T extends NSObject> T invokeStatic(Class<T> clazz, String selector) {
ID instance = Foundation.invoke(getObjcClass(clazz.getSimpleName()), selector);
return wrap(instance, clazz);
}

Expand All @@ -38,25 +47,37 @@ private ID getId() {

@Override
public Object invoke(Object proxy, Method method, Object[] args) {
if (method.getName().equals("equals")) {
return false;
} else if (method.getName().equals("hashCode")) {
return id.hashCode();
}
if (method.getName().equals("toString")) {
return Foundation.toStringViaUTF8(Foundation.invoke(id, "description"));
}
switch (method.getName()) {
case EQUALS:
return isFoundationProxy(args[0]) && Objects.equals(getId(), getIdFromProxy(args[0]));
case HASH_CODE:
return id.hashCode();
case TO_STRING:
return Foundation.toStringViaUTF8(Foundation.invoke(id, DESCRIPTION));
default:
return invokeNative(method, args);
}
}

private Object invokeNative(Method method, Object[] args) {
Object[] foundationArguments = getFoundationArguments(args);
String selector = getSelector(method);

ID result = Foundation.safeInvoke(id, selector, foundationArguments);
if (Foundation.isNil(result)) {
if (!isPrimitiveType(method.getReturnType()) && Foundation.isNil(result)) {
return null;
}
return wrapReturnValue(method, result);
}

private boolean isPrimitiveType(Class<?> returnType) {
return boolean.class == returnType
|| int.class == returnType
|| long.class == returnType
|| double.class == returnType
|| float.class == returnType;
}

private String getSelector(Method method) {
if (method.getParameterCount() == 0) {
return method.getName();
Expand Down Expand Up @@ -88,6 +109,12 @@ private Object wrapReturnValue(Method method, ID result) {
return result.longValue();
} else if (int.class == returnType || Integer.class == returnType) {
return result.longValue();
} else if (double.class == returnType || Double.class == returnType) {
return result.doubleValue();
} else if (float.class == returnType || Float.class == returnType) {
return result.floatValue();
} else if (boolean.class == returnType || Boolean.class == returnType) {
return result.booleanValue();
}

return result;
Expand All @@ -100,13 +127,21 @@ private Object[] getFoundationArguments(Object[] args) {
private Object toFoundationArgument(Object arg) {
if (arg == null) {
return ID.NIL;
} else if (Proxy.isProxyClass(arg.getClass()) && Proxy.getInvocationHandler(arg) instanceof FoundationProxy) {
return ((FoundationProxy) Proxy.getInvocationHandler(arg)).getId();
} else if (isFoundationProxy(arg)) {
return getIdFromProxy(arg);
} else if (arg instanceof String) {
return Foundation.nsString((String) arg);
}

return arg;
}

private ID getIdFromProxy(Object arg) {
return ((FoundationProxy) Proxy.getInvocationHandler(arg)).getId();
}

private boolean isFoundationProxy(Object arg) {
return Proxy.isProxyClass(arg.getClass()) && Proxy.getInvocationHandler(arg) instanceof FoundationProxy;
}
}

7 changes: 3 additions & 4 deletions src/main/java/de/jangassen/jfa/appkit/NSApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


import de.jangassen.jfa.FoundationProxy;
import de.jangassen.jfa.foundation.ID;

import static de.jangassen.jfa.foundation.Foundation.getObjcClass;
import static de.jangassen.jfa.foundation.Foundation.invoke;
Expand All @@ -17,9 +18,7 @@ static NSApplication sharedApplication() {

void setMainMenu(NSMenu mainMenu);

void hide();
void hide(ID sender);

void hideOtherApplications();

void unhideAllApplications();
void unhide(ID sender);
}
6 changes: 3 additions & 3 deletions src/main/java/de/jangassen/jfa/appkit/NSMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ static NSMenu alloc() {

NSMenu init();

NSMenu initWithTitle(@NamedArg("title") String title);
NSMenu initWithTitle(String title);

void setTitle(String title);

Expand All @@ -26,9 +26,9 @@ static NSMenu alloc() {

void addItem(NSMenuItem item);

void insertItem(NSMenuItem item, int index);
void insertItem(NSMenuItem item, @NamedArg("atIndex") int index);

NSMenuItem itemAtIndex(int index);

long numberOfItems();
}
15 changes: 15 additions & 0 deletions src/main/java/de/jangassen/jfa/appkit/NSWorkspace.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package de.jangassen.jfa.appkit;


import de.jangassen.jfa.FoundationProxy;

import static de.jangassen.jfa.foundation.Foundation.getObjcClass;
import static de.jangassen.jfa.foundation.Foundation.invoke;

public interface NSWorkspace extends NSObject {
static NSWorkspace sharedWorkspace() {
return FoundationProxy.wrap(invoke(getObjcClass("NSWorkspace"), "sharedWorkspace"), NSWorkspace.class);
}

void hideOtherApplications();
}
18 changes: 15 additions & 3 deletions src/main/java/de/jangassen/jfa/foundation/Foundation.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,21 @@ public final class Foundation {
private static final Function myObjcMsgSend;

static {
myFoundationLibrary = Native.load("Foundation", FoundationLibrary.class, Collections.singletonMap("jna.encoding", "UTF8"));
NativeLibrary nativeLibrary = ((Library.Handler) Proxy.getInvocationHandler(myFoundationLibrary)).getNativeLibrary();
myObjcMsgSend = nativeLibrary.getFunction("objc_msgSend");
FoundationLibrary foundationLibrary = null;
Function objcMsgSend = null;
try {
foundationLibrary = Native.load("Foundation", FoundationLibrary.class, Collections.singletonMap("jna.encoding", "UTF8"));
NativeLibrary nativeLibrary = ((Library.Handler) Proxy.getInvocationHandler(foundationLibrary)).getNativeLibrary();
objcMsgSend = nativeLibrary.getFunction("objc_msgSend");
} catch (RuntimeException e) {
// Foundation not available
}
myFoundationLibrary = foundationLibrary;
myObjcMsgSend = objcMsgSend;
}

public static boolean isAvailable() {
return myFoundationLibrary != null && myObjcMsgSend != null;
}

public static void init() { /* fake method to init de.jangassen.foundation */ }
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/de/jangassen/jfa/appkit/NSApplicationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package de.jangassen.jfa.appkit;

import org.junit.Assert;
import org.junit.Test;

public class NSApplicationTest {
@Test
public void getSharedApplication() {
NSApplication app = NSApplication.sharedApplication();

Assert.assertNotNull(app);
}
}
33 changes: 33 additions & 0 deletions src/test/java/de/jangassen/jfa/appkit/NSMenuItemTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package de.jangassen.jfa.appkit;

import org.junit.Assert;
import org.junit.Test;

public class NSMenuItemTest {

@Test
public void createMenuItem() {
NSMenuItem item = NSMenuItem.alloc();

Assert.assertNotNull(item);
Assert.assertFalse(item.hasSubmenu());
}

@Test
public void initMenuItem() {
NSMenuItem item = NSMenuItem.alloc().initWithTitle("Test", null, "");

Assert.assertNotNull(item);
Assert.assertEquals("Test", item.title());
}

@Test
public void addSubmenu() {
NSMenuItem item = NSMenuItem.alloc().initWithTitle("Test", null, "");
NSMenu submenu = NSMenu.alloc().initWithTitle("test");
item.setSubmenu(submenu);

Assert.assertNotNull(item);
Assert.assertTrue(item.hasSubmenu());
}
}
71 changes: 71 additions & 0 deletions src/test/java/de/jangassen/jfa/appkit/NSMenuTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package de.jangassen.jfa.appkit;

import org.junit.Assert;
import org.junit.Test;

public class NSMenuTest {
@Test
public void createMenu() {
NSMenu menu = NSMenu.alloc().initWithTitle("title");

Assert.assertNotNull(menu);
Assert.assertEquals("title", menu.title());
}

@Test
public void addMenuItem() {
NSMenu menu = NSMenu.alloc().initWithTitle("title");
NSMenuItem menuItem = NSMenuItem.alloc().initWithTitle("title", null, "");

menu.addItem(menuItem);
NSMenuItem item = menu.itemAtIndex(0);

Assert.assertEquals("title", menuItem.title());
Assert.assertEquals(item, menuItem);
}

@Test
public void insertMenuItem() {
NSMenu menu = NSMenu.alloc().initWithTitle("title");
NSMenuItem menuItem = NSMenuItem.alloc().initWithTitle("title", null, "");

menu.insertItem(menuItem, 0);
NSMenuItem item = menu.itemAtIndex(0);

Assert.assertEquals("title", menuItem.title());
Assert.assertEquals(item, menuItem);
}

@Test
public void RemoveMenuItem() {
NSMenu menu = NSMenu.alloc().initWithTitle("title");
NSMenuItem menuItem = NSMenuItem.alloc().initWithTitle("title", null, "");

menu.addItem(menuItem);
menu.removeItem(menuItem);

Assert.assertEquals(0, menu.numberOfItems());
}

@Test
public void removeMenuItemAtIndex() {
NSMenu menu = NSMenu.alloc().initWithTitle("title");
NSMenuItem menuItem = NSMenuItem.alloc().initWithTitle("title", null, "");

menu.addItem(menuItem);
menu.removeItemAtIndex(0);

Assert.assertEquals(0, menu.numberOfItems());
}

@Test
public void removeAllItems() {
NSMenu menu = NSMenu.alloc().initWithTitle("title");
NSMenuItem menuItem = NSMenuItem.alloc().initWithTitle("title", null, "");

menu.addItem(menuItem);
menu.removeAllItems();

Assert.assertEquals(0, menu.numberOfItems());
}
}

0 comments on commit 4412e69

Please sign in to comment.