OSDN Git Service

#27621 言語間リンク取得時に<includeonly>, <noinclude>を考慮するよう修正,
[wptscs/wpts.git] / WptscsTest / Parsers / MediaWikiLinkParserTest.cs
1 // ================================================================================================
2 // <summary>
3 //      MediaWikiLinkParserのテストクラスソース。</summary>
4 //
5 // <copyright file="MediaWikiLinkParserTest.cs" company="honeplusのメモ帳">
6 //      Copyright (C) 2012 Honeplus. All rights reserved.</copyright>
7 // <author>
8 //      Honeplus</author>
9 // ================================================================================================
10
11 namespace Honememo.Wptscs.Parsers
12 {
13     using System;
14     using System.Collections.Generic;
15     using Honememo.Parsers;
16     using Honememo.Wptscs.Models;
17     using Honememo.Wptscs.Websites;
18     using NUnit.Framework;
19
20     /// <summary>
21     /// <see cref="MediaWikiLinkParser"/>のテストクラスです。
22     /// </summary>
23     [TestFixture]
24     class MediaWikiLinkParserTest
25     {
26         #region private変数
27
28         /// <summary>
29         /// 前処理・後処理で生成/解放される言語別の<see cref="MediaWikiParser"/>。
30         /// </summary>
31         private IDictionary<string, MediaWikiParser> mediaWikiParsers = new Dictionary<string, MediaWikiParser>();
32
33         #endregion
34
35         #region 前処理・後処理
36
37         /// <summary>
38         /// テストの前処理。
39         /// </summary>
40         /// <remarks><see cref="MediaWikiParser.Dispose"/>が必要な<see cref="MediaWikiParser"/>の生成。</remarks>
41         [TestFixtureSetUp]
42         public void SetUpBeforeClass()
43         {
44             this.mediaWikiParsers["en"] = new MediaWikiParser(new MockFactory().GetMediaWiki("en"));
45             this.mediaWikiParsers["ja"] = new MediaWikiParser(new MockFactory().GetMediaWiki("ja"));
46         }
47
48         /// <summary>
49         /// テストの後処理。
50         /// </summary>
51         /// <remarks><see cref="MediaWikiParser.Dispose"/>が必要な<see cref="MediaWikiParser"/>の解放。</remarks>
52         [TestFixtureTearDown]
53         public void TearDownAfterClass()
54         {
55             foreach (IDisposable parser in this.mediaWikiParsers.Values)
56             {
57                 parser.Dispose();
58             }
59
60             this.mediaWikiParsers.Clear();
61         }
62
63         #endregion
64
65         #region インタフェース実装メソッドテストケース
66
67         /// <summary>
68         /// <see cref="MediaWikiLinkParser.TryParse"/>メソッドテストケース(基本的な構文)。
69         /// </summary>
70         [Test]
71         public void TestTryParseBasic()
72         {
73             IElement element;
74             MediaWikiLink link;
75             MediaWikiLinkParser parser = new MediaWikiLinkParser(this.mediaWikiParsers["en"]);
76
77             // タイトルのみ
78             Assert.IsTrue(parser.TryParse("[[testtitle]]", out element));
79             link = (MediaWikiLink)element;
80             Assert.AreEqual("testtitle", link.Title);
81             Assert.IsNull(link.Section);
82             Assert.AreEqual(0, link.PipeTexts.Count);
83             Assert.IsNull(link.Interwiki);
84             Assert.IsFalse(link.IsColon);
85
86             // タイトルとセクション
87             Assert.IsTrue(parser.TryParse("[[testtitle#testsection]]", out element));
88             link = (MediaWikiLink)element;
89             Assert.AreEqual("testtitle", link.Title);
90             Assert.AreEqual("testsection", link.Section);
91             Assert.AreEqual(0, link.PipeTexts.Count);
92             Assert.IsNull(link.Interwiki);
93             Assert.IsFalse(link.IsColon);
94
95             // タイトルとセクションとパイプ後の文字列
96             Assert.IsTrue(parser.TryParse("[[testtitle#testsection|testpipe1|testpipe2]]", out element));
97             link = (MediaWikiLink)element;
98             Assert.AreEqual("testtitle", link.Title);
99             Assert.AreEqual("testsection", link.Section);
100             Assert.AreEqual(2, link.PipeTexts.Count);
101             Assert.AreEqual("testpipe1", link.PipeTexts[0].ToString());
102             Assert.AreEqual("testpipe2", link.PipeTexts[1].ToString());
103             Assert.IsNull(link.Interwiki);
104             Assert.IsFalse(link.IsColon);
105
106             // タイトルとセクションとパイプ後の文字列とコード
107             Assert.IsTrue(parser.TryParse("[[en:testtitle#testsection|testpipe1|testpipe2]]", out element));
108             link = (MediaWikiLink)element;
109             Assert.AreEqual("testtitle", link.Title);
110             Assert.AreEqual("testsection", link.Section);
111             Assert.AreEqual(2, link.PipeTexts.Count);
112             Assert.AreEqual("testpipe1", link.PipeTexts[0].ToString());
113             Assert.AreEqual("testpipe2", link.PipeTexts[1].ToString());
114             Assert.AreEqual("en", link.Interwiki);
115             Assert.IsFalse(link.IsColon);
116
117             // コメントはどこにあってもOK
118             // TODO: [<!--test-->[タイトル]] みたいなのもMediaWiki上では認識されるが、2012年1月現在未対応
119             Assert.IsTrue(parser.TryParse("[[testtitle<!--仮-->|testpipe1<!--コメントアウト-->]]", out element));
120             link = (MediaWikiLink)element;
121             Assert.AreEqual("testtitle<!--仮-->", link.Title);
122             Assert.AreEqual(1, link.PipeTexts.Count);
123             Assert.AreEqual("testpipe1<!--コメントアウト-->", link.PipeTexts[0].ToString());
124         }
125
126         /// <summary>
127         /// <see cref="MediaWikiLinkParser.TryParse"/>メソッドテストケース(NGパターン)。
128         /// </summary>
129         [Test]
130         public void TestTryParseNg()
131         {
132             IElement element;
133             MediaWikiLinkParser parser = new MediaWikiLinkParser(this.mediaWikiParsers["en"]);
134
135             // 開始タグが無い
136             Assert.IsFalse(parser.TryParse("testtitle]]", out element));
137
138             // 閉じタグが無い
139             Assert.IsFalse(parser.TryParse("[[testtitle", out element));
140
141             // 先頭が開始タグではない
142             Assert.IsFalse(parser.TryParse(" [[testtitle]]", out element));
143
144             // 外部リンクタグ
145             Assert.IsFalse(parser.TryParse("[testtitle]", out element));
146
147             // テンプレートタグ
148             Assert.IsFalse(parser.TryParse("{{testtitle}}", out element));
149
150             // 記事名名の部分に < > [ ] { } \n のいずれかの文字が存在する場合、NG
151             // ※ コメントや変数であれば可能、それ以外で存在するのがNG
152             Assert.IsFalse(parser.TryParse("[[test<title]]", out element));
153             Assert.IsFalse(parser.TryParse("[[test>title]]", out element));
154             Assert.IsFalse(parser.TryParse("[[test[title]]", out element));
155             Assert.IsFalse(parser.TryParse("[[test]title]]", out element));
156             Assert.IsFalse(parser.TryParse("[[test{title]]", out element));
157             Assert.IsFalse(parser.TryParse("[[test}title]]", out element));
158             Assert.IsFalse(parser.TryParse("[[testtitle\n]]", out element));
159
160             // 空・null
161             Assert.IsFalse(parser.TryParse(String.Empty, out element));
162             Assert.IsFalse(parser.TryParse(null, out element));
163         }
164
165         /// <summary>
166         /// <see cref="MediaWikiLinkParser.TryParse"/>メソッドテストケース(入れ子)。
167         /// </summary>
168         [Test]
169         public void TestTryParseNested()
170         {
171             IElement element;
172             MediaWikiLink link;
173             MediaWikiLinkParser parser = new MediaWikiLinkParser(this.mediaWikiParsers["en"]);
174
175             // テンプレートはパイプ以後にある分には全てOK
176             Assert.IsTrue(parser.TryParse("[[ロシア語|{{lang|ru|русский язык}}]]", out element));
177             link = (MediaWikiLink)element;
178             Assert.AreEqual("ロシア語", link.Title);
179             Assert.AreEqual(1, link.PipeTexts.Count);
180             Assert.AreEqual("{{lang|ru|русский язык}}", link.PipeTexts[0].ToString());
181
182             // 変数の場合、記事名の部分にも入れられる
183             Assert.IsTrue(parser.TryParse("[[{{{title|デフォルトジャンル}}}-stub]]", out element));
184             link = (MediaWikiLink)element;
185             Assert.AreEqual("{{{title|デフォルトジャンル}}}-stub", link.Title);
186         }
187
188         /// <summary>
189         /// <see cref="MediaWikiLinkParser.TryParse"/>メソッドテストケース(名前空間)。
190         /// </summary>
191         [Test]
192         public void TestTryParseNamespace()
193         {
194             IElement element;
195             MediaWikiLink link;
196             MediaWikiLinkParser parser = new MediaWikiLinkParser(this.mediaWikiParsers["ja"]);
197
198             // カテゴリ標準
199             Assert.IsTrue(parser.TryParse("[[Category:test]]", out element));
200             link = (MediaWikiLink)element;
201             Assert.AreEqual("Category:test", link.Title);
202             Assert.AreEqual(0, link.PipeTexts.Count);
203             Assert.IsNull(link.Interwiki);
204             Assert.IsFalse(link.IsColon);
205
206             // カテゴリソート名指定
207             Assert.IsTrue(parser.TryParse("[[Category:test|てすと]]", out element));
208             link = (MediaWikiLink)element;
209             Assert.AreEqual("Category:test", link.Title);
210             Assert.AreEqual(1, link.PipeTexts.Count);
211             Assert.AreEqual("てすと", link.PipeTexts[0].ToString());
212             Assert.IsNull(link.Interwiki);
213             Assert.IsFalse(link.IsColon);
214
215             // カテゴリにならないような指定
216             Assert.IsTrue(parser.TryParse("[[:Category:test]]", out element));
217             link = (MediaWikiLink)element;
218             Assert.AreEqual("Category:test", link.Title);
219             Assert.AreEqual(0, link.PipeTexts.Count);
220             Assert.IsNull(link.Interwiki);
221             Assert.IsTrue(link.IsColon);
222
223             // ファイル、入れ子もあり
224             Assert.IsTrue(parser.TryParse("[[ファイル:test.png|thumb|100px|テスト[[画像]]]]", out element));
225             link = (MediaWikiLink)element;
226             Assert.AreEqual("ファイル:test.png", link.Title);
227             Assert.AreEqual(3, link.PipeTexts.Count);
228             Assert.AreEqual("thumb", link.PipeTexts[0].ToString());
229             Assert.AreEqual("100px", link.PipeTexts[1].ToString());
230             Assert.AreEqual("テスト[[画像]]", link.PipeTexts[2].ToString());
231             Assert.IsInstanceOf(typeof(ListElement), link.PipeTexts[2]);
232             ListElement list = (ListElement)link.PipeTexts[2];
233             Assert.AreEqual(2, list.Count);
234             Assert.AreEqual("テスト", list[0].ToString());
235             Assert.AreEqual("[[画像]]", list[1].ToString());
236             Assert.IsNull(link.Interwiki);
237         }
238
239         /// <summary>
240         /// <see cref="MediaWikiLinkParser.TryParse"/>メソッドテストケース(サブページ)。
241         /// </summary>
242         [Test]
243         public void TestTryParseSubpage()
244         {
245             IElement element;
246             MediaWikiLink link;
247             MediaWikiLinkParser parser = new MediaWikiLinkParser(this.mediaWikiParsers["en"]);
248
249             // 全て指定されているケースは通常の記事と同じ扱い
250             Assert.IsTrue(parser.TryParse("[[testtitle/subpage]]", out element));
251             link = (MediaWikiLink)element;
252             Assert.AreEqual("testtitle/subpage", link.Title);
253             Assert.IsFalse(link.IsSubpage());
254
255             // 記事名が省略されているケース
256             Assert.IsTrue(parser.TryParse("[[/subpage]]", out element));
257             link = (MediaWikiLink)element;
258             Assert.AreEqual("/subpage", link.Title);
259             Assert.IsTrue(link.IsSubpage());
260
261             // 記事名が省略されているケース2
262             Assert.IsTrue(parser.TryParse("[[../../subpage]]", out element));
263             link = (MediaWikiLink)element;
264             Assert.AreEqual("../../subpage", link.Title);
265             Assert.IsTrue(link.IsSubpage());
266         }
267
268         /// <summary>
269         /// <see cref="MediaWikiLinkParser.TryParse"/>メソッドテストケース(ウィキ間リンク)。
270         /// </summary>
271         [Test]
272         public void TestTryParseInterwiki()
273         {
274             IElement element;
275             MediaWikiLink link;
276             MediaWikiLinkParser parser = new MediaWikiLinkParser(this.mediaWikiParsers["en"]);
277
278             // タイトルとセクションとパイプ後の文字列とウィキ間リンクとコロンの全部入り
279             Assert.IsTrue(parser.TryParse("[[:en:testtitle#testsection|testpipe1|testpipe2]]", out element));
280             link = (MediaWikiLink)element;
281             Assert.AreEqual("testtitle", link.Title);
282             Assert.AreEqual("testsection", link.Section);
283             Assert.AreEqual(2, link.PipeTexts.Count);
284             Assert.AreEqual("testpipe1", link.PipeTexts[0].ToString());
285             Assert.AreEqual("testpipe2", link.PipeTexts[1].ToString());
286             Assert.AreEqual("en", link.Interwiki);
287             Assert.IsTrue(link.IsColon);
288
289             // 普通の言語間リンク
290             Assert.IsTrue(parser.TryParse("[[ja:日本語版記事名]]", out element));
291             link = (MediaWikiLink)element;
292             Assert.AreEqual("日本語版記事名", link.Title);
293             Assert.AreEqual("ja", link.Interwiki);
294
295             // ウィキ間リンク
296             Assert.IsTrue(parser.TryParse("[[commons:コモンズ記事名]]", out element));
297             link = (MediaWikiLink)element;
298             Assert.AreEqual("コモンズ記事名", link.Title);
299             Assert.AreEqual("commons", link.Interwiki);
300
301             // ウィキ間リンクの構文だが名前空間と被るためそうならないもの
302             Assert.IsTrue(parser.TryParse("[[wikipedia:ウィキペディア記事名]]", out element));
303             link = (MediaWikiLink)element;
304             Assert.AreEqual("wikipedia:ウィキペディア記事名", link.Title);
305             Assert.IsNull(link.Interwiki);
306
307             // :が含まれるだけの普通の記事(1.10以前のバージョンでは誤判定されていた)
308             Assert.IsTrue(parser.TryParse("[[Marathon 2: Durandal]]", out element));
309             link = (MediaWikiLink)element;
310             Assert.AreEqual("Marathon 2: Durandal", link.Title);
311             Assert.IsNull(link.Interwiki);
312         }
313
314         #endregion
315     }
316 }