Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds tests for numbers #58

Merged
merged 4 commits into from
Aug 17, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions src/test/java/org/json/junit/Fraction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package org.json.junit;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;

/**
* basic fraction class, no frills.
* @author John Aylward
*
*/
public class Fraction extends Number implements Comparable<Fraction> {
/**
* serial id.
*/
private static final long serialVersionUID = 1L;

/**
* value as a big decimal.
*/
private final BigDecimal bigDecimal;

/**
* value of the denominator.
*/
private final BigInteger denominator;
/**
* value of the numerator.
*/
private final BigInteger numerator;

/**
* @param numerator
* numerator
* @param denominator
* denominator
*/
public Fraction(final BigInteger numerator, final BigInteger denominator) {
super();
if (numerator == null || denominator == null) {
throw new IllegalArgumentException("All values must be non-null");
}
if (denominator.compareTo(BigInteger.ZERO)==0) {
throw new IllegalArgumentException("Divide by zero");
}

final BigInteger n;
final BigInteger d;
// normalize fraction
if (denominator.signum()<0) {
n = numerator.negate();
d = denominator.negate();
} else {
n = numerator;
d = denominator;
}
this.numerator = n;
this.denominator = d;
if (n.compareTo(BigInteger.ZERO)==0) {
this.bigDecimal = BigDecimal.ZERO;
} else if (n.compareTo(d)==0) {// i.e. 4/4, 10/10
this.bigDecimal = BigDecimal.ONE;
} else {
this.bigDecimal = new BigDecimal(this.numerator).divide(new BigDecimal(this.denominator),
RoundingMode.HALF_EVEN);
}
}

/**
* @param numerator
* numerator
* @param denominator
* denominator
*/
public Fraction(final long numerator, final long denominator) {
this(BigInteger.valueOf(numerator),BigInteger.valueOf(denominator));
}

/**
* @return the decimal
*/
public BigDecimal bigDecimalValue() {
return this.bigDecimal;
}

@Override
public int compareTo(final Fraction o) {
// .equals call this, so no .equals compare allowed

// if they are the same reference, just return equals
if (this == o) {
return 0;
}

// if my denominators are already equal, just compare the numerators
if (this.denominator.compareTo(o.denominator)==0) {
return this.numerator.compareTo(o.numerator);
}

// get numerators of common denominators
// a x ay xb
// --- --- = ---- ----
// b y by yb
final BigInteger thisN = this.numerator.multiply(o.denominator);
final BigInteger otherN = o.numerator.multiply(this.denominator);

return thisN.compareTo(otherN);
}

@Override
public double doubleValue() {
return this.bigDecimal.doubleValue();
}

/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
final Fraction other = (Fraction) obj;
return this.compareTo(other) == 0;
}

@Override
public float floatValue() {
return this.bigDecimal.floatValue();
}

/**
* @return the denominator
*/
public BigInteger getDenominator() {
return this.denominator;
}

/**
* @return the numerator
*/
public BigInteger getNumerator() {
return this.numerator;
}

/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (this.bigDecimal == null ? 0 : this.bigDecimal.hashCode());
return result;
}

@Override
public int intValue() {
return this.bigDecimal.intValue();
}

@Override
public long longValue() {
return this.bigDecimal.longValue();
}

/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return this.numerator + "/" + this.denominator;
}
}
51 changes: 49 additions & 2 deletions src/test/java/org/json/junit/JSONObjectTest.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.json.junit;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand All @@ -20,6 +20,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.json.CDL;
import org.json.JSONArray;
Expand Down Expand Up @@ -49,7 +50,7 @@ public void jsonObjectByNullBean() {
MyBean myBean = null;
new JSONObject(myBean);
}

/**
* A JSONObject can be created with no content
*/
Expand Down Expand Up @@ -165,6 +166,52 @@ public void verifyConstructor() {
expected.similar(jaObjObj));
}

/**
* Tests Number serialization.
*/
@Test
public void verifyNumberOutput(){
JSONObject jsonObject = new JSONObject(new MyNumberContainer());
String actual = jsonObject.toString();

// before wrapping of Number is allowed the number was converted as a bean
String expected = "{\"myNumber\":{\"number\":42}}";
//String expected = "{\"myNumber\":42}";
assertEquals("Not Equal", expected , actual);

// put handles objects differently than the constructor.
jsonObject = new JSONObject();
jsonObject.put("myNumber", new MyNumber());
actual = jsonObject.toString();
// the output is the toString of the number as a number.
expected = "{\"myNumber\":42}";
assertEquals("Not Equal", expected , actual);

jsonObject = new JSONObject(Collections.singletonMap("myNumber", new AtomicInteger(42)));
actual = jsonObject.toString();
// before wrapping of Number is allowed the number was converted to a string
expected = "{\"myNumber\":\"42\"}";
assertEquals("Not Equal", expected , actual);

// put handles objects differently than the constructor.
jsonObject = new JSONObject();
jsonObject.put("myNumber", new AtomicInteger(42));
actual = jsonObject.toString();
expected = "{\"myNumber\":42}";
assertEquals("Not Equal", expected , actual);

// verify Fraction output
jsonObject = new JSONObject(Collections.singletonMap("myNumber", new Fraction(4,2)));
assertEquals("Numerator", BigInteger.valueOf(4) , jsonObject.query("/myNumber/numerator"));
assertEquals("Denominator", BigInteger.valueOf(2) , jsonObject.query("/myNumber/denominator"));

jsonObject = new JSONObject();
jsonObject.put("myNumber", new Fraction(4,2));
actual = jsonObject.toString();
expected = "{\"myNumber\":4/2}"; // this is NOT valid JSON!!!!!!!!!!! BUG!
assertEquals("Not Equal", expected , actual);
}

/**
* Verifies that the put Collection has backwards compatability with RAW types pre-java5.
*/
Expand Down
97 changes: 97 additions & 0 deletions src/test/java/org/json/junit/MyNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.json.junit;

import java.math.BigDecimal;

/**
* Number override for testing. Number overrides should always override
* toString, hashCode, and Equals.
*
* @see <a
* href="https://docs.oracle.com/javase/tutorial/java/data/numberclasses.html">The
* Numbers Classes</a>
* @see <a
* href="https://docs.oracle.com/javase/tutorial/java/data/numberformat.html">Formatting
* Numeric Print Output</a>
*
* @author John Aylward
*/
public class MyNumber extends Number {
private Number number = BigDecimal.valueOf(42);
/**
*/
private static final long serialVersionUID = 1L;

/**
* @return number!
*/
public Number getNumber() {
return this.number;
}

@Override
public int intValue() {
return getNumber().intValue();
}

@Override
public long longValue() {
return getNumber().longValue();
}

@Override
public float floatValue() {
return getNumber().floatValue();
}

@Override
public double doubleValue() {
return getNumber().doubleValue();
}

/* (non-Javadoc)
* @see java.lang.Object#toString()
*
* Number overrides should in general always override the toString method.
*/
@Override
public String toString() {
return getNumber().toString();
}

/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.number == null) ? 0 : this.number.hashCode());
return result;
}

/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof MyNumber)) {
return false;
}
MyNumber other = (MyNumber) obj;
if (this.number == null) {
if (other.number != null) {
return false;
}
} else if (!this.number.equals(other.number)) {
return false;
}
return true;
}

}
13 changes: 13 additions & 0 deletions src/test/java/org/json/junit/MyNumberContainer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.json.junit;

/**
* Class that holds our MyNumber override as a property.
* @author John Aylward
*/
public class MyNumberContainer {
private MyNumber myNumber = new MyNumber();
/**
* @return a MyNumber.
*/
public Number getMyNumber() {return this.myNumber;}
}