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

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

このコミットは、Go言語のテストスイートにおける複数のテストファイルと、それらの期待される出力が記録されたgolden.outファイルを更新するものです。具体的には、test/bugs/bug006.gotest/if1.gotest/switch1.goの3つのGoソースコードファイルと、テスト結果の基準となるtest/golden.outが変更されています。これらの変更は、Go言語の初期開発段階におけるコンパイラやランタイムの挙動の変化に伴い、テストの期待値を調整するために行われたと考えられます。

コミット

  • コミットハッシュ: 39b28df01eff7c9111cad6497544956289c8fb6a
  • 作者: Rob Pike r@golang.org
  • 日付: Mon Jun 16 11:36:23 2008 -0700
  • コミットメッセージ:
    update test results
    
    SVN=122912
    

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

https://github.com/golang/go/commit/39b28df01eff7c9111cad6497544956289c8fb6a

元コミット内容

commit 39b28df01eff7c9111cad6497544956289c8fb6a
Author: Rob Pike <r@golang.org>
Date:   Mon Jun 16 11:36:23 2008 -0700

    update test results
    
    SVN=122912
---
 test/bugs/bug006.go |  6 ++++-
 test/golden.out     | 78 +++++++++++++++++++++++------------------------------
 test/if1.go         | 13 ++++++---\n test/switch1.go     | 14 +++++-----\n 4 files changed, 56 insertions(+), 55 deletions(-)\n

変更の背景

このコミットの背景には、Go言語のコンパイラやランタイムの進化があります。Go言語は2008年当時、まだ活発に開発が進められている初期段階にありました。この時期には、言語仕様の変更、バグ修正、最適化などが頻繁に行われており、それらの変更が既存のテストの期待される出力に影響を与えることがありました。

update test resultsというコミットメッセージが示す通り、このコミットは、Go言語の内部的な変更によって、既存のテストケースの実行結果が以前と異なるようになったため、その新しい正しい結果に合わせてテストの期待値を更新することを目的としています。特にtest/golden.outの変更は、コンパイラのエラーメッセージやランタイムの出力形式、あるいはプログラムの実行結果自体が変更されたことを強く示唆しています。

また、SVN=122912という記述は、当時のGo言語がSubversion(SVN)でバージョン管理されていたことを示しており、このコミットがSVNリポジトリからGitリポジトリへの移行過程、またはその後の同期の一環として行われた可能性も示唆しています。

前提知識の解説

このコミットを理解するためには、以下のGo言語の基本的な概念とテストに関する知識が必要です。

  1. Go言語の初期開発: Go言語は2007年にGoogleで設計が始まり、2009年にオープンソースとして公開されました。このコミットが行われた2008年は、まだ言語仕様が固まっておらず、コンパイラやランタイムの挙動が頻繁に変更されていた時期です。
  2. iota: Go言語における定数宣言で用いられるキーワードです。constブロック内で使用され、連続する定数に自動的にインクリメントされる値を割り当てます。最初のiota0、次のiota1といった具合に、定数宣言ごとに値が増加します。
    const (
        a = iota // a = 0
        b = iota // b = 1
        c = iota // c = 2
    )
    
    また、式と組み合わせることも可能です。
    const (
        x float = iota * 1.0 // x = 0.0
        y float = iota * 2.0 // y = 2.0 (iota is 1 here)
    )
    
  3. ifステートメントのショート宣言: Go言語のifステートメントは、条件式の前に短い変数の宣言と初期化を行うことができます。この変数はifブロック内でのみスコープを持ちます。
    if err := someFunc(); err != nil {
        // err はこのブロック内でのみ有効
    }
    
  4. switchステートメントのショート宣言: ifと同様に、switchステートメントも条件式の前に短い変数の宣言と初期化を行うことができます。
    switch x := someValue(); x {
    case 1:
        // x はこのブロック内でのみ有効
    case 2:
        // ...
    }
    
  5. テストのゴールデンファイル(Golden File Testing): test/golden.outのようなファイルは、ゴールデンファイルまたはスナップショットテストで用いられます。これは、プログラムの出力(コンソール出力、エラーメッセージ、生成されたファイルの内容など)を事前に記録しておき、テスト実行時に現在の出力とこのゴールデンファイルを比較することで、プログラムの挙動が期待通りであることを検証する手法です。Go言語のテストスイートでは、コンパイラのエラーメッセージやランタイムの出力が時間とともに変化する可能性があるため、このようなゴールデンファイルが特に重要になります。

技術的詳細

このコミットの技術的詳細は、Go言語のコンパイラとランタイムの挙動が、特定のコードパターンに対してどのように変化したかを示しています。

  • test/bugs/bug006.goの変更:

    • 元のコードではconst (g float = 4.5 * iota;);のみでしたが、x float = iota;が追加されました。これにより、iotaの挙動がgに影響を与える前にxでリセットされる(またはx0g4.5となる)ことをテストしています。
    • func main() {}func main() int {}に変更され、main関数が整数を返すようになりました。これは、Go言語の初期段階でmain関数の戻り値の型が試行錯誤されていたことを示唆しています。
    • if g == 0.0 { print "zero\\n";}if g != 4.5 { print " fail\\n"; return 1; }が追加され、gの値が期待通りであるか、そしてmain関数が0または1を返すことでテストの成功/失敗を示すようになりました。これは、テストの自動化と結果の検証をより明確にするための変更です。
    • 元のコメントshould 4.5 * iota be ok? perhaps, perhaps not. but (all!) error msgs are bad:は、iotaと浮動小数点数の組み合わせに関するコンパイラの挙動が不安定であったか、エラーメッセージが不明瞭であったことを示しています。このコミットでテストが更新されたということは、その挙動が安定したか、少なくとも期待される挙動が明確になったことを意味します。
  • test/if1.goの変更:

    • func main() {}func main() int {}に変更され、main関数が整数を返すようになりました。
    • count := 0;count := 7;に変更されました。
    • if one := 1; { // BUG if there is a simple stat, the condition must be presentというコメントが削除されました。これは、ifステートメントのショート宣言に関するコンパイラのバグが修正されたか、またはその挙動が明確になったことを示唆しています。元のコメントは、ショート宣言がある場合に条件式が必須であるという制約が、当時のコンパイラで正しく処理されていなかった可能性を示しています。
    • if count != 8 { print count, " should be 8\\n"; return 1 }が追加され、ifブロック内の処理が正しく行われたか(count7 + 1 = 8になるか)を検証し、テスト結果をmain関数の戻り値で示すようになりました。
  • test/switch1.goの変更:

    • func main() {}func main() int {}に変更され、main関数が整数を返すようになりました。
    • switch x := 5; { // BUG if there is a simple stat, the condition must be presentというコメントが削除されました。これもifと同様に、switchステートメントのショート宣言に関するコンパイラのバグが修正されたか、挙動が明確になったことを示唆しています。
    • case i < x:case i == x:case i > x:の各ケースにreturn 0;return 1;が追加され、switch文の実行パスが期待通りであるかをmain関数の戻り値で検証するようになりました。
  • test/golden.outの変更:

    • このファイルは、Goコンパイラやテストランナーの出力(エラーメッセージ、警告、プログラムの標準出力など)の「正しい」バージョンを記録しています。
    • 変更内容を見ると、多くのエラーメッセージのフォーマットが変更されています(例: nil.go:30 fatal error:nil.go:30: fatal error:に)。これは、コンパイラのエラー報告機能が改善されたことを示しています。
    • BUG: known to succeed incorrectlyBUG: known to fail incorrectlyといったコメントが削除されている箇所が多数あります。これは、以前は誤った結果を出力していたテストが、コンパイラやランタイムの修正によって正しい結果を出すようになったことを意味します。
    • 特にbugs/bug006.goのセクションでは、以前の多数のエラーメッセージが削除され、代わりにzero failというプログラムの出力が記録されています。これは、bug006.goのテストがコンパイルエラーではなく、実行時のロジックエラーを検出するテストに変わったことを示しています。

これらの変更は、Go言語のコンパイラとランタイムが成熟し、より正確で予測可能な挙動を示すようになったことを反映しています。テストスイートの更新は、この進化を追跡し、将来の変更に対する回帰テストの基盤を維持するために不可欠です。

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

test/bugs/bug006.go

--- a/test/bugs/bug006.go
+++ b/test/bugs/bug006.go
@@ -7,10 +7,14 @@
  package main
  
  const (
++		x float = iota;
  	g float = 4.5 * iota;
  );
  
-func main() {
+func main() int {
+	if g == 0.0 { print "zero\\n";}\
+	if g != 4.5 { print " fail\\n"; return 1; }\
+	return 0;
 }
  /*
  should 4.5 * iota be ok? perhaps, perhaps not. but (all!) error msgs are bad:

test/golden.out

変更が非常に多いため、主要な変更点のみを抜粋します。

--- a/test/golden.out
+++ b/test/golden.out
@@ -18,7 +18,6 @@ hello, world
 =========== ./if.go
 
 =========== ./if1.go
-BUG: known to succeed incorrectly
  
 =========== ./int_lit.go
  
@@ -27,11 +26,11 @@ BUG: known to succeed incorrectly
 =========== ./literal.go
  
 =========== ./nil.go
-nil.go:30 fatal error: naddr: const <T>{<i><int32>INT32;}\n+nil.go:30: fatal error: naddr: const <T>{<i><int32>INT32;}\n BUG: known to fail incorrectly
  
 =========== ./sieve.go
-sieve.go:8 fatal error: walktype: switch 1 unknown op SEND l(114)\n+sieve.go:8: fatal error: walktype: switch 1 unknown op SEND l(151)\n BUG: known to fail incorrectly
  
 =========== ./string_lit.go
@@ -39,19 +38,21 @@ BUG: known to fail incorrectly
 =========== ./switch.go
  
 =========== ./switch1.go
-BUG: known to succeed incorrectly
  
 =========== ./test0.go
-test0.go:23 warning: addtyp: renaming Point/<Point>{<x><int32>INT32;<y><int32>INT32;} to Point2/<Point2>FORW
-test0.go:48: illegal types for operand
-\t(<float32>FLOAT32) AS (<int32>INT32)
-test0.go:49: illegal types for operand
-\t(<float32>FLOAT32) AS (<int32>INT32)
+test0.go:48: illegal types for operand: AS
+\t(<float32>FLOAT32)
+\t(<int32>INT32)
+test0.go:49: illegal types for operand: AS
+\t(<float32>FLOAT32)
+\t(<int32>INT32)
 test0.go:50: error in shape across assignment
-test0.go:55: illegal types for operand
-\t(*<Point2>{}) CALLMETH (<Point2>{})
-test0.go:54: illegal types for operand
-\t(<Point2>{}) AS ({})
+test0.go:55: illegal types for operand: CALLMETH
+\t(*<Point>{})
+\t(<Point>{<x><int32>INT32;<y><int32>INT32;<Point_Initialize>120({},{}){};<Point_Distance>101({},{}){};})
+test0.go:54: illegal types for operand: AS
+\t(<Point>{<x><int32>INT32;<y><int32>INT32;<Point_Initialize>120({},{}){};<Point_Distance>101({},{}){};})
+\t({})
  BUG: known to fail incorrectly
  
 =========== ./turing.go
@@ -121,57 +122,45 @@ BUG: known to succeed incorrectly
  
 =========== bugs/bug003.go
  bugs/bug003.go:6: switch statement must have case labels
-bugs/bug003.go:6 fatal error: walkswitch: not case EMPTY
-\n BUG: fatal error
  
 =========== bugs/bug004.go
  BUG: known to succeed incorrectly
  
 =========== bugs/bug006.go
-bugs/bug006.go:6: illegal combination of literals 0 0
-bugs/bug006.go:6: expression must be a constant
-bugs/bug006.go:6: expression must be a constant
-bugs/bug006.go:6: expression must be a constant
-bugs/bug006.go:6: expression must be a constant
-bugs/bug006.go:6: expression must be a constant
-bugs/bug006.go:6: expression must be a constant
-bugs/bug006.go:6: expression must be a constant
-bugs/bug006.go:6: expression must be a constant
-bugs/bug006.go:6 fatal error: too many errors
+zero
+ fail
  BUG: known to fail incorrectly
  
 =========== bugs/bug010.go
  bugs/bug010.go:7: i undefined
-bugs/bug010.go:8: illegal conversion of constant to 020({},<_o135>{},{})\n+bugs/bug010.go:8: illegal conversion of constant to 002({},{}){}\n bugs/bug010.go:9: error in shape across assignment
  BUG: known to fail incorrectly
  
 =========== bugs/bug014.go
-bugs/bug014.go:6 warning: non-oct character in escape sequence: '\n-bugs/bug014.go:6 warning: non-oct character in escape sequence: '\n-bugs/bug014.go:7 warning: non-oct character in escape sequence: '\n-bugs/bug014.go:8 warning: non-hex character in escape sequence: '\n-bugs/bug014.go:9 warning: non-hex character in escape sequence: '\n+bugs/bug014.go:6: non-oct character in escape sequence: '\n+bugs/bug014.go:6: non-oct character in escape sequence: '\n+bugs/bug014.go:7: non-oct character in escape sequence: '\n+bugs/bug014.go:8: non-hex character in escape sequence: '\n+bugs/bug014.go:9: non-hex character in escape sequence: '\n BUG: errors caught but exit code should be non-zero
  
 =========== bugs/bug015.go
  BUG: known to succeed incorrectly
  
 =========== bugs/bug022.go
-bugs/bug022.go:8: illegal types for operand
-\t(*<string>*STRING) INDEXPTR (<int32>INT32)
-bugs/bug022.go:8: illegal types for operand
-\t(<uint8>UINT8) AS \n+bugs/bug022.go:8: illegal types for operand: INDEXPTR
+\t(*<string>*STRING)
+\t(<int32>INT32)
  BUG: known to fail incorrectly
  
 =========== bugs/bug023.go
-bugs/bug023.go:20 fatal error: naddr: const <Type>I{<TypeName>110(<_t138>{},<_o140>{},{});}\n+bugs/bug023.go:20: fatal error: naddr: const <Type>I{<TypeName>101({},{}){};}\n BUG: known to fail incorrectly
  
 =========== bugs/bug025.go
-bugs/bug025.go:7 fatal error: dumpexportvar: oname nil: Foo\n+bugs/bug025.go:7: fatal error: dumpexportvar: oname nil: Foo
  
  BUG: known to fail incorrectly or at least with a bad message
  
@@ -180,10 +169,12 @@ check: main_sigs_I: not defined
  BUG: known to fail incorrectly
  
 =========== bugs/bug027.go
-bugs/bug027.go:50: illegal types for operand
-\t(<Element>I{}) CONV (<I>{})
-bugs/bug027.go:50: illegal types for operand
-\t(<Element>I{}) CONV (<I>{})\n+bugs/bug027.go:50: illegal types for operand: CONV
+\t(<Element>I{})
+\t(<I>{<val><int32>INT32;})
+bugs/bug027.go:50: illegal types for operand: CONV
+\t(<Element>I{})
+\t(<I>{<val><int32>INT32;})
  BUG: known to fail incorrectly
  
 =========== bugs/bug028.go
@@ -240,7 +231,7 @@ bugs/bug044.go:23: error in shape across assignment
  BUG: compilation should succeed
  
 =========== bugs/bug045.go
-bugs/bug045.go:13 fatal error: naddr: const <T>{<i><int32>INT32;}\n+bugs/bug045.go:13: fatal error: naddr: const <T>{<i><int32>INT32;}\n BUG: known to fail incorrectly
  
 =========== bugs/bug046.go
  
@@ -252,7 +243,6 @@ BUG: known to fail incorrectly
 =========== fixedbugs/bug005.go
  
 =========== fixedbugs/bug007.go
-fixedbugs/bug007.go:7 warning: addtyp: renaming Point/<Point>{<x><float32>FLOAT32;<y><float32>FLOAT32;} to Polar/<Polar>FORW
  
 =========== fixedbugs/bug008.go

test/if1.go

--- a/test/if1.go
+++ b/test/if1.go
@@ -6,9 +6,14 @@
  
  package main
  
-func main() {
-\tcount := 0;
-\tif one := 1; {  // BUG if there is a simple stat, the condition must be present
-\t\tcount = count + one;\t\
+func main() int {
+\tcount := 7;
+\tif one := 1; {
+\t\tcount = count + one\t
  	}
+\tif count != 8 {
+\t\tprint count, " should be 8\\n";
+\t\treturn 1
+\t}
+\treturn 0
 }

test/switch1.go

--- a/test/switch1.go
+++ b/test/switch1.go
@@ -6,11 +6,13 @@
  
  package main
  
-func main() {
-  i := 0;
-\tswitch x := 5; {  // BUG if there is a simple stat, the condition must be present
-\tcase i < x:\
-\tcase i == x:\
-\tcase i > x:\
+func main() int {
+\ti := 0;
+\tswitch x := 5; {
+\t\tcase i < x:\
+\t\t\treturn 0;
+\t\tcase i == x:\
+\t\tcase i > x:\
+\t\t\treturn 1;
  	}
 }

コアとなるコードの解説

test/bugs/bug006.go

このファイルは、iotaキーワードと浮動小数点数の定数宣言の挙動、およびmain関数の戻り値によるテスト結果の報告方法をテストしています。

  • const (x float = iota; g float = 4.5 * iota;);:
    • Go言語のiotaは、constブロック内で宣言されるたびに値がインクリメントされます。
    • x float = iota;では、iota0となり、x0.0に初期化されます。
    • g float = 4.5 * iota;では、iotaは次の値である1となり、g4.5 * 1 = 4.5に初期化されます。
    • この変更は、iotaが連続する定数宣言でどのように機能するかを明確にテストするためのものです。
  • func main() int { ... return 0; }:
    • main関数の戻り値がint型になり、テストの成功を0、失敗を1で示すようになりました。これは、Go言語のテストフレームワークがまだ成熟していなかった初期段階において、シェルスクリプトなどからテスト結果を判定するための一般的な手法です。
  • if g == 0.0 { print "zero\\n";}if g != 4.5 { print " fail\\n"; return 1; }:
    • gの値が期待通り4.5になっているかを検証しています。もしg0.0であれば"zero"と出力し、4.5でなければ" fail"と出力してテストを失敗させます。これにより、iotaの計算が正しく行われていることを確認します。

test/golden.out

このファイルは、Goコンパイラとランタイムの出力の「スナップショット」です。このコミットでの変更は、主に以下の点を反映しています。

  • エラーメッセージのフォーマット統一: 多くのエラーメッセージで、ファイル名と行番号の後にコロン(:)が追加され、より標準的なエラー報告形式に統一されました(例: nil.go:30 fatal error: -> nil.go:30: fatal error:)。これは、コンパイラの出力がより機械的に解析しやすくなったことを示唆しています。
  • バグ修正によるテスト結果の変更: 以前はBUG: known to succeed incorrectlyBUG: known to fail incorrectlyとマークされていたテストが、コンパイラやランタイムの修正によって正しい結果を返すようになったため、これらのコメントが削除されています。
  • bug006.goの出力変更: 以前はbug006.goが多数のコンパイルエラーを出力していましたが、変更後はzero failというプログラムの実行結果が出力されるようになりました。これは、bug006.goがコンパイルエラーをテストするのではなく、実行時のロジックをテストするファイルに変わったことを明確に示しています。

test/if1.go

このファイルは、ifステートメントのショート宣言の挙動をテストしています。

  • func main() int { ... return 0 }: bug006.goと同様に、main関数の戻り値でテスト結果を報告する形式に変更されました。
  • count := 7;: 初期値が0から7に変更されました。これは、テストの意図をより明確にするため、または特定の数値で問題が顕在化するかを確認するためかもしれません。
  • if one := 1; { ... }: ifステートメントのショート宣言の構文自体は変更されていませんが、以前のコメント// BUG if there is a simple stat, the condition must be presentが削除されました。これは、この構文に関するコンパイラのバグが修正され、期待通りに動作するようになったことを示しています。
  • if count != 8 { print count, " should be 8\\n"; return 1 }: ifブロック内の処理(count = count + one)が正しく行われ、count8になることを検証しています。

test/switch1.go

このファイルは、switchステートメントのショート宣言の挙動をテストしています。

  • func main() int { ... return 0; }: if1.gobug006.goと同様に、main関数の戻り値でテスト結果を報告する形式に変更されました。
  • switch x := 5; { ... }: switchステートメントのショート宣言の構文自体は変更されていませんが、以前のコメント// BUG if there is a simple stat, the condition must be presentが削除されました。これもifの場合と同様に、この構文に関するコンパイラのバグが修正されたか、挙動が明確になったことを示しています。
  • case i < x: return 0;case i == x:case i > x: return 1;: 各caseブロックにreturnステートメントが追加され、switch文が期待されるパスを通ることを検証しています。この場合、i0x5なので、i < xのケースが実行され、0が返されることが期待されます。

これらの変更は、Go言語の初期開発における言語機能の安定化と、それに対応するテストスイートの改善プロセスを明確に示しています。

関連リンク

特になし。

参考にした情報源リンク

  • コミットデータ (./commit_data/176.txt)
  • Go言語の基本的な構文と概念に関する一般的な知識
  • Go言語の初期開発に関する歴史的背景知識