1+ <?php
2+ class PHP_CodeCoverage_Report_XML {
3+
4+ /**
5+ * @var string
6+ */
7+ private $ target ;
8+
9+ /**
10+ * @var PHP_CodeCoverage_Report_XML_Project
11+ */
12+ private $ project ;
13+
14+ public function process (PHP_CodeCoverage $ coverage , $ target )
15+ {
16+ if (substr ($ target , -1 , 1 ) != DIRECTORY_SEPARATOR ) {
17+ $ target .= DIRECTORY_SEPARATOR ;
18+ }
19+ $ this ->target = $ target ;
20+ $ this ->initTargetDirectory ($ target );
21+ $ report = $ coverage ->getReport ();
22+
23+ $ this ->project = new PHP_CodeCoverage_Report_XML_Project (
24+ $ coverage ->getReport ()->getName ()
25+ );
26+ $ this ->processTests ($ coverage ->getTests ());
27+
28+ $ this ->processDirectory ($ report , $ this ->project );
29+
30+ $ index = $ this ->project ->asDom ();
31+ $ index ->formatOutput = TRUE ;
32+ $ index ->preserveWhiteSpace = FALSE ;
33+ $ index ->save ($ target . '/index.xml ' );
34+ }
35+
36+ private function initTargetDirectory ($ dir )
37+ {
38+ if (file_exists ($ dir )) {
39+
40+ if (!is_dir ($ dir )) {
41+ throw new PHP_CodeCoverage_Exception ("' $ dir' exists but is not a directory. " );
42+ }
43+
44+ if (!is_writable ($ dir )) {
45+ throw new PHP_CodeCoverage_Exception ("' $ dir' exists but is not writable. " );
46+ }
47+ }
48+ else if (!@mkdir ($ dir , 0777 , TRUE )) {
49+ throw new PHP_CodeCoverage_Exception ("' $ dir' could not be created. " );
50+ }
51+ }
52+
53+ private function processDirectory (PHP_CodeCoverage_Report_Node_Directory $ directory , PHP_CodeCoverage_Report_XML_Node $ context )
54+ {
55+ $ dirObject = $ context ->addDirectory ($ directory ->getName ());
56+ $ this ->setTotals ($ directory , $ dirObject ->getTotals ());
57+ foreach ($ directory as $ node ) {
58+ if ($ node instanceof PHP_CodeCoverage_Report_Node_Directory) {
59+ $ this ->processDirectory ($ node , $ dirObject );
60+ continue ;
61+ }
62+ if ($ node instanceof PHP_CodeCoverage_Report_Node_File) {
63+ $ this ->processFile ($ node , $ dirObject );
64+ continue ;
65+ }
66+ throw new PHP_CodeCoverage_Exception ('Unknown node type for XML Report ' );
67+ }
68+ }
69+
70+ private function processFile (PHP_CodeCoverage_Report_Node_File $ file , PHP_CodeCoverage_Report_XML_Directory $ context )
71+ {
72+ $ fileObject = $ context ->addFile ($ file ->getName (), $ file ->getId () . '.xml ' );
73+ $ this ->setTotals ($ file , $ fileObject ->getTotals ());
74+
75+ $ fileReport = new PHP_CodeCoverage_Report_XML_File_Report ($ file ->getName ());
76+ $ this ->setTotals ($ file , $ fileReport ->getTotals ());
77+
78+ foreach ($ file ->getClassesAndTraits () as $ unit ) {
79+ $ this ->processUnit ($ unit , $ fileReport );
80+ }
81+
82+ foreach ($ file ->getFunctions () as $ function ) {
83+ $ this ->processFunction ($ function , $ fileReport );
84+ }
85+
86+ foreach ($ file ->getCoverageData () as $ line => $ tests ) {
87+ if (!is_array ($ tests ) || count ($ tests ) == 0 ) {
88+ continue ;
89+ }
90+ $ coverage = $ fileReport ->getLineCoverage ($ line );
91+ foreach ($ tests as $ test ) {
92+ $ coverage ->addTest ($ test );
93+ }
94+ }
95+
96+ $ this ->initTargetDirectory ($ this ->target . dirname ($ file ->getId ()) . '/ ' );
97+ $ fileDom = $ fileReport ->asDom ();
98+ $ fileDom ->formatOutput = TRUE ;
99+ $ fileDom ->preserveWhiteSpace = FALSE ;
100+ $ fileDom ->save ($ this ->target . $ file ->getId () . '.xml ' );
101+ }
102+
103+ private function processUnit ($ unit , PHP_CodeCoverage_Report_XML_File_Report $ report )
104+ {
105+ if (isset ($ unit ['className ' ])) {
106+ $ unitObject = $ report ->getClassObject ($ unit ['className ' ]);
107+ }
108+ else {
109+ $ unitObject = $ report ->getTraitObject ($ unit ['traitName ' ]);
110+ }
111+
112+ $ unitObject ->setLines (
113+ $ unit ['startLine ' ],
114+ $ unit ['executableLines ' ],
115+ $ unit ['executedLines ' ]
116+ );
117+ $ unitObject ->setCrap ($ unit ['crap ' ]);
118+
119+ $ unitObject ->setPackage (
120+ $ unit ['package ' ]['fullPackage ' ],
121+ $ unit ['package ' ]['package ' ],
122+ $ unit ['package ' ]['subpackage ' ],
123+ $ unit ['package ' ]['category ' ]
124+ );
125+
126+ $ unitObject ->setNamespace ($ unit ['package ' ]['namespace ' ]);
127+
128+ foreach ($ unit ['methods ' ] as $ method ) {
129+ $ methodObject = $ unitObject ->addMethod ($ method ['methodName ' ]);
130+ $ methodObject ->setSignature ($ method ['signature ' ]);
131+ $ methodObject ->setLines ($ method ['startLine ' ], $ method ['endLine ' ]);
132+ $ methodObject ->setCrap ($ method ['crap ' ]);
133+ $ methodObject ->setTotals ($ method ['executableLines ' ], $ method ['executedLines ' ], $ method ['coverage ' ]);
134+ }
135+ }
136+
137+ private function processFunction ($ function , PHP_CodeCoverage_Report_XML_File_Report $ report )
138+ {
139+ $ functionObject = $ report ->getFunctionObject ($ function ['functionName ' ]);
140+ $ functionObject ->setSignature ($ function ['signature ' ]);
141+ $ functionObject ->setLines ($ function ['startLine ' ]);
142+ $ functionObject ->setCrap ($ function ['crap ' ]);
143+ $ functionObject ->setTotals ($ function ['executableLines ' ], $ function ['executedLines ' ], $ function ['coverage ' ]);
144+ }
145+
146+ private function processTests (array $ tests )
147+ {
148+ $ testsObject = $ this ->project ->getTests ();
149+ foreach ($ tests as $ test => $ result ) {
150+ if ($ test == 'UNCOVERED_FILES_FROM_WHITELIST ' ) {
151+ continue ;
152+ }
153+ $ testsObject ->addTest ($ test , $ result );
154+ }
155+ }
156+
157+ private function setTotals (PHP_CodeCoverage_Report_Node $ node , PHP_CodeCoverage_Report_XML_Totals $ totals )
158+ {
159+ $ loc = $ node ->getLinesOfCode ();
160+ $ totals ->setNumLines (
161+ $ loc ['loc ' ],
162+ $ loc ['cloc ' ],
163+ $ loc ['ncloc ' ],
164+ $ node ->getNumExecutableLines (),
165+ $ node ->getNumExecutedLines ()
166+ );
167+
168+ $ totals ->setNumClasses (
169+ $ node ->getNumClasses (),
170+ $ node ->getNumTestedClasses ()
171+ );
172+
173+ $ totals ->setNumTraits (
174+ $ node ->getNumTraits (),
175+ $ node ->getNumTestedTraits ()
176+ );
177+
178+ $ totals ->setNumMethods (
179+ $ node ->getNumMethods (),
180+ $ node ->getNumTestedMethods ()
181+ );
182+
183+ $ totals ->setNumFunctions (
184+ $ node ->getNumFunctions (),
185+ $ node ->getNumTestedFunctions ()
186+ );
187+ }
188+
189+ }
0 commit comments