2014-08-13 10:39:27 +01:00
//
// RuntimeHelpersTest.cs - NUnit Test Cases for the System.Runtime.CompilerServices.RuntimeHelpers class
//
// Zoltan Varga (vargaz@freemail.hu)
//
// (C) Ximian, Inc. http://www.ximian.com
using System ;
using System.Runtime.CompilerServices ;
2017-04-10 11:41:01 +00:00
using System.Threading ;
2014-08-13 10:39:27 +01:00
using NUnit.Framework ;
namespace MonoTests.System.Runtime.CompilerServices {
[TestFixture]
public class RuntimeHelpersTest {
struct FooStruct {
public int i ;
public string j ;
public override int GetHashCode ( ) {
return 5 ;
}
public override bool Equals ( object o ) {
Assert . Fail ( ) ;
return false ;
}
}
class FooClass {
public static int counter = 0 ;
static FooClass ( ) {
counter = counter + 1 ;
}
public override int GetHashCode ( ) {
return 5 ;
}
public override bool Equals ( object o ) {
Assert . Fail ( ) ;
return true ;
}
}
2017-04-10 11:41:01 +00:00
[Test]
2014-08-13 10:39:27 +01:00
public void TestOffsetToStringData ( )
{
Assert . AreEqual (
RuntimeHelpers . OffsetToStringData ,
RuntimeHelpers . OffsetToStringData , "OffsetToStringData is not constant" ) ;
}
2017-04-10 11:41:01 +00:00
[Test]
2014-08-13 10:39:27 +01:00
public void TestGetObjectValue ( )
{
FooStruct s1 ;
FooStruct s2 ;
// Test null
Assert . AreEqual ( RuntimeHelpers . GetObjectValue ( null ) ,
null ) ;
// Test non-valuetype
Assert . AreEqual ( RuntimeHelpers . GetObjectValue ( this ) ,
this ) ;
// Test valuetype
s1 . i = 42 ;
s1 . j = "FOO" ;
s2 = ( FooStruct ) RuntimeHelpers . GetObjectValue ( s1 ) ;
s1 . i = 43 ;
s1 . j = "BAR" ;
Assert . AreEqual ( s2 . i , 42 ) ;
Assert . AreEqual ( s2 . j , "FOO" ) ;
}
2017-04-10 11:41:01 +00:00
[Test]
2014-08-13 10:39:27 +01:00
public void TestRunClassConstructor ( )
{
RuntimeHelpers . RunClassConstructor ( typeof ( FooClass ) . TypeHandle ) ;
Assert . AreEqual ( FooClass . counter , 1 ) ;
// Each static constructor should only be run once
RuntimeHelpers . RunClassConstructor ( typeof ( FooClass ) . TypeHandle ) ;
Assert . AreEqual ( FooClass . counter , 1 ) ;
}
[Test]
[ExpectedException (typeof (ArgumentException))]
public void RunClassConstructor_Default ( )
{
RuntimeTypeHandle rth = new RuntimeTypeHandle ( ) ;
Assert . AreEqual ( IntPtr . Zero , rth . Value , "Value" ) ;
RuntimeHelpers . RunClassConstructor ( rth ) ;
}
2015-01-13 10:44:36 +00:00
// Expected the handle here is that way, because we are going to test for an ArgumentException being thrown
#pragma warning disable 649
2014-08-13 10:39:27 +01:00
static RuntimeTypeHandle handle ;
2015-01-13 10:44:36 +00:00
#pragma warning restore 649
2014-08-13 10:39:27 +01:00
[Test]
[ExpectedException (typeof (ArgumentException))]
public void RunClassConstructor_Uninitialized ( )
{
RuntimeHelpers . RunClassConstructor ( handle ) ;
}
class Thrower {
static Thrower ( )
{
throw new NotFiniteNumberException ( ) ;
}
}
[Test]
[ExpectedException (typeof (TypeInitializationException))]
public void RunClassConstructor_Throw ( )
{
RuntimeHelpers . RunClassConstructor ( typeof ( Thrower ) . TypeHandle ) ;
2016-02-22 11:00:01 -05:00
}
class GClass < T > {
protected T Field ;
}
[Test]
public void RunClassConstructor_Generic ( )
{
RuntimeHelpers . RunClassConstructor ( typeof ( GClass < > ) . TypeHandle ) ;
2014-08-13 10:39:27 +01:00
}
class Fielder {
public byte [ ] array = new byte [ 1 ] ;
}
static RuntimeFieldHandle rfh = typeof ( Fielder ) . GetField ( "array" ) . FieldHandle ;
2015-01-13 10:44:36 +00:00
// Disable expected warning: the point of the test is to validate that an exception is thrown for something with a null (the default value in this case)
#pragma warning disable 649
2014-08-13 10:39:27 +01:00
static RuntimeFieldHandle static_rfh ;
2015-01-13 10:44:36 +00:00
#pragma warning restore 649
2014-08-13 10:39:27 +01:00
[Test]
[ExpectedException (typeof (ArgumentNullException))]
public void InitializeArray_Null ( )
{
RuntimeHelpers . InitializeArray ( null , rfh ) ;
}
[Test]
[ExpectedException (typeof (ArgumentNullException))]
public void InitializeArray_Default ( )
{
RuntimeFieldHandle h = new RuntimeFieldHandle ( ) ;
RuntimeHelpers . InitializeArray ( new Fielder ( ) . array , h ) ;
}
[Test]
[ExpectedException (typeof (ArgumentNullException))]
public void InitializeArray_Uninitialized ( )
{
RuntimeHelpers . InitializeArray ( new Fielder ( ) . array , static_rfh ) ;
}
[Test]
[ExpectedException (typeof (ArgumentException))]
public void InitializeArray ( )
{
RuntimeHelpers . InitializeArray ( new Fielder ( ) . array , rfh ) ;
}
2017-04-10 11:41:01 +00:00
[Test]
2014-08-13 10:39:27 +01:00
public void TestGetHashCode ( )
{
Assert . AreEqual ( 0 , RuntimeHelpers . GetHashCode ( null ) ) ;
object o = new object ( ) ;
Assert . AreEqual ( o . GetHashCode ( ) , RuntimeHelpers . GetHashCode ( o ) ) ;
Assert . IsTrue ( 5 ! = RuntimeHelpers . GetHashCode ( new FooClass ( ) ) ) ;
}
2017-04-10 11:41:01 +00:00
[Test]
2014-08-13 10:39:27 +01:00
public void TestEquals ( )
{
Assert . IsTrue ( RuntimeHelpers . Equals ( null , null ) ) ;
Assert . IsTrue ( ! RuntimeHelpers . Equals ( new object ( ) , null ) ) ;
Assert . IsTrue ( ! RuntimeHelpers . Equals ( null , new object ( ) ) ) ;
FooStruct f1 = new FooStruct ( ) ;
f1 . i = 5 ;
FooStruct f2 = new FooStruct ( ) ;
f2 . i = 5 ;
object o1 = f1 ;
object o2 = o1 ;
object o3 = f2 ;
object o4 = "AAA" ;
Assert . IsTrue ( RuntimeHelpers . Equals ( o1 , o2 ) ) ;
// This should do a bit-by-bit comparison for valuetypes
Assert . IsTrue ( RuntimeHelpers . Equals ( o1 , o3 ) ) ;
Assert . IsTrue ( ! RuntimeHelpers . Equals ( o1 , o4 ) ) ;
}
2017-04-10 11:41:01 +00:00
[Test]
public void TestEnsureSufficientExecutionStack ( )
{
var t = new Thread ( ( ) = > {
unsafe {
var s = stackalloc byte [ 1024 ] ;
}
RuntimeHelpers . EnsureSufficientExecutionStack ( ) ;
} ) ;
t . Start ( ) ;
t . Join ( ) ;
}
2014-08-13 10:39:27 +01:00
}
}