[Cmake-commits] CMake branch, next, updated. v2.8.12-3633-gfe488fa

Brad King brad.king at kitware.com
Tue Oct 8 09:24:47 EDT 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  fe488fa93b91cd5b78733fe344288b1b70b82115 (commit)
       via  d0ec3a01a61f259768d31fc20791780807e1788e (commit)
      from  83357a929a9f01361a7783045077314289edab94 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fe488fa93b91cd5b78733fe344288b1b70b82115
commit fe488fa93b91cd5b78733fe344288b1b70b82115
Merge: 83357a9 d0ec3a0
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Oct 8 09:24:44 2013 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue Oct 8 09:24:44 2013 -0400

    Merge topic 'Add-coverage.py-Coverage' into next
    
    d0ec3a0 Adding support for the Python coverage.py tool.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d0ec3a01a61f259768d31fc20791780807e1788e
commit d0ec3a01a61f259768d31fc20791780807e1788e
Author:     Patrick Reynolds <patrick.reynolds at kitware.com>
AuthorDate: Fri Sep 27 10:42:39 2013 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Oct 8 09:20:30 2013 -0400

    Adding support for the Python coverage.py tool.
    
    This assumes that coverage.py has been run in such a way to produce its
    standard XML output. This uses the Cobertura schema and should be somewhat
    generalizable.

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 8412e3e..50e9d2b 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -439,6 +439,7 @@ set(CTEST_SRCS cmCTest.cxx
   CTest/cmParseCacheCoverage.cxx
   CTest/cmParseGTMCoverage.cxx
   CTest/cmParsePHPCoverage.cxx
+  CTest/cmParsePythonCoverage.cxx
   CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
   CTest/cmCTestGenericHandler.cxx
   CTest/cmCTestHandlerCommand.cxx
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 20aded2..ef071b9 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -11,6 +11,7 @@
 ============================================================================*/
 #include "cmCTestCoverageHandler.h"
 #include "cmParsePHPCoverage.h"
+#include "cmParsePythonCoverage.h"
 #include "cmParseGTMCoverage.h"
 #include "cmParseCacheCoverage.h"
 #include "cmCTest.h"
@@ -392,6 +393,13 @@ int cmCTestCoverageHandler::ProcessHandler()
     {
     return error;
     }
+  file_count += this->HandlePythonCoverage(&cont);
+  error = cont.Error;
+  if ( file_count < 0 )
+    {
+    return error;
+    }
+
   file_count += this->HandleMumpsCoverage(&cont);
   error = cont.Error;
   if ( file_count < 0 )
@@ -761,6 +769,32 @@ int cmCTestCoverageHandler::HandlePHPCoverage(
     }
   return static_cast<int>(cont->TotalCoverage.size());
 }
+
+//----------------------------------------------------------------------
+int cmCTestCoverageHandler::HandlePythonCoverage(
+  cmCTestCoverageHandlerContainer* cont)
+{
+  cmParsePythonCoverage cov(*cont, this->CTest);
+
+  // Assume the coverage.xml is in the source directory
+  std::string coverageXMLFile = this->CTest->GetBinaryDir() + "/coverage.xml";
+
+  if(cmSystemTools::FileExists(coverageXMLFile.c_str()))
+    {
+    cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+               "Parsing coverage.py XML file: " << coverageXMLFile
+               << std::endl);
+    cov.ReadCoverageXML(coverageXMLFile.c_str());
+    }
+  else
+    {
+    cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+               "Cannot find coverage.py XML file: " << coverageXMLFile
+               << std::endl);
+    }
+  return static_cast<int>(cont->TotalCoverage.size());
+}
+
 //----------------------------------------------------------------------
 int cmCTestCoverageHandler::HandleMumpsCoverage(
   cmCTestCoverageHandlerContainer* cont)
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index 92b0b22..3506928 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -70,6 +70,10 @@ private:
 
   //! Handle coverage using xdebug php coverage
   int HandlePHPCoverage(cmCTestCoverageHandlerContainer* cont);
+
+  //! Handle coverage for Python with coverage.py
+  int HandlePythonCoverage(cmCTestCoverageHandlerContainer* cont);
+
   //! Handle coverage for mumps
   int HandleMumpsCoverage(cmCTestCoverageHandlerContainer* cont);
 
diff --git a/Source/CTest/cmParsePythonCoverage.cxx b/Source/CTest/cmParsePythonCoverage.cxx
new file mode 100644
index 0000000..a086f13
--- /dev/null
+++ b/Source/CTest/cmParsePythonCoverage.cxx
@@ -0,0 +1,113 @@
+#include "cmStandardIncludes.h"
+#include "cmSystemTools.h"
+#include "cmXMLParser.h"
+#include "cmParsePythonCoverage.h"
+#include <cmsys/Directory.hxx>
+
+
+//----------------------------------------------------------------------------
+class cmParsePythonCoverage::XMLParser: public cmXMLParser
+{
+public:
+  XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
+    : CTest(ctest), Coverage(cont)
+  {
+  }
+
+  virtual ~XMLParser()
+  {
+  }
+
+protected:
+
+  virtual void StartElement(const char* name, const char** atts)
+  {
+    if(strcmp(name, "class") == 0)
+    {
+      int tagCount = 0;
+      while(true)
+      {
+        if(strcmp(atts[tagCount], "filename") == 0)
+        {
+          cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Reading file: "
+                     << atts[tagCount+1] << std::endl);
+          this->CurFileName = this->Coverage.SourceDir + "/" +
+                                 atts[tagCount+1];
+          FileLinesType& curFileLines =
+            this->Coverage.TotalCoverage[this->CurFileName];
+          std::ifstream fin(this->CurFileName.c_str());
+          if(!fin)
+          {
+            cmCTestLog(this->CTest, ERROR_MESSAGE,
+                       "Python Coverage: Error opening " << this->CurFileName
+                       << std::endl);
+            this->Coverage.Error++;
+            break;
+          }
+
+          std::string line;
+          curFileLines.push_back(-1);
+          while(cmSystemTools::GetLineFromStream(fin, line))
+          {
+            curFileLines.push_back(-1);
+          }
+
+          break;
+        }
+        ++tagCount;
+      }
+    }
+    else if(strcmp(name, "line") == 0)
+    {
+      int tagCount = 0;
+      int curNumber = -1;
+      int curHits = -1;
+      while(true)
+      {
+        if(strcmp(atts[tagCount], "hits") == 0)
+        {
+          curHits = atoi(atts[tagCount+1]);
+        }
+        else if(strcmp(atts[tagCount], "number") == 0)
+        {
+          curNumber = atoi(atts[tagCount+1]);
+        }
+
+        if(curHits > -1 && curNumber > -1)
+        {
+          FileLinesType& curFileLines =
+            this->Coverage.TotalCoverage[this->CurFileName];
+          curFileLines[curNumber] = curHits;
+          break;
+        }
+        ++tagCount;
+      }
+    }
+  }
+
+  virtual void EndElement(const char*) {}
+
+private:
+
+  typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
+     FileLinesType;
+  cmCTest* CTest;
+  cmCTestCoverageHandlerContainer& Coverage;
+  std::string CurFileName;
+
+};
+
+
+cmParsePythonCoverage::cmParsePythonCoverage(
+    cmCTestCoverageHandlerContainer& cont,
+    cmCTest* ctest)
+    :Coverage(cont), CTest(ctest)
+{
+}
+
+bool cmParsePythonCoverage::ReadCoverageXML(const char* xmlFile)
+{
+  cmParsePythonCoverage::XMLParser parser(this->CTest, this->Coverage);
+  parser.ParseFile(xmlFile);
+  return true;
+}
diff --git a/Source/CTest/cmParsePythonCoverage.h b/Source/CTest/cmParsePythonCoverage.h
new file mode 100644
index 0000000..668c7f9
--- /dev/null
+++ b/Source/CTest/cmParsePythonCoverage.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 cmParsePythonCoverage_h
+#define cmParsePythonCoverage_h
+
+#include "cmStandardIncludes.h"
+#include "cmCTestCoverageHandler.h"
+
+/** \class cmParsePythonCoverage
+ * \brief Parse coverage.py Python coverage information
+ *
+ * This class is used to parse the output of the coverage.py tool that
+ * is currently maintained by Ned Batchelder. That tool has a command
+ * that produces xml output in the format typically output by the common
+ * Java-based Cobertura coverage application. This helper class parses
+ * that XML file to fill the coverage-handler container.
+ */
+class cmParsePythonCoverage
+{
+public:
+
+  //! Create the coverage parser by passing in the coverage handler
+  //! container and the cmCTest object
+  cmParsePythonCoverage(cmCTestCoverageHandlerContainer& cont,
+    cmCTest* ctest);
+
+  //! Read the XML produced by running `coverage xml`
+  bool ReadCoverageXML(const char* xmlFile);
+
+private:
+
+  class XMLParser;
+  cmCTestCoverageHandlerContainer& Coverage;
+  cmCTest* CTest;
+  std::string CurFileName;
+};
+
+#endif
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 9c3ed59..030137c 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1959,6 +1959,25 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
       PASS_REGULAR_EXPRESSION
       "Process file.*XINDEX.m.*Total LOC:.*125.*Percentage Coverage: 85.60.*"
       ENVIRONMENT COVFILE=)
+
+  # Adding a test case for Python Coverage
+  configure_file(
+     "${CMake_SOURCE_DIR}/Tests/PythonCoverage/coverage.xml.in"
+     "${CMake_BINARY_DIR}/Testing/PythonCoverage/coverage.xml")
+  configure_file(
+     "${CMake_SOURCE_DIR}/Tests/PythonCoverage/DartConfiguration.tcl.in"
+     "${CMake_BINARY_DIR}/Testing/PythonCoverage/DartConfiguration.tcl")
+  file(COPY "${CMake_SOURCE_DIR}/Tests/PythonCoverage/coveragetest"
+    DESTINATION "${CMake_BINARY_DIR}/Testing/PythonCoverage")
+  add_test(NAME CTestPythonCoverage
+    COMMAND cmake -E chdir
+    ${CMake_BINARY_DIR}/Testing/PythonCoverage
+    $<TARGET_FILE:ctest> -T Coverage --debug)
+  set_tests_properties(CTestPythonCoverage PROPERTIES
+      PASS_REGULAR_EXPRESSION
+      "Process file.*foo.py.*Total LOC:.*13.*Percentage Coverage: 84.62.*"
+      ENVIRONMENT COVFILE=)
+
   # Use macro, not function so that build can still be driven by CMake 2.4.
   # After 2.6 is required, this could be a function without the extra 'set'
   # calls.
diff --git a/Tests/PythonCoverage/DartConfiguration.tcl.in b/Tests/PythonCoverage/DartConfiguration.tcl.in
new file mode 100644
index 0000000..e29cffe
--- /dev/null
+++ b/Tests/PythonCoverage/DartConfiguration.tcl.in
@@ -0,0 +1,8 @@
+# This file is configured by CMake automatically as DartConfiguration.tcl
+# If you choose not to use CMake, this file may be hand configured, by
+# filling in the required variables.
+
+
+# Configuration directories and files
+SourceDirectory: ${CMake_BINARY_DIR}/Testing/PythonCoverage/coveragetest
+BuildDirectory: ${CMake_BINARY_DIR}/Testing/PythonCoverage
diff --git a/Tests/PythonCoverage/coverage.xml.in b/Tests/PythonCoverage/coverage.xml.in
new file mode 100644
index 0000000..fcc1b1c
--- /dev/null
+++ b/Tests/PythonCoverage/coverage.xml.in
@@ -0,0 +1,35 @@
+<?xml version="1.0" ?>
+<!DOCTYPE coverage
+  SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-03.dtd'>
+<coverage branch-rate="0" line-rate="0.8462" timestamp="1380469411433" version="3.6">
+	<!-- Generated by coverage.py: http://nedbatchelder.com/code/coverage -->
+	<packages>
+		<package branch-rate="0" complexity="0" line-rate="0.8462" name="">
+			<classes>
+				<class branch-rate="0" complexity="0" filename="foo.py" line-rate="0.6667" name="foo">
+					<methods/>
+					<lines>
+						<line hits="1" number="2"/>
+						<line hits="1" number="3"/>
+						<line hits="1" number="4"/>
+						<line hits="1" number="6"/>
+						<line hits="0" number="7"/>
+						<line hits="0" number="8"/>
+					</lines>
+				</class>
+				<class branch-rate="0" complexity="0" filename="test_foo.py" line-rate="1" name="test_foo">
+					<methods/>
+					<lines>
+						<line hits="1" number="2"/>
+						<line hits="1" number="3"/>
+						<line hits="1" number="5"/>
+						<line hits="1" number="7"/>
+						<line hits="1" number="8"/>
+						<line hits="1" number="10"/>
+						<line hits="1" number="11"/>
+					</lines>
+				</class>
+			</classes>
+		</package>
+	</packages>
+</coverage>
diff --git a/Tests/PythonCoverage/coveragetest/foo.py b/Tests/PythonCoverage/coveragetest/foo.py
new file mode 100644
index 0000000..97b5a41
--- /dev/null
+++ b/Tests/PythonCoverage/coveragetest/foo.py
@@ -0,0 +1,8 @@
+
+def foo():
+    x = 3 + 3
+    return x
+
+def bar():
+    y = 2 + 2
+    return y
diff --git a/Tests/PythonCoverage/coveragetest/test_foo.py b/Tests/PythonCoverage/coveragetest/test_foo.py
new file mode 100644
index 0000000..51a69d8
--- /dev/null
+++ b/Tests/PythonCoverage/coveragetest/test_foo.py
@@ -0,0 +1,11 @@
+
+import foo
+import unittest
+
+class TestFoo(unittest.TestCase):
+
+    def testFoo(self):
+        self.assertEquals(foo.foo(), 6, 'foo() == 6')
+
+if __name__ == '__main__':
+    unittest.main()

-----------------------------------------------------------------------

Summary of changes:


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list