/** * Put the specified questions on the specified pages of a given quiz. * * The first row should be column names: * | question | page | maxmark | * The first two of those are required. The others are optional. * * question needs to uniquely match a question name. * page is a page number. Must start at 1, and on each following * row should be the same as the previous, or one more. * maxmark What the question is marked out of. Defaults to question.defaultmark. * * Then there should be a number of rows of data, one for each question you want to add. * * For backwards-compatibility reasons, specifying the column names is optional * (but strongly encouraged). If not specified, the columns are asseumed to be * | question | page | maxmark |. * * @param string $quizname the name of the quiz to add questions to. * @param TableNode $data information about the questions to add. * * @Given /^quiz "([^"]*)" contains the following questions:$/ */ public function quiz_contains_the_following_questions($quizname, TableNode $data) { global $CFG, $DB; require_once __DIR__ . '/../../editlib.php'; $quiz = $DB->get_record('quiz', array('name' => $quizname), '*', MUST_EXIST); // Deal with backwards-compatibility, optional first row. $firstrow = $data->getRow(0); if (!in_array('question', $firstrow) && !in_array('page', $firstrow)) { if (count($firstrow) == 2) { $headings = array('question', 'page'); } else { if (count($firstrow) == 3) { $headings = array('question', 'page', 'maxmark'); } else { throw new ExpectationException('When adding questions to a quiz, you should give 2 or three 3 things: ' . ' the question name, the page number, and optionally the maxiumum mark. ' . count($firstrow) . ' values passed.', $this->getSession()); } } $rows = $data->getRows(); array_unshift($rows, $headings); $data->setRows($rows); } // Add the questions. $lastpage = 0; foreach ($data->getHash() as $questiondata) { if (!array_key_exists('question', $questiondata)) { throw new ExpectationException('When adding questions to a quiz, ' . 'the question name column is required.', $this->getSession()); } if (!array_key_exists('page', $questiondata)) { throw new ExpectationException('When adding questions to a quiz, ' . 'the page number column is required.', $this->getSession()); } // Question id. $questionid = $DB->get_field('question', 'id', array('name' => $questiondata['question']), MUST_EXIST); // Page number. $page = clean_param($questiondata['page'], PARAM_INT); if ($page <= 0 || (string) $page !== $questiondata['page']) { throw new ExpectationException('The page number for question "' . $questiondata['question'] . '" must be a positive integer.', $this->getSession()); } if ($page < $lastpage || $page > $lastpage + 1) { throw new ExpectationException('When adding questions to a quiz, ' . 'the page number for each question must either be the same, ' . 'or one more, then the page number for the previous question.', $this->getSession()); } $lastpage = $page; // Max mark. if (!array_key_exists('maxmark', $questiondata) || $questiondata['maxmark'] === '') { $maxmark = null; } else { $maxmark = clean_param($questiondata['maxmark'], PARAM_FLOAT); if (!is_numeric($questiondata['maxmark']) || $maxmark < 0) { throw new ExpectationException('The max mark for question "' . $questiondata['question'] . '" must be a positive number.', $this->getSession()); } } // Add the question. quiz_add_quiz_question($questionid, $quiz, $page, $maxmark); } quiz_update_sumgrades($quiz); }
/** * @Given /^I create a simple Workbook to be tested$/ */ public function iCreateASimpleWorkbookToBeTested() { $this->iCreateAWorkbook(); $this->getSubcontext('sheet')->iCreateASheet(); $this->getSubcontext('style')->iCreateAStyleCollectionAndIUseIt(); $styleData = new TableNode(); $styleData->setRows([['name', 'color', 'size'], ['Verdana', 'ff0000', 14]]); $this->getSubcontext('style')->iAddAStyle('Font', 'current', $styleData); $this->getSubcontext('sheet')->iAddANewCell('Foo', "null", "current", "1,1"); $this->getSubcontext('sheet')->iCreateASheetAndIUseIt(); $this->getSubcontext('sheet')->iAddANewCell('Bar', "null", "current", "1,1"); $this->iAddAllSheetIntoTheWorkbook(); $this->iAddTheStylecollectionWithTheIndexIntoMyWorkbook("current"); }
/** * @Transform /^table:/ */ public function mockEmailInTable(TableNode $table) { if ($this->connection) { $rows = $table->getRows(); foreach ($rows as $index => $row) { foreach ($row as $key => $value) { if (preg_match('/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i', $value)) { $row[$key] = $this->mockEmail($value); } $rows[$index] = $row; } } $table->setRows($rows); } return $table; }
/** * Transformations for TableNode arguments. * * Transformations applicable to TableNode arguments should also * be applied, adding them in a different method for Behat API restrictions. * * @Transform /^table:(.*)/ * @param TableNode $tablenode * @return TableNode The transformed table */ public function tablenode_transformations(TableNode $tablenode) { // Walk through all values including the optional headers. $rows = $tablenode->getRows(); foreach ($rows as $rowkey => $row) { foreach ($row as $colkey => $value) { // Transforms vars into nasty strings. if (preg_match('/\\$NASTYSTRING(\\d)/', $rows[$rowkey][$colkey])) { $rows[$rowkey][$colkey] = $this->replace_nasty_strings($rows[$rowkey][$colkey]); } } } // Return the transformed TableNode. $tablenode->setRows($rows); return $tablenode; }
/** * Creates the specified element with relative time applied to field values. * More info about available elements in http://docs.moodle.org/dev/Acceptance_testing#Fixtures. * * @Given /^the following "(?P<element_string>(?:[^"]|\\")*)" exist with relative dates:$/ * * @throws Exception * @throws PendingException * @param string $elementname The name of the entity to add * @param TableNode $data */ public function the_following_exist($elementname, TableNode $data) { global $CFG; require_once $CFG->dirroot . '/lib/testing/generator/lib.php'; $dg = new behat_data_generators(); $tablemode = method_exists($data, 'getTable'); $table = $tablemode ? $data->getTable() : $data->getRows(); foreach ($table as $rkey => $row) { $r = 0; foreach ($row as $key => $val) { $r++; if ($r > 1) { $val = preg_replace_callback('/(?:the|a) timestamp of (.*)$/', function ($match) { return strtotime($match[1]); }, $val); } $row[$key] = $val; } $rows[$rkey] = $row; } if ($tablemode) { $data = new TableNode($rows); } else { $data->setRows($rows); } $dg->the_following_exist($elementname, $data); }
/** * Creates a new course with the provided table data matching course settings names with the desired values. * * @Given /^I create a course with:$/ * @param TableNode $table The course data * @return Given[] */ public function i_create_a_course_with(TableNode $table) { $steps = array(new Given('I go to the courses management page'), new Given('I should see the "' . get_string('categories') . '" management page'), new Given('I click on category "' . get_string('miscellaneous') . '" in the management interface'), new Given('I should see the "' . get_string('categoriesandcoures') . '" management page'), new Given('I click on "' . get_string('createnewcourse') . '" "link" in the "#course-listing" "css_element"')); // If the course format is one of the fields we change how we // fill the form as we need to wait for the form to be set. $rowshash = $table->getRowsHash(); $formatfieldrefs = array(get_string('format'), 'format', 'id_format'); foreach ($formatfieldrefs as $fieldref) { if (!empty($rowshash[$fieldref])) { $formatfield = $fieldref; } } // Setting the format separately. if (!empty($formatfield)) { // Removing the format field from the TableNode. $rows = $table->getRows(); $formatvalue = $rowshash[$formatfield]; foreach ($rows as $key => $row) { if ($row[0] == $formatfield) { unset($rows[$key]); } } $table->setRows($rows); // Adding a forced wait until editors are loaded as otherwise selenium sometimes tries clicks on the // format field when the editor is being rendered and the click misses the field coordinates. $steps[] = new Given('I expand all fieldsets'); $steps[] = new Given('I set the field "' . $formatfield . '" to "' . $formatvalue . '"'); $steps[] = new Given('I set the following fields to these values:', $table); } else { $steps[] = new Given('I set the following fields to these values:', $table); } $steps[] = new Given('I press "' . get_string('savechanges') . '"'); return $steps; }