diff options
author | Joseph Snyder <joe.snyder@kitware.com> | 2014-10-23 17:03:30 -0400 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2014-10-29 11:27:11 -0400 |
commit | 220e81345b68ed3ad15ef294f6de653fcd1a874c (patch) | |
tree | 759f57741cb0ba02e764515142284d6bf99ae8a1 /Source/CTest | |
parent | a2456e157223255f0e2a71f2ddd510510e42b9e4 (diff) | |
download | cmake-220e81345b68ed3ad15ef294f6de653fcd1a874c.tar.gz |
CTest: Add Javascript coverage parser
Add a coverage parser for the Blanket.js library using the JSON output of
the mocha.js test runner.
Add a test for the new parser.
Diffstat (limited to 'Source/CTest')
-rw-r--r-- | Source/CTest/cmCTestCoverageHandler.cxx | 40 | ||||
-rw-r--r-- | Source/CTest/cmCTestCoverageHandler.h | 3 | ||||
-rw-r--r-- | Source/CTest/cmParseBlanketJSCoverage.cxx | 166 | ||||
-rw-r--r-- | Source/CTest/cmParseBlanketJSCoverage.h | 48 |
4 files changed, 257 insertions, 0 deletions
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 7d3c6bc1b7..8dc22a8fa0 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -16,6 +16,7 @@ #include "cmParseCacheCoverage.h" #include "cmParseJacocoCoverage.h" #include "cmParseDelphiCoverage.h" +#include "cmParseBlanketJSCoverage.h" #include "cmCTest.h" #include "cmake.h" #include "cmMakefile.h" @@ -424,6 +425,13 @@ int cmCTestCoverageHandler::ProcessHandler() return error; } + file_count += this->HandleBlanketJSCoverage(&cont); + error = cont.Error; + if ( file_count < 0 ) + { + return error; + } + file_count += this->HandleDelphiCoverage(&cont); error = cont.Error; if ( file_count < 0 ) @@ -927,10 +935,12 @@ int cmCTestCoverageHandler::HandleDelphiCoverage( std::vector<std::string> files; g.SetRecurse(true); + std::string BinDir = this->CTest->GetBinaryDir(); std::string coverageFile = BinDir+ "/*.html"; + g.FindFiles(coverageFile); files=g.GetFiles(); if (files.size() > 0) @@ -947,6 +957,36 @@ int cmCTestCoverageHandler::HandleDelphiCoverage( } return static_cast<int>(cont->TotalCoverage.size()); } + +//---------------------------------------------------------------------- +int cmCTestCoverageHandler::HandleBlanketJSCoverage( + cmCTestCoverageHandlerContainer* cont) + { + cmParseBlanketJSCoverage cov = + cmParseBlanketJSCoverage(*cont, this->CTest); + std::string SourceDir + = this->CTest->GetCTestConfiguration("SourceDirectory"); + + //Look for something other than output.json, still JSON extension. + std::string coverageFile = SourceDir+ "/*.json"; + cmsys::Glob g; + std::vector<std::string> files; + g.FindFiles(coverageFile); + files=g.GetFiles(); + if (files.size() > 0) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Found BlanketJS output JSON, Performing Coverage" << std::endl); + cov.LoadCoverageData(files); + } + else + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Cannot find BlanketJS coverage files: " << coverageFile + << std::endl); + } + return static_cast<int>(cont->TotalCoverage.size()); + } //---------------------------------------------------------------------- int cmCTestCoverageHandler::HandleGCovCoverage( cmCTestCoverageHandlerContainer* cont) diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h index 01c5d7fea3..4aec795571 100644 --- a/Source/CTest/cmCTestCoverageHandler.h +++ b/Source/CTest/cmCTestCoverageHandler.h @@ -87,6 +87,9 @@ private: //! Handle coverage for Delphi (Pascal) int HandleDelphiCoverage(cmCTestCoverageHandlerContainer* cont); + //! Handle coverage for Jacoco + int HandleBlanketJSCoverage(cmCTestCoverageHandlerContainer* cont); + //! Handle coverage using Bullseye int HandleBullseyeCoverage(cmCTestCoverageHandlerContainer* cont); int RunBullseyeSourceSummary(cmCTestCoverageHandlerContainer* cont); diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx new file mode 100644 index 0000000000..5f4a70822a --- /dev/null +++ b/Source/CTest/cmParseBlanketJSCoverage.cxx @@ -0,0 +1,166 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmStandardIncludes.h" +#include <stdio.h> +#include <stdlib.h> +#include "cmSystemTools.h" +#include "cmParseBlanketJSCoverage.h" +#include <cmsys/Directory.hxx> +#include <cmsys/Glob.hxx> +#include <cmsys/FStream.hxx> + + +class cmParseBlanketJSCoverage::JSONParser + { +public: + typedef cmCTestCoverageHandlerContainer:: + SingleFileCoverageVector FileLinesType; + JSONParser(cmCTestCoverageHandlerContainer& cont) + : Coverage(cont) + { + } + + virtual ~JSONParser() + { + } + + std::string getValue(std::string line, int type) + { + size_t begIndex; + size_t endIndex; + endIndex = line.rfind(','); + begIndex = line.find_first_of(':'); + if(type == 0) + { + // A unique substring to remove the extra characters + // around the files name in the JSON (extra " and ,) + std::string foundFileName = + line.substr(begIndex+3,endIndex-(begIndex+4)); + return foundFileName; + } + else + { + return line.substr(begIndex,line.npos); + } + } + bool ParseFile(std::string file) + { + FileLinesType localCoverageVector; + std::string filename; + bool foundFile = false; + bool inSource = false; + std::string covResult; + std::string line; + + cmsys::ifstream in(file.c_str()); + if(!in) + { + return false; + } + while( cmSystemTools::GetLineFromStream(in, line)) + { + if(line.find("filename") != line.npos) + { + if(foundFile) + { + /* + * Upon finding a second file name, generate a + * vector within the total coverage to capture the + * information in the local vector + */ + FileLinesType& CoverageVector = + this->Coverage.TotalCoverage[filename.c_str()]; + CoverageVector = localCoverageVector; + localCoverageVector.clear(); + foundFile=false; + } + foundFile= true; + inSource = false; + filename = getValue(line,0).c_str(); + } + else if((line.find("coverage") != line.npos) && foundFile && inSource ) + { + /* + * two types of "coverage" in the JSON structure + * + * The coverage result over the file or set of files + * and the coverage for each individual line + * + * FoundFile and foundSource ensure that + * only the value of the line coverage is captured + */ + std::string result = getValue(line,1).c_str(); + result = result.substr(2,result.npos); + if(result == "\"\"") + { + // Empty quotation marks indicate that the + // line is not executable + localCoverageVector.push_back(-1); + } + else + { + // Else, it contains the number of time executed + localCoverageVector.push_back(atoi(result.c_str())); + } + } + else if(line.find("source") != line.npos) + { + inSource=true; + } + } + + // On exit, capture end of last file covered. + FileLinesType& CoverageVector = + this->Coverage.TotalCoverage[filename.c_str()]; + CoverageVector = localCoverageVector; + foundFile=false; + localCoverageVector.clear(); + return true; + } +private: + cmCTestCoverageHandlerContainer& Coverage; +}; + +cmParseBlanketJSCoverage::cmParseBlanketJSCoverage( + cmCTestCoverageHandlerContainer& cont, cmCTest* ctest) + :Coverage(cont), CTest(ctest) + { + } + +bool cmParseBlanketJSCoverage::LoadCoverageData(std::vector<std::string> files) + { + size_t i=0; + std::string path; + cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Found " << files.size() <<" Files" << std::endl); + for(i=0;i<files.size();i++) + { + cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Reading JSON File " << files[i] << std::endl); + + if(!this->ReadJSONFile(files[i])) + { + return false; + } + } + return true; + } + +bool cmParseBlanketJSCoverage::ReadJSONFile(std::string file) + { + cmParseBlanketJSCoverage::JSONParser parser + (this->Coverage); + cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Parsing " << file << std::endl); + parser.ParseFile(file); + return true; + } diff --git a/Source/CTest/cmParseBlanketJSCoverage.h b/Source/CTest/cmParseBlanketJSCoverage.h new file mode 100644 index 0000000000..fc1d477474 --- /dev/null +++ b/Source/CTest/cmParseBlanketJSCoverage.h @@ -0,0 +1,48 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmParseBlanketJSCoverage_h +#define cmParseBlanketJSCoverage_h + +#include "cmStandardIncludes.h" +#include "cmCTestCoverageHandler.h" + + +/** \class cmParseBlanketJSCoverage + * \brief Parse BlanketJS coverage information + * + * This class is used to parse BlanketJS(Pascal) coverage information + * generated by the Blanket.js library when used in conjunction with the + * test runner mocha.js, which is used to write out the JSON format. + * + * Blanket.js: + * http://blanketjs.org/ + * + * Mocha.js + * http://visionmedia.github.io/mocha/ + */ +class cmParseBlanketJSCoverage +{ +public: + cmParseBlanketJSCoverage(cmCTestCoverageHandlerContainer& cont, + cmCTest* ctest); + bool LoadCoverageData(std::vector<std::string> files); + // Read the JSON output + bool ReadJSONFile(std::string file); + +protected: + + class JSONParser; + cmCTestCoverageHandlerContainer& Coverage; + cmCTest* CTest; +}; +#endif |