76a4d258699d8a01e6a0511fb82ab73719e1f922
[moodle.git] / lib / behat / classes / behat_command.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Behat command utils
19  *
20  * @package    core
21  * @category   test
22  * @copyright  2012 David MonllaĆ³
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 require_once(__DIR__ . '/../lib.php');
30 /**
31  * Behat command related utils
32  *
33  * @package    core
34  * @category   test
35  * @copyright  2013 David MonllaĆ³
36  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
38 class behat_command {
40     /**
41      * Docs url
42      */
43     const DOCS_URL = 'http://docs.moodle.org/dev/Acceptance_testing';
45     /**
46      * Ensures the behat dir exists in moodledata
47      * @return string Full path
48      */
49     public static function get_behat_dir() {
50         global $CFG;
52         $behatdir = $CFG->behat_dataroot . '/behat';
54         if (!is_dir($behatdir)) {
55             if (!mkdir($behatdir, $CFG->directorypermissions, true)) {
56                 behat_error(BEHAT_EXITCODE_PERMISSIONS, 'Directory ' . $behatdir . ' can not be created');
57             }
58         }
60         if (!is_writable($behatdir)) {
61             behat_error(BEHAT_EXITCODE_PERMISSIONS, 'Directory ' . $behatdir . ' is not writable');
62         }
64         return $behatdir;
65     }
67     /**
68      * Returns the executable path
69      *
70      * Allows returning a customized command for cygwin when the
71      * command is just displayed, when using exec(), system() and
72      * friends we stay with DIRECTORY_SEPARATOR as they use the
73      * normal cmd.exe (in Windows).
74      *
75      * @param  bool $custombyterm  If the provided command should depend on the terminal where it runs
76      * @return string
77      */
78     public final static function get_behat_command($custombyterm = false) {
80         $separator = DIRECTORY_SEPARATOR;
81         $exec = 'behat';
83         // Cygwin uses linux-style directory separators.
84         if ($custombyterm && testing_is_cygwin()) {
85             $separator = '/';
87             // MinGW can not execute .bat scripts.
88             if (!testing_is_mingw()) {
89                 $exec = 'behat.bat';
90             }
91         }
92         return 'vendor' . $separator . 'bin' . $separator . $exec;
93     }
95     /**
96      * Runs behat command with provided options
97      *
98      * Execution continues when the process finishes
99      *
100      * @param  string $options  Defaults to '' so tests would be executed
101      * @return array            CLI command outputs [0] => string, [1] => integer
102      */
103     public final static function run($options = '') {
104         global $CFG;
106         $currentcwd = getcwd();
107         chdir($CFG->dirroot);
108         exec(self::get_behat_command() . ' ' . $options, $output, $code);
109         chdir($currentcwd);
111         return array($output, $code);
112     }
114     /**
115      * Checks if behat is set up and working
116      *
117      * Uses notice() instead of behat_error() because is
118      * also called from web interface
119      *
120      * It checks behat dependencies have been installed and runs
121      * the behat help command to ensure it works as expected
122      *
123      * @return int Error code or 0 if all ok
124      */
125     public static function behat_setup_problem() {
126         global $CFG;
128         $clibehaterrorstr = "Behat dependencies not installed. Ensure you ran the composer installer. " . self::DOCS_URL . "#Installation\n";
130         // Moodle setting.
131         if (!self::are_behat_dependencies_installed()) {
134             // With HTML.
135             if (!CLI_SCRIPT) {
137                 $msg = get_string('wrongbehatsetup', 'tool_behat');
138                 $docslink = self::DOCS_URL . '#Installation';
139                 $docslink = html_writer::tag('a', $docslink, array('href' => $docslink, 'target' => '_blank'));
140                 $msg .= get_string('moreinfoin', 'tool_behat', $docslink);
141             } else {
142                 $msg = $clibehaterrorstr;
143             }
145             self::output_msg($msg);
146             return BEHAT_EXITCODE_COMPOSER;
147         }
149         // Behat test command.
150         list($output, $code) = self::run(' --help');
152         if ($code != 0) {
153             // Returning composer error code to avoid conflicts with behat and moodle error codes.
154             if (!CLI_SCRIPT) {
155                 $msg = get_string('wrongbehatsetup', 'tool_behat');
156             } else {
157                 $msg = $clibehaterrorstr;
158             }
159             self::output_msg($msg);
160             return BEHAT_EXITCODE_COMPOSER;
161         }
163         // Checking behat dataroot existence otherwise echo about admin/tool/behat/cli/init.php.
164         if (!empty($CFG->behat_dataroot)) {
165             $CFG->behat_dataroot = realpath($CFG->behat_dataroot);
166         }
167         if (empty($CFG->behat_dataroot) || !is_dir($CFG->behat_dataroot) || !is_writable($CFG->behat_dataroot)) {
168             self::output_msg(get_string('runclitool', 'tool_behat', 'php admin/tool/behat/cli/init.php'));
169             return BEHAT_EXITCODE_CONFIG;
170         }
172         return 0;
173     }
175     /**
176      * Has the site installed composer with --dev option
177      * @return bool
178      */
179     public static function are_behat_dependencies_installed() {
180         if (!is_dir(__DIR__ . '/../../../vendor/behat')) {
181             return false;
182         }
183         return true;
184     }
186     /**
187      * Outputs a message.
188      *
189      * Used in CLI + web UI methods. Stops the
190      * execution in web.
191      *
192      * @param string $msg
193      * @return void
194      */
195     protected static function output_msg($msg) {
197         if (!CLI_SCRIPT) {
198             // General info about the tool purpose.
199             $msg = get_string('aim', 'tool_behat') . '<br /><br />' . $msg;
200             notice($msg);
201         } else {
202             echo $msg;
203         }
204     }