main.cpp
No OneTemporary

File Metadata

Created
Tue, Jul 7, 3:50 PM

main.cpp

#include <iostream>
#include <stdlib.h>
#include <boost/format.hpp>
#include <string>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/split.hpp>
#include <map>
#include <list>
#include <set>
using namespace std;
char* pathTestsOutput = "/tmp/xreate-tests-output-XXXXXX";
const string& pathComponentsGraph = "/private/prg/code/xreate/project/subsystems.graphml";
map<string, bool> tests;
set<string> testsUnused;
void runTests(){
//mkstemp(pathTestsOutput);
const string &cmm_export = string("export GTEST_OUTPUT=\"xml:")+ pathTestsOutput +"\"";
const string &cmm_chdir = "cd /private/prg/code/xreate/";
const string &cmm_runtest = "exec build/xreate";
const string& comm = boost::str(boost::format("(%1% && %2% && %3%)") % cmm_export % cmm_chdir % cmm_runtest);
system(comm.c_str());
}
void parseTestsOutput(){
const string& queryTestCases = "//testcase[@status='run']";
xmlDocPtr doc = xmlParseFile(pathTestsOutput);
xmlXPathContextPtr context = xmlXPathNewContext(doc);
xmlXPathObjectPtr testcases = xmlXPathEvalExpression((xmlChar*) queryTestCases.c_str(), context);
for (int caseId = 0; caseId < testcases->nodesetval->nodeNr; ++caseId) {
xmlNodePtr testcase = testcases->nodesetval->nodeTab[caseId];
string nameTestSuite((const char *) xmlGetProp(testcase->parent, (const xmlChar*)"name"));
string nameTestCase((const char *) xmlGetProp(testcase, (const xmlChar*)"name"));
bool flagSuccess = (testcase->children)? false: true;
string testName = nameTestSuite+":"+nameTestCase;
tests.emplace(testName, flagSuccess);
testsUnused.insert(testName);
}
}
string getTestsResultForComponent(const string& signature){
list<string> componentParts;
boost::split(componentParts, signature, [](const char& a){return a==',';});
int resNeg = 0; int resPos = 0; bool flagTestsFound = false;
for(auto test: tests){
for(const string& signature: componentParts){
if (boost::icontains(test.first, signature)){
if (test.second){
resPos ++;
} else {
resNeg--;
}
flagTestsFound = true;
testsUnused.erase(test.first);
break;
}
}
}
if (!flagTestsFound){
cout << "Warning: No tests for "<<signature << endl;
}
return (resNeg!=0)? to_string(resNeg) : to_string(resPos);
}
void parseComponentsGraph(){
const string& queryNode = "//a:node[a:data[@key=\"d4\"]]";
const string& queryTestResults = "a:data[@key='d5']";
const string& queryTestSignature = "a:data[@key='d4']";
xmlDocPtr doc = xmlParseFile(pathComponentsGraph.c_str());
xmlNodePtr root = xmlDocGetRootElement(doc);
xmlXPathContextPtr context = xmlXPathNewContext(doc);
xmlXPathRegisterNs(context, (xmlChar*) "a", (xmlChar*) "http://graphml.graphdrawing.org/xmlns");
xmlXPathObjectPtr setComponents = xmlXPathEvalExpression((xmlChar*) queryNode.c_str(), context);
for (int nodeId=0; nodeId < setComponents->nodesetval->nodeNr; ++nodeId){
xmlNodePtr nodeComponent = setComponents->nodesetval->nodeTab[nodeId];
//xmlXPathSetContextNode(node, context);
context->node = nodeComponent;
xmlXPathObjectPtr setNodeTestSignature = xmlXPathEvalExpression((xmlChar*) queryTestSignature.c_str(), context);
assert(setNodeTestSignature->nodesetval->nodeNr==1);
char* componentTestsSignature = (char*) xmlNodeGetContent(setNodeTestSignature->nodesetval->nodeTab[0]);
string componentTestsResult = getTestsResultForComponent(componentTestsSignature);
xmlXPathObjectPtr setNodeTestResult = xmlXPathEvalExpression((xmlChar*) queryTestResults.c_str(), context);
if (0 == setNodeTestResult->nodesetval->nodeNr){
xmlNodePtr dataTestsResult = xmlNewChild(nodeComponent, NULL, BAD_CAST "data",
BAD_CAST componentTestsResult.c_str());
xmlNewProp(dataTestsResult, BAD_CAST "key", BAD_CAST "d5");
continue;
}
assert(setNodeTestResult->nodesetval->nodeNr == 1);
xmlNodePtr dataTestsResult = setNodeTestResult->nodesetval->nodeTab[0];
xmlNodeSetContent(dataTestsResult, BAD_CAST componentTestsResult.c_str());
}
xmlSaveFile(pathComponentsGraph.c_str(), doc);
}
void checkUnusedTests(){
for (string test: testsUnused){
cout << "Warning: no components use test "<<test << endl;
}
}
int main()
{
runTests();
parseTestsOutput();
parseComponentsGraph();
checkUnusedTests();
return 0;
}

Event Timeline