Skip to content

Commit 5314f3f

Browse files
authored
Add unit tests for Collections, apache#1116 (apache#1124)
* Add unit tests for Collections, apache#1116 * Improve nullability use and add nullable value/reference type unit tests * Apply same fix as last commit to ReverseComparer<T> too
1 parent 972ac07 commit 5314f3f

2 files changed

Lines changed: 367 additions & 56 deletions

File tree

Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
// Some tests adapted from Apache Harmony:
2+
// https://github.com/apache/harmony/blob/02970cb7227a335edd2c8457ebdde0195a735733/classlib/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/util/CollectionsTest.java
3+
4+
using Lucene.Net.Attributes;
5+
using Lucene.Net.Util;
6+
using NUnit.Framework;
7+
using System;
8+
using System.Collections.Generic;
9+
10+
#nullable enable
11+
12+
namespace Lucene.Net.Support
13+
{
14+
/*
15+
* Licensed to the Apache Software Foundation (ASF) under one or more
16+
* contributor license agreements. See the NOTICE file distributed with
17+
* this work for additional information regarding copyright ownership.
18+
* The ASF licenses this file to You under the Apache License, Version 2.0
19+
* (the "License"); you may not use this file except in compliance with
20+
* the License. You may obtain a copy of the License at
21+
*
22+
* http://www.apache.org/licenses/LICENSE-2.0
23+
*
24+
* Unless required by applicable law or agreed to in writing, software
25+
* distributed under the License is distributed on an "AS IS" BASIS,
26+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27+
* See the License for the specific language governing permissions and
28+
* limitations under the License.
29+
*/
30+
31+
[TestFixture]
32+
public class TestCollections : LuceneTestCase
33+
{
34+
private List<object> ll = null!; // LUCENENET specific: was LinkedList in Harmony tests, !: will be initialized in SetUp
35+
36+
// LUCENENET - omitting unused fields
37+
38+
private static object[] objArray = LoadObjArray(); // LUCENENET - use static loader method instead of static ctor
39+
40+
private static object[] LoadObjArray()
41+
{
42+
object[] objArray = new object[1000];
43+
for (int i = 0; i < objArray.Length; i++)
44+
{
45+
objArray[i] = i;
46+
}
47+
48+
return objArray;
49+
}
50+
51+
[Test, LuceneNetSpecific]
52+
public void TestEmptyList()
53+
{
54+
IList<object> list = Collections.EmptyList<object>();
55+
56+
Assert.AreEqual(0, list.Count);
57+
Assert.IsTrue(list.IsReadOnly);
58+
Assert.Throws<NotSupportedException>(() => list.Add(new object()));
59+
60+
IList<object> list2 = Collections.EmptyList<object>();
61+
62+
Assert.AreSame(list, list2); // ensure it does not allocate
63+
}
64+
65+
[Test, LuceneNetSpecific]
66+
public void TestEmptyMap()
67+
{
68+
IDictionary<object, object> map = Collections.EmptyMap<object, object>();
69+
70+
Assert.AreEqual(0, map.Count);
71+
Assert.IsTrue(map.IsReadOnly);
72+
Assert.Throws<NotSupportedException>(() => map.Add(new object(), new object()));
73+
74+
IDictionary<object, object> map2 = Collections.EmptyMap<object, object>();
75+
76+
Assert.AreSame(map, map2); // ensure it does not allocate
77+
}
78+
79+
[Test, LuceneNetSpecific]
80+
public void TestEmptySet()
81+
{
82+
ISet<object> set = Collections.EmptySet<object>();
83+
84+
Assert.AreEqual(0, set.Count);
85+
Assert.IsTrue(set.IsReadOnly);
86+
Assert.Throws<NotSupportedException>(() => set.Add(new object()));
87+
88+
ISet<object> set2 = Collections.EmptySet<object>();
89+
90+
Assert.AreSame(set, set2); // ensure it does not allocate
91+
}
92+
93+
/// <summary>
94+
/// Adapted from Harmony test_reverseLjava_util_List()
95+
/// </summary>
96+
[Test]
97+
public void TestReverse()
98+
{
99+
// Test for method void java.util.Collections.reverse(java.util.List)
100+
try
101+
{
102+
Collections.Reverse<object>(null!);
103+
fail("Expected NullPointerException for null list parameter");
104+
}
105+
catch (Exception e) when (e.IsNullPointerException())
106+
{
107+
//Expected
108+
}
109+
110+
Collections.Reverse(ll);
111+
using var i = ll.GetEnumerator();
112+
int count = objArray.Length - 1;
113+
while (i.MoveNext())
114+
{
115+
assertEquals("Failed to reverse collection", objArray[count], i.Current);
116+
--count;
117+
}
118+
119+
var myList = new List<object?>
120+
{
121+
null,
122+
20,
123+
};
124+
Collections.Reverse(myList);
125+
assertEquals($"Did not reverse correctly--first element is: {myList[0]}", 20, myList[0]);
126+
assertNull($"Did not reverse correctly--second element is: {myList[1]}", myList[1]);
127+
}
128+
129+
/// <summary>
130+
/// Adapted from Harmony test_reverseOrder()
131+
/// </summary>
132+
[Test]
133+
public void TestReverseOrder() {
134+
// Test for method IComparer<T>
135+
// Collections.ReverseOrder()
136+
// assumes no duplicates in ll
137+
IComparer<object> comp = Collections.ReverseOrder<object>();
138+
var list2 = new List<object>(ll); // LUCENENET - was LinkedList in Harmony
139+
list2.Sort(comp);
140+
int llSize = ll.Count;
141+
for (int counter = 0; counter < llSize; counter++)
142+
{
143+
assertEquals("New comparator does not reverse sorting order", list2[llSize - counter - 1], ll[counter]);
144+
}
145+
}
146+
147+
[Test, LuceneNetSpecific]
148+
public void TestReverseOrder_WithComparer()
149+
{
150+
IComparer<string> comp = Collections.ReverseOrder<string>(StringComparer.OrdinalIgnoreCase);
151+
var list = new List<string> { "B", "c", "a", "D" };
152+
list.Sort(comp);
153+
Assert.AreEqual(4, list.Count);
154+
Assert.AreEqual("D", list[0]);
155+
Assert.AreEqual("c", list[1]);
156+
Assert.AreEqual("B", list[2]);
157+
Assert.AreEqual("a", list[3]);
158+
}
159+
160+
[Test, LuceneNetSpecific]
161+
public void TestReverseOrder_NullableValueTypes()
162+
{
163+
IComparer<int?> comp = Collections.ReverseOrder<int?>();
164+
var list = new List<int?> { 5, null, 2, 8, null, 1, 3 };
165+
list.Sort(comp);
166+
167+
Assert.AreEqual(7, list.Count);
168+
Assert.AreEqual(8, list[0]);
169+
Assert.AreEqual(5, list[1]);
170+
Assert.AreEqual(3, list[2]);
171+
Assert.AreEqual(2, list[3]);
172+
Assert.AreEqual(1, list[4]);
173+
Assert.IsNull(list[5]);
174+
Assert.IsNull(list[6]);
175+
}
176+
177+
[Test, LuceneNetSpecific]
178+
public void TestReverseOrder_NullableValueTypes_WithComparer()
179+
{
180+
IComparer<double?> baseComparer = Comparer<double?>.Default;
181+
IComparer<double?> comp = Collections.ReverseOrder(baseComparer);
182+
var list = new List<double?> { 3.14, null, 2.71, null, 1.41, 0.0 };
183+
list.Sort(comp);
184+
185+
Assert.AreEqual(6, list.Count);
186+
Assert.AreEqual(3.14, list[0]);
187+
Assert.AreEqual(2.71, list[1]);
188+
Assert.AreEqual(1.41, list[2]);
189+
Assert.AreEqual(0.0, list[3]);
190+
Assert.IsNull(list[4]);
191+
Assert.IsNull(list[5]);
192+
}
193+
194+
[Test, LuceneNetSpecific]
195+
public void TestReverseOrder_NullableReferenceTypes()
196+
{
197+
IComparer<string?> comp = Collections.ReverseOrder<string?>();
198+
var list = new List<string?> { "zebra", null, "apple", "mango", null, "banana" };
199+
list.Sort(comp);
200+
201+
Assert.AreEqual(6, list.Count);
202+
Assert.AreEqual("zebra", list[0]);
203+
Assert.AreEqual("mango", list[1]);
204+
Assert.AreEqual("banana", list[2]);
205+
Assert.AreEqual("apple", list[3]);
206+
Assert.IsNull(list[4]);
207+
Assert.IsNull(list[5]);
208+
}
209+
210+
[Test, LuceneNetSpecific]
211+
public void TestReverseOrder_NullableReferenceTypes_WithComparer()
212+
{
213+
IComparer<string?> comp = Collections.ReverseOrder(StringComparer.OrdinalIgnoreCase);
214+
var list = new List<string?> { "Zebra", null, "apple", "Mango", null, "BANANA" };
215+
list.Sort(comp);
216+
217+
Assert.AreEqual(6, list.Count);
218+
Assert.AreEqual("Zebra", list[0]);
219+
Assert.AreEqual("Mango", list[1]);
220+
Assert.AreEqual("BANANA", list[2]);
221+
Assert.AreEqual("apple", list[3]);
222+
Assert.IsNull(list[4]);
223+
Assert.IsNull(list[5]);
224+
}
225+
226+
[Test, LuceneNetSpecific]
227+
public void TestSingletonMap()
228+
{
229+
IDictionary<string, string> map = Collections.SingletonMap("key", "value");
230+
231+
Assert.AreEqual(1, map.Count);
232+
Assert.IsTrue(map.IsReadOnly);
233+
Assert.Throws<NotSupportedException>(() => map.Add("key2", "value2"));
234+
Assert.Throws<NotSupportedException>(() => map["key"] = "value2");
235+
236+
Assert.AreEqual("value", map["key"]);
237+
}
238+
239+
[Test, LuceneNetSpecific]
240+
public void TestToString_Collection_Null()
241+
{
242+
Assert.AreEqual("null", Collections.ToString<object>(null!));
243+
}
244+
245+
[Test, LuceneNetSpecific]
246+
public void TestToString_Collection_Empty()
247+
{
248+
Assert.AreEqual("[]", Collections.ToString(new List<object>()));
249+
}
250+
251+
[Test, LuceneNetSpecific]
252+
public void TestToString_Collection()
253+
{
254+
var list = new List<object?>();
255+
list.Add(list);
256+
list.Add(1);
257+
list.Add('a');
258+
list.Add(2.1);
259+
list.Add("xyz");
260+
list.Add(new List<int> { 1, 2, 3 });
261+
list.Add(null);
262+
263+
Assert.AreEqual("[(this Collection), 1, a, 2.1, xyz, [1, 2, 3], null]", Collections.ToString(list));
264+
}
265+
266+
[Test, LuceneNetSpecific]
267+
public void TestToString_Dictionary()
268+
{
269+
var dict = new Dictionary<object, object?>()
270+
{
271+
{ "key1", "value1" },
272+
{ "key2", 2 },
273+
{ "key3", 'a' },
274+
{ "key4", 3.1 },
275+
{ "key5", new List<int> { 1, 2, 3 } },
276+
{ "key6", null }
277+
};
278+
279+
Assert.AreEqual("{key1=value1, key2=2, key3=a, key4=3.1, key5=[1, 2, 3], key6=null}", Collections.ToString(dict));
280+
}
281+
282+
[Test, LuceneNetSpecific]
283+
public void TestToString_Object_Null()
284+
{
285+
Assert.AreEqual("null", Collections.ToString(null));
286+
}
287+
288+
[Test, LuceneNetSpecific]
289+
public void TestToString_Object()
290+
{
291+
Assert.AreEqual("1", Collections.ToString(1));
292+
Assert.AreEqual("a", Collections.ToString('a'));
293+
Assert.AreEqual("2.1", Collections.ToString(2.1));
294+
Assert.AreEqual("xyz", Collections.ToString("xyz"));
295+
Assert.AreEqual("[1, 2, 3]", Collections.ToString(new List<int> { 1, 2, 3 }));
296+
}
297+
298+
[Test, LuceneNetSpecific]
299+
public void TestAsReadOnly_List()
300+
{
301+
var list = new List<object> { 1, 2, 3 };
302+
IList<object> readOnlyList = Collections.AsReadOnly(list);
303+
304+
Assert.AreEqual(3, readOnlyList.Count);
305+
Assert.IsTrue(readOnlyList.IsReadOnly);
306+
Assert.Throws<NotSupportedException>(() => readOnlyList.Add(4));
307+
Assert.Throws<NotSupportedException>(() => readOnlyList[0] = 5);
308+
}
309+
310+
[Test, LuceneNetSpecific]
311+
public void TestAsReadOnly_Dictionary()
312+
{
313+
var dict = new Dictionary<object, object>
314+
{
315+
{ "key1", "value1" },
316+
{ "key2", 2 },
317+
{ "key3", 'a' }
318+
};
319+
IDictionary<object, object> readOnlyDict = Collections.AsReadOnly(dict);
320+
321+
Assert.AreEqual(3, readOnlyDict.Count);
322+
Assert.IsTrue(readOnlyDict.IsReadOnly);
323+
Assert.Throws<NotSupportedException>(() => readOnlyDict.Add("key4", 4));
324+
Assert.Throws<NotSupportedException>(() => readOnlyDict["key1"] = "value2");
325+
}
326+
327+
public override void SetUp()
328+
{
329+
base.SetUp();
330+
331+
ll = new List<object>();
332+
// LUCENENET - omitting unused fields
333+
334+
for (int i = 0; i < objArray.Length; i++)
335+
{
336+
ll.Add(objArray[i]);
337+
}
338+
}
339+
}
340+
}

0 commit comments

Comments
 (0)