Skip to content

Commit 9afb5af

Browse files
committed
[compat] missing OpenSSL:BN to_int, -@, +@, abs, negative?
1 parent f176706 commit 9afb5af

File tree

2 files changed

+102
-4
lines changed

2 files changed

+102
-4
lines changed

src/main/java/org/jruby/ext/openssl/BN.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,8 @@ public RubyInteger hash(final ThreadContext context) {
292292
return context.runtime.newFixnum(hashCode());
293293
}
294294

295-
@JRubyMethod(name = "to_i")
296-
public RubyInteger to_i() {
295+
@JRubyMethod(name = "to_int", alias = "to_i")
296+
public RubyInteger to_int() {
297297
if ( value.compareTo( MAX_LONG ) > 0 || value.compareTo( MIN_LONG ) < 0 ) {
298298
return RubyBignum.newBignum(getRuntime(), value);
299299
}
@@ -306,15 +306,14 @@ public BN to_bn() {
306306
}
307307

308308
@JRubyMethod(name="coerce")
309-
// FIXME: is this right? don't see how it would be useful...
310309
public IRubyObject coerce(IRubyObject other) {
311310
final Ruby runtime = getRuntime();
312311
IRubyObject self;
313312
if ( other instanceof RubyString ) {
314313
self = runtime.newString(value.toString());
315314
}
316315
else if ( other instanceof RubyInteger ) {
317-
self = to_i();
316+
self = to_int();
318317
}
319318
else if ( other instanceof BN ) {
320319
self = this;
@@ -325,6 +324,26 @@ else if ( other instanceof BN ) {
325324
return runtime.newArray(other, self);
326325
}
327326

327+
@JRubyMethod(name="-@")
328+
public IRubyObject op_uminus(final ThreadContext context) {
329+
return newBN(context.runtime, value.negate());
330+
}
331+
332+
@JRubyMethod(name="+@")
333+
public IRubyObject op_uplus(final ThreadContext context) {
334+
return newBN(context.runtime, value);
335+
}
336+
337+
@JRubyMethod
338+
public IRubyObject abs(final ThreadContext context) {
339+
return newBN(context.runtime, value.abs());
340+
}
341+
342+
@JRubyMethod(name="negative?")
343+
public IRubyObject negative_p(final ThreadContext context) {
344+
return context.runtime.newBoolean(value.signum() == -1);
345+
}
346+
328347
@JRubyMethod(name="zero?")
329348
public RubyBoolean zero_p(final ThreadContext context) {
330349
return context.runtime.newBoolean( value.equals(BigInteger.ZERO) );

src/test/ruby/test_bn.rb

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,85 @@
22

33
class TestBN < TestCase
44

5+
def setup
6+
super
7+
@e1 = OpenSSL::BN.new(999.to_s(16), 16) # OpenSSL::BN.new(str, 16) must be most stable
8+
@e2 = OpenSSL::BN.new("-" + 999.to_s(16), 16)
9+
@e3 = OpenSSL::BN.new((2**107-1).to_s(16), 16)
10+
@e4 = OpenSSL::BN.new("-" + (2**107-1).to_s(16), 16)
11+
end
12+
13+
def test_to_int
14+
assert_equal(999, @e1.to_i)
15+
assert_equal(-999, @e2.to_i)
16+
assert_equal(2**107-1, @e3.to_i)
17+
assert_equal(-(2**107-1), @e4.to_i)
18+
19+
assert_equal(999, @e1.to_int)
20+
end
21+
22+
def test_coerce
23+
assert_equal(["", "-999"], @e2.coerce(""))
24+
assert_equal([1000, -999], @e2.coerce(1000))
25+
assert_raise(TypeError) { @e2.coerce(Class.new.new) }
26+
end
27+
28+
def test_zero_p
29+
assert_equal(true, 0.to_bn.zero?)
30+
assert_equal(false, 1.to_bn.zero?)
31+
end
32+
33+
def test_one_p
34+
assert_equal(true, 1.to_bn.one?)
35+
assert_equal(false, 2.to_bn.one?)
36+
end
37+
38+
def test_odd_p
39+
assert_equal(true, 1.to_bn.odd?)
40+
assert_equal(false, 2.to_bn.odd?)
41+
end
42+
43+
def test_negative_p
44+
assert_equal(false, 0.to_bn.negative?)
45+
assert_equal(false, @e1.negative?)
46+
assert_equal(true, @e2.negative?)
47+
end
48+
49+
def test_abs
50+
assert_equal(@e1, @e2.abs)
51+
assert_equal(@e3, @e4.abs)
52+
assert_not_equal(@e2, @e2.abs)
53+
assert_not_equal(@e4, @e4.abs)
54+
assert_equal(false, @e2.abs.negative?)
55+
assert_equal(false, @e4.abs.negative?)
56+
assert_equal(true, (-@e1.abs).negative?)
57+
assert_equal(true, (-@e2.abs).negative?)
58+
assert_equal(true, (-@e3.abs).negative?)
59+
assert_equal(true, (-@e4.abs).negative?)
60+
end
61+
62+
def test_unary_plus_minus
63+
assert_equal(999, +@e1)
64+
assert_equal(-999, +@e2)
65+
assert_equal(-999, -@e1)
66+
assert_equal(+999, -@e2)
67+
68+
# These methods create new BN instances due to BN mutability
69+
# Ensure that the instance isn't the same
70+
e1_plus = +@e1
71+
e1_minus = -@e1
72+
assert_equal(false, @e1.equal?(e1_plus))
73+
assert_equal(true, @e1 == e1_plus)
74+
assert_equal(false, @e1.equal?(e1_minus))
75+
end
76+
77+
def test_mod
78+
assert_equal(1, 1.to_bn % 2)
79+
assert_equal(0, 2.to_bn % 1)
80+
#assert_equal(-2, -2.to_bn % 7)
81+
end
82+
83+
584
def test_new
685
bn = OpenSSL::BN.new('0') unless defined? JRUBY_VERSION
786
assert_equal ( bn || OpenSSL::BN.new(0) ).to_s, '0'

0 commit comments

Comments
 (0)