public void Various_Bool() { // note: this test was ported from RserveCLI. Not in the typical Arrange/Act/Assert format using (var service = new Rservice()) { var sexpTrue = new SexpArrayBool(true); var sexpFalse = new SexpArrayBool(false); var sexpNa = new SexpArrayBool(( bool? )null); // ReSharper disable EqualExpressionComparison Assert.True(sexpTrue.Equals(sexpTrue)); Assert.True(sexpFalse.Equals(sexpFalse)); Assert.True(sexpNa.Equals(sexpNa)); // ReSharper restore EqualExpressionComparison Assert.True(!sexpTrue.Equals(sexpFalse)); Assert.True(!sexpTrue.Equals(sexpNa)); Assert.True(sexpTrue.Equals(true)); Assert.True(sexpFalse.Equals(false)); Assert.True(!sexpNa.Equals(true)); Assert.True(!sexpNa.Equals(false)); foreach (var a in new Sexp[] { sexpTrue, sexpFalse, sexpNa }) { Assert.True(!a.Equals(new SexpNull())); } service.RConnection["x.bool"] = Sexp.Make(true); } }
public void Indexer_SetWithNonSexpArrayDate_ThrowsNotSupportedException() { // Arrange var sexp1 = new SexpArrayDate(new DateTime(2004, 01, 23)); var sexp2 = new SexpArrayDate(new[] { new DateTime(2004, 01, 23), new DateTime(2005, 01, 23), new DateTime(2007, 03, 12) }); // Act & Assert Assert.Throws <NotSupportedException>(() => sexp1[0] = new SexpArrayBool(false)); Assert.Throws <NotSupportedException>(() => sexp2[0] = new SexpArrayString("asdf")); }
public void Various_ArrayBool() { // note: this test was ported from RserveCLI. Not in the typical Arrange/Act/Assert format using (var service = new Rservice()) { var testvals = new bool?[] { true, false, null }; var x1 = new SexpArrayBool(testvals); Assert.Equal(testvals.Length, x1.Count); service.RConnection["x1"] = x1; for (int i = 0; i < x1.Count; i++) { Assert.Equal(new SexpArrayBool(testvals[i]).AsBool, x1[i].AsBool); } service.RConnection.Eval("x2 <- as.logical(c(TRUE,FALSE,NA))"); var x2 = service.RConnection["x2"]; Assert.Equal(x1.Count, x2.Count); for (int i = 0; i < x1.Count; i++) { if (x1[i].IsNa) { Assert.True(x2[i].IsNa); } else { Assert.Equal(x1[i].AsBool, x2[i].AsBool); } } var equals = service.RConnection["x1 == x2"]; Assert.Equal(x1.Count, equals.Count); for (int i = 0; i < x1.Count; i++) { if (!x1[i].IsNa) { Assert.True(( bool )(equals[i].AsBool), equals.ToString()); } } Assert.Equal(x1.IndexOf(Sexp.Make(false)), 1); x1.AsList[0] = false; Assert.Equal(x1[0].AsBool, false); } }
public void AsBools_WriteSexpArrayBoolToRAndReadBack_ReturnsArrayOfNullableBools() { using ( var service = new Rservice() ) { // Arrange Sexp bool1 = new SexpArrayBool(); Sexp bool2 = new SexpArrayBool( true ); Sexp bool3 = new SexpArrayBool( false ); Sexp bool4 = new SexpArrayBool( ( bool? )null ); Sexp bool5 = new SexpArrayBool( new bool?[] { true } ); Sexp bool6 = new SexpArrayBool( new bool?[] { false } ); Sexp bool7 = new SexpArrayBool( new bool?[] { null } ); Sexp bool8 = new SexpArrayBool( new bool?[] { true , null , false } ); Sexp bool9 = new SexpArrayBool( new bool?[] { true , false , null , true , false , null } ); bool9.Attributes.Add( "dim" , Sexp.Make( new[] { 2 , 3 } ) ); // Act service.RConnection[ "bool1" ] = bool1; service.RConnection[ "bool2" ] = bool2; service.RConnection[ "bool3" ] = bool3; service.RConnection[ "bool4" ] = bool4; service.RConnection[ "bool5" ] = bool5; service.RConnection[ "bool6" ] = bool6; service.RConnection[ "bool7" ] = bool7; service.RConnection[ "bool8" ] = bool8; service.RConnection[ "bool9" ] = bool9; bool1 = service.RConnection[ "bool1" ]; bool2 = service.RConnection[ "bool2" ]; bool3 = service.RConnection[ "bool3" ]; bool4 = service.RConnection[ "bool4" ]; bool5 = service.RConnection[ "bool5" ]; bool6 = service.RConnection[ "bool6" ]; bool7 = service.RConnection[ "bool7" ]; bool8 = service.RConnection[ "bool8" ]; bool9 = service.RConnection[ "bool9" ]; // Assert Assert.Equal( new bool?[] { } , bool1.AsBools ); Assert.Equal( new bool?[] { true } , bool2.AsBools ); Assert.Equal( new bool?[] { false } , bool3.AsBools ); Assert.Equal( new bool?[] { null } , bool4.AsBools ); Assert.Equal( new bool?[] { true } , bool5.AsBools ); Assert.Equal( new bool?[] { false } , bool6.AsBools ); Assert.Equal( new bool?[] { null } , bool7.AsBools ); Assert.Equal( new bool?[] { true , null , false } , bool8.AsBools ); Assert.Equal( new bool?[] { true , false , null , true , false , null } , bool9.AsBools ); } }
public void AsBools_WriteSexpArrayBoolToRAndReadBack_ReturnsArrayOfNullableBools() { using (var service = new Rservice()) { // Arrange Sexp bool1 = new SexpArrayBool(); Sexp bool2 = new SexpArrayBool(true); Sexp bool3 = new SexpArrayBool(false); Sexp bool4 = new SexpArrayBool(( bool? )null); Sexp bool5 = new SexpArrayBool(new bool?[] { true }); Sexp bool6 = new SexpArrayBool(new bool?[] { false }); Sexp bool7 = new SexpArrayBool(new bool?[] { null }); Sexp bool8 = new SexpArrayBool(new bool?[] { true, null, false }); Sexp bool9 = new SexpArrayBool(new bool?[] { true, false, null, true, false, null }); bool9.Attributes.Add("dim", Sexp.Make(new[] { 2, 3 })); // Act service.RConnection["bool1"] = bool1; service.RConnection["bool2"] = bool2; service.RConnection["bool3"] = bool3; service.RConnection["bool4"] = bool4; service.RConnection["bool5"] = bool5; service.RConnection["bool6"] = bool6; service.RConnection["bool7"] = bool7; service.RConnection["bool8"] = bool8; service.RConnection["bool9"] = bool9; bool1 = service.RConnection["bool1"]; bool2 = service.RConnection["bool2"]; bool3 = service.RConnection["bool3"]; bool4 = service.RConnection["bool4"]; bool5 = service.RConnection["bool5"]; bool6 = service.RConnection["bool6"]; bool7 = service.RConnection["bool7"]; bool8 = service.RConnection["bool8"]; bool9 = service.RConnection["bool9"]; // Assert Assert.Equal(new bool?[] { }, bool1.AsBools); Assert.Equal(new bool?[] { true }, bool2.AsBools); Assert.Equal(new bool?[] { false }, bool3.AsBools); Assert.Equal(new bool?[] { null }, bool4.AsBools); Assert.Equal(new bool?[] { true }, bool5.AsBools); Assert.Equal(new bool?[] { false }, bool6.AsBools); Assert.Equal(new bool?[] { null }, bool7.AsBools); Assert.Equal(new bool?[] { true, null, false }, bool8.AsBools); Assert.Equal(new bool?[] { true, false, null, true, false, null }, bool9.AsBools); } }
public void Equals_ComparedToObjectOfDifferentType_ReturnsFalse() { // Arrange var value1 = new SexpArrayDouble(new[] { 2.3, double.NaN, 4 }); var value2 = new SexpArrayBool(true); var value3 = new SexpArrayInt(new[] { 1, 3 }); // Act & Assert // ReSharper disable RedundantCast Assert.False(value1.Equals(value2)); Assert.False(value1.Equals(( object )value2)); Assert.False(value1.Equals(value3)); Assert.False(value1.Equals(( object )value3)); // ReSharper restore RedundantCast }
public void Command_AssignAndEvalLargeSexpArrayBool_ProperlyEncodesAndDecodesArrayOfBoolean() { using (var service = new Rservice()) { // Arrange var random = new Random(); const int count = 25497500; var sexpBool1ToEncode = new SexpArrayBool(Enumerable.Range(0, count).Select(x => { var y = random.Next(1, 4); return(y == 1 ? true : y == 2 ? false : ( bool? )null); })); var sexpBool2ToEncode = new SexpArrayBool(Enumerable.Range(0, count + 1).Select(x => { var y = random.Next(1, 4); return(y == 1 ? true : y == 2 ? false : ( bool? )null); })); var sexpBool3ToEncode = new SexpArrayBool(Enumerable.Range(0, count + 3).Select(x => { var y = random.Next(1, 4); return(y == 1 ? true : y == 2 ? false : ( bool? )null); })); var sexpBool4ToEncode = new SexpArrayBool(Enumerable.Range(0, count + 4).Select(x => { var y = random.Next(1, 4); return(y == 1 ? true : y == 2 ? false : ( bool? )null); })); // Act service.RConnection["bools1"] = sexpBool1ToEncode; service.RConnection["bools2"] = sexpBool2ToEncode; service.RConnection["bools3"] = sexpBool3ToEncode; service.RConnection["bools4"] = sexpBool4ToEncode; Sexp sexpBool1ToDecoded = service.RConnection["bools1"]; Sexp sexpBool2ToDecoded = service.RConnection["bools2"]; Sexp sexpBool3ToDecoded = service.RConnection["bools3"]; Sexp sexpBool4ToDecoded = service.RConnection["bools4"]; // Assert Assert.IsType <SexpArrayBool>(sexpBool1ToDecoded); Assert.IsType <SexpArrayBool>(sexpBool2ToDecoded); Assert.IsType <SexpArrayBool>(sexpBool3ToDecoded); Assert.IsType <SexpArrayBool>(sexpBool4ToDecoded); Assert.True(sexpBool1ToEncode.Values.SequenceEqual(sexpBool1ToDecoded.Values)); Assert.True(sexpBool2ToEncode.Values.SequenceEqual(sexpBool2ToDecoded.Values)); Assert.True(sexpBool3ToEncode.Values.SequenceEqual(sexpBool3ToDecoded.Values)); Assert.True(sexpBool4ToEncode.Values.SequenceEqual(sexpBool4ToDecoded.Values)); } }
public void Command_AssignAndEvalLargeSexpArrayBool_ProperlyEncodesAndDecodesArrayOfBoolean() { using ( var service = new Rservice() ) { // Arrange var random = new Random(); const int count = 25497500; var sexpBool1ToEncode = new SexpArrayBool( Enumerable.Range( 0 , count ).Select( x => { var y = random.Next( 1 , 4 ); return ( y == 1 ? true : y == 2 ? false : ( bool? )null ); } ) ); var sexpBool2ToEncode = new SexpArrayBool( Enumerable.Range( 0 , count + 1 ).Select( x => { var y = random.Next( 1 , 4 ); return ( y == 1 ? true : y == 2 ? false : ( bool? )null ); } ) ); var sexpBool3ToEncode = new SexpArrayBool( Enumerable.Range( 0 , count + 3 ).Select( x => { var y = random.Next( 1 , 4 ); return ( y == 1 ? true : y == 2 ? false : ( bool? )null ); } ) ); var sexpBool4ToEncode = new SexpArrayBool( Enumerable.Range( 0 , count + 4 ).Select( x => { var y = random.Next( 1 , 4 ); return ( y == 1 ? true : y == 2 ? false : ( bool? )null ); } ) ); // Act service.RConnection[ "bools1" ] = sexpBool1ToEncode; service.RConnection[ "bools2" ] = sexpBool2ToEncode; service.RConnection[ "bools3" ] = sexpBool3ToEncode; service.RConnection[ "bools4" ] = sexpBool4ToEncode; Sexp sexpBool1ToDecoded = service.RConnection[ "bools1" ]; Sexp sexpBool2ToDecoded = service.RConnection[ "bools2" ]; Sexp sexpBool3ToDecoded = service.RConnection[ "bools3" ]; Sexp sexpBool4ToDecoded = service.RConnection[ "bools4" ]; // Assert Assert.IsType<SexpArrayBool>( sexpBool1ToDecoded ); Assert.IsType<SexpArrayBool>( sexpBool2ToDecoded ); Assert.IsType<SexpArrayBool>( sexpBool3ToDecoded ); Assert.IsType<SexpArrayBool>( sexpBool4ToDecoded ); Assert.True( sexpBool1ToEncode.Values.SequenceEqual( sexpBool1ToDecoded.Values ) ); Assert.True( sexpBool2ToEncode.Values.SequenceEqual( sexpBool2ToDecoded.Values ) ); Assert.True( sexpBool3ToEncode.Values.SequenceEqual( sexpBool3ToDecoded.Values ) ); Assert.True( sexpBool4ToEncode.Values.SequenceEqual( sexpBool4ToDecoded.Values ) ); } }
public void Equals_ComparedToObjectOfDifferentType_ReturnsFalse() { // Arrange var value1 = new SexpArrayDouble( new[] { 2.3 , double.NaN , 4 } ); var value2 = new SexpArrayBool( true ); var value3 = new SexpArrayInt( new[] { 1 , 3 } ); // Act & Assert // ReSharper disable RedundantCast Assert.False( value1.Equals( value2 ) ); Assert.False( value1.Equals( ( object )value2 ) ); Assert.False( value1.Equals( value3 ) ); Assert.False( value1.Equals( ( object )value3 ) ); // ReSharper restore RedundantCast }
public void Various_ArrayBool() { // note: this test was ported from RserveCLI. Not in the typical Arrange/Act/Assert format using ( var service = new Rservice() ) { var testvals = new bool?[] { true , false , null }; var x1 = new SexpArrayBool( testvals ); Assert.Equal( testvals.Length , x1.Count ); service.RConnection[ "x1" ] = x1; for ( int i = 0 ; i < x1.Count ; i++ ) { Assert.Equal( new SexpArrayBool( testvals[ i ] ).AsBool , x1[ i ].AsBool ); } service.RConnection.Eval( "x2 <- as.logical(c(TRUE,FALSE,NA))" ); var x2 = service.RConnection[ "x2" ]; Assert.Equal( x1.Count , x2.Count ); for ( int i = 0 ; i < x1.Count ; i++ ) { if ( x1[ i ].IsNa ) { Assert.True( x2[ i ].IsNa ); } else { Assert.Equal( x1[ i ].AsBool , x2[ i ].AsBool ); } } var equals = service.RConnection[ "x1 == x2" ]; Assert.Equal( x1.Count , equals.Count ); for ( int i = 0 ; i < x1.Count ; i++ ) { if ( !x1[ i ].IsNa ) { Assert.True( ( bool )( equals[ i ].AsBool ) , equals.ToString() ); } } Assert.Equal( x1.IndexOf( Sexp.Make( false ) ) , 1 ); x1.AsList[ 0 ] = false; Assert.Equal( x1[ 0 ].AsBool , false ); } }
public void Various_Bool() { // note: this test was ported from RserveCLI. Not in the typical Arrange/Act/Assert format using ( var service = new Rservice() ) { var sexpTrue = new SexpArrayBool( true ); var sexpFalse = new SexpArrayBool( false ); var sexpNa = new SexpArrayBool( ( bool? )null ); // ReSharper disable EqualExpressionComparison Assert.True( sexpTrue.Equals( sexpTrue ) ); Assert.True( sexpFalse.Equals( sexpFalse ) ); Assert.True( sexpNa.Equals( sexpNa ) ); // ReSharper restore EqualExpressionComparison Assert.True( !sexpTrue.Equals( sexpFalse ) ); Assert.True( !sexpTrue.Equals( sexpNa ) ); Assert.True( sexpTrue.Equals( true ) ); Assert.True( sexpFalse.Equals( false ) ); Assert.True( !sexpNa.Equals( true ) ); Assert.True( !sexpNa.Equals( false ) ); foreach ( var a in new Sexp[] { sexpTrue , sexpFalse , sexpNa } ) { Assert.True( !a.Equals( new SexpNull() ) ); } service.RConnection[ "x.bool" ] = Sexp.Make( true ); } }
public void Indexer_SetWithNonSexpArrayDate_ThrowsNotSupportedException() { // Arrange var sexp1 = new SexpArrayDate( new DateTime( 2004 , 01 , 23 ) ); var sexp2 = new SexpArrayDate( new[] { new DateTime( 2004 , 01 , 23 ) , new DateTime( 2005 , 01 , 23 ) , new DateTime( 2007 , 03 , 12 ) } ); // Act & Assert Assert.Throws<NotSupportedException>( () => sexp1[ 0 ] = new SexpArrayBool( false ) ); Assert.Throws<NotSupportedException>( () => sexp2[ 0 ] = new SexpArrayString( "asdf" ) ); }
/// <summary> /// Decode a Qap1-encoded Sexp /// </summary> /// <param name="data">The byte stream in which the Sexp is encoded</param> /// <param name="start">At which index of data does the Sexp begin?</param> /// <returns>The decoded Sexp.</returns> private static Sexp DecodeSexp( byte[] data , ref long start ) { // pull sexp type byte xt = data[ start ]; // calculate length of payload var lengthBuf = new byte[ 8 ]; Array.Copy( data , start + 1 , lengthBuf , 0 , 3 ); start += 4; if ( ( xt & XtLarge ) == XtLarge ) { Array.Copy( data , start , lengthBuf , 3 , 4 ); start += 4; xt -= XtLarge; } var length = ( long )BitConverter.ToUInt64( lengthBuf , 0 ); // has attributes? process first SexpTaggedList attrs = null; if ( ( xt & XtHasAttr ) == XtHasAttr ) { xt -= XtHasAttr; long oldstart = start; attrs = ( SexpTaggedList )DecodeSexp( data , ref start ); length -= start - oldstart; } long end = start + length; Sexp result; switch ( xt ) { case XtNull: { if ( length != 0 ) { throw new RserveException( "Attempting to decode an SexpNull, but it is followed by data when it shouldn't be." ); } result = new SexpNull(); } break; case XtSymName: { // keep all characters up to the first null var symnNamBuf = new byte[ length ]; Array.Copy( data , start , symnNamBuf , 0 , length ); string res = Encoding.UTF8.GetString( symnNamBuf ); result = new SexpSymname( res.Split( '\x00' )[ 0 ] ); } break; case XtArrayInt: { var res = new int[ length / 4 ]; var intBuf = new byte[ 4 ]; for ( long i = 0 ; i < length ; i += 4 ) { Array.Copy( data , start + i , intBuf , 0 , 4 ); res[ i / 4 ] = BitConverter.ToInt32( intBuf , 0 ); } // is date or just an integer? if ( ( attrs != null ) && ( attrs.ContainsKey( "class" ) && attrs[ "class" ].AsStrings.Contains( "Date" ) ) ) { result = new SexpArrayDate( res ); } else { result = new SexpArrayInt( res ); } } break; case XtArrayBool: { if ( length < 4 ) { throw new RserveException( "Decoding an SexpArrayBool where data doesn't seem to contain a data length field." ); } var boolLengthBuf = new byte[ 4 ]; Array.Copy( data , start , boolLengthBuf , 0 , 4 ); var datalength = BitConverter.ToInt32( boolLengthBuf , 0 ); if ( datalength > length - 4 ) { throw new RserveException( "Decoding an SexpArrayBool where transmitted data field too short for number of entries." ); } var res = new bool?[ datalength ]; for ( int i = 0 ; i < datalength ; i++ ) { // R logical is false if 0, true if 1, and NA if 2 switch ( data[ start + i + 4 ] ) { case 0: res[ i ] = false; break; case 1: res[ i ] = true; break; case 2: res[ i ] = null; break; default: throw new RserveException( "Decoding an SexpArrayBool and found an element in the array that is not an R bool: " + data[ start + i + 4 ] ); } } result = new SexpArrayBool( res ); } break; case XtArrayDouble: { var res = new double[ length / 8 ]; var doubleBuf = new byte[ 8 ]; for ( long i = 0 ; i < length ; i += 8 ) { Array.Copy( data , start + i , doubleBuf , 0 , 8 ); res[ i / 8 ] = BitConverter.ToDouble( doubleBuf , 0 ); } // is date or just a double? if ( ( attrs != null ) && ( attrs.ContainsKey( "class" ) && attrs[ "class" ].AsStrings.Contains( "Date" ) ) ) { result = new SexpArrayDate( res.Select( Convert.ToInt32 ) ); } else { result = new SexpArrayDouble( res ); } } break; case XtArrayString: { var res = new List<string>(); long i = 0; for ( long j = 0 ; j < length ; j++ ) { if ( data[ start + j ] != 0 ) { continue; } if ( ( j == i + 1 ) && ( data[ start + i ] == 255 ) ) { res.Add( null ); } else { if ( data[ start + i ] == 255 ) { i++; } var stringBuf = new byte[ j - i ]; Array.Copy( data , start + i , stringBuf , 0 , j - i ); res.Add( Encoding.UTF8.GetString( stringBuf ) ); } i = j + 1; } result = new SexpArrayString( res ); } break; case XtListNoTag: case XtLangNoTag: case XtVector: result = new SexpList(); while ( start < end ) { result.Add( DecodeSexp( data , ref start ) ); } break; case XtLangTag: case XtListTag: result = new SexpTaggedList(); while ( start < end ) { Sexp val = DecodeSexp( data , ref start ); Sexp key = DecodeSexp( data , ref start ); result.Add( key.IsNull ? String.Empty : key.AsString , val ); } break; case XtRaw: { var d = new byte[ length ]; Array.Copy( data , start , d , 0 , length ); result = new SexpQap1Raw( xt , d ); } break; default: throw new RserveException( "Cannot decode an Sexp because the type is not recognized: " + xt ); } if ( start > end ) { throw new RserveException( "When decoding an Sexp, more data consumed than provided." ); } start = end; if ( attrs != null ) { foreach ( var a in attrs.AsSexpDictionary ) { result.Attributes.Add( a.Key , a.Value ); } } return result; }