OSDN Git Service

bit.ly API キーの検証を行わず、URL短縮の実行時に認証情報の有無のみ確認する
[opentween/open-tween.git] / OpenTween.Tests / LRUCacheDictionaryTest.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2013 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
4 //
5 // This file is part of OpenTween.
6 //
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)
10 // any later version.
11 //
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
15 // for more details.
16 //
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.
21
22 using System;
23 using System.Collections;
24 using System.Collections.Generic;
25 using System.Linq;
26 using System.Text;
27 using Xunit;
28 using Xunit.Extensions;
29
30 namespace OpenTween
31 {
32     public class LRUCacheDictionaryTest
33     {
34         private static AnyOrderComparer<string> collComparer = AnyOrderComparer<string>.Instance;
35
36         [Fact]
37         public void InnerListTest()
38         {
39             var dict = new LRUCacheDictionary<string, string>
40             {
41                 ["key1"] = "value1",
42                 ["key2"] = "value2",
43                 ["key3"] = "value3",
44             };
45
46             var node = dict.innerList.First;
47             Assert.Equal("key3", node.Value.Key);
48             node = node.Next;
49             Assert.Equal("key2", node.Value.Key);
50             node = node.Next;
51             Assert.Equal("key1", node.Value.Key);
52
53             // 2 -> 3 -> 1 の順に値を参照
54             var x = dict["key2"];
55             x = dict["key3"];
56             x = dict["key1"];
57
58             // 直近に参照した順で並んでいるかテスト
59             node = dict.innerList.First;
60             Assert.Equal("key1", node.Value.Key);
61             node = node.Next;
62             Assert.Equal("key3", node.Value.Key);
63             node = node.Next;
64             Assert.Equal("key2", node.Value.Key);
65         }
66
67         [Theory]
68         [InlineData(1)]
69         [InlineData(2)]
70         [InlineData(3)]
71         [InlineData(4)]
72         [InlineData(5)]
73         public void TrimLimitTest(int trimLimit)
74         {
75             var dict = new LRUCacheDictionary<string, string>()
76             {
77                 ["key1"] = "value1",
78                 ["key2"] = "value2",
79                 ["key3"] = "value3",
80             };
81
82             dict.TrimLimit = trimLimit;
83             var ret = dict.Trim();
84
85             if (trimLimit >= 3)
86             {
87                 // trimLimit がアイテムの件数より大きい場合、Trim メソッドは動作せずに false を返す。
88                 Assert.False(ret);
89                 Assert.Equal(3, dict.Count);
90             }
91             else
92             {
93                 Assert.True(ret);
94                 Assert.Equal(trimLimit, dict.Count);
95             }
96         }
97
98         [Fact]
99         public void TrimOrderTest()
100         {
101             var dict = new LRUCacheDictionary<string, string>()
102             {
103                 ["key1"] = "value1",
104                 ["key2"] = "value2",
105                 ["key3"] = "value3",
106                 ["key4"] = "value4",
107                 ["key5"] = "value5",
108             };
109
110             // 4 -> 2 -> 3 -> 1 -> 5 の順で参照
111             var x = dict["key4"];
112             x = dict["key2"];
113             x = dict["key3"];
114             x = dict["key1"];
115             x = dict["key5"];
116
117             // 3 個までに縮小
118             dict.TrimLimit = 3;
119             dict.Trim();
120
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"));
127         }
128
129         [Fact]
130         public void AutoTrimTest()
131         {
132             var dict = new LRUCacheDictionary<string, string>();
133
134             dict.AutoTrimCount = 4; // 4アクセス毎に
135             dict.TrimLimit = 3; // 3個を越えるアイテムを削除する
136
137             dict["key1"] = "value1"; // 1アクセス目
138             dict["key2"] = "value2"; // 2アクセス目
139             dict["key3"] = "value3"; // 3アクセス目
140             dict["key4"] = "value4"; // 4アクセス目 (この直後にTrim)
141
142             // 1 -> 2 -> 3 -> 4 の順にアクセスしたため、直近 3 件の 2, 3, 4 だけが残る
143             Assert.Equal(new[] { "key2", "key3", "key4" }, dict.innerDict.Keys, collComparer);
144
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)
149
150             // 5 -> 6 -> 2 -> 4 の順でアクセスしたため、直近 3 件の 6, 2, 4 だけが残る
151             Assert.Equal(new[] { "key6", "key2", "key4" }, dict.innerDict.Keys, collComparer);
152         }
153
154         [Fact]
155         public void CacheRemovedEventTest()
156         {
157             var dict = new LRUCacheDictionary<string, string>();
158
159             dict["key1"] = "value1";
160             dict["key2"] = "value2";
161             dict["key3"] = "value3";
162             dict["key4"] = "value4";
163
164             // イベント設定
165             var removedList = new List<string>();
166             dict.CacheRemoved += (s, e) =>
167             {
168                 removedList.Add(e.Item.Key);
169             };
170
171             // 2 個までに縮小
172             dict.TrimLimit = 2;
173             dict.Trim();
174
175             // 直近に参照された 3, 4 以外のアイテムに対してイベントが発生しているはず
176             Assert.Equal(new[] { "key1", "key2" }, removedList, collComparer);
177         }
178
179         // ここから下は IDictionary としての機能が正しく動作するかのテスト
180
181         [Fact]
182         public void AddTest()
183         {
184             var dict = new LRUCacheDictionary<string, string>();
185
186             dict.Add("key1", "value1");
187
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);
193
194             dict.Add("key2", "value2");
195
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);
201         }
202
203         [Fact]
204         public void ContainsKeyTest()
205         {
206             var dict = new LRUCacheDictionary<string, string>
207             {
208                 ["key1"] = "value1",
209                 ["key2"] = "value2",
210                 ["key3"] = "value3",
211             };
212
213             Assert.True(dict.ContainsKey("key1"));
214             Assert.True(dict.ContainsKey("key3"));
215             Assert.False(dict.ContainsKey("value1"));
216             Assert.False(dict.ContainsKey("hogehoge"));
217         }
218
219         [Fact]
220         public void ContainsTest()
221         {
222             var dict = new LRUCacheDictionary<string, string>
223             {
224                 ["key1"] = "value1",
225                 ["key2"] = "value2",
226                 ["key3"] = "value3",
227             };
228
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")));
233         }
234
235         [Fact]
236         public void RemoveTest()
237         {
238             var dict = new LRUCacheDictionary<string, string>
239             {
240                 ["key1"] = "value1",
241                 ["key2"] = "value2",
242                 ["key3"] = "value3",
243             };
244
245             var ret = dict.Remove("key1");
246
247             Assert.True(ret);
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"));
253
254             dict.Remove("key2");
255             dict.Remove("key3");
256
257             Assert.Empty(dict.innerDict);
258             Assert.Empty(dict.innerList);
259
260             ret = dict.Remove("hogehoge");
261             Assert.False(ret);
262         }
263
264         [Fact]
265         public void Remove2Test()
266         {
267             var dict = new LRUCacheDictionary<string, string>
268             {
269                 ["key1"] = "value1",
270                 ["key2"] = "value2",
271                 ["key3"] = "value3",
272             };
273
274             var ret = dict.Remove(new KeyValuePair<string, string>("key1", "value1"));
275
276             Assert.True(ret);
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"));
282
283             ret = dict.Remove(new KeyValuePair<string, string>("key2", "hogehoge"));
284             Assert.False(ret);
285
286             dict.Remove(new KeyValuePair<string, string>("key2", "value2"));
287             dict.Remove(new KeyValuePair<string, string>("key3", "value3"));
288
289             Assert.Empty(dict.innerDict);
290             Assert.Empty(dict.innerList);
291
292             ret = dict.Remove(new KeyValuePair<string, string>("hogehoge", "hogehoge"));
293             Assert.False(ret);
294         }
295
296         public void GetterTest()
297         {
298             var dict = new LRUCacheDictionary<string, string>
299             {
300                 ["key1"] = "value1",
301                 ["key2"] = "value2",
302                 ["key3"] = "value3",
303             };
304
305             Assert.Equal("value1", dict["key1"]);
306             Assert.Equal("value2", dict["key2"]);
307             Assert.Equal("value3", dict["key3"]);
308
309             Assert.Throws<KeyNotFoundException>(() => { var x = dict["hogehoge"]; });
310         }
311
312         [Fact]
313         public void SetterTest()
314         {
315             var dict = new LRUCacheDictionary<string, string>
316             {
317                 ["key1"] = "value1",
318                 ["key2"] = "value2",
319                 ["key3"] = "value3",
320             };
321
322             dict["key1"] = "foo";
323             Assert.Equal("foo", dict.innerDict["key1"].Value.Value);
324
325             dict["hogehoge"] = "bar";
326             Assert.True(dict.innerDict.ContainsKey("hogehoge"));
327             Assert.Equal("bar", dict.innerDict["hogehoge"].Value.Value);
328         }
329
330         [Fact]
331         public void TryGetValueTest()
332         {
333             var dict = new LRUCacheDictionary<string, string>
334             {
335                 ["key1"] = "value1",
336                 ["key2"] = "value2",
337                 ["key3"] = "value3",
338             };
339
340             var ret = dict.TryGetValue("key1", out var value);
341             Assert.True(ret);
342             Assert.Equal("value1", value);
343
344             ret = dict.TryGetValue("hogehoge", out value);
345             Assert.False(ret);
346             Assert.Null(value);
347         }
348
349         [Fact]
350         public void KeysTest()
351         {
352             var dict = new LRUCacheDictionary<string, string>
353             {
354                 ["key1"] = "value1",
355                 ["key2"] = "value2",
356                 ["key3"] = "value3",
357             };
358
359             Assert.Equal(new[] { "key1", "key2", "key3" }, dict.Keys, collComparer);
360
361             dict.Add("foo", "bar");
362             Assert.Equal(new[] { "key1", "key2", "key3", "foo" }, dict.Keys, collComparer);
363
364             dict.Remove("key2");
365             Assert.Equal(new[] { "key1", "key3", "foo" }, dict.Keys, collComparer);
366
367             dict.Clear();
368             Assert.Empty(dict.Keys);
369         }
370
371         [Fact]
372         public void ValuesTest()
373         {
374             var dict = new LRUCacheDictionary<string, string>
375             {
376                 ["key1"] = "value1",
377                 ["key2"] = "value2",
378                 ["key3"] = "value3",
379             };
380
381             Assert.Equal(new[] { "value1", "value2", "value3" }, dict.Values, collComparer);
382
383             dict.Add("foo", "bar");
384             Assert.Equal(new[] { "value1", "value2", "value3", "bar" }, dict.Values, collComparer);
385
386             dict.Remove("key2");
387             Assert.Equal(new[] { "value1", "value3", "bar" }, dict.Values, collComparer);
388
389             dict.Clear();
390             Assert.Empty(dict.Values);
391         }
392
393         [Fact]
394         public void CountTest()
395         {
396             var dict = new LRUCacheDictionary<string, string>();
397
398             Assert.Equal(0, dict.Count);
399
400             dict.Add("key1", "value1");
401             Assert.Equal(1, dict.Count);
402
403             dict.Add("key2", "value2");
404             Assert.Equal(2, dict.Count);
405
406             dict.Remove("key1");
407             Assert.Equal(1, dict.Count);
408
409             dict.Clear();
410             Assert.Equal(0, dict.Count);
411         }
412
413         [Fact]
414         public void CopyToTest()
415         {
416             var dict = new LRUCacheDictionary<string, string>
417             {
418                 ["key1"] = "value1",
419                 ["key2"] = "value2",
420                 ["key3"] = "value3",
421             };
422
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]);
430
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]);
438
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));
444         }
445
446         [Fact]
447         public void IsReadOnlyTest()
448         {
449             var dict = new LRUCacheDictionary<string, string>();
450
451             Assert.False(dict.IsReadOnly);
452         }
453
454         [Fact]
455         public void EnumeratorTest()
456         {
457             var dict = new LRUCacheDictionary<string, string>
458             {
459                 ["key1"] = "value1",
460                 ["key2"] = "value2",
461                 ["key3"] = "value3",
462             };
463
464             var enumerator = dict.GetEnumerator();
465
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());
473         }
474
475         [Fact]
476         public void Enumerator2Test()
477         {
478             var dict = new LRUCacheDictionary<string, string>
479             {
480                 ["key1"] = "value1",
481                 ["key2"] = "value2",
482                 ["key3"] = "value3",
483             };
484
485             var enumerator = ((IEnumerable)dict).GetEnumerator();
486
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());
494         }
495     }
496 }