タイトルは coberturaに日本語パッチをあてる - お仕事の備忘録みたいなもの からいただきました。どもすみません。
※ cobertura のテストが幾つか失敗してます。参考程度にどうぞ。
Cobertura が用意しているテストはクリアしたので、まぁまぁ大丈夫だと思います。が、動作の保証まではできません。ごめんなさい。
- UTF-8 で "(" を含んだ文字列
が入っていると、ant の cobertura-report タスクで以下のようなエラーを吐いて死ぬ。超困る。何とかせねば。
TokenMgrError: Lexical error at line 17, column 38. Encountered: "\r" (13), after : "\"\u8b41\uff70\u7e3a\u52b1\uff1e\ufffd\ufffd.equals(arg) ) {" [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParserTokenManager.getNextToken(JavaParserTokenManager.java:2078) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.jj_scan_token(JavaParser.java:10181) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.jj_3R_198(JavaParser.java:8524) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.jj_3R_178(JavaParser.java:8924) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.jj_3R_151(JavaParser.java:8901) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.jj_3R_102(JavaParser.java:8960) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.jj_3_25(JavaParser.java:9977) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.jj_2_25(JavaParser.java:5999) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.Expression(JavaParser.java:2762) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.IfStatement(JavaParser.java:4251) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.Statement(JavaParser.java:3816) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.BlockStatement(JavaParser.java:3997) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.Block(JavaParser.java:3947) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.MethodDeclaration(JavaParser.java:2039) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.ClassBodyDeclaration(JavaParser.java:1082) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.ClassBody(JavaParser.java:941) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.UnmodifiedClassDeclaration(JavaParser.java:854) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.ClassDeclaration(JavaParser.java:761) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.TypeDeclaration(JavaParser.java:608) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.CompilationUnit(JavaParser.java:353) [cobertura-report] at net.sourceforge.cobertura.javancss.parser.JavaParser.parse(JavaParser.java:137) [cobertura-report] at net.sourceforge.cobertura.javancss.Javancss._measureSource(Javancss.java:256) [cobertura-report] at net.sourceforge.cobertura.javancss.Javancss._measureRoot(Javancss.java:339) [cobertura-report] at net.sourceforge.cobertura.javancss.Javancss.<init>(Javancss.java:419) [cobertura-report] at net.sourceforge.cobertura.reporting.ComplexityCalculator.getAccumlatedCCNForSource(ComplexityCalculator.java:104) [cobertura-report] at net.sourceforge.cobertura.reporting.ComplexityCalculator.getAccumlatedCCNForSingleFile(ComplexityCalculator.java:141) [cobertura-report] at net.sourceforge.cobertura.reporting.ComplexityCalculator.getCCNForSourceFileNameInternal(ComplexityCalculator.java:226) [cobertura-report] at net.sourceforge.cobertura.reporting.ComplexityCalculator.getCCNForPackageInternal(ComplexityCalculator.java:196) [cobertura-report] at net.sourceforge.cobertura.reporting.ComplexityCalculator.getCCNForProject(ComplexityCalculator.java:166) [cobertura-report] at net.sourceforge.cobertura.reporting.html.HTMLReport.generateTableRowForTotal(HTMLReport.java:704) [cobertura-report] at net.sourceforge.cobertura.reporting.html.HTMLReport.generateOverview(HTMLReport.java:336) [cobertura-report] at net.sourceforge.cobertura.reporting.html.HTMLReport.generateOverviews(HTMLReport.java:271) [cobertura-report] at net.sourceforge.cobertura.reporting.html.HTMLReport.<init>(HTMLReport.java:96) [cobertura-report] at net.sourceforge.cobertura.reporting.Main.parseArguments(Main.java:107) [cobertura-report] at net.sourceforge.cobertura.reporting.Main.main(Main.java:176) [cobertura-report] WARN getAccumlatedCCNForSource, JavaNCSS got an error while parsing the java file D:\Development\_Projects\cobertura-test\.\src\local\my\project\HelloWorld.java [cobertura-report] TokenMgrError in STDIN [cobertura-report] Lexical error at line 17, column 38. Encountered: "\r" (13), after : "\"\u8b41\uff70\u7e3a\u52b1\uff1e\ufffd\ufffd.equals(arg) ) {"
調査
Cobertura をビルドできるようにする
> ant jar
で JAR作成してくれる。
やばそうなところを見つける
スタックトレースから追いかけるだけの簡単なお仕事。
最初は net.sourceforge.cobertura.javancss.parser.JavaParserTokenManager.getNextToken
辺りを見ていたんだけど、さっぱり分からないので、呼び出し元を見ながら分かりそうなところまで行ってみる。
で、分かったこと。
- net.sourceforge.cobertura.javancss.Javancss はエンコーディングの設定ができる
- が、Javancss を使っている net.sourceforge.cobertura.reporting.ComplexityCalculator.getAccumlatedCCNForSource がエンコーディングの設定をしていない
private Complexity getAccumlatedCCNForSource(String sourceFileName, Source source) { if (source == null) { return ZERO_COMPLEXITY; } if (!sourceFileName.endsWith(".java")) { return ZERO_COMPLEXITY; } Javancss javancss = new Javancss(source.getInputStream()); /* ここだ! */
コードを修正する
Ant の cobertura-report タスクにある encoding プロパティ?を使えるように修正してみる。
net.sourceforge.cobertura.reporting.Main.java
103: ComplexityCalculator complexity = new ComplexityCalculator(finder);
104: complexity.setEncoding(encoding);
net.sourceforge.cobertura.reporting.ComplexityCalculator
67: private Map packageCNNCache = new HashMap();
68:
69: private String encoding;
95: private Complexity getAccumlatedCCNForSource(String sourceFileName, Source source) { 96: if (source == null) 97: { 98: return ZERO_COMPLEXITY; 99: } 100: if (!sourceFileName.endsWith(".java")) 101: { 102: return ZERO_COMPLEXITY; 103: } 104: Javancss javancss = new Javancss(source.getInputStream(), encoding);
245: public void setEncoding(String encoding) { 246: this.encoding = encoding; 247: }
net.sourceforge.cobertura.javancss.Javancss
413: public Javancss(InputStream isJavaSource_, String encoding) { 414: Util.debug( "Javancss.(InputStream).sJavaSourceFile_: " + isJavaSource_ ); 415: _sErrorMessage = null; 416: _vJavaSourceFiles = null; 417: this.encoding = encoding;
ビルドして実験
無事カバレッジが作成された!!
気の迷いかもしれないので、ソースを元に戻して再度挑戦。大丈夫そう。
テストを通す
せっかく作ってくれているテストは通しておきたい…。
> ant
net.sourceforge.cobertura.test.SwitchFunctionalTest のテストが1つこけるけども、これは修正前もこけてたのでよしとする。