OSDN Git Service

ff21cba7f7b231bd65cd69db39988b78de89a202
[wptscs/wpts.git] / WptscsTest / Logics / MediaWikiTranslatorTest.cs
1 // ================================================================================================
2 // <summary>
3 //      MediaWikiTranslatorのテストクラスソース。</summary>
4 //
5 // <copyright file="MediaWikiTranslatorTest.cs" company="honeplusのメモ帳">
6 //      Copyright (C) 2012 Honeplus. All rights reserved.</copyright>
7 // <author>
8 //      Honeplus</author>
9 // ================================================================================================
10
11 namespace Honememo.Wptscs.Logics
12 {
13     using System;
14     using System.Collections.Generic;
15     using System.IO;
16     using Honememo.Parsers;
17     using Honememo.Utilities;
18     using Honememo.Wptscs.Models;
19     using Honememo.Wptscs.Parsers;
20     using Honememo.Wptscs.Utilities;
21     using Honememo.Wptscs.Websites;
22     using Microsoft.VisualStudio.TestTools.UnitTesting;
23
24     /// <summary>
25     /// <see cref="MediaWikiTranslator"/>のテストクラスです。
26     /// </summary>
27     [TestClass]
28     internal class MediaWikiTranslatorTest
29     {
30         #region 定数
31
32         /// <summary>
33         /// テスト結果が格納されているフォルダパス。
34         /// </summary>
35         private static readonly string ResultDir = Path.Combine(MockFactory.TestMediaWikiDir, "result");
36
37         #endregion
38
39         #region private変数
40
41         /// <summary>
42         /// テスト実施中カルチャを変更し後で戻すため、そのバックアップ。
43         /// </summary>
44         private System.Globalization.CultureInfo backupCulture;
45
46         #endregion
47
48         #region 前処理・後処理
49
50         /// <summary>
51         /// テストの前処理。
52         /// </summary>
53         [TestInitialize]
54         public void SetUp()
55         {
56             // ロガーの処理結果はカルチャーにより変化するため、ja-JPを明示的に設定する
57             this.backupCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
58             System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("ja-JP");
59             System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
60         }
61
62         /// <summary>
63         /// テストの後処理。
64         /// </summary>
65         [TestCleanup]
66         public void TearDown()
67         {
68             // カルチャーを元に戻す
69             System.Threading.Thread.CurrentThread.CurrentUICulture = this.backupCulture;
70             System.Threading.Thread.CurrentThread.CurrentCulture = this.backupCulture;
71         }
72
73         #endregion
74
75         #region 各処理のメソッドテストケース
76
77         /// <summary>
78         /// <see cref="MediaWikiTranslator.ReplaceLink"/>メソッドテストケース。
79         /// </summary>
80         [TestMethod]
81         public void TestReplaceLink()
82         {
83             TestMediaWikiTranslator translator = new TestMediaWikiTranslator();
84             MockFactory mock = new MockFactory();
85             translator.From = mock.GetMediaWiki("ja");
86             translator.To = mock.GetMediaWiki("en");
87             translator.To.LinkInterwikiFormat = null;
88
89             // 見出しの変換パターンを設定
90             translator.HeadingTable = new TranslationTable();
91             IDictionary<string, string[]> dic = new Dictionary<string, string[]>();
92             dic["en"] = new string[] { "External links" };
93             dic["ja"] = new string[] { "外部リンク" };
94             translator.HeadingTable.Add(dic);
95             translator.HeadingTable.From = "ja";
96             translator.HeadingTable.To = "en";
97             MediaWikiPage parent;
98             MediaWikiLink link;
99
100             // 記事名だけの内部リンクで言語間リンクあり、変換先言語へのリンクとなる
101             // ※ 以下オブジェクトを毎回作り直しているのは、更新されてしまうケースがあるため
102             parent = new MediaWikiPage(translator.From, "スペースシップツー");
103             link = new MediaWikiLink();
104             link.Title = "ホワイトナイトツー";
105             Assert.AreEqual("[[Scaled Composites White Knight Two|ホワイトナイトツー]]", translator.ReplaceLink(link, parent).ToString());
106
107             // 見出しあり
108             link = new MediaWikiLink();
109             link.Title = "ホワイトナイトツー";
110             link.Section = "見出し";
111             Assert.AreEqual("[[Scaled Composites White Knight Two#見出し|ホワイトナイトツー#見出し]]", translator.ReplaceLink(link, parent).ToString());
112
113             // 変換パターンに該当する見出しの場合
114             link = new MediaWikiLink();
115             link.Title = "ホワイトナイトツー";
116             link.Section = "外部リンク";
117             Assert.AreEqual("[[Scaled Composites White Knight Two#External links|ホワイトナイトツー#外部リンク]]", translator.ReplaceLink(link, parent).ToString());
118
119             // 表示名あり
120             link = new MediaWikiLink();
121             link.Title = "ホワイトナイトツー";
122             link.Section = "外部リンク";
123             link.PipeTexts.Add(new TextElement("母機"));
124             Assert.AreEqual("[[Scaled Composites White Knight Two#External links|母機]]", translator.ReplaceLink(link, parent).ToString());
125
126             // 記事名だけの内部リンクで言語間リンクなし、変換元言語へのリンクとなる
127             translator.From = mock.GetMediaWiki("en");
128             translator.To = mock.GetMediaWiki("ja");
129             translator.To.LinkInterwikiFormat = null;
130             translator.HeadingTable.From = "en";
131             translator.HeadingTable.To = "ja";
132             parent = new MediaWikiPage(translator.From, "example");
133             link = new MediaWikiLink();
134             link.Title = "Exemplum";
135             Assert.AreEqual("[[:en:Exemplum|Exemplum]]", translator.ReplaceLink(link, parent).ToString());
136
137             // 見出しあり
138             link = new MediaWikiLink();
139             link.Title = "Exemplum";
140             link.Section = "Three examples of exempla";
141             Assert.AreEqual("[[:en:Exemplum#Three examples of exempla|Exemplum#Three examples of exempla]]", translator.ReplaceLink(link, parent).ToString());
142
143             // 変換パターンに該当する見出しの場合
144             link = new MediaWikiLink();
145             link.Title = "Exemplum";
146             link.Section = "External links";
147             Assert.AreEqual("[[:en:Exemplum#外部リンク|Exemplum#External links]]", translator.ReplaceLink(link, parent).ToString());
148
149             // 表示名あり
150             link = new MediaWikiLink();
151             link.Title = "Exemplum";
152             link.Section = "External links";
153             link.PipeTexts.Add(new TextElement("Exemplum_1"));
154             Assert.AreEqual("[[:en:Exemplum#外部リンク|Exemplum_1]]", translator.ReplaceLink(link, parent).ToString());
155
156             // 記事名だけの内部リンクで赤リンク、処理されない
157             link = new MediaWikiLink();
158             link.Title = "Nothing Page";
159             Assert.AreEqual("[[Nothing Page]]", translator.ReplaceLink(link, parent).ToString());
160
161             // 見出しあり
162             link = new MediaWikiLink();
163             link.Title = "Nothing Page";
164             link.Section = "Section A";
165             Assert.AreEqual("[[Nothing Page#Section A]]", translator.ReplaceLink(link, parent).ToString());
166
167             // 変換パターンに該当する見出しの場合
168             link = new MediaWikiLink();
169             link.Title = "Nothing Page";
170             link.Section = "External links";
171             Assert.AreEqual("[[Nothing Page#外部リンク]]", translator.ReplaceLink(link, parent).ToString());
172
173             // 表示名あり
174             link = new MediaWikiLink();
175             link.Title = "Nothing Page";
176             link.PipeTexts.Add(new TextElement("Dummy Link"));
177             Assert.AreEqual("[[Nothing Page|Dummy Link]]", translator.ReplaceLink(link, parent).ToString());
178
179             // [[Apollo&nbsp;17]] のように文字参照が入っていても処理できる
180             link = new MediaWikiLink();
181             link.Title = "Fuji&nbsp;(Spacecraft)";
182             Assert.AreEqual("[[ふじ (宇宙船)|Fuji&nbsp;(Spacecraft)]]", translator.ReplaceLink(link, parent).ToString());
183         }
184
185         /// <summary>
186         /// <see cref="MediaWikiTranslator.ReplaceLink"/>メソッドテストケース(サブページ)。
187         /// </summary>
188         [TestMethod]
189         public void TestReplaceLinkSubpage()
190         {
191             TestMediaWikiTranslator translator = new TestMediaWikiTranslator();
192             MockFactory mock = new MockFactory();
193             translator.From = mock.GetMediaWiki("en");
194             translator.To = mock.GetMediaWiki("ja");
195             MediaWikiPage parent;
196             MediaWikiLink link;
197
198             // 全て指定したサブページ
199             // ※ 以下オブジェクトを毎回作り直しているのは、更新されてしまうケースがあるため
200             parent = new MediaWikiPage(translator.From, "Template:Table cell templates");
201             link = new MediaWikiLink();
202             link.Title = "Template:Table cell templates/doc";
203             Assert.AreEqual("[[Template:Table cell templates|Template:Table cell templates/doc]]", translator.ReplaceLink(link, parent).ToString());
204
205             // サブページ(子)
206             link = new MediaWikiLink();
207             link.Title = "/Doc";
208             Assert.AreEqual("[[Template:Table cell templates|/Doc]]", translator.ReplaceLink(link, parent).ToString());
209
210             // サブページ(親)、処理対象外
211             link = new MediaWikiLink();
212             link.Title = "../";
213             Assert.AreEqual("[[../]]", translator.ReplaceLink(link, parent).ToString());
214
215             // サブページ(兄弟)
216             parent = new MediaWikiPage(translator.From, "Template:Table cell templates/xxx");
217             link = new MediaWikiLink();
218             link.Title = "../Doc";
219             Assert.AreEqual("[[Template:Table cell templates|../Doc]]", translator.ReplaceLink(link, parent).ToString());
220         }
221
222         /// <summary>
223         /// <see cref="MediaWikiTranslator.ReplaceLink"/>メソッドテストケース(カテゴリ)。
224         /// </summary>
225         [TestMethod]
226         public void TestReplaceLinkCategory()
227         {
228             TestMediaWikiTranslator translator = new TestMediaWikiTranslator();
229             MockFactory mock = new MockFactory();
230             translator.From = mock.GetMediaWiki("ja");
231             translator.To = mock.GetMediaWiki("en");
232             MediaWikiPage parent = new MediaWikiPage(translator.From, "スペースシップツー");
233             MediaWikiLink link;
234
235             // 記事名だけの内部リンクで言語間リンクあり、変換先言語でのカテゴリとなる
236             // ※ 以下オブジェクトを毎回作り直しているのは、更新されてしまうケースがあるため
237             link = new MediaWikiLink();
238             link.Title = "Category:宇宙船";
239             Assert.AreEqual("[[Category:Manned spacecraft]]", translator.ReplaceLink(link, parent).ToString());
240
241             // ソートキーあり
242             link = new MediaWikiLink();
243             link.Title = "Category:宇宙船";
244             link.PipeTexts.Add(new TextElement("すへえすしつふつう"));
245             Assert.AreEqual("[[Category:Manned spacecraft|すへえすしつふつう]]", translator.ReplaceLink(link, parent).ToString());
246
247             // 記事名だけの内部リンクで言語間リンクなし、変換元言語へのリンクとなり元のカテゴリはコメントとなる
248             translator.To = mock.GetMediaWiki("it");
249             link = new MediaWikiLink();
250             link.Title = "Category:宇宙船";
251             Assert.AreEqual("[[:ja:Category:宇宙船]]<!-- [[Category:宇宙船]] -->", translator.ReplaceLink(link, parent).ToString());
252
253             // ソートキーあり
254             link = new MediaWikiLink();
255             link.Title = "Category:宇宙船";
256             link.PipeTexts.Add(new TextElement("すへえすしつふつう"));
257             Assert.AreEqual("[[:ja:Category:宇宙船]]<!-- [[Category:宇宙船|すへえすしつふつう]] -->", translator.ReplaceLink(link, parent).ToString());
258
259             // 記事名だけの内部リンクで赤リンク、処理されない
260             link = new MediaWikiLink();
261             link.Title = "Category:xx国の宇宙船";
262             Assert.AreEqual("[[Category:xx国の宇宙船]]", translator.ReplaceLink(link, parent).ToString());
263
264             // ソートキーあり
265             link = new MediaWikiLink();
266             link.Title = "Category:xx国の宇宙船";
267             link.PipeTexts.Add(new TextElement("すへえすしつふつう"));
268             Assert.AreEqual("[[Category:xx国の宇宙船|すへえすしつふつう]]", translator.ReplaceLink(link, parent).ToString());
269         }
270
271         /// <summary>
272         /// <see cref="MediaWikiTranslator.ReplaceLink"/>メソッドテストケース(ファイル)。
273         /// </summary>
274         [TestMethod]
275         public void TestReplaceLinkFile()
276         {
277             TestMediaWikiTranslator translator = new TestMediaWikiTranslator();
278             MockFactory mock = new MockFactory();
279             translator.From = mock.GetMediaWiki("en");
280             translator.To = mock.GetMediaWiki("ja");
281             MediaWikiPage parent;
282             MediaWikiLink link;
283
284             // 画像などのファイルについては、名前空間を他国語に置き換えるだけ
285             // ※ 以下オブジェクトを毎回作り直しているのは、更新されてしまうケースがあるため
286             parent = new MediaWikiPage(translator.From, "Kepler-22b");
287             link = new MediaWikiLink();
288             link.Title = "File:Kepler22b-artwork.jpg";
289             Assert.AreEqual("[[ファイル:Kepler22b-artwork.jpg]]", translator.ReplaceLink(link, parent).ToString());
290
291             // パラメータあり
292             link = new MediaWikiLink();
293             link.Title = "File:Kepler22b-artwork.jpg";
294             link.PipeTexts.Add(new TextElement("thumb"));
295             link.PipeTexts.Add(new TextElement("right"));
296             link.PipeTexts.Add(new TextElement("Artist's conception of Kepler-22b."));
297             Assert.AreEqual("[[ファイル:Kepler22b-artwork.jpg|thumb|right|Artist's conception of Kepler-22b.]]", translator.ReplaceLink(link, parent).ToString());
298
299             // ja→enの場合もちゃんと置き換える(en→jaはFileのままでも使えるが逆は置き換えないと動かない)
300             translator.From = mock.GetMediaWiki("ja");
301             translator.To = mock.GetMediaWiki("en");
302
303             parent = new MediaWikiPage(translator.From, "ケプラー22b");
304             link = new MediaWikiLink();
305             link.Title = "ファイル:Kepler22b-artwork.jpg";
306             Assert.AreEqual("[[File:Kepler22b-artwork.jpg]]", translator.ReplaceLink(link, parent).ToString());
307         }
308
309         /// <summary>
310         /// <see cref="MediaWikiTranslator.ReplaceLink"/>メソッドテストケース(仮リンク)。
311         /// </summary>
312         [TestMethod]
313         public void TestReplaceLinkLinkInterwiki()
314         {
315             TestMediaWikiTranslator translator = new TestMediaWikiTranslator();
316             MockFactory mock = new MockFactory();
317             translator.From = mock.GetMediaWiki("en");
318             translator.To = mock.GetMediaWiki("ja");
319
320             // 見出しの変換パターンを設定
321             translator.HeadingTable = new TranslationTable();
322             IDictionary<string, string[]> dic = new Dictionary<string, string[]>();
323             dic["en"] = new string[] { "External links" };
324             dic["ja"] = new string[] { "外部リンク" };
325             translator.HeadingTable.Add(dic);
326             translator.HeadingTable.From = "en";
327             translator.HeadingTable.To = "ja";
328             MediaWikiPage parent = new MediaWikiPage(translator.From, "example");
329             MediaWikiLink link;
330
331             // 記事名だけの内部リンクで言語間リンクなし、変換元言語へのリンクとなる
332             // ※ 以下オブジェクトを毎回作り直しているのは、更新されてしまうケースがあるため
333             link = new MediaWikiLink();
334             link.Title = "Exemplum";
335             Assert.AreEqual("{{仮リンク|Exemplum|en|Exemplum|label=Exemplum}}", translator.ReplaceLink(link, parent).ToString());
336
337             // 見出しあり
338             link = new MediaWikiLink();
339             link.Title = "Exemplum";
340             link.Section = "Three examples of exempla";
341             Assert.AreEqual("{{仮リンク|Exemplum#Three examples of exempla|en|Exemplum#Three examples of exempla|label=Exemplum#Three examples of exempla}}", translator.ReplaceLink(link, parent).ToString());
342
343             // 変換パターンに該当する見出しの場合
344             link = new MediaWikiLink();
345             link.Title = "Exemplum";
346             link.Section = "External links";
347             Assert.AreEqual("{{仮リンク|Exemplum#外部リンク|en|Exemplum#External links|label=Exemplum#External links}}", translator.ReplaceLink(link, parent).ToString());
348
349             // 表示名あり
350             link = new MediaWikiLink();
351             link.Title = "Exemplum";
352             link.Section = "External links";
353             link.PipeTexts.Add(new TextElement("Exemplum_1"));
354             Assert.AreEqual("{{仮リンク|Exemplum#外部リンク|en|Exemplum#External links|label=Exemplum_1}}", translator.ReplaceLink(link, parent).ToString());
355
356             // 言語間リンクありの場合、仮リンクは使用されない
357             link = new MediaWikiLink();
358             link.Title = "Example.com";
359             Assert.AreEqual("[[Example.com|Example.com]]", translator.ReplaceLink(link, parent).ToString());
360
361             // 記事名だけの内部リンクで赤リンクも、使用されない
362             link = new MediaWikiLink();
363             link.Title = "Nothing Page";
364             Assert.AreEqual("[[Nothing Page]]", translator.ReplaceLink(link, parent).ToString());
365         }
366
367         /// <summary>
368         /// <see cref="MediaWikiTranslator.ReplaceTemplate"/>メソッドテストケース。
369         /// </summary>
370         [TestMethod]
371         public void TestReplaceTemplate()
372         {
373             TestMediaWikiTranslator translator = new TestMediaWikiTranslator();
374             MockFactory mock = new MockFactory();
375             translator.From = mock.GetMediaWiki("en");
376             translator.To = mock.GetMediaWiki("ja");
377             MediaWikiPage parent = new MediaWikiPage(translator.From, "example");
378             MediaWikiTemplate template;
379
380             // テンプレート名だけで言語間リンクあり、変換先言語でのテンプレートとなる
381             // ※ 以下オブジェクトを毎回作り直しているのは、更新されてしまうケースがあるため
382             template = new MediaWikiTemplate("Citation needed");
383             Assert.AreEqual("{{要出典}}", translator.ReplaceTemplate(template, parent).ToString());
384
385             // パラメータあり
386             template = new MediaWikiTemplate("Citation needed");
387             template.PipeTexts.Add(new TextElement("date=January 2012"));
388             Assert.AreEqual("{{要出典|date=January 2012}}", translator.ReplaceTemplate(template, parent).ToString());
389
390             // テンプレート名だけで言語間リンクなし、変換元言語へのリンクとなり元のテンプレートはコメントとなる
391             template = new MediaWikiTemplate("Wiktionary");
392             Assert.AreEqual("[[:en:Template:Wiktionary]]<!-- {{Wiktionary}} -->", translator.ReplaceTemplate(template, parent).ToString());
393
394             // パラメータあり
395             template = new MediaWikiTemplate("Wiktionary");
396             template.PipeTexts.Add(new TextElement("Sample"));
397             Assert.AreEqual("[[:en:Template:Wiktionary]]<!-- {{Wiktionary|Sample}} -->", translator.ReplaceTemplate(template, parent).ToString());
398
399             // テンプレート名だけで赤リンク、処理されない
400             template = new MediaWikiTemplate("Invalid Template");
401             Assert.AreEqual("{{Invalid Template}}", translator.ReplaceTemplate(template, parent).ToString());
402
403             // パラメータあり
404             template = new MediaWikiTemplate("Invalid Template");
405             template.PipeTexts.Add(new TextElement("parameter=1"));
406             Assert.AreEqual("{{Invalid Template|parameter=1}}", translator.ReplaceTemplate(template, parent).ToString());
407
408             // システム定義変数、処理されない
409             template = new MediaWikiTemplate("PAGENAME");
410             Assert.AreEqual("{{PAGENAME}}", translator.ReplaceTemplate(template, parent).ToString());
411         }
412
413         /// <summary>
414         /// <see cref="MediaWikiTranslator.ReplaceTemplate"/>メソッドテストケース(入れ子)。
415         /// </summary>
416         [TestMethod]
417         public void TestReplaceTemplateNested()
418         {
419             TestMediaWikiTranslator translator = new TestMediaWikiTranslator();
420             MockFactory mock = new MockFactory();
421             translator.From = mock.GetMediaWiki("en");
422             translator.To = mock.GetMediaWiki("ja");
423             MediaWikiPage parent = new MediaWikiPage(translator.From, "example");
424             MediaWikiTemplate template;
425             MediaWikiLink link;
426             ListElement list;
427
428             // テンプレート名だけで言語間リンクあり、入れ子も処理される
429             // ※ 以下オブジェクトを毎回作り直しているのは、更新されてしまうケースがあるため
430             template = new MediaWikiTemplate("Citation needed");
431             template.PipeTexts.Add(new TextElement("date=January 2012"));
432             list = new ListElement();
433             list.Add(new TextElement("note=See also "));
434             link = new MediaWikiLink();
435             link.Title = "Fuji (Spacecraft)";
436             list.Add(link);
437             template.PipeTexts.Add(list);
438             Assert.AreEqual("{{要出典|date=January 2012|note=See also [[ふじ (宇宙船)|Fuji (Spacecraft)]]}}", translator.ReplaceTemplate(template, parent).ToString());
439
440             // テンプレート名だけで言語間リンクなし、入れ子は処理されない
441             template = new MediaWikiTemplate("Wiktionary");
442             template.PipeTexts.Add(new TextElement("Sample"));
443             list = new ListElement();
444             list.Add(new TextElement("note=See also "));
445             link = new MediaWikiLink();
446             link.Title = "Fuji (Spacecraft)";
447             list.Add(link);
448             template.PipeTexts.Add(list);
449             Assert.AreEqual("[[:en:Template:Wiktionary]]<!-- {{Wiktionary|Sample|note=See also [[Fuji (Spacecraft)]]}} -->", translator.ReplaceTemplate(template, parent).ToString());
450
451             // テンプレート名だけで赤リンク、入れ子は処理されない
452             template = new MediaWikiTemplate("Invalid Template");
453             template.PipeTexts.Add(new TextElement("parameter=1"));
454             list = new ListElement();
455             list.Add(new TextElement("note=See also "));
456             link = new MediaWikiLink();
457             link.Title = "Fuji (Spacecraft)";
458             list.Add(link);
459             template.PipeTexts.Add(list);
460             Assert.AreEqual("{{Invalid Template|parameter=1|note=See also [[Fuji (Spacecraft)]]}}", translator.ReplaceTemplate(template, parent).ToString());
461         }
462
463         /// <summary>
464         /// <see cref="MediaWikiTranslator.ReplaceHeading"/>メソッドテストケース。
465         /// </summary>
466         [TestMethod]
467         public void TestReplaceHeading()
468         {
469             TestMediaWikiTranslator translator = new TestMediaWikiTranslator();
470             MockFactory mock = new MockFactory();
471             translator.From = mock.GetMediaWiki("en");
472             translator.To = mock.GetMediaWiki("ja");
473
474             // 見出しの変換パターンを設定
475             translator.HeadingTable = new TranslationTable();
476             IDictionary<string, string[]> dic = new Dictionary<string, string[]>();
477             dic["en"] = new string[] { "External links" };
478             dic["ja"] = new string[] { "外部リンク" };
479             translator.HeadingTable.Add(dic);
480             translator.HeadingTable.From = "en";
481             translator.HeadingTable.To = "ja";
482
483             MediaWikiPage parent = new MediaWikiPage(translator.From, "example");
484             MediaWikiHeading heading = new MediaWikiHeading();
485
486             // 対訳表に登録されていない見出し
487             // ※ 以下リストを毎回作り直しているのは、更新されてしまうケースがあるため
488             heading.Level = 2;
489             heading.Add(new TextElement(" invalid section "));
490             Assert.AreEqual("== invalid section ==", translator.ReplaceHeading(heading, parent).ToString());
491
492             // 対訳表に登録されている見出し
493             heading.Clear();
494             heading.Add(new TextElement(" External links "));
495             Assert.AreEqual("==外部リンク==", translator.ReplaceHeading(heading, parent).ToString());
496
497             // 一部が内部リンク等になっている場合、対訳表とは一致しない
498             heading.Clear();
499             heading.Add(new TextElement(" External "));
500             heading.Add(new MediaWikiLink("link"));
501             heading.Add(new TextElement("s "));
502             Assert.AreEqual("== External [[link]]s ==", translator.ReplaceHeading(heading, parent).ToString());
503         }
504
505         /// <summary>
506         /// <see cref="MediaWikiTranslator.ReplaceHeading"/>メソッドテストケース(入れ子)。
507         /// </summary>
508         [TestMethod]
509         public void TestReplaceHeadingNested()
510         {
511             TestMediaWikiTranslator translator = new TestMediaWikiTranslator();
512             MockFactory mock = new MockFactory();
513             translator.From = mock.GetMediaWiki("ja");
514             translator.To = mock.GetMediaWiki("en");
515
516             // 見出しの変換パターンを設定
517             translator.HeadingTable = new TranslationTable();
518             IDictionary<string, string[]> dic = new Dictionary<string, string[]>();
519             translator.HeadingTable.Add(dic);
520             translator.HeadingTable.From = "ja";
521             translator.HeadingTable.To = "en";
522
523             MediaWikiPage parent = new MediaWikiPage(translator.From, "スペースシップツー");
524             MediaWikiHeading heading = new MediaWikiHeading();
525
526             // 対訳表に登録されていない見出しの場合、入れ子も処理される
527             // ※ 以下リストを毎回作り直しているのは、更新されてしまうケースがあるため
528             heading.Level = 3;
529             heading.Add(new TextElement(" "));
530             heading.Add(new MediaWikiLink("宇宙旅行"));
531             heading.Add(new MediaWikiTemplate("ref-en"));
532             heading.Add(new TextElement(" "));
533             Assert.AreEqual("=== [[Space tourism|宇宙旅行]]{{En icon}} ===", translator.ReplaceHeading(heading, parent).ToString());
534
535             // 対訳表に登録されている見出しの場合、入れ子は処理されない
536             dic["ja"] = new string[] { "[[宇宙旅行]]{{ref-en}}" };
537             dic["en"] = new string[] { "[[弾道飛行]]{{ref-en}}" };
538             heading.Clear();
539             heading.Add(new TextElement(" "));
540             heading.Add(new MediaWikiLink("宇宙旅行"));
541             heading.Add(new MediaWikiTemplate("ref-en"));
542             heading.Add(new TextElement(" "));
543             Assert.AreEqual("===[[弾道飛行]]{{ref-en}}===", translator.ReplaceHeading(heading, parent).ToString());
544         }
545
546         /// <summary>
547         /// <see cref="MediaWikiTranslator.CreateOpening"/>メソッドテストケース。
548         /// </summary>
549         [TestMethod]
550         public void TestCreateOpening()
551         {
552             // From, Toの設定に応じて変換後記事の冒頭部を作り出す
553             TestMediaWikiTranslator translator = new TestMediaWikiTranslator();
554             MockFactory mock = new MockFactory();
555             translator.From = mock.GetMediaWiki("en");
556             translator.To = mock.GetMediaWiki("ja");
557
558             // 完全な形
559             Assert.AreEqual(
560                 "'''xxx'''([[英語|英]]: '''{{Lang|en|English's title}}''')\n\n",
561                 translator.CreateOpening("English's title"));
562
563             // リンクなし・略称あり
564             translator.To.HasLanguagePage = false;
565             Assert.AreEqual(
566                 "'''xxx'''(英: '''{{Lang|en|English's title}}''')\n\n",
567                 translator.CreateOpening("English's title"));
568
569             // リンクなし・略称なし
570             Language.LanguageName name = translator.From.Language.Names["ja"];
571             name.ShortName = null;
572             translator.From.Language.Names["ja"] = name;
573             Assert.AreEqual(
574                 "'''xxx'''(英語: '''{{Lang|en|English's title}}''')\n\n",
575                 translator.CreateOpening("English's title"));
576
577             // リンクあり・略称なし
578             translator.To.HasLanguagePage = true;
579             Assert.AreEqual(
580                 "'''xxx'''([[英語]]: '''{{Lang|en|English's title}}''')\n\n",
581                 translator.CreateOpening("English's title"));
582
583             // 言語名なし・リンク有り
584             translator.From.Language.Names.Remove("ja");
585             Assert.AreEqual(
586                 "'''xxx'''('''{{Lang|en|English's title}}''')\n\n",
587                 translator.CreateOpening("English's title"));
588
589             // 言語名なし・リンクなし
590             translator.To.HasLanguagePage = false;
591             Assert.AreEqual(
592                 "'''xxx'''('''{{Lang|en|English's title}}''')\n\n",
593                 translator.CreateOpening("English's title"));
594
595             // 仮リンクフォーマットなし
596             translator.To.LangFormat = null;
597             Assert.AreEqual(
598                 "'''xxx'''('''English's title''')\n\n",
599                 translator.CreateOpening("English's title"));
600
601             // 括弧のフォーマット変更
602             // ※ パラメータ上なしには出来ない
603             translator.To.Language.Bracket = "「$1」";
604             Assert.AreEqual(
605                 "'''xxx'''「'''English's title'''」\n\n",
606                 translator.CreateOpening("English's title"));
607
608             // 括弧のフォーマットの$1なし
609             translator.To.Language.Bracket = "後で消す";
610             Assert.AreEqual(
611                 "'''xxx'''後で消す\n\n",
612                 translator.CreateOpening("English's title"));
613         }
614
615         #endregion
616
617         #region 全体テストケース
618
619         /// <summary>
620         /// テストデータを用い、Runを通しで実行するテストケース。基本動作。
621         /// </summary>
622         [TestMethod]
623         public void TestExampleIgnoreHeading()
624         {
625             MockFactory mock = new MockFactory();
626             MediaWiki from = mock.GetMediaWiki("en");
627             MediaWikiTranslator translator = new MediaWikiTranslator();
628             translator.From = from;
629             translator.To = mock.GetMediaWiki("ja");
630             translator.To.LinkInterwikiFormat = null;
631             translator.HeadingTable = new TranslationTable();
632             translator.HeadingTable.From = "en";
633             translator.HeadingTable.To = "ja";
634             translator.Run("example");
635
636             // テストデータの変換結果を期待される結果と比較する
637             // バージョン表記部分は毎回変化するため、期待される結果のうち該当部分を更新する
638             Assert.AreEqual(
639                 File.ReadAllText(Path.Combine(ResultDir, "example_定型句なし.txt")).Replace("<!-- Wikipedia 翻訳支援ツール Ver0.xx", "<!-- " + FormUtils.ApplicationName()),
640                 translator.Text);
641
642             // テストデータの変換ログを期待されるログと比較する
643             // 1行目のパスが一致しないので、期待される結果のうち該当部分を更新する
644             Assert.AreEqual(
645                 File.ReadAllText(Path.Combine(ResultDir, "example_定型句なし.log")).Replace("file:///xxx/Data/MediaWiki/en/", from.Location),
646                 translator.Log);
647         }
648
649         /// <summary>
650         /// テストデータを用い、Runを通しで実行するテストケース。基本動作見出しの変換含む。
651         /// </summary>
652         /// <remarks>C++/CLI版の0.73までと同等の動作。</remarks>
653         [TestMethod]
654         public void TestExample()
655         {
656             MockFactory mock = new MockFactory();
657             MediaWiki from = mock.GetMediaWiki("en");
658             MediaWikiTranslator translator = new MediaWikiTranslator();
659             translator.From = from;
660             translator.To = mock.GetMediaWiki("ja");
661             translator.To.LinkInterwikiFormat = null;
662             translator.To.LangFormat = null;
663
664             // 見出しの変換パターンを設定
665             translator.HeadingTable = new TranslationTable();
666             IDictionary<string, string[]> dic = new Dictionary<string, string[]>();
667             dic["en"] = new string[] { "See also" };
668             dic["ja"] = new string[] { "関連項目" };
669             translator.HeadingTable.Add(dic);
670             translator.HeadingTable.From = "en";
671             translator.HeadingTable.To = "ja";
672             translator.Run("example");
673
674             // テストデータの変換結果を期待される結果と比較する
675             // バージョン表記部分は毎回変化するため、期待される結果のうち該当部分を更新する
676             Assert.AreEqual(
677                 File.ReadAllText(Path.Combine(ResultDir, "example.txt")).Replace("<!-- Wikipedia 翻訳支援ツール Ver0.73", "<!-- " + FormUtils.ApplicationName()),
678                 translator.Text);
679
680             // テストデータの変換ログを期待されるログと比較する
681             // 1行目のパスが一致しないので、期待される結果のうち該当部分を更新する
682             Assert.AreEqual(
683                 File.ReadAllText(Path.Combine(ResultDir, "example.log")).Replace("http://en.wikipedia.org", from.Location),
684                 translator.Log);
685         }
686
687         /// <summary>
688         /// テストデータを用い、Runを通しで実行するテストケース。キャッシュ使用。
689         /// </summary>
690         [TestMethod]
691         public void TestExampleWithCache()
692         {
693             MockFactory mock = new MockFactory();
694             MediaWiki from = mock.GetMediaWiki("en");
695             MediaWikiTranslator translator = new MediaWikiTranslator();
696             translator.From = from;
697             translator.To = mock.GetMediaWiki("ja");
698             translator.To.LinkInterwikiFormat = null;
699
700             // 見出しの変換パターンを設定
701             translator.HeadingTable = new TranslationTable();
702             IDictionary<string, string[]> dic = new Dictionary<string, string[]>();
703             dic["en"] = new string[] { "See also" };
704             dic["ja"] = new string[] { "関連項目" };
705             translator.HeadingTable.Add(dic);
706             translator.HeadingTable.From = "en";
707             translator.HeadingTable.To = "ja";
708
709             // 以下のキャッシュパターンを指定して実行
710             TranslationDictionary table = new TranslationDictionary("en", "ja");
711             table.Add("Template:Wiktionary", new TranslationDictionary.Item { Word = "Template:Wiktionary" });
712             table.Add("example.org", new TranslationDictionary.Item());
713             table.Add(".example", new TranslationDictionary.Item { Word = "。さんぷる", Alias = ".dummy" });
714             table.Add("Template:Disambig", new TranslationDictionary.Item { Word = "Template:曖昧さ回避" });
715             translator.ItemTable = table;
716             translator.Run("example");
717
718             // キャッシュに今回の処理で取得した内容が更新されているかを確認
719             Assert.IsTrue(table.ContainsKey("example.com"));
720             Assert.AreEqual("Example.com", table["example.com"].Word);
721             Assert.IsNull(table["example.com"].Alias);
722             Assert.IsNotNull(table["example.com"].Timestamp);
723             Assert.IsTrue(table.ContainsKey("Exemplum"));
724             Assert.AreEqual(string.Empty, table["Exemplum"].Word);
725             Assert.IsNull(table["Exemplum"].Alias);
726             Assert.IsNotNull(table["Exemplum"].Timestamp);
727             Assert.IsTrue(table.ContainsKey("example.net"));
728             Assert.AreEqual("Example.com", table["example.net"].Word);
729             Assert.AreEqual("Example.com", table["example.net"].Alias);
730             Assert.IsNotNull(table["example.net"].Timestamp);
731
732             // テストデータの変換結果を期待される結果と比較する
733             // バージョン表記部分は毎回変化するため、期待される結果のうち該当部分を更新する
734             Assert.AreEqual(
735                 File.ReadAllText(Path.Combine(ResultDir, "example_キャッシュ使用.txt")).Replace("<!-- Wikipedia 翻訳支援ツール Ver0.xx", "<!-- " + FormUtils.ApplicationName()),
736                 translator.Text);
737
738             // テストデータの変換ログを期待されるログと比較する
739             // 1行目のパスが一致しないので、期待される結果のうち該当部分を更新する
740             Assert.AreEqual(
741                 File.ReadAllText(Path.Combine(ResultDir, "example_キャッシュ使用.log")).Replace("file:///xxx/Data/MediaWiki/en/", from.Location),
742                 translator.Log);
743         }
744
745         /// <summary>
746         /// テストデータを用い、Runを通しで実行するテストケース。基本動作見出しの変換、{{仮リンク}}への置き換え含む。
747         /// </summary>
748         [TestMethod]
749         public void TestExampleWithLinkInterwiki()
750         {
751             MockFactory mock = new MockFactory();
752             MediaWiki from = mock.GetMediaWiki("en");
753             MediaWikiTranslator translator = new MediaWikiTranslator();
754             translator.From = from;
755             translator.To = mock.GetMediaWiki("ja");
756
757             // 見出しの変換パターンを設定
758             translator.HeadingTable = new TranslationTable();
759             IDictionary<string, string[]> dic = new Dictionary<string, string[]>();
760             dic["en"] = new string[] { "See also" };
761             dic["ja"] = new string[] { "関連項目" };
762             translator.HeadingTable.Add(dic);
763             translator.HeadingTable.From = "en";
764             translator.HeadingTable.To = "ja";
765             translator.Run("example");
766
767             // テストデータの変換結果を期待される結果と比較する
768             // バージョン表記部分は毎回変化するため、期待される結果のうち該当部分を更新する
769             Assert.AreEqual(
770                 File.ReadAllText(Path.Combine(ResultDir, "example_仮リンク有効.txt")).Replace("<!-- Wikipedia 翻訳支援ツール Ver0.73", "<!-- " + FormUtils.ApplicationName()),
771                 translator.Text);
772
773             // テストデータの変換ログを期待されるログと比較する
774             // 1行目のパスが一致しないので、期待される結果のうち該当部分を更新する
775             Assert.AreEqual(
776                 File.ReadAllText(Path.Combine(ResultDir, "example.log")).Replace("http://en.wikipedia.org", from.Location),
777                 translator.Log);
778         }
779
780         /// <summary>
781         /// テストデータを用い、Runを通しで実行するテストケース(日本語版→英語版)。
782         /// </summary>
783         /// <remarks>C++/CLI版の0.73までと同等の動作。</remarks>
784         [TestMethod]
785         public void TestSpaceShipTwo()
786         {
787             MockFactory mock = new MockFactory();
788             MediaWiki from = mock.GetMediaWiki("ja");
789             MediaWikiTranslator translator = new MediaWikiTranslator();
790             translator.From = from;
791             translator.To = mock.GetMediaWiki("en");
792             translator.To.LinkInterwikiFormat = null;
793             translator.ItemTable = new TranslationDictionary("ja", "en");
794             translator.IsContinueAtInterwikiExisted = (string interwiki) => true;
795
796             // 見出しの変換パターンを設定
797             translator.HeadingTable = new TranslationTable();
798             IDictionary<string, string[]> dic = new Dictionary<string, string[]>();
799             dic["en"] = new string[] { "See Also" };
800             dic["ja"] = new string[] { "関連項目" };
801             translator.HeadingTable.Add(dic);
802             dic = new Dictionary<string, string[]>();
803             dic["en"] = new string[] { "External links" };
804             dic["ja"] = new string[] { "外部リンク" };
805             translator.HeadingTable.Add(dic);
806             dic = new Dictionary<string, string[]>();
807             dic["en"] = new string[] { "Notes" };
808             dic["ja"] = new string[] { "脚注" };
809             translator.HeadingTable.Add(dic);
810             translator.HeadingTable.From = "ja";
811             translator.HeadingTable.To = "en";
812             translator.Run("スペースシップツー");
813
814             // テストデータの変換結果を期待される結果と比較する
815             // バージョン表記部分は毎回変化するため、期待される結果のうち該当部分を更新する
816             Assert.AreEqual(
817                 File.ReadAllText(Path.Combine(ResultDir, "スペースシップツー.txt")).Replace("<!-- Wikipedia 翻訳支援ツール Ver0.73", "<!-- " + FormUtils.ApplicationName()),
818                 translator.Text);
819
820             // テストデータの変換ログを期待されるログと比較する
821             // 1行目のパスが一致しないので、期待される結果のうち該当部分を更新する
822             Assert.AreEqual(
823                 File.ReadAllText(Path.Combine(ResultDir, "スペースシップツー.log")).Replace("http://ja.wikipedia.org", from.Location),
824                 translator.Log);
825         }
826
827         /// <summary>
828         /// Runを通しで実行するテストケース(対象記事なし)。
829         /// </summary>
830         [TestMethod]
831         public void TestPageNothing()
832         {
833             MockFactory mock = new MockFactory();
834             MediaWiki from = mock.GetMediaWiki("en");
835             Translator translator = new MediaWikiTranslator();
836             translator.From = from;
837             translator.To = mock.GetMediaWiki("ja");
838
839             try
840             {
841                 translator.Run("Nothing Page");
842                 Assert.Fail();
843             }
844             catch (ApplicationException)
845             {
846                 // 実行ログを期待されるログと比較する
847                 Assert.AreEqual(
848                     ("http://en.wikipedia.org より [[Nothing Page]] を取得。\r\n"
849                     + "→ 翻訳元として指定された記事は存在しません。記事名を確認してください。\r\n")
850                     .Replace("http://en.wikipedia.org", from.Location),
851                     translator.Log);
852             }
853         }
854
855         /// <summary>
856         /// Runを通しで実行するテストケース(対象記事がリダイレクトで無し)。
857         /// </summary>
858         [TestMethod]
859         public void TestPageRedirectNothing()
860         {
861             MockFactory mock = new MockFactory();
862             MediaWiki from = mock.GetMediaWiki("en");
863             Translator translator = new MediaWikiTranslator();
864             translator.From = from;
865             translator.To = mock.GetMediaWiki("ja");
866
867             try
868             {
869                 translator.Run("Redirect→Nothing Page");
870                 Assert.Fail();
871             }
872             catch (ApplicationException)
873             {
874                 // 実行ログを期待されるログと比較する
875                 Assert.AreEqual(
876                     ("http://en.wikipedia.org より [[Redirect→Nothing Page]] を取得。\r\n"
877                     + "→ リダイレクト [[Nothing Page]]\r\n"
878                     + "→ 翻訳元として指定された記事は存在しません。記事名を確認してください。\r\n")
879                     .Replace("http://en.wikipedia.org", from.Location),
880                     translator.Log);
881             }
882         }
883         #endregion
884
885         #region テスト用クラス
886
887         /// <summary>
888         /// <see cref="MediaWikiTranslator"/>テスト用のクラスです。
889         /// </summary>
890         private class TestMediaWikiTranslator : MediaWikiTranslator
891         {
892             #region 非公開メソッドテスト用のオーラーライドメソッド
893
894             /// <summary>
895             /// 内部リンクを解析し、変換先言語の記事へのリンクに変換する。
896             /// </summary>
897             /// <param name="link">変換元リンク。</param>
898             /// <param name="parent">ページ要素を取得した変換元記事。</param>
899             /// <returns>変換済みリンク。</returns>
900             public new IElement ReplaceLink(MediaWikiLink link, MediaWikiPage parent)
901             {
902                 return base.ReplaceLink(link, parent);
903             }
904
905             /// <summary>
906             /// テンプレートを解析し、変換先言語の記事へのテンプレートに変換する。
907             /// </summary>
908             /// <param name="template">変換元テンプレート。</param>
909             /// <param name="parent">ページ要素を取得した変換元記事。</param>
910             /// <returns>変換済みテンプレート。</returns>
911             public new IElement ReplaceTemplate(MediaWikiTemplate template, MediaWikiPage parent)
912             {
913                 return base.ReplaceTemplate(template, parent);
914             }
915
916             /// <summary>
917             /// 指定された見出しに対して、対訳表による変換を行う。
918             /// </summary>
919             /// <param name="heading">見出し。</param>
920             /// <param name="parent">ページ要素を取得した変換元記事。</param>
921             /// <returns>変換後の見出し。</returns>
922             public new IElement ReplaceHeading(MediaWikiHeading heading, MediaWikiPage parent)
923             {
924                 return base.ReplaceHeading(heading, parent);
925             }
926
927             /// <summary>
928             /// 変換後記事冒頭用の「'''日本語記事名'''([[英語|英]]: '''{{Lang|en|英語記事名}}''')」みたいなのを作成する。
929             /// </summary>
930             /// <param name="title">翻訳支援対象の記事名。</param>
931             /// <returns>冒頭部のテキスト。</returns>
932             public new string CreateOpening(string title)
933             {
934                 return base.CreateOpening(title);
935             }
936
937             #endregion
938         }
939
940         #endregion
941     }
942 }