Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 15364] ファイルの概要

このコミットは、Go言語の標準ライブラリsrc/pkg/testingパッケージにおける出力フォーマットの不具合を修正するものです。具体的には、テスト結果のログ出力において、特に複数行にわたるメッセージのインデントが意図した通りに行われない問題を解決しています。

コミット

commit 782cbb4f90dc873eced4248e100e69a6502d7aee
Author: Robert Dinu <r@oktett.se>
Date:   Thu Feb 21 14:17:43 2013 -0800

    testing: fix output formatting
    
    Revision 5e7fd762f356 has changed the output formatting in a way that
    is no longer in line with the format described by the revision
    ff0ade0b937b which has introduced this functionality.
    When decorating the first line, instead of indenting the whole line,
    the current implementation adds indentation right after the "decorate"
    part and  before the "log" message.
    The fix addresses this issue.
    
    R=golang-dev, iant, minux.ma, r, rsc, remyoudompheng
    CC=golang-dev
    https://golang.org/cl/7304094

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/782cbb4f90dc873eced4248e100e69a6502d7aee

元コミット内容

このコミットは、testingパッケージの出力フォーマットに関するバグ修正です。以前のコミット5e7fd762f356が、ff0ade0b937bで導入された機能の出力フォーマットと整合性が取れていない状態を引き起こしていました。具体的には、最初の行を装飾(decorate)する際に、行全体をインデントするのではなく、「decorate」部分の直後、かつ「log」メッセージの前にインデントが追加されてしまう問題がありました。この修正はこの問題を解決します。

変更の背景

Go言語のtestingパッケージは、テストの実行と結果の報告を担当します。テストが失敗したり、t.Logt.Errorなどのメソッドが呼び出されたりすると、そのメッセージは特定のフォーマットで出力されます。このフォーマットは、テストの実行状況を開発者が視覚的に理解しやすくするために重要です。

このコミットの背景には、過去の2つのリビジョンが関係しています。

  1. ff0ade0b937b: このリビジョンで、testingパッケージのログ出力に特定の装飾(decoration)とインデント機能が導入されました。これは、テストの出力を見やすくするための改善でした。
  2. 5e7fd762f356: このリビジョンで、出力フォーマットに関する変更が加えられましたが、その変更がff0ade0b937bで確立されたインデントルールと矛盾する結果となりました。具体的には、複数行にわたるログメッセージの最初の行のインデントが正しく適用されず、行全体ではなくメッセージの一部にのみインデントが適用されるという問題が発生しました。

この不整合により、テスト出力の可読性が損なわれ、開発者がテスト結果を正確に把握することが困難になる可能性がありました。本コミットは、このフォーマットの不整合を解消し、意図されたインデントルールを復元することを目的としています。

前提知識の解説

  • Go言語のtestingパッケージ: Go言語に組み込まれているテストフレームワークです。go testコマンドによって実行され、ユニットテスト、ベンチマークテスト、例(Example)テストなどを記述・実行するために使用されます。*testing.T型はテスト関数に渡され、テストの失敗報告、ログ出力、ヘルパー関数の呼び出しなど、テスト実行中の様々な操作を提供します。
  • t.Log / t.Error: *testing.T型が提供するメソッドで、テスト中にメッセージをログ出力するために使用されます。t.Errorはログ出力に加えてテストを失敗としてマークします。これらのメソッドに渡される文字列は、複数行にわたる場合があり、その際のインデントがこのコミットの焦点となっています。
  • 出力フォーマットとインデント: テストの出力は、どのテストが実行され、どの行で問題が発生したかを示すために、ファイル名、行番号、そしてログメッセージが特定の形式で表示されます。複数行のメッセージの場合、後続の行が適切にインデントされることで、どのメッセージがどのテストに関連しているかが明確になります。
  • bytes.Buffer: Go言語の標準ライブラリbytesパッケージに含まれる型で、可変長のバイトシーケンスを扱うためのバッファを提供します。文字列の構築や、I/O操作の効率化によく用いられます。このコミットでは、出力文字列を構築するために使用されています。
  • strings.Split: Go言語の標準ライブラリstringsパッケージに含まれる関数で、指定された区切り文字で文字列を分割し、文字列のスライスを返します。ここでは、ログメッセージを改行文字で分割し、各行を個別に処理するために使用されています。
  • fmt.Fprintf: Go言語の標準ライブラリfmtパッケージに含まれる関数で、フォーマットされた文字列を指定されたio.Writerに書き込みます。ここではbytes.Bufferに書き込んでいます。

技術的詳細

このコミットの修正は、src/pkg/testing/testing.goファイル内のdecorate関数に集中しています。この関数は、テストのログメッセージにファイル名、行番号、および適切なインデントを追加して整形する役割を担っています。

修正前のコードでは、decorate関数は以下のようなロジックでインデントを処理していました。

  1. ファイル名と行番号をbufに書き込む。
  2. メッセージを改行で分割し、各行をループ処理する。
  3. 最初の行(i == 0)の場合、インデントは追加されない。
  4. 2行目以降(i > 0)の場合、まず改行文字\nを書き込み、その後、1つのタブ\tを追加してインデントする。さらに、2行目以降は追加のタブ\tを書き込むことで、合計2つのタブでインデントされる。

このロジックの問題点は、最初の行のインデントが不足していることでした。コミットメッセージにあるように、「decorate」部分の直後、かつ「log」メッセージの前にインデントが追加されるべきところが、実際には行全体がインデントされていませんでした。

修正後のコードでは、この問題に対処するために以下の変更が加えられました。

  1. 最初の行のインデントの追加: fmt.Fprintfでファイル名と行番号を書き込む直前に、buf.WriteByte('\t')が追加されました。これにより、すべての行(最初の行を含む)が少なくとも1つのタブでインデントされるようになります。これは、コメント// Every line is indented at least one tab.によって意図が明確にされています。
  2. 改行とインデントのロジックの変更: 以前のコードでは、ループ内でif i > 0の条件分岐を使って改行とインデントを追加していましたが、これが簡略化されました。
    • if i > 0のブロック内で、buf.WriteByte('\n')buf.WriteByte('\t')(最初のタブ)が削除され、代わりにbuf.WriteString("\n\t\t")が追加されました。
    • これにより、2行目以降の行は、まず改行され、その後2つのタブ\t\tでインデントされるようになります。これは、最初の行にすでに1つのタブが追加されているため、2行目以降は合計で3つのタブ(最初の1つ + 追加の2つ)でインデントされることを意味します。

この変更により、すべてのログ行が適切にインデントされ、特に複数行にわたるメッセージの可読性が向上しました。

コアとなるコードの変更箇所

src/pkg/testing/testing.goファイルのdecorate関数内の変更です。

--- a/src/pkg/testing/testing.go
+++ b/src/pkg/testing/testing.go
@@ -166,21 +166,17 @@ func decorate(s string) string {
 	\tline = 1
 	}
 	buf := new(bytes.Buffer)
+\t// Every line is indented at least one tab.
+\tbuf.WriteByte('\t')
 	fmt.Fprintf(buf, "%s:%d: ", file, line)
-\n \tlines := strings.Split(s, "\n")
 \tif l := len(lines); l > 1 && lines[l-1] == "" {
 \t\tlines = lines[:l-1]
 \t}
 \tfor i, line := range lines {
-\t\tif i > 0 {\
-\t\t\tbuf.WriteByte('\n')
-\t\t}\
-\t\t// Every line is indented at least one tab.\
-\t\tbuf.WriteByte('\t')
 \t\tif i > 0 {\
 \t\t\t// Second and subsequent lines are indented an extra tab.\
-\t\t\tbuf.WriteByte('\t')
+\t\t\tbuf.WriteString("\n\t\t")
 \t\t}
 \t\tbuf.WriteString(line)
 \t}

コアとなるコードの解説

変更されたdecorate関数は、テストのログメッセージを整形し、ファイル名、行番号、そして適切なインデントを追加してstringとして返す役割を担っています。

  1. buf := new(bytes.Buffer): bytes.Bufferの新しいインスタンスを作成し、整形された文字列を構築するためのバッファとして使用します。
  2. buf.WriteByte('\t'): 追加された行。ここで、すべてのログメッセージの最初の行に、ファイル名と行番号の前に1つのタブ文字\tが書き込まれます。これにより、メッセージ全体が左端からインデントされるようになります。
  3. fmt.Fprintf(buf, "%s:%d: ", file, line): ファイル名と行番号をbufに書き込みます。例えば、my_test.go:42: のような形式になります。
  4. lines := strings.Split(s, "\n"): 入力されたログメッセージsを改行文字\nで分割し、各行を文字列のスライスlinesに格納します。
  5. if l := len(lines); l > 1 && lines[l-1] == "" { lines = lines[:l-1] }: ログメッセージが空行で終わる場合(例えば、"hello\nworld\n"のように最後の改行の後に空文字列がある場合)、その空行を削除します。これは、余分な空行が出力されないようにするための一般的な処理です。
  6. for i, line := range lines: 分割された各行をループ処理します。
  7. if i > 0 { buf.WriteString("\n\t\t") }: 変更された行
    • i > 0の条件は、現在の行が最初の行ではない(つまり、2行目以降である)ことを意味します。
    • 以前はここで\n\tを個別に書き込んでいましたが、buf.WriteString("\n\t\t")に変更されました。
    • これにより、2行目以降の各行は、まず改行され(\n)、その後2つのタブ文字(\t\t)でインデントされます。
    • 最初の行にはすでに1つのタブが追加されているため、2行目以降の行は合計で3つのタブ(最初の1つ + 追加の2つ)でインデントされることになり、視覚的に階層化された出力が実現されます。
  8. buf.WriteString(line): 現在の行のテキストをbufに書き込みます。
  9. return buf.String(): 最終的に、整形されたすべての内容を含むbufの文字列を返します。

この修正により、複数行にわたるテストログメッセージが、最初の行から適切にインデントされ、後続の行もさらに深くインデントされることで、テスト出力の可読性が大幅に向上しました。

関連リンク

参考にした情報源リンク

  • Go言語の公式リポジトリ: https://github.com/golang/go
  • Go CL (Change List) 7304094: https://golang.org/cl/7304094 (これはコミットメッセージに記載されているリンクであり、このコミットのレビューページに相当します。)
  • Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
  • Go言語のテストに関するブログ記事やチュートリアル (一般的な情報源)
  • Go言語のソースコード (特にsrc/pkg/testing/testing.goファイル)
  • Go言語のtestingパッケージの歴史に関する情報 (もしあれば、5e7fd762f356ff0ade0b937bのような特定のコミットに関する詳細)

[インデックス 15364] ファイルの概要

このコミットは、Go言語の標準ライブラリsrc/pkg/testingパッケージにおける出力フォーマットの不具合を修正するものです。具体的には、テスト結果のログ出力において、特に複数行にわたるメッセージのインデントが意図した通りに行われない問題を解決しています。

コミット

commit 782cbb4f90dc873eced4248e100e69a6502d7aee
Author: Robert Dinu <r@oktett.se>
Date:   Thu Feb 21 14:17:43 2013 -0800

    testing: fix output formatting
    
    Revision 5e7fd762f356 has changed the output formatting in a way that
    is no longer in line with the format described by the revision
    ff0ade0b937b which has introduced this functionality.
    When decorating the first line, instead of indenting the whole line,
    the current implementation adds indentation right after the "decorate"
    part and  before the "log" message.
    The fix addresses this issue.
    
    R=golang-dev, iant, minux.ma, r, rsc, remyoudompheng
    CC=golang-dev
    https://golang.org/cl/7304094

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/782cbb4f90dc873eced4248e100e69a6502d7aee

元コミット内容

このコミットは、testingパッケージの出力フォーマットに関するバグ修正です。以前のコミット5e7fd762f356が、ff0ade0b937bで導入された機能の出力フォーマットと整合性が取れていない状態を引き起こしていました。具体的には、最初の行を装飾(decorate)する際に、行全体をインデントするのではなく、「decorate」部分の直後、かつ「log」メッセージの前にインデントが追加されてしまう問題がありました。この修正はこの問題を解決します。

変更の背景

Go言語のtestingパッケージは、テストの実行と結果の報告を担当します。テストが失敗したり、t.Logt.Errorなどのメソッドが呼び出されたりすると、そのメッセージは特定のフォーマットで出力されます。このフォーマットは、テストの実行状況を開発者が視覚的に理解しやすくするために重要です。

このコミットの背景には、過去の2つのリビジョンが関係しています。

  1. ff0ade0b937b: このリビジョンで、testingパッケージのログ出力に特定の装飾(decoration)とインデント機能が導入されました。これは、テストの出力を見やすくするための改善でした。
  2. 5e7fd762f356: このリビジョンで、出力フォーマットに関する変更が加えられましたが、その変更がff0ade0b937bで確立されたインデントルールと矛盾する結果となりました。具体的には、複数行にわたるログメッセージの最初の行のインデントが正しく適用されず、行全体ではなくメッセージの一部にのみインデントが適用されるという問題が発生しました。

この不整合により、テスト出力の可読性が損なわれ、開発者がテスト結果を正確に把握することが困難になる可能性がありました。本コミットは、このフォーマットの不整合を解消し、意図されたインデントルールを復元することを目的としています。

前提知識の解説

  • Go言語のtestingパッケージ: Go言語に組み込まれているテストフレームワークです。go testコマンドによって実行され、ユニットテスト、ベンチマークテスト、例(Example)テストなどを記述・実行するために使用されます。*testing.T型はテスト関数に渡され、テストの失敗報告、ログ出力、ヘルパー関数の呼び出しなど、テスト実行中の様々な操作を提供します。
  • t.Log / t.Error: *testing.T型が提供するメソッドで、テスト中にメッセージをログ出力するために使用されます。t.Errorはログ出力に加えてテストを失敗としてマークします。これらのメソッドに渡される文字列は、複数行にわたる場合があり、その際のインデントがこのコミットの焦点となっています。
  • 出力フォーマットとインデント: テストの出力は、どのテストが実行され、どの行で問題が発生したかを示すために、ファイル名、行番号、そしてログメッセージが特定の形式で表示されます。複数行のメッセージの場合、後続の行が適切にインデントされることで、どのメッセージがどのテストに関連しているかが明確になります。
  • bytes.Buffer: Go言語の標準ライブラリbytesパッケージに含まれる型で、可変長のバイトシーケンスを扱うためのバッファを提供します。文字列の構築や、I/O操作の効率化によく用いられます。このコミットでは、出力文字列を構築するために使用されています。
  • strings.Split: Go言語の標準ライブラリstringsパッケージに含まれる関数で、指定された区切り文字で文字列を分割し、文字列のスライスを返します。ここでは、ログメッセージを改行文字で分割し、各行を個別に処理するために使用されています。
  • fmt.Fprintf: Go言語の標準ライブラリfmtパッケージに含まれる関数で、フォーマットされた文字列を指定されたio.Writerに書き込みます。ここではbytes.Bufferに書き込んでいます。

技術的詳細

このコミットの修正は、src/pkg/testing/testing.goファイル内のdecorate関数に集中しています。この関数は、テストのログメッセージにファイル名、行番号、および適切なインデントを追加して整形する役割を担っています。

修正前のコードでは、decorate関数は以下のようなロジックでインデントを処理していました。

  1. ファイル名と行番号をbufに書き込む。
  2. メッセージを改行で分割し、各行をループ処理する。
  3. 最初の行(i == 0)の場合、インデントは追加されない。
  4. 2行目以降(i > 0)の場合、まず改行文字\nを書き込み、その後、1つのタブ\tを追加してインデントする。さらに、2行目以降は追加のタブ\tを書き込むことで、合計2つのタブでインデントされる。

このロジックの問題点は、最初の行のインデントが不足していることでした。コミットメッセージにあるように、「decorate」部分の直後、かつ「log」メッセージの前にインデントが追加されるべきところが、実際には行全体がインデントされていませんでした。

修正後のコードでは、この問題に対処するために以下の変更が加えられました。

  1. 最初の行のインデントの追加: fmt.Fprintfでファイル名と行番号を書き込む直前に、buf.WriteByte('\t')が追加されました。これにより、すべての行(最初の行を含む)が少なくとも1つのタブでインデントされるようになります。これは、コメント// Every line is indented at least one tab.によって意図が明確にされています。
  2. 改行とインデントのロジックの変更: 以前のコードでは、ループ内でif i > 0の条件分岐を使って改行とインデントを追加していましたが、これが簡略化されました。
    • if i > 0のブロック内で、buf.WriteByte('\n')buf.WriteByte('\t')(最初のタブ)が削除され、代わりにbuf.WriteString("\n\t\t")が追加されました。
    • これにより、2行目以降の行は、まず改行され、その後2つのタブ\t\tでインデントされるようになります。これは、最初の行にすでに1つのタブが追加されているため、2行目以降は合計で3つのタブ(最初の1つ + 追加の2つ)でインデントされることを意味します。

この変更により、すべてのログ行が適切にインデントされ、特に複数行にわたるメッセージの可読性が向上しました。

コアとなるコードの変更箇所

src/pkg/testing/testing.goファイルのdecorate関数内の変更です。

--- a/src/pkg/testing/testing.go
+++ b/src/pkg/testing/testing.go
@@ -166,21 +166,17 @@ func decorate(s string) string {
 	\tline = 1
 	}
 	buf := new(bytes.Buffer)
+\t// Every line is indented at least one tab.
+\tbuf.WriteByte('\t')
 	fmt.Fprintf(buf, "%s:%d: ", file, line)
-\n \tlines := strings.Split(s, "\n")
 \tif l := len(lines); l > 1 && lines[l-1] == "" {
 \t\tlines = lines[:l-1]
 \t}
 \tfor i, line := range lines {
-\t\tif i > 0 {\
-\t\t\tbuf.WriteByte('\n')
-\t\t}\
-\t\t// Every line is indented at least one tab.\
-\t\tbuf.WriteByte('\t')
 \t\tif i > 0 {\
 \t\t\t// Second and subsequent lines are indented an extra tab.\
-\t\t\tbuf.WriteByte('\t')
+\t\t\tbuf.WriteString("\n\t\t")
 \t\t}
 \t\tbuf.WriteString(line)
 \t}

コアとなるコードの解説

変更されたdecorate関数は、テストのログメッセージを整形し、ファイル名、行番号、そして適切なインデントを追加してstringとして返す役割を担っています。

  1. buf := new(bytes.Buffer): bytes.Bufferの新しいインスタンスを作成し、整形された文字列を構築するためのバッファとして使用します。
  2. buf.WriteByte('\t'): 追加された行。ここで、すべてのログメッセージの最初の行に、ファイル名と行番号の前に1つのタブ文字\tが書き込まれます。これにより、メッセージ全体が左端からインデントされるようになります。
  3. fmt.Fprintf(buf, "%s:%d: ", file, line): ファイル名と行番号をbufに書き込みます。例えば、my_test.go:42: のような形式になります。
  4. lines := strings.Split(s, "\n"): 入力されたログメッセージsを改行文字\nで分割し、各行を文字列のスライスlinesに格納します。
  5. if l := len(lines); l > 1 && lines[l-1] == "" { lines = lines[:l-1] }: ログメッセージが空行で終わる場合(例えば、"hello\nworld\n"のように最後の改行の後に空文字列がある場合)、その空行を削除します。これは、余分な空行が出力されないようにするための一般的な処理です。
  6. for i, line := range lines: 分割された各行をループ処理します。
  7. if i > 0 { buf.WriteString("\n\t\t") }: 変更された行
    • i > 0の条件は、現在の行が最初の行ではない(つまり、2行目以降である)ことを意味します。
    • 以前はここで\n\tを個別に書き込んでいましたが、buf.WriteString("\n\t\t")に変更されました。
    • これにより、2行目以降の各行は、まず改行され(\n)、その後2つのタブ文字(\t\t)でインデントされます。
    • 最初の行にはすでに1つのタブが追加されているため、2行目以降の行は合計で3つのタブ(最初の1つ + 追加の2つ)でインデントされることになり、視覚的に階層化された出力が実現されます。
  8. buf.WriteString(line): 現在の行のテキストをbufに書き込みます。
  9. return buf.String(): 最終的に、整形されたすべての内容を含むbufの文字列を返します。

この修正により、複数行にわたるテストログメッセージが、最初の行から適切にインデントされ、後続の行もさらに深くインデントされることで、テスト出力の可読性が大幅に向上しました。

関連リンク

参考にした情報源リンク

  • Go言語の公式リポジトリ: https://github.com/golang/go
  • Go CL (Change List) 7304094: https://golang.org/cl/7304094 (これはコミットメッセージに記載されているリンクであり、このコミットのレビューページに相当します。)
  • Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
  • Go言語のテストに関するブログ記事やチュートリアル (一般的な情報源)
  • Go言語のソースコード (特にsrc/pkg/testing/testing.goファイル)
  • Go言語のtestingパッケージの歴史に関する情報 (もしあれば、5e7fd762f356ff0ade0b937bのような特定のコミットに関する詳細)