TAP::Parser - 分析 TAP 輸出
版本 3.44
use TAP::Parser;
my $parser = TAP::Parser->new( { source => $source } );
while ( my $result = $parser->next ) {
print $result->as_string;
}
TAP::Parser
旨在正確分析 TAP 輸出。如需瞭解如何透過此模組執行測試的範例,請參閱簡單的範例程式碼 examples/
。
有一個專門的 Wiki 網站介紹 Test Anything Protocol
其中包含 TAP::Parser 食譜
http://testanything.org/testing-with-tap/perl/tap::parser-cookbook.html
new
my $parser = TAP::Parser->new(\%args);
傳回新的 TAP::Parser
物件。
參數應為雜湊參照,其中包含下列 其中一個 鍵
source
在 3.18 中變更
這是傳遞輸入給建構函式的首選方法。
source
用於建立 TAP::Parser::Source,該物件會傳遞給 "iterator_factory_class",而後者會找出如何處理來源並為其建立 <TAP::Parser::Iterator>。剖析器會使用反覆器讀取 TAP 串流。
若要設定 IteratorFactory,請使用下方的 sources
參數。
請注意,source
、tap
和 exec
是 互斥 的。
tap
在 3.18 中變更
值應為完整的 TAP 輸出。
tap 用於建立 TAP::Parser::Source,該物件會傳遞給 "iterator_factory_class",而後者會找出如何處理來源並為其建立 <TAP::Parser::Iterator>。剖析器會使用反覆器讀取 TAP 串流。
若要設定 IteratorFactory,請使用下方的 sources
參數。
請注意,source
、tap
和 exec
是 互斥 的。
exec
必須傳遞陣列參照。
exec 陣列參照用於建立 TAP::Parser::Source,該物件會傳遞給 "iterator_factory_class",而後者會找出如何處理來源並為其建立 <TAP::Parser::Iterator>。剖析器會使用反覆器讀取 TAP 串流。
預設情況下,TAP::Parser::SourceHandler::Executable 類別會建立一個 TAP::Parser::Iterator::Process 物件來處理來源。這會將陣列參考字串作為命令引數傳遞給 IPC::Open3::open3
exec => [ '/usr/bin/ruby', 't/my_test.rb' ]
如果提供了任何 test_args
,它們將會附加到命令引數清單的結尾。
若要設定 IteratorFactory,請使用下方的 sources
參數。
請注意,source
、tap
和 exec
是 互斥 的。
下列金鑰是選用的。
sources
3.18 新增.
如果設定,sources
必須是一個雜湊參考,其中包含要載入和/或設定的 TAP::Parser::SourceHandler 的名稱。這些值是設定的雜湊,來源處理常式可以透過 "TAP::Parser::Source 中的 config_for" 來存取。
例如
sources => {
Perl => { exec => '/path/to/custom/perl' },
File => { extensions => [ '.tap', '.txt' ] },
MyCustom => { some => 'config' },
}
這將導致 TAP::Parser
傳遞自訂設定給兩個內建來源處理常式 - TAP::Parser::SourceHandler::Perl、TAP::Parser::SourceHandler::File - 並嘗試載入 MyCustom
類別。請參閱 "TAP::Parser::IteratorFactory 中的 load_handlers" 以取得更多詳細資料。
sources
參數會影響 source
、tap
和 exec
參數的處理方式。
請參閱 TAP::Parser::IteratorFactory、TAP::Parser::SourceHandler 和子類別以取得更多詳細資料。
callback
如果存在,每個對應於特定結果類型的回呼函式都將以結果作為引數呼叫,如果使用 run
方法的話
my %callbacks = (
test => \&test_callback,
plan => \&plan_callback,
comment => \&comment_callback,
bailout => \&bailout_callback,
unknown => \&unknown_callback,
);
my $aggregator = TAP::Parser::Aggregator->new;
for my $file ( @test_files ) {
my $parser = TAP::Parser->new(
{
source => $file,
callbacks => \%callbacks,
}
);
$parser->run;
$aggregator->add( $file, $parser );
}
switches
如果使用 Perl 檔案作為來源,可以傳遞選用的開關,這些開關將會在呼叫 perl 可執行檔時使用。
my $parser = TAP::Parser->new( {
source => $test_file,
switches => [ '-Ilib' ],
} );
test_args
與 source
和 exec
選項搭配使用,以提供對 @ARGV
風格引數陣列的參考,傳遞給測試程式。
spool
如果傳遞一個檔案控制代碼,將會將所有已剖析 TAP 的副本寫入該控制代碼。
merge
如果為 false,STDERR 就不會被擷取(儘管它會被「中繼」以使其與 STDOUT 保持某種同步)。
如果為 true,STDERR 和 STDOUT 是同一個檔案控制代碼。如果 STDERR 含有任何類似 TAP 格式的內容,這可能會導致中斷,但允許精確同步。
此行為的細微差別可能取決於平台,並且未來可能會變更。
grammar_class
引入此選項是為了讓您可以輕鬆自訂剖析器應使用的文法類別。預設為 TAP::Parser::Grammar。
另請參閱 "make_grammar"。
result_factory_class
此選項的用意是讓您可以輕鬆自訂剖析器應使用的結果工廠類別。預設為 TAP::Parser::ResultFactory。
另請參閱 "make_result"。
iterator_factory_class
在 3.18 中變更
此選項的用意是讓您可以輕鬆自訂剖析器應使用的反覆運算器工廠類別。預設為 TAP::Parser::IteratorFactory。
next
my $parser = TAP::Parser->new( { source => $file } );
while ( my $result = $parser->next ) {
print $result->as_string, "\n";
}
此方法會一次傳回一個剖析結果。請注意,此方法具有破壞性。您無法倒帶並檢查先前的結果。
如果使用回呼,則會在此呼叫傳回之前發出回呼。
傳回的每個結果都是 TAP::Parser::Result 的子類別。請參閱該模組和相關類別,以取得如何使用它們的更多資訊。
run
$parser->run;
此方法只會執行剖析器並剖析所有 TAP。
make_grammar
建立新的 TAP::Parser::Grammar 物件並傳回。傳遞任何給定的引數。
grammar_class
可以自訂,如 "new" 中所述。
make_result
使用剖析器的 TAP::Parser::ResultFactory 建立新的 TAP::Parser::Result 物件,並傳回。傳遞任何給定的引數。
result_factory_class
可以自訂,如 "new" 中所述。
make_iterator_factory
3.18 新增.
建立新的 TAP::Parser::IteratorFactory 物件並傳回。傳遞任何給定的引數。
iterator_factory_class
可以自訂,如 "new" 中所述。
如果您已經讀到文件中的這裡,您會看到這個
while ( my $result = $parser->next ) {
print $result->as_string;
}
傳回的每個結果都是 TAP::Parser::Result 子類別,稱為結果類型。
基本上,您可以從 TAP 中擷取個別結果。六種類型,每個類型都有範例,如下所示
版本
TAP version 12
計畫
1..42
Pragma
pragma +strict
測試
ok 3 - We should start with some foobar!
註解
# Hope we don't use up the foobar.
退出
Bail out! We ran out of foobar!
未知
... yo, this ain't TAP! ...
擷取的每個結果都是不同類型的結果物件。每個結果物件都有共用方法,而不同類型可能有其類型獨有的方法。有時類型方法可能會在子類別中覆寫,但保證其使用方式相同。
type
傳回結果類型,例如 comment
或 test
。
as_string
列印標記的字串表示形式。不過,這可能不是確切的輸出。如果測試沒有數字,則會加上測試數字,TODO 和 SKIP 指令會變成大寫,而且一般來說,會將內容清理乾淨。如果您需要標記的原始文字,請參閱 raw
方法。
raw
傳回已分析的原始文字列。
is_plan
指出這是否是測試計畫列。
is_test
指出這是否是測試列。
is_comment
指出這是否是註解。如果 STDERR 已合併到 STDOUT,註解通常只會出現在 TAP 串流中。請參閱 merge
選項。
is_bailout
指出這是否是退出列。
is_yaml
指出目前的項目是否是 YAML 區塊。
is_unknown
指出目前的列是否可以分析。
is_ok
if ( $result->is_ok ) { ... }
報告給定的結果是否已通過。任何不是測試結果的項目都會傳回 true。這僅提供一個方便的捷徑,讓您可以執行此操作
my $parser = TAP::Parser->new( { source => $source } );
while ( my $result = $parser->next ) {
# only print failing results
print $result->as_string unless $result->is_ok;
}
plan
方法if ( $result->is_plan ) { ... }
如果上述評估為真,則下列方法將在 $result
物件上提供。
plan
if ( $result->is_plan ) {
print $result->plan;
}
這只不過是 as_string
的同義詞。
directive
my $directive = $result->directive;
如果 SKIP 指令包含在計畫中,這個方法將會傳回它。
1..0 # SKIP: why bother?
explanation
my $explanation = $result->explanation;
如果 SKIP 指令包含在計畫中,這個方法將會傳回說明,如果有的話。
pragma
方法if ( $result->is_pragma ) { ... }
如果上述評估為真,則下列方法將在 $result
物件上提供。
pragmas
傳回指令清單,每個指令清單都是 + 或 -,後面接著指令名稱。
comment
方法if ( $result->is_comment ) { ... }
如果上述評估為真,則下列方法將在 $result
物件上提供。
comment
if ( $result->is_comment ) {
my $comment = $result->comment;
print "I have something to say: $comment";
}
bailout
方法if ( $result->is_bailout ) { ... }
如果上述評估為真,則下列方法將在 $result
物件上提供。
explanation
if ( $result->is_bailout ) {
my $explanation = $result->explanation;
print "We bailed out because ($explanation)";
}
如果且僅當一個代幣是救援代幣時,你可以透過這個方法取得「說明」。說明是出現在 tap 輸出中神秘的「Bail out!」字詞之後的文字。
unknown
方法if ( $result->is_unknown ) { ... }
沒有針對未知結果的獨特方法。
test
方法if ( $result->is_test ) { ... }
如果上述評估為真,則下列方法將在 $result
物件上提供。
ok
my $ok = $result->ok;
傳回 ok
或 not ok
狀態的文字。
number
my $test_number = $result->number;
傳回測試的編號,即使原始的 TAP 輸出沒有提供該編號。
description
my $description = $result->description;
傳回測試的說明,如果有的話。這是測試編號之後但指令之前的部分。
directive
my $directive = $result->directive;
如果測試行有任何指令,傳回 TODO
或 SKIP
。
explanation
my $explanation = $result->explanation;
如果測試有任何 TODO
或 SKIP
指令,這個方法將會傳回隨附的說明,如果有的話。
not ok 17 - 'Pigs can fly' # TODO not enough acid
對於上述行,解釋為酸度不足。
is_ok
if ( $result->is_ok ) { ... }
傳回一個布林值,指出測試是否通過。請記住,對於 TODO 測試,測試總是通過。
注意:這以前是passed
。後者方法已棄用,並會發出警告。
is_actual_ok
if ( $result->is_actual_ok ) { ... }
傳回一個布林值,指出測試是否通過,不論其 TODO 狀態為何。
注意:這以前是actual_passed
。後者方法已棄用,並會發出警告。
is_unplanned
if ( $test->is_unplanned ) { ... }
如果測試編號大於已規劃測試的數量,此方法會傳回 true。未規劃測試對於is_ok
總是會傳回 false,不論測試是否有has_todo
(有關此項目的更多資訊,請參閱TAP::Parser::Result::Test)。
has_skip
if ( $result->has_skip ) { ... }
傳回一個布林值,指出此測試是否具有 SKIP 指令。
has_todo
if ( $result->has_todo ) { ... }
傳回一個布林值,指出此測試是否具有 TODO 指令。
請注意,TODO 測試總是通過。如果您需要知道它們是否真的通過,請檢查is_actual_ok
方法。
in_todo
if ( $parser->in_todo ) { ... }
在最近的結果為 TODO 時為 True。在傳回 TODO 結果之前變為 True,並在傳回下一個非 TODO 測試之前保持為 True。
在分析 TAP 之後,有許多方法可讓您深入探討結果,並決定對您有意義的內容。
這些結果是指執行個別測試。
passed
my @passed = $parser->passed; # the test numbers which passed
my $passed = $parser->passed; # the number of tests which passed
此方法讓您知道哪些(或多少)測試通過。如果測試失敗,但有 TODO 指令,則會將其計為通過測試。
failed
my @failed = $parser->failed; # the test numbers which failed
my $failed = $parser->failed; # the number of tests which failed
此方法讓您知道哪些(或多少)測試失敗。如果測試通過,但有 TODO 指令,則不會將其計為失敗測試。
actual_passed
# the test numbers which actually passed
my @actual_passed = $parser->actual_passed;
# the number of tests which actually passed
my $actual_passed = $parser->actual_passed;
此方法讓您知道哪些(或多少)測試實際上通過,不論是否找到 TODO 指令。
actual_ok
此方法是 actual_passed
的同義詞。
actual_failed
# the test numbers which actually failed
my @actual_failed = $parser->actual_failed;
# the number of tests which actually failed
my $actual_failed = $parser->actual_failed;
此方法讓您知道哪些(或多少)測試實際上失敗,無論是否找到 TODO 指令。
todo
my @todo = $parser->todo; # the test numbers with todo directives
my $todo = $parser->todo; # the number of tests with todo directives
此方法讓您知道哪些(或多少)測試有 TODO 指令。
todo_passed
# the test numbers which unexpectedly succeeded
my @todo_passed = $parser->todo_passed;
# the number of tests which unexpectedly succeeded
my $todo_passed = $parser->todo_passed;
此方法讓您知道哪些(或多少)測試實際上通過,但被宣告為「TODO」測試。
todo_failed
# deprecated in favor of 'todo_passed'. This method was horribly misnamed.
這是一個命名不當的方法。它指出哪些 TODO 測試意外成功。現在將發出警告並呼叫 todo_passed
。
skipped
my @skipped = $parser->skipped; # the test numbers with SKIP directives
my $skipped = $parser->skipped; # the number of tests with SKIP directives
此方法讓您知道哪些(或多少)測試有 SKIP 指令。
pragma
取得或設定 pragma。若要取得 pragma 的狀態
if ( $p->pragma('strict') ) {
# be strict
}
若要設定 pragma 的狀態
$p->pragma('strict', 1); # enable strict mode
pragmas
取得目前已啟用 pragma 的清單
my @pragmas_enabled = $p->pragmas;
這些結果是關於個別測試程式總結果的「後設」資訊。
plan
my $plan = $parser->plan;
如果找到,傳回測試計畫。
good_plan
已過時。請改用 is_good_plan
。
is_good_plan
if ( $parser->is_good_plan ) { ... }
傳回布林值,指出計畫的測試數量是否與執行的測試數量相符。
注意:這以前是 good_plan
。後者方法已過時,將發出警告。
既然我們在討論這個主題...
tests_planned
print $parser->tests_planned;
根據計畫,傳回計畫的測試數量。例如,計畫為「1..17」表示計畫了 17 個測試。
tests_run
print $parser->tests_run;
傳回實際執行的測試數量。希望這會與 $parser->tests_planned
的數量相符。
skip_all
如果所有測試都略過,傳回真值(實際上是略過的理由)。
start_time
傳回建立剖析器時的牆上時鐘時間。
end_time
傳回看到 TAP 輸入結束時的牆上時鐘時間。
start_times
傳回建立剖析器時的 CPU 時間(例如 "times" in perlfunc)。
end_times
傳回看到 TAP 輸入結束時的 CPU 時間(例如 "times" in perlfunc)。
has_problems
if ( $parser->has_problems ) {
...
}
這是一個「萬用」方法,如果任何測試目前失敗、任何 TODO 測試意外成功,或發生任何剖析錯誤,則傳回 true。
version
$parser->version;
剖析器完成後,這將傳回剖析 TAP 的版本號碼。版本號碼在 TAP 版本 13 中引入,因此如果找不到版本號碼,則假設為版本 12。
exit
$parser->exit;
剖析器完成後,這將傳回結束狀態。如果剖析器執行可執行檔,則傳回可執行檔的結束狀態。
wait
$parser->wait;
剖析器完成後,這將傳回等待狀態。如果剖析器執行可執行檔,則傳回可執行檔的等待狀態。否則,這只會傳回 exit
狀態。
ignore_exit
$parser->ignore_exit(1);
在決定測試是否通過時,告訴剖析器忽略測試的結束狀態。通常,即使所有個別測試都通過,但具有非零結束狀態的測試仍會被視為失敗。在無法控制測試腳本的結束值的情況下,請使用此選項來忽略它。
parse_errors
my @errors = $parser->parse_errors; # the parser errors
my $errors = $parser->parse_errors; # the number of parser_errors
幸運的是,所有 TAP 輸出都是完美的。如果並非如此,這個方法將傳回剖析器錯誤。請注意,剖析器無法辨識的垃圾行 不是
錯誤。這允許此剖析器處理 TAP 的未來版本。以下是剖析器報告的所有 TAP 錯誤
計畫錯誤
計畫(例如「1..5」)只能出現在 TAP 輸出的開始或結束。
沒有計畫
一定要有計畫!
多於一個計畫
1..3
ok 1 - input file opened
not ok 2 - first line of the input valid # todo some data
ok 3 read the rest of the file
1..3
對。很好笑。不要這樣做。
測試號碼順序錯誤
1..3
ok 1 - input file opened
not ok 2 - first line of the input valid # todo some data
ok 2 read the rest of the file
上面最後一行的測試號碼應為「3」,而非「2」。
請注意,有些行有測試號碼,有些行沒有,這完全可以接受。但是,當找到測試號碼時,它必須是順序的。以下也是錯誤的
1..3
ok 1 - input file opened
not ok - first line of the input valid # todo some data
ok 2 read the rest of the file
但這不是
1..3
ok - input file opened
not ok - first line of the input valid # todo some data
ok 3 read the rest of the file
get_select_handles
取得檔案處理序清單,可以傳遞給 select
以確定此剖析器的準備狀態。
delete_spool
刪除並傳回暫存區。
my $fh = $parser->delete_spool;
如前所述,可以將「callback」金鑰新增到 TAP::Parser
建構函式中。如果存在,每個對應於特定結果類型的 callback 都會以結果作為引數呼叫,如果使用 run
方法。預期 callback 是子常式參考(或匿名子常式),並以剖析器結果作為其引數呼叫。
my %callbacks = (
test => \&test_callback,
plan => \&plan_callback,
comment => \&comment_callback,
bailout => \&bailout_callback,
unknown => \&unknown_callback,
);
my $aggregator = TAP::Parser::Aggregator->new;
for my $file ( @test_files ) {
my $parser = TAP::Parser->new(
{
source => $file,
callbacks => \%callbacks,
}
);
$parser->run;
$aggregator->add( $file, $parser );
}
也可以這樣新增 callback
$parser->callback( test => \&test_callback );
$parser->callback( plan => \&plan_callback );
允許 callback 的以下金鑰。這些金鑰區分大小寫。
test
如果 $result->is_test
傳回 true,則呼叫。
version
如果 $result->is_version
傳回 true,則呼叫。
plan
如果 $result->is_plan
傳回 true,則呼叫。
comment
如果 $result->is_comment
傳回 true,則呼叫。
bailout
如果 $result->is_unknown
傳回 true,則呼叫。
yaml
如果 $result->is_yaml
傳回 true,則呼叫。
unknown
如果 $result->is_unknown
傳回 true,則呼叫。
ELSE
如果結果沒有為其定義 callback,則會呼叫此 callback。因此,如果所有先前的結果類型都指定為 callback,則永遠不會呼叫此 callback。
ALL
此 callback 將永遠被呼叫,而且會在呼叫上述 callback 之後為每個結果發生。例如,如果載入 Term::ANSIColor,可以使用以下內容為測試輸出著色
my %callbacks = (
test => sub {
my $test = shift;
if ( $test->is_ok && not $test->directive ) {
# normal passing test
print color 'green';
}
elsif ( !$test->is_ok ) { # even if it's TODO
print color 'white on_red';
}
elsif ( $test->has_skip ) {
print color 'white on_blue';
}
elsif ( $test->has_todo ) {
print color 'white';
}
},
ELSE => sub {
# plan, comment, and so on (anything which isn't a test line)
print color 'black on_white';
},
ALL => sub {
# now print them
print shift->as_string;
print color 'reset';
print "\n";
},
);
EOF
當沒有更多要剖析的行時呼叫。由於沒有附帶的 TAP::Parser::Result 物件,因此會傳遞 TAP::Parser
物件。
如果您正在尋找 EBNF 語法,請參閱 TAP::Parser::Grammar。
Perl-QA 清單嘗試確保與 Test::Harness 向後相容。但是,有一些細微的差異。
待辦事項計畫
鮮為人知的 Test::Harness 功能之一是它支援計畫中的 TODO 清單
1..2 todo 2
ok 1 - We have liftoff
not ok 2 - Anti-gravity device activated
在 Test::Harness 中,測試編號 2 會通過,因為它在計畫行中列為 TODO 測試。不過,我們不知道實際上有人使用這項功能,而且不建議硬編碼測試編號,因為新增測試並中斷測試編號順序非常容易。這會讓測試套件非常脆弱。建議改用下列方式
1..2
ok 1 - We have liftoff
not ok 2 - Anti-gravity device activated # TODO
「遺漏」測試
很少發生,但有時測試套件可能會遇到「遺漏測試
ok 1
ok 2
ok 15
ok 16
ok 17
Test::Harness 會報告測試 3-14 失敗。對於 TAP::Parser
,這些測試不會被視為失敗,因為它們從未執行過。它們會被報告為解析失敗(測試順序錯誤)。
如果您發現需要提供自訂功能(就像使用 Test::Harness::Straps 一樣),您很幸運:TAP::Parser
和相關元件的設計很容易插入和/或子類化。
在開始之前,請務必了解幾件事
所有 TAP::*
物件都繼承自 TAP::Object。
許多 TAP::*
類別都有子類化區段來指導您。
請注意,TAP::Parser
的設計是作為中央「製造者」,也就是說,它負責建立 TAP::Parser::*
名稱空間中的大多數新物件。
這讓您可以單一設定要使用的子類別,這表示在許多情況下,您會發現您只需要子類化解析器的其中一個元件。
此規則的例外是SourceHandlers 和Iterators,但它們都是使用可自訂的IteratorFactory 建立的。
透過子類化,您可能會覆寫未記錄的方法。這本身不是壞事,但請注意,未記錄的方法可能會在不同版本之間不經警告地變更,我們無法保證向後相容性。如果需要變更任何已記錄的方法,它會先被標示為不建議使用,然後在後續版本中變更。
TAP 解析器會使用單一 TAP原始來源的輸入,它可以來自任何地方(檔案、可執行檔、資料庫、IO 處理、URI 等)。來源會打包在 TAP::Parser::Source 物件中,它會收集一些關於來源的元資料。然後,解析器會使用 TAP::Parser::IteratorFactory 來決定要使用哪個 TAP::Parser::SourceHandler,透過 "Iterators" 將原始來源轉換為 TAP 串流。
如果您只是想讓 TAP::Parser
處理新的 TAP 來源,您可能不需要子類化 TAP::Parser
本身。相反地,您需要建立新的 TAP::Parser::SourceHandler 類別,並使用sources 參數將它插入解析器中,參數為 "new"。在開始撰寫之前,請先閱讀 TAP::Parser::IteratorFactory,以了解系統運作的方式。
如果您發現您真的需要使用您自己的迭代器工廠,您仍然可以在不子類別化 TAP::Parser
的情況下透過設定 "iterator_factory_class" 來進行。
如果您僅需要在建立時自訂物件,請子類別化 TAP::Parser 並覆寫 "make_iterator_factory"。
請注意,make_source
和 make_perl_source
已被標示為過時,並已移除。
TAP 解析器使用迭代器來迴圈讀取從來源讀取的 TAP 串流。預設提供幾種類型的迭代器,全部都是 TAP::Parser::Iterator 的子類別。選擇使用哪個迭代器是迭代器工廠的責任,儘管它僅委派給它使用的來源處理常式。
如果您正在撰寫您自己的 TAP::Parser::SourceHandler,您可能也需要建立您自己的迭代器。如果是這樣,您需要子類別化 TAP::Parser::Iterator。
請注意,"make_iterator" 已被標示為過時,並已移除。
TAP 解析器在迴圈讀取輸入串流時會建立 TAP::Parser::Result。提供相當多的結果類型;選擇使用哪個類別是結果工廠的責任。
若要建立您自己的結果類型,您有兩個選項
子類別化 TAP::Parser::Result 並將您的新結果類型/類別註冊到預設的 TAP::Parser::ResultFactory。
子類別化 TAP::Parser::ResultFactory 本身並實作您自己的 TAP::Parser::Result 建立邏輯。然後,您需要透過設定 result_factory_class
參數來自訂您的解析器所使用的類別。請參閱 "new" 以取得更多詳細資訊。
如果您需要在建立時自訂物件,請子類別化 TAP::Parser 並覆寫 "make_result"。
TAP::Parser::Grammar 是解析器的核心。它將 TAP 輸入串流進行標記化並產生結果。如果您需要自訂其行為,您應該先熟悉來源。足夠的說教了。
子類別化 TAP::Parser::Grammar 並透過設定 grammar_class
參數來自訂您的解析器。請參閱 "new" 以取得更多詳細資訊。
如果您需要在建立時自訂物件,請子類別化 TAP::Parser 並覆寫 "make_grammar"
以下所有人均提供協助。錯誤回報、修補程式、(不)道德支援或僅是鼓勵的話語,都已陸續收到。
Michael Schwern
Andy Lester
chromatic
GEOFFR
Shlomi Fish
Torsten Schoenfeld
Jerry Gay
Aristotle
Adam Kennedy
Yves Orton
Adrian Howard
Sean & Lil
Andreas J. Koenig
Florian Ragwitz
Corion
Mark Stosberg
Matt Kraai
David Wheeler
Alex Vandiver
Cosimo Streppone
Ville Skyttä
Curtis "Ovid" Poe <ovid@cpan.org>
Andy Armstong <andy@hexten.net>
Eric Wilhelm @ <ewilhelm at cpan dot org>
Michael Peters <mpeters at plusthree dot com>
Leif Eriksen <leif dot eriksen at bigpond dot com>
Steve Purkis <spurkis@cpan.org>
Nicholas Clark <nick@ccl4.org>
Lee Johnson <notfadeaway at btinternet dot com>
Philippe Bruhat <book@cpan.org>
請將任何錯誤或功能要求回報至 bug-test-harness@rt.cpan.org
,或透過 http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Harness 上的網路介面。我們會收到通知,然後當我們進行變更時,您會自動收到錯誤進度的通知。
顯然地,包含修補程式的錯誤是最好的。如果您願意,您可以透過匿名檢出最新版本來針對 bleed 進行修補
git clone git://github.com/Perl-Toolchain-Gang/Test-Harness.git
版權所有 2006-2008 Curtis "Ovid" Poe,保留所有權利。
此程式為自由軟體;您可以在與 Perl 相同的條款下重新散布或修改它。