1 // OpenTween - Client of Twitter
2 // Copyright (c) 2013 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
5 // This file is part of OpenTween.
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 // You should have received a copy of the GNU General Public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
23 using System.Collections;
24 using System.Collections.Generic;
28 using Xunit.Extensions;
32 public class LRUCacheDictionaryTest
34 private static readonly AnyOrderComparer<string> CollComparer = AnyOrderComparer<string>.Instance;
37 public void InnerListTest()
39 var dict = new LRUCacheDictionary<string, string>
46 var node = dict.InnerList.First;
47 Assert.Equal("key3", node.Value.Key);
49 Assert.Equal("key2", node.Value.Key);
51 Assert.Equal("key1", node.Value.Key);
53 // 2 -> 3 -> 1 の順に値を参照
59 node = dict.InnerList.First;
60 Assert.Equal("key1", node.Value.Key);
62 Assert.Equal("key3", node.Value.Key);
64 Assert.Equal("key2", node.Value.Key);
73 public void TrimLimitTest(int trimLimit)
75 var dict = new LRUCacheDictionary<string, string>()
82 dict.TrimLimit = trimLimit;
83 var ret = dict.Trim();
87 // trimLimit がアイテムの件数より大きい場合、Trim メソッドは動作せずに false を返す。
89 Assert.Equal(3, dict.Count);
94 Assert.Equal(trimLimit, dict.Count);
99 public void TrimOrderTest()
101 var dict = new LRUCacheDictionary<string, string>()
110 // 4 -> 2 -> 3 -> 1 -> 5 の順で参照
121 // 直近に参照された 3 -> 1 -> 5 のみ残っているはず
122 Assert.True(dict.ContainsKey("key1"));
123 Assert.False(dict.ContainsKey("key2"));
124 Assert.True(dict.ContainsKey("key3"));
125 Assert.False(dict.ContainsKey("key4"));
126 Assert.True(dict.ContainsKey("key5"));
130 public void AutoTrimTest()
132 var dict = new LRUCacheDictionary<string, string>();
134 dict.AutoTrimCount = 4; // 4アクセス毎に
135 dict.TrimLimit = 3; // 3個を越えるアイテムを削除する
137 dict["key1"] = "value1"; // 1アクセス目
138 dict["key2"] = "value2"; // 2アクセス目
139 dict["key3"] = "value3"; // 3アクセス目
140 dict["key4"] = "value4"; // 4アクセス目 (この直後にTrim)
142 // 1 -> 2 -> 3 -> 4 の順にアクセスしたため、直近 3 件の 2, 3, 4 だけが残る
143 Assert.Equal(new[] { "key2", "key3", "key4" }, dict.InnerDict.Keys, CollComparer);
145 dict["key5"] = "value5"; // 5アクセス目
146 dict.Add("key6", "value6"); // 6アクセス目
147 _ = dict["key2"]; // 7アクセス目
148 dict.TryGetValue("key4", out _); // 8アクセス目 (この直後にTrim)
150 // 5 -> 6 -> 2 -> 4 の順でアクセスしたため、直近 3 件の 6, 2, 4 だけが残る
151 Assert.Equal(new[] { "key6", "key2", "key4" }, dict.InnerDict.Keys, CollComparer);
155 public void CacheRemovedEventTest()
157 var dict = new LRUCacheDictionary<string, string>();
159 dict["key1"] = "value1";
160 dict["key2"] = "value2";
161 dict["key3"] = "value3";
162 dict["key4"] = "value4";
165 var removedList = new List<string>();
166 dict.CacheRemoved += (s, e) => removedList.Add(e.Item.Key);
172 // 直近に参照された 3, 4 以外のアイテムに対してイベントが発生しているはず
173 Assert.Equal(new[] { "key1", "key2" }, removedList, CollComparer);
176 // ここから下は IDictionary としての機能が正しく動作するかのテスト
179 public void AddTest()
181 var dict = new LRUCacheDictionary<string, string>();
183 dict.Add("key1", "value1");
185 Assert.Single(dict.InnerDict);
186 Assert.True(dict.InnerDict.ContainsKey("key1"));
187 var internalNode = dict.InnerDict["key1"];
188 Assert.Equal("key1", internalNode.Value.Key);
189 Assert.Equal("value1", internalNode.Value.Value);
191 dict.Add("key2", "value2");
193 Assert.Equal(2, dict.InnerDict.Count);
194 Assert.True(dict.InnerDict.ContainsKey("key2"));
195 internalNode = dict.InnerDict["key2"];
196 Assert.Equal("key2", internalNode.Value.Key);
197 Assert.Equal("value2", internalNode.Value.Value);
201 public void ContainsKeyTest()
203 var dict = new LRUCacheDictionary<string, string>
210 Assert.True(dict.ContainsKey("key1"));
211 Assert.True(dict.ContainsKey("key3"));
212 Assert.False(dict.ContainsKey("value1"));
213 Assert.False(dict.ContainsKey("hogehoge"));
217 public void ContainsTest()
219 var dict = new LRUCacheDictionary<string, string>
226 #pragma warning disable xUnit2017
227 Assert.True(dict.Contains(new("key1", "value1")));
228 Assert.False(dict.Contains(new("key3", "value2")));
229 Assert.False(dict.Contains(new("value3", "key3")));
230 Assert.False(dict.Contains(new("hogehoge", "hogehoge")));
231 #pragma warning restore xUnit2017
235 public void RemoveTest()
237 var dict = new LRUCacheDictionary<string, string>
244 var ret = dict.Remove("key1");
247 Assert.Equal(2, dict.InnerDict.Count);
248 Assert.Equal(2, dict.InnerList.Count);
249 Assert.False(dict.InnerDict.ContainsKey("key1"));
250 Assert.True(dict.InnerDict.ContainsKey("key2"));
251 Assert.True(dict.InnerDict.ContainsKey("key3"));
256 Assert.Empty(dict.InnerDict);
257 Assert.Empty(dict.InnerList);
259 ret = dict.Remove("hogehoge");
264 public void Remove2Test()
266 var dict = new LRUCacheDictionary<string, string>
273 var ret = dict.Remove(new KeyValuePair<string, string>("key1", "value1"));
276 Assert.Equal(2, dict.InnerDict.Count);
277 Assert.Equal(2, dict.InnerList.Count);
278 Assert.False(dict.InnerDict.ContainsKey("key1"));
279 Assert.True(dict.InnerDict.ContainsKey("key2"));
280 Assert.True(dict.InnerDict.ContainsKey("key3"));
282 ret = dict.Remove(new KeyValuePair<string, string>("key2", "hogehoge"));
285 dict.Remove(new KeyValuePair<string, string>("key2", "value2"));
286 dict.Remove(new KeyValuePair<string, string>("key3", "value3"));
288 Assert.Empty(dict.InnerDict);
289 Assert.Empty(dict.InnerList);
291 ret = dict.Remove(new KeyValuePair<string, string>("hogehoge", "hogehoge"));
296 public void GetterTest()
298 var dict = new LRUCacheDictionary<string, string>
305 Assert.Equal("value1", dict["key1"]);
306 Assert.Equal("value2", dict["key2"]);
307 Assert.Equal("value3", dict["key3"]);
309 Assert.Throws<KeyNotFoundException>(() => { var x = dict["hogehoge"]; });
313 public void SetterTest()
315 var dict = new LRUCacheDictionary<string, string>
322 dict["key1"] = "foo";
323 Assert.Equal("foo", dict.InnerDict["key1"].Value.Value);
325 dict["hogehoge"] = "bar";
326 Assert.True(dict.InnerDict.ContainsKey("hogehoge"));
327 Assert.Equal("bar", dict.InnerDict["hogehoge"].Value.Value);
331 public void TryGetValueTest()
333 var dict = new LRUCacheDictionary<string, string>
340 var ret = dict.TryGetValue("key1", out var value);
342 Assert.Equal("value1", value);
344 ret = dict.TryGetValue("hogehoge", out value);
350 public void KeysTest()
352 var dict = new LRUCacheDictionary<string, string>
359 Assert.Equal(new[] { "key1", "key2", "key3" }, dict.Keys, CollComparer);
361 dict.Add("foo", "bar");
362 Assert.Equal(new[] { "key1", "key2", "key3", "foo" }, dict.Keys, CollComparer);
365 Assert.Equal(new[] { "key1", "key3", "foo" }, dict.Keys, CollComparer);
368 Assert.Empty(dict.Keys);
372 public void ValuesTest()
374 var dict = new LRUCacheDictionary<string, string>
381 Assert.Equal(new[] { "value1", "value2", "value3" }, dict.Values, CollComparer);
383 dict.Add("foo", "bar");
384 Assert.Equal(new[] { "value1", "value2", "value3", "bar" }, dict.Values, CollComparer);
387 Assert.Equal(new[] { "value1", "value3", "bar" }, dict.Values, CollComparer);
390 Assert.Empty(dict.Values);
394 public void CountTest()
396 var dict = new LRUCacheDictionary<string, string>();
400 dict.Add("key1", "value1");
403 dict.Add("key2", "value2");
404 Assert.Equal(2, dict.Count);
414 public void CopyToTest()
416 var dict = new LRUCacheDictionary<string, string>
423 var array = new KeyValuePair<string, string>[5];
424 dict.CopyTo(array, 0);
425 Assert.Equal(new KeyValuePair<string, string>("key1", "value1"), array[0]);
426 Assert.Equal(new KeyValuePair<string, string>("key2", "value2"), array[1]);
427 Assert.Equal(new KeyValuePair<string, string>("key3", "value3"), array[2]);
428 Assert.Equal(new KeyValuePair<string, string>(), array[3]);
429 Assert.Equal(new KeyValuePair<string, string>(), array[4]);
431 array = new KeyValuePair<string, string>[5];
432 dict.CopyTo(array, 1);
433 Assert.Equal(new KeyValuePair<string, string>(), array[0]);
434 Assert.Equal(new KeyValuePair<string, string>("key1", "value1"), array[1]);
435 Assert.Equal(new KeyValuePair<string, string>("key2", "value2"), array[2]);
436 Assert.Equal(new KeyValuePair<string, string>("key3", "value3"), array[3]);
437 Assert.Equal(new KeyValuePair<string, string>(), array[4]);
439 array = new KeyValuePair<string, string>[5];
440 Assert.Throws<ArgumentException>(() => dict.CopyTo(array, 3));
441 Assert.Throws<ArgumentException>(() => dict.CopyTo(array, 5));
442 Assert.Throws<ArgumentOutOfRangeException>(() => dict.CopyTo(array, -1));
443 Assert.Throws<ArgumentNullException>(() => dict.CopyTo(null!, 0));
447 public void IsReadOnlyTest()
449 var dict = new LRUCacheDictionary<string, string>();
451 Assert.False(dict.IsReadOnly);
455 public void EnumeratorTest()
457 var dict = new LRUCacheDictionary<string, string>
464 var enumerator = dict.GetEnumerator();
466 Assert.True(enumerator.MoveNext());
467 Assert.Equal(new KeyValuePair<string, string>("key1", "value1"), enumerator.Current);
468 Assert.True(enumerator.MoveNext());
469 Assert.Equal(new KeyValuePair<string, string>("key2", "value2"), enumerator.Current);
470 Assert.True(enumerator.MoveNext());
471 Assert.Equal(new KeyValuePair<string, string>("key3", "value3"), enumerator.Current);
472 Assert.False(enumerator.MoveNext());
476 public void Enumerator2Test()
478 var dict = new LRUCacheDictionary<string, string>
485 var enumerator = ((IEnumerable)dict).GetEnumerator();
487 Assert.True(enumerator.MoveNext());
488 Assert.Equal(new KeyValuePair<string, string>("key1", "value1"), enumerator.Current);
489 Assert.True(enumerator.MoveNext());
490 Assert.Equal(new KeyValuePair<string, string>("key2", "value2"), enumerator.Current);
491 Assert.True(enumerator.MoveNext());
492 Assert.Equal(new KeyValuePair<string, string>("key3", "value3"), enumerator.Current);
493 Assert.False(enumerator.MoveNext());