From edac084b3d2d37cfc7c8ebee49e912be55a47be3 Mon Sep 17 00:00:00 2001
From: mterwoord_cp <7cd3fd84a0151ea055c2f79e4d2eef9576fe9afesxUZAwxD>
Date: Wed, 27 Feb 2008 18:17:59 +0000
Subject: [PATCH] Fixed exceptions
---
source/Indy.IL2CPU.Assembler/Assembler.cs | 1 -
source/Indy.IL2CPU.IL.X86/Box.cs | 10 +-
source/Indy.IL2CPU.IL.X86/Call.cs | 26 +-
source/Indy.IL2CPU.IL.X86/Callvirt.cs | 6 +-
source/Indy.IL2CPU.IL.X86/Castclass.cs | 6 +-
source/Indy.IL2CPU.IL.X86/Ceq.cs | 2 +-
source/Indy.IL2CPU.IL.X86/Cgt.cs | 2 +-
source/Indy.IL2CPU.IL.X86/Clt.cs | 2 +-
source/Indy.IL2CPU.IL.X86/Clt_Un.cs | 2 +-
source/Indy.IL2CPU.IL.X86/Isinst.cs | 8 +-
source/Indy.IL2CPU.IL.X86/Newobj.cs | 12 +-
source/Indy.IL2CPU.IL.X86/Op.cs | 8 +-
source/Indy.IL2CPU.IL.X86/Starg.cs | 1 +
source/Indy.IL2CPU.IL.X86/Throw.cs | 8 +-
source/Indy.IL2CPU.IL.X86/Unbox.cs | 19 +-
.../X86CustomMethodImplementationOp.cs | 2 +-
.../X86CustomMethodImplementationProxyOp.cs | 2 +-
source/Indy.IL2CPU.IL/ILReader.cs | 22 +-
source/Indy.IL2CPU.IL/Op.cs | 2 +-
source/Indy.IL2CPU/Engine.cs | 18 +-
source/TestKernel/Assertion.cs | 36 +
source/TestKernel/Attributes.cs | 23 +-
source/TestKernel/Program.cs | 82 +-
source/TestKernel/TestKernel.csproj | 2 +
source/TestKernel/Tests/NoInit/StringTests.cs | 22 +-
.../NoInit/mscorlib/System/ArrayListTest.cs | 1963 +++++++++++++++++
26 files changed, 2175 insertions(+), 112 deletions(-)
create mode 100644 source/TestKernel/Assertion.cs
create mode 100644 source/TestKernel/Tests/NoInit/mscorlib/System/ArrayListTest.cs
diff --git a/source/Indy.IL2CPU.Assembler/Assembler.cs b/source/Indy.IL2CPU.Assembler/Assembler.cs
index e44188b89..6a06dba7d 100644
--- a/source/Indy.IL2CPU.Assembler/Assembler.cs
+++ b/source/Indy.IL2CPU.Assembler/Assembler.cs
@@ -54,7 +54,6 @@ namespace Indy.IL2CPU.Assembler {
}
public static void ExceptionOccurred() {
- Console.WriteLine("Exception Occurred!");
System.Diagnostics.Debugger.Break();
}
diff --git a/source/Indy.IL2CPU.IL.X86/Box.cs b/source/Indy.IL2CPU.IL.X86/Box.cs
index ed3307f6e..55f1c2f46 100644
--- a/source/Indy.IL2CPU.IL.X86/Box.cs
+++ b/source/Indy.IL2CPU.IL.X86/Box.cs
@@ -22,20 +22,20 @@ namespace Indy.IL2CPU.IL.X86 {
//} else {
mTheSize = Engine.GetFieldStorageSize(xTypeRef);
//}
- if (((mTheSize / 4) * 4) != mTheSize) {
- throw new Exception("Incorrect Datasize. ( ((mTheSize / 4) * 4) === mTheSize should evaluate to true!");
- }
+ //if (((mTheSize / 4) * 4) != mTheSize) {
+ // throw new Exception("Incorrect Datasize. ( ((mTheSize / 4) * 4) === mTheSize should evaluate to true!");
+ //}
//if (!(xTypeRef is GenericParameter)) {
mTypeId = Engine.RegisterType(xTypeRef);
//}
}
public override void DoAssemble() {
- new CPUx86.Pushd("0x" + (4 + ObjectImpl.FieldDataOffset).ToString("X").ToUpper());
+ new CPUx86.Pushd("0x" + (ObjectImpl.FieldDataOffset + mTheSize + (4 - (mTheSize % 4))).ToString("X").ToUpper());
new CPUx86.Call(CPU.Label.GenerateLabelName(RuntimeEngineRefs.Heap_AllocNewObjectRef));
new CPUx86.Move("dword", CPUx86.Registers.AtEAX, "0x" + mTypeId.ToString("X"));
new CPUx86.Move("dword", "[eax + 4]", "0x" + InstanceTypeEnum.BoxedValueType.ToString("X"));
- for (int i = 0; i < (mTheSize / 4); i++) {
+ for (int i = 0; i < ((mTheSize + (4 - (mTheSize % 4))) / 4); i++) {
new CPUx86.Pop(CPUx86.Registers.EDX);
new CPUx86.Move("dword", "[eax + 0x" + (ObjectImpl.FieldDataOffset + (i * 4)).ToString("X") + "]", "edx");
}
diff --git a/source/Indy.IL2CPU.IL.X86/Call.cs b/source/Indy.IL2CPU.IL.X86/Call.cs
index b48ba8b05..b50b1cea3 100644
--- a/source/Indy.IL2CPU.IL.X86/Call.cs
+++ b/source/Indy.IL2CPU.IL.X86/Call.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
-
using CPU = Indy.IL2CPU.Assembler;
using CPUx86 = Indy.IL2CPU.Assembler.X86;
using System.Reflection;
@@ -20,17 +19,21 @@ namespace Indy.IL2CPU.IL.X86 {
private MethodInformation mMethodInfo;
private MethodInformation mTargetMethodInfo;
private string mNextLabelName;
- public Call(MethodBase aMethod)
+ private int mCurrentILOffset;
+ public Call(MethodBase aMethod, int aCurrentILOffset)
: base(null, null) {
if (aMethod == null) {
throw new ArgumentNullException("aMethod");
}
- Initialize(aMethod);
+ Initialize(aMethod, aCurrentILOffset);
}
- public static void EmitExceptionLogic(Assembler.Assembler aAssembler, MethodInformation aMethodInfo, string aNextLabel, bool aDoTest) {
+ public static void EmitExceptionLogic(Assembler.Assembler aAssembler, int aCurrentOpOffset, MethodInformation aMethodInfo, string aNextLabel, bool aDoTest) {
string xJumpTo = MethodFooterOp.EndOfMethodLabelNameException;
if (aMethodInfo != null && aMethodInfo.CurrentHandler != null) {
+ if (aMethodInfo.CurrentHandler.HandlerOffset >= aCurrentOpOffset && (aMethodInfo.CurrentHandler.HandlerLength + aMethodInfo.CurrentHandler.HandlerOffset) <= aCurrentOpOffset) {
+ return;
+ }
switch (aMethodInfo.CurrentHandler.Flags) {
case ExceptionHandlingClauseOptions.Clause: {
xJumpTo = Op.GetInstructionLabel(aMethodInfo.CurrentHandler.HandlerOffset);
@@ -52,20 +55,15 @@ namespace Indy.IL2CPU.IL.X86 {
new CPUx86.Test("ecx", "2");
new CPUx86.JumpIfNotEquals(xJumpTo);
}
- // }
- // new CPUx86.JumpAlways(xJumpTo);
- //}
}
-
- private void Initialize(MethodBase aMethod) {
+ private void Initialize(MethodBase aMethod, int aCurrentILOffset) {
mIsDebugger_Break = aMethod.GetFullName() == "System.Void System.Diagnostics.Debugger.Break()";
if (mIsDebugger_Break) {
return;
}
+ mCurrentILOffset = aCurrentILOffset;
mTargetMethodInfo = Engine.GetMethodInfo(aMethod, aMethod, Label.GenerateLabelName(aMethod), Engine.GetTypeInfo(aMethod.DeclaringType));
-
-
mResultSize = 0;
if (mTargetMethodInfo != null) {
mResultSize = mTargetMethodInfo.ReturnSize;
@@ -102,13 +100,13 @@ namespace Indy.IL2CPU.IL.X86 {
MethodBase xMethod = aReader.OperandValueMethod;
mMethodInfo = aMethodInfo;
if (!aReader.EndOfStream) {
- mNextLabelName = GetInstructionLabel(aReader.Position);
+ mNextLabelName = GetInstructionLabel(aReader.NextPosition);
}
- Initialize(xMethod);
+ Initialize(xMethod, (int)aReader.Position);
}
public void Assemble(string aMethod, int aArgumentCount) {
new CPUx86.Call(aMethod);
- EmitExceptionLogic(Assembler, mMethodInfo, mNextLabelName, true);
+ EmitExceptionLogic(Assembler, mCurrentILOffset, mMethodInfo, mNextLabelName, true);
for (int i = 0; i < aArgumentCount; i++) {
Assembler.StackContents.Pop();
}
diff --git a/source/Indy.IL2CPU.IL.X86/Callvirt.cs b/source/Indy.IL2CPU.IL.X86/Callvirt.cs
index 3c9bb9c9e..fab31b2be 100644
--- a/source/Indy.IL2CPU.IL.X86/Callvirt.cs
+++ b/source/Indy.IL2CPU.IL.X86/Callvirt.cs
@@ -19,6 +19,7 @@ namespace Indy.IL2CPU.IL.X86 {
private readonly string mLabelName;
private readonly MethodInformation mCurrentMethodInfo;
private readonly MethodInformation mTargetMethodInfo;
+ private readonly int mCurrentILOffset;
public Callvirt(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
mLabelName = GetInstructionLabel(aReader);
@@ -43,6 +44,7 @@ namespace Indy.IL2CPU.IL.X86 {
mArgumentCount = mTargetMethodInfo.Arguments.Length;
mReturnSize = mTargetMethodInfo.ReturnSize;
mThisOffset = mTargetMethodInfo.Arguments[0].Offset;
+ mCurrentILOffset = aReader.Position;
}
public override void DoAssemble() {
@@ -59,13 +61,13 @@ namespace Indy.IL2CPU.IL.X86 {
}
//Assembler.Add(new CPUx86.Pop("eax"));
//Assembler.Add(new CPUx86.Pushd("eax"));
- EmitCompareWithNull(Assembler, mCurrentMethodInfo, "[esp + 0x" + mThisOffset.ToString("X") + "]", mLabelName, mLabelName + "_AfterNullRefCheck", xEmitCleanup);
+ EmitCompareWithNull(Assembler, mCurrentMethodInfo, "[esp + 0x" + mThisOffset.ToString("X") + "]", mLabelName, mLabelName + "_AfterNullRefCheck", xEmitCleanup, mCurrentILOffset);
new CPU.Label(mLabelName + "_AfterNullRefCheck");
new CPUx86.Move(CPUx86.Registers.EAX, "[esp + 0x" + mThisOffset.ToString("X") + "]");
new CPUx86.Pushd(CPUx86.Registers.AtEAX);
new CPUx86.Pushd("0" + mMethodIdentifier.ToString("X") + "h");
new CPUx86.Call(CPU.Label.GenerateLabelName(VTablesImplRefs.GetMethodAddressForTypeRef));
- Call.EmitExceptionLogic(Assembler, mCurrentMethodInfo, mLabelName + "_AfterAddressCheck", true);
+ Call.EmitExceptionLogic(Assembler, mCurrentILOffset, mCurrentMethodInfo, mLabelName + "_AfterAddressCheck", true);
new CPU.Label(mLabelName + "_AfterAddressCheck");
if (mTargetMethodInfo.Arguments[0].ArgumentType == typeof(object)) {
new CPUx86.Push("eax");
diff --git a/source/Indy.IL2CPU.IL.X86/Castclass.cs b/source/Indy.IL2CPU.IL.X86/Castclass.cs
index f6b5097de..a736800e9 100644
--- a/source/Indy.IL2CPU.IL.X86/Castclass.cs
+++ b/source/Indy.IL2CPU.IL.X86/Castclass.cs
@@ -14,6 +14,7 @@ namespace Indy.IL2CPU.IL.X86 {
private string mThisLabel;
private string mNextOpLabel;
private Type mCastAsType;
+ private int mCurrentILOffset;
public Castclass(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
Type xType = aReader.OperandValueType;
@@ -23,7 +24,8 @@ namespace Indy.IL2CPU.IL.X86 {
mCastAsType = xType;
mTypeId = Engine.RegisterType(mCastAsType);
mThisLabel = GetInstructionLabel(aReader);
- mNextOpLabel = GetInstructionLabel(aReader.Position);
+ mNextOpLabel = GetInstructionLabel(aReader.NextPosition);
+ mCurrentILOffset = (int)aReader.Position;
}
public override void DoAssemble() {
@@ -39,7 +41,7 @@ namespace Indy.IL2CPU.IL.X86 {
Assembler.StackContents.Push(new StackContent(4, true, false, false));
MethodBase xMethodIsInstance = Engine.GetMethodBase(Engine.GetType("", "Indy.IL2CPU.VTablesImpl"), "IsInstance", "System.Int32", "System.Int32");
Engine.QueueMethod(xMethodIsInstance);
- Op xOp = new Call(xMethodIsInstance);
+ Op xOp = new Call(xMethodIsInstance, mCurrentILOffset);
xOp.Assembler = Assembler;
xOp.Assemble();
new CPUx86.Pop(CPUx86.Registers.EAX);
diff --git a/source/Indy.IL2CPU.IL.X86/Ceq.cs b/source/Indy.IL2CPU.IL.X86/Ceq.cs
index b8c3f82f7..afbdecfd8 100644
--- a/source/Indy.IL2CPU.IL.X86/Ceq.cs
+++ b/source/Indy.IL2CPU.IL.X86/Ceq.cs
@@ -12,7 +12,7 @@ namespace Indy.IL2CPU.IL.X86 {
private readonly string CurInstructionLabel;
public Ceq(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
- NextInstructionLabel = GetInstructionLabel(aReader.Position);
+ NextInstructionLabel = GetInstructionLabel(aReader.NextPosition);
CurInstructionLabel = GetInstructionLabel(aReader);
}
private void Assemble4Byte() {
diff --git a/source/Indy.IL2CPU.IL.X86/Cgt.cs b/source/Indy.IL2CPU.IL.X86/Cgt.cs
index d70b6182c..a920cc673 100644
--- a/source/Indy.IL2CPU.IL.X86/Cgt.cs
+++ b/source/Indy.IL2CPU.IL.X86/Cgt.cs
@@ -13,7 +13,7 @@ namespace Indy.IL2CPU.IL.X86 {
private readonly string CurInstructionLabel;
public Cgt(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
- NextInstructionLabel = GetInstructionLabel(aReader.Position);
+ NextInstructionLabel = GetInstructionLabel(aReader.NextPosition);
CurInstructionLabel = GetInstructionLabel(aReader);
}
public override void DoAssemble() {
diff --git a/source/Indy.IL2CPU.IL.X86/Clt.cs b/source/Indy.IL2CPU.IL.X86/Clt.cs
index bf913efde..8508f017c 100644
--- a/source/Indy.IL2CPU.IL.X86/Clt.cs
+++ b/source/Indy.IL2CPU.IL.X86/Clt.cs
@@ -13,7 +13,7 @@ namespace Indy.IL2CPU.IL.X86 {
private readonly string CurInstructionLabel;
public Clt(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
- NextInstructionLabel = GetInstructionLabel(aReader.Position);
+ NextInstructionLabel = GetInstructionLabel(aReader.NextPosition);
CurInstructionLabel = GetInstructionLabel(aReader);
}
public override void DoAssemble() {
diff --git a/source/Indy.IL2CPU.IL.X86/Clt_Un.cs b/source/Indy.IL2CPU.IL.X86/Clt_Un.cs
index 7eff44e2b..56361dd69 100644
--- a/source/Indy.IL2CPU.IL.X86/Clt_Un.cs
+++ b/source/Indy.IL2CPU.IL.X86/Clt_Un.cs
@@ -13,7 +13,7 @@ namespace Indy.IL2CPU.IL.X86 {
private readonly string CurInstructionLabel;
public Clt_Un(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
- NextInstructionLabel = GetInstructionLabel(aReader.Position);
+ NextInstructionLabel = GetInstructionLabel(aReader.NextPosition);
CurInstructionLabel = GetInstructionLabel(aReader);
}
public override void DoAssemble() {
diff --git a/source/Indy.IL2CPU.IL.X86/Isinst.cs b/source/Indy.IL2CPU.IL.X86/Isinst.cs
index 1547d85a7..e8e556196 100644
--- a/source/Indy.IL2CPU.IL.X86/Isinst.cs
+++ b/source/Indy.IL2CPU.IL.X86/Isinst.cs
@@ -13,6 +13,7 @@ namespace Indy.IL2CPU.IL.X86 {
private int mTypeId;
private string mThisLabel;
private string mNextOpLabel;
+ private int mCurrentILOffset;
public Isinst(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
Type xType = aReader.OperandValueType;
@@ -21,8 +22,9 @@ namespace Indy.IL2CPU.IL.X86 {
}
Type xTypeDef = xType;
mTypeId = Engine.RegisterType(xTypeDef);
- mThisLabel = GetInstructionLabel(aReader.OldPosition);
- mNextOpLabel = GetInstructionLabel(aReader.Position);
+ mThisLabel = GetInstructionLabel(aReader.Position);
+ mNextOpLabel = GetInstructionLabel(aReader.NextPosition);
+ mCurrentILOffset = (int)aReader.Position;
}
public override void DoAssemble() {
@@ -35,7 +37,7 @@ namespace Indy.IL2CPU.IL.X86 {
Assembler.StackContents.Push(new StackContent(4, typeof(object)));
MethodBase xMethodIsInstance = Engine.GetMethodBase(typeof(VTablesImpl), "IsInstance", "System.Int32", "System.Int32");
Engine.QueueMethod(xMethodIsInstance);
- Op xOp = new Call(xMethodIsInstance);
+ Op xOp = new Call(xMethodIsInstance, mCurrentILOffset);
xOp.Assembler = Assembler;
xOp.Assemble();
new CPUx86.Pop(CPUx86.Registers.EAX);
diff --git a/source/Indy.IL2CPU.IL.X86/Newobj.cs b/source/Indy.IL2CPU.IL.X86/Newobj.cs
index 68d0c5ee9..96ddfe39b 100644
--- a/source/Indy.IL2CPU.IL.X86/Newobj.cs
+++ b/source/Indy.IL2CPU.IL.X86/Newobj.cs
@@ -15,22 +15,20 @@ namespace Indy.IL2CPU.IL.X86 {
public MethodBase CtorDef;
public string CurrentLabel;
public MethodInformation MethodInformation;
- public Newobj()
- : base(null, null) {
- }
-
+ public int ILOffset;
public Newobj(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
CtorDef = aReader.OperandValueMethod;
CurrentLabel = GetInstructionLabel(aReader);
MethodInformation = aMethodInfo;
+ ILOffset = (int)aReader.Position;
}
public override void DoAssemble() {
- Assemble(Assembler, ObjectUtilities.GetObjectStorageSize(CtorDef.DeclaringType), CtorDef, Engine.RegisterType(CtorDef.DeclaringType), CurrentLabel, MethodInformation);
+ Assemble(Assembler, ObjectUtilities.GetObjectStorageSize(CtorDef.DeclaringType), CtorDef, Engine.RegisterType(CtorDef.DeclaringType), CurrentLabel, MethodInformation, ILOffset);
}
- public static void Assemble(Assembler.Assembler aAssembler, int aObjectSize, MethodBase aCtorDef, int aTypeId, string aCurrentLabel, MethodInformation aCurrentMethodInformation) {
+ public static void Assemble(Assembler.Assembler aAssembler, int aObjectSize, MethodBase aCtorDef, int aTypeId, string aCurrentLabel, MethodInformation aCurrentMethodInformation, int aCurrentILOffset) {
if (aCtorDef != null) {
Engine.QueueMethod(aCtorDef);
} else {
@@ -103,7 +101,7 @@ namespace Indy.IL2CPU.IL.X86 {
foreach (var xStackInt in aAssembler.StackContents) {
new CPUx86.Add("esp", xStackInt.Size.ToString());
}
- Call.EmitExceptionLogic(aAssembler, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_4", false);
+ Call.EmitExceptionLogic(aAssembler, aCurrentILOffset, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_4", false);
new CPU.Label(aCurrentLabel + "_NO_ERROR_4");
new CPUx86.Pop(CPUx86.Registers.EAX);
// aAssembler.StackSizes.Pop();
diff --git a/source/Indy.IL2CPU.IL.X86/Op.cs b/source/Indy.IL2CPU.IL.X86/Op.cs
index c83a79a5e..450dcb5ee 100644
--- a/source/Indy.IL2CPU.IL.X86/Op.cs
+++ b/source/Indy.IL2CPU.IL.X86/Op.cs
@@ -19,18 +19,18 @@ namespace Indy.IL2CPU.IL.X86 {
///
///
///
- public static void EmitCompareWithNull(Assembler.Assembler aAssembler, MethodInformation aMethodInfo, string aAddress, string aCurrentLabel, string aNextLabel, Action aEmitCleanupMethod) {
+ public static void EmitCompareWithNull(Assembler.Assembler aAssembler, MethodInformation aMethodInfo, string aAddress, string aCurrentLabel, string aNextLabel, Action aEmitCleanupMethod, int aCurrentILOffset) {
new CPUx86.Compare("dword " + aAddress, "0");
new CPUx86.JumpIfNotEquals(aNextLabel);
Type xNullRefExcType = typeof(NullReferenceException);
- Newobj.Assemble(aAssembler, Engine.GetTypeInfo(xNullRefExcType).StorageSize, xNullRefExcType.GetConstructor(new Type[0]), Engine.RegisterType(xNullRefExcType), aCurrentLabel, aMethodInfo);
+ Newobj.Assemble(aAssembler, Engine.GetTypeInfo(xNullRefExcType).StorageSize, xNullRefExcType.GetConstructor(new Type[0]), Engine.RegisterType(xNullRefExcType), aCurrentLabel, aMethodInfo, aCurrentILOffset);
aAssembler.StackContents.Pop();
new CPUx86.Move("[" + DataMember.GetStaticFieldName(CPU.Assembler.CurrentExceptionRef) + "]", "eax");
Engine.QueueMethod(CPU.Assembler.CurrentExceptionOccurredRef);
new CPUx86.Call(Label.GenerateLabelName(CPU.Assembler.CurrentExceptionOccurredRef));
new CPUx86.Move("ecx", "3");
aEmitCleanupMethod();
- Call.EmitExceptionLogic(aAssembler, aMethodInfo, aNextLabel, false);
+ Call.EmitExceptionLogic(aAssembler, aCurrentILOffset, aMethodInfo, aNextLabel, false);
}
public Op(ILReader aReader, MethodInformation aMethodInfo)
@@ -65,7 +65,7 @@ namespace Indy.IL2CPU.IL.X86 {
mCatchType = null;
}
if (mCatchType != null && aMethodInfo != null && aMethodInfo.CurrentHandler != null && aMethodInfo.CurrentHandler.HandlerOffset > 0) {
- mNeedsTypeCheck = aMethodInfo.CurrentHandler.HandlerOffset == aReader.Position;
+ mNeedsTypeCheck = aMethodInfo.CurrentHandler.HandlerOffset == aReader.NextPosition;
}
}
diff --git a/source/Indy.IL2CPU.IL.X86/Starg.cs b/source/Indy.IL2CPU.IL.X86/Starg.cs
index ecee9080b..da8adbc56 100644
--- a/source/Indy.IL2CPU.IL.X86/Starg.cs
+++ b/source/Indy.IL2CPU.IL.X86/Starg.cs
@@ -9,6 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
private string[] mAddresses;
protected void SetArgIndex(int aIndex, MethodInformation aMethodInfo) {
mAddresses = aMethodInfo.Arguments[aIndex].VirtualAddresses;
+
}
public Starg(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
diff --git a/source/Indy.IL2CPU.IL.X86/Throw.cs b/source/Indy.IL2CPU.IL.X86/Throw.cs
index 70f4c8ff5..7de89d676 100644
--- a/source/Indy.IL2CPU.IL.X86/Throw.cs
+++ b/source/Indy.IL2CPU.IL.X86/Throw.cs
@@ -10,23 +10,25 @@ namespace Indy.IL2CPU.IL.X86 {
[OpCode(OpCodeEnum.Throw, false)]
public class Throw: Op {
private MethodInformation mMethodInfo;
+ private int mCurrentILOffset;
public Throw(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
mMethodInfo = aMethodInfo;
+ mCurrentILOffset = (int)aReader.Position;
}
- public static void Assemble(Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
+ public static void Assemble(Assembler.Assembler aAssembler, MethodInformation aMethodInfo, int aCurrentILOffset) {
new CPUx86.Pop("eax");
new CPUx86.Move("[" + CPU.DataMember.GetStaticFieldName(CPU.Assembler.CurrentExceptionRef) + "]", "eax");
Engine.QueueMethod(CPU.Assembler.CurrentExceptionOccurredRef);
new CPUx86.Call(CPU.Label.GenerateLabelName(CPU.Assembler.CurrentExceptionOccurredRef));
new CPUx86.Move("ecx", "3");
- Call.EmitExceptionLogic(aAssembler, aMethodInfo, null, false);
+ Call.EmitExceptionLogic(aAssembler,aCurrentILOffset, aMethodInfo, null, false);
aAssembler.StackContents.Pop();
}
public override void DoAssemble() {
- Assemble(Assembler, mMethodInfo);
+ Assemble(Assembler, mMethodInfo, mCurrentILOffset);
}
}
}
\ No newline at end of file
diff --git a/source/Indy.IL2CPU.IL.X86/Unbox.cs b/source/Indy.IL2CPU.IL.X86/Unbox.cs
index deac9470e..a70df19c2 100644
--- a/source/Indy.IL2CPU.IL.X86/Unbox.cs
+++ b/source/Indy.IL2CPU.IL.X86/Unbox.cs
@@ -15,6 +15,7 @@ namespace Indy.IL2CPU.IL.X86 {
private string mNextOpLabel;
private Type mType;
private int mTypeSize;
+ private int mCurrentILOffset;
public Unbox(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
mType = aReader.OperandValueType;
@@ -24,11 +25,12 @@ namespace Indy.IL2CPU.IL.X86 {
mTypeSize = Engine.GetFieldStorageSize(mType);
mTypeId = Engine.RegisterType(mType);
mThisLabel = GetInstructionLabel(aReader);
- mNextOpLabel = GetInstructionLabel(aReader.Position);
+ mNextOpLabel = GetInstructionLabel(aReader.NextPosition);
+ mCurrentILOffset = aReader.Position;
}
public override void DoAssemble() {
string mReturnNullLabel = mThisLabel + "_ReturnNull";
- new CPUx86.Pop(CPUx86.Registers.EAX);
+ new CPUx86.Move(CPUx86.Registers.EAX, CPUx86.Registers.AtESP);
new CPUx86.Compare(CPUx86.Registers.EAX, "0");
new CPUx86.JumpIfZero(mReturnNullLabel);
new CPUx86.Pushd(CPUx86.Registers.AtEAX);
@@ -37,17 +39,26 @@ namespace Indy.IL2CPU.IL.X86 {
Assembler.StackContents.Push(new StackContent(4, typeof(uint)));
MethodBase xMethodIsInstance = Engine.GetMethodBase(Engine.GetType("", "Indy.IL2CPU.VTablesImpl"), "IsInstance", "System.Int32", "System.Int32");
Engine.QueueMethod(xMethodIsInstance);
- Op xOp = new Call(xMethodIsInstance);
+ Op xOp = new Call(xMethodIsInstance, mCurrentILOffset);
xOp.Assembler = Assembler;
xOp.Assemble();
new CPUx86.Pop(CPUx86.Registers.EAX);
Assembler.StackContents.Pop();
new CPUx86.Compare(CPUx86.Registers.EAX, "0");
new CPUx86.JumpIfEquals(mReturnNullLabel);
- new CPUx86.Pushd(CPUx86.Registers.EAX);
+ new CPUx86.Pop(CPUx86.Registers.EAX);
+ int xSize = mTypeSize;
+ if (xSize % 4 > 0) {
+ xSize += 4 - (xSize % 4);
+ }
+ int xItems = xSize /4;
+ for (int i = xItems - 1; i >= 0; i--) {
+ new CPUx86.Push("[eax + " + ((i * 4) + ObjectImpl.FieldDataOffset) + "]");
+ }
Assembler.StackContents.Push(new StackContent(mTypeSize, mType));
new CPUx86.JumpAlways(mNextOpLabel);
new CPU.Label(mReturnNullLabel);
+ new CPUx86.Add(CPUx86.Registers.ESP, "4");
new CPUx86.Pushd("0");
Assembler.StackContents.Push(new StackContent(4, typeof(object)));
}
diff --git a/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationOp.cs b/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationOp.cs
index c60d8f3ec..ee5ac4933 100644
--- a/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationOp.cs
+++ b/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationOp.cs
@@ -21,7 +21,7 @@ namespace Indy.IL2CPU.IL.X86 {
Ldarg.Ldarg(Assembler, MethodInfo.Arguments[i]);
}
Engine.QueueMethod(aMethod);
- Op xOp = new Call(aMethod);
+ Op xOp = new Call(aMethod,0);
xOp.Assembler = Assembler;
xOp.Assemble();
}
diff --git a/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationProxyOp.cs b/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationProxyOp.cs
index c6df03dc6..a6507fd7d 100644
--- a/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationProxyOp.cs
+++ b/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationProxyOp.cs
@@ -20,7 +20,7 @@ namespace Indy.IL2CPU.IL.X86 {
}
protected override void CallProxiedMethod() {
- Op x = new Call(ProxiedMethod);
+ Op x = new Call(ProxiedMethod, 0);
x.Assembler = Assembler;
x.Assemble();
}
diff --git a/source/Indy.IL2CPU.IL/ILReader.cs b/source/Indy.IL2CPU.IL/ILReader.cs
index 8f692709f..da0ffd6cd 100644
--- a/source/Indy.IL2CPU.IL/ILReader.cs
+++ b/source/Indy.IL2CPU.IL/ILReader.cs
@@ -21,14 +21,14 @@ namespace Indy.IL2CPU.IL {
private byte[] mOperand;
private bool mHasOperand;
- public long OldPosition {
+ public int Position {
get;
private set;
}
- public long Position {
+ public int NextPosition {
get {
- return mStream.Position;
+ return (int)mStream.Position;
}
}
@@ -91,17 +91,17 @@ namespace Indy.IL2CPU.IL {
if (mOperandValueBranchPosition == null) {
//sbyte xTemp = (sbyte)mOperand;
//if (xTemp == mOperand) {
- // mOperandValueBranchPosition = Position + xTemp;
+ // mOperandValueBranchPosition = NextPosition + xTemp;
//} else {
- // if (mStream.Length < (Position + mOperand + 1)) {
+ // if (mStream.Length < (NextPosition + mOperand + 1)) {
// mOperandValueBranchPosition = (uint)mOperand;
// } else {
- // mOperandValueBranchPosition = (uint)(Position + mOperand);
+ // mOperandValueBranchPosition = (uint)(NextPosition + mOperand);
// }
if (!mIsShortcut) {
- mOperandValueBranchPosition = (uint?)(Position + OperandValueInt32);
+ mOperandValueBranchPosition = (uint?)(NextPosition + OperandValueInt32);
} else {
- mOperandValueBranchPosition = (uint?)(Position + (sbyte)OperandValueInt32);
+ mOperandValueBranchPosition = (uint?)(NextPosition + (sbyte)OperandValueInt32);
}
//}
}
@@ -183,7 +183,7 @@ namespace Indy.IL2CPU.IL {
}
public bool Read() {
- OldPosition = Position;
+ Position = NextPosition;
int xByteValueInt = mStream.ReadByte();
OpCodeEnum xOpCode;
if (xByteValueInt == -1) {
@@ -231,10 +231,10 @@ namespace Indy.IL2CPU.IL {
}
uint[] xResult = new uint[xBranchLocations1.Length];
for (int i = 0; i < xBranchLocations1.Length; i++) {
- if ((Position + xBranchLocations1[i]) < 0) {
+ if ((NextPosition + xBranchLocations1[i]) < 0) {
xResult[i] = (uint)xBranchLocations1[i];
} else {
- xResult[i] = (uint)(Position + xBranchLocations1[i]);
+ xResult[i] = (uint)(NextPosition + xBranchLocations1[i]);
}
}
OperandValueBranchLocations = xResult;
diff --git a/source/Indy.IL2CPU.IL/Op.cs b/source/Indy.IL2CPU.IL/Op.cs
index 6afdd8861..37de6c1bc 100644
--- a/source/Indy.IL2CPU.IL/Op.cs
+++ b/source/Indy.IL2CPU.IL/Op.cs
@@ -12,7 +12,7 @@ namespace Indy.IL2CPU.IL {
private readonly string mILComment;
private readonly bool mSupportsMetalMode;
public static string GetInstructionLabel(ILReader aReader) {
- return GetInstructionLabel(aReader.OldPosition);
+ return GetInstructionLabel(aReader.Position);
}
public static string GetInstructionLabel(long aPosition) {
return ".L" + aPosition.ToString("X8");
diff --git a/source/Indy.IL2CPU/Engine.cs b/source/Indy.IL2CPU/Engine.cs
index 6e504da84..538b96914 100644
--- a/source/Indy.IL2CPU/Engine.cs
+++ b/source/Indy.IL2CPU/Engine.cs
@@ -411,7 +411,7 @@ namespace Indy.IL2CPU {
// GenericParameter xGenericParam = xArray.ElementType as GenericParameter;
// GenericParameter xFoundGenericParam = xFoundArray.ElementType as GenericParameter;
// if (xGenericParam != null && xFoundGenericParam != null) {
- // if (xGenericParam.Position != xFoundGenericParam.Position) {
+ // if (xGenericParam.NextPosition != xFoundGenericParam.NextPosition) {
// continue;
// }
// }
@@ -551,8 +551,8 @@ namespace Indy.IL2CPU {
public static int GetFieldStorageSize(Type aType) {
if (aType.FullName == "System.Void") {
return 0;
- }
- if (!aType.IsValueType && aType.IsClass) {
+ }
+ if ((!aType.IsValueType && aType.IsClass) || aType.IsInterface) {
return 4;
}
switch (aType.FullName) {
@@ -766,12 +766,6 @@ namespace Indy.IL2CPU {
MethodBody xBody = xCurrentMethod.GetMethodBody();
// todo: add better detection of implementation state
if (xBody != null) {
- // todo: add support for types which need different stack size
- //foreach (LocalVariableInfo xLocal in xBody.LocalVariables) {
- // if (xLocal.LocalType.IsValueType && !xLocal.LocalType.IsPrimitive && !xLocal.LocalType.IsEnum && !xLocal.LocalType.IsPointer) {
- // throw new Exception("Structs as locals not yet supported!");
- // }
- //}
mInstructionsToSkip = 0;
mAssembler.StackContents.Clear();
ILReader xReader = new ILReader(xCurrentMethod);
@@ -783,7 +777,7 @@ namespace Indy.IL2CPU {
ExceptionHandlingClause xCurrentHandler = null;
foreach (ExceptionHandlingClause xHandler in xBody.ExceptionHandlingClauses) {
if (xHandler.TryOffset > 0) {
- if (xHandler.TryOffset <= xReader.Position && (xHandler.TryLength + xHandler.TryOffset) > xReader.Position) {
+ if (xHandler.TryOffset <= xReader.NextPosition && (xHandler.TryLength + xHandler.TryOffset) > xReader.NextPosition) {
if (xCurrentHandler == null) {
xCurrentHandler = xHandler;
continue;
@@ -796,7 +790,7 @@ namespace Indy.IL2CPU {
}
}
if (xHandler.HandlerOffset > 0) {
- if (xHandler.HandlerOffset <= xReader.Position && (xHandler.HandlerOffset + xHandler.HandlerLength) > xReader.Position) {
+ if (xHandler.HandlerOffset <= xReader.NextPosition && (xHandler.HandlerOffset + xHandler.HandlerLength) > xReader.NextPosition) {
if (xCurrentHandler == null) {
xCurrentHandler = xHandler;
continue;
@@ -810,7 +804,7 @@ namespace Indy.IL2CPU {
}
if ((xHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0) {
if (xHandler.FilterOffset > 0) {
- if (xHandler.FilterOffset <= xReader.Position) {
+ if (xHandler.FilterOffset <= xReader.NextPosition) {
if (xCurrentHandler == null) {
xCurrentHandler = xHandler;
continue;
diff --git a/source/TestKernel/Assertion.cs b/source/TestKernel/Assertion.cs
new file mode 100644
index 000000000..4636a445b
--- /dev/null
+++ b/source/TestKernel/Assertion.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace NUnit.Framework {
+ public class Assertion {
+ public class AssertException:Exception {
+ public AssertException(string aMessage):base(aMessage) {
+ }
+ }
+ public static void AssertNotNull(string aMessage, object aObject) {
+ if (aObject == null) {
+ throw new AssertException(aMessage);
+ }
+ }
+ public static void Assert(string aMessage, bool aAssert) {
+ if (!aAssert) {
+ throw new AssertException(aMessage);
+ }
+ }
+
+ public static void Fail(string aMessage) {
+ throw new AssertException(aMessage);
+ }
+ public static void AssertEquals(string aMessage, int a, int b) {
+ if (a != b) {
+ Fail(aMessage);
+ }
+ }
+ public static void AssertEquals(string aMessage, object a, object b) {
+ if (!Object.Equals(a, b)) {
+ Fail(aMessage);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/TestKernel/Attributes.cs b/source/TestKernel/Attributes.cs
index ef3217e3e..68298ab71 100644
--- a/source/TestKernel/Attributes.cs
+++ b/source/TestKernel/Attributes.cs
@@ -1,11 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using TestKernel;
-namespace TestKernel {
+namespace System {
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class TestFixtureAttribute:Attribute {
+ public string BaseName {
+ get;
+ set;
+ }
+ }
[AttributeUsage(AttributeTargets.Method)]
public sealed class TestAttribute: Attribute {
public TestAttribute() {
+ TestGroup = TestGroups.NoInit;
}
public string TestGroup {
@@ -13,7 +22,7 @@ namespace TestKernel {
set;
}
- public string Description {
+ public string Name{
get;
set;
}
@@ -23,4 +32,14 @@ namespace TestKernel {
set;
}
}
+ [AttributeUsage(AttributeTargets.Method)]
+ public sealed class ExpectedExceptionAttribute: Attribute {
+ public ExpectedExceptionAttribute(Type aException) {
+ Exception = aException;
+ }
+ public Type Exception {
+ get;
+ set;
+ }
+ }
}
diff --git a/source/TestKernel/Program.cs b/source/TestKernel/Program.cs
index 23f7bdbfd..9d27d23bb 100644
--- a/source/TestKernel/Program.cs
+++ b/source/TestKernel/Program.cs
@@ -6,36 +6,75 @@ using Cosmos.Build.Windows;
namespace TestKernel {
class Program {
+ private class TestInfo {
+ public Type ExpectedException;
+ public string Name;
+ public string TestGroup;
+ public bool IsExperimental;
+ }
[STAThread]
public static void Main(string[] aArgs) {
if (aArgs.Length == 0) {
var xBuilder = new Builder();
xBuilder.Build();
} else {
- List> xTests = new List>();
+ List> xTests = new List>();
#region detect all current tests
foreach (var xType in typeof(Program).Assembly.GetTypes()) {
+ string xBaseName = "";
+ var xFixture = xType.GetCustomAttributes(typeof(TestFixtureAttribute), true).FirstOrDefault() as TestFixtureAttribute;
+ if (xFixture != null) {
+ xBaseName = xFixture.BaseName;
+ }
+ if (String.IsNullOrEmpty(xBaseName)) {
+ xBaseName = xType.FullName;
+ }
foreach (var xMethod in xType.GetMethods()) {
var xAttrib = xMethod.GetCustomAttributes(typeof(TestAttribute), true).FirstOrDefault() as TestAttribute;
if (xAttrib != null) {
- xTests.Add(new KeyValuePair(xType.FullName.Replace('+', '.') + "." + xMethod.Name, xAttrib));
+ string xName = xAttrib.Name;
+ if (String.IsNullOrEmpty(xName)) {
+ xName = xBaseName + "." + xMethod.Name;
+ }
+ Type xExpectedException = null;
+ var xExpException = xMethod.GetCustomAttributes(typeof(ExpectedExceptionAttribute), true).FirstOrDefault() as ExpectedExceptionAttribute;
+ if (xExpException != null) {
+ xExpectedException = xExpException.Exception;
+ }
+ xTests.Add(new KeyValuePair(xType.FullName.Replace('+', '.') + "." + xMethod.Name, new TestInfo() {
+ ExpectedException = xExpectedException,
+ Name = xName,
+ IsExperimental = xAttrib.IsExperimental,
+ TestGroup = xAttrib.TestGroup
+ }));
}
}
}
#endregion
Console.WriteLine("public static void Init() {");
Console.WriteLine("string xTestResult=null;");
+ Console.WriteLine("bool xError;");
foreach (var xTest in (from item in xTests
- where item.Value.TestGroup == aArgs[0] && ((!item.Value.IsExperimental) || ((aArgs.Length > 1) && (aArgs[1] == "-experimental")))
- select item)) {
- Console.WriteLine("Console.WriteLine(\"Running test '{0}'\");", xTest.Value.Description);
- Console.WriteLine("xTestResult = {0}();", xTest.Key);
+ where item.Value.TestGroup == aArgs[0] && ((!item.Value.IsExperimental) || ((aArgs.Length > 1) && (aArgs[1] == "-experimental")))
+ select item)) {
+ Console.WriteLine("Console.WriteLine(\"Running test '{0}'\");", xTest.Value.Name);
+ Console.WriteLine("try{");
+ Console.WriteLine("xError = false;");
+ Console.WriteLine("{0}();", xTest.Key);
+ if (xTest.Value.ExpectedException != null) {
+ Console.WriteLine("}}catch({0}){{", xTest.Value.ExpectedException.FullName.Replace("+", "."));
+ }
+ if (xTest.Value.ExpectedException != typeof(Exception)) {
+ Console.WriteLine("}catch(Exception E){");
+ Console.WriteLine("Console.Write(\" \");");
+ Console.WriteLine("Console.WriteLine(E.Message);");
+ Console.WriteLine("xError = true;");
+ }
+ Console.WriteLine("}");
+ Console.WriteLine("if(!xError){");
Console.WriteLine("Console.Write(\" \");");
- Console.WriteLine("if (xTestResult == null) {");
Console.WriteLine("Console.WriteLine(\"Success\");");
- Console.WriteLine("} else {");
- Console.WriteLine("Console.Write(\"Error: \");");
- Console.WriteLine("Console.WriteLine(xTestResult);}");
+ Console.WriteLine("}");
}
Console.WriteLine("Console.WriteLine(\"All tests executed!\");");
@@ -47,14 +86,23 @@ namespace TestKernel {
public static void Init() {
string xTestResult = null;
- Console.WriteLine("Running test 'System.String_EmbeddedStringContents'");
- xTestResult = TestKernel.Tests.NoInit.StringTests.TestEmbedded();
- Console.Write(" ");
- if (xTestResult == null) {
+ bool xError;
+ Console.WriteLine("Running test 'Whoohoo'");
+ try {
+ xError = false;
+ TestKernel.Tests.NoInit.StringTests.OurTest();
+ } catch (Exception E) {
+ Console.Write(" ");
+ if (E == null) {
+ Console.WriteLine("<>");
+ } else {
+ Console.WriteLine(E.Message);
+ }
+ xError = true;
+ }
+ if (!xError) {
+ Console.Write(" ");
Console.WriteLine("Success");
- } else {
- Console.Write("Error: ");
- Console.WriteLine(xTestResult);
}
Console.WriteLine("All tests executed!");
while (true)
diff --git a/source/TestKernel/TestKernel.csproj b/source/TestKernel/TestKernel.csproj
index ee1cc81d5..bf7cf270a 100644
--- a/source/TestKernel/TestKernel.csproj
+++ b/source/TestKernel/TestKernel.csproj
@@ -49,10 +49,12 @@
+
+
diff --git a/source/TestKernel/Tests/NoInit/StringTests.cs b/source/TestKernel/Tests/NoInit/StringTests.cs
index 28b645393..afa335486 100644
--- a/source/TestKernel/Tests/NoInit/StringTests.cs
+++ b/source/TestKernel/Tests/NoInit/StringTests.cs
@@ -4,24 +4,10 @@ using System.Linq;
namespace TestKernel.Tests.NoInit {
public static class StringTests {
- [Test(TestGroup=TestGroups.NoInit, Description="System.String_EmbeddedStringContents", IsExperimental=false)]
- public static string TestEmbedded() {
- string MyString = "Hello";
- if (MyString == null)
- return "MyString is null";
- if (MyString.Length != 5)
- return "MyString Length is not 5";
- if (MyString[0] != 'H')
- return "MyString[0] != 'H'";
- if (MyString[1] != 'e')
- return "MyString[1] != 'e'";
- if (MyString[2] != 'l')
- return "MyString[2] != 'l'";
- if (MyString[3] != 'l')
- return "MyString[3] != 'l'";
- if (MyString[4] != 'o')
- return "MyString[4] != 'o'";
- return null;
+ [Test(Name="Whoohoo", TestGroup="Test")]
+ public static void OurTest() {
+ // succeeds
+ throw new Exception("Error");
}
}
}
\ No newline at end of file
diff --git a/source/TestKernel/Tests/NoInit/mscorlib/System/ArrayListTest.cs b/source/TestKernel/Tests/NoInit/mscorlib/System/ArrayListTest.cs
new file mode 100644
index 000000000..50b20b7a3
--- /dev/null
+++ b/source/TestKernel/Tests/NoInit/mscorlib/System/ArrayListTest.cs
@@ -0,0 +1,1963 @@
+// ArrayListTest.cs - NUnit Test Cases for the System.Collections.ArrayList class
+//
+// David Brandt (bucky@keystreams.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+// Copyright (C) 2005 Novell (http://www.novell.com)
+//
+
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+namespace MonoTests.System.Collections
+{
+ [TestFixture]
+ public class ArrayListTest : Assertion
+ {
+ [Test]
+ public static void TestCtor ()
+ {
+ {
+ ArrayList al1 = new ArrayList ();
+ AssertNotNull ("no basic ArrayList", al1);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList (null);
+ } catch (ArgumentNullException) {
+ errorThrown = true;
+ }
+ Assert ("null icollection error not thrown",
+ errorThrown);
+ }
+ {
+ try {
+ Char [,] c1 = new Char [2, 2];
+ ArrayList al1 = new ArrayList (c1);
+ Fail ("Should fail with multi-dimensional array in constructor.");
+ } catch (RankException) {
+ }
+ }
+
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList (-1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("negative capacity error not thrown",
+ errorThrown);
+ }
+ }
+
+ [Test]
+ public static void TestCapacity ()
+ {
+#if NET_2_0
+ int default_capacity = 4;
+ int unspecified_capacity = 0;
+#else
+ int default_capacity = 16;
+ int unspecified_capacity = 16;
+#endif
+ for (int i = 1; i < 100; i++) {
+ ArrayList al1 = new ArrayList (i);
+ AssertEquals ("Bad capacity of " + i,
+ i, al1.Capacity);
+ }
+ {
+ ArrayList al1 = new ArrayList (0);
+ // LAMESPEC:
+ // AssertEquals("Bad capacity when set to 0",
+ // 16, al1.Capacity);
+ al1.Add ("?");
+ AssertEquals ("Bad capacity when set to 0",
+ default_capacity, al1.Capacity);
+ }
+ {
+ ArrayList al1 = new ArrayList ();
+ AssertEquals ("Bad default capacity",
+ unspecified_capacity, al1.Capacity);
+ }
+ }
+
+ [Test]
+ public static void TestCount ()
+ {
+ {
+ ArrayList al1 = new ArrayList ();
+ AssertEquals ("Bad initial count",
+ 0, al1.Count);
+ for (int i = 1; i <= 100; i++) {
+ al1.Add (i);
+ AssertEquals ("Bad count " + i,
+ i, al1.Count);
+ }
+ }
+ for (int i = 0; i < 100; i++) {
+ char [] coll = new Char [i];
+ ArrayList al1 = new ArrayList (coll);
+ AssertEquals ("Bad count for " + i,
+ i, al1.Count);
+ }
+ }
+
+ [Test]
+ public static void TestIsFixed ()
+ {
+ ArrayList al1 = new ArrayList ();
+ Assert ("should not be fixed by default", !al1.IsFixedSize);
+ ArrayList al2 = ArrayList.FixedSize (al1);
+ Assert ("fixed-size wrapper not working", al2.IsFixedSize);
+ }
+
+ [Test]
+ public static void TestIsReadOnly ()
+ {
+ ArrayList al1 = new ArrayList ();
+ Assert ("should not be ReadOnly by default", !al1.IsReadOnly);
+ ArrayList al2 = ArrayList.ReadOnly (al1);
+ Assert ("read-only wrapper not working", al2.IsReadOnly);
+ }
+
+ [Test]
+ public static void TestIsSynchronized ()
+ {
+ ArrayList al1 = new ArrayList ();
+ Assert ("should not be synchronized by default",
+ !al1.IsSynchronized);
+ ArrayList al2 = ArrayList.Synchronized (al1);
+ Assert ("synchronized wrapper not working", al2.IsSynchronized);
+ }
+
+ [Test]
+ public static void TestItem ()
+ {
+ ArrayList al1 = new ArrayList ();
+ {
+ bool errorThrown = false;
+ try {
+ object o = al1 [-1];
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("negative item error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ object o = al1 [1];
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("past-end item error not thrown",
+ errorThrown);
+ }
+ for (int i = 0; i <= 100; i++) {
+ al1.Add (i);
+ }
+ for (int i = 0; i <= 100; i++) {
+ AssertEquals ("item not fetched for " + i,
+ i, al1 [i]);
+ }
+ }
+
+ [Test]
+ public static void TestAdapter ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = ArrayList.Adapter (null);
+ } catch (ArgumentNullException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 1: " + e.ToString ());
+ }
+ Assert ("null adapter error not thrown",
+ errorThrown);
+ }
+ {
+ char [] list = { 'a', 'b', 'c', 'd' };
+ ArrayList al1 = ArrayList.Adapter (list);
+ AssertNotNull ("Couldn't get an adapter", al1);
+ for (int i = 0; i < list.Length; i++) {
+ AssertEquals ("adapter not adapting", list [i], al1 [i]);
+ }
+ list [0] = 'z';
+ for (int i = 0; i < list.Length; i++) {
+ AssertEquals ("adapter not adapting", list [i], al1 [i]);
+ }
+ }
+ // Test Binary Search
+ {
+ bool errorThrown = false;
+ try {
+
+ String [] s1 = { "This", "is", "a", "test" };
+ ArrayList al1 = ArrayList.Adapter (s1);
+ al1.BinarySearch (42);
+ } catch (InvalidOperationException) {
+ // this is what .NET throws
+ errorThrown = true;
+ } catch (ArgumentException) {
+ // this is what the docs say it should throw
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 1: " + e.ToString ());
+ }
+ Assert ("search-for-wrong-type error not thrown",
+ errorThrown);
+ }
+
+ {
+ char [] arr = { 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'd' };
+ ArrayList al1 = ArrayList.Adapter (arr);
+ Assert ("couldn't find elem #1",
+ al1.BinarySearch ('c') >= 3);
+ Assert ("couldn't find elem #2",
+ al1.BinarySearch ('c') < 6);
+ }
+ {
+ char [] arr = { 'a', 'b', 'b', 'd', 'd', 'd', 'e', 'e' };
+ ArrayList al1 = ArrayList.Adapter (arr);
+ AssertEquals ("couldn't find next-higher elem",
+ -4, al1.BinarySearch ('c'));
+ }
+ {
+ char [] arr = { 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'd' };
+ ArrayList al1 = ArrayList.Adapter (arr);
+ AssertEquals ("couldn't find end",
+ -9, al1.BinarySearch ('e'));
+ }
+ // Sort
+ {
+ char [] starter = { 'd', 'b', 'f', 'e', 'a', 'c' };
+ ArrayList al1 = ArrayList.Adapter (starter);
+ al1.Sort ();
+ AssertEquals ("Should be sorted", 'a', al1 [0]);
+ AssertEquals ("Should be sorted", 'b', al1 [1]);
+ AssertEquals ("Should be sorted", 'c', al1 [2]);
+ AssertEquals ("Should be sorted", 'd', al1 [3]);
+ AssertEquals ("Should be sorted", 'e', al1 [4]);
+ AssertEquals ("Should be sorted", 'f', al1 [5]);
+ }
+
+ // TODO - test other adapter types?
+ }
+
+ [Test]
+ public static void TestAdd ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.FixedSize (new ArrayList ());
+ al1.Add ("Hi!");
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 1: " + e.ToString ());
+ }
+ Assert ("add to fixed size error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList ());
+ al1.Add ("Hi!");
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 2: " + e.ToString ());
+ }
+ Assert ("add to read only error not thrown",
+ errorThrown);
+ }
+ {
+ ArrayList al1 = new ArrayList ();
+ for (int i = 1; i <= 100; i++) {
+ al1.Add (i);
+ AssertEquals ("add failed " + i,
+ i, al1.Count);
+ AssertEquals ("add failed " + i,
+ i, al1 [i - 1]);
+
+ }
+ }
+ {
+ string [] strArray = new string [] { };
+ ArrayList al1 = new ArrayList (strArray);
+ al1.Add ("Hi!");
+ al1.Add ("Hi!");
+ AssertEquals ("add failed", 2, al1.Count);
+ }
+ }
+
+ [Test]
+ public static void TestAddRange ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.FixedSize (new ArrayList ());
+ String [] s1 = { "Hi!" };
+ al1.AddRange (s1);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 1: " + e.ToString ());
+ }
+ Assert ("add to fixed size error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList ());
+ String [] s1 = { "Hi!" };
+ al1.AddRange (s1);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 2: " + e.ToString ());
+ }
+ Assert ("add to read only error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList ();
+ al1.AddRange (null);
+ } catch (ArgumentNullException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 3: " + e.ToString ());
+ }
+ Assert ("add to read only error not thrown",
+ errorThrown);
+ }
+
+ {
+ ArrayList a1 = new ArrayList ();
+ AssertEquals ("ArrayList should start empty",
+ 0, a1.Count);
+ char [] coll = { 'a', 'b', 'c' };
+ a1.AddRange (coll);
+ AssertEquals ("ArrayList has wrong elements",
+ 3, a1.Count);
+ a1.AddRange (coll);
+ AssertEquals ("ArrayList has wrong elements",
+ 6, a1.Count);
+ }
+
+ {
+ ArrayList list = new ArrayList ();
+
+ for (int i = 0; i < 100; i++) {
+ list.Add (1);
+ }
+
+ AssertEquals ("BinarySearch off-by-one bug",
+ 49, list.BinarySearch (1));
+ }
+ }
+
+ [Test]
+ public static void TestBinarySearch ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList ();
+ String [] s1 = { "This", "is", "a", "test" };
+ al1.AddRange (s1);
+ al1.BinarySearch (42);
+ } catch (InvalidOperationException) {
+ // this is what .NET throws
+ errorThrown = true;
+ } catch (ArgumentException) {
+ // this is what the docs say it should throw
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 1: " + e.ToString ());
+ }
+ Assert ("search-for-wrong-type error not thrown",
+ errorThrown);
+ }
+
+ {
+ char [] arr = { 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'd' };
+ ArrayList al1 = new ArrayList (arr);
+ Assert ("couldn't find elem #1",
+ al1.BinarySearch ('c') >= 3);
+ Assert ("couldn't find elem #2",
+ al1.BinarySearch ('c') < 6);
+ }
+ {
+ char [] arr = { 'a', 'b', 'b', 'd', 'd', 'd', 'e', 'e' };
+ ArrayList al1 = new ArrayList (arr);
+ AssertEquals ("couldn't find next-higher elem",
+ -4, al1.BinarySearch ('c'));
+ }
+ {
+ char [] arr = { 'a', 'b', 'b', 'c', 'c', 'c', 'd', 'd' };
+ ArrayList al1 = new ArrayList (arr);
+ AssertEquals ("couldn't find end",
+ -9, al1.BinarySearch ('e'));
+ }
+
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void BinarySearch_IndexOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ object o = new object();
+ al.Add (o);
+ al.BinarySearch (Int32.MaxValue, 1, o, null);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void BinarySearch_CountOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ var o = new object();
+ al.Add (o);
+ al.BinarySearch (1, Int32.MaxValue, o, null);
+ }
+
+ [Test]
+ public static void BinarySearch_Null ()
+ {
+ ArrayList al = new ArrayList ();
+ var o = new object();
+ al.Add (o);
+ AssertEquals ("null", -1, al.BinarySearch (null));
+ }
+
+ // TODO - BinarySearch with IComparer
+
+ [Test]
+ public static void TestClear ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.FixedSize (new ArrayList ());
+ al1.Clear ();
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("add to fixed size error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList ());
+ al1.Clear ();
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("add to read only error not thrown",
+ errorThrown);
+ }
+ {
+ ArrayList al1 = new ArrayList ();
+ al1.Add ('c');
+ AssertEquals ("should have one element",
+ 1, al1.Count);
+ al1.Clear ();
+ AssertEquals ("should be empty",
+ 0, al1.Count);
+ }
+ {
+ int [] i1 = { 1, 2, 3, 4 };
+ ArrayList al1 = new ArrayList (i1);
+ AssertEquals ("should have elements",
+ i1.Length, al1.Count);
+ int capacity = al1.Capacity;
+ al1.Clear ();
+ AssertEquals ("should be empty again",
+ 0, al1.Count);
+ AssertEquals ("capacity shouldn't have changed",
+ capacity, al1.Capacity);
+ }
+ }
+
+ [Test]
+ public static void TestClone ()
+ {
+ {
+ char [] c1 = { 'a', 'b', 'c' };
+ ArrayList al1 = new ArrayList (c1);
+ ArrayList al2 = (ArrayList) al1.Clone ();
+ AssertEquals ("ArrayList match", al1 [0], al2 [0]);
+ AssertEquals ("ArrayList match", al1 [1], al2 [1]);
+ AssertEquals ("ArrayList match", al1 [2], al2 [2]);
+ }
+ {
+ char [] d10 = { 'a', 'b' };
+ char [] d11 = { 'a', 'c' };
+ char [] d12 = { 'b', 'c' };
+ char [] [] d1 = { d10, d11, d12 };
+ ArrayList al1 = new ArrayList (d1);
+ ArrayList al2 = (ArrayList) al1.Clone ();
+ AssertEquals ("Array match", al1 [0], al2 [0]);
+ AssertEquals ("Array match", al1 [1], al2 [1]);
+ AssertEquals ("Array match", al1 [2], al2 [2]);
+
+ ((char []) al1 [0]) [0] = 'z';
+ AssertEquals ("shallow copy", al1 [0], al2 [0]);
+ }
+ }
+
+ [Test]
+ public static void TestContains ()
+ {
+ char [] c1 = { 'a', 'b', 'c' };
+ ArrayList al1 = new ArrayList (c1);
+ Assert ("never find a null", !al1.Contains (null));
+ Assert ("can't find value", al1.Contains ('b'));
+ Assert ("shouldn't find value", !al1.Contains ('?'));
+ }
+
+ [Test]
+ public static void TestCopyTo ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ Char [] c1 = new Char [2];
+ ArrayList al1 = new ArrayList (c1);
+ al1.CopyTo (null, 2);
+ } catch (ArgumentNullException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 1: " + e.ToString ());
+ }
+ Assert ("error not thrown 1", errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ Char [] c1 = new Char [2];
+ ArrayList al1 = new ArrayList (c1);
+ Char [,] c2 = new Char [2, 2];
+ al1.CopyTo (c2, 2);
+ } catch (ArgumentException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 2: " + e.ToString ());
+ }
+ Assert ("error not thrown 2", errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ // This appears to be a bug in the ArrayList Constructor.
+ // It throws a RankException if a multidimensional Array
+ // is passed. The docs imply that an IEnumerator is used
+ // to retrieve the items from the collection, so this should
+ // work. In anycase this test is for CopyTo, so use what
+ // works on both platforms.
+ //Char[,] c1 = new Char[2,2];
+ Char [] c1 = new Char [2];
+ ArrayList al1 = new ArrayList (c1);
+ Char [] c2 = new Char [2];
+ al1.CopyTo (c2, 2);
+ } catch (ArgumentException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 3: " + e.ToString ());
+ }
+ Assert ("error not thrown 3", errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ Char [] c1 = new Char [2];
+ ArrayList al1 = new ArrayList (c1);
+ Char [] c2 = new Char [2];
+ al1.CopyTo (c2, -1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 4: " + e.ToString ());
+ }
+ Assert ("error not thrown 4", errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ Char [] c1 = new Char [2];
+ ArrayList al1 = new ArrayList (c1);
+ Char [] c2 = new Char [2];
+ al1.CopyTo (c2, 3);
+ } catch (ArgumentException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 5: " + e.ToString ());
+ }
+ Assert ("error not thrown 5", errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ Char [] c1 = new Char [2];
+ ArrayList al1 = new ArrayList (c1);
+ Char [] c2 = new Char [2];
+ al1.CopyTo (c2, 1);
+ } catch (ArgumentException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 6: " + e.ToString ());
+ }
+ Assert ("error not thrown 6", errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ String [] c1 = { "String", "array" };
+ ArrayList al1 = new ArrayList (c1);
+ Char [] c2 = new Char [2];
+ al1.CopyTo (c2, 0);
+ } catch (InvalidCastException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 7: " + e.ToString ());
+ }
+ Assert ("error not thrown 7", errorThrown);
+ }
+
+ Char [] orig = { 'a', 'b', 'c', 'd' };
+ ArrayList al = new ArrayList (orig);
+ Char [] copy = new Char [10];
+ Array.Clear (copy, 0, copy.Length);
+ al.CopyTo (copy, 3);
+ AssertEquals ("Wrong CopyTo 0", (char) 0, copy [0]);
+ AssertEquals ("Wrong CopyTo 1", (char) 0, copy [1]);
+ AssertEquals ("Wrong CopyTo 2", (char) 0, copy [2]);
+ AssertEquals ("Wrong CopyTo 3", orig [0], copy [3]);
+ AssertEquals ("Wrong CopyTo 4", orig [1], copy [4]);
+ AssertEquals ("Wrong CopyTo 5", orig [2], copy [5]);
+ AssertEquals ("Wrong CopyTo 6", orig [3], copy [6]);
+ AssertEquals ("Wrong CopyTo 7", (char) 0, copy [7]);
+ AssertEquals ("Wrong CopyTo 8", (char) 0, copy [8]);
+ AssertEquals ("Wrong CopyTo 9", (char) 0, copy [9]);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void CopyTo_IndexOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add (new object());
+ al.CopyTo (Int32.MaxValue, new byte [2], 0, 0);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void CopyTo_ArrayIndexOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.CopyTo (0, new byte [2], Int32.MaxValue, 0);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void CopyTo_CountOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.CopyTo (0, new byte [2], 0, Int32.MaxValue);
+ }
+
+ [Test]
+ public static void TestFixedSize ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = ArrayList.FixedSize (null);
+ } catch (ArgumentNullException) {
+ errorThrown = true;
+ }
+ Assert ("null arg error not thrown", errorThrown);
+ }
+ {
+ ArrayList al1 = new ArrayList ();
+ AssertEquals ("arrays start un-fixed.",
+ false, al1.IsFixedSize);
+ ArrayList al2 = ArrayList.FixedSize (al1);
+ AssertEquals ("should be fixed.",
+ true, al2.IsFixedSize);
+ }
+ }
+
+ [Test]
+ public static void TestEnumerator ()
+ {
+ String [] s1 = { "this", "is", "a", "test" };
+ ArrayList al1 = new ArrayList (s1);
+ IEnumerator en = al1.GetEnumerator ();
+ en.MoveNext ();
+ al1.Add ("something");
+ try {
+ en.MoveNext ();
+ Fail ("Add() didn't invalidate the enumerator");
+ } catch (InvalidOperationException) {
+ // do nothing...this is what we expect
+ }
+
+ en = al1.GetEnumerator ();
+ en.MoveNext ();
+ al1.AddRange (al1);
+ try {
+ en.MoveNext ();
+ Fail ("AddRange() didn't invalidate the enumerator");
+ } catch (InvalidOperationException) {
+ // do nothing...this is what we expect
+ }
+
+ en = al1.GetEnumerator ();
+ en.MoveNext ();
+ al1.Clear ();
+ try {
+ en.MoveNext ();
+ Fail ("Clear() didn't invalidate the enumerator");
+ } catch (InvalidOperationException) {
+ // do nothing...this is what we expect
+ }
+
+ al1 = new ArrayList (s1);
+ en = al1.GetEnumerator ();
+ en.MoveNext ();
+ al1.Insert (0, "new first");
+ try {
+ en.MoveNext ();
+ Fail ("Insert() didn't invalidate the enumerator");
+ } catch (InvalidOperationException) {
+ // do nothing...this is what we expect
+ }
+
+ en = al1.GetEnumerator ();
+ en.MoveNext ();
+ al1.InsertRange (0, al1);
+ try {
+ en.MoveNext ();
+ Fail ("InsertRange() didn't invalidate the enumerator");
+ } catch (InvalidOperationException) {
+ // do nothing...this is what we expect
+ }
+
+ en = al1.GetEnumerator ();
+ en.MoveNext ();
+ al1.Remove ("this");
+ try {
+ en.MoveNext ();
+ Fail ("Remove() didn't invalidate the enumerator");
+ } catch (InvalidOperationException) {
+ // do nothing...this is what we expect
+ }
+
+ en = al1.GetEnumerator ();
+ en.MoveNext ();
+ al1.RemoveAt (2);
+ try {
+ en.MoveNext ();
+ Fail ("RemoveAt() didn't invalidate the enumerator");
+ } catch (InvalidOperationException) {
+ // do nothing...this is what we expect
+ }
+
+ en = al1.GetEnumerator ();
+ en.MoveNext ();
+ al1.RemoveRange (1, 1);
+ try {
+ en.MoveNext ();
+ Fail ("RemoveRange() didn't invalidate the enumerator");
+ } catch (InvalidOperationException) {
+ // do nothing...this is what we expect
+ }
+
+ en = al1.GetEnumerator ();
+ en.MoveNext ();
+ al1.Reverse ();
+ try {
+ en.MoveNext ();
+ Fail ("Reverse() didn't invalidate the enumerator");
+ } catch (InvalidOperationException) {
+ // do nothing...this is what we expect
+ }
+
+ en = al1.GetEnumerator ();
+ en.MoveNext ();
+ al1.Sort ();
+ try {
+ en.MoveNext ();
+ Fail ("Sort() didn't invalidate the enumerator");
+ } catch (InvalidOperationException) {
+ // do nothing...this is what we expect
+ }
+ }
+
+ [Test]
+ public static void TestGetEnumerator ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList ();
+ IEnumerator en = a.GetEnumerator (-1, 1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("negative index error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList ();
+ IEnumerator en = a.GetEnumerator (1, -1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("negative index error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList ();
+ IEnumerator en = a.GetEnumerator (1, 1);
+ } catch (ArgumentException) {
+ errorThrown = true;
+ }
+ Assert ("out-of-range index error not thrown",
+ errorThrown);
+ }
+ {
+ String [] s1 = { "this", "is", "a", "test" };
+ ArrayList al1 = new ArrayList (s1);
+ IEnumerator en = al1.GetEnumerator ();
+ AssertNotNull ("No enumerator", en);
+
+ for (int i = 0; i < s1.Length; i++) {
+ en.MoveNext ();
+ AssertEquals ("Not enumerating",
+ al1 [i], en.Current);
+ }
+ }
+ {
+ String [] s1 = { "this", "is", "a", "test" };
+ ArrayList al1 = new ArrayList (s1);
+ IEnumerator en = al1.GetEnumerator (1, 2);
+ AssertNotNull ("No enumerator", en);
+
+ for (int i = 0; i < 2; i++) {
+ en.MoveNext ();
+ AssertEquals ("Not enumerating",
+ al1 [i + 1], en.Current);
+ }
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void GetEnumerator_IndexOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.GetEnumerator (Int32.MaxValue, 0);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void GetEnumerator_CountOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.GetEnumerator (0, Int32.MaxValue);
+ }
+
+ [Test]
+ public static void TestGetRange ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList ();
+ ArrayList b = a.GetRange (-1, 1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("negative index error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList ();
+ ArrayList b = a.GetRange (1, -1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("negative index error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList ();
+ ArrayList b = a.GetRange (1, 1);
+ } catch (ArgumentException) {
+ errorThrown = true;
+ }
+ Assert ("out-of-range index error not thrown",
+ errorThrown);
+ }
+ {
+ char [] chars = { 'a', 'b', 'c', 'd', 'e', 'f' };
+ ArrayList a = new ArrayList (chars);
+ ArrayList b = a.GetRange (1, 3);
+ AssertEquals ("GetRange returned wrong size ArrayList", 3, b.Count);
+ for (int i = 0; i < b.Count; i++) {
+ AssertEquals ("range didn't work",
+ chars [i + 1], b [i]);
+ }
+
+ a [2] = '?'; // should screw up ArrayList b.
+ bool errorThrown = false;
+ try {
+ int i = b.Count;
+ } catch (InvalidOperationException) {
+ errorThrown = true;
+ }
+ AssertEquals ("Munging 'a' should mess up 'b'",
+ true, errorThrown);
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void GetRange_IndexOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.GetRange (Int32.MaxValue, 0);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void GetRange_CountOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.GetRange (0, Int32.MaxValue);
+ }
+
+ [Test]
+ public static void TestIndexOf ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList (1);
+ int i = a.IndexOf ('a', -1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("negative indexof error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList (1);
+ int i = a.IndexOf ('a', 2);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("past-end indexof error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList (1);
+ int i = a.IndexOf ('a', 0, -1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("negative indexof error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList (1);
+ int i = a.IndexOf ('a', 0, 2);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("past-end indexof error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList (2);
+ int i = a.IndexOf ('a', 1, 2);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("past-end indexof error not thrown",
+ errorThrown);
+ }
+ {
+ char [] c = { 'a', 'b', 'c', 'd', 'e' };
+ ArrayList a = new ArrayList (c);
+ AssertEquals ("never find null",
+ -1, a.IndexOf (null));
+ AssertEquals ("never find null",
+ -1, a.IndexOf (null, 0));
+ AssertEquals ("never find null",
+ -1, a.IndexOf (null, 0, 5));
+ AssertEquals ("can't find elem",
+ 2, a.IndexOf ('c'));
+ AssertEquals ("can't find elem",
+ 2, a.IndexOf ('c', 2));
+ AssertEquals ("can't find elem",
+ 2, a.IndexOf ('c', 2, 2));
+ AssertEquals ("shouldn't find elem",
+ -1, a.IndexOf ('c', 3, 2));
+ AssertEquals ("shouldn't find", -1, a.IndexOf ('?'));
+ AssertEquals ("shouldn't find", -1, a.IndexOf (3));
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentOutOfRangeException))]
+ public static void IndexOf_StartIndexOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.IndexOf ('a', Int32.MaxValue, 1);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentOutOfRangeException))]
+ public static void IndexOf_CountOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.IndexOf ('a', 1, Int32.MaxValue);
+ }
+
+ [Test]
+ public static void TestInsert ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.FixedSize (new ArrayList ());
+ al1.Insert (0, "Hi!");
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("insert to fixed size error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList ());
+ al1.Insert (0, "Hi!");
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("insert to read only error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ al1.Insert (-1, "Hi!");
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("insert to read only error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ al1.Insert (4, "Hi!");
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("insert to read only error not thrown",
+ errorThrown);
+ }
+ {
+ ArrayList al1 = new ArrayList ();
+ AssertEquals ("arraylist starts empty", 0, al1.Count);
+ al1.Insert (0, 'a');
+ al1.Insert (1, 'b');
+ al1.Insert (0, 'c');
+ AssertEquals ("arraylist needs stuff", 3, al1.Count);
+ AssertEquals ("arraylist got stuff", 'c', al1 [0]);
+ AssertEquals ("arraylist got stuff", 'a', al1 [1]);
+ AssertEquals ("arraylist got stuff", 'b', al1 [2]);
+ }
+ }
+
+ [Test]
+ public static void TestInsertRange ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.FixedSize (new ArrayList ());
+ string [] s = { "Hi!" };
+ al1.InsertRange (0, s);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("insert to fixed size error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList ());
+ string [] s = { "Hi!" };
+ al1.InsertRange (0, s);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("insert to read only error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ string [] s = { "Hi!" };
+ al1.InsertRange (-1, s);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("negative index insert error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ string [] s = { "Hi!" };
+ al1.InsertRange (4, s);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("out-of-range insert error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ al1.InsertRange (0, null);
+ } catch (ArgumentNullException) {
+ errorThrown = true;
+ }
+ Assert ("null insert error not thrown",
+ errorThrown);
+ }
+ {
+ char [] c = { 'a', 'b', 'c' };
+ ArrayList a = new ArrayList (c);
+ a.InsertRange (1, c);
+ AssertEquals ("bad insert 1", 'a', a [0]);
+ AssertEquals ("bad insert 2", 'a', a [1]);
+ AssertEquals ("bad insert 3", 'b', a [2]);
+ AssertEquals ("bad insert 4", 'c', a [3]);
+ AssertEquals ("bad insert 5", 'b', a [4]);
+ AssertEquals ("bad insert 6", 'c', a [5]);
+ }
+ }
+
+ [Test]
+ public static void TestLastIndexOf ()
+ {
+ //{
+ //bool errorThrown = false;
+ //try {
+ //ArrayList a = new ArrayList(1);
+ //int i = a.LastIndexOf('a', -1);
+ //} catch (ArgumentOutOfRangeException) {
+ //errorThrown = true;
+ //}
+ //Assert("first negative lastindexof error not thrown",
+ //errorThrown);
+ //}
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList a = new ArrayList (1);
+ int i = a.LastIndexOf ('a', 2);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("past-end lastindexof error not thrown",
+ errorThrown);
+ }
+ //{
+ //bool errorThrown = false;
+ //try {
+ //ArrayList a = new ArrayList(1);
+ //int i = a.LastIndexOf('a', 0, -1);
+ //} catch (ArgumentOutOfRangeException) {
+ //errorThrown = true;
+ //}
+ //Assert("second negative lastindexof error not thrown",
+ //errorThrown);
+ //}
+ //{
+ //bool errorThrown = false;
+ //try {
+ //ArrayList a = new ArrayList(1);
+ //int i = a.LastIndexOf('a', 0, 2);
+ //} catch (ArgumentOutOfRangeException) {
+ //errorThrown = true;
+ //}
+ //Assert("past-end lastindexof error not thrown",
+ //errorThrown);
+ //}
+ //{
+ //bool errorThrown = false;
+ //try {
+ //ArrayList a = new ArrayList(2);
+ //int i = a.LastIndexOf('a', 0, 2);
+ //} catch (ArgumentOutOfRangeException) {
+ //errorThrown = true;
+ //}
+ //Assert("past-end lastindexof error not thrown",
+ //errorThrown);
+ //}
+ int iTest = 0;
+ try {
+ char [] c = { 'a', 'b', 'c', 'd', 'e' };
+ ArrayList a = new ArrayList (c);
+ AssertEquals ("never find null",
+ -1, a.LastIndexOf (null));
+ iTest++;
+ AssertEquals ("never find null",
+ -1, a.LastIndexOf (null, 4));
+ iTest++;
+ AssertEquals ("never find null",
+ -1, a.LastIndexOf (null, 4, 5));
+ iTest++;
+ AssertEquals ("can't find elem",
+ 2, a.LastIndexOf ('c'));
+ iTest++;
+ AssertEquals ("can't find elem",
+ 2, a.LastIndexOf ('c', 4));
+ iTest++;
+ AssertEquals ("can't find elem",
+ 2, a.LastIndexOf ('c', 3, 2));
+ iTest++;
+ AssertEquals ("shouldn't find elem",
+ -1, a.LastIndexOf ('c', 4, 2));
+ iTest++;
+ AssertEquals ("shouldn't find", -1, a.LastIndexOf ('?'));
+ iTest++;
+ AssertEquals ("shouldn't find", -1, a.LastIndexOf (1));
+ } catch (Exception e) {
+ Fail ("Unexpected exception caught when iTest=" + iTest + ". e=" + e);
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentOutOfRangeException))]
+ public static void LastIndexOf_StartIndexOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.LastIndexOf ('a', Int32.MaxValue, 1);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentOutOfRangeException))]
+ public static void LastIndexOf_CountOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.LastIndexOf ('a', 1, Int32.MaxValue);
+ }
+
+ [Test]
+ public static void TestReadOnly ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = ArrayList.ReadOnly (null);
+ } catch (ArgumentNullException) {
+ errorThrown = true;
+ }
+ Assert ("null arg error not thrown", errorThrown);
+ }
+ {
+ ArrayList al1 = new ArrayList ();
+ AssertEquals ("arrays start writeable.",
+ false, al1.IsReadOnly);
+ ArrayList al2 = ArrayList.ReadOnly (al1);
+ AssertEquals ("should be readonly.",
+ true, al2.IsReadOnly);
+ }
+ }
+
+ [Test]
+ public static void TestRemove ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.FixedSize (new ArrayList (3));
+ al1.Remove (1);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("remove fixed size error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList (3));
+ al1.Remove (1);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("remove read only error not thrown",
+ errorThrown);
+ }
+ {
+ char [] c = { 'a', 'b', 'c' };
+ ArrayList a = new ArrayList (c);
+ a.Remove (1);
+ a.Remove ('?');
+ AssertEquals ("should be unchanged", c.Length, a.Count);
+ a.Remove ('a');
+ AssertEquals ("should be changed", 2, a.Count);
+ AssertEquals ("should have shifted", 'b', a [0]);
+ AssertEquals ("should have shifted", 'c', a [1]);
+ }
+ }
+
+ [Test]
+ public static void TestRemoveAt ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.FixedSize (new ArrayList (3));
+ al1.RemoveAt (1);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("remove from fixed size error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList (3));
+ al1.RemoveAt (1);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("remove from read only error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ al1.RemoveAt (-1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("remove at negative index error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ al1.RemoveAt (4);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("remove at out-of-range index error not thrown",
+ errorThrown);
+ }
+ {
+ char [] c = { 'a', 'b', 'c' };
+ ArrayList a = new ArrayList (c);
+ a.RemoveAt (0);
+ AssertEquals ("should be changed", 2, a.Count);
+ AssertEquals ("should have shifted", 'b', a [0]);
+ AssertEquals ("should have shifted", 'c', a [1]);
+ }
+ }
+
+ [Test]
+ public static void TestRemoveRange ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.FixedSize (new ArrayList (3));
+ al1.RemoveRange (0, 1);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("removerange from fixed size error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList (3));
+ al1.RemoveRange (0, 1);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("removerange from read only error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ al1.RemoveRange (-1, 1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("removerange at negative index error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ al1.RemoveRange (0, -1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("removerange at negative index error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ al1.RemoveRange (2, 3);
+ } catch (ArgumentException) {
+ errorThrown = true;
+ }
+ Assert ("removerange at bad range error not thrown",
+ errorThrown);
+ }
+ {
+ char [] c = { 'a', 'b', 'c' };
+ ArrayList a = new ArrayList (c);
+ a.RemoveRange (1, 2);
+ AssertEquals ("should be changed", 1, a.Count);
+ AssertEquals ("should have shifted", 'a', a [0]);
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void RemoveRange_IndexOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.RemoveRange (Int32.MaxValue, 1);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void RemoveRange_CountOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.RemoveRange (1, Int32.MaxValue);
+ }
+
+ [Test]
+ public static void TestRepeat ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = ArrayList.Repeat ('c', -1);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ }
+ Assert ("repeat negative copies error not thrown",
+ errorThrown);
+ }
+ {
+ ArrayList al1 = ArrayList.Repeat ("huh?", 0);
+ AssertEquals ("should be nothing in array",
+ 0, al1.Count);
+ }
+ {
+ ArrayList al1 = ArrayList.Repeat ("huh?", 3);
+ AssertEquals ("should be something in array",
+ 3, al1.Count);
+ AssertEquals ("array elem doesn't check",
+ "huh?", al1 [0]);
+ AssertEquals ("array elem doesn't check",
+ "huh?", al1 [1]);
+ AssertEquals ("array elem doesn't check",
+ "huh?", al1 [2]);
+ }
+ }
+
+ [Test]
+ public static void TestReverse ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList ());
+ al1.Reverse ();
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("reverse on read only error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ char [] c = new Char [2];
+ ArrayList al1 = new ArrayList (c);
+ al1.Reverse (0, 3);
+ } catch (ArgumentException) {
+ errorThrown = true;
+ }
+ Assert ("error not thrown", errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ char [] c = new Char [2];
+ ArrayList al1 = new ArrayList (c);
+ al1.Reverse (3, 0);
+ } catch (ArgumentException) {
+ errorThrown = true;
+ }
+ Assert ("error not thrown", errorThrown);
+ }
+ {
+ char [] c = { 'a', 'b', 'c', 'd', 'e' };
+ ArrayList al1 = new ArrayList (c);
+ al1.Reverse (2, 1);
+ for (int i = 0; i < al1.Count; i++) {
+ AssertEquals ("Should be no change yet",
+ c [i], al1 [i]);
+ }
+ al1.Reverse ();
+ for (int i = 0; i < al1.Count; i++) {
+ AssertEquals ("Should be reversed",
+ c [i], al1 [4 - i]);
+ }
+ al1.Reverse ();
+ for (int i = 0; i < al1.Count; i++) {
+ AssertEquals ("Should be back to normal",
+ c [i], al1 [i]);
+ }
+ al1.Reverse (1, 3);
+ AssertEquals ("Should be back to normal", c [0], al1 [0]);
+ AssertEquals ("Should be back to normal", c [3], al1 [1]);
+ AssertEquals ("Should be back to normal", c [2], al1 [2]);
+ AssertEquals ("Should be back to normal", c [1], al1 [3]);
+ AssertEquals ("Should be back to normal", c [4], al1 [4]);
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void Reverse_IndexOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.Reverse (Int32.MaxValue, 1);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void Reverse_CountOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.Reverse (1, Int32.MaxValue);
+ }
+
+ [Test]
+ public static void TestSetRange ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ char [] c = { 'a', 'b', 'c' };
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList (3));
+ al1.SetRange (0, c);
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 1: " + e.ToString ());
+ }
+ Assert ("setrange on read only error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 = new ArrayList (3);
+ al1.SetRange (0, null);
+ } catch (ArgumentNullException) {
+ errorThrown = true;
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 2: " + e.ToString ());
+ }
+ Assert ("setrange with null error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ char [] c = { 'a', 'b', 'c' };
+ ArrayList al1 = new ArrayList (3);
+ al1.SetRange (-1, c);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 3: " + e.ToString ());
+ }
+ Assert ("setrange with negative index error not thrown",
+ errorThrown);
+ }
+ {
+ bool errorThrown = false;
+ try {
+ char [] c = { 'a', 'b', 'c' };
+ ArrayList al1 = new ArrayList (3);
+ al1.SetRange (2, c);
+ } catch (ArgumentOutOfRangeException) {
+ errorThrown = true;
+ } catch (Exception e) {
+ Fail ("Incorrect exception thrown at 4: " + e.ToString ());
+ }
+ Assert ("setrange with too much error not thrown",
+ errorThrown);
+ }
+
+ {
+ char [] c = { 'a', 'b', 'c' };
+ ArrayList al1 = ArrayList.Repeat ('?', 3);
+ Assert ("no match yet", c [0] != (char) al1 [0]);
+ Assert ("no match yet", c [1] != (char) al1 [1]);
+ Assert ("no match yet", c [2] != (char) al1 [2]);
+ al1.SetRange (0, c);
+ AssertEquals ("should match", c [0], al1 [0]);
+ AssertEquals ("should match", c [1], al1 [1]);
+ AssertEquals ("should match", c [2], al1 [2]);
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentOutOfRangeException))]
+ public static void SetRange_Overflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.SetRange (Int32.MaxValue, new ArrayList ());
+ }
+
+ [Test]
+ public static void TestInsertRange_this ()
+ {
+ String [] s1 = { "this", "is", "a", "test" };
+ ArrayList al = new ArrayList (s1);
+ al.InsertRange (2, al);
+ String [] s2 = { "this", "is", "this", "is", "a", "test", "a", "test" };
+ for (int i = 0; i < al.Count; i++) {
+ AssertEquals ("at i=" + i, s2 [i], al [i]);
+ }
+ }
+
+ [Test]
+ public static void TestSort ()
+ {
+ {
+ bool errorThrown = false;
+ try {
+ ArrayList al1 =
+ ArrayList.ReadOnly (new ArrayList ());
+ al1.Sort ();
+ } catch (NotSupportedException) {
+ errorThrown = true;
+ }
+ Assert ("sort on read only error not thrown",
+ errorThrown);
+ }
+ {
+ char [] starter = { 'd', 'b', 'f', 'e', 'a', 'c' };
+ ArrayList al1 = new ArrayList (starter);
+ al1.Sort ();
+ AssertEquals ("Should be sorted", 'a', al1 [0]);
+ AssertEquals ("Should be sorted", 'b', al1 [1]);
+ AssertEquals ("Should be sorted", 'c', al1 [2]);
+ AssertEquals ("Should be sorted", 'd', al1 [3]);
+ AssertEquals ("Should be sorted", 'e', al1 [4]);
+ AssertEquals ("Should be sorted", 'f', al1 [5]);
+ }
+ {
+ ArrayList al1 = new ArrayList ();
+ al1.Add (null);
+ al1.Add (null);
+ al1.Add (32);
+ al1.Add (33);
+ al1.Add (null);
+ al1.Add (null);
+
+ al1.Sort ();
+ AssertEquals ("Should be null", null, al1 [0]);
+ AssertEquals ("Should be 2. null", null, al1 [1]);
+ AssertEquals ("Should be 3. null", null, al1 [2]);
+ AssertEquals ("Should be 4. null", null, al1 [3]);
+ AssertEquals ("Should be 32", 32, al1 [4]);
+ AssertEquals ("Should be 33", 33, al1 [5]);
+ }
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void Sort_IndexOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.Sort (Int32.MaxValue, 1, null);
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public static void Sort_CountOverflow ()
+ {
+ ArrayList al = new ArrayList ();
+ al.Add(new object());
+ al.Sort (1, Int32.MaxValue, null);
+ }
+
+ // TODO - Sort with IComparers
+
+ // TODO - Synchronize
+
+ //[Test]
+ //public static void TestToArray ()
+ //{
+ // {
+ // bool errorThrown = false;
+ // try {
+ // ArrayList al1 = new ArrayList (3);
+ // al1.ToArray (null);
+ // } catch (ArgumentNullException) {
+ // errorThrown = true;
+ // }
+ // Assert ("toarray with null error not thrown",
+ // errorThrown);
+ // }
+ // {
+ // bool errorThrown = false;
+ // try {
+ // char [] c = { 'a', 'b', 'c' };
+ // string s = "huh?";
+ // ArrayList al1 = new ArrayList (c);
+ // al1.ToArray (s.GetType ());
+ // } catch (InvalidCastException) {
+ // errorThrown = true;
+ // }
+ // Assert ("toarray with bad type error not thrown",
+ // errorThrown);
+ // }
+ // {
+ // char [] c1 = { 'a', 'b', 'c', 'd', 'e' };
+ // ArrayList al1 = new ArrayList (c1);
+ // object [] o2 = al1.ToArray ();
+ // for (int i = 0; i < c1.Length; i++) {
+ // AssertEquals ("should be copy", c1 [i], o2 [i]);
+ // }
+ // Array c2 = al1.ToArray (c1 [0].GetType ());
+ // for (int i = 0; i < c1.Length; i++) {
+ // AssertEquals ("should be copy",
+ // c1 [i], c2.GetValue (i));
+ // }
+ // }
+ //}
+
+ [Test]
+ [ExpectedException (typeof (NotSupportedException))]
+ public static void TrimToSize_ReadOnly ()
+ {
+ ArrayList al1 = ArrayList.ReadOnly (new ArrayList ());
+ al1.TrimToSize ();
+ }
+
+ [Test]
+ public static void TrimToSize ()
+ {
+ ArrayList al1 = new ArrayList ();
+#if NET_2_0
+ // Capacity is 0 under 2.0
+ int capacity = 4;
+#else
+ int capacity = al1.Capacity;
+#endif
+ int size = capacity / 2;
+ for (int i = 1; i <= size; i++) {
+ al1.Add ('?');
+ }
+ al1.RemoveAt (0);
+ al1.TrimToSize ();
+ AssertEquals ("no capacity match", size - 1, al1.Capacity);
+
+ al1.Clear ();
+ al1.TrimToSize ();
+ AssertEquals ("no default capacity", capacity, al1.Capacity);
+ }
+
+ class Comparer : IComparer
+ {
+
+ private bool called = false;
+
+ public bool Called
+ {
+ get
+ {
+ bool result = called;
+ called = false;
+ return called;
+ }
+ }
+
+ public int Compare (object x, object y)
+ {
+ called = true;
+ return 0;
+ }
+ }
+
+ [Test]
+ public static void BinarySearch1_EmptyList ()
+ {
+ ArrayList list = new ArrayList ();
+ AssertEquals ("BinarySearch", -1, list.BinarySearch (0));
+ }
+
+ [Test]
+ public static void BinarySearch2_EmptyList ()
+ {
+ Comparer comparer = new Comparer ();
+ ArrayList list = new ArrayList ();
+ AssertEquals ("BinarySearch", -1, list.BinarySearch (0, comparer));
+ // bug 77030 - the comparer isn't called for an empty array/list
+ Assert ("Called", !comparer.Called);
+ }
+
+ [Test]
+ public static void BinarySearch3_EmptyList ()
+ {
+ Comparer comparer = new Comparer ();
+ ArrayList list = new ArrayList ();
+ AssertEquals ("BinarySearch", -1, list.BinarySearch (0, 0, 0, comparer));
+ // bug 77030 - the comparer isn't called for an empty array/list
+ Assert ("Called", !comparer.Called);
+ }
+
+ [Test]
+#if ONLY_1_1
+ [Category ("NotDotNet")] // MS bug
+#endif
+ public static void AddRange_GetRange ()
+ {
+ ArrayList source = ArrayList.Adapter (new object [] { "1", "2" });
+ AssertEquals ("#1", 2, source.Count);
+ AssertEquals ("#2", "1", source [0]);
+ AssertEquals ("#3", "2", source [1]);
+ ArrayList range = source.GetRange (1, 1);
+ AssertEquals ("#4", 1, range.Count);
+ AssertEquals ("#5", "2", range [0]);
+ ArrayList target = new ArrayList ();
+ target.AddRange (range);
+ AssertEquals ("#6", 1, target.Count);
+ AssertEquals ("#7", "2", target [0]);
+ }
+
+ [Test]
+#if ONLY_1_1
+ [Category ("NotDotNet")] // MS bug
+#endif
+ public static void IterateSelf ()
+ {
+ ArrayList list = new ArrayList ();
+ list.Add (list);
+ IEnumerator enumerator = list.GetEnumerator ();
+ Assert ("#1", enumerator.MoveNext ());
+ Assert ("#2", object.ReferenceEquals (list, enumerator.Current));
+ Assert ("#3", !enumerator.MoveNext ());
+ }
+ }
+}