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 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 の順で参照
111 var x = dict["key4"];
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 var x = dict["key2"]; // 7アクセス目
148 dict.TryGetValue("key4", out x); // 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) =>
168 removedList.Add(e.Item.Key);
175 // 直近に参照された 3, 4 以外のアイテムに対してイベントが発生しているはず
176 Assert.Equal(new[] { "key1", "key2" }, removedList, collComparer);
179 // ここから下は IDictionary としての機能が正しく動作するかのテスト
182 public void AddTest()
184 var dict = new LRUCacheDictionary<string, string>();
186 dict.Add("key1", "value1");
188 Assert.Equal(1, dict.innerDict.Count);
189 Assert.True(dict.innerDict.ContainsKey("key1"));
190 var internalNode = dict.innerDict["key1"];
191 Assert.Equal("key1", internalNode.Value.Key);
192 Assert.Equal("value1", internalNode.Value.Value);
194 dict.Add("key2", "value2");
196 Assert.Equal(2, dict.innerDict.Count);
197 Assert.True(dict.innerDict.ContainsKey("key2"));
198 internalNode = dict.innerDict["key2"];
199 Assert.Equal("key2", internalNode.Value.Key);
200 Assert.Equal("value2", internalNode.Value.Value);
204 public void ContainsKeyTest()
206 var dict = new LRUCacheDictionary<string, string>
213 Assert.True(dict.ContainsKey("key1"));
214 Assert.True(dict.ContainsKey("key3"));
215 Assert.False(dict.ContainsKey("value1"));
216 Assert.False(dict.ContainsKey("hogehoge"));
220 public void ContainsTest()
222 var dict = new LRUCacheDictionary<string, string>
229 Assert.True(dict.Contains(new KeyValuePair<string, string>("key1", "value1")));
230 Assert.False(dict.Contains(new KeyValuePair<string, string>("key3", "value2")));
231 Assert.False(dict.Contains(new KeyValuePair<string, string>("value3", "key3")));
232 Assert.False(dict.Contains(new KeyValuePair<string, string>("hogehoge", "hogehoge")));
236 public void RemoveTest()
238 var dict = new LRUCacheDictionary<string, string>
245 var ret = dict.Remove("key1");
248 Assert.Equal(2, dict.innerDict.Count);
249 Assert.Equal(2, dict.innerList.Count);
250 Assert.False(dict.innerDict.ContainsKey("key1"));
251 Assert.True(dict.innerDict.ContainsKey("key2"));
252 Assert.True(dict.innerDict.ContainsKey("key3"));
257 Assert.Empty(dict.innerDict);
258 Assert.Empty(dict.innerList);
260 ret = dict.Remove("hogehoge");
265 public void Remove2Test()
267 var dict = new LRUCacheDictionary<string, string>
274 var ret = dict.Remove(new KeyValuePair<string, string>("key1", "value1"));
277 Assert.Equal(2, dict.innerDict.Count);
278 Assert.Equal(2, dict.innerList.Count);
279 Assert.False(dict.innerDict.ContainsKey("key1"));
280 Assert.True(dict.innerDict.ContainsKey("key2"));
281 Assert.True(dict.innerDict.ContainsKey("key3"));
283 ret = dict.Remove(new KeyValuePair<string, string>("key2", "hogehoge"));
286 dict.Remove(new KeyValuePair<string, string>("key2", "value2"));
287 dict.Remove(new KeyValuePair<string, string>("key3", "value3"));
289 Assert.Empty(dict.innerDict);
290 Assert.Empty(dict.innerList);
292 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>
341 var ret = dict.TryGetValue("key1", out value);
343 Assert.Equal("value1", value);
345 ret = dict.TryGetValue("hogehoge", out value);
351 public void KeysTest()
353 var dict = new LRUCacheDictionary<string, string>
360 Assert.Equal(new[] { "key1", "key2", "key3" }, dict.Keys, collComparer);
362 dict.Add("foo", "bar");
363 Assert.Equal(new[] { "key1", "key2", "key3", "foo" }, dict.Keys, collComparer);
366 Assert.Equal(new[] { "key1", "key3", "foo" }, dict.Keys, collComparer);
369 Assert.Empty(dict.Keys);
373 public void ValuesTest()
375 var dict = new LRUCacheDictionary<string, string>
382 Assert.Equal(new[] { "value1", "value2", "value3" }, dict.Values, collComparer);
384 dict.Add("foo", "bar");
385 Assert.Equal(new[] { "value1", "value2", "value3", "bar" }, dict.Values, collComparer);
388 Assert.Equal(new[] { "value1", "value3", "bar" }, dict.Values, collComparer);
391 Assert.Empty(dict.Values);
395 public void CountTest()
397 var dict = new LRUCacheDictionary<string, string>();
399 Assert.Equal(0, dict.Count);
401 dict.Add("key1", "value1");
402 Assert.Equal(1, dict.Count);
404 dict.Add("key2", "value2");
405 Assert.Equal(2, dict.Count);
408 Assert.Equal(1, dict.Count);
411 Assert.Equal(0, dict.Count);
415 public void CopyToTest()
417 var dict = new LRUCacheDictionary<string, string>
424 var array = new KeyValuePair<string, string>[5];
425 dict.CopyTo(array, 0);
426 Assert.Equal(new KeyValuePair<string, string>("key1", "value1"), array[0]);
427 Assert.Equal(new KeyValuePair<string, string>("key2", "value2"), array[1]);
428 Assert.Equal(new KeyValuePair<string, string>("key3", "value3"), array[2]);
429 Assert.Equal(new KeyValuePair<string, string>(), array[3]);
430 Assert.Equal(new KeyValuePair<string, string>(), array[4]);
432 array = new KeyValuePair<string, string>[5];
433 dict.CopyTo(array, 1);
434 Assert.Equal(new KeyValuePair<string, string>(), array[0]);
435 Assert.Equal(new KeyValuePair<string, string>("key1", "value1"), array[1]);
436 Assert.Equal(new KeyValuePair<string, string>("key2", "value2"), array[2]);
437 Assert.Equal(new KeyValuePair<string, string>("key3", "value3"), array[3]);
438 Assert.Equal(new KeyValuePair<string, string>(), array[4]);
440 array = new KeyValuePair<string, string>[5];
441 Assert.Throws<ArgumentException>(() => dict.CopyTo(array, 3));
442 Assert.Throws<ArgumentException>(() => dict.CopyTo(array, 5));
443 Assert.Throws<ArgumentOutOfRangeException>(() => dict.CopyTo(array, -1));
444 Assert.Throws<ArgumentNullException>(() => dict.CopyTo(null, 0));
448 public void IsReadOnlyTest()
450 var dict = new LRUCacheDictionary<string, string>();
452 Assert.False(dict.IsReadOnly);
456 public void EnumeratorTest()
458 var dict = new LRUCacheDictionary<string, string>
465 var enumerator = dict.GetEnumerator();
467 Assert.True(enumerator.MoveNext());
468 Assert.Equal(new KeyValuePair<string, string>("key1", "value1"), enumerator.Current);
469 Assert.True(enumerator.MoveNext());
470 Assert.Equal(new KeyValuePair<string, string>("key2", "value2"), enumerator.Current);
471 Assert.True(enumerator.MoveNext());
472 Assert.Equal(new KeyValuePair<string, string>("key3", "value3"), enumerator.Current);
473 Assert.False(enumerator.MoveNext());
477 public void Enumerator2Test()
479 var dict = new LRUCacheDictionary<string, string>
486 var enumerator = ((IEnumerable)dict).GetEnumerator();
488 Assert.True(enumerator.MoveNext());
489 Assert.Equal(new KeyValuePair<string, string>("key1", "value1"), enumerator.Current);
490 Assert.True(enumerator.MoveNext());
491 Assert.Equal(new KeyValuePair<string, string>("key2", "value2"), enumerator.Current);
492 Assert.True(enumerator.MoveNext());
493 Assert.Equal(new KeyValuePair<string, string>("key3", "value3"), enumerator.Current);
494 Assert.False(enumerator.MoveNext());