using System; using System.Diagnostics; using System.Runtime.InteropServices; using NUnit.Framework; namespace Developpez.Dotnet.Tests { [TestFixture] public class DisposablePointerTests { [Test] public void Test_Using() { using (Process proc = Process.GetCurrentProcess()) { bool wasDisposed = false; int allocSize = 100 * 1024 * 1024; Action disposeAction = p => { Marshal.FreeHGlobal(p); wasDisposed = true; }; long memoryBefore = proc.PrivateMemorySize64; long memoryDuring = 0; long memoryAfter = 0; using (var ptr = new DisposablePointer(Marshal.AllocHGlobal(allocSize), disposeAction)) { proc.Refresh(); memoryDuring = proc.PrivateMemorySize64; Assert.AreNotEqual(IntPtr.Zero, ptr.Value); Assert.IsFalse(wasDisposed); } proc.Refresh(); memoryAfter = proc.PrivateMemorySize64; Assert.IsTrue(wasDisposed); Assert.IsTrue(AreAlmostEqual(memoryBefore + allocSize, memoryDuring, 0.05)); Assert.IsTrue(AreAlmostEqual(memoryBefore, memoryAfter, 0.05)); } } private bool AreAlmostEqual(long expected, long actual, double tolerance) { double diffRatio = Math.Abs((double)(expected - actual) / expected); return diffRatio <= tolerance; } [Test] public void Test_ObjectDisposedException() { bool wasDisposed = false; int allocSize = 1024 * 1024; Action disposeAction = p => { Marshal.FreeHGlobal(p); wasDisposed = true; }; DisposablePointer ptr = null; try { ptr = new DisposablePointer(Marshal.AllocHGlobal(allocSize), disposeAction); Assert.AreNotEqual(IntPtr.Zero, ptr.Value); Assert.IsFalse(wasDisposed); } finally { if (ptr != null) ptr.Dispose(); Assert.IsTrue(wasDisposed); IntPtr p = IntPtr.Zero; Assert.Throws( () => p = ptr.Value); } Assert.IsTrue(wasDisposed); } [Test] public void Test_AllocHGlobal() { int allocSize = 1024 * 1024; DisposablePointer ptr = null; try { ptr = DisposablePointer.AllocHGlobal(allocSize); Assert.AreNotEqual(IntPtr.Zero, ptr.Value); } finally { if (ptr != null) ptr.Dispose(); IntPtr p = IntPtr.Zero; Assert.Throws( () => p = ptr.Value); } } } }