[TDD の練習(2)] (すっかり出遅れた) 縦書き祭
わんくま blog での縦書き祭は → このへんから
てことで、 仕様はこんな感じにします。
・ 入力は全角のテキストだとする。 ( そうじゃなかったら、 読み込んだときに変換してね )
・ Console.WriteLine() で出力していくと、 縦書きしてあるように見えること。
・ 無駄な空白 (右端と下端) は、 出力しない。
前回と同様に、 どんなテストコードを書いていけばいいのかを、 文章で書いてみますので、 ユニットテストに書き下してみてください。
- 最初に、 どんな使い方をするものなのか、 考えます。
コードの流れはどんなふうでしょう。 その中で、 今回作るモノはどのように使うでしょう? 分かりにくいときは、 ざっと書いてみます。
ここは回答例を書いておきましょう。 こんな感じでしょうか…
// 読み込んだら、UNICODE 正規化と全角変換して
List<string> 横書きデータ = new List<string>();
foreach (string 一行 in 横書きデータ元) {
string 正規化済み
= 一行.Normalize(
System.Text.NormalizationForm.FormC);
string 全角化済み
= Microsoft.VisualBasic.Strings.StrConv(
正規化済み,
Microsoft.VisualBasic.VbStrConv.Wide,
0x0411);
横書きデータ.Add(全角化済み);
}
// 縦横変換機を呼び出して
IEnumerable<string> 変換後データ
= 縦横変換機.縦書きに直せ(横書きデータ);
// コンソールに書き出させる
foreach (string 横一行分 in 変換後データ) {
Console.WriteLine(横一行分);
}
上で書いたコードで、 まだ無いモノは 縦横変換機 ってヤツです。 こいつを作るためのテストを書いていきます。
- null や空文字のリストを渡すテスト
※ ムダな空白を出力しない、 という仕様から、 このテストケースが導かれます。- (1-1) null → 1行も出力されないこと。
- (1-2) リストの各要素が全て null か空文字 → やはり 1行も出力されないこと。
- 一行だけのリストを渡す
その一行の文字数に等しいだけの、 文字列のリスト ( 配列 ) が返ってくればよいですね。 ただし、 行末の空白は出てはダメです。
- 二行のリストを渡す
- (3-1) 一行目が短い
- (3-2) 二行目のほうが短い
- (3-3) 先頭の空行は出力されない (連続していても)
- (3-4) 空行じゃない行が出現したあとの、 空行は出力される
- (3-5) 空行じゃない行が出現したあとの、 null は空行扱い
…だいたい、 こんなところでしょう。
大きいほうの限界を見ていませんが、 まぁ良しとします。 ( おそらくは、 メモリがパンクするところが限界になるんじゃないかな。 )
回答例 ( C# + NUnit 用のソースコード ) はこちら → DirectionChangerTests.cs [6KB]
ちゃんと自分で書いてみてから、 見てくださいね f(^^;
そして、 このテストコードをパスするように実装とリファクタリングしたコードは、 こうなりました。
C# 2008 ( .NET Framework 3.5 ) なので、 LINQ 式 と yield return を使っています。
public static class 縦横変換機 {
public static IEnumerable<string> 縦書きに直せ(IList<string> 横書き文章) {
if (横書き文章 == null)
yield break;
int 最大長 = 横書き文章.Max(s => (s == null ? 0 : s.Length));
if(最大長 == 0)
yield break;
for (int rowIndex = 0; rowIndex < 最大長; rowIndex++) {
string 横一列分 = 横一列分を取り出せ(横書き文章, rowIndex);
yield return 横一列分.TrimEnd();
}
}
private static string 横一列分を取り出せ(IList<string> 横書き文章, int rowIndex) {
int 行数 = 横書き文章.Count;
StringBuilder sb = new StringBuilder(行数);
for (int arrayIndex = 横書き文章.Count - 1; arrayIndex >= 0; arrayIndex--) {
string 一行 = 横書き文章[arrayIndex];
if (一行 == null) {
sb.Append(' ');
continue;
}
if (一行.Length > rowIndex)
sb.Append(一行[rowIndex]);
else
sb.Append(' ');
}
return sb.ToString();
}
}
上のコードでは、 いっぺん使ってみたかった yield を使ってますが、 使わなきゃいけないってことはありません。 っていうか、 そもそも .NET Framework 2.0 には存在しないですしね。
| 固定リンク
「プログラミング」カテゴリの記事
- 【.NET / Win8.1 ストアアプリ】 HttpClient で TLS 1.1 / 1.2 に対応するには(2018.06.17)
- 【VS2017 15.7pv2】 XAML のランタイム ツールに 「ヒートマップ」 が増えた(2018.03.28)
- 【.NET Core】 プロジェクトを作ると 「project.assets.json が見つかりません」 エラー(2018.02.10)
- 【#UWP】 ビットマップの表示色を変える (Win2D.uwp 経由で Direct2D を使う)(2017.08.23)
- 【#UWP】 CompactOverlay モード: Picture in Picture というか、「最前面に表示」するウィンドウを作る(2017.08.16)
「-プログラミング ( わんくま )」カテゴリの記事
- [わんくま名古屋] 第21回: Metro サンプルコード解説 (1/3)(2012.04.15)
- [わんくま名古屋] 第21回は 4月 14日 - Windows 8 Metro をやるよ~♪(2012.04.12)
- [わんくま東京] 第59回の資料を公開しました(2011.06.02)
- [わんくま東京] 第59回は 5月 28日 - 名古屋から侵略します♪(2011.05.23)
- [わんくま名古屋] 第17回は 4月 9日 - TDD ネタで喋ります(2011.04.03)
この記事へのコメントは終了しました。
コメント