@ -2886,13 +2886,6 @@ public class NanoTest extends TestCase {
TestAllTypesNano . BAR ,
TestAllTypesNano . BAZ
} ;
// We set the _nan fields to something other than nan, because equality
// is defined for nan such that Float.NaN != Float.NaN, which makes any
// instance of TestAllTypesNano unequal to any other instance unless
// these fields are set. This is also the behavior of the regular java
// generator when the value of a field is NaN.
message . defaultFloatNan = 1 . 0f ;
message . defaultDoubleNan = 1 . 0 ;
return message ;
}
@ -2915,7 +2908,6 @@ public class NanoTest extends TestCase {
TestAllTypesNano . BAR ,
TestAllTypesNano . BAZ
} ;
message . defaultFloatNan = 1 . 0f ;
return message ;
}
@ -2924,8 +2916,7 @@ public class NanoTest extends TestCase {
. setOptionalInt32 ( 5 )
. setOptionalString ( "Hello" )
. setOptionalBytes ( new byte [ ] { 1 , 2 , 3 } )
. setOptionalNestedEnum ( TestNanoAccessors . BAR )
. setDefaultFloatNan ( 1 . 0f ) ;
. setOptionalNestedEnum ( TestNanoAccessors . BAR ) ;
message . optionalNestedMessage = new TestNanoAccessors . NestedMessage ( ) . setBb ( 27 ) ;
message . repeatedInt32 = new int [ ] { 5 , 6 , 7 , 8 } ;
message . repeatedString = new String [ ] { "One" , "Two" } ;
@ -2973,6 +2964,126 @@ public class NanoTest extends TestCase {
return message ;
}
public void testEqualsWithSpecialFloatingPointValues ( ) throws Exception {
// Checks that the nano implementation complies with Object.equals() when treating
// floating point numbers, i.e. NaN == NaN and +0.0 != -0.0.
// This test assumes that the generated equals() implementations are symmetric, so
// there will only be one direction for each equality check.
TestAllTypesNano m1 = new TestAllTypesNano ( ) ;
m1 . optionalFloat = Float . NaN ;
m1 . optionalDouble = Double . NaN ;
TestAllTypesNano m2 = new TestAllTypesNano ( ) ;
m2 . optionalFloat = Float . NaN ;
m2 . optionalDouble = Double . NaN ;
assertTrue ( m1 . equals ( m2 ) ) ;
assertTrue ( m1 . equals (
MessageNano . mergeFrom ( new TestAllTypesNano ( ) , MessageNano . toByteArray ( m1 ) ) ) ) ;
m1 . optionalFloat = + 0f ;
m2 . optionalFloat = - 0f ;
assertFalse ( m1 . equals ( m2 ) ) ;
m1 . optionalFloat = - 0f ;
m1 . optionalDouble = + 0d ;
m2 . optionalDouble = - 0d ;
assertFalse ( m1 . equals ( m2 ) ) ;
m1 . optionalDouble = - 0d ;
assertTrue ( m1 . equals ( m2 ) ) ;
assertFalse ( m1 . equals ( new TestAllTypesNano ( ) ) ) ; // -0 does not equals() the default +0
assertTrue ( m1 . equals (
MessageNano . mergeFrom ( new TestAllTypesNano ( ) , MessageNano . toByteArray ( m1 ) ) ) ) ;
// -------
TestAllTypesNanoHas m3 = new TestAllTypesNanoHas ( ) ;
m3 . optionalFloat = Float . NaN ;
m3 . hasOptionalFloat = true ;
m3 . optionalDouble = Double . NaN ;
m3 . hasOptionalDouble = true ;
TestAllTypesNanoHas m4 = new TestAllTypesNanoHas ( ) ;
m4 . optionalFloat = Float . NaN ;
m4 . hasOptionalFloat = true ;
m4 . optionalDouble = Double . NaN ;
m4 . hasOptionalDouble = true ;
assertTrue ( m3 . equals ( m4 ) ) ;
assertTrue ( m3 . equals (
MessageNano . mergeFrom ( new TestAllTypesNanoHas ( ) , MessageNano . toByteArray ( m3 ) ) ) ) ;
m3 . optionalFloat = + 0f ;
m4 . optionalFloat = - 0f ;
assertFalse ( m3 . equals ( m4 ) ) ;
m3 . optionalFloat = - 0f ;
m3 . optionalDouble = + 0d ;
m4 . optionalDouble = - 0d ;
assertFalse ( m3 . equals ( m4 ) ) ;
m3 . optionalDouble = - 0d ;
m3 . hasOptionalFloat = false ; // -0 does not equals() the default +0,
m3 . hasOptionalDouble = false ; // so these incorrect 'has' flags should be disregarded.
assertTrue ( m3 . equals ( m4 ) ) ; // note: m4 has the 'has' flags set.
assertFalse ( m3 . equals ( new TestAllTypesNanoHas ( ) ) ) ; // note: the new message has +0 defaults
assertTrue ( m3 . equals (
MessageNano . mergeFrom ( new TestAllTypesNanoHas ( ) , MessageNano . toByteArray ( m3 ) ) ) ) ;
// note: the deserialized message has the 'has' flags set.
// -------
TestNanoAccessors m5 = new TestNanoAccessors ( ) ;
m5 . setOptionalFloat ( Float . NaN ) ;
m5 . setOptionalDouble ( Double . NaN ) ;
TestNanoAccessors m6 = new TestNanoAccessors ( ) ;
m6 . setOptionalFloat ( Float . NaN ) ;
m6 . setOptionalDouble ( Double . NaN ) ;
assertTrue ( m5 . equals ( m6 ) ) ;
assertTrue ( m5 . equals (
MessageNano . mergeFrom ( new TestNanoAccessors ( ) , MessageNano . toByteArray ( m6 ) ) ) ) ;
m5 . setOptionalFloat ( + 0f ) ;
m6 . setOptionalFloat ( - 0f ) ;
assertFalse ( m5 . equals ( m6 ) ) ;
m5 . setOptionalFloat ( - 0f ) ;
m5 . setOptionalDouble ( + 0d ) ;
m6 . setOptionalDouble ( - 0d ) ;
assertFalse ( m5 . equals ( m6 ) ) ;
m5 . setOptionalDouble ( - 0d ) ;
assertTrue ( m5 . equals ( m6 ) ) ;
assertFalse ( m5 . equals ( new TestNanoAccessors ( ) ) ) ;
assertTrue ( m5 . equals (
MessageNano . mergeFrom ( new TestNanoAccessors ( ) , MessageNano . toByteArray ( m6 ) ) ) ) ;
// -------
NanoReferenceTypes . TestAllTypesNano m7 = new NanoReferenceTypes . TestAllTypesNano ( ) ;
m7 . optionalFloat = Float . NaN ;
m7 . optionalDouble = Double . NaN ;
NanoReferenceTypes . TestAllTypesNano m8 = new NanoReferenceTypes . TestAllTypesNano ( ) ;
m8 . optionalFloat = Float . NaN ;
m8 . optionalDouble = Double . NaN ;
assertTrue ( m7 . equals ( m8 ) ) ;
assertTrue ( m7 . equals ( MessageNano . mergeFrom (
new NanoReferenceTypes . TestAllTypesNano ( ) , MessageNano . toByteArray ( m7 ) ) ) ) ;
m7 . optionalFloat = + 0f ;
m8 . optionalFloat = - 0f ;
assertFalse ( m7 . equals ( m8 ) ) ;
m7 . optionalFloat = - 0f ;
m7 . optionalDouble = + 0d ;
m8 . optionalDouble = - 0d ;
assertFalse ( m7 . equals ( m8 ) ) ;
m7 . optionalDouble = - 0d ;
assertTrue ( m7 . equals ( m8 ) ) ;
assertFalse ( m7 . equals ( new NanoReferenceTypes . TestAllTypesNano ( ) ) ) ;
assertTrue ( m7 . equals ( MessageNano . mergeFrom (
new NanoReferenceTypes . TestAllTypesNano ( ) , MessageNano . toByteArray ( m7 ) ) ) ) ;
}
public void testNullRepeatedFields ( ) throws Exception {
// Check that serialization after explicitly setting a repeated field
// to null doesn't NPE.