summaryrefslogtreecommitdiffstats
path: root/3rdparty/simpletest/extensions/coverage/coverage_data_handler.php
blob: bbf81106fc5ee2507937e8bc3687270055565b22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?php
/**
 * @package        SimpleTest
 * @subpackage     Extensions
 */
/**
 * @todo	which db abstraction layer is this?
 */
require_once 'DB/sqlite.php';

/**
 * Persists code coverage data into SQLite database and aggregate data for convienent
 * interpretation in report generator.  Be sure to not to keep an instance longer
 * than you have, otherwise you risk overwriting database edits from another process
 * also trying to make updates.
 * @package        SimpleTest
 * @subpackage     Extensions
 */
class CoverageDataHandler {

    var $db;

    function __construct($filename) {
        $this->filename = $filename;
        $this->db = new SQLiteDatabase($filename);
        if (empty($this->db)) {
            throw new Exception("Could not create sqlite db ". $filename);
        }
    }

    function createSchema() {
        $this->db->queryExec("create table untouched (filename text)");
        $this->db->queryExec("create table coverage (name text, coverage text)");
    }

    function &getFilenames() {
        $filenames = array();
        $cursor = $this->db->unbufferedQuery("select distinct name from coverage");
        while ($row = $cursor->fetch()) {
            $filenames[] = $row[0];
        }

        return $filenames;
    }

    function write($coverage) {
        foreach ($coverage as $file => $lines) {
            $coverageStr = serialize($lines);
            $relativeFilename = self::ltrim(getcwd() . '/', $file);
            $sql = "insert into coverage (name, coverage) values ('$relativeFilename', '$coverageStr')";
            # if this fails, check you have write permission
            $this->db->queryExec($sql);
        }
    }

    function read() {
        $coverage = array_flip($this->getFilenames());
        foreach($coverage as $file => $garbage) {
            $coverage[$file] = $this->readFile($file);
        }
        return $coverage;
    }

    function &readFile($file) {
        $sql = "select coverage from coverage where name = '$file'";
        $aggregate = array();
        $result = $this->db->query($sql);
        while ($result->valid()) {
            $row = $result->current();
            $this->aggregateCoverage($aggregate, unserialize($row[0]));
            $result->next();
        }

        return $aggregate;
    }

    function aggregateCoverage(&$total, $next) {
        foreach ($next as $lineno => $code) {
            if (!isset($total[$lineno])) {
                $total[$lineno] = $code;
            } else {
                $total[$lineno] = $this->aggregateCoverageCode($total[$lineno], $code);
            }
        }
    }

    function aggregateCoverageCode($code1, $code2) {
        switch($code1) {
            case -2: return -2;
            case -1: return $code2;
            default:
                switch ($code2) {
                    case -2: return -2;
                    case -1: return $code1;
                }
        }
        return $code1 + $code2;
    }

    static function ltrim($cruft, $pristine) {
        if(stripos($pristine, $cruft) === 0) {
            return substr($pristine, strlen($cruft));
        }
        return $pristine;
    }

    function writeUntouchedFile($file) {
        $relativeFile = CoverageDataHandler::ltrim('./', $file);
        $sql = "insert into untouched values ('$relativeFile')";
        $this->db->queryExec($sql);
    }

    function &readUntouchedFiles() {
        $untouched = array();
        $result = $this->db->query("select filename from untouched order by filename");
        while ($result->valid()) {
            $row = $result->current();
            $untouched[] = $row[0];
            $result->next();
        }

        return $untouched;
    }
}
?>