DtaResult.php 8.58 KB
Newer Older
1
<?php
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16

Lückemeyer's avatar
Lückemeyer committed
17
18
19
20
21
22
23
/**
 * entity classes for DTA submission plugin result summary and test results
 *
 * @package assignsubmission_dta
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @copyright Gero Lueckemeyer and student project teams
 */
24
25
defined('MOODLE_INTERNAL') || die();

Lückemeyer's avatar
Lückemeyer committed
26
27
28
29
30
31
32
/**
 * entity class for DTA submission plugin result
 *
 * @package assignsubmission_dta
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @copyright Gero Lueckemeyer and student project teams
 */
33
34
class DtaResult {

Lückemeyer's avatar
Lückemeyer committed
35
    /**
Lückemeyer's avatar
Lückemeyer committed
36
37
     * Broadly used in logic, parametrized for easier change.
     */
38
39
    const COMPONENT_NAME = "assignsubmission_dta";

Lückemeyer's avatar
Lückemeyer committed
40
41
    /**
     * @var $packagename Package name of the test.
Lückemeyer's avatar
Lückemeyer committed
42
     */
43
    public $packagename;
Lückemeyer's avatar
Lückemeyer committed
44
45
46

    /**
     * @var $classname Unit name of the test.
Lückemeyer's avatar
Lückemeyer committed
47
     */
48
    public $classname;
Lückemeyer's avatar
Lückemeyer committed
49
50
51

    /**
     * @var $name Name of the test.
Lückemeyer's avatar
Lückemeyer committed
52
     */
53
54
55
    public $name;

    /**
Lückemeyer's avatar
Lückemeyer committed
56
     * @var $state State is defined like below
57
58
59
60
61
62
63
64
     *
     *  0 UNKNOWN
     *  1 SUCCESS
     *  2 FAILURE
     *  3 COMPILATIONERROR
     */
    public $state;

Lückemeyer's avatar
Lückemeyer committed
65
66
    /**
     * @var $failuretype Type of test failure if applicable, "" otherwise.
Lückemeyer's avatar
Lückemeyer committed
67
     */
68
    public $failuretype;
Lückemeyer's avatar
Lückemeyer committed
69
70
71

    /**
     * @var $failurereason Reason of test failure if applicable, "" otherwise.
72
     */
73
    public $failurereason;
Lückemeyer's avatar
Lückemeyer committed
74
75
76
77

    /**
     * @var $stacktrace Stack trace of test failure if applicable, "" otherwise.
     */
78
79
    public $stacktrace;

Lückemeyer's avatar
Lückemeyer committed
80
81
82
    /**
     * @var $columnnumber Column number of compile failure if applicable, "" otherwise.
     */
83
    public $columnnumber;
Lückemeyer's avatar
Lückemeyer committed
84
85
86
    /**
     * @var $linenumber Line number of compile failure if applicable, "" otherwise.
     */
87
    public $linenumber;
Lückemeyer's avatar
Lückemeyer committed
88
89
90
    /**
     * @var $position Position of compile failure if applicable, "" otherwise.
     */
91
92
93
    public $position;

    /**
Lückemeyer's avatar
Lückemeyer committed
94
     * Returns the name of a state with the given number of display.
95
96
     * @param int $state number of the state
     * @return string name of state as defined
97
     */
98
    public static function getstatename(int $state): string {
99
        if ($state == 1) {
100
            return get_string("tests_successful", self::COMPONENT_NAME);
101
        } else if ($state == 2) {
102
            return get_string("failures", self::COMPONENT_NAME);
103
        } else if ($state == 3) {
104
            return get_string("compilation_errors", self::COMPONENT_NAME);
105
        } else {
106
            return get_string("unknown_state", self::COMPONENT_NAME);
107
108
109
110
        }
    }
}

Lückemeyer's avatar
Lückemeyer committed
111
112
113
114
115
116
117
/**
 * entity class for DTA submission plugin result
 *
 * @package assignsubmission_dta
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @copyright Gero Lueckemeyer and student project teams
 */
118
119
class DtaResultSummary {

Lückemeyer's avatar
Lückemeyer committed
120
121
    /**
     * @var $timestamp Result timestamp for chronological ordering and deletion of previous results.
122
     */
123
    public $timestamp;
Lückemeyer's avatar
Lückemeyer committed
124
125
126
127

    /**
     * @var $globalstacktrace Global stack trace if applicable, "" otherwise.
     */
128
    public $globalstacktrace;
Lückemeyer's avatar
Lückemeyer committed
129
130
131
132

    /**
     * @var $successfultestcompetencies Successfully tested competencies according to tests and weights, "" otherwise.
     */
133
    public $successfultestcompetencies;
Lückemeyer's avatar
Lückemeyer committed
134
135
136
    /**
     * @var overalltestcompetencies Overall tested competencies according to tests and weights, "" otherwise.
     */
137
    public $overalltestcompetencies;
Lückemeyer's avatar
Lückemeyer committed
138
139
140
    /**
     * @var results List of detail results.
     */
141
142
143
    public $results;

    /**
Lückemeyer's avatar
Lückemeyer committed
144
     * Decodes the JSON result summary returned by the backend service call into the plugin PHP data structure.
Lückemeyer's avatar
Lückemeyer committed
145
     * @param string $jsonstring jsonString containing DtaResultSummary
Lückemeyer's avatar
Lückemeyer committed
146
     * @return DtaResultSummary the result summary
147
     */
Lückemeyer's avatar
Lückemeyer committed
148
    public static function decodejson(string $jsonstring): DtaResultSummary {
149
        $response = json_decode($jsonstring);
Kurzenberger's avatar
Kurzenberger committed
150
        
151
152
153

        $summary = new DtaResultSummary();
        $summary->timestamp = $response->timestamp;
154
        $summary->globalstacktrace = $response->globalstacktrace;
155

156
157
        $summary->successfultestcompetencies = $response->successfulTestCompetencyProfile;
        $summary->overalltestcompetencies = $response->overallTestCompetencyProfile;
158

159
        $summary->results = self::decodejsonresultarray($response->results);
160
161
162
163

        return $summary;
    }

Kurzenberger's avatar
Kurzenberger committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
    public static function decodeJsonRecommendation(string $jsonstring): array {
        // Decode the JSON string into a PHP object
        $response = json_decode($jsonstring);
        error_log("decodeJsonRecommendation");
        error_log(print_r($response, true));

        
        // Initialize an empty array to store recommendations
        $recommendations = [];
    
        // Loop through the recommendations in the response
        if (!empty($response->recommendations)) {
            foreach ($response->recommendations as $recommendation) {
                // For each recommendation, create an associative array with the properties
                $recommendations[] = [
                    'topic' => $recommendation->topic ?? null,
                    'url' => $recommendation->exerciseName ?? null,
                    'exercise_name' => $recommendation->url ?? null,
                    'difficulty' => $recommendation->difficulty ?? null,
                    'score' => $recommendation->score ?? null
                ];
            }
        }
        error_log(print_r($recommendations,true));
        // Return the array of recommendations
        return $recommendations;
    }
    

193
    /**
Lückemeyer's avatar
Lückemeyer committed
194
     * Decodes the array of JSON detail results returned by the backend service call into the plugin PHP data structure.
Lückemeyer's avatar
Lückemeyer committed
195
     * @param array $jsonarray decoded json array of results array
196
197
     * @return array of DtaResult
     */
198
    private static function decodejsonresultarray($jsonarray): array {
199
        $ret = [];
200
        foreach ($jsonarray as $entry) {
201
            $value = new DtaResult();
202
203
            $value->packagename = $entry->packageName;
            $value->classname = $entry->className;
204
205
            $value->name = $entry->name;

206
207
            $value->state = $entry->state;

208
209
            $value->failuretype = $entry->failureType;
            $value->failurereason = $entry->failureReason;
210
211
            $value->stacktrace = $entry->stacktrace;

212
213
            $value->columnnumber = $entry->columnNumber;
            $value->linenumber = $entry->lineNumber;
214
215
216
217
218
219
220
            $value->position = $entry->position;

            $ret[] = $value;
        }
        return $ret;
    }

Lückemeyer's avatar
Lückemeyer committed
221

Lückemeyer's avatar
Lückemeyer committed
222
223
224
225
    /**
     * Returns the number of detail results attached to the summary.
     * @return int count of occurences
     */
226
227
228
229
    public function resultcount(): int {
        return count($this->results);
    }

230
    /**
Lückemeyer's avatar
Lückemeyer committed
231
     * Returns the number of detail results with the given state attached to the summary.
232
233
234
     * @param int $state state ordinal number
     * @return int count of occurences provided state has
     */
235
    public function stateoccurencecount(int $state): int {
236
        $num = 0;
237
        foreach ($this->results as $r) {
238
239
240
241
242
243
244
            if ($r->state == $state) {
                $num++;
            }
        }
        return $num;
    }

Lückemeyer's avatar
Lückemeyer committed
245
246
247
248
    /**
     * Returns the number of detail results with compilation errors attached to the summary.
     * @return int count of occurences
     */
249
250
    public function compilationerrorcount(): int {
        return $this->stateoccurencecount(3);
251
252
    }

Lückemeyer's avatar
Lückemeyer committed
253
254
255
256
    /**
     * Returns the number of detail results with test failures attached to the summary.
     * @return int count of occurences
     */
257
258
    public function failedcount(): int {
        return $this->stateoccurencecount(2);
259
260
    }

Lückemeyer's avatar
Lückemeyer committed
261
262
263
264
    /**
     * Returns the number of detail results with successful tests attached to the summary.
     * @return int count of occurences
     */
265
266
    public function successfulcount(): int {
        return $this->stateoccurencecount(1);
267
268
    }

Lückemeyer's avatar
Lückemeyer committed
269
270
271
272
    /**
     * Returns the number of detail results with an unknown result - mostly due to compile errors - attached to the summary.
     * @return int count of occurences
     */
273
274
    public function unknowncount(): int {
        return $this->stateoccurencecount(0);
275
276
277
    }

}