[runtime] Fix Empty generic enumerator equality
[mono.git] / mcs / class / corlib / Test / System / ArrayTest.cs
index f53eb6dd25d062f8fed18b780db13b1e027bd2dd..36db33d6352b9ac3efc47122a7897ed4289ea21d 100644 (file)
@@ -61,7 +61,21 @@ public class ArrayTest
 {
        char [] arrsort = {'d', 'b', 'f', 'e', 'a', 'c'};
 
-       public ArrayTest() {}
+       interface I
+       {
+       }
+
+       class C
+       {
+       }
+
+       class DC : C
+       {
+       }
+
+       class DI : I
+       {
+       }
 
        [Test]
        public void TestIsFixedSize() {
@@ -225,7 +239,23 @@ public class ArrayTest
                Assert.AreEqual (-1, Array.BinarySearch (o, 0, 3, null, null), "O=a,i,i,o,c");
        }
 
-       // TODO - testBinarySearch with explicit IComparer args
+       class TestComparer7 : IComparer<int>
+       {
+               public int Compare (int x, int y)
+               {
+                       if (y != 7)
+                               throw new ApplicationException ();
+
+                       return x.CompareTo (y);
+               }
+       }
+
+       [Test]
+       public void BinarySearch_WithComparer ()
+       {
+               var a = new int[] { 2, 6, 9 };
+               Assert.AreEqual (-3, Array.BinarySearch (a, 7, new TestComparer7 ()));
+       }
 
        [Test]
        public void TestClear() {
@@ -472,14 +502,24 @@ public class ArrayTest
        }
 
        [Test]
-       [ExpectedException (typeof (InvalidCastException))]
        public void Copy_InvalidCast () {
                object[] arr1 = new object [10];
                Type[] arr2 = new Type [10];
-
                arr1 [0] = new object ();
 
-               Array.Copy (arr1, 0, arr2, 0, 10);
+               try {
+                       Array.Copy (arr1, 0, arr2, 0, 10);
+                       Assert.Fail ("#1");
+               } catch (InvalidCastException) {
+               }
+
+               var arr1_2 = new I [1] { new DI () };
+               var arr2_2 = new C [1] { new DC () };
+               try {
+                       Array.Copy (arr2_2, arr1_2, 1);
+                       Assert.Fail ("#1");
+               } catch (InvalidCastException) {
+               }
        }
 
        [Test]
@@ -503,11 +543,6 @@ public class ArrayTest
                        } catch (ArgumentException) {
                                errorThrown = true;
                        }
-#if TARGET_JVM // This is really implementation dependent behaviour.
-                       catch (RankException) {
-                               errorThrown = true;
-                       }
-#endif // TARGET_JVM
                        Assert.IsTrue (errorThrown, "#E62");
                }
                {
@@ -657,7 +692,7 @@ public class ArrayTest
                        }
                        Assert.IsTrue (errorThrown, "#F03a");
                }
-#if NET_1_1
+
                {
                        bool errorThrown = false;
                        try {
@@ -667,8 +702,6 @@ public class ArrayTest
                        }
                        Assert.IsTrue (errorThrown, "#F03b");
                }
-#endif
-#if !TARGET_JVM // Arrays lower bounds are not supported for TARGET_JVM
                {
                        bool errorThrown = false;
                        try {
@@ -678,7 +711,6 @@ public class ArrayTest
                        }
                        Assert.IsTrue (errorThrown, "#F04");
                }
-#endif // TARGET_JVM
                {
                        bool errorThrown = false;
                        try {
@@ -689,7 +721,6 @@ public class ArrayTest
                        }
                        Assert.IsTrue (errorThrown, "#F05");
                }
-#if !TARGET_JVM // CreateInstance with lower bounds not supported for TARGET_JVM
                {
                        bool errorThrown = false;
                        try {
@@ -732,7 +763,6 @@ public class ArrayTest
                Type szarrayType = new int [10].GetType ();
                Assert.IsTrue (szarrayType == (Array.CreateInstance (typeof (int), new int[] {1}, new int[] {0})).GetType ());
                Assert.IsTrue (szarrayType != (Array.CreateInstance (typeof (int), new int[] {1}, new int[] {1})).GetType ());
-#endif // TARGET_JVM
        }
        
        [Test]
@@ -749,6 +779,14 @@ public class ArrayTest
                Array.CreateInstance (typeof (Int32), (long[])null);
        }
 
+       [Test]
+       public void CreateInstanceVoid ()
+       {
+               Assert.Throws<NotSupportedException> (delegate () {
+                               Array.CreateInstance (typeof (void), 1);
+                       });
+       }
+
        [Test]
        public void TestGetEnumerator() {
                String[] s1 = {"this", "is", "a", "test"};
@@ -803,7 +841,6 @@ public class ArrayTest
        }
 
        [Test]
-       [Category ("TargetJvmNotSupported")] // Arrays lower bounds are not supported for TARGET_JVM
        public void TestGetEnumeratorNonZeroLowerBounds() {
                int[] myLengthsArray = new int[2] { 3, 5 };
                int[] myBoundsArray = new int[2] { 2, 3 };
@@ -832,7 +869,6 @@ public class ArrayTest
        }
 
        [Test]
-       [Category ("TargetJvmNotSupported")] // Arrays lower bounds are not supported for TARGET_JVM
        public void TestIList_Add () {
                int[] myLengthsArray = new int[2] { 3, 5 };
                int[] myBoundsArray = new int[2] { 2, 3 };
@@ -853,7 +889,6 @@ public class ArrayTest
        }
 
        [Test]
-       [Category ("TargetJvmNotSupported")] // Arrays lower bounds are not supported for TARGET_JVM
        public void TestIList_Insert () {
                int[] myLengthsArray = new int[2] { 3, 5 };
                int[] myBoundsArray = new int[2] { 2, 3 };
@@ -874,7 +909,6 @@ public class ArrayTest
        }
 
        [Test]
-       [Category ("TargetJvmNotSupported")] // Arrays lower bounds are not supported for TARGET_JVM
        public void TestIList_Remove () {
                int[] myLengthsArray = new int[2] { 3, 5 };
                int[] myBoundsArray = new int[2] { 2, 3 };
@@ -895,7 +929,6 @@ public class ArrayTest
        }
 
        [Test]
-       [Category ("TargetJvmNotSupported")] // Arrays lower bounds are not supported for TARGET_JVM
        public void TestIList_RemoveAt () {
                int[] myLengthsArray = new int[2] { 3, 5 };
                int[] myBoundsArray = new int[2] { 2, 3 };
@@ -916,7 +949,6 @@ public class ArrayTest
        }
 
        [Test]
-       [Category ("TargetJvmNotSupported")] // Arrays lower bounds are not supported for TARGET_JVM
        public void TestIList_Contains () {
                int[] myLengthsArray = new int[2] { 3, 5 };
                int[] myBoundsArray = new int[2] { 2, 3 };
@@ -942,7 +974,6 @@ public class ArrayTest
        }
 
        [Test]
-       [Category ("TargetJvmNotSupported")] // Arrays lower bounds are not supported for TARGET_JVM
        public void TestIList_IndexOf () {
                int[] myLengthsArray = new int[2] { 3, 5 };
                int[] myBoundsArray = new int[2] { 2, 3 };
@@ -972,7 +1003,6 @@ public class ArrayTest
                int[] myBoundArray = new int[1] { Int32.MinValue };
                Array myExtremeArray=Array.CreateInstance ( typeof(String), myLengthArray, myBoundArray );
                Assert.AreEqual (Int32.MaxValue, ((IList)myExtremeArray).IndexOf (42), "AD04");
-
        }
 
        [Test]
@@ -1603,6 +1633,126 @@ public class ArrayTest
                }
        }
 
+
+       [Test]
+       public void FindIndexTest ()
+       {
+               var a = new int[] { 2, 2, 2, 3, 2 };
+               Assert.AreEqual (2, Array.FindIndex (a, 2, 2, l => true));
+       }
+
+       [Test]
+       public void FindIndex_Invalid ()
+       {
+               var array = new int [] { 1, 2, 3, 4, 5 };
+
+               try {
+                       Array.FindIndex (array, null);
+                       Assert.Fail ("#1");
+               } catch (ArgumentNullException) {
+               }
+
+               try {
+                       Array.FindIndex (array, -1, l => true);
+                       Assert.Fail ("#2");
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               try {
+                       Array.FindIndex (array, -1, 0, l => true);
+                       Assert.Fail ("#2b");
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               try {
+                       Array.FindIndex (array, 0, -1, l => true);
+                       Assert.Fail ("#3");
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               try {
+                       Array.FindIndex (array, 100, l => true);
+                       Assert.Fail ("#4");
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               try {
+                       Array.FindIndex (array, 100, 0, l => true);
+                       Assert.Fail ("#4b");
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               try {
+                       Array.FindIndex (array, 7, 2, l => true);
+                       Assert.Fail ("#5");
+               } catch (ArgumentOutOfRangeException) {
+               }
+       }
+
+       [Test, ExpectedException (typeof (ArgumentNullException))]
+       public void FindLastNullTest ()
+       {
+               var array = new int [] { 1, 2, 3, 4, 5 };               
+               Array.FindLast (array, null);
+       }
+
+       [Test]
+       public void FindLastIndexTest ()
+       {
+               var array = new int [] { 1, 2, 3, 4, 5 };
+
+               Assert.AreEqual (2, Array.FindLastIndex (array, 2, 3, l => true));
+               Assert.AreEqual (2, Array.FindLastIndex (array, 2, 2, l => true));
+               Assert.AreEqual (1, Array.FindLastIndex (array, 1, 2, l => true));
+       }
+
+       [Test]
+       public void FindLastIndex_Invalid ()
+       {
+               var array = new int [] { 1, 2, 3, 4, 5 };
+               try {
+                       Array.FindLastIndex (array, null);
+                       Assert.Fail ("#1");
+               } catch (ArgumentNullException) {
+               }
+
+               try {
+                       Array.FindLastIndex (array, -1, l => true);
+                       Assert.Fail ("#2");
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               try {
+                       Array.FindLastIndex (array, -1, 0, l => true);
+                       Assert.Fail ("#2b");
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               try {
+                       Array.FindLastIndex (array, 0, -1, l => true);
+                       Assert.Fail ("#3");
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               try {
+                       Array.FindLastIndex (array, 100, l => true);
+                       Assert.Fail ("#4");
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               try {
+                       Array.FindLastIndex (array, 100, 0, l => true);
+                       Assert.Fail ("#4b");
+               } catch (ArgumentOutOfRangeException) {
+               }
+
+               try {
+                       Array.FindLastIndex (array, 2, 4, l => true);
+                       Assert.Fail ("#5");
+               } catch (ArgumentOutOfRangeException) {
+               }
+       }
+
        [Test]
        public void TestReverse() {
                {
@@ -1680,6 +1830,25 @@ public class ArrayTest
                Assert.AreEqual ('d', c2[3], "#L14");
        }
 
+       [Test]
+       // #8904
+       public void ReverseStruct () {
+               BStruct[] c3 = new BStruct[2];
+               c3 [0] = new BStruct () { i1 = 1, i2 = 2, i3 = 3 };
+               c3 [1] = new BStruct () { i1 = 4, i2 = 5, i3 = 6 };
+               Array.Reverse (c3);
+               Assert.AreEqual (4, c3 [0].i1);
+               Assert.AreEqual (5, c3 [0].i2);
+               Assert.AreEqual (6, c3 [0].i3);
+               Assert.AreEqual (1, c3 [1].i1);
+               Assert.AreEqual (2, c3 [1].i2);
+               Assert.AreEqual (3, c3 [1].i3);
+       }
+
+       struct BStruct {
+               public int i1, i2, i3;
+       }
+
        [Test]
        public void TestSetValue1() {
                {
@@ -2332,6 +2501,27 @@ public class ArrayTest
                }
        }
 
+       [Test]
+       public void Sort_NullValues ()
+       {
+               var s = new [] { "a", null, "b", null };
+               Array.Sort (s, (a, b) => {
+                       if (a == null) {
+                               return b == null ? 0 : 1;
+                       }
+
+                       if (b == null)
+                               return -1;
+
+                       return a.CompareTo (b);
+               });
+
+               Assert.AreEqual ("a", s [0], "#1");
+               Assert.AreEqual ("b", s [1], "#2");
+               Assert.IsNull (s [2], "#3");
+               Assert.IsNull (s [3], "#4");
+       }
+
        [Test] // #616416
        public void SortNonGenericDoubleItems () {
             double[] doubleValues = new double[11];
@@ -2365,6 +2555,53 @@ public class ArrayTest
                        Assert.AreEqual (4, indices [0]);
        }
 
+       [Test]
+       public void TestSortComparable()
+       {
+               int[] source = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+               int[] expected = { 6, 5, 4, 3, 2, 1, 7, 8, 9 };
+               Comp[] c = { new Comp (100), new Comp (16), new Comp (11), new Comp (9), new Comp (0), new Comp (-100) };
+               IComparer<Comp> comp = null;
+               Array.Sort<Comp, int> (c, source, comp);
+
+               Assert.AreEqual (expected, source);
+       }
+
+       class Comp : IComparable
+       {
+               readonly int val;
+
+               public Comp (int a)
+               {
+                       val = a;
+               }
+
+               int IComparable.CompareTo (object obj)
+               {
+                       return val.CompareTo ((obj as Comp).val);
+               }
+       }
+
+       [Test]
+       public void TestSortComparableMixed()
+       {
+               var m = new TestSortComparableMixed_Comparer ();
+               var arr = new object [] { 1, 2, m, 4, 5, 6, 7, 8, 9, 10 };
+
+               Array.Sort (arr);
+
+               var expected = new object [] { m, 1, 2, 4, 5, 6, 7, 8, 9, 10 };
+               Assert.AreEqual (expected, arr);
+       }
+
+       class TestSortComparableMixed_Comparer : IComparable
+       {
+               public int CompareTo (object other)
+               {
+                       return -1;
+               }
+       }
+
        [Test]
        public void TestInitializeEmpty()
        {
@@ -2979,7 +3216,6 @@ public class ArrayTest
                public int i, j;
        }
 
-#if !TARGET_JVM // BugBUG: T[] is not yet ICollection<T> under TARGET_JVM
        [Test]
        // From bug #80563
        public void ICollectionNull ()
@@ -3035,7 +3271,6 @@ public class ArrayTest
                Assert.AreEqual (-1, test.IndexOf (null), "array with test");
        }
        
-#endif // TARGET_JVM
 
        #region Bug 80299
 
@@ -3150,6 +3385,30 @@ public class ArrayTest
                }
        }
 
+       [Test]
+       public void IEnumerator_Dispose ()
+       {
+               IEnumerable<int> e = new int[] { 1 };
+               var en = e.GetEnumerator ();
+               Assert.IsTrue (en.MoveNext (), "#1");
+               Assert.IsFalse (en.MoveNext (), "#2");
+               en.Dispose ();
+               Assert.IsFalse (en.MoveNext (), "#3");
+       }
+
+       [Test]
+       public void IEnumerator_ZeroSize ()
+       {
+               IEnumerable<int> e = Array.Empty<int> ();
+               var en = e.GetEnumerator ();
+               Assert.IsFalse (en.MoveNext (), "#1");
+
+               e = Array.Empty<int> ();
+               en = e.GetEnumerator ();
+               Assert.IsFalse (en.MoveNext (), "#2");
+       }
+
+       [Test]
        public void ICollection_IsReadOnly() {
                ICollection<string> arr = new string [10];
 
@@ -3258,7 +3517,16 @@ public class ArrayTest
                }
        }
 
-#if NET_4_0
+       [Test] //bxc #11184
+       public void UnalignedArrayClear ()
+       {
+               byte[] input = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+               byte[] expected = new byte[] { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+               Array.Clear (input, 5, 11);
+               
+               Assert.AreEqual (input, expected);
+       }
+
        [Test]
        [ExpectedException (typeof (ArgumentException))]
        public void CompareToWithJaggedArray () {
@@ -3392,7 +3660,82 @@ public class ArrayTest
                array.Equals (array2, EqualityComparer<long>.Default);
        }
 
-#endif
+       [Test]
+       [ExpectedException (typeof (ArgumentNullException))]    
+       public void IStructuralEquatable_GetHashCode_NullComparer ()
+       {
+               IStructuralEquatable a = new int[] { 1, 2 };
+               a.GetHashCode (null);
+       }
+
+       class TestComparer_GetHashCode : IEqualityComparer
+       {
+               public int Counter;
+
+               bool IEqualityComparer.Equals (object x, object y)
+               {
+                       throw new NotImplementedException ();
+               }
 
+               public int GetHashCode (object obj)
+               {
+                       return Counter++;
+               }
+       }
+
+       [Test]
+       public void IStructuralEquatable_GetHashCode ()
+       {
+               IStructuralEquatable a = new int[] { 1, 2, 9 };
+
+               var c = new TestComparer_GetHashCode ();
+               a.GetHashCode (c);
+               Assert.AreEqual (3, c.Counter);         
+       }
+
+       [Test]
+       public void EnumeratorsEquality ()
+       {
+               int [] normalBase = new int [0];
+               IEnumerable<int> specialBase = new int [0];
+
+               var firstSpecial = specialBase.GetEnumerator ();
+               var secondSpecial = specialBase.GetEnumerator ();
+               var firstNormal = normalBase.GetEnumerator ();
+               var secondNormal = normalBase.GetEnumerator ();
+
+               Assert.IsFalse (object.ReferenceEquals (firstNormal, secondNormal));
+               Assert.IsTrue (object.ReferenceEquals (firstSpecial, secondSpecial));
+       }
+
+       [Test]
+       public void JaggedArrayCtor ()
+       {
+        var type = Type.GetType ("System.Object[][]");
+
+               ConstructorInfo ctor = null;
+        foreach (var c in type.GetConstructors ()) {
+                       if (c.GetParameters ().Length == 2)
+                               ctor = c;
+               }
+               Assert.IsNotNull (ctor);
+               var arr = (object[])ctor.Invoke (new object [] { 4, 10 });
+               for (int i = 0; i < 4; ++i) {
+                       Assert.IsNotNull (arr [i]);
+                       Assert.AreEqual (10, ((object[])arr [i]).Length);
+               }
+       }
+
+       [Test]
+       public unsafe void PointerArraysBoxing ()
+       {
+               var x = new int*[10];
+               var e = x.GetEnumerator ();
+               e.MoveNext ();
+
+               Assert.Throws<NotSupportedException> (() => { var _ = e.Current; }, "#1");
+               Assert.Throws<NotSupportedException> (() => { var _ = x.GetValue (0); }, "#2");
+               Assert.Throws<NotSupportedException> (() => { x.SetValue (0, 0); }, "#3");
+       }
 }
 }