Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 30c127697c13
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: feb3c574ac2e
Choose a head ref
  • 10 commits
  • 10 files changed
  • 1 contributor

Commits on Apr 1, 2016

  1. Copy the full SHA
    afd765a View commit details
  2. Copy the full SHA
    6e3c07d View commit details
  3. [ji] support (value equality) == of Ruby arrays to Java arrays

    ... this is consistent since we already seamlessly convert Ruby arrays to Java ones
    kares committed Apr 1, 2016
    Copy the full SHA
    cf8c486 View commit details
  4. Copy the full SHA
    6c68d71 View commit details
  5. Copy the full SHA
    955395f View commit details
  6. Copy the full SHA
    808784c View commit details
  7. [ji] handle 2.3 #dig on Java arrays - could be useful for digging out…

    … nested Java arrays
    
    ... potentially mixed up with / wrapped in Ruby arrays
    kares committed Apr 1, 2016
    Copy the full SHA
    1150a01 View commit details
  8. initialize cause for Java class loading errors so that its easier to …

    …identify the issue
    
    ... esp. in embed mode where RaiseException will show the cause on err
    kares committed Apr 1, 2016
    Copy the full SHA
    d8920ad View commit details
  9. cleanup NativeException - improve joined Java+Ruby backtrace generation

    ... (without a lot of copying due previous RubyArray unshift-ing)
    kares committed Apr 1, 2016
    Copy the full SHA
    d2a1ed3 View commit details
  10. Copy the full SHA
    feb3c57 View commit details
49 changes: 30 additions & 19 deletions core/src/main/java/org/jruby/NativeException.java
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@ public NativeException(Ruby runtime, RubyClass rubyClass, Throwable cause) {
private NativeException(Ruby runtime, RubyClass rubyClass) {
super(runtime, rubyClass);
this.cause = new Throwable();
this.message = runtime.newString();
this.message = RubyString.newEmptyString(runtime);
}

private static ObjectAllocator NATIVE_EXCEPTION_ALLOCATOR = new ObjectAllocator() {
@@ -72,32 +72,43 @@ public static RubyClass createClass(Ruby runtime, RubyClass baseClass) {
}

@JRubyMethod
public final IRubyObject cause() {
return Java.getInstance(getRuntime(), getCause());
}

@Deprecated
public IRubyObject cause(Block unusedBlock) {
return Java.getInstance(getRuntime(), cause);
return cause();
}

public IRubyObject backtrace() {
@Override
public final IRubyObject backtrace() {
IRubyObject rubyTrace = super.backtrace();
if (rubyTrace.isNil()) {
return rubyTrace;
}
if ( rubyTrace.isNil() ) return rubyTrace;

final Ruby runtime = getRuntime();
RubyArray array = (RubyArray) rubyTrace.dup();
StackTraceElement[] stackTrace = cause.getStackTrace();
for (int i = stackTrace.length - 1; i >= 0; i--) {
StackTraceElement element = stackTrace[i];
final RubyArray rTrace = (RubyArray) rubyTrace;
StackTraceElement[] jTrace = cause.getStackTrace();
final IRubyObject[] trace = new IRubyObject[jTrace.length + rTrace.size()];
final StringBuilder line = new StringBuilder(32);
for ( int i = 0; i < jTrace.length; i++ ) {
StackTraceElement element = jTrace[i];
final String className = element.getClassName();
final String line;
line.setLength(0);
if (element.getFileName() == null) {
line = className + ':' + element.getLineNumber() + ":in `" + element.getMethodName() + '\'';
line.append(className).append(':').append(element.getLineNumber()).append(":in `").append(element.getMethodName()).append('\'');
} else {
final int index = className.lastIndexOf('.');
final String packageName = index == -1 ? "" : className.substring(0, index) + '/';
line = packageName.replace('.', '/') + element.getFileName() + ':' + element.getLineNumber() + ":in `" + element.getMethodName() + '\'';
if ( index > - 1 ) {
line.append(className.substring(0, index).replace('.', '/'));
line.append('/');
}
line.append(element.getFileName()).append(':').append(element.getLineNumber()).append(":in `").append(element.getMethodName()).append('\'');
}
array.unshift(runtime.newString(line));
trace[i] = RubyString.newString(runtime, line.toString());
}
return array;
System.arraycopy(rTrace.toJavaArrayMaybeUnsafe(), 0, trace, jTrace.length, rTrace.size());
return RubyArray.newArrayNoCopy(runtime, trace);
}

@Deprecated // not used
@@ -155,9 +166,9 @@ private static String searchStackMessage(Throwable cause) {
String message;
do {
message = cause.getMessage();
if ( message != null ) return message;
cause = cause.getCause();
} while (message == null && cause != null);

return message;
} while ( cause != null );
return null;
}
}
30 changes: 16 additions & 14 deletions core/src/main/java/org/jruby/RubyBasicObject.java
Original file line number Diff line number Diff line change
@@ -1189,32 +1189,28 @@ public int compareTo(IRubyObject other) {
return 0;
}

@Override
public IRubyObject op_equal(ThreadContext context, IRubyObject obj) {
return op_equal_19(context, obj);
}

/** rb_obj_equal
*
* Will by default use identity equality to compare objects. This
* follows the Ruby semantics.
*
* The name of this method doesn't follow the convention because hierarchy problems
*/
@Override
@JRubyMethod(name = "==")
public IRubyObject op_equal_19(ThreadContext context, IRubyObject obj) {
public IRubyObject op_equal(ThreadContext context, IRubyObject obj) {
return this == obj ? context.runtime.getTrue() : context.runtime.getFalse();
}

@Deprecated
public IRubyObject op_equal_19(ThreadContext context, IRubyObject obj) {
return op_equal(context, obj);
}

@Override
public IRubyObject op_eqq(ThreadContext context, IRubyObject other) {
// Remain unimplemented due to problems with the double java hierarchy
return context.runtime.getNil();
}

@JRubyMethod(name = "equal?", required = 1)
public IRubyObject equal_p19(ThreadContext context, IRubyObject other) {
return op_equal_19(context, other);
return context.nil;
}

/**
@@ -1931,8 +1927,14 @@ private void callFinalizer(IRubyObject finalizer) {
*
* Will use Java identity equality.
*/
public IRubyObject equal_p(ThreadContext context, IRubyObject obj) {
return this == obj ? context.runtime.getTrue() : context.runtime.getFalse();
@JRubyMethod(name = "equal?", required = 1)
public IRubyObject equal_p(ThreadContext context, IRubyObject other) {
return this == other ? context.runtime.getTrue() : context.runtime.getFalse();
}

@Deprecated
public IRubyObject equal_p19(ThreadContext context, IRubyObject other) {
return equal_p(context, other);
}

/** rb_obj_equal
20 changes: 9 additions & 11 deletions core/src/main/java/org/jruby/RubyBignum.java
Original file line number Diff line number Diff line change
@@ -638,6 +638,7 @@ public IRubyObject op_pow19(ThreadContext context, IRubyObject other) {
/** rb_big_and
*
*/
@JRubyMethod(name = "&", required = 1)
public IRubyObject op_and(ThreadContext context, IRubyObject other) {
if (other instanceof RubyBignum) {
return bignorm(getRuntime(), value.and(((RubyBignum) other).value));
@@ -647,14 +648,14 @@ public IRubyObject op_and(ThreadContext context, IRubyObject other) {
return coerceBit(context, "&", other);
}

@JRubyMethod(name = "&", required = 1)
public IRubyObject op_and19(ThreadContext context, IRubyObject other) {
return op_and(context, other);
}

/** rb_big_or
*
*/
@JRubyMethod(name = "|", required = 1)
public IRubyObject op_or(ThreadContext context, IRubyObject other) {
if (other instanceof RubyBignum) {
return bignorm(getRuntime(), value.or(((RubyBignum) other).value));
@@ -665,14 +666,14 @@ public IRubyObject op_or(ThreadContext context, IRubyObject other) {
return coerceBit(context, "|", other);
}

@JRubyMethod(name = "|", required = 1)
public IRubyObject op_or19(ThreadContext context, IRubyObject other) {
return op_or(context, other);
}

/** rb_big_xor
*
*/
@JRubyMethod(name = "^", required = 1)
public IRubyObject op_xor(ThreadContext context, IRubyObject other) {
if (other instanceof RubyBignum) {
return bignorm(getRuntime(), value.xor(((RubyBignum) other).value));
@@ -682,8 +683,7 @@ public IRubyObject op_xor(ThreadContext context, IRubyObject other) {
}
return coerceBit(context, "^", other);
}

@JRubyMethod(name = "^", required = 1)

public IRubyObject op_xor19(ThreadContext context, IRubyObject other) {
return op_xor(context, other);
}
@@ -850,23 +850,21 @@ public IRubyObject op_equal(IRubyObject other) {
*
*/
@Override
@JRubyMethod(name = {"==="}, required = 1)
public IRubyObject eql_p(IRubyObject other) {
return eql_p19(other);
// '==' and '===' are the same, but they differ from 'eql?'.
return op_equal(other);
}

/**
* In ruby 1.9, '==' and '===' are the same, but they differ from 'eql?'.
*/
@JRubyMethod(name = {"==="}, required = 1)
public IRubyObject eql_p19(IRubyObject other) {
return op_equal(other);
return eql_p(other);
}

/** rb_big_hash
*
*/
@JRubyMethod(name = "hash")
@Override
@JRubyMethod(name = "hash")
public RubyFixnum hash() {
return getRuntime().newFixnum(value.hashCode());
}
45 changes: 14 additions & 31 deletions core/src/main/java/org/jruby/RubyFixnum.java
Original file line number Diff line number Diff line change
@@ -159,11 +159,6 @@ public final boolean eql(IRubyObject other) {

@Override
public IRubyObject equal_p(ThreadContext context, IRubyObject obj) {
return equal_p19(context, obj);
}

@Override
public IRubyObject equal_p19(ThreadContext context, IRubyObject obj) {
return context.runtime.newBoolean(this == obj || eql(obj));
}

@@ -428,7 +423,7 @@ private IRubyObject addOther(ThreadContext context, IRubyObject other) {
@JRubyMethod(name = "-")
public IRubyObject op_minus(ThreadContext context, IRubyObject other) {
if (other instanceof RubyFixnum) {
return subtractFixnum(context, (RubyFixnum)other);
return subtractFixnum(context, (RubyFixnum) other);
}
return subtractOther(context, other);
}
@@ -490,7 +485,7 @@ private IRubyObject subtractOther(ThreadContext context, IRubyObject other) {
@JRubyMethod(name = "*")
public IRubyObject op_mul(ThreadContext context, IRubyObject other) {
if (other instanceof RubyFixnum) {
return op_mul(context, ((RubyFixnum)other).value);
return op_mul(context, ((RubyFixnum) other).value);
} else {
return multiplyOther(context, other);
}
@@ -630,7 +625,7 @@ private IRubyObject idivLong(ThreadContext context, long x, long y) {
public IRubyObject op_mod(ThreadContext context, IRubyObject other) {
checkZeroDivisionError(context, other);
if (other instanceof RubyFixnum) {
return moduloFixnum(context, (RubyFixnum)other);
return moduloFixnum(context, (RubyFixnum) other);
}
return coerceBin(context, "%", other);
}
@@ -893,7 +888,7 @@ private int compareToOther(IRubyObject other) {
@JRubyMethod(name = "<=>")
public IRubyObject op_cmp(ThreadContext context, IRubyObject other) {
return other instanceof RubyFixnum ?
op_cmp(context, ((RubyFixnum)other).value) : compareOther(context, other);
op_cmp(context, ((RubyFixnum) other).value) : compareOther(context, other);
}

public IRubyObject op_cmp(ThreadContext context, long other) {
@@ -907,7 +902,7 @@ private IRubyObject compareOther(ThreadContext context, IRubyObject other) {
return newFixnum(context.runtime, BigInteger.valueOf(value).compareTo(((RubyBignum)other).getValue()));
}
if (other instanceof RubyFloat) {
return dbl_cmp(context.runtime, (double)value, ((RubyFloat)other).getDoubleValue());
return dbl_cmp(context.runtime, (double) value, ((RubyFloat) other).getDoubleValue());
}
return coerceCmp(context, "<=>", other);
}
@@ -979,7 +974,7 @@ private IRubyObject op_geOther(ThreadContext context, IRubyObject other) {
@JRubyMethod(name = "<")
public IRubyObject op_lt(ThreadContext context, IRubyObject other) {
if (other instanceof RubyFixnum) {
return op_lt(context, ((RubyFixnum)other).value);
return op_lt(context, ((RubyFixnum) other).value);
}
return op_ltOther(context, other);
}
@@ -1046,7 +1041,11 @@ public IRubyObject op_neg() {
*/
@JRubyMethod(name = "&")
public IRubyObject op_and(ThreadContext context, IRubyObject other) {
return op_and19(context, other);
if (!((other = bitCoerce(context, other)) instanceof RubyFixnum)) {
return ((RubyBignum) other).op_and(context, this);
}

return op_andOther(context, other);
}

private IRubyObject op_andOther(ThreadContext context, IRubyObject other) {
@@ -1060,14 +1059,6 @@ public IRubyObject op_and(ThreadContext context, long other) {
return newFixnum(context.runtime, value & other);
}

private IRubyObject op_and19(ThreadContext context, IRubyObject other) {
if (!((other = bitCoerce(context, other)) instanceof RubyFixnum)) {
return ((RubyBignum) other).op_and(context, this);
}

return op_andOther(context, other);
}

/** fix_or
*
*/
@@ -1089,10 +1080,9 @@ public IRubyObject op_or(ThreadContext context, long other) {
*/
@JRubyMethod(name = "^")
public IRubyObject op_xor(ThreadContext context, IRubyObject other) {
return op_xor19(context, other);
}

private IRubyObject op_xor18(ThreadContext context, IRubyObject other) {
if (!((other = bitCoerce(context, other)) instanceof RubyFixnum)) {
return ((RubyBignum) other).op_xor(context, this);
}
if (other instanceof RubyFixnum || (other = fixCoerce(other)) instanceof RubyFixnum) {
return newFixnum(context.runtime, value ^ ((RubyFixnum) other).value);
}
@@ -1103,13 +1093,6 @@ public IRubyObject op_xor(ThreadContext context, long other) {
return newFixnum(context.runtime, value ^ other);
}

private IRubyObject op_xor19(ThreadContext context, IRubyObject other) {
if (!((other = bitCoerce(context, other)) instanceof RubyFixnum)) {
return ((RubyBignum) other).op_xor(context, this);
}
return op_xor18(context, other);
}

/** fix_aref
*
*/
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyObject.java
Original file line number Diff line number Diff line change
@@ -517,7 +517,7 @@ public static RubyString inspect(ThreadContext context, IRubyObject object) {
}

// MRI: rb_obj_dig
static IRubyObject dig(ThreadContext context, IRubyObject obj, IRubyObject[] args, int idx) {
public static IRubyObject dig(ThreadContext context, IRubyObject obj, IRubyObject[] args, int idx) {
if ( obj.isNil() ) return context.nil;
if ( obj instanceof RubyArray ) {
// TODO: cache somewhere
43 changes: 37 additions & 6 deletions core/src/main/java/org/jruby/java/proxies/ArrayJavaProxy.java
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
import org.jruby.RubyFixnum;
import org.jruby.RubyModule;
import org.jruby.RubyNumeric;
import org.jruby.RubyObject;
import org.jruby.RubyRange;
import org.jruby.RubyString;
import org.jruby.anno.JRubyMethod;
@@ -102,17 +103,27 @@ public void set(final int index, final Object value) {
}

@JRubyMethod(name = "[]", required = 1, rest = true)
public IRubyObject op_aref(ThreadContext context, IRubyObject[] args) {
public final IRubyObject op_aref(ThreadContext context, IRubyObject[] args) {
if ( args.length == 1 ) return op_aref(context, args[0]);
return getRange(context, args);
}

@JRubyMethod(name = "[]=")
public IRubyObject op_aset(ThreadContext context, IRubyObject index, IRubyObject value) {
public final IRubyObject op_aset(ThreadContext context, IRubyObject index, IRubyObject value) {
final int i = convertArrayIndex(index);
return ArrayUtils.asetDirect(context.runtime, getObject(), converter, i, value);
}

@JRubyMethod(name = "dig", required = 1, rest = true)
public final IRubyObject dig(ThreadContext context, IRubyObject[] args) {
return dig(context, args, 0);
}

final IRubyObject dig(ThreadContext context, IRubyObject[] args, int idx) {
final IRubyObject val = at(context, args[idx++]);
return idx == args.length ? val : RubyObject.dig(context, val, args, idx);
}

private static int convertArrayIndex(final IRubyObject index) {
if ( index instanceof JavaProxy ) {
return (Integer) index.toJava(Integer.class);
@@ -122,12 +133,14 @@ private static int convertArrayIndex(final IRubyObject index) {

@JRubyMethod
public IRubyObject at(ThreadContext context, IRubyObject index) {
return at(context, convertArrayIndex(index));
}

private final IRubyObject at(ThreadContext context, int i) {
final Ruby runtime = context.runtime;
final Object array = getObject();
final int length = Array.getLength(array);

int i = convertArrayIndex(index);

if ( i < 0 ) i = i + length;

if ( i >= 0 && i < length ) {
@@ -225,18 +238,36 @@ private StringBuilder arrayToString() {

@Override
@JRubyMethod(name = "==")
public RubyBoolean op_eqq(ThreadContext context, IRubyObject other) {
public RubyBoolean op_equal(ThreadContext context, IRubyObject other) {
if ( other instanceof RubyArray ) {
// we respond_to? to_ary thus shall handle [1].to_java == [1]
return context.runtime.newBoolean( equalsRubyArray((RubyArray) other) );
}
return eql_p(context, other);
}

private boolean equalsRubyArray(final RubyArray rubyArray) {
final Object thisArray = this.getObject();
final int len = rubyArray.size();
if ( len != Array.getLength(thisArray) ) return false;
final Class<?> componentType = thisArray.getClass().getComponentType();
for ( int i = 0; i < len; i++ ) {
final Object ruby = rubyArray.eltInternal(i).toJava(componentType);
final Object elem = Array.get(thisArray, i);
if ( ruby == null ) return elem == null;
if ( ! ruby.equals(elem) ) return false;
}
return true;
}

@JRubyMethod(name = "eql?")
public RubyBoolean eql_p(ThreadContext context, IRubyObject obj) {
boolean equals = false;
if ( obj instanceof ArrayJavaProxy ) {
final ArrayJavaProxy that = (ArrayJavaProxy) obj;
equals = arraysEquals(this.getObject(), that.getObject());
}
if ( obj.getClass().isArray() ) {
else if ( obj.getClass().isArray() ) {
equals = arraysEquals(getObject(), obj);
}
return context.runtime.newBoolean(equals);
17 changes: 10 additions & 7 deletions core/src/main/java/org/jruby/java/util/ArrayUtils.java
Original file line number Diff line number Diff line change
@@ -17,13 +17,16 @@
* A collection of utilities for manipulating Java arrays.
*/
public class ArrayUtils {

private ArrayUtils() { /* no instances */ }

public static IRubyObject arefDirect(Ruby runtime, Object array, JavaUtil.JavaConverter javaConverter, int intIndex) {
try {
return JavaUtil.convertJavaArrayElementToRuby(runtime, javaConverter, array, intIndex);
} catch (IndexOutOfBoundsException e) {
throw runtime.newArgumentError(
"index out of bounds for java array (" + intIndex +
" for length " + Array.getLength(array) + ")");
" for length " + Array.getLength(array) + ')');
}
}

@@ -96,15 +99,15 @@ public static IRubyObject asetDirect(Ruby runtime, Object array, JavaUtil.JavaCo
} catch (IndexOutOfBoundsException e) {
throw runtime.newArgumentError(
"index out of bounds for java array (" + intIndex +
" for length " + Array.getLength(array) + ")");
" for length " + Array.getLength(array) + ')');
} catch (ArrayStoreException e) {
throw runtime.newTypeError(
"wrong element type " + value.getClass() + "(array contains " +
array.getClass().getComponentType().getName() + ")");
array.getClass().getComponentType().getName() + ')');
} catch (IllegalArgumentException iae) {
throw runtime.newArgumentError(
"wrong element type " + value.getClass() + "(array contains " +
array.getClass().getComponentType().getName() + ")");
array.getClass().getComponentType().getName() + ')');
}
return value;
}
@@ -115,15 +118,15 @@ public static void setWithExceptionHandlingDirect(Ruby runtime, Object ary, int
} catch (IndexOutOfBoundsException e) {
throw runtime.newArgumentError(
"index out of bounds for java array (" + intIndex +
" for length " + Array.getLength(ary) + ")");
" for length " + Array.getLength(ary) + ')');
} catch (ArrayStoreException e) {
throw runtime.newTypeError(
"wrong element type " + javaObject.getClass() + "(array contains " +
ary.getClass().getComponentType().getName() + ")");
ary.getClass().getComponentType().getName() + ')');
} catch (IllegalArgumentException iae) {
throw runtime.newArgumentError(
"wrong element type " + javaObject.getClass() + "(array contains " +
ary.getClass().getComponentType().getName() + ")");
ary.getClass().getComponentType().getName() + ')');
}
}

38 changes: 21 additions & 17 deletions core/src/main/java/org/jruby/javasupport/JavaSupportImpl.java
Original file line number Diff line number Diff line change
@@ -157,32 +157,36 @@ public Class loadJavaClass(String className) throws ClassNotFoundException {
public Class loadJavaClassVerbose(String className) {
try {
return loadJavaClass(className);
} catch (ClassNotFoundException cnfExcptn) {
throw runtime.newNameError("cannot load Java class " + className, className, cnfExcptn);
} catch (ExceptionInInitializerError eiie) {
throw runtime.newNameError("cannot initialize Java class " + className, className, eiie);
} catch (LinkageError le) {
throw runtime.newNameError("cannot link Java class " + className + ", probable missing dependency: " + le.getLocalizedMessage(), className, le);
} catch (SecurityException se) {
if (runtime.isVerbose()) se.printStackTrace(runtime.getErrorStream());
throw runtime.newSecurityError(se.getLocalizedMessage());
} catch (ClassNotFoundException ex) {
throw initCause(runtime.newNameError("cannot load Java class " + className, className, ex), ex);
} catch (ExceptionInInitializerError ex) {
throw initCause(runtime.newNameError("cannot initialize Java class " + className, className, ex), ex);
} catch (LinkageError ex) {
throw initCause(runtime.newNameError("cannot link Java class " + className + ", probable missing dependency: " + ex.getLocalizedMessage(), className, ex), ex);
} catch (SecurityException ex) {
if (runtime.isVerbose()) ex.printStackTrace(runtime.getErrorStream());
throw initCause(runtime.newSecurityError(ex.getLocalizedMessage()), ex);
}
}

public Class loadJavaClassQuiet(String className) {
try {
return loadJavaClass(className);
} catch (ClassNotFoundException cnfExcptn) {
throw runtime.newNameError("cannot load Java class " + className, className, cnfExcptn, false);
} catch (ExceptionInInitializerError eiie) {
throw runtime.newNameError("cannot initialize Java class " + className, className, eiie, false);
} catch (LinkageError le) {
throw runtime.newNameError("cannot link Java class " + className, className, le, false);
} catch (SecurityException se) {
throw runtime.newSecurityError(se.getLocalizedMessage());
} catch (ClassNotFoundException ex) {
throw initCause(runtime.newNameError("cannot load Java class " + className, className, ex, false), ex);
} catch (ExceptionInInitializerError ex) {
throw initCause(runtime.newNameError("cannot initialize Java class " + className, className, ex, false), ex);
} catch (LinkageError ex) {
throw initCause(runtime.newNameError("cannot link Java class " + className, className, ex, false), ex);
} catch (SecurityException ex) {
throw initCause(runtime.newSecurityError(ex.getLocalizedMessage()), ex);
}
}

private static RaiseException initCause(final RaiseException ex, final Throwable cause) {
ex.initCause(cause); return ex;
}

public JavaClass getJavaClassFromCache(Class clazz) {
return javaClassCache.get(clazz);
}
3 changes: 2 additions & 1 deletion core/src/test/java/org/jruby/javasupport/TestJava.java
Original file line number Diff line number Diff line change
@@ -101,7 +101,8 @@ public void test_get_java_class() {
assert false;
}
catch (RaiseException ex) {
// assertNotNull(ex.getCause());
assertNotNull(ex.getCause());
assertEquals(ClassNotFoundException.class, ex.getCause().getClass());
}
}

144 changes: 144 additions & 0 deletions spec/java_integration/types/array_spec.rb
Original file line number Diff line number Diff line change
@@ -156,6 +156,26 @@
expect(arr.inspect).to match(/^byte\[1, 2, 3\]@[0-9a-f]+$/)
end

it 'handles equality to another array' do
arr1 = [ 1, -123, 127 ].to_java :byte
arr2 = Java::byte[3].new
arr2[0] = 1; arr2[2] = 127; arr2[1] = -123
expect( arr1 == arr2 ).to be true
expect( arr1.eql? arr2 ).to be true
expect( [ 1, -123, 127 ].to_java(:int).eql? arr2 ).to be false
expect( [ 1, -123, -127 ].to_java(:byte) == arr2 ).to be false

expect( arr1 === arr1 ).to be true
expect( arr2 === arr1 ).to be true
expect( arr1.class === arr2 ).to be true

expect( arr1 == [ 1, -123 ] ).to be false
expect( arr1 == [ 1, -123, 127 ] ).to be true
expect( [ 1, -123, 127 ] == arr2 ).to be true
expect( arr1.eql? [ 1, -123, 127 ] ).to be false
expect( arr2 === [ 1, -123, 127 ] ).to be true
end

it "makes an ascii 8 bit string on to_s" do
expect([86, 87].to_java(:byte).to_s).to eq("VW")
end
@@ -232,6 +252,23 @@
expect(arr.inspect).to match(/^char\[d, e, f\]@[0-9a-f]+$/)
end

it 'handles equality to another array' do
arr1 = [ 0, 111 ].to_java :char
arr2 = Java::char[2].new
arr2[0] = 0; arr2[1] = 111
expect( arr1 == arr2 ).to be true
expect( arr1.eql? arr2 ).to be true
expect( [ 0, 111 ].to_java(:int).eql? arr2 ).to be false
expect( [ 111 ].to_java(:char) == arr2 ).to be false
expect( [ 1, 111 ].to_java(:char) == arr2 ).to be false

expect( arr1 == [ 0 ] ).to be false
expect( arr1 == [ 0, 111 ] ).to be true
expect( [ 0, 111 ] == arr2 ).to be true
expect( arr1.eql? [ 0, 111 ] ).to be false
expect( arr2 === [ 0, 111 ] ).to be true
end

it "uses toString on to_s" do
arr = [100, 101, 102].to_java :char
expect(arr.to_s).to match(/\[C@[0-9a-f]+$/)
@@ -304,6 +341,22 @@
expect(ret.to_a).to eq([13.2, 42.3, 120.4])
end

it 'handles equality to another array' do
arr1 = [-111, 101010.99].to_java :double
arr2 = Java::double[2].new
arr2[0] = -111; arr2[1] = 101010.99
expect( arr1 == arr2 ).to be true
expect( arr1.eql? arr2 ).to be true
expect( [-111, 101010.99].to_java(:float).eql? arr2 ).to be false
expect( [ -111 ].to_java(:double) == arr2 ).to be false

expect( arr1 == [ -111 ] ).to be false
expect( arr1 == [ -111, 101010.99 ] ).to be true
expect( [ -111, 101010.99 ] == arr2 ).to be true
expect( arr1.eql? [ -111, 101010.99 ] ).to be false
expect( arr2 === [ -111, 101010.99 ] ).to be true
end

it "inspects to show type and contents" do
arr = [1.0, 1.1, 1.2].to_java :double
expect(arr.inspect).to match(/^double\[1\.0, 1\.1, 1\.2\]@[0-9a-f]+$/)
@@ -380,6 +433,27 @@
expect(ret[2]).to be_within(0.00001).of(120.4)
end

it 'handles equality to another array' do
arr1 = [-111, 101010.99].to_java :float
arr2 = Java::float[2].new
arr2[0] = -111; arr2[1] = 101010.99
expect( arr1 == arr2 ).to be true
expect( arr1.eql? arr2 ).to be true
expect( [-111, 101010.99].to_java(:double).eql? arr2 ).to be false
expect( arr1 == [ -111.1, 101010.99 ] ).to be false
expect( [ -111 ].to_java(:float) == arr2 ).to be false

expect( arr1 === arr1 ).to be true
expect( arr2 === arr1 ).to be true
expect( arr1.class === arr2 ).to be true

expect( arr1 == [ -111 ] ).to be false
expect( arr1 == [ -111, 101010.99 ] ).to be true
expect( [ -111, 101010.99 ] == arr2 ).to be true
expect( arr1.eql? [ -111, 101010.99 ] ).to be false
expect( arr1 === [ -111, 101010.99 ] ).to be true
end

it "inspects to show type and contents" do
arr = [1.0, 1.1, 1.2].to_java :float
expect(arr.inspect).to match(/^float\[1\.0, 1\.1, 1\.2\]@[0-9a-f]+$/)
@@ -452,6 +526,26 @@
expect(ret.to_a).to eq([13, 42, 120])
end

it 'handles equality to another array' do
arr1 = [-111, 12345678].to_java :int
arr2 = Java::int[2].new
arr2[0] = 111; arr2[1] = 12345678
arr2[0] = arr2[0] * -1
expect( arr1 == arr2 ).to be true
expect( arr1.eql? arr2 ).to be true
expect( [-111, 12345678].to_java(:long).eql? arr2 ).to be false
expect( [ -111 ].to_java(:int) == arr2 ).to be false

expect( arr1 == [ -111 ] ).to be false
expect( arr1 == [ -111, 12345678 ] ).to be true
expect( [ -111, 12345678 ] == arr2 ).to be true
expect( arr1.eql? [ -111, 12345678 ] ).to be false

expect( arr1 === arr1 ).to be true
expect( arr2 === arr1 ).to be true
expect( arr1.class === arr2 ).to be true
end

it "inspects to show type and contents" do
arr = [13, 42, 120].to_java :int
expect(arr.inspect).to match(/^int\[13, 42, 120\]@[0-9a-f]+$/)
@@ -524,6 +618,20 @@
expect(ret.to_a).to eq([13, 42, 120])
end

it 'handles equality to another array' do
arr1 = [111, 2222222222].to_java :long
arr2 = Java::long[2].new
arr2[0] = 111; arr2[1] = 2222222222
expect( arr1 == arr2 ).to be true
expect( arr1.eql? arr2 ).to be true
expect( [ 111 ].to_java(:long) == arr2 ).to be false

expect( arr1 == [ 111 ] ).to be false
expect( arr1 == [ 111, 2222222222 ] ).to be true
expect( [ 111, 2222222222 ] == arr2 ).to be true
expect( arr1.eql? [ 111, 2222222222 ] ).to be false
end

it "inspects to show type and contents" do
arr = [13, 42, 120].to_java :long
expect(arr.inspect).to match(/^long\[13, 42, 120\]@[0-9a-f]+$/)
@@ -954,4 +1062,40 @@ def blah()
expect( r_arr[0] ).to eql 1
end

describe "#dig" do

it 'returns #at with one arg' do
expect( [1].to_java.dig(0) ).to eql 1
expect( [1].to_java(:byte).dig(0) ).to eql 1
expect( [1].to_java.dig(1) ).to be nil

expect( Java::long[2].new.dig(1) ).to be 0
expect( Java::long[2].new.dig(2) ).to be nil
expect( java.lang.String[1].new.dig(1) ).to be nil
end

it 'recurses array elements' do
arr = Java::int[2].new ; arr[0] = 2; arr[1] = 3
a = [ [ 1, arr ] ].to_java
expect( a.dig(0, 0) ).to eql 1
expect( a.dig(0, 1, 1) ).to eql 3
expect( a.dig(0, -1, 0) ).to eql 2
end

it 'returns the nested value specified if the sequence includes a key' do
a = [42, { foo: :bar }].to_java :Object
expect( a.dig(1, :foo) ).to eql :bar
end

it 'raises a TypeError for a non-numeric index' do
expect { ['a'].dig(:first) }.to raise_error(TypeError)
end

it 'raises a TypeError if any intermediate step does not respond to #dig' do
a = [1, 2].to_java(:int)
expect { a.dig(0, 1) }.to raise_error(TypeError)
end

end

end