Skip to content
Open
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
112 changes: 112 additions & 0 deletions src/IKVM.CoreLib.Tests/Collections/WeakHashTableTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;

using FluentAssertions;

using IKVM.CoreLib.Collections;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace IKVM.CoreLib.Tests.Collections
{

[TestClass]
public class WeakHashTableTests
{

class ArrayComparer : EqualityComparer<object[]>
{

public override bool Equals(object[]? x, object[]? y)
{
return Enumerable.SequenceEqual(x ?? [], y ?? []);
}

public override int GetHashCode([DisallowNull] object[] obj)
{
var hc = new HashCode();
foreach (var i in obj)
hc.Add(i);

return hc.ToHashCode();
}

}

[TestMethod]
public void CanGetOrCreateValueAtPath()
{
var a = new object();
var b = new object();
var c = new object();
var r = new object();

var t = new WeakHashTable<object[], object>(new ArrayComparer());
var v1 = t.GetOrCreateValue([a, b, c], k => r);
v1.Should().BeSameAs(r);
var v2 = t.GetOrCreateValue([a, b, c], k => new object());
v2.Should().BeSameAs(r);
}

[TestMethod]
public void CachedValueDoesNotExpireWhenReferenced()
{
var t = new WeakHashTable<object[], object>(new ArrayComparer());

var a = new object();
var b = new object();
var c = new object();
var r = new object();

void Test(WeakHashTable<object[], object> t)
{
var v1 = t.GetOrCreateValue([a, b, c], k => r);
v1.Should().BeSameAs(r);
t.Should().HaveCount(1);
}

Test(t);

GC.Collect();
GC.Collect();
GC.Collect();
Thread.Sleep(10);

t.Should().HaveCount(1);
GC.KeepAlive(r);
}

[TestMethod]
public void CachedValueExpiresWhenUnreferenced()
{
var t = new WeakHashTable<object[], object>(new ArrayComparer());

var a = new object();
var b = new object();
var c = new object();

void Test(WeakHashTable<object[], object> t)
{
var r = new object();

var v1 = t.GetOrCreateValue([a, b, c], k => r);
v1.Should().BeSameAs(r);
t.Should().HaveCount(1);
}

Test(t);

GC.Collect();
GC.Collect();
GC.Collect();
Thread.Sleep(10);

t.Should().HaveCount(0);
}

}

}
63 changes: 63 additions & 0 deletions src/IKVM.CoreLib.Tests/Runtime/DependentHandleTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using FluentAssertions;

using IKVM.CoreLib.Runtime;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace IKVM.CoreLib.Tests.Runtime
{

[TestClass]
public class DependentHandleTests
{

[TestMethod]
public void CanCreate()
{
var a = new object();
var b = new object();
var dh = new DependentHandle<object, object>(a, b);
dh.IsAllocated.Should().BeTrue();
}

[TestMethod]
public void CanGetTarget()
{
var a = new object();
var b = new object();
var dh = new DependentHandle<object, object>(a, b);
dh.Target.Should().BeSameAs(a);
}

[TestMethod]
public void CanGetDependent()
{
var a = new object();
var b = new object();
var dh = new DependentHandle<object, object>(a, b);
dh.Dependent.Should().BeSameAs(b);
}

[TestMethod]
public void CanGetTargetAndDependent()
{
var a = new object();
var b = new object();
var dh = new DependentHandle<object, object>(a, b);
var td = dh.TargetAndDependent;
td.Target.Should().BeSameAs(a);
td.Dependent.Should().BeSameAs(b);
}

[TestMethod]
public void CanDispose()
{
var a = new object();
var b = new object();
var dh = new DependentHandle<object, object>(a, b);
dh.Dispose();
}

}

}
25 changes: 25 additions & 0 deletions src/IKVM.CoreLib.Tests/Symbols/AssemblySymbolTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using FluentAssertions;

using IKVM.CoreLib.Symbols;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace IKVM.CoreLib.Tests.Symbols
{

public abstract class AssemblySymbolTests<TInit, TSymbols>
where TInit : SymbolTestInit<TSymbols>, new()
where TSymbols : SymbolContext
{

protected TInit Init { get; } = new TInit();

[TestMethod]
public void SystemObjectShouldNotBeNull()
{
Init.Symbols.ResolveCoreType("System.Object").Should().NotBeNull();
}

}

}
39 changes: 39 additions & 0 deletions src/IKVM.CoreLib.Tests/Symbols/Emit/AssemblySymbolBuilderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;

using FluentAssertions;

using IKVM.CoreLib.Symbols;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace IKVM.CoreLib.Tests.Symbols.Emit
{

public abstract class AssemblySymbolBuilderTests<TInit, TSymbols>
where TInit : SymbolTestInit<TSymbols>, new()
where TSymbols: SymbolContext
{

protected TInit Init { get; } = new TInit();

[TestMethod]
public void ThrowsOnFreeze()
{
var a = Init.Symbols.DefineAssembly(new AssemblyIdentity("Test"), []);
a.Freeze();
a.Invoking(_ => _.DefineModule("Test.dll", "Test.dll")).Should().ThrowExactly<InvalidOperationException>();
}

[TestMethod]
public void CanDefineModule()
{
var a = Init.Symbols.DefineAssembly(new AssemblyIdentity("Test"), []);
a.FullName.Should().Be("Test, Version=0.0.0.0, PublicKeyToken=null");
var m = a.DefineModule("Test.dll", "Test.dll");
m.Name.Should().Be("Test.dll");
m.ScopeName.Should().Be("Test.dll");
}

}

}
61 changes: 61 additions & 0 deletions src/IKVM.CoreLib.Tests/Symbols/Emit/ModuleSymbolBuilderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.Reflection;
using System.Reflection.Emit;

using FluentAssertions;

using IKVM.CoreLib.Symbols;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace IKVM.CoreLib.Tests.Symbols.Emit
{

public abstract class ModuleSymbolBuilderTests<TInit, TSymbols>
where TInit : SymbolTestInit<TSymbols>, new()
where TSymbols: SymbolContext
{

protected TInit Init { get; } = new TInit();

[TestMethod]
public void ThrowsOnFreeze()
{
var a = Init.Symbols.DefineAssembly(new AssemblyIdentity("Test"), []);
var m = a.DefineModule("Test.dll", "Test.dll");
m.Freeze();
m.Invoking(_ => _.DefineType("Namespace.TestType", TypeAttributes.Public)).Should().ThrowExactly<InvalidOperationException>();
}

[TestMethod]
public void CanDefineGlobalMethod()
{
var a = Init.Symbols.DefineAssembly(new AssemblyIdentity("Test"), []);
var m = a.DefineModule("Test.dll", "Test.dll");
var f = m.DefineGlobalMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Static, null, []);
f.Name.Should().Be("TestMethod");
f.Module.Should().Be(m);
f.Assembly.Should().Be(a);
f.Attributes.Should().HaveFlag(MethodAttributes.Public);
f.Attributes.Should().HaveFlag(MethodAttributes.Static);
var il = f.GetILGenerator();
il.Emit(OpCodes.Ret);
}

[TestMethod]
public void CanDefineType()
{
var a = Init.Symbols.DefineAssembly(new AssemblyIdentity("Test"), []);
var m = a.DefineModule("Test.dll", "Test.dll");
var t = m.DefineType("Namespace.TestType", TypeAttributes.Public);
t.Assembly.Should().Be(a);
t.Module.Should().Be(m);
t.Name.Should().Be("TestType");
t.FullName.Should().Be("Namespace.TestType");
t.Attributes.Should().HaveFlag(TypeAttributes.Public);
t.Attributes.Should().HaveFlag(TypeAttributes.Class);
}

}

}
64 changes: 64 additions & 0 deletions src/IKVM.CoreLib.Tests/Symbols/Emit/TypeSymbolBuilderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Reflection;
using System.Reflection.Emit;

using FluentAssertions;

using IKVM.CoreLib.Symbols;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace IKVM.CoreLib.Tests.Symbols.Emit
{

public abstract class TypeSymbolBuilderTests<TInit, TSymbols>
where TInit : SymbolTestInit<TSymbols>, new()
where TSymbols: SymbolContext
{

protected TInit Init { get; } = new TInit();

[TestMethod]
public void ThrowsOnFreeze()
{
var a = Init.Symbols.DefineAssembly(new AssemblyIdentity("Test"), []);
var m = a.DefineModule("Test.dll", "Test.dll");
var t = m.DefineType("Test");
t.Freeze();
t.Invoking(_ => _.SetParent(null)).Should().ThrowExactly<InvalidOperationException>();
}

[TestMethod]
public void CanDefineMethod()
{
var a = Init.Symbols.DefineAssembly(new AssemblyIdentity("Test"), []);
var m = a.DefineModule("Test.dll", "Test.dll");
var t = m.DefineType("Test");
var f = t.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Static, null, []);
f.Name.Should().Be("TestMethod");
f.Module.Should().Be(m);
f.Assembly.Should().Be(a);
f.Attributes.Should().HaveFlag(MethodAttributes.Public);
f.Attributes.Should().HaveFlag(MethodAttributes.Static);
var il = f.GetILGenerator();
il.Emit(OpCodes.Ret);
}

[TestMethod]
public void CanDefineNestedType()
{
var a = Init.Symbols.DefineAssembly(new AssemblyIdentity("Test"), []);
var m = a.DefineModule("Test.dll", "Test.dll");
var t = m.DefineType("Namespace.TestType", TypeAttributes.Public);
var n = t.DefineNestedType("NestedType");
n.Assembly.Should().Be(a);
n.Module.Should().Be(m);
n.Name.Should().Be("NestedType");
n.FullName.Should().Be("Namespace.TestType+NestedType");
n.Attributes.Should().HaveFlag(TypeAttributes.Public);
n.Attributes.Should().HaveFlag(TypeAttributes.Class);
}

}

}
Loading
Loading