From 496f03965f62569a072f44ad7275f79f1997659d Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Fri, 13 Dec 2013 19:08:54 +0200 Subject: [PATCH 001/204] Integration with Scrutinizer CI 1. adding configuration file 2. replacing external references to Drupal coding standards with local copy 3. adding badge to repo homepage 4. send code coverage information --- .scrutinizer.yml | 22 ++++ .travis.yml | 4 +- CodingStandard/Sniffs/Array/ArraySniff.php | 94 +++++++++++++++ .../Classes/ClassCreateInstanceSniff.php | 71 +++++++++++ .../ControlSignatureSniff.php | 72 ++++++++++++ .../Sniffs/ControlStructures/ElseIfSniff.php | 80 +++++++++++++ .../Sniffs/Formatting/ItemAssignmentSniff.php | 111 ++++++++++++++++++ .../Sniffs/Formatting/SpaceOperatorSniff.php | 77 ++++++++++++ .../Formatting/SpaceUnaryOperatorSniff.php | 71 +++++++++++ .../Strings/ConcatenationSpacingSniff.php | 92 +++++++++++++++ CodingStandard/ruleset.xml | 21 ++-- README.md | 1 + 12 files changed, 706 insertions(+), 10 deletions(-) create mode 100644 .scrutinizer.yml create mode 100644 CodingStandard/Sniffs/Array/ArraySniff.php create mode 100644 CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php create mode 100644 CodingStandard/Sniffs/ControlStructures/ControlSignatureSniff.php create mode 100644 CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php create mode 100644 CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php create mode 100644 CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php create mode 100644 CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php create mode 100644 CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php diff --git a/.scrutinizer.yml b/.scrutinizer.yml new file mode 100644 index 0000000..23c31cd --- /dev/null +++ b/.scrutinizer.yml @@ -0,0 +1,22 @@ +filter: + excluded_paths: + - 'vendor/*' + paths: + - 'library/*' + - 'tests/*' + +tools: + php_cpd: true + + php_pdepend: + excluded_dirs: [vendor] + + php_code_sniffer: + enabled: true + config: + tab_width: 0 + standard: custom + ruleset: CodingStandard + + external_code_coverage: + timeout: 600 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index b645438..315a40b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,6 @@ script: - phpunit -v --coverage-clover build/logs/clover.xml after_script: - - php vendor/bin/coveralls -v \ No newline at end of file + - php vendor/bin/coveralls -v + - wget https://scrutinizer-ci.com/ocular.phar + - php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml \ No newline at end of file diff --git a/CodingStandard/Sniffs/Array/ArraySniff.php b/CodingStandard/Sniffs/Array/ArraySniff.php new file mode 100644 index 0000000..895d7b5 --- /dev/null +++ b/CodingStandard/Sniffs/Array/ArraySniff.php @@ -0,0 +1,94 @@ + + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +/** + * CodingStandard_Sniffs_Array_ArraySniff. + * + * Checks if the array's are styled in the Drupal way. + * - Comma after the last array element + * + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_Array_ArraySniff implements PHP_CodeSniffer_Sniff +{ + + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return array(T_ARRAY); + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the + * stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + + $tokens = $phpcsFile->getTokens(); + $this->sniffItemClosings($phpcsFile, $stackPtr, $tokens); + + }//end process() + + /** + * Checks if the last item in the array is closed with a comma + * If the array is written on one line there must also be a space + * after the comma + * + * @param $tokens + */ + function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens){ + $lastItem = $phpcsFile->findPrevious( + array(T_WHITESPACE), + $tokens[$stackPtr]['parenthesis_closer']-1, + $stackPtr, + true + ); + + //empty array + if ($lastItem == $tokens[$stackPtr]['parenthesis_opener'] ) { + return; + } + //Inline array + $isInlineArray = $tokens[$tokens[$stackPtr]['parenthesis_opener']]['line'] == $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line']; + + //Check if the last item in a multiline array has a "closing" comma. + if ($tokens[$lastItem]['code'] !== T_COMMA && !$isInlineArray) { + $phpcsFile->addWarning('A comma should follow the last multiline array item. Found: ' . $tokens[$lastItem]['content'], $lastItem); + return; + } + + if($tokens[$lastItem]['code'] == T_COMMA && $isInlineArray){ + $phpcsFile->addWarning('Last item of an inline array must not followed by a comma', $lastItem); + return; + } + } + + +}//end class + +?> diff --git a/CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php b/CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php new file mode 100644 index 0000000..9f71fc9 --- /dev/null +++ b/CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php @@ -0,0 +1,71 @@ + + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +/** + * Class create instance Test. + * + * Checks the declaration of the class is correct. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_Classes_ClassCreateInstanceSniff implements PHP_CodeSniffer_Sniff +{ + + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return array( + T_NEW, + ); + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the + * stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + $nextParenthesis = $phpcsFile->findNext(array(T_OPEN_PARENTHESIS,T_SEMICOLON), $stackPtr, null, false, null, true); + if ($tokens[$nextParenthesis]['code'] != T_OPEN_PARENTHESIS || $tokens[$nextParenthesis]['line'] != $tokens[$stackPtr]['line']) { + $error = 'Calling class constructors must always include parentheses'; + $phpcsFile->addError($error, $nextParenthesis); + return; + } + + if ($tokens[$nextParenthesis-1]['code'] == T_WHITESPACE) { + $error = 'Between the class name and the opening parenthesis spaces are not welcome'; + $phpcsFile->addError($error, $nextParenthesis-1); + return; + } + }//end process() + + +}//end class + +?> diff --git a/CodingStandard/Sniffs/ControlStructures/ControlSignatureSniff.php b/CodingStandard/Sniffs/ControlStructures/ControlSignatureSniff.php new file mode 100644 index 0000000..1057b89 --- /dev/null +++ b/CodingStandard/Sniffs/ControlStructures/ControlSignatureSniff.php @@ -0,0 +1,72 @@ + + * @author Marc McIntyre + * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) + * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence + * @version CVS: $Id: ControlSignatureSniff.php,v 1.7 2007/10/23 06:05:14 squiz Exp $ + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +if (class_exists('PHP_CodeSniffer_Standards_AbstractPatternSniff', true) === false) { + throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractPatternSniff not found'); +} + +/** + * Verifies that control statements conform to their coding standards. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Greg Sherwood + * @author Marc McIntyre + * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) + * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence + * @version Release: 1.2.0RC3 + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_ControlStructures_ControlSignatureSniff extends PHP_CodeSniffer_Standards_AbstractPatternSniff +{ + + + /** + * Constructs a PEAR_Sniffs_ControlStructures_ControlSignatureSniff. + */ + public function __construct() + { + parent::__construct(true); + + }//end __construct() + + + /** + * Returns the patterns that this test wishes to verify. + * + * @return array(string) + */ + protected function getPatterns() + { + return array( + 'do {EOL...} while (...);EOL', + 'while (...) {EOL', + 'switch (...) {EOL', + 'for (...) {EOL', + 'if (...) {EOL', + 'foreach (...) {EOL', + //'} else if (...) {EOL', + '}EOLelseif (...) {EOL', + '}EOLelse {EOL', + 'do {EOL', + ); + + }//end getPatterns() + + +}//end class + +?> diff --git a/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php b/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php new file mode 100644 index 0000000..ad340cc --- /dev/null +++ b/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php @@ -0,0 +1,80 @@ + + * @author Marc McIntyre + * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) + * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence + * @version CVS: $Id: ElseIfSniff.php,v 1.7 2007/10/23 06:05:14 squiz Exp $ + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +if (class_exists('PHP_CodeSniffer_Standards_AbstractPatternSniff', true) === false) { + throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractPatternSniff not found'); +} + +/** + * Verifies that control statements conform to their coding standards. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Greg Sherwood + * @author Marc McIntyre + * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) + * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence + * @version Release: 1.2.0RC3 + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_ControlStructures_ElseIfSniff implements PHP_CodeSniffer_Sniff +{ + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return array(T_ELSE); + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the + * stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + + $tokens = $phpcsFile->getTokens(); + + $nextNonWhiteSpace = $phpcsFile->findNext( + T_WHITESPACE, + $stackPtr + 1, + null, + true, + null, + true + ); + + if($tokens[$nextNonWhiteSpace]['code'] == T_IF){ + $phpcsFile->addError('Use "elseif" in place of "else if"', $nextNonWhiteSpace); + } + + + }//end process() + +}//end class + +?> diff --git a/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php b/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php new file mode 100644 index 0000000..ab85f1a --- /dev/null +++ b/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php @@ -0,0 +1,111 @@ + + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +/** + * CodingStandard_Sniffs_Formatting_ItemAssignmentSniff. + * + * Checks if the item assignemnt operator (=>) has + * - a space before and after + * + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_Formatting_ItemAssignmentSniff implements PHP_CodeSniffer_Sniff +{ + + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return array(T_DOUBLE_ARROW); + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the + * stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + + $tokens = $phpcsFile->getTokens(); + $this->sniffElementItemAssignmentOperator($phpcsFile, $stackPtr, $tokens); + + }//end process() + + /** + * Checks if there are spaces before and after the Assignment operators in the array + * + * Enter description here ... + * @param $tokens + */ + function sniffElementItemAssignmentOperator(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens) { + if ($tokens[$stackPtr - 1]['code'] !== T_WHITESPACE) { + $phpcsFile->addError('A whitespace must prefix the item assignment operator =>', $stackPtr); + } + if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { + $phpcsFile->addError('A whitespace must follow to the item assignemtn operator =>', $stackPtr); + } + } + + /** + * Checks if the last item in the array is closed with a comma + * If the array is written on one line there must also be a space + * after the comma + * + * @param $tokens + */ + function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens){ + $lastItem = $phpcsFile->findPrevious( + array(T_WHITESPACE), + $tokens[$stackPtr]['parenthesis_closer']-1, + $stackPtr, + true + ); + + //empty array + if ($lastItem == $tokens[$stackPtr]['parenthesis_opener'] ) { + return; + } + //Check if the last item in the array has a "closing" comma. + if ($tokens[$lastItem]['code'] !== T_COMMA) { + $phpcsFile->addWarning('A comma followed by a whitespace should follow the last array item. Found: ' . $tokens[$lastItem]['content'], $lastItem); + return; + } + + //If the closing parenthesis is on the + //same line as the last item there has to be a whitespace + //after the comma + if ($tokens[$lastItem]['line'] == $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line'] + && $tokens[$lastItem+1]['code'] !== T_WHITESPACE + ) { + $phpcsFile->addWarning('Afther the last comma in an array must be a whitespace', $lastItem); + return; + } + } + + +}//end class + +?> diff --git a/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php b/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php new file mode 100644 index 0000000..db35ff5 --- /dev/null +++ b/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php @@ -0,0 +1,77 @@ + + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +/** + * CodingStandard_Sniffs_Formatting_SpaceOperatorSniff. + * + * Ensures there is a single space after a operator + * + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @version Release: 1.2.2 + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_Formatting_SpaceOperatorSniff implements PHP_CodeSniffer_Sniff +{ + + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + $tokens = array_merge( + PHP_CodeSniffer_Tokens::$assignmentTokens, + PHP_CodeSniffer_Tokens::$equalityTokens, + PHP_CodeSniffer_Tokens::$comparisonTokens + ); + + return $tokens; + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in + * the stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE + || $tokens[($stackPtr + 1)]['content'] != ' ' + ) { + $error = 'A opeator statement must be followed by a single space'; + $phpcsFile->addError($error, $stackPtr); + } + if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE + || $tokens[($stackPtr - 1)]['content'] != ' ' + ) { + $error = 'There must be a single space befora a opeator statement'; + $phpcsFile->addError($error, $stackPtr); + } + + }//end process() + + +}//end class + +?> diff --git a/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php b/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php new file mode 100644 index 0000000..9c1dd50 --- /dev/null +++ b/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php @@ -0,0 +1,71 @@ + + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +/** + * CodingStandard_Sniffs_Formatting_SpaceUnaryOperatorSniff. + * + * Ensures there are no spaces on increment / decrement statements. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @version Release: 1.2.2 + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_Formatting_SpaceUnaryOperatorSniff implements PHP_CodeSniffer_Sniff +{ + + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return array(T_DEC, T_INC); + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in + * the stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + $modifyLeft = substr($tokens[($stackPtr - 1)]['content'], 0, 1) == '$' || + $tokens[($stackPtr + 1)]['content'] == ';'; + + if ($modifyLeft && $tokens[($stackPtr - 1)]['code'] === T_WHITESPACE) { + $error = 'There must not be a single space befora a unary opeator statement'; + $phpcsFile->addError($error, $stackPtr); + } + + if (!$modifyLeft && substr($tokens[($stackPtr + 1)]['content'], 0, 1) != '$') { + $error = 'A unary opeator statement must not followed by a single space'; + $phpcsFile->addError($error, $stackPtr); + } + + }//end process() + + +}//end class + +?> diff --git a/CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php b/CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php new file mode 100644 index 0000000..16164ab --- /dev/null +++ b/CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php @@ -0,0 +1,92 @@ + + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +/** + * CodingStandard_Sniffs_Strings_ConcatenationSpacingSniff. + * + * Makes sure there are the needed spaces between the concatenation operator (.) and + * the strings being concatenated. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_Strings_ConcatenationSpacingSniff implements PHP_CodeSniffer_Sniff +{ + + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return array(T_STRING_CONCAT); + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the + * stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + $found = ''; + $expected = ''; + $error = false; + + if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE) { + $expected .= '...'.substr($tokens[($stackPtr - 2)]['content'], -5).$tokens[$stackPtr]['content']; + $found .= '...'.substr($tokens[($stackPtr - 2)]['content'], -5).$tokens[($stackPtr - 1)]['content'].$tokens[$stackPtr]['content']; + $error = true; + } else { + $found .= '...'.substr($tokens[($stackPtr - 1)]['content'], -5).$tokens[$stackPtr]['content']; + $expected .= '...'.substr($tokens[($stackPtr - 1)]['content'], -5).$tokens[$stackPtr]['content']; + } + + if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE) { + $expected .= substr($tokens[($stackPtr + 2)]['content'], 0, 5).'...'; + $found .= $tokens[($stackPtr + 1)]['content'].substr($tokens[($stackPtr + 2)]['content'], 0, 5).'...'; + $error = true; + } else { + $found .= $tokens[($stackPtr + 1)]['content']; + $expected .= $tokens[($stackPtr + 1)]['content']; + } + + if ($error === true) { + $found = str_replace("\r\n", '\n', $found); + $found = str_replace("\n", '\n', $found); + $found = str_replace("\r", '\n', $found); + $expected = str_replace("\r\n", '\n', $expected); + $expected = str_replace("\n", '\n', $expected); + $expected = str_replace("\r", '\n', $expected); + + $message = "Concat operator must be surrounded by spaces. Found \"$found\"; expected \"$expected\""; + $phpcsFile->addError($message, $stackPtr); + } + + }//end process() + + +}//end class + +?> diff --git a/CodingStandard/ruleset.xml b/CodingStandard/ruleset.xml index f0bf8a5..ec165f4 100644 --- a/CodingStandard/ruleset.xml +++ b/CodingStandard/ruleset.xml @@ -20,6 +20,7 @@ + @@ -32,15 +33,17 @@ - - - - - - - - - + diff --git a/README.md b/README.md index 938e28d..bd4c1de 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # phpunit-mink [![Build Status](https://travis-ci.org/aik099/phpunit-mink.png?branch=master)](https://travis-ci.org/aik099/phpunit-mink) +[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/aik099/phpunit-mink/badges/quality-score.png?s=57e408500d59e10ce44b604df678ec8b59a1b8f8)](https://scrutinizer-ci.com/g/aik099/phpunit-mink/) [![Coverage Status](https://coveralls.io/repos/aik099/phpunit-mink/badge.png?branch=master)](https://coveralls.io/r/aik099/phpunit-mink?branch=master) [![Latest Stable Version](https://poser.pugx.org/aik099/phpunit-mink/v/stable.png)](https://packagist.org/packages/aik099/phpunit-mink) From a7c3742588e850c994730b8c0449982a15bd4f38 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Fri, 13 Dec 2013 19:19:50 +0200 Subject: [PATCH 002/204] Use composer installation from Travis box --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 315a40b..80a9fa4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,7 @@ php: - 5.5 before_script: - - curl http://getcomposer.org/installer | php - - php composer.phar require satooshi/php-coveralls:dev-master --dev --prefer-source + - composer require satooshi/php-coveralls:dev-master --dev --prefer-source script: - mkdir -p build/logs From 06aada5feefde44e870ecea57e396c1007c3dcbd Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 15 Dec 2013 10:22:28 +0200 Subject: [PATCH 003/204] Adding VersionEye badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index bd4c1de..f52d8a9 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Build Status](https://travis-ci.org/aik099/phpunit-mink.png?branch=master)](https://travis-ci.org/aik099/phpunit-mink) [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/aik099/phpunit-mink/badges/quality-score.png?s=57e408500d59e10ce44b604df678ec8b59a1b8f8)](https://scrutinizer-ci.com/g/aik099/phpunit-mink/) [![Coverage Status](https://coveralls.io/repos/aik099/phpunit-mink/badge.png?branch=master)](https://coveralls.io/r/aik099/phpunit-mink?branch=master) +[![Dependency Status](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049/badge.png)](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049) [![Latest Stable Version](https://poser.pugx.org/aik099/phpunit-mink/v/stable.png)](https://packagist.org/packages/aik099/phpunit-mink) [![Total Downloads](https://poser.pugx.org/aik099/phpunit-mink/downloads.png)](https://packagist.org/packages/aik099/phpunit-mink) From 5e50954b9fd141d40f2875b01267ace5b62cde49 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 28 Dec 2013 12:03:32 +0200 Subject: [PATCH 004/204] Use global Scrunitizer CI config. Adding Composer branch alias. --- .scrutinizer.yml | 22 ---------------------- composer.json | 6 ++++++ 2 files changed, 6 insertions(+), 22 deletions(-) delete mode 100644 .scrutinizer.yml diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 23c31cd..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,22 +0,0 @@ -filter: - excluded_paths: - - 'vendor/*' - paths: - - 'library/*' - - 'tests/*' - -tools: - php_cpd: true - - php_pdepend: - excluded_dirs: [vendor] - - php_code_sniffer: - enabled: true - config: - tab_width: 0 - standard: custom - ruleset: CodingStandard - - external_code_coverage: - timeout: 600 \ No newline at end of file diff --git a/composer.json b/composer.json index f1de000..13d5722 100644 --- a/composer.json +++ b/composer.json @@ -27,5 +27,11 @@ "psr-0": { "aik099\\": "./library/" } + }, + + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } } } From 0f8fb6bb818ee156aa56810577517f535a4dc4a7 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Mon, 3 Feb 2014 23:05:36 +0200 Subject: [PATCH 005/204] Extensibility improvements (public API kept the same) Things done: 1. connecting EventDispatcher 2. connection DIC 3. moving out object instantiation to dedicated factory classes 4. type hinting using interfaces Things left to do: 1. verify that in real life components do communicate through event dispatcher 2. upon browser configuration disposal remove it from event dispatcher 3. move "test case ended" event generation to test case class Related to #9 --- composer.json | 4 +- .../BrowserConfiguration.php | 209 ++++++++------ .../BrowserConfigurationFactory.php | 87 ++++++ .../IBrowserConfigurationFactory.php | 39 +++ .../SauceLabsBrowserConfiguration.php | 132 +++++---- library/aik099/PHPUnit/BrowserTestCase.php | 116 ++++++-- library/aik099/PHPUnit/DIContainer.php | 146 ++++++++++ .../aik099/PHPUnit/Event/TestEndedEvent.php | 54 ++++ library/aik099/PHPUnit/Event/TestEvent.php | 67 +++++ .../aik099/PHPUnit/Event/TestFailedEvent.php | 50 ++++ .../aik099/PHPUnit/IEventDispatcherAware.php | 32 +++ .../aik099/PHPUnit/ITestApplicationAware.php | 29 ++ .../PHPUnit/Session/ISessionFactory.php | 35 +++ .../ISessionStrategy.php | 33 +-- .../Session/ISessionStrategyFactory.php | 31 ++ .../Session/IsolatedSessionStrategy.php | 98 +++++++ .../aik099/PHPUnit/Session/SessionFactory.php | 64 +++++ .../Session/SessionStrategyFactory.php | 65 +++++ .../SessionStrategyManager.php | 90 ++---- .../SharedSessionStrategy.php | 121 ++++---- .../IsolatedSessionStrategy.php | 80 ------ library/aik099/PHPUnit/TestApplication.php | 98 +++++++ library/aik099/PHPUnit/TestSuite.php | 73 ----- .../PHPUnit/TestSuite/AbstractTestSuite.php | 122 ++++++++ .../BrowserTestSuite.php} | 28 +- .../PHPUnit/TestSuite/RegularTestSuite.php | 21 ++ .../PHPUnit/TestSuite/TestSuiteBuilder.php | 142 +++++++++ library/aik099/PHPUnit/TestSuiteBase.php | 93 ------ .../BrowserConfigurationFactoryTest.php | 107 +++++++ .../BrowserConfigurationTest.php | 271 +++++++++--------- .../SauceLabsBrowserConfigurationTest.php | 177 +++++++----- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 147 ++++++---- .../PHPUnit/Event/TestEndedEventTest.php | 58 ++++ tests/aik099/PHPUnit/Event/TestEventTest.php | 87 ++++++ .../PHPUnit/Event/TestFailedEventTest.php | 59 ++++ .../Session/IsolatedSessionStrategyTest.php | 91 ++++++ .../PHPUnit/Session/SessionFactoryTest.php | 59 ++++ .../Session/SessionStrategyFactoryTest.php | 82 ++++++ .../Session/SessionStrategyManagerTest.php | 144 ++++++++++ .../Session/SessionStrategyTestCase.php | 54 ++++ .../Session/SharedSessionStrategyTest.php | 189 ++++++++++++ .../IsolatedSessionStrategyTest.php | 129 --------- .../SessionStrategyManagerTest.php | 146 ---------- .../SharedSessionStrategyTest.php | 169 ----------- tests/aik099/PHPUnit/SuiteBuildingTest.php | 14 +- .../TestCase/TestApplicationAwareTestCase.php | 53 ++++ 46 files changed, 2888 insertions(+), 1307 deletions(-) create mode 100644 library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php create mode 100644 library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php create mode 100644 library/aik099/PHPUnit/DIContainer.php create mode 100644 library/aik099/PHPUnit/Event/TestEndedEvent.php create mode 100644 library/aik099/PHPUnit/Event/TestEvent.php create mode 100644 library/aik099/PHPUnit/Event/TestFailedEvent.php create mode 100644 library/aik099/PHPUnit/IEventDispatcherAware.php create mode 100644 library/aik099/PHPUnit/ITestApplicationAware.php create mode 100644 library/aik099/PHPUnit/Session/ISessionFactory.php rename library/aik099/PHPUnit/{SessionStrategy => Session}/ISessionStrategy.php (57%) create mode 100644 library/aik099/PHPUnit/Session/ISessionStrategyFactory.php create mode 100644 library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php create mode 100644 library/aik099/PHPUnit/Session/SessionFactory.php create mode 100644 library/aik099/PHPUnit/Session/SessionStrategyFactory.php rename library/aik099/PHPUnit/{SessionStrategy => Session}/SessionStrategyManager.php (50%) rename library/aik099/PHPUnit/{SessionStrategy => Session}/SharedSessionStrategy.php (50%) delete mode 100644 library/aik099/PHPUnit/SessionStrategy/IsolatedSessionStrategy.php create mode 100644 library/aik099/PHPUnit/TestApplication.php delete mode 100644 library/aik099/PHPUnit/TestSuite.php create mode 100644 library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php rename library/aik099/PHPUnit/{BrowserSuite.php => TestSuite/BrowserTestSuite.php} (63%) create mode 100644 library/aik099/PHPUnit/TestSuite/RegularTestSuite.php create mode 100644 library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php delete mode 100644 library/aik099/PHPUnit/TestSuiteBase.php create mode 100644 tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php create mode 100644 tests/aik099/PHPUnit/Event/TestEndedEventTest.php create mode 100644 tests/aik099/PHPUnit/Event/TestEventTest.php create mode 100644 tests/aik099/PHPUnit/Event/TestFailedEventTest.php create mode 100644 tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php create mode 100644 tests/aik099/PHPUnit/Session/SessionFactoryTest.php create mode 100644 tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php create mode 100644 tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php create mode 100644 tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php create mode 100644 tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php delete mode 100644 tests/aik099/PHPUnit/SessionStrategy/IsolatedSessionStrategyTest.php delete mode 100644 tests/aik099/PHPUnit/SessionStrategy/SessionStrategyManagerTest.php delete mode 100644 tests/aik099/PHPUnit/SessionStrategy/SharedSessionStrategyTest.php create mode 100644 tests/aik099/PHPUnit/TestCase/TestApplicationAwareTestCase.php diff --git a/composer.json b/composer.json index 13d5722..6aa351a 100644 --- a/composer.json +++ b/composer.json @@ -14,8 +14,8 @@ "require": { "php": ">=5.3.2", - "behat/mink": "1.5.*", - "behat/mink-selenium2-driver": "*", + "symfony/event-dispatcher": "~2.4", + "pimple/pimple": "~2.0@dev", "phpunit/phpunit": "3.7.*" }, diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index c1bc544..452f929 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -12,16 +12,17 @@ use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\SessionStrategy\SessionStrategyManager; -use Behat\Mink\Driver\Selenium2Driver; -use Behat\Mink\Session; +use aik099\PHPUnit\IEventDispatcherAware; +use aik099\PHPUnit\Session\SessionStrategyManager; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Browser configuration for browser. * * @method \Mockery\Expectation shouldReceive */ -class BrowserConfiguration +class BrowserConfiguration implements EventSubscriberInterface, IEventDispatcherAware { /** @@ -39,11 +40,50 @@ class BrowserConfiguration protected $aliases; /** - * Creates browser configuration. + * Test case. * - * @param array $aliases Browser configuration aliases. + * @var BrowserTestCase + */ + private $_testCase; + + /** + * Event dispatcher. + * + * @var EventDispatcherInterface + */ + private $_eventDispatcher; + + /** + * Resolves browser alias into corresponding browser configuration. + * + * @param array $parameters Browser configuration. + * @param array $aliases Browser configuration aliases. + * + * @return array + * @throws \InvalidArgumentException When unable to resolve used browser alias. */ - public function __construct(array $aliases = array()) + public static function resolveAliases(array $parameters, array $aliases) + { + if ( !isset($parameters['alias']) ) { + return $parameters; + } + + $browser_alias = $parameters['alias']; + unset($parameters['alias']); + + if ( isset($aliases[$browser_alias]) ) { + $candidate_params = self::arrayMergeRecursive($aliases[$browser_alias], $parameters); + + return self::resolveAliases($candidate_params, $aliases); + } + + throw new \InvalidArgumentException(sprintf('Unable to resolve "%s" browser alias', $browser_alias)); + } + + /** + * Creates browser configuration. + */ + public function __construct() { $this->parameters = array( // server related @@ -59,7 +99,67 @@ public function __construct(array $aliases = array()) // test related 'sessionStrategy' => SessionStrategyManager::ISOLATED_STRATEGY, ); + } + + /** + * Returns an array of event names this subscriber wants to listen to. + * + * @return array The event names to listen to + */ + public static function getSubscribedEvents() + { + return array(); + } + + /** + * Sets event dispatcher. + * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * + * @return void + */ + public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) + { + $this->_eventDispatcher = $event_dispatcher; + } + /** + * Attaches listeners. + * + * @param BrowserTestCase $test_case Test case. + * + * @return void + */ + public function attachToTestCase(BrowserTestCase $test_case) + { + $this->_testCase = $test_case; + $this->_eventDispatcher->addSubscriber($this); + } + + /** + * Returns associated test case. + * + * @return BrowserTestCase + * @throws \RuntimeException When test case not attached. + */ + public function getTestCase() + { + if ( $this->_testCase === null ) { + throw new \RuntimeException('Test Case not attached, use "attachToTestCase" method'); + } + + return $this->_testCase; + } + + /** + * Sets aliases. + * + * @param array $aliases Browser configuration aliases. + * + * @return void + */ + public function setAliases(array $aliases = array()) + { $this->aliases = $aliases; } @@ -72,7 +172,7 @@ public function __construct(array $aliases = array()) */ public function setup(array $parameters) { - $parameters = array_merge($this->parameters, self::resolveAliases($parameters, $this->aliases)); + $parameters = $this->prepareParameters($parameters); $this->setHost($parameters['host'])->setPort($parameters['port'])->setTimeout($parameters['timeout']); $this->setBrowserName($parameters['browserName'])->setDesiredCapabilities($parameters['desiredCapabilities']); @@ -82,6 +182,18 @@ public function setup(array $parameters) return $this; } + /** + * Merges together default, given parameter and resolves aliases along the way. + * + * @param array $parameters Browser configuration parameters. + * + * @return array + */ + protected function prepareParameters(array $parameters) + { + return array_merge($this->parameters, self::resolveAliases($parameters, $this->aliases)); + } + /** * Sets hostname to browser configuration. * @@ -308,16 +420,14 @@ public function isShared() /** * Returns session strategy hash based on given test case and current browser configuration. * - * @param BrowserTestCase $test_case Test case. - * * @return integer */ - public function getSessionStrategyHash(BrowserTestCase $test_case) + public function getSessionStrategyHash() { $ret = $this->getBrowserHash(); if ( $this->isShared() ) { - $ret .= '::' . get_class($test_case); + $ret .= '::' . get_class($this->getTestCase()); } return $ret; @@ -356,56 +466,6 @@ protected function getBrowserHash() return crc32(serialize($this->parameters)); } - /** - * Creates new session based on browser configuration. - * - * @return Session - */ - public function createSession() - { - $capabilities = $this->getDesiredCapabilities(); - $capabilities['browserName'] = $this->getBrowserName(); - - // TODO: maybe doesn't work - ini_set('default_socket_timeout', $this->getTimeout()); - - // create driver: - $driver = new Selenium2Driver( - $this->getBrowserName(), - $capabilities, - 'http://' . $this->getHost() . ':' . $this->getPort() . '/wd/hub' - ); - - return new Session($driver); - } - - /** - * Resolves browser alias into corresponding browser configuration. - * - * @param array $parameters Browser configuration. - * @param array $aliases Browser configuration aliases. - * - * @return array - * @throws \InvalidArgumentException When unable to resolve used browser alias. - */ - public static function resolveAliases(array $parameters, array $aliases) - { - if ( !isset($parameters['alias']) ) { - return $parameters; - } - - $browser_alias = $parameters['alias']; - unset($parameters['alias']); - - if ( isset($aliases[$browser_alias]) ) { - $candidate_params = self::arrayMergeRecursive($aliases[$browser_alias], $parameters); - - return self::resolveAliases($candidate_params, $aliases); - } - - throw new \InvalidArgumentException(sprintf('Unable to resolve "%s" browser alias', $browser_alias)); - } - /** * Similar to array_merge_recursive but keyed-valued are always overwritten. * @@ -434,29 +494,4 @@ protected static function arrayMergeRecursive($array1, $array2) return $array1; } - /** - * Hook, called from "BrowserTestCase::setUp" method. - * - * @param BrowserTestCase $test_case Browser test case. - * - * @return self - */ - public function testSetUpHook(BrowserTestCase $test_case) - { - return $this; - } - - /** - * Hook, called from "BrowserTestCase::run" method. - * - * @param BrowserTestCase $test_case Browser test case. - * @param \PHPUnit_Framework_TestResult $test_result Test result. - * - * @return self - */ - public function testAfterRunHook(BrowserTestCase $test_case, \PHPUnit_Framework_TestResult $test_result) - { - return $this; - } - } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php new file mode 100644 index 0000000..6b1bb9b --- /dev/null +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php @@ -0,0 +1,87 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\BrowserConfiguration; + + +use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\ITestApplicationAware; +use aik099\PHPUnit\TestApplication; +use WebDriver\SauceLabs\SauceRest; + +class BrowserConfigurationFactory implements IBrowserConfigurationFactory, ITestApplicationAware +{ + + /** + * Application. + * + * @var TestApplication + */ + protected $application; + + /** + * Sets application. + * + * @param TestApplication $application The application. + * + * @return void + */ + public function setApplication(TestApplication $application) + { + $this->application = $application; + } + + /** + * Returns browser configuration instance. + * + * @param array $config Browser. + * @param BrowserTestCase $test_case Test case. + * + * @return BrowserConfiguration + */ + public function createBrowserConfiguration(array $config, BrowserTestCase $test_case) + { + $aliases = $test_case->getBrowserAliases(); + $config = BrowserConfiguration::resolveAliases($config, $aliases); + + /** @var BrowserConfiguration $browser */ + if ( isset($config['sauce']) ) { + $browser = $this->application->getObject('sauce_labs_browser_configuration'); + } + else { + $browser = $this->application->getObject('browser_configuration'); + } + + $browser->setAliases($aliases); + $browser->setup($config); + + return $browser; + } + + /** + * Creates API client. + * + * @param BrowserConfiguration $browser Browser configuration. + * + * @return \stdClass + * @throws \LogicException When unsupported browser configuration given. + */ + public function createAPIClient(BrowserConfiguration $browser) + { + if ( $browser instanceof SauceLabsBrowserConfiguration ) { + $sauce = $browser->getSauce(); + + return new SauceRest($sauce['username'], $sauce['api_key']); + } + + throw new \LogicException('Unsupported browser configuration given'); + } + +} diff --git a/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php new file mode 100644 index 0000000..ad1ec10 --- /dev/null +++ b/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php @@ -0,0 +1,39 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\BrowserConfiguration; + + +use aik099\PHPUnit\BrowserTestCase; + +interface IBrowserConfigurationFactory +{ + + /** + * Returns browser configuration instance. + * + * @param array $config Browser. + * @param BrowserTestCase $test_case Test case. + * + * @return BrowserConfiguration + */ + public function createBrowserConfiguration(array $config, BrowserTestCase $test_case); + + /** + * Creates API client. + * + * @param BrowserConfiguration $browser Browser configuration. + * + * @return \stdClass + * @throws \LogicException When unsupported browser configuration given. + */ + public function createAPIClient(BrowserConfiguration $browser); + +} diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 217c87b..cf538b9 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -12,9 +12,9 @@ use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\SessionStrategy\SessionStrategyManager; -use Behat\Mink\Driver\Selenium2Driver; -use WebDriver\SauceLabs\Capability as SauceLabsCapability; +use aik099\PHPUnit\Event\TestEndedEvent; +use aik099\PHPUnit\Event\TestEvent; +use Behat\Mink\Session; use WebDriver\SauceLabs\SauceRest; /** @@ -23,18 +23,50 @@ class SauceLabsBrowserConfiguration extends BrowserConfiguration { + /** + * The build number. + */ + const BUILD_NUMBER_CAPABILITY = 'build'; + + /** + * The test name. + */ + const NAME_CAPABILITY = 'name'; + + /** + * Browser configuration factory. + * + * @var IBrowserConfigurationFactory + */ + private $_browserConfigurationFactory; + /** * Creates browser configuration. * - * @param array $aliases Browser configuration aliases. + * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. */ - public function __construct(array $aliases = array()) + public function __construct(IBrowserConfigurationFactory $browser_configuration_factory) { - parent::__construct($aliases); + parent::__construct(); + $this->_browserConfigurationFactory = $browser_configuration_factory; $this->parameters['sauce'] = array('username' => '', 'api_key' => ''); } + /** + * Returns an array of event names this subscriber wants to listen to. + * + * @return array The event names to listen to + */ + public static function getSubscribedEvents() + { + $events = parent::getSubscribedEvents(); + $events[BrowserTestCase::TEST_SETUP_EVENT] = array('onTestSetup', 100); + $events[BrowserTestCase::TEST_ENDED_EVENT] = array('onTestEnded', 100); + + return $events; + } + /** * Initializes a browser with given configuration. * @@ -44,8 +76,8 @@ public function __construct(array $aliases = array()) */ public function setup(array $parameters) { - $parameters = array_merge($this->parameters, self::resolveAliases($parameters, $this->aliases)); - $this->setSauce($parameters['sauce']); + $prepared_parameters = $this->prepareParameters($parameters); + $this->setSauce($prepared_parameters['sauce']); return parent::setup($parameters); } @@ -140,90 +172,86 @@ public function getDesiredCapabilities() /** * Hook, called from "BrowserTestCase::setUp" method. * - * @param BrowserTestCase $test_case Browser test case. + * @param TestEvent $event Test event. * - * @return self + * @return void */ - public function testSetUpHook(BrowserTestCase $test_case) + public function onTestSetup(TestEvent $event) { $desired_capabilities = $this->getDesiredCapabilities(); - - $desired_capabilities[SauceLabsCapability::NAME] = $this->getJobName($test_case); + $desired_capabilities[self::NAME_CAPABILITY] = $this->getJobName($event->getTestCase()); $jenkins_build_number = getenv('BUILD_NUMBER'); if ( $jenkins_build_number ) { - $desired_capabilities[SauceLabsCapability::BUILD] = $jenkins_build_number; + $desired_capabilities[self::BUILD_NUMBER_CAPABILITY] = $jenkins_build_number; } $this->setDesiredCapabilities($desired_capabilities); - - return $this; } /** - * Hook, called from "BrowserTestCase::run" method. + * Returns Job name for "Sauce Labs" service. * - * @param BrowserTestCase $test_case Browser test case. - * @param \PHPUnit_Framework_TestResult $test_result Test result. + * @param BrowserTestCase $test_case Browser test case. * - * @return self + * @return string */ - public function testAfterRunHook(BrowserTestCase $test_case, \PHPUnit_Framework_TestResult $test_result) + protected function getJobName(BrowserTestCase $test_case) { - $passed = $this->getTestStatus($test_case, $test_result); - $this->getRestClient()->updateJob($this->getJobId($test_case), array('passed' => $passed)); + if ( $this->isShared() ) { + return get_class($test_case); + } - return $this; + return $test_case->toString(); } /** - * Get Selenium2 current session id. + * Hook, called from "BrowserTestCase::run" method. * - * @param BrowserTestCase $test_case Browser test case. + * @param TestEndedEvent $event Test ended event. * - * @return string - * @throws \RuntimeException When test case session was created using an unsupported driver. + * @return void */ - protected function getJobId(BrowserTestCase $test_case) + public function onTestEnded(TestEndedEvent $event) { - $driver = $test_case->getSession()->getDriver(); - - if ( $driver instanceof Selenium2Driver ) { - $wd_session = $driver->getWebDriverSession(); - - return $wd_session ? basename($wd_session->getUrl()) : ''; - } + $test_case = $event->getTestCase(); - throw new \RuntimeException('Unsupported session driver'); + $this->getAPIClient()->updateJob( + $this->getSessionId($test_case->getSession()), + array('passed' => $this->getTestStatus($test_case, $event->getTestResult())) + ); } /** - * Returns Job name for "Sauce Labs" service. - * - * @param BrowserTestCase $test_case Browser test case. + * Returns API class for "Sauce Labs" service interaction. * - * @return string + * @return SauceRest */ - protected function getJobName(BrowserTestCase $test_case) + protected function getAPIClient() { - if ( $this->isShared() ) { - return get_class($test_case); - } - - return $test_case->toString(); + return $this->_browserConfigurationFactory->createAPIClient($this); } /** - * Returns API class for "Sauce Labs" service interaction. + * Get Selenium2 current session id. * - * @return SauceRest + * @param Session $session Session. + * + * @return string + * @throws \RuntimeException When session was created using an unsupported driver. */ - protected function getRestClient() + protected function getSessionId(Session $session) { - $sauce = $this->getSauce(); + $driver = $session->getDriver(); + + if ( method_exists($driver, 'getWebDriverSession') ) { + $wd_session = $driver->getWebDriverSession(); + + return $wd_session ? basename($wd_session->getUrl()) : ''; + } - return new SauceRest($sauce['username'], $sauce['api_key']); + return ''; } } diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 3dfc3f1..dd5626b 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -12,21 +12,34 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\Common\RemoteCoverage; -use aik099\PHPUnit\SessionStrategy\ISessionStrategy; -use aik099\PHPUnit\SessionStrategy\SessionStrategyManager; +use aik099\PHPUnit\Event\TestEndedEvent; +use aik099\PHPUnit\Event\TestEvent; +use aik099\PHPUnit\Event\TestFailedEvent; +use aik099\PHPUnit\Session\ISessionStrategy; +use aik099\PHPUnit\Session\SessionStrategyManager; +use aik099\PHPUnit\TestSuite\RegularTestSuite; use Behat\Mink\Exception\DriverException; use Behat\Mink\Session; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Test Case class for writing browser-based tests. * * @method \Mockery\Expectation shouldReceive */ -abstract class BrowserTestCase extends \PHPUnit_Framework_TestCase +abstract class BrowserTestCase extends \PHPUnit_Framework_TestCase implements IEventDispatcherAware { + const TEST_ENDED_EVENT = 'test.ended'; + + const TEST_CASE_ENDED_EVENT = 'test_case.ended'; + + const TEST_FAILED_EVENT = 'test.failed'; + + const TEST_SETUP_EVENT = 'test.setup'; + /** * Browser list to be used in tests. * @@ -34,6 +47,20 @@ abstract class BrowserTestCase extends \PHPUnit_Framework_TestCase */ public static $browsers = array(); + /** + * Event dispatcher. + * + * @var EventDispatcherInterface + */ + private $_eventDispatcher; + + /** + * Browser configuration factory. + * + * @var IBrowserConfigurationFactory + */ + private $_browserConfigurationFactory; + /** * Remote coverage collection url. * @@ -76,6 +103,30 @@ abstract class BrowserTestCase extends \PHPUnit_Framework_TestCase */ private $_testId; + /** + * Sets application. + * + * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. + * + * @return void + */ + public function setBrowserConfigurationFactory(IBrowserConfigurationFactory $browser_configuration_factory) + { + $this->_browserConfigurationFactory = $browser_configuration_factory; + } + + /** + * Sets event dispatcher. + * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * + * @return void + */ + public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) + { + $this->_eventDispatcher = $event_dispatcher; + } + /** * Sets session strategy manager. * @@ -99,7 +150,13 @@ protected function setUp() { parent::setUp(); - $this->getBrowser()->testSetUpHook($this); + // TODO: verify, that still works + $this->_eventDispatcher->dispatch( + self::TEST_SETUP_EVENT, + new TestEvent($this) + ); + +// $this->getBrowser()->onTestSetup(new TestEvent($this, $this->_session)); } /** @@ -112,13 +169,10 @@ protected function setUp() public function setBrowser(BrowserConfiguration $browser) { $this->_browser = $browser; + $browser->attachToTestCase($this); // configure session strategy - $session_strategy = $browser->getSessionStrategy(); - $session_strategy_hash = $browser->getSessionStrategyHash($this); - $browser_strategy = $this->sessionStrategyManager->getSessionStrategy($session_strategy, $session_strategy_hash); - - return $this->setSessionStrategy($browser_strategy); + return $this->setSessionStrategy($this->sessionStrategyManager->getSessionStrategy($browser)); } /** @@ -145,17 +199,7 @@ public function getBrowser() */ public function setBrowserFromConfiguration(array $browser_config) { - $browser_config = BrowserConfiguration::resolveAliases($browser_config, $this->getBrowserAliases()); - - // configure browser - if ( isset($browser_config['sauce']) ) { - $browser = new SauceLabsBrowserConfiguration($this->getBrowserAliases()); - } - else { - $browser = new BrowserConfiguration($this->getBrowserAliases()); - } - - $browser->setup($browser_config); + $browser = $this->_browserConfigurationFactory->createBrowserConfiguration($browser_config, $this); return $this->setBrowser($browser); } @@ -240,10 +284,14 @@ public function run(\PHPUnit_Framework_TestResult $result = null) $result->getCodeCoverage()->append($this->getRemoteCodeCoverageInformation(), $this); } - $this->getBrowser()->testAfterRunHook($this, $result); - + // TODO: verify, that still works // do not call this before to give the time to the Listeners to run - $this->getSessionStrategy()->endOfTest($this->_session); + $this->_eventDispatcher->dispatch( + self::TEST_ENDED_EVENT, + new TestEndedEvent($this, $result, $this->_session) + ); +// $this->getBrowser()->onTestEnded(new TestEndedEvent($this, $result, $this->_session)); +// $this->getSessionStrategy()->onTestEnd(new TestEndedEvent($this, $result, $this->_session)); return $result; } @@ -291,7 +339,12 @@ protected function runTest() */ public function endOfTestCase() { - $this->getSessionStrategy()->endOfTestCase($this->_session); + // TODO: verify, that still works + $this->_eventDispatcher->dispatch( + self::TEST_CASE_ENDED_EVENT, + new TestEvent($this, $this->_session) + ); +// $this->getSessionStrategy()->onTestCaseEnd(new TestEvent($this, $this->_session)); return $this; } @@ -313,11 +366,13 @@ public function getRemoteCodeCoverageInformation() * * @param string $class_name Test case class name. * - * @return TestSuite + * @return RegularTestSuite */ public static function suite($class_name) { - return TestSuite::fromTestCaseClass($class_name); + $application = TestApplication::getInstance(); + + return $application->getTestSuiteBuilder()->createSuiteFromTestCase($class_name); } /** @@ -329,7 +384,12 @@ public static function suite($class_name) */ protected function onNotSuccessfulTest(\Exception $e) { - $this->getSessionStrategy()->notSuccessfulTest($e); + // TODO: verify, that still works + $this->_eventDispatcher->dispatch( + self::TEST_FAILED_EVENT, + new TestFailedEvent($e, $this, $this->_session) + ); +// $this->getSessionStrategy()->onTestFailed(new TestFailedEvent($this, $e)); parent::onNotSuccessfulTest($e); } diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php new file mode 100644 index 0000000..7d4d071 --- /dev/null +++ b/library/aik099/PHPUnit/DIContainer.php @@ -0,0 +1,146 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; +use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use aik099\PHPUnit\Session\IsolatedSessionStrategy; +use aik099\PHPUnit\Session\SessionFactory; +use aik099\PHPUnit\Session\SessionStrategyFactory; +use aik099\PHPUnit\Session\SessionStrategyManager; +use aik099\PHPUnit\Session\SharedSessionStrategy; +use aik099\PHPUnit\TestSuite\BrowserTestSuite; +use aik099\PHPUnit\TestSuite\RegularTestSuite; +use aik099\PHPUnit\TestSuite\TestSuiteBuilder; +use Symfony\Component\EventDispatcher\EventDispatcher; + +class DIContainer extends \Pimple implements ITestApplicationAware +{ + + /** + * Application. + * + * @var TestApplication + */ + protected $application; + + /** + * Sets application. + * + * @param TestApplication $application The application. + * + * @return void + */ + public function setApplication(TestApplication $application) + { + $this->application = $application; + } + + /** + * Instantiate the container. + * + * Objects and parameters can be passed as argument to the constructor. + * + * @param array $values The parameters or objects. + */ + public function __construct(array $values = array()) + { + parent::__construct($values); + + $this['event_dispatcher'] = function ($c) { + return new EventDispatcher(); + }; + + $this['session_factory'] = function ($c) { + return new SessionFactory(); + }; + + $this['session_strategy_factory'] = function (DIContainer $c) { + $session_strategy_factory = new SessionStrategyFactory(); + $session_strategy_factory->setApplication($c->getApplication()); + + return $session_strategy_factory; + }; + + $this['session_strategy_manager'] = function ($c) { + return new SessionStrategyManager($c['session_strategy_factory']); + }; + + $this['isolated_session_strategy'] = $this->factory(function ($c) { + $session_strategy = new IsolatedSessionStrategy($c['session_factory']); + $session_strategy->setEventDispatcher($c['event_dispatcher']); + + return $session_strategy; + }); + + $this['shared_session_strategy'] = $this->factory(function ($c) { + $session_strategy = new SharedSessionStrategy($c['isolated_session_strategy']); + $session_strategy->setEventDispatcher($c['event_dispatcher']); + + return $session_strategy; + }); + + $this['test_suite_builder'] = function (DIContainer $c) { + $test_suite_builder = new TestSuiteBuilder($c['session_strategy_manager'], $c['browser_configuration_factory']); + $test_suite_builder->setApplication($c->getApplication()); + + return $test_suite_builder; + }; + + $this['regular_test_suite'] = $this->factory(function (DIContainer $c) { + $test_suite = new RegularTestSuite(); + $test_suite->setEventDispatcher($c['event_dispatcher']); + + return $test_suite; + }); + + $this['browser_test_suite'] = $this->factory(function (DIContainer $c) { + $test_suite = new BrowserTestSuite(); + $test_suite->setEventDispatcher($c['event_dispatcher']); + + return $test_suite; + }); + + $this['browser_configuration_factory'] = function (DIContainer $c) { + $browser_configuration_factory = new BrowserConfigurationFactory(); + $browser_configuration_factory->setApplication($c->getApplication()); + + return $browser_configuration_factory; + }; + + $this['browser_configuration'] = $this->factory(function ($c) { + $browser = new BrowserConfiguration(); + $browser->setEventDispatcher($c['event_dispatcher']); + + return $browser; + }); + + $this['sauce_labs_browser_configuration'] = $this->factory(function ($c) { + $browser = new SauceLabsBrowserConfiguration($c['browser_configuration_factory']); + $browser->setEventDispatcher($c['event_dispatcher']); + + return $browser; + }); + } + + /** + * Returns application. + * + * @return TestApplication + */ + protected function getApplication() + { + return $this->application; + } + +} diff --git a/library/aik099/PHPUnit/Event/TestEndedEvent.php b/library/aik099/PHPUnit/Event/TestEndedEvent.php new file mode 100644 index 0000000..56c4da6 --- /dev/null +++ b/library/aik099/PHPUnit/Event/TestEndedEvent.php @@ -0,0 +1,54 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\Event; + + +use aik099\PHPUnit\BrowserTestCase; +use Behat\Mink\Session; + +class TestEndedEvent extends TestEvent +{ + + /** + * Test result. + * + * @var \PHPUnit_Framework_TestResult + */ + private $_testResult; + + /** + * Remembers the exception which caused test to fail. + * + * @param BrowserTestCase $test_case Test case. + * @param \PHPUnit_Framework_TestResult $test_result Test result. + * @param Session $session Session. + */ + public function __construct( + BrowserTestCase $test_case, + \PHPUnit_Framework_TestResult $test_result, + Session $session = null + ) + { + parent::__construct($test_case, $session); + $this->_testResult = $test_result; + } + + /** + * Returns test result. + * + * @return \PHPUnit_Framework_TestResult + */ + public function getTestResult() + { + return $this->_testResult; + } + +} diff --git a/library/aik099/PHPUnit/Event/TestEvent.php b/library/aik099/PHPUnit/Event/TestEvent.php new file mode 100644 index 0000000..6540830 --- /dev/null +++ b/library/aik099/PHPUnit/Event/TestEvent.php @@ -0,0 +1,67 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\Event; + + +use aik099\PHPUnit\BrowserTestCase; +use Behat\Mink\Session; +use Symfony\Component\EventDispatcher\Event; + +class TestEvent extends Event +{ + + /** + * Test case. + * + * @var BrowserTestCase + */ + private $_testCase; + + /** + * Session. + * + * @var Session + */ + private $_session; + + /** + * Creates test event. + * + * @param BrowserTestCase $test_case Test case. + * @param Session $session Session. + */ + public function __construct(BrowserTestCase $test_case, Session $session = null) + { + $this->_testCase = $test_case; + $this->_session = $session; + } + + /** + * Returns test case. + * + * @return BrowserTestCase + */ + public function getTestCase() + { + return $this->_testCase; + } + + /** + * Returns session. + * + * @return Session + */ + public function getSession() + { + return $this->_session; + } + +} diff --git a/library/aik099/PHPUnit/Event/TestFailedEvent.php b/library/aik099/PHPUnit/Event/TestFailedEvent.php new file mode 100644 index 0000000..afb0f73 --- /dev/null +++ b/library/aik099/PHPUnit/Event/TestFailedEvent.php @@ -0,0 +1,50 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\Event; + + +use aik099\PHPUnit\BrowserTestCase; +use Behat\Mink\Session; + +class TestFailedEvent extends TestEvent +{ + + /** + * Exception. + * + * @var \Exception + */ + private $_exception; + + /** + * Remembers the exception which caused test to fail. + * + * @param \Exception $e Exception. + * @param BrowserTestCase $test_case Test case. + * @param Session $session Session. + */ + public function __construct(\Exception $e, BrowserTestCase $test_case, Session $session = null) + { + parent::__construct($test_case, $session); + $this->_exception = $e; + } + + /** + * Returns exception, that caused test to fail. + * + * @return \Exception + */ + public function getException() + { + return $this->_exception; + } + +} diff --git a/library/aik099/PHPUnit/IEventDispatcherAware.php b/library/aik099/PHPUnit/IEventDispatcherAware.php new file mode 100644 index 0000000..dec3e31 --- /dev/null +++ b/library/aik099/PHPUnit/IEventDispatcherAware.php @@ -0,0 +1,32 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit; + + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + + +/** + * Interface to indicate that class is capable of using event dispatcher. + */ +interface IEventDispatcherAware +{ + + /** + * Sets event dispatcher. + * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * + * @return void + */ + public function setEventDispatcher(EventDispatcherInterface $event_dispatcher); + +} diff --git a/library/aik099/PHPUnit/ITestApplicationAware.php b/library/aik099/PHPUnit/ITestApplicationAware.php new file mode 100644 index 0000000..fa2a99d --- /dev/null +++ b/library/aik099/PHPUnit/ITestApplicationAware.php @@ -0,0 +1,29 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit; + + +/** + * Interface to indicate that test case or test suite class understands TestApplication. + */ +interface ITestApplicationAware +{ + + /** + * Sets application. + * + * @param TestApplication $application The application. + * + * @return void + */ + public function setApplication(TestApplication $application); + +} diff --git a/library/aik099/PHPUnit/Session/ISessionFactory.php b/library/aik099/PHPUnit/Session/ISessionFactory.php new file mode 100644 index 0000000..41c9770 --- /dev/null +++ b/library/aik099/PHPUnit/Session/ISessionFactory.php @@ -0,0 +1,35 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\Session; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use Behat\Mink\Session; + + +/** + * Specifies how to create Session objects for running tests. + * + * @method \Mockery\Expectation shouldReceive + */ +interface ISessionFactory +{ + + /** + * Creates new session based on browser configuration. + * + * @param BrowserConfiguration $browser Browser configuration. + * + * @return Session + */ + public function createSession(BrowserConfiguration $browser); + +} diff --git a/library/aik099/PHPUnit/SessionStrategy/ISessionStrategy.php b/library/aik099/PHPUnit/Session/ISessionStrategy.php similarity index 57% rename from library/aik099/PHPUnit/SessionStrategy/ISessionStrategy.php rename to library/aik099/PHPUnit/Session/ISessionStrategy.php index 9b51cbe..e27aef3 100644 --- a/library/aik099/PHPUnit/SessionStrategy/ISessionStrategy.php +++ b/library/aik099/PHPUnit/Session/ISessionStrategy.php @@ -8,18 +8,20 @@ * @link https://github.com/aik099/phpunit-mink */ -namespace aik099\PHPUnit\SessionStrategy; +namespace aik099\PHPUnit\Session; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\IEventDispatcherAware; use Behat\Mink\Session; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Specifies how to create Session objects for running tests. * * @method \Mockery\Expectation shouldReceive */ -interface ISessionStrategy +interface ISessionStrategy extends EventSubscriberInterface, IEventDispatcherAware { /** @@ -31,31 +33,4 @@ interface ISessionStrategy */ public function session(BrowserConfiguration $browser); - /** - * Called, when test fails. - * - * @param \Exception $e Exception. - * - * @return self - */ - public function notSuccessfulTest(\Exception $e); - - /** - * Called, when test ends. - * - * @param Session|null $session Session. - * - * @return self - */ - public function endOfTest(Session $session = null); - - /** - * Called, when test case ends. - * - * @param Session|null $session Session. - * - * @return self - */ - public function endOfTestCase(Session $session = null); - } diff --git a/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php b/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php new file mode 100644 index 0000000..b04dfd8 --- /dev/null +++ b/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php @@ -0,0 +1,31 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\Session; + + +/** + * Specifies how to create Session objects for running tests. + * + * @method \Mockery\Expectation shouldReceive + */ +interface ISessionStrategyFactory +{ + + /** + * Creates specified session strategy. + * + * @param string $strategy_type Session strategy type. + * + * @return ISessionStrategy + */ + public function createStrategy($strategy_type); + +} diff --git a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php new file mode 100644 index 0000000..b00df40 --- /dev/null +++ b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php @@ -0,0 +1,98 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\Session; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Event\TestEvent; +use Behat\Mink\Session; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * Produces a new Session object shared for each test. + * + * @method \Mockery\Expectation shouldReceive + */ +class IsolatedSessionStrategy implements ISessionStrategy +{ + + /** + * Session factory. + * + * @var ISessionFactory + */ + private $_sessionFactory; + + /** + * Creates isolated session strategy instance. + * + * @param ISessionFactory $session_factory Session factory. + */ + public function __construct(ISessionFactory $session_factory) + { + $this->_sessionFactory = $session_factory; + } + + /** + * Returns an array of event names this subscriber wants to listen to. + * + * @return array The event names to listen to + */ + public static function getSubscribedEvents() + { + return array( + BrowserTestCase::TEST_ENDED_EVENT => array('onTestEnd', 0), + ); + } + + /** + * Sets event dispatcher. + * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * + * @return void + */ + public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) + { + $event_dispatcher->addSubscriber($this); + } + + /** + * Returns Mink session with given browser configuration. + * + * @param BrowserConfiguration $browser Browser configuration for a session. + * + * @return Session + */ + public function session(BrowserConfiguration $browser) + { + $session = $this->_sessionFactory->createSession($browser); + $session->start(); + + return $session; + } + + /** + * Called, when test ends. + * + * @param TestEvent $event Test event. + * + * @return void + */ + public function onTestEnd(TestEvent $event) + { + if ( $event->getSession() !== null ) { + $event->getSession()->stop(); + } + } + +} diff --git a/library/aik099/PHPUnit/Session/SessionFactory.php b/library/aik099/PHPUnit/Session/SessionFactory.php new file mode 100644 index 0000000..c7a72a0 --- /dev/null +++ b/library/aik099/PHPUnit/Session/SessionFactory.php @@ -0,0 +1,64 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\Session; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use Behat\Mink\Driver\DriverInterface; +use Behat\Mink\Driver\Selenium2Driver; +use Behat\Mink\Session; + +/** + * Produces sessions. + * + * @method \Mockery\Expectation shouldReceive + */ +class SessionFactory implements ISessionFactory +{ + + /** + * Creates new session based on browser configuration. + * + * @param BrowserConfiguration $browser Browser configuration. + * + * @return Session + */ + public function createSession(BrowserConfiguration $browser) + { + return new Session($this->_createDriver($browser)); + } + + /** + * Creates driver based on browser configuration. + * + * @param BrowserConfiguration $browser Browser configuration. + * + * @return DriverInterface + */ + private function _createDriver(BrowserConfiguration $browser) + { + $browser_name = $browser->getBrowserName(); + $capabilities = $browser->getDesiredCapabilities(); + $capabilities['browserName'] = $browser_name; + + // TODO: maybe doesn't work + ini_set('default_socket_timeout', $browser->getTimeout()); + + $driver = new Selenium2Driver( + $browser_name, + $capabilities, + 'http://' . $browser->getHost() . ':' . $browser->getPort() . '/wd/hub' + ); + + return $driver; + } + +} diff --git a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php new file mode 100644 index 0000000..9546292 --- /dev/null +++ b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php @@ -0,0 +1,65 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\Session; + + +use aik099\PHPUnit\ITestApplicationAware; +use aik099\PHPUnit\TestApplication; + + +/** + * Produces sessions. + * + * @method \Mockery\Expectation shouldReceive + */ +class SessionStrategyFactory implements ISessionStrategyFactory, ITestApplicationAware +{ + + /** + * Application. + * + * @var TestApplication + */ + protected $application; + + /** + * Sets application. + * + * @param TestApplication $application The application. + * + * @return void + */ + public function setApplication(TestApplication $application) + { + $this->application = $application; + } + + /** + * Creates specified session strategy. + * + * @param string $strategy_type Session strategy type. + * + * @return ISessionStrategy + * @throws \InvalidArgumentException When session strategy type is invalid. + */ + public function createStrategy($strategy_type) + { + if ( $strategy_type == SessionStrategyManager::ISOLATED_STRATEGY ) { + return $this->application->getObject('isolated_session_strategy'); + } + elseif ( $strategy_type == SessionStrategyManager::SHARED_STRATEGY ) { + return $this->application->getObject('shared_session_strategy'); + } + + throw new \InvalidArgumentException('Incorrect session strategy type'); + } + +} diff --git a/library/aik099/PHPUnit/SessionStrategy/SessionStrategyManager.php b/library/aik099/PHPUnit/Session/SessionStrategyManager.php similarity index 50% rename from library/aik099/PHPUnit/SessionStrategy/SessionStrategyManager.php rename to library/aik099/PHPUnit/Session/SessionStrategyManager.php index bbc42ae..90af73a 100644 --- a/library/aik099/PHPUnit/SessionStrategy/SessionStrategyManager.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyManager.php @@ -8,9 +8,11 @@ * @link https://github.com/aik099/phpunit-mink */ -namespace aik099\PHPUnit\SessionStrategy; +namespace aik099\PHPUnit\Session; +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; + /** * Manages session strategies used across browser tests. * @@ -51,93 +53,59 @@ class SessionStrategyManager protected $defaultSessionStrategy; /** - * No direct instantiation. + * Session strategy factory. + * + * @var ISessionStrategyFactory */ - protected function __construct() - { - - } + private $_sessionStrategyFactory; /** - * Returns instance of strategy manager. + * Creates session strategy manager instance. * - * @return self + * @param ISessionStrategyFactory $session_strategy_factory Session strategy factory. */ - public static function getInstance() + public function __construct(ISessionStrategyFactory $session_strategy_factory) { - static $instance = null; - - if ( null === $instance ) { - $instance = new static(); - } - - return $instance; + $this->_sessionStrategyFactory = $session_strategy_factory; } /** - * Initializes session strategy using given browser test case. - * - * @param string $session_strategy Session strategy. - * @param string $session_strategy_hash Session strategy hash. + * Creates default session strategy. * * @return ISessionStrategy */ - public function getSessionStrategy($session_strategy, $session_strategy_hash) + public function getDefaultSessionStrategy() { - // This logic creates separate strategy for: - // - each browser configuration in BrowserTestCase::$browsers (for isolated strategy) - // - each browser configuration in BrowserTestCase::$browsers for each test case class (for shared strategy) - - if ( $session_strategy_hash != $this->lastUsedSessionStrategyHash ) { - switch ( $session_strategy ) { - case self::ISOLATED_STRATEGY: - $this->sessionStrategiesInUse[$session_strategy_hash] = $this->createSessionStrategy(false); - break; - - case self::SHARED_STRATEGY: - $this->sessionStrategiesInUse[$session_strategy_hash] = $this->createSessionStrategy(true); - break; - } + if ( !$this->defaultSessionStrategy ) { + $this->defaultSessionStrategy = $this->_sessionStrategyFactory->createStrategy(self::ISOLATED_STRATEGY); } - $this->lastUsedSessionStrategyHash = $session_strategy_hash; - - return $this->sessionStrategiesInUse[$session_strategy_hash]; + return $this->defaultSessionStrategy; } /** - * Creates specified session strategy. + * Initializes session strategy using given browser test case. * - * @param boolean $share_session Share or not the session. + * @param BrowserConfiguration $browser Browser configuration. * * @return ISessionStrategy - * @throws \InvalidArgumentException When incorrect argument is given. */ - public function createSessionStrategy($share_session) + public function getSessionStrategy(BrowserConfiguration $browser) { - if ( !is_bool($share_session) ) { - throw new \InvalidArgumentException('The shared session support can only be switched on or off.'); - } - - if ( $share_session ) { - return new SharedSessionStrategy(new IsolatedSessionStrategy()); - } + // This logic creates separate strategy for: + // - each browser configuration in BrowserTestCase::$browsers (for isolated strategy) + // - each browser configuration in BrowserTestCase::$browsers for each test case class (for shared strategy) - return new IsolatedSessionStrategy(); - } + $strategy_type = $browser->getSessionStrategy(); + $strategy_hash = $browser->getSessionStrategyHash(); - /** - * Creates default session strategy. - * - * @return ISessionStrategy - */ - public function getDefaultSessionStrategy() - { - if ( !$this->defaultSessionStrategy ) { - $this->defaultSessionStrategy = $this->createSessionStrategy(false); + if ( $strategy_hash !== $this->lastUsedSessionStrategyHash ) { + $this->sessionStrategiesInUse[$strategy_hash] = $this->_sessionStrategyFactory->createStrategy($strategy_type); } - return $this->defaultSessionStrategy; + $this->lastUsedSessionStrategyHash = $strategy_hash; + + return $this->sessionStrategiesInUse[$strategy_hash]; } } diff --git a/library/aik099/PHPUnit/SessionStrategy/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php similarity index 50% rename from library/aik099/PHPUnit/SessionStrategy/SharedSessionStrategy.php rename to library/aik099/PHPUnit/Session/SharedSessionStrategy.php index 2a58c57..75ea4ee 100644 --- a/library/aik099/PHPUnit/SessionStrategy/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -8,12 +8,15 @@ * @link https://github.com/aik099/phpunit-mink */ -namespace aik099\PHPUnit\SessionStrategy; +namespace aik099\PHPUnit\Session; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Driver\Selenium2Driver; +use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Event\TestEvent; +use aik099\PHPUnit\Event\TestFailedEvent; use Behat\Mink\Session; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Keeps a Session object shared between test runs to save time. @@ -37,19 +40,12 @@ class SharedSessionStrategy implements ISessionStrategy */ private $_session; - /** - * Window name, which was opened upon session creation. - * - * @var string - */ - private $_mainWindow; - /** * Remembers if last test failed. * * @var boolean */ - private $_lastTestWasNotSuccessful = false; + private $_lastTestFailed = false; /** * Remembers original session strategy upon shared strategy creation. @@ -61,6 +57,31 @@ public function __construct(ISessionStrategy $original_strategy) $this->_originalStrategy = $original_strategy; } + /** + * Returns an array of event names this subscriber wants to listen to. + * + * @return array The event names to listen to + */ + public static function getSubscribedEvents() + { + return array( + BrowserTestCase::TEST_FAILED_EVENT => array('onTestFailed', 0), + BrowserTestCase::TEST_CASE_ENDED_EVENT => array('onTestCaseEnd', 0), + ); + } + + /** + * Sets event dispatcher. + * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * + * @return void + */ + public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) + { + $event_dispatcher->addSubscriber($this); + } + /** * Returns Mink session with given browser configuration. * @@ -70,103 +91,77 @@ public function __construct(ISessionStrategy $original_strategy) */ public function session(BrowserConfiguration $browser) { - if ( $this->_lastTestWasNotSuccessful ) { - if ( $this->_session !== null ) { - $this->_session->stop(); - $this->_session = null; - } - - $this->_lastTestWasNotSuccessful = false; + if ( $this->_lastTestFailed ) { + $this->stopSession(); + $this->_lastTestFailed = false; } if ( $this->_session === null ) { $this->_session = $this->_originalStrategy->session($browser); - $this->rememberMainWindow(); } else { - // if session is reused, then switch to window, that was created along with session creation - $this->restoreMainWindow(); + $this->_switchToMainWindow(); } return $this->_session; } /** - * Remember window name, which was created along with session. + * Stops session. * - * @return self + * @return void */ - protected function rememberMainWindow() + protected function stopSession() { - $driver = $this->_session->getDriver(); - - if ( $driver instanceof Selenium2Driver ) { - $wd_session = $driver->getWebDriverSession(); - $this->_mainWindow = $wd_session->window_handle(); + if ( $this->_session === null ) { + return; } - return $this; + $this->_session->stop(); + $this->_session = null; } /** * Switches to window, that was created upon session creation. * - * @return self + * @return void */ - protected function restoreMainWindow() + private function _switchToMainWindow() { - $this->_session->switchToWindow($this->_mainWindow); - - return $this; + $this->_session->switchToWindow(null); } /** * Called, when test fails. * - * @param \Exception $e Exception. + * @param TestFailedEvent $event Test failed event. * - * @return self + * @return void */ - public function notSuccessfulTest(\Exception $e) + public function onTestFailed(TestFailedEvent $event) { - if ( $e instanceof \PHPUnit_Framework_IncompleteTestError ) { - return $this; + if ( $event->getException() instanceof \PHPUnit_Framework_IncompleteTestError ) { + return; } - elseif ( $e instanceof \PHPUnit_Framework_SkippedTestError ) { - return $this; + elseif ( $event->getException() instanceof \PHPUnit_Framework_SkippedTestError ) { + return; } - $this->_lastTestWasNotSuccessful = true; - - return $this; - } - - /** - * Called, when test ends. - * - * @param Session|null $session Session. - * - * @return self - */ - public function endOfTest(Session $session = null) - { - return $this; + $this->_lastTestFailed = true; } /** * Called, when test case ends. * - * @param Session|null $session Session. + * @param TestEvent $event Test event. * - * @return self + * @return void */ - public function endOfTestCase(Session $session = null) + public function onTestCaseEnd(TestEvent $event) { - if ( $session !== null ) { - $session->stop(); + if ( $event->getSession() !== null ) { + $event->getSession()->stop(); } - - return $this; } } diff --git a/library/aik099/PHPUnit/SessionStrategy/IsolatedSessionStrategy.php b/library/aik099/PHPUnit/SessionStrategy/IsolatedSessionStrategy.php deleted file mode 100644 index 2177fb6..0000000 --- a/library/aik099/PHPUnit/SessionStrategy/IsolatedSessionStrategy.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit\SessionStrategy; - - -use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Session; - -/** - * Produces a new Session object shared for each test. - * - * @method \Mockery\Expectation shouldReceive - */ -class IsolatedSessionStrategy implements ISessionStrategy -{ - - /** - * Returns Mink session with given browser configuration. - * - * @param BrowserConfiguration $browser Browser configuration for a session. - * - * @return Session - */ - public function session(BrowserConfiguration $browser) - { - $session = $browser->createSession(); - $session->start(); - - return $session; - } - - /** - * Called, when test fails. - * - * @param \Exception $e Exception. - * - * @return self - */ - public function notSuccessfulTest(\Exception $e) - { - return $this; - } - - /** - * Called, when test ends. - * - * @param Session|null $session Session. - * - * @return self - */ - public function endOfTest(Session $session = null) - { - if ( $session !== null ) { - $session->stop(); - } - - return $this; - } - - /** - * Called, when test case ends. - * - * @param Session|null $session Session. - * - * @return self - */ - public function endOfTestCase(Session $session = null) - { - return $this; - } - -} diff --git a/library/aik099/PHPUnit/TestApplication.php b/library/aik099/PHPUnit/TestApplication.php new file mode 100644 index 0000000..3251b82 --- /dev/null +++ b/library/aik099/PHPUnit/TestApplication.php @@ -0,0 +1,98 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit; + + +use aik099\PHPUnit\TestSuite\TestSuiteBuilder; + + +/** + * Main application class. + * + * @method \Mockery\Expectation shouldReceive + */ +class TestApplication +{ + + /** + * Dependency injection container. + * + * @var \Pimple + */ + protected $container; + + /** + * Returns instance of strategy manager. + * + * @param \Pimple $container Dependency injection container. + * + * @return self + */ + public static function getInstance(\Pimple $container = null) + { + static $instance = null; + + if ( null === $instance ) { + $instance = new static($container); + } + + return $instance; + } + + /** + * Prevents direct instantiation. + * + * @param \Pimple $container Dependency injection container. + */ + private function __construct(\Pimple $container = null) + { + if ( !isset($container) ) { + $container = new DIContainer(); + } + + $this->container = $container; + $this->container->setApplication($this); + } + + /** + * Returns test suite builder. + * + * @return TestSuiteBuilder + * @see BrowserTestCase::suite() + */ + public function getTestSuiteBuilder() + { + return $this->getObject('test_suite_builder'); + } + + /** + * Returns object from the container. + * + * @param string $name Name of the object in the container. + * + * @return \stdClass + */ + public function getObject($name) + { + return $this->container[$name]; + } + + /** + * Prevents cloning. + * + * @return void + */ + private function __clone() + { + + } + +} diff --git a/library/aik099/PHPUnit/TestSuite.php b/library/aik099/PHPUnit/TestSuite.php deleted file mode 100644 index fbc2eae..0000000 --- a/library/aik099/PHPUnit/TestSuite.php +++ /dev/null @@ -1,73 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit; - - -use aik099\PHPUnit\SessionStrategy\SessionStrategyManager; - - -/** - * Test Suite class for browser tests. - */ -class TestSuite extends TestSuiteBase -{ - - /** - * Creating TestSuite from given class. - * - * @param string $class_name Descendant of TestCase class. - * - * @return self - */ - public static function fromTestCaseClass($class_name) - { - $suite = new static(); - $suite->setName($class_name); - - $class = new \ReflectionClass($class_name); - $static_properties = $class->getStaticProperties(); - - $session_strategy_manager = SessionStrategyManager::getInstance(); - - // create tests from test methods for multiple browsers - if ( !empty($static_properties['browsers']) ) { - foreach ($static_properties['browsers'] as $browser) { - $suite->addTest(static::createBrowserSuite($class, $browser, $session_strategy_manager)); - } - } - else { - // create tests from test methods for single browser - $suite->addTestMethods($class, $session_strategy_manager); - } - - return $suite; - } - - /** - * Creates browser suite. - * - * @param \ReflectionClass $class Class. - * @param array $browser Browser configuration. - * @param SessionStrategyManager $session_strategy_manager Session strategy manager. - * - * @return BrowserSuite - */ - protected static function createBrowserSuite(\ReflectionClass $class, array $browser, SessionStrategyManager $session_strategy_manager) - { - $suite = BrowserSuite::fromClassAndBrowser($class->name, $browser); - - $suite->addTestMethods($class, $session_strategy_manager); - $suite->setBrowserFromConfiguration($browser); - - return $suite; - } - -} diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php new file mode 100644 index 0000000..c1b41bb --- /dev/null +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -0,0 +1,122 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\TestSuite; + + +use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; +use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\IEventDispatcherAware; +use aik099\PHPUnit\Session\SessionStrategyManager; +use ReflectionClass; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + + +/** + * Base Test Suite class for browser tests. + * + * @method \Mockery\Expectation shouldReceive + */ +abstract class AbstractTestSuite extends \PHPUnit_Framework_TestSuite implements IEventDispatcherAware +{ + + /** + * Event dispatcher. + * + * @var EventDispatcherInterface + */ + private $_eventDispatcher; + + /** + * Overriding the default: Selenium suites are always built from a TestCase class. + * + * @var boolean + */ + protected $testCase = true; + + /** + * Sets event dispatcher. + * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * + * @return void + */ + public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) + { + $this->_eventDispatcher = $event_dispatcher; + } + + /** + * Adds test methods to the suite. + * + * @param string $class_name Test case class name. + * + * @return self + */ + public function addTestMethods($class_name) + { + $class = new \ReflectionClass($class_name); + + foreach ( $class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method ) { + $this->addTestMethod($class, $method); + } + + return $this; + } + + /** + * Sets session strategy manager recursively to all tests. + * + * @param SessionStrategyManager $session_strategy_manager Session strategy manager. + * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. + * + * @return self + */ + public function setTestDependencies( + SessionStrategyManager $session_strategy_manager, + IBrowserConfigurationFactory $browser_configuration_factory + ) + { + /* @var $test BrowserTestCase */ + foreach ( $this->tests() as $test ) { + $test->setEventDispatcher($this->_eventDispatcher); + $test->setSessionStrategyManager($session_strategy_manager); + $test->setBrowserConfigurationFactory($browser_configuration_factory); + } + + return $this; + } + + /** + * Report back suite ending to each it's test. + * + * @return void + */ + protected function tearDown() + { + /* @var $test BrowserTestCase */ + + foreach ( $this->tests() as $test ) { + $test->endOfTestCase(); + } + } + + /** + * Indicates end of the test suite. + * + * @return void + * @codeCoverageIgnore + */ + public function endOfTestCase() + { + // method created just to simplify tearDown method + } + +} diff --git a/library/aik099/PHPUnit/BrowserSuite.php b/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php similarity index 63% rename from library/aik099/PHPUnit/BrowserSuite.php rename to library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php index 62da121..6113389 100644 --- a/library/aik099/PHPUnit/BrowserSuite.php +++ b/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php @@ -8,40 +8,36 @@ * @link https://github.com/aik099/phpunit-mink */ -namespace aik099\PHPUnit; +namespace aik099\PHPUnit\TestSuite; + + +use aik099\PHPUnit\BrowserTestCase; /** * Test Suite class for a set of tests from a single Test Case Class executed with a particular browser. */ -class BrowserSuite extends TestSuiteBase +class BrowserTestSuite extends AbstractTestSuite { /** - * Create test suite based on given class name on browser configuration. + * Generates suite name by the browser configuration. * - * @param string $class_name Class name. - * @param array $browser Browser configuration. + * @param array $browser Browser configuration. * - * @return self + * @return string */ - public static function fromClassAndBrowser($class_name, array $browser) + public function nameFromBrowser(array $browser) { - $suite = new static(); - - $name = 'undefined'; $try_settings = array('alias', 'browserName', 'name'); - foreach ($try_settings as $try_setting) { + foreach ( $try_settings as $try_setting ) { if ( isset($browser[$try_setting]) ) { - $name = $browser[$try_setting]; - break; + return $browser[$try_setting]; } } - $suite->setName($class_name . ': ' . $name); - - return $suite; + return 'undefined'; } /** diff --git a/library/aik099/PHPUnit/TestSuite/RegularTestSuite.php b/library/aik099/PHPUnit/TestSuite/RegularTestSuite.php new file mode 100644 index 0000000..cfdd41c --- /dev/null +++ b/library/aik099/PHPUnit/TestSuite/RegularTestSuite.php @@ -0,0 +1,21 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\TestSuite; + + +/** + * Test Suite class for browser tests. + */ +class RegularTestSuite extends AbstractTestSuite +{ + + +} diff --git a/library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php b/library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php new file mode 100644 index 0000000..3b8e1ac --- /dev/null +++ b/library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php @@ -0,0 +1,142 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\TestSuite; + + +use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; +use aik099\PHPUnit\ITestApplicationAware; +use aik099\PHPUnit\Session\SessionStrategyManager; +use aik099\PHPUnit\TestApplication; + + +/** + * Creates test suites based on test case class configuration. + * + * @method \Mockery\Expectation shouldReceive + */ +class TestSuiteBuilder implements ITestApplicationAware +{ + + /** + * Session strategy manager. + * + * @var SessionStrategyManager + */ + private $_sessionStrategyManager; + + /** + * Application. + * + * @var TestApplication + */ + protected $application; + + /** + * Browser configuration factory. + * + * @var IBrowserConfigurationFactory + */ + private $_browserConfigurationFactory; + + /** + * Creates test suite builder instance. + * + * @param SessionStrategyManager $session_strategy_manager Session strategy manager. + * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. + */ + public function __construct( + SessionStrategyManager $session_strategy_manager, + IBrowserConfigurationFactory $browser_configuration_factory + ) + { + $this->_sessionStrategyManager = $session_strategy_manager; + $this->_browserConfigurationFactory = $browser_configuration_factory; + } + + /** + * Sets application. + * + * @param TestApplication $application The application. + * + * @return void + */ + public function setApplication(TestApplication $application) + { + $this->application = $application; + } + + /** + * Creates test suite based on given test case class. + * + * @param string $class_name Test case class name. + * + * @return AbstractTestSuite + */ + public function createSuiteFromTestCase($class_name) + { + /** @var RegularTestSuite $suite */ + $suite = $this->application->getObject('regular_test_suite'); + $suite->setName($class_name); + + $browsers = $this->_getBrowsers($class_name); + + if ( $browsers ) { + // create tests from test methods for multiple browsers + foreach ( $browsers as $browser ) { + $suite->addTest($this->_createBrowserSuite($class_name, $browser)); + } + } + else { + // create tests from test methods for single browser + $suite->addTestMethods($class_name); + $suite->setTestDependencies($this->_sessionStrategyManager, $this->_browserConfigurationFactory); + } + + return $suite; + } + + /** + * Returns browser configuration of a class. + * + * @param string $class_name Test case class name. + * + * @return array + */ + private function _getBrowsers($class_name) + { + $class = new \ReflectionClass($class_name); + $static_properties = $class->getStaticProperties(); + + return !empty($static_properties['browsers']) ? $static_properties['browsers'] : array(); + } + + /** + * Creates browser suite. + * + * @param string $class_name Descendant of TestCase class. + * @param array $browser Browser configuration. + * + * @return BrowserTestSuite + */ + private function _createBrowserSuite($class_name, array $browser) + { + /** @var BrowserTestSuite $suite */ + $suite = $this->application->getObject('browser_test_suite'); + $suite->setName($class_name . ': ' . $suite->nameFromBrowser($browser)); + + $suite->addTestMethods($class_name); + $suite->setTestDependencies($this->_sessionStrategyManager, $this->_browserConfigurationFactory); + $suite->setBrowserFromConfiguration($browser); + + return $suite; + } + +} diff --git a/library/aik099/PHPUnit/TestSuiteBase.php b/library/aik099/PHPUnit/TestSuiteBase.php deleted file mode 100644 index 22d08d9..0000000 --- a/library/aik099/PHPUnit/TestSuiteBase.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit; - - -use aik099\PHPUnit\SessionStrategy\SessionStrategyManager; - - -/** - * Base Test Suite class for browser tests. - * - * @method \Mockery\Expectation shouldReceive - */ -abstract class TestSuiteBase extends \PHPUnit_Framework_TestSuite -{ - - /** - * Overriding the default: Selenium suites are always built from a TestCase class. - * - * @var boolean - */ - protected $testCase = true; - - /** - * Adds test methods to the suite. - * - * @param \ReflectionClass $class Class reflection. - * @param SessionStrategyManager $session_strategy_manager Session strategy manager. - * - * @return self - */ - public function addTestMethods(\ReflectionClass $class, SessionStrategyManager $session_strategy_manager) - { - foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { - $this->addTestMethod($class, $method); - } - - $this->setSessionStrategyManager($session_strategy_manager); - - return $this; - } - - /** - * Sets session strategy manager. - * - * @param SessionStrategyManager $session_strategy_manager Session strategy manager. - * - * @return self - */ - public function setSessionStrategyManager(SessionStrategyManager $session_strategy_manager) - { - /* @var $test \aik099\PHPUnit\BrowserTestCase */ - foreach ( $this->tests() as $test ) { - $test->setSessionStrategyManager($session_strategy_manager); - } - - return $this; - } - - /** - * Report back suite ending to each it's test. - * - * @return void - */ - protected function tearDown() - { - /* @var $test BrowserTestCase */ - - foreach ( $this->tests() as $test ) { - $test->endOfTestCase(); - } - } - - /** - * Indicates end of the test suite. - * - * @return void - * @codeCoverageIgnore - */ - public function endOfTestCase() - { - // method created just to simplify tearDown method - } - -} diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php new file mode 100644 index 0000000..481ed47 --- /dev/null +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -0,0 +1,107 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; +use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use Mockery as m; +use tests\aik099\PHPUnit\TestCase\TestApplicationAwareTestCase; + +class BrowserConfigurationFactoryTest extends TestApplicationAwareTestCase +{ + + /** + * Browser configuration factory. + * + * @var BrowserConfigurationFactory + */ + private $_factory; + + /** + * Configures the tests. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->_factory = new BrowserConfigurationFactory(); + $this->_factory->setApplication($this->application); + } + + /** + * Test description. + * + * @param array $browser_config Browser config. + * @param string $service_id Service ID in factory. + * + * @return void + * @dataProvider createBrowserConfigurationDataProvider + */ + public function testCreateBrowserConfiguration(array $browser_config, $service_id) + { + $browser_aliases = array('alias-one' => array()); + $browser_class = 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; + + $browser = m::mock($browser_class); + $browser->shouldReceive('setAliases')->with($browser_aliases)->once(); + $browser->shouldReceive('setup')->with($browser_config)->once(); + $this->expectFactoryCall($service_id, $browser); + + $test_case = m::mock('aik099\\PHPUnit\\BrowserTestCase'); + $test_case->shouldReceive('getBrowserAliases')->once()->andReturn($browser_aliases); + + $actual_browser = $this->_factory->createBrowserConfiguration($browser_config, $test_case); + $this->assertInstanceOf($browser_class, $actual_browser); + } + + /** + * Returns data for possible browser configuration creation ways. + * + * @return array + */ + public function createBrowserConfigurationDataProvider() + { + return array( + array(array('port' => 9999), 'browser_configuration'), + array(array('port' => 9999, 'sauce' => array()), 'sauce_labs_browser_configuration'), + ); + } + + /** + * Test description. + * + * @return void + */ + public function testCreateAPIClientSuccess() + { + $browser = new SauceLabsBrowserConfiguration($this->_factory); + $api_client = $this->_factory->createAPIClient($browser); + + $this->assertInstanceOf('WebDriver\\SauceLabs\\SauceRest', $api_client); + } + + /** + * Test description. + * + * @return void + * @expectedException \LogicException + */ + public function testCreateAPIClientFailure() + { + $browser = new BrowserConfiguration(); + $this->_factory->createAPIClient($browser); + } + +} diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index db53c10..81ad008 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -13,12 +13,22 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\SessionStrategy\SessionStrategyManager; +use aik099\PHPUnit\Session\SessionStrategyManager; use Mockery as m; +use Mockery\MockInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; +use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; class BrowserConfigurationTest extends \PHPUnit_Framework_TestCase { + const TEST_CASE_CLASS = '\\aik099\\PHPUnit\\BrowserTestCase'; + + const HOST = 'example_host'; + + const PORT = 1234; + /** * Hostname. * @@ -47,6 +57,13 @@ class BrowserConfigurationTest extends \PHPUnit_Framework_TestCase */ protected $browser; + /** + * Event dispatcher. + * + * @var EventDispatcherInterface|MockInterface + */ + protected $eventDispatcher; + /** * Configures all tests. * @@ -56,12 +73,9 @@ protected function setUp() { parent::setUp(); - $this->host = 'example_host'; - $this->port = 1234; - $this->setup = array( - 'host' => $this->host, - 'port' => $this->port, + 'host' => self::HOST, + 'port' => self::PORT, 'timeout' => 500, 'browserName' => 'safari', 'desiredCapabilities' => array('platform' => 'Windows 7', 'version' => 10), @@ -69,62 +83,95 @@ protected function setUp() 'sessionStrategy' => SessionStrategyManager::SHARED_STRATEGY, ); + $this->eventDispatcher = m::mock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); $this->browser = $this->createBrowserConfiguration(); } /** * Test description. * + * @param array $aliases Test case aliases. + * @param array $browser_config Browser config. + * @param array $expected_config Expected browser config. + * * @return void + * @dataProvider aliasResolutionDataProvider */ - public function testResolveAliasesUsingSingleAlias() + public function testAliasResolution(array $aliases, array $browser_config, array $expected_config) { - $browser = $this->createBrowserConfiguration(array( - 'a1' => array('host' => $this->host, 'port' => $this->port), - )); + $this->browser->setAliases($aliases); + $this->browser->setup($browser_config); - $browser->setup(array('alias' => 'a1')); - - $this->assertEquals($this->host, $browser->getHost()); - $this->assertEquals($this->port, $browser->getPort()); + $this->assertEquals($expected_config['host'], $this->browser->getHost()); + $this->assertEquals($expected_config['port'], $this->browser->getPort()); + $this->assertEquals($expected_config['browserName'], $this->browser->getBrowserName()); + $this->assertEquals($expected_config['baseUrl'], $this->browser->getBaseUrl()); } /** - * Test description. + * Alias resolution checking data provider. * - * @return void + * @return array */ - public function testResolveAliasesUsingRecursiveAlias() + public function aliasResolutionDataProvider() { - $browser = $this->createBrowserConfiguration(array( - 'a1' => array('alias' => 'a2', 'host' => $this->host, 'port' => $this->port), - 'a2' => array('browserName' => 'safari', 'baseUrl' => 'http://example_host'), - )); - - $browser->setup(array('alias' => 'a1')); - - $this->assertEquals($this->host, $browser->getHost()); - $this->assertEquals($this->port, $browser->getPort()); - $this->assertEquals('safari', $browser->getBrowserName()); - $this->assertEquals('http://example_host', $browser->getBaseUrl()); + return array( + 'single alias' => array( + array( + 'a1' => array('host' => static::HOST, 'port' => static::PORT), + ), + array('alias' => 'a1'), + array( + 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'firefox', 'baseUrl' => '', + ), + ), + 'recursive alias' => array( + array( + 'a1' => array('alias' => 'a2', 'host' => static::HOST, 'port' => static::PORT), + 'a2' => array('browserName' => 'safari', 'baseUrl' => 'http://example_host'), + ), + array('alias' => 'a1'), + array( + 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'safari', 'baseUrl' => 'http://example_host', + ), + ), + 'alias merging' => array( + array( + 'a1' => array('host' => static::HOST, 'port' => static::PORT), + ), + array('alias' => 'a1', 'browserName' => 'firefox'), + array( + 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'firefox', 'baseUrl' => '', + ), + ), + 'with overwrite' => array( + array( + 'a1' => array('host' => 'alias-host', 'port' => static::PORT), + ), + array('alias' => 'a1', 'host' => static::HOST), + array( + 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'firefox', 'baseUrl' => '', + ), + ), + 'without alias given' => array( + array(), + array('host' => static::HOST, 'port' => static::PORT, 'browserName' => 'safari'), + array( + 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'safari', 'baseUrl' => '', + ), + ), + ); } /** * Test description. * * @return void + * @expectedException \InvalidArgumentException */ - public function testResolveAliasesUsingAliasMerging() + public function testResolveAliasesUsingIncorrectAlias() { - $browser = $this->createBrowserConfiguration(array( - 'a1' => array('host' => $this->host, 'port' => $this->port), - )); - - $browser->setup(array('alias' => 'a1', 'browserName' => 'firefox')); - - $this->assertEquals($this->host, $browser->getHost()); - $this->assertEquals($this->port, $browser->getPort()); - $this->assertEquals('firefox', $browser->getBrowserName()); + $this->browser->setup(array('alias' => 'not_found')); } /** @@ -132,38 +179,26 @@ public function testResolveAliasesUsingAliasMerging() * * @return void */ - public function testResolveAliasesWithOverwrite() + public function testAttachToTestCase() { - $browser = $this->createBrowserConfiguration(array( - 'a1' => array('host' => 'alias-host', 'port' => $this->port), - )); - - $browser->setup(array('alias' => 'a1', 'host' => $this->host)); + $browser = $this->createBrowserConfiguration(array(), true); - $this->assertEquals($this->host, $browser->getHost()); - } + /* @var $test_case BrowserTestCase */ + $test_case = m::mock(self::TEST_CASE_CLASS); + $browser->attachToTestCase($test_case); - /** - * Test description. - * - * @return void - * @expectedException \InvalidArgumentException - */ - public function testResolveAliasesUsingIncorrectAlias() - { - $this->browser->setup(array('alias' => 'not_found')); + $this->assertSame($test_case, $browser->getTestCase()); } /** * Test description. * * @return void + * @expectedException \RuntimeException */ - public function testResolveAliasesWithoutAliasGiven() + public function testGetTestCaseException() { - $this->browser->setup(array('browserName' => 'safari')); - - $this->assertEquals('safari', $this->browser->getBrowserName()); + $this->browser->getTestCase(); } /** @@ -282,6 +317,7 @@ public function testSetBaseUrlCorrect() * @param array|null $expected Expected capabilities. * * @return void + * @see SauceLabsBrowserConfigurationTest::testSetDesiredCapabilitiesCorrect() */ public function testSetDesiredCapabilitiesCorrect(array $desired_capabilities = null, array $expected = null) { @@ -294,46 +330,48 @@ public function testSetDesiredCapabilitiesCorrect(array $desired_capabilities = * Test description. * * @return void + * @expectedException \InvalidArgumentException */ - public function testSetTimeoutCorrect() + public function testSetTimeoutIncorrect() { - $expected = 1000; - $this->assertSame($this->browser, $this->browser->setTimeout($expected)); - $this->assertSame($expected, $this->browser->getTimeout()); + $this->browser->setTimeout('5555'); } /** * Test description. * * @return void - * @expectedException \InvalidArgumentException */ - public function testSetTimeoutIncorrect() + public function testSetTimeoutCorrect() { - $this->browser->setTimeout('5555'); + $expected = 1000; + $this->assertSame($this->browser, $this->browser->setTimeout($expected)); + $this->assertSame($expected, $this->browser->getTimeout()); } /** * Test description. * * @return void + * @expectedException \InvalidArgumentException */ - public function testSetSessionStrategyCorrect() + public function testSetSessionStrategyIncorrect() { - $expected = SessionStrategyManager::SHARED_STRATEGY; - $this->assertSame($this->browser, $this->browser->setSessionStrategy($expected)); - $this->assertSame($expected, $this->browser->getSessionStrategy()); + $this->browser->setSessionStrategy('wrong'); } /** * Test description. * + * @param string $expected Expected strategy. + * * @return void - * @expectedException \InvalidArgumentException + * @dataProvider sessionSharingDataProvider */ - public function testSetSessionStrategyIncorrect() + public function testSetSessionStrategyCorrect($expected) { - $this->browser->setSessionStrategy('wrong'); + $this->assertSame($this->browser, $this->browser->setSessionStrategy($expected)); + $this->assertSame($expected, $this->browser->getSessionStrategy()); } /** @@ -346,16 +384,16 @@ public function testSetSessionStrategyIncorrect() */ public function testGetSessionStrategyHashBrowserSharing($session_strategy) { - $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase'); + $test_case = m::mock(self::TEST_CASE_CLASS); /* @var $test_case BrowserTestCase */ - $browser1 = $this->createBrowserConfiguration(); - $browser1->setSessionStrategy($session_strategy); + $browser1 = $this->createBrowserConfiguration(array(), true); + $browser1->setSessionStrategy($session_strategy)->attachToTestCase($test_case); - $browser2 = $this->createBrowserConfiguration(); - $browser2->setSessionStrategy($session_strategy); + $browser2 = $this->createBrowserConfiguration(array(), true); + $browser2->setSessionStrategy($session_strategy)->attachToTestCase($test_case); - $this->assertSame($browser1->getSessionStrategyHash($test_case), $browser2->getSessionStrategyHash($test_case)); + $this->assertSame($browser1->getSessionStrategyHash(), $browser2->getSessionStrategyHash()); } /** @@ -378,17 +416,13 @@ public function sessionSharingDataProvider() */ public function testGetSessionStrategyHashNotSharing() { - $test_case1 = m::mock('\\aik099\\PHPUnit\\BrowserTestCase'); - /* @var $test_case1 BrowserTestCase */ - - $browser1 = $this->createBrowserConfiguration(); - $browser1->setSessionStrategy(SessionStrategyManager::SHARED_STRATEGY); - - $test_case2 = m::mock('\\aik099\\PHPUnit\\BrowserTestCase'); - /* @var $test_case2 BrowserTestCase */ + $test_case1 = new WithBrowserConfig(); + $browser1 = $this->createBrowserConfiguration(array(), true); + $browser1->setSessionStrategy(SessionStrategyManager::SHARED_STRATEGY)->attachToTestCase($test_case1); - $browser2 = $this->createBrowserConfiguration(); - $browser2->setSessionStrategy(SessionStrategyManager::SHARED_STRATEGY); + $test_case2 = new WithoutBrowserConfig(); + $browser2 = $this->createBrowserConfiguration(array(), true); + $browser2->setSessionStrategy(SessionStrategyManager::SHARED_STRATEGY)->attachToTestCase($test_case2); $this->assertNotSame($browser1->getSessionStrategyHash($test_case1), $browser2->getSessionStrategyHash($test_case2)); } @@ -400,7 +434,7 @@ public function testGetSessionStrategyHashNotSharing() */ public function testGetTestStatusIsolated() { - $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase'); + $test_case = m::mock(self::TEST_CASE_CLASS); $test_case->shouldReceive('hasFailed')->once()->andReturn(false); $test_result = m::mock('\\PHPUnit_Framework_TestResult'); @@ -415,7 +449,7 @@ public function testGetTestStatusIsolated() */ public function testGetTestStatusShared() { - $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase'); + $test_case = m::mock(self::TEST_CASE_CLASS); $test_result = m::mock('\\PHPUnit_Framework_TestResult'); $test_result->shouldReceive('wasSuccessful')->once()->andReturn(true); @@ -423,58 +457,23 @@ public function testGetTestStatusShared() $this->assertTrue($this->browser->getTestStatus($test_case, $test_result)); } - /** - * Test description. - * - * @return void - */ - public function testCreateSession() - { - $session = $this->browser->createSession(); - - $this->assertInstanceOf('\\Behat\\Mink\\Session', $session); - $this->assertInstanceOf('\\Behat\\Mink\\Driver\\Selenium2Driver', $session->getDriver()); - } - - /** - * Test description. - * - * @return void - */ - public function testSetUpHook() - { - $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase'); - /* @var $test_case BrowserTestCase */ - - $this->assertSame($this->browser, $this->browser->testSetUpHook($test_case)); - } - - /** - * Test description. - * - * @return void - */ - public function testAfterRunHook() - { - $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase'); - /* @var $test_case BrowserTestCase */ - - $test_result = m::mock('\\PHPUnit_Framework_TestResult'); - /* @var $test_result \PHPUnit_Framework_TestResult */ - - $this->assertSame($this->browser, $this->browser->testAfterRunHook($test_case, $test_result)); - } - /** * Creates instance of browser configuration. * - * @param array $aliases Aliases. + * @param array $aliases Aliases. + * @param boolean $add_subscriber Expect addition of subscriber to event dispatcher. * * @return BrowserConfiguration */ - protected function createBrowserConfiguration(array $aliases = array()) + protected function createBrowserConfiguration(array $aliases = array(), $add_subscriber = false) { - return new BrowserConfiguration($aliases); + $browser = new BrowserConfiguration(); + $browser->setAliases($aliases); + + $browser->setEventDispatcher($this->eventDispatcher); + $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); + + return $browser; } } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 5937cf9..827e21f 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -11,8 +11,12 @@ namespace tests\aik099\PHPUnit; -use aik099\PHPUnit\SessionStrategy\SessionStrategyManager; -use WebDriver\SauceLabs\Capability as SauceLabsCapability; +use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; +use aik099\PHPUnit\Event\TestEndedEvent; +use aik099\PHPUnit\Event\TestEvent; +use aik099\PHPUnit\Session\SessionStrategyManager; +use Mockery\MockInterface; +use Symfony\Component\EventDispatcher\EventDispatcher; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; use Mockery as m; @@ -20,6 +24,19 @@ class SauceLabsBrowserConfigurationTest extends BrowserConfigurationTest { + const HOST = ':@ondemand.saucelabs.com'; + + const PORT = 80; + + const AUTOMATIC_TEST_NAME = 'AUTOMATIC'; + + /** + * Browser configuration factory. + * + * @var IBrowserConfigurationFactory|MockInterface + */ + private $_browserConfigurationFactory; + /** * Configures all tests. * @@ -27,10 +44,9 @@ class SauceLabsBrowserConfigurationTest extends BrowserConfigurationTest */ protected function setUp() { - parent::setUp(); + $this->_browserConfigurationFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); - $this->host = ':@ondemand.saucelabs.com'; - $this->port = 80; + parent::setUp(); $this->setup['host'] = 'UN:AK@ondemand.saucelabs.com'; $this->setup['port'] = 80; @@ -82,7 +98,7 @@ public function testSetSauceCorrect() */ public function testSetHostCorrect() { - $browser = $this->createBrowserConfiguration(array(), true); + $browser = $this->createBrowserConfiguration(array(), false, true); $this->assertSame($browser, $browser->setHost('EXAMPLE_HOST')); $this->assertSame('A:B@ondemand.saucelabs.com', $browser->getHost()); @@ -95,7 +111,7 @@ public function testSetHostCorrect() */ public function testSetPortCorrect() { - $browser = $this->createBrowserConfiguration(array(), true); + $browser = $this->createBrowserConfiguration(array(), false, true); $this->assertSame($browser, $browser->setPort(5555)); $this->assertSame(80, $browser->getPort()); } @@ -107,7 +123,7 @@ public function testSetPortCorrect() */ public function testSetBrowserNameCorrect() { - $browser = $this->createBrowserConfiguration(array(), true); + $browser = $this->createBrowserConfiguration(array(), false, true); $this->assertSame($browser, $browser->setBrowserName('')); $this->assertSame('chrome', $browser->getBrowserName()); } @@ -123,7 +139,7 @@ public function testSetBrowserNameCorrect() */ public function testSetDesiredCapabilitiesCorrect(array $desired_capabilities = null, array $expected = null) { - $browser = $this->createBrowserConfiguration(array(), true); + $browser = $this->createBrowserConfiguration(array(), false, true); $this->assertSame($browser, $browser->setDesiredCapabilities($desired_capabilities)); $this->assertSame($expected, $browser->getDesiredCapabilities()); } @@ -147,119 +163,126 @@ public function desiredCapabilitiesDataProvider() ); } - /** - * Test description. - * - * @return void - */ - public function testSetUpHook() - { - $this->markTestSkipped('Other more complex tests cover this'); - } - /** * Test description. * * @param string $session_strategy Session strategy. - * @param string $expected Expected job name. + * @param string $test_name Expected job name. + * @param string $build_number Build number. * * @return void - * @dataProvider jobNameDataProvider - * @covers \aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration::testSetUpHook + * @dataProvider setupEventDataProvider */ - public function testJobName($session_strategy, $expected) + public function testTestSetupEvent($session_strategy, $test_name, $build_number = null) { - /* @var $test_case BrowserTestCase */ - $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase'); + putenv('BUILD_NUMBER' . ($build_number ? '=' . $build_number : '')); + + $this->browser->setSessionStrategy($session_strategy); + + $event_dispatcher = new EventDispatcher(); + $event_dispatcher->addSubscriber($this->browser); + + $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('toString')->times($this->_isAutomaticTestName($test_name) ? 0 : 1)->andReturn($test_name); - if ( !isset($expected) ) { - $expected = get_class($test_case); + if ( $this->_isAutomaticTestName($test_name) ) { + $test_name = get_class($test_case); } - $this->browser->setSessionStrategy($session_strategy); - $test_case->shouldReceive('toString')->andReturn($expected); + $event_dispatcher->dispatch( + BrowserTestCase::TEST_SETUP_EVENT, + new TestEvent($test_case, m::mock('Behat\\Mink\\Session')) + ); + + $desired_capabilities = $this->browser->getDesiredCapabilities(); - $this->browser->testSetUpHook($test_case); + $this->assertArrayHasKey(SauceLabsBrowserConfiguration::NAME_CAPABILITY, $desired_capabilities); + $this->assertEquals($test_name, $desired_capabilities[SauceLabsBrowserConfiguration::NAME_CAPABILITY]); - $capabilities = $this->browser->getDesiredCapabilities(); - $this->assertArrayHasKey(SauceLabsCapability::NAME, $capabilities); - $this->assertSame($expected, $capabilities[SauceLabsCapability::NAME]); + if ( isset($build_number) ) { + $this->assertArrayHasKey(SauceLabsBrowserConfiguration::BUILD_NUMBER_CAPABILITY, $desired_capabilities); + $this->assertEquals($build_number, $desired_capabilities[SauceLabsBrowserConfiguration::BUILD_NUMBER_CAPABILITY]); + } + else { + $this->assertArrayNotHasKey(SauceLabsBrowserConfiguration::BUILD_NUMBER_CAPABILITY, $desired_capabilities); + } } /** - * JobName data provider. + * Checks that test name is automatic. * - * @return array + * @param string $test_name Expected job name. + * + * @return boolean */ - public function jobNameDataProvider() + private function _isAutomaticTestName($test_name) { - return array( - array(SessionStrategyManager::ISOLATED_STRATEGY, 'TEST_NAME'), - array(SessionStrategyManager::SHARED_STRATEGY, null), - ); + return $test_name == self::AUTOMATIC_TEST_NAME; } /** - * Test description. + * Data provider for TestSetup event handler. * - * @return void - * @covers \aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration::testSetUpHook + * @return array */ - public function testBuildNumberPresent() + public function setupEventDataProvider() { - /* @var $test_case BrowserTestCase */ - $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase'); - $this->browser->setSessionStrategy(SessionStrategyManager::SHARED_STRATEGY); - - $expected = 'X'; - putenv('BUILD_NUMBER=' . $expected); - $this->browser->testSetUpHook($test_case); - putenv('BUILD_NUMBER'); - - $capabilities = $this->browser->getDesiredCapabilities(); - $this->assertArrayHasKey(SauceLabsCapability::BUILD, $capabilities); - $this->assertSame($expected, $capabilities[SauceLabsCapability::BUILD]); + return array( + 'isolated, name, build' => array(SessionStrategyManager::ISOLATED_STRATEGY, 'TEST_NAME', 'BUILD_NUMBER'), + 'shared, no name, build' => array(SessionStrategyManager::SHARED_STRATEGY, self::AUTOMATIC_TEST_NAME, 'BUILD_NUMBER'), + 'isolated, name, no build' => array(SessionStrategyManager::ISOLATED_STRATEGY, 'TEST_NAME'), + 'shared, no name, no build' => array(SessionStrategyManager::SHARED_STRATEGY, self::AUTOMATIC_TEST_NAME), + ); } /** * Test description. * * @return void - * @covers \aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration::testSetUpHook */ - public function testBuildNumberAbsent() + public function testTestEndedEvent() { - /* @var $test_case BrowserTestCase */ - $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase'); - $this->browser->setSessionStrategy(SessionStrategyManager::SHARED_STRATEGY); + $sauce_rest = m::mock('WebDriver\\SauceLabs\\SauceRest'); + $sauce_rest->shouldReceive('updateJob')->with('', array('passed' => true))->once(); - $this->browser->testSetUpHook($test_case); + $this->_browserConfigurationFactory->shouldReceive('createAPIClient')->with($this->browser)->andReturn($sauce_rest); - $capabilities = $this->browser->getDesiredCapabilities(); - $this->assertArrayNotHasKey(SauceLabsCapability::BUILD, $capabilities); - } + $event_dispatcher = new EventDispatcher(); + $event_dispatcher->addSubscriber($this->browser); - /** - * Test description. - * - * @return void - */ - public function testAfterRunHook() - { - $this->markTestSkipped('TODO'); + $session = m::mock('Behat\\Mink\\Session'); + $session->shouldReceive('getDriver')->once()->andReturn(new \stdClass()); + + $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('getSession')->once()->andReturn($session); + $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // for shared strategy + + $test_result = m::mock('PHPUnit_Framework_TestResult'); + + $event = $event_dispatcher->dispatch( + BrowserTestCase::TEST_ENDED_EVENT, + new TestEndedEvent($test_case, $test_result, $session) + ); + + $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $event); } /** * Creates instance of browser configuration. * - * @param array $aliases Aliases. - * @param boolean $with_sauce Include test sauce configuration. + * @param array $aliases Aliases. + * @param boolean $add_subscriber Expect addition of subscriber to event dispatcher. + * @param boolean $with_sauce Include test sauce configuration. * * @return SauceLabsBrowserConfiguration */ - protected function createBrowserConfiguration(array $aliases = array(), $with_sauce = false) + protected function createBrowserConfiguration(array $aliases = array(), $add_subscriber = false, $with_sauce = false) { - $browser = new SauceLabsBrowserConfiguration($aliases); + $browser = new SauceLabsBrowserConfiguration($this->_browserConfigurationFactory); + $browser->setAliases($aliases); + + $browser->setEventDispatcher($this->eventDispatcher); + $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); if ( $with_sauce ) { $browser->setSauce(array('username' => 'A', 'api_key' => 'B')); diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index c39039b..4ace87b 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -12,10 +12,13 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\SessionStrategy\ISessionStrategy; -use aik099\PHPUnit\SessionStrategy\SessionStrategyManager; +use aik099\PHPUnit\Session\ISessionStrategy; +use aik099\PHPUnit\Session\SessionStrategyManager; use Mockery as m; +use Mockery\MockInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; @@ -24,9 +27,36 @@ class BrowserTestCaseTest extends \PHPUnit_Framework_TestCase const BROWSER_CLASS = '\\aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; - const MANAGER_CLASS = '\\aik099\\PHPUnit\\SessionStrategy\\SessionStrategyManager'; + const MANAGER_CLASS = '\\aik099\\PHPUnit\\Session\\SessionStrategyManager'; - const SESSION_STRATEGY_INTERFACE = '\\aik099\\PHPUnit\\SessionStrategy\\ISessionStrategy'; + const SESSION_STRATEGY_INTERFACE = '\\aik099\\PHPUnit\\Session\\ISessionStrategy'; + + /** + * Browser configuration factory. + * + * @var IBrowserConfigurationFactory|MockInterface + */ + protected $browserConfigurationFactory; + + /** + * Event dispatcher. + * + * @var EventDispatcherInterface|MockInterface + */ + protected $eventDispatcher; + + /** + * Configures all tests. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->browserConfigurationFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + $this->eventDispatcher = m::mock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); + } /** * Test description. @@ -35,7 +65,7 @@ class BrowserTestCaseTest extends \PHPUnit_Framework_TestCase */ public function testSetSessionStrategyManager() { - /* @var $manager \aik099\PHPUnit\SessionStrategy\SessionStrategyManager */ + /* @var $manager SessionStrategyManager */ $manager = m::mock(self::MANAGER_CLASS); $test_case = new WithoutBrowserConfig(); @@ -57,9 +87,12 @@ public function testSetBrowserCorrect() $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); /* @var $session_strategy ISessionStrategy */ - $browser = new BrowserConfiguration(); $test_case = $this->getFixture($session_strategy); + $browser = new BrowserConfiguration(); + $browser->setEventDispatcher($this->eventDispatcher); + $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->once(); + $this->assertSame($test_case, $test_case->setBrowser($browser)); $this->assertSame($browser, $test_case->getBrowser()); $this->assertSame($session_strategy, $test_case->getSessionStrategy()); @@ -85,43 +118,18 @@ public function testGetBrowserNotSpecified() public function testSetBrowserFromConfigurationDefault() { $test_case = $this->getFixture(); - $this->assertSame($test_case, $test_case->setBrowserFromConfiguration(array( - 'browserName' => 'safari', - ))); - $this->assertInstanceOf(self::BROWSER_CLASS, $test_case->getBrowser()); - } + $browser = $this->getBrowser(0); + $browser_config = array('browserName' => 'safari'); - /** - * Test description. - * - * @return void - */ - public function testSetBrowserFromConfigurationWithSauce() - { - $test_case = $this->getFixture(); - $this->assertSame($test_case, $test_case->setBrowserFromConfiguration(array( - 'browserName' => 'safari', 'sauce' => array('username' => 'test-user', 'api_key' => 'ABC'), - ))); - - $expected = '\\aik099\\PHPUnit\\BrowserConfiguration\\SauceLabsBrowserConfiguration'; - $this->assertInstanceOf($expected, $test_case->getBrowser()); - } + $this->browserConfigurationFactory + ->shouldReceive('createBrowserConfiguration') + ->with($browser_config, $test_case) + ->once() + ->andReturn($browser); - /** - * Test description. - * - * @return void - */ - public function testSetBrowserFromConfigurationStrategy() - { - /* @var $test_case BrowserTestCase */ - $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase[setBrowser]'); - $test_case->shouldReceive('setBrowser')->once()->andReturn($test_case); - - $this->assertSame($test_case, $test_case->setBrowserFromConfiguration(array( - 'browserName' => 'safari', - ))); + $this->assertSame($test_case, $test_case->setBrowserFromConfiguration($browser_config)); + $this->assertInstanceOf(self::BROWSER_CLASS, $test_case->getBrowser()); } /** @@ -131,7 +139,7 @@ public function testSetBrowserFromConfigurationStrategy() */ public function testSetSessionStrategy() { - /* @var $session_strategy \aik099\PHPUnit\SessionStrategy\ISessionStrategy */ + /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $test_case = new WithoutBrowserConfig(); @@ -147,7 +155,7 @@ public function testSetSessionStrategy() */ public function testGetSessionStrategySharing() { - /* @var $manager \aik099\PHPUnit\SessionStrategy\SessionStrategyManager */ + /* @var $manager SessionStrategyManager */ $manager = m::mock(self::MANAGER_CLASS); $manager->shouldReceive('getDefaultSessionStrategy')->twice()->andReturn('STRATEGY'); @@ -168,7 +176,7 @@ public function testGetSessionStrategySharing() */ public function testGetSession() { - $browser = $this->getBrowser(); + $browser = $this->getBrowser(0); $expected_session1 = m::mock('\\Behat\\Mink\\Session'); $expected_session1->shouldReceive('isStarted')->withNoArgs()->once()->andReturn(false); @@ -206,7 +214,7 @@ public function testGetSession() */ public function testGetSessionDriverError() { - $browser = $this->getBrowser(); + $browser = $this->getBrowser(1); /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); @@ -222,15 +230,16 @@ public function testGetSessionDriverError() /** * Returns browser mock. * + * @param integer $times How much times configuration should be read. + * * @return BrowserConfiguration */ - protected function getBrowser() + protected function getBrowser($times) { $browser = m::mock(self::BROWSER_CLASS); - $browser->shouldReceive('getSessionStrategy')->once()->andReturnNull(); - $browser->shouldReceive('getSessionStrategyHash')->once()->andReturnNull(); - $browser->shouldReceive('getHost')->andReturnNull(); - $browser->shouldReceive('getPort')->andReturnNull(); + $browser->shouldReceive('getHost')->times($times)->andReturnNull(); + $browser->shouldReceive('getPort')->times($times)->andReturnNull(); + $browser->shouldReceive('attachToTestCase')->once(); return $browser; } @@ -333,11 +342,13 @@ public function testRunWithCoverage() */ public function testEndOfTestCase() { - /* @var $session_strategy \aik099\PHPUnit\SessionStrategy\ISessionStrategy */ + $this->expectEvent(BrowserTestCase::TEST_CASE_ENDED_EVENT); + + /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - $session_strategy->shouldReceive('endOfTestCase')->with(null)->once()->andReturnNull(); $test_case = new WithoutBrowserConfig(); + $test_case->setEventDispatcher($this->eventDispatcher); $test_case->setSessionStrategy($session_strategy); $this->assertSame($test_case, $test_case->endOfTestCase()); @@ -350,11 +361,12 @@ public function testEndOfTestCase() * @expectedException \Exception * @expectedExceptionMessage MSG_TEST */ - public function testNotSuccessfulTest() + public function testOnTestFailed() { + $this->expectEvent(BrowserTestCase::TEST_FAILED_EVENT); + /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - $session_strategy->shouldReceive('notSuccessfulTest')->once()->andReturnNull(); $test_case = $this->getFixture($session_strategy); $test_case->setSessionStrategy($session_strategy); @@ -374,16 +386,16 @@ public function testNotSuccessfulTest() */ protected function prepareForRun(array $mock_methods = array()) { + $this->expectEvent(BrowserTestCase::TEST_SETUP_EVENT); + $this->expectEvent(BrowserTestCase::TEST_ENDED_EVENT); + /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - $session_strategy->shouldReceive('endOfTest')->once()->andReturnNull(); $test_case = $this->getFixture($session_strategy, $mock_methods); $test_case->setName('testSuccess'); - $browser = $this->getBrowser(); - $browser->shouldReceive('testSetUpHook')->once()->andReturnNull(); - $browser->shouldReceive('testAfterRunHook')->with($test_case, m::any())->once()->andReturnNull(); + $browser = $this->getBrowser(0); $test_case->setBrowser($browser); return array($test_case, $session_strategy); @@ -396,7 +408,7 @@ protected function prepareForRun(array $mock_methods = array()) * @param integer $run_count Test run count. * @param boolean $collect_coverage Should collect coverage information. * - * @return \PHPUnit_Framework_TestResult|\Mockery\Expectation + * @return \PHPUnit_Framework_TestResult|MockInterface */ protected function getTestResult(BrowserTestCase $test_case, $run_count, $collect_coverage = false) { @@ -424,7 +436,7 @@ protected function getFixture(ISessionStrategy $session_strategy = null, array $ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); } - /* @var $manager \aik099\PHPUnit\SessionStrategy\SessionStrategyManager */ + /* @var $manager SessionStrategyManager */ $manager = m::mock(self::MANAGER_CLASS); $manager->shouldReceive('getSessionStrategy')->andReturn($session_strategy); @@ -435,9 +447,26 @@ protected function getFixture(ISessionStrategy $session_strategy = null, array $ $test_case = new WithoutBrowserConfig(); } + $test_case->setEventDispatcher($this->eventDispatcher); + $test_case->setBrowserConfigurationFactory($this->browserConfigurationFactory); $test_case->setSessionStrategyManager($manager); return $test_case; } + /** + * Expects a specific event to be called. + * + * @param string $event_name Event name. + * + * @return void + */ + protected function expectEvent($event_name) + { + $this->eventDispatcher + ->shouldReceive('dispatch') + ->with($event_name, m::any()) + ->once(); + } + } diff --git a/tests/aik099/PHPUnit/Event/TestEndedEventTest.php b/tests/aik099/PHPUnit/Event/TestEndedEventTest.php new file mode 100644 index 0000000..37dca83 --- /dev/null +++ b/tests/aik099/PHPUnit/Event/TestEndedEventTest.php @@ -0,0 +1,58 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Event; + + +use aik099\PHPUnit\Event\TestEndedEvent; + +class TestEndedEventTest extends TestEventTest +{ + + /** + * Test result. + * + * @var \PHPUnit_Framework_TestResult + */ + private $_testResult; + + /** + * Prepares the tests. + * + * @return void + */ + protected function setUp() + { + $this->_testResult = new \PHPUnit_Framework_TestResult(); + + parent::setUp(); + } + + /** + * Test description. + * + * @return void + */ + public function testGetTestResult() + { + $this->assertSame($this->_testResult, $this->event->getTestResult()); + } + + /** + * Creates new event. + * + * @return TestEndedEvent + */ + protected function createEvent() + { + return new TestEndedEvent($this->testCase, $this->_testResult, $this->session); + } + +} diff --git a/tests/aik099/PHPUnit/Event/TestEventTest.php b/tests/aik099/PHPUnit/Event/TestEventTest.php new file mode 100644 index 0000000..3b734cb --- /dev/null +++ b/tests/aik099/PHPUnit/Event/TestEventTest.php @@ -0,0 +1,87 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Event; + + +use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Event\TestEvent; +use Behat\Mink\Session; +use Mockery as m; + +class TestEventTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Test event. + * + * @var TestEvent + */ + protected $event; + + /** + * Test case. + * + * @var BrowserTestCase + */ + protected $testCase; + + /** + * Session. + * + * @var Session + */ + protected $session; + + /** + * Prepares the tests. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->testCase = m::mock('aik099\\PHPUnit\\BrowserTestCase'); + $this->session = m::mock('Behat\\Mink\\Session'); + $this->event = $this->createEvent(); + } + + /** + * Test description. + * + * @return void + */ + public function testGetTestCase() + { + $this->assertSame($this->testCase, $this->event->getTestCase()); + } + + /** + * Test description. + * + * @return void + */ + public function testGetSession() + { + $this->assertSame($this->session, $this->event->getSession()); + } + + /** + * Creates new event. + * + * @return TestEvent + */ + protected function createEvent() + { + return new TestEvent($this->testCase, $this->session); + } + +} diff --git a/tests/aik099/PHPUnit/Event/TestFailedEventTest.php b/tests/aik099/PHPUnit/Event/TestFailedEventTest.php new file mode 100644 index 0000000..a53fb10 --- /dev/null +++ b/tests/aik099/PHPUnit/Event/TestFailedEventTest.php @@ -0,0 +1,59 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Event; + + +use aik099\PHPUnit\Event\TestFailedEvent; +use Mockery\CountValidator\Exception; + +class TestFailedEventTest extends TestEventTest +{ + + /** + * Exception. + * + * @var \Exception + */ + private $_exception; + + /** + * Prepares the tests. + * + * @return void + */ + protected function setUp() + { + $this->_exception = new Exception(); + + parent::setUp(); + } + + /** + * Test description. + * + * @return void + */ + public function testGetException() + { + $this->assertSame($this->_exception, $this->event->getException()); + } + + /** + * Creates new event. + * + * @return TestFailedEvent + */ + protected function createEvent() + { + return new TestFailedEvent($this->_exception, $this->testCase, $this->session); + } + +} diff --git a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php new file mode 100644 index 0000000..0c2b487 --- /dev/null +++ b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php @@ -0,0 +1,91 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Session; + + +use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Event\TestEndedEvent; +use aik099\PHPUnit\Session\ISessionFactory; +use aik099\PHPUnit\Session\IsolatedSessionStrategy; +use Mockery as m; +use Mockery\MockInterface; + +class IsolatedSessionStrategyTest extends SessionStrategyTestCase +{ + + /** + * Session factory. + * + * @var ISessionFactory|MockInterface + */ + private $_factory; + + /** + * Creates session strategy. + * + * @return void + */ + protected function setUp() + { + $this->_factory = m::mock('aik099\\PHPUnit\\Session\\ISessionFactory'); + $this->strategy = new IsolatedSessionStrategy($this->_factory); + + parent::setUp(); + } + + /** + * Test description. + * + * @return void + */ + public function testSession() + { + $browser = m::mock(self::BROWSER_CLASS); + + $session1 = m::mock(self::SESSION_CLASS); + $session1->shouldReceive('start')->once(); + + $session2 = m::mock(self::SESSION_CLASS); + $session2->shouldReceive('start')->once(); + + $this->_factory + ->shouldReceive('createSession') + ->with($browser) + ->twice() + ->andReturn($session1, $session2); + + $this->assertEquals($session1, $this->strategy->session($browser)); + $this->assertEquals($session2, $this->strategy->session($browser)); + } + + /** + * Test description. + * + * @return void + */ + public function testOnTestEnd() + { + $session = m::mock(self::SESSION_CLASS); + $session->shouldReceive('stop')->once(); + + $event = $this->eventDispatcher->dispatch( + BrowserTestCase::TEST_ENDED_EVENT, + new TestEndedEvent( + m::mock(self::TEST_CASE_CLASS), + m::mock('PHPUnit_Framework_TestResult'), + $session + ) + ); + + $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $event); + } + +} diff --git a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php new file mode 100644 index 0000000..352a3c8 --- /dev/null +++ b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php @@ -0,0 +1,59 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Session; + + +use aik099\PHPUnit\Session\SessionFactory; +use Mockery as m; + +class SessionFactoryTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Session factory. + * + * @var SessionFactory + */ + private $_factory; + + /** + * Creates session strategy. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->_factory = new SessionFactory(); + } + + /** + * Test description. + * + * @return void + */ + public function testCreateSession() + { + $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser->shouldReceive('getDesiredCapabilities')->once()->andReturn(array()); + $browser->shouldReceive('getBrowserName')->once()->andReturn(''); + $browser->shouldReceive('getTimeout')->once()->andReturn(0); + $browser->shouldReceive('getHost')->once()->andReturn(''); + $browser->shouldReceive('getPort')->once()->andReturn(0); + + $session = $this->_factory->createSession($browser); + + $this->assertInstanceOf('Behat\\Mink\\Session', $session); + $this->assertInstanceOf('Behat\\Mink\\Driver\\Selenium2Driver', $session->getDriver()); + } + +} diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php new file mode 100644 index 0000000..7ce4f53 --- /dev/null +++ b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php @@ -0,0 +1,82 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Session; + + +use aik099\PHPUnit\Session\SessionStrategyFactory; +use aik099\PHPUnit\Session\SessionStrategyManager; +use Mockery as m; +use tests\aik099\PHPUnit\TestCase\TestApplicationAwareTestCase; + +class SessionStrategyFactoryTest extends TestApplicationAwareTestCase +{ + + /** + * Session factory. + * + * @var SessionStrategyFactory + */ + private $_factory; + + /** + * Creates session strategy. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->_factory = new SessionStrategyFactory(); + $this->_factory->setApplication($this->application); + } + + /** + * Test description. + * + * @param string $strategy_type Strategy type. + * @param string $service_id Service ID. + * + * @return void + * @dataProvider createStrategyDataProvider + */ + public function testCreateStrategySuccess($strategy_type, $service_id) + { + $expected = 'OK'; + $this->expectFactoryCall($service_id, $expected); + $this->assertEquals($expected, $this->_factory->createStrategy($strategy_type)); + } + + /** + * Returns possible strategies. + * + * @return array + */ + public function createStrategyDataProvider() + { + return array( + array(SessionStrategyManager::ISOLATED_STRATEGY, 'isolated_session_strategy'), + array(SessionStrategyManager::SHARED_STRATEGY, 'shared_session_strategy'), + ); + } + + /** + * Test description. + * + * @return void + * @expectedException \InvalidArgumentException + */ + public function testCreateStrategyFailure() + { + $this->_factory->createStrategy('wrong'); + } + +} diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php new file mode 100644 index 0000000..67a9567 --- /dev/null +++ b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php @@ -0,0 +1,144 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Session; + + +use aik099\PHPUnit\Session\ISessionStrategy; +use aik099\PHPUnit\Session\SessionStrategyFactory; +use aik099\PHPUnit\Session\SessionStrategyManager; +use Mockery as m; + +class SessionStrategyManagerTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Session strategy manager. + * + * @var SessionStrategyManager + */ + protected $manager; + + /** + * Session strategy factory. + * + * @var SessionStrategyFactory + */ + protected $factory; + + /** + * Creates session strategy manager to use for tests. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->factory = m::mock('aik099\\PHPUnit\\Session\\ISessionStrategyFactory'); + $this->manager = new SessionStrategyManager($this->factory); + } + + /** + * Test description. + * + * @return void + */ + public function testGetDefaultSessionStrategy() + { + $expected = 'OK'; + $this->factory->shouldReceive('createStrategy')->andReturn($expected); + + $this->assertEquals($expected, $this->manager->getDefaultSessionStrategy()); + } + + /** + * Test description. + * + * @return void + */ + public function testGetDefaultSessionStrategySharing() + { + $this->factory->shouldReceive('createStrategy')->andReturn('OK'); + + $this->assertEquals($this->manager->getDefaultSessionStrategy(), $this->manager->getDefaultSessionStrategy()); + } + + /** + * Test description. + * + * @return void + */ + public function testGetSessionStrategySharing() + { + $this->factory + ->shouldReceive('createStrategy') + ->andReturnUsing(function () { + return m::mock('aik099\\PHPUnit\\Session\\ISessionStrategy'); + }); + + // sequential identical browser configurations share strategy + $strategy1 = $this->_getStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H1'); + $strategy2 = $this->_getStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H1'); + $this->assertSame($strategy1, $strategy2); + + // different browser configuration use different strategy + $strategy3 = $this->_getStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H2'); + $this->assertNotSame($strategy2, $strategy3); + + // different browser configuration break the sequence + $strategy4 = $this->_getStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H1'); + $this->assertNotSame($strategy1, $strategy4); + } + + /** + * Test description. + * + * @return void + */ + public function testGetSessionStrategyIsolated() + { + $expected = '\\aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'; + $this->factory->shouldReceive('createStrategy')->andReturn(m::mock($expected)); + + $this->assertInstanceOf($expected, $this->_getStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'IS1')); + } + + /** + * Test description. + * + * @return void + */ + public function testGetSessionStrategyShared() + { + $expected = '\\aik099\\PHPUnit\\Session\\SharedSessionStrategy'; + $this->factory->shouldReceive('createStrategy')->andReturn(m::mock($expected)); + + $this->assertInstanceOf($expected, $this->_getStrategy(SessionStrategyManager::SHARED_STRATEGY, 'SH1')); + } + + /** + * Creates browser configuration. + * + * @param string $strategy_type Strategy type. + * @param string $strategy_hash Strategy hash. + * + * @return ISessionStrategy + */ + private function _getStrategy($strategy_type, $strategy_hash) + { + $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser->shouldReceive('getSessionStrategy')->once()->andReturn($strategy_type); + $browser->shouldReceive('getSessionStrategyHash')->once()->andReturn($strategy_hash); + + return $this->manager->getSessionStrategy($browser); + } + +} diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php b/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php new file mode 100644 index 0000000..fc85847 --- /dev/null +++ b/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php @@ -0,0 +1,54 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Session; + + +use aik099\PHPUnit\Session\ISessionStrategy; +use Mockery as m; +use Symfony\Component\EventDispatcher\EventDispatcher; + +class SessionStrategyTestCase extends \PHPUnit_Framework_TestCase +{ + + const BROWSER_CLASS = '\\aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; + + const SESSION_CLASS = '\\Behat\\Mink\\Session'; + + const TEST_CASE_CLASS = 'aik099\\PHPUnit\\BrowserTestCase'; + + /** + * Event dispatcher. + * + * @var EventDispatcher + */ + protected $eventDispatcher; + + /** + * Session strategy. + * + * @var ISessionStrategy + */ + protected $strategy; + + /** + * Configures all tests. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->eventDispatcher = new EventDispatcher(); + $this->strategy->setEventDispatcher($this->eventDispatcher); + } + +} diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php new file mode 100644 index 0000000..69abd1c --- /dev/null +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -0,0 +1,189 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Session; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Event\TestEvent; +use aik099\PHPUnit\Event\TestFailedEvent; +use aik099\PHPUnit\Session\IsolatedSessionStrategy; +use aik099\PHPUnit\Session\SharedSessionStrategy; +use Behat\Mink\Session; +use Mockery as m; +use Mockery\MockInterface; + +class SharedSessionStrategyTest extends SessionStrategyTestCase +{ + + /** + * Isolated strategy. + * + * @var IsolatedSessionStrategy + */ + private $_isolatedStrategy; + + /** + * First created session. + * + * @var IsolatedSessionStrategy + */ + private $_session1; + + /** + * Second created session. + * + * @var IsolatedSessionStrategy + */ + private $_session2; + + /** + * Creates session strategy. + * + * @return void + */ + protected function setUp() + { + $this->_session1 = $this->createSession(); + $this->_session2 = $this->createSession(); + + $this->_isolatedStrategy = m::mock('\\aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'); + $this->strategy = new SharedSessionStrategy($this->_isolatedStrategy); + + parent::setUp(); + } + + /** + * Test description. + * + * @param \Exception $e Exception. + * + * @return void + * @dataProvider ignoreExceptionDataProvider + */ + public function testSessionSharing(\Exception $e = null) + { + /* @var $browser BrowserConfiguration */ + $browser = m::mock(self::BROWSER_CLASS); + $this->_isolatedStrategy->shouldReceive('session')->once()->with($browser)->andReturn($this->_session1); + + $this->_session1->shouldReceive('switchToWindow')->once(); + + $this->assertSame($this->_session1, $this->strategy->session($browser)); + + if ( isset($e) ) { + $this->_sessionFailure($e); + } + + $this->assertSame($this->_session1, $this->strategy->session($browser)); + } + + /** + * Returns exceptions, that doesn't reset session. + * + * @return array + */ + public function ignoreExceptionDataProvider() + { + return array( + array(null), + array(new \PHPUnit_Framework_IncompleteTestError()), + array(new \PHPUnit_Framework_SkippedTestError()), + ); + } + + /** + * Test description. + * + * @return void + */ + public function testSessionResetOnFailure() + { + /* @var $browser BrowserConfiguration */ + $browser = m::mock(self::BROWSER_CLASS); + + $this->_isolatedStrategy + ->shouldReceive('session') + ->with($browser) + ->twice() + ->andReturn($this->_session1, $this->_session2); + + $this->_session1->shouldReceive('stop')->once(); + $this->_session2->shouldReceive('switchToWindow')->once(); + + $session = $this->strategy->session($browser); + $this->assertSame($this->_session1, $session); + + $this->_sessionFailure(new \Exception()); + + $this->assertSame($this->_session2, $this->strategy->session($browser)); + $this->assertSame($this->_session2, $this->strategy->session($browser)); + } + + /** + * Test description. + * + * @return void + */ + public function testImmediateSessionFailure() + { + $this->_sessionFailure(new \Exception()); + + $this->_isolatedStrategy->shouldReceive('session')->once()->andReturn($this->_session1); + $this->assertSame($this->_session1, $this->strategy->session(m::mock(self::BROWSER_CLASS))); + } + + /** + * Generates test failure. + * + * @param \Exception $e Exception. + * + * @return TestFailedEvent + */ + private function _sessionFailure(\Exception $e) + { + $event = $this->eventDispatcher->dispatch( + BrowserTestCase::TEST_FAILED_EVENT, + new TestFailedEvent($e, m::mock(self::TEST_CASE_CLASS), $this->_session1) + ); + + return $event; + } + + /** + * Test description. + * + * @return void + */ + public function testEndOfTestCaseWithSession() + { + $session = $this->createSession(); + $session->shouldReceive('stop')->withNoArgs()->once(); + + $event = $this->eventDispatcher->dispatch( + BrowserTestCase::TEST_CASE_ENDED_EVENT, + new TestEvent(m::mock(self::TEST_CASE_CLASS), $session) + ); + + $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEvent', $event); + } + + /** + * Creates session mock. + * + * @return Session|MockInterface + */ + protected function createSession() + { + return m::mock(self::SESSION_CLASS); + } + +} diff --git a/tests/aik099/PHPUnit/SessionStrategy/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/SessionStrategy/IsolatedSessionStrategyTest.php deleted file mode 100644 index 6fc07b0..0000000 --- a/tests/aik099/PHPUnit/SessionStrategy/IsolatedSessionStrategyTest.php +++ /dev/null @@ -1,129 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace tests\aik099\PHPUnit\SessionStrategy; - - -use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use aik099\PHPUnit\SessionStrategy\IsolatedSessionStrategy; -use Behat\Mink\Session; -use Mockery as m; - -class IsolatedSessionStrategyTest extends \PHPUnit_Framework_TestCase -{ - - const BROWSER_CLASS = '\\aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; - - const SESSION_CLASS = '\\Behat\\Mink\\Session'; - - /** - * Session strategy. - * - * @var IsolatedSessionStrategy - */ - protected $strategy; - - /** - * Creates session strategy. - * - * @return void - */ - protected function setUp() - { - parent::setUp(); - - $this->strategy = new IsolatedSessionStrategy(); - } - - /** - * Test description. - * - * @return void - */ - public function testSession() - { - $expected_session1 = $this->createSession(1); - $expected_session2 = $this->createSession(1); - - /* @var $browser BrowserConfiguration */ - $browser = m::mock(self::BROWSER_CLASS); - $browser->shouldReceive('createSession')->twice()->andReturn($expected_session1, $expected_session2); - - $session1 = $this->strategy->session($browser); - $session2 = $this->strategy->session($browser); - - $this->assertInstanceOf(self::SESSION_CLASS, $session1); - $this->assertSame($expected_session1, $session1); - - $this->assertInstanceOf(self::SESSION_CLASS, $session2); - $this->assertSame($expected_session2, $session2); - - $this->assertNotSame($session1, $session2); - } - - /** - * Test description. - * - * @return void - */ - public function testNotSuccessfulTest() - { - $this->assertSame($this->strategy, $this->strategy->notSuccessfulTest(new \Exception())); - } - - /** - * Test description. - * - * @return void - */ - public function testEndOfTestWithSession() - { - $session = $this->createSession(0); - $session->shouldReceive('stop')->withNoArgs()->once()->andReturnNull(); - - $this->assertSame($this->strategy, $this->strategy->endOfTest($session)); - } - - /** - * Test description. - * - * @return void - */ - public function testEndOfTestWithoutSession() - { - $this->assertSame($this->strategy, $this->strategy->endOfTest()); - } - - /** - * Test description. - * - * @return void - */ - public function testEndOfTestCase() - { - $this->assertSame($this->strategy, $this->strategy->endOfTestCase()); - } - - /** - * Creates session. - * - * @param integer $start_count Session start time count. - * - * @return Session - */ - protected function createSession($start_count = 0) - { - $session = m::mock(self::SESSION_CLASS); - $session->shouldReceive('start')->withNoArgs()->times($start_count)->andReturnNull(); - - return $session; - } - -} diff --git a/tests/aik099/PHPUnit/SessionStrategy/SessionStrategyManagerTest.php b/tests/aik099/PHPUnit/SessionStrategy/SessionStrategyManagerTest.php deleted file mode 100644 index e60b324..0000000 --- a/tests/aik099/PHPUnit/SessionStrategy/SessionStrategyManagerTest.php +++ /dev/null @@ -1,146 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace tests\aik099\PHPUnit\SessionStrategy; - - -use aik099\PHPUnit\SessionStrategy\SessionStrategyManager; -use Mockery as m; - -class SessionStrategyManagerTest extends \PHPUnit_Framework_TestCase -{ - - /** - * Session strategy manager. - * - * @var SessionStrategyManager - */ - protected $manager; - - /** - * Creates session strategy manager to use for tests. - * - * @return void - */ - protected function setUp() - { - $this->manager = SessionStrategyManager::getInstance(); - } - - /** - * Test description. - * - * @return void - */ - public function testGetInstance() - { - $this->assertSame(SessionStrategyManager::getInstance(), SessionStrategyManager::getInstance()); - } - - /** - * Test description. - * - * @return void - */ - public function testGetSessionStrategySharing() - { - // sequential identical browser configurations share strategy - $strategy1 = $this->manager->getSessionStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H1'); - $strategy2 = $this->manager->getSessionStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H1'); - $this->assertSame($strategy1, $strategy2); - - // different browser configuration use different strategy - $strategy3 = $this->manager->getSessionStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H2'); - $this->assertNotSame($strategy2, $strategy3); - - // different browser configuration break the sequence - $strategy4 = $this->manager->getSessionStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H1'); - $this->assertNotSame($strategy1, $strategy4); - } - - /** - * Test description. - * - * @return void - */ - public function testGetSessionStrategyIsolated() - { - $actual = $this->manager->getSessionStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'IS1'); - - $this->assertInstanceOf('\\aik099\\PHPUnit\\SessionStrategy\\IsolatedSessionStrategy', $actual); - } - - /** - * Test description. - * - * @return void - */ - public function testCreateSessionStrategyIsolated() - { - $expected = '\\aik099\\PHPUnit\\SessionStrategy\\IsolatedSessionStrategy'; - $this->assertInstanceOf($expected, $this->manager->createSessionStrategy(false)); - } - - /** - * Test description. - * - * @return void - */ - public function testGetSessionStrategyShared() - { - $actual = $this->manager->getSessionStrategy(SessionStrategyManager::SHARED_STRATEGY, 'SH1'); - - $this->assertInstanceOf('\\aik099\\PHPUnit\\SessionStrategy\\SharedSessionStrategy', $actual); - } - - /** - * Test description. - * - * @return void - */ - public function testCreateSessionStrategyShared() - { - $expected = '\\aik099\\PHPUnit\\SessionStrategy\\SharedSessionStrategy'; - $this->assertInstanceOf($expected, $this->manager->createSessionStrategy(true)); - } - - /** - * Test description. - * - * @return void - * @expectedException \InvalidArgumentException - */ - public function testCreateSessionStrategyIncorrect() - { - $this->manager->createSessionStrategy('wrong'); - } - - /** - * Test description. - * - * @return void - */ - public function testGetDefaultSessionStrategy() - { - $expected = '\\aik099\\PHPUnit\\SessionStrategy\\IsolatedSessionStrategy'; - $this->assertInstanceOf($expected, $this->manager->getDefaultSessionStrategy()); - } - - /** - * Test description. - * - * @return void - */ - public function testGetDefaultSessionStrategySharing() - { - $this->assertSame($this->manager->getDefaultSessionStrategy(), $this->manager->getDefaultSessionStrategy()); - } - -} diff --git a/tests/aik099/PHPUnit/SessionStrategy/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/SessionStrategy/SharedSessionStrategyTest.php deleted file mode 100644 index f63619d..0000000 --- a/tests/aik099/PHPUnit/SessionStrategy/SharedSessionStrategyTest.php +++ /dev/null @@ -1,169 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace tests\aik099\PHPUnit\SessionStrategy; - - -use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use aik099\PHPUnit\SessionStrategy\IsolatedSessionStrategy; -use aik099\PHPUnit\SessionStrategy\SharedSessionStrategy; -use Behat\Mink\Session; -use Mockery as m; - -class SharedSessionStrategyTest extends \PHPUnit_Framework_TestCase -{ - - const BROWSER_CLASS = '\\aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; - - const SESSION_CLASS = '\\Behat\\Mink\\Session'; - - /** - * Session strategy. - * - * @var SharedSessionStrategy - */ - protected $strategy; - - /** - * Isolated strategy. - * - * @var IsolatedSessionStrategy - */ - protected $isolatedStrategy; - - /** - * First created session. - * - * @var IsolatedSessionStrategy - */ - protected $session1; - - /** - * Second created session. - * - * @var IsolatedSessionStrategy - */ - protected $session2; - - /** - * Creates session strategy. - * - * @return void - */ - protected function setUp() - { - parent::setUp(); - - $this->session1 = $this->createSession(); - $this->session2 = $this->createSession(); - - $this->isolatedStrategy = m::mock('\\aik099\\PHPUnit\\SessionStrategy\\IsolatedSessionStrategy'); - $this->strategy = new SharedSessionStrategy($this->isolatedStrategy); - } - - /** - * Test description. - * - * @return void - */ - public function testSessionSharing() - { - $browser = m::mock(self::BROWSER_CLASS); - /* @var $browser BrowserConfiguration */ - - $this->isolatedStrategy->shouldReceive('session')->once()->with($browser)->andReturn($this->session1); - - $this->assertSame($this->session1, $this->strategy->session($browser)); - $this->assertSame($this->session1, $this->strategy->session($browser)); - $this->assertSame($this->session1, $this->strategy->session($browser)); - } - - /** - * Test description. - * - * @return void - */ - public function testSessionResetOnFailure() - { - $browser = m::mock(self::BROWSER_CLASS); - /* @var $browser BrowserConfiguration */ - - $this->isolatedStrategy - ->shouldReceive('session')->twice()->with($browser)->andReturn($this->session1, $this->session2); - - $this->session1->shouldReceive('stop')->once()->andReturnNull(); - - $session = $this->strategy->session($browser); - $this->assertSame($this->session1, $session); - - $this->strategy->notSuccessfulTest(new \Exception()); - - $this->assertSame($this->session2, $this->strategy->session($browser)); - $this->assertSame($this->session2, $this->strategy->session($browser)); - } - - /** - * Test description. - * - * @return void - */ - public function testNotSuccessfulTest() - { - $this->assertSame($this->strategy, $this->strategy->notSuccessfulTest(new \Exception())); - } - - /** - * Test description. - * - * @return void - */ - public function testEndOfTest() - { - $this->assertSame($this->strategy, $this->strategy->endOfTest()); - } - - /** - * Test description. - * - * @return void - */ - public function testEndOfTestCaseWithSession() - { - $session = $this->createSession(); - $session->shouldReceive('stop')->withNoArgs()->once()->andReturnNull(); - - $this->assertSame($this->strategy, $this->strategy->endOfTestCase($session)); - } - - /** - * Test description. - * - * @return void - */ - public function testEndOfTestCaseWithoutSession() - { - $this->assertSame($this->strategy, $this->strategy->endOfTestCase()); - } - - /** - * Creates session mock. - * - * @return Session - */ - protected function createSession() - { - $session = m::mock(self::SESSION_CLASS); - $session->shouldReceive('getDriver')->andReturnNull(); - $session->shouldReceive('switchToWindow')->with(null)->andReturnNull(); - - return $session; - } - -} diff --git a/tests/aik099/PHPUnit/SuiteBuildingTest.php b/tests/aik099/PHPUnit/SuiteBuildingTest.php index be5fa68..14ca51b 100644 --- a/tests/aik099/PHPUnit/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/SuiteBuildingTest.php @@ -11,8 +11,8 @@ namespace tests\aik099\PHPUnit; -use aik099\PHPUnit\BrowserSuite; -use aik099\PHPUnit\TestSuite; +use aik099\PHPUnit\TestSuite\BrowserTestSuite; +use aik099\PHPUnit\TestSuite\RegularTestSuite; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use Mockery as m; @@ -20,9 +20,9 @@ class SuiteBuildingTest extends \PHPUnit_Framework_TestCase { - const SUITE_CLASS = '\\aik099\\PHPUnit\\TestSuite'; + const SUITE_CLASS = '\\aik099\\PHPUnit\\TestSuite\\RegularTestSuite'; - const BROWSER_SUITE_CLASS = '\\aik099\\PHPUnit\\BrowserSuite'; + const BROWSER_SUITE_CLASS = '\\aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'; const TEST_CASE_WITH_CONFIG = '\\tests\\aik099\\PHPUnit\\Fixture\\WithBrowserConfig'; @@ -40,7 +40,7 @@ public function testWithBrowserConfiguration() $this->assertInstanceOf(self::SUITE_CLASS, $suite); $tests = $suite->tests(); - /* @var $tests BrowserSuite[] */ + /* @var $tests BrowserTestSuite[] */ $this->checkArray($tests, 2, self::BROWSER_SUITE_CLASS); @@ -73,7 +73,7 @@ public function testSuiteTearDown() $sub_browser_suite = $this->createTestSuite(self::BROWSER_SUITE_CLASS); $sub_test_suite = $this->createTestSuite(self::SUITE_CLASS); - $suite = new TestSuite(); + $suite = new RegularTestSuite(); $suite->setName(self::TEST_CASE_WITH_CONFIG); $suite->addTest($sub_browser_suite); $suite->addTest($sub_test_suite); @@ -91,7 +91,7 @@ public function testSuiteTearDown() * * @param string $class_name Class name. * - * @return TestSuite + * @return RegularTestSuite */ protected function createTestSuite($class_name) { diff --git a/tests/aik099/PHPUnit/TestCase/TestApplicationAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/TestApplicationAwareTestCase.php new file mode 100644 index 0000000..1a5b182 --- /dev/null +++ b/tests/aik099/PHPUnit/TestCase/TestApplicationAwareTestCase.php @@ -0,0 +1,53 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\TestCase; + + +use aik099\PHPUnit\TestApplication; +use Mockery\MockInterface; +use Mockery as m; + +class TestApplicationAwareTestCase extends \PHPUnit_Framework_TestCase +{ + + /** + * Application. + * + * @var TestApplication|MockInterface + */ + protected $application; + + /** + * Configures the tests. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->application = m::mock('aik099\\PHPUnit\\TestApplication'); + } + + /** + * Expects a factory call. + * + * @param string $service_id Service ID. + * @param mixed $returned_object Object to return. + * + * @return void + */ + protected function expectFactoryCall($service_id, $returned_object) + { + $this->application->shouldReceive('getObject')->with($service_id)->andReturn($returned_object); + } + +} \ No newline at end of file From 513428b6c39013c5d8bb8b77c29c20b10d35c64e Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Mon, 3 Feb 2014 23:30:05 +0200 Subject: [PATCH 006/204] Adding back dependencies removed by accident --- composer.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/composer.json b/composer.json index 6aa351a..b04a00d 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,8 @@ "require": { "php": ">=5.3.2", + "behat/mink": "~1.5", + "behat/mink-selenium2-driver": "~1.1", "symfony/event-dispatcher": "~2.4", "pimple/pimple": "~2.0@dev", "phpunit/phpunit": "3.7.*" From 4770d90cc0a2879ccd51294ae56eff40a2aeaed6 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Mon, 3 Feb 2014 23:51:23 +0200 Subject: [PATCH 007/204] Store application inside DIC to be able to safely (even on PHP 5.3) reference it in dependencies --- library/aik099/PHPUnit/DIContainer.php | 35 +++++++------------------- 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index 7d4d071..daace64 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -27,13 +27,6 @@ class DIContainer extends \Pimple implements ITestApplicationAware { - /** - * Application. - * - * @var TestApplication - */ - protected $application; - /** * Sets application. * @@ -43,7 +36,7 @@ class DIContainer extends \Pimple implements ITestApplicationAware */ public function setApplication(TestApplication $application) { - $this->application = $application; + $this['application'] = $application; } /** @@ -65,9 +58,9 @@ public function __construct(array $values = array()) return new SessionFactory(); }; - $this['session_strategy_factory'] = function (DIContainer $c) { + $this['session_strategy_factory'] = function ($c) { $session_strategy_factory = new SessionStrategyFactory(); - $session_strategy_factory->setApplication($c->getApplication()); + $session_strategy_factory->setApplication($c['application']); return $session_strategy_factory; }; @@ -90,30 +83,30 @@ public function __construct(array $values = array()) return $session_strategy; }); - $this['test_suite_builder'] = function (DIContainer $c) { + $this['test_suite_builder'] = function ($c) { $test_suite_builder = new TestSuiteBuilder($c['session_strategy_manager'], $c['browser_configuration_factory']); - $test_suite_builder->setApplication($c->getApplication()); + $test_suite_builder->setApplication($c['application']); return $test_suite_builder; }; - $this['regular_test_suite'] = $this->factory(function (DIContainer $c) { + $this['regular_test_suite'] = $this->factory(function ($c) { $test_suite = new RegularTestSuite(); $test_suite->setEventDispatcher($c['event_dispatcher']); return $test_suite; }); - $this['browser_test_suite'] = $this->factory(function (DIContainer $c) { + $this['browser_test_suite'] = $this->factory(function ($c) { $test_suite = new BrowserTestSuite(); $test_suite->setEventDispatcher($c['event_dispatcher']); return $test_suite; }); - $this['browser_configuration_factory'] = function (DIContainer $c) { + $this['browser_configuration_factory'] = function ($c) { $browser_configuration_factory = new BrowserConfigurationFactory(); - $browser_configuration_factory->setApplication($c->getApplication()); + $browser_configuration_factory->setApplication($c['application']); return $browser_configuration_factory; }; @@ -133,14 +126,4 @@ public function __construct(array $values = array()) }); } - /** - * Returns application. - * - * @return TestApplication - */ - protected function getApplication() - { - return $this->application; - } - } From c9680f8a0535d58bd3b8328f2bcccb516d4a3b69 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 4 Feb 2014 22:36:14 +0200 Subject: [PATCH 008/204] Renaming TestApplication class into Application --- .../PHPUnit/{TestApplication.php => Application.php} | 2 +- .../BrowserConfigurationFactory.php | 12 ++++++------ library/aik099/PHPUnit/BrowserTestCase.php | 2 +- library/aik099/PHPUnit/DIContainer.php | 6 +++--- ...estApplicationAware.php => IApplicationAware.php} | 8 ++++---- .../PHPUnit/Session/SessionStrategyFactory.php | 12 ++++++------ .../aik099/PHPUnit/TestSuite/TestSuiteBuilder.php | 12 ++++++------ .../BrowserConfigurationFactoryTest.php | 4 ++-- .../PHPUnit/Session/SessionStrategyFactoryTest.php | 4 ++-- ...wareTestCase.php => ApplicationAwareTestCase.php} | 8 ++++---- 10 files changed, 35 insertions(+), 35 deletions(-) rename library/aik099/PHPUnit/{TestApplication.php => Application.php} (98%) rename library/aik099/PHPUnit/{ITestApplicationAware.php => IApplicationAware.php} (72%) rename tests/aik099/PHPUnit/TestCase/{TestApplicationAwareTestCase.php => ApplicationAwareTestCase.php} (80%) diff --git a/library/aik099/PHPUnit/TestApplication.php b/library/aik099/PHPUnit/Application.php similarity index 98% rename from library/aik099/PHPUnit/TestApplication.php rename to library/aik099/PHPUnit/Application.php index 3251b82..41cb1b3 100644 --- a/library/aik099/PHPUnit/TestApplication.php +++ b/library/aik099/PHPUnit/Application.php @@ -19,7 +19,7 @@ * * @method \Mockery\Expectation shouldReceive */ -class TestApplication +class Application { /** diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php index 6b1bb9b..fb11369 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php @@ -12,28 +12,28 @@ use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\ITestApplicationAware; -use aik099\PHPUnit\TestApplication; +use aik099\PHPUnit\IApplicationAware; +use aik099\PHPUnit\Application; use WebDriver\SauceLabs\SauceRest; -class BrowserConfigurationFactory implements IBrowserConfigurationFactory, ITestApplicationAware +class BrowserConfigurationFactory implements IBrowserConfigurationFactory, IApplicationAware { /** * Application. * - * @var TestApplication + * @var Application */ protected $application; /** * Sets application. * - * @param TestApplication $application The application. + * @param Application $application The application. * * @return void */ - public function setApplication(TestApplication $application) + public function setApplication(Application $application) { $this->application = $application; } diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index dd5626b..a7792a4 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -370,7 +370,7 @@ public function getRemoteCodeCoverageInformation() */ public static function suite($class_name) { - $application = TestApplication::getInstance(); + $application = Application::getInstance(); return $application->getTestSuiteBuilder()->createSuiteFromTestCase($class_name); } diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index daace64..4d61f54 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -24,17 +24,17 @@ use aik099\PHPUnit\TestSuite\TestSuiteBuilder; use Symfony\Component\EventDispatcher\EventDispatcher; -class DIContainer extends \Pimple implements ITestApplicationAware +class DIContainer extends \Pimple implements IApplicationAware { /** * Sets application. * - * @param TestApplication $application The application. + * @param Application $application The application. * * @return void */ - public function setApplication(TestApplication $application) + public function setApplication(Application $application) { $this['application'] = $application; } diff --git a/library/aik099/PHPUnit/ITestApplicationAware.php b/library/aik099/PHPUnit/IApplicationAware.php similarity index 72% rename from library/aik099/PHPUnit/ITestApplicationAware.php rename to library/aik099/PHPUnit/IApplicationAware.php index fa2a99d..19e92f3 100644 --- a/library/aik099/PHPUnit/ITestApplicationAware.php +++ b/library/aik099/PHPUnit/IApplicationAware.php @@ -12,18 +12,18 @@ /** - * Interface to indicate that test case or test suite class understands TestApplication. + * Interface to indicate that test case or test suite class understands Application. */ -interface ITestApplicationAware +interface IApplicationAware { /** * Sets application. * - * @param TestApplication $application The application. + * @param Application $application The application. * * @return void */ - public function setApplication(TestApplication $application); + public function setApplication(Application $application); } diff --git a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php index 9546292..3d585d2 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php @@ -11,8 +11,8 @@ namespace aik099\PHPUnit\Session; -use aik099\PHPUnit\ITestApplicationAware; -use aik099\PHPUnit\TestApplication; +use aik099\PHPUnit\IApplicationAware; +use aik099\PHPUnit\Application; /** @@ -20,24 +20,24 @@ * * @method \Mockery\Expectation shouldReceive */ -class SessionStrategyFactory implements ISessionStrategyFactory, ITestApplicationAware +class SessionStrategyFactory implements ISessionStrategyFactory, IApplicationAware { /** * Application. * - * @var TestApplication + * @var Application */ protected $application; /** * Sets application. * - * @param TestApplication $application The application. + * @param Application $application The application. * * @return void */ - public function setApplication(TestApplication $application) + public function setApplication(Application $application) { $this->application = $application; } diff --git a/library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php b/library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php index 3b8e1ac..c244a96 100644 --- a/library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php +++ b/library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php @@ -12,9 +12,9 @@ use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; -use aik099\PHPUnit\ITestApplicationAware; +use aik099\PHPUnit\IApplicationAware; use aik099\PHPUnit\Session\SessionStrategyManager; -use aik099\PHPUnit\TestApplication; +use aik099\PHPUnit\Application; /** @@ -22,7 +22,7 @@ * * @method \Mockery\Expectation shouldReceive */ -class TestSuiteBuilder implements ITestApplicationAware +class TestSuiteBuilder implements IApplicationAware { /** @@ -35,7 +35,7 @@ class TestSuiteBuilder implements ITestApplicationAware /** * Application. * - * @var TestApplication + * @var Application */ protected $application; @@ -64,11 +64,11 @@ public function __construct( /** * Sets application. * - * @param TestApplication $application The application. + * @param Application $application The application. * * @return void */ - public function setApplication(TestApplication $application) + public function setApplication(Application $application) { $this->application = $application; } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index 481ed47..974ef9b 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -15,9 +15,9 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use Mockery as m; -use tests\aik099\PHPUnit\TestCase\TestApplicationAwareTestCase; +use tests\aik099\PHPUnit\TestCase\ApplicationAwareTestCase; -class BrowserConfigurationFactoryTest extends TestApplicationAwareTestCase +class BrowserConfigurationFactoryTest extends ApplicationAwareTestCase { /** diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php index 7ce4f53..60e8417 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php @@ -14,9 +14,9 @@ use aik099\PHPUnit\Session\SessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyManager; use Mockery as m; -use tests\aik099\PHPUnit\TestCase\TestApplicationAwareTestCase; +use tests\aik099\PHPUnit\TestCase\ApplicationAwareTestCase; -class SessionStrategyFactoryTest extends TestApplicationAwareTestCase +class SessionStrategyFactoryTest extends ApplicationAwareTestCase { /** diff --git a/tests/aik099/PHPUnit/TestCase/TestApplicationAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php similarity index 80% rename from tests/aik099/PHPUnit/TestCase/TestApplicationAwareTestCase.php rename to tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php index 1a5b182..789f8bf 100644 --- a/tests/aik099/PHPUnit/TestCase/TestApplicationAwareTestCase.php +++ b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php @@ -11,17 +11,17 @@ namespace tests\aik099\PHPUnit\TestCase; -use aik099\PHPUnit\TestApplication; +use aik099\PHPUnit\Application; use Mockery\MockInterface; use Mockery as m; -class TestApplicationAwareTestCase extends \PHPUnit_Framework_TestCase +class ApplicationAwareTestCase extends \PHPUnit_Framework_TestCase { /** * Application. * - * @var TestApplication|MockInterface + * @var Application|MockInterface */ protected $application; @@ -34,7 +34,7 @@ protected function setUp() { parent::setUp(); - $this->application = m::mock('aik099\\PHPUnit\\TestApplication'); + $this->application = m::mock('aik099\\PHPUnit\\Application'); } /** From 1c0026404413158a3e2257d4636b6ee5608270f3 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 4 Feb 2014 23:27:32 +0200 Subject: [PATCH 009/204] Create `createBrowserConfiguration` method to ease custom per-test browser setup 1. fixed version in README 2. updated example code to reflect changes in BrowserConfiguration creation ways --- README.md | 19 ++++++++++++++----- library/aik099/PHPUnit/BrowserTestCase.php | 14 ++++++++++++-- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f52d8a9..1810e09 100644 --- a/README.md +++ b/README.md @@ -65,14 +65,23 @@ class PerBrowserConfigTest extends BrowserTestCase protected function setUp() { - $browser = new BrowserConfiguration($this->getBrowserAliases()); -// $browser = new SauceLabsBrowserConfiguration($this->getBrowserAliases()); -// $browser->setSauce(array('username' => 'sauce_username', 'api_key' => 'sauce_api_key')); - + // to create regular browser configuration via BrowserConfigurationFactory + $browser = $this->createBrowserConfiguration(array( + // options goes here (optional) + )); + + // to create "Sauce Labs" browser configuration via BrowserConfigurationFactory + $browser = $this->createBrowserConfiguration(array( + 'sauce' => array('username' => 'sauce_username', 'api_key' => 'sauce_api_key'), // required + // options goes here (optional) + )); + + // options can be changed later (optional) $browser->setHost('selenium_host')->setPort('selenium_port')->setTimeout(30); $browser->setBrowserName('browser name')->setDesiredCapabilities(array('version' => '6.5')); $browser->setBaseUrl('http://www.test-host.com'); + // set browser configuration to test case $this->setBrowser($browser); parent::setUp(); @@ -235,7 +244,7 @@ There are also corresponding `set` and `get` methods for each of mentioned above ```json { "require": { - "aik099/phpunit-mink": "dev-master" + "aik099/phpunit-mink": "~1.0" }, "repositories": [ { diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index a7792a4..790e63e 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -199,9 +199,19 @@ public function getBrowser() */ public function setBrowserFromConfiguration(array $browser_config) { - $browser = $this->_browserConfigurationFactory->createBrowserConfiguration($browser_config, $this); + return $this->setBrowser($this->createBrowserConfiguration($browser_config)); + } - return $this->setBrowser($browser); + /** + * Returns browser configuration instance. + * + * @param array $browser_config Browser. + * + * @return BrowserConfiguration + */ + protected function createBrowserConfiguration(array $browser_config) + { + return $this->_browserConfigurationFactory->createBrowserConfiguration($browser_config, $this); } /** From 53444f62fc2b7d6e44b3f623dc4c190bd0112dd5 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 4 Feb 2014 23:38:56 +0200 Subject: [PATCH 010/204] Make browser configuration attaching to test case easier to read --- .../PHPUnit/BrowserConfiguration/BrowserConfiguration.php | 4 +++- library/aik099/PHPUnit/BrowserTestCase.php | 3 +-- .../PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php | 2 +- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 452f929..a748009 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -128,12 +128,14 @@ public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) * * @param BrowserTestCase $test_case Test case. * - * @return void + * @return self */ public function attachToTestCase(BrowserTestCase $test_case) { $this->_testCase = $test_case; $this->_eventDispatcher->addSubscriber($this); + + return $this; } /** diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 790e63e..5fcccdd 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -168,8 +168,7 @@ protected function setUp() */ public function setBrowser(BrowserConfiguration $browser) { - $this->_browser = $browser; - $browser->attachToTestCase($this); + $this->_browser = $browser->attachToTestCase($this); // configure session strategy return $this->setSessionStrategy($this->sessionStrategyManager->getSessionStrategy($browser)); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 81ad008..6e226b2 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -185,8 +185,8 @@ public function testAttachToTestCase() /* @var $test_case BrowserTestCase */ $test_case = m::mock(self::TEST_CASE_CLASS); - $browser->attachToTestCase($test_case); + $this->assertSame($browser, $browser->attachToTestCase($test_case)); $this->assertSame($test_case, $browser->getTestCase()); } diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 4ace87b..1fe56be 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -239,7 +239,7 @@ protected function getBrowser($times) $browser = m::mock(self::BROWSER_CLASS); $browser->shouldReceive('getHost')->times($times)->andReturnNull(); $browser->shouldReceive('getPort')->times($times)->andReturnNull(); - $browser->shouldReceive('attachToTestCase')->once(); + $browser->shouldReceive('attachToTestCase')->once()->andReturn($browser); return $browser; } From ad6fea2e920731009142ddba5b78d2a64cc199ad Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 5 Feb 2014 22:07:42 +0200 Subject: [PATCH 011/204] Detect unknown browser configuration parameters 1. don't validate session strategy inside browser configuration Fixes #10 --- .../BrowserConfiguration.php | 49 +++++++++++-------- .../SauceLabsBrowserConfiguration.php | 6 +-- .../BrowserConfigurationTest.php | 24 ++++----- 3 files changed, 44 insertions(+), 35 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index a748009..f8468a3 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -25,6 +25,26 @@ class BrowserConfiguration implements EventSubscriberInterface, IEventDispatcherAware { + /** + * Default browser configuration. + * + * @var array + */ + protected $defaultParameters = array( + // server related + 'host' => 'localhost', + 'port' => 4444, + 'timeout' => 60, + + // browser related + 'browserName' => 'firefox', + 'desiredCapabilities' => array(), + 'baseUrl' => '', + + // test related + 'sessionStrategy' => SessionStrategyManager::ISOLATED_STRATEGY, + ); + /** * Browser configuration. * @@ -85,20 +105,7 @@ public static function resolveAliases(array $parameters, array $aliases) */ public function __construct() { - $this->parameters = array( - // server related - 'host' => 'localhost', - 'port' => 4444, - 'timeout' => 60, - - // browser related - 'browserName' => 'firefox', - 'desiredCapabilities' => array(), - 'baseUrl' => '', - - // test related - 'sessionStrategy' => SessionStrategyManager::ISOLATED_STRATEGY, - ); + $this->parameters = $this->defaultParameters; } /** @@ -171,10 +178,18 @@ public function setAliases(array $aliases = array()) * @param array $parameters Browser configuration parameters. * * @return self + * @throws \InvalidArgumentException When unknown parameter is discovered. */ public function setup(array $parameters) { $parameters = $this->prepareParameters($parameters); + $unknown_parameters = array_diff(array_keys($parameters), array_keys($this->defaultParameters)); + + if ( $unknown_parameters ) { + throw new \InvalidArgumentException( + 'Following parameter(-s) are unknown: "' . implode('", "', $unknown_parameters) . '"' + ); + } $this->setHost($parameters['host'])->setPort($parameters['port'])->setTimeout($parameters['timeout']); $this->setBrowserName($parameters['browserName'])->setDesiredCapabilities($parameters['desiredCapabilities']); @@ -388,12 +403,6 @@ public function getTimeout() */ public function setSessionStrategy($session_strategy) { - $allowed = array(SessionStrategyManager::ISOLATED_STRATEGY, SessionStrategyManager::SHARED_STRATEGY); - - if ( !in_array($session_strategy, $allowed) ) { - throw new \InvalidArgumentException(vsprintf('Session strategy must be either "%s" or "%s"', $allowed)); - } - $this->parameters['sessionStrategy'] = $session_strategy; return $this; diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index cf538b9..be7aec4 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -47,10 +47,10 @@ class SauceLabsBrowserConfiguration extends BrowserConfiguration */ public function __construct(IBrowserConfigurationFactory $browser_configuration_factory) { - parent::__construct(); - $this->_browserConfigurationFactory = $browser_configuration_factory; - $this->parameters['sauce'] = array('username' => '', 'api_key' => ''); + $this->defaultParameters['sauce'] = array('username' => '', 'api_key' => ''); + + parent::__construct(); } /** diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 6e226b2..82c14d9 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -218,6 +218,17 @@ public function testSetup() $this->assertSame($this->setup['sessionStrategy'], $this->browser->getSessionStrategy()); } + /** + * Test description. + * + * @return void + * @expectedException \InvalidArgumentException + */ + public function testSetupScreamsAboutUnknownParameters() + { + $this->browser->setup(array('unknown-parameter' => 'value')); + } + /** * Test description. * @@ -349,17 +360,6 @@ public function testSetTimeoutCorrect() $this->assertSame($expected, $this->browser->getTimeout()); } - /** - * Test description. - * - * @return void - * @expectedException \InvalidArgumentException - */ - public function testSetSessionStrategyIncorrect() - { - $this->browser->setSessionStrategy('wrong'); - } - /** * Test description. * @@ -368,7 +368,7 @@ public function testSetSessionStrategyIncorrect() * @return void * @dataProvider sessionSharingDataProvider */ - public function testSetSessionStrategyCorrect($expected) + public function testSetSessionStrategy($expected) { $this->assertSame($this->browser, $this->browser->setSessionStrategy($expected)); $this->assertSame($expected, $this->browser->getSessionStrategy()); From f15fff41013df2752a353c1326d3321f7e9ed712 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Thu, 6 Feb 2014 09:23:38 +0200 Subject: [PATCH 012/204] Moving session strategy type constants to ISessionStrategyFactory interface --- .../BrowserConfiguration.php | 6 +++--- .../PHPUnit/Session/ISessionStrategyFactory.php | 10 ++++++++++ .../PHPUnit/Session/SessionStrategyFactory.php | 4 ++-- .../PHPUnit/Session/SessionStrategyManager.php | 14 +++----------- .../BrowserConfigurationTest.php | 16 ++++++++-------- .../SauceLabsBrowserConfigurationTest.php | 10 +++++----- .../Session/SessionStrategyFactoryTest.php | 6 +++--- .../Session/SessionStrategyManagerTest.php | 13 +++++++------ 8 files changed, 41 insertions(+), 38 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index f8468a3..ce50cfa 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -13,7 +13,7 @@ use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\IEventDispatcherAware; -use aik099\PHPUnit\Session\SessionStrategyManager; +use aik099\PHPUnit\Session\ISessionStrategyFactory; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -42,7 +42,7 @@ class BrowserConfiguration implements EventSubscriberInterface, IEventDispatcher 'baseUrl' => '', // test related - 'sessionStrategy' => SessionStrategyManager::ISOLATED_STRATEGY, + 'sessionStrategy' => ISessionStrategyFactory::TYPE_ISOLATED, ); /** @@ -425,7 +425,7 @@ public function getSessionStrategy() */ public function isShared() { - return $this->getSessionStrategy() == SessionStrategyManager::SHARED_STRATEGY; + return $this->getSessionStrategy() == ISessionStrategyFactory::TYPE_SHARED; } /** diff --git a/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php b/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php index b04dfd8..fd44eee 100644 --- a/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php +++ b/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php @@ -19,6 +19,16 @@ interface ISessionStrategyFactory { + /** + * Strategy, that create new session for each test in a test case. + */ + const TYPE_ISOLATED = 'isolated'; + + /** + * Strategy, that allows to share session across all tests in a single test case. + */ + const TYPE_SHARED = 'shared'; + /** * Creates specified session strategy. * diff --git a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php index 3d585d2..05e47d9 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php @@ -52,10 +52,10 @@ public function setApplication(Application $application) */ public function createStrategy($strategy_type) { - if ( $strategy_type == SessionStrategyManager::ISOLATED_STRATEGY ) { + if ( $strategy_type == ISessionStrategyFactory::TYPE_ISOLATED ) { return $this->application->getObject('isolated_session_strategy'); } - elseif ( $strategy_type == SessionStrategyManager::SHARED_STRATEGY ) { + elseif ( $strategy_type == ISessionStrategyFactory::TYPE_SHARED ) { return $this->application->getObject('shared_session_strategy'); } diff --git a/library/aik099/PHPUnit/Session/SessionStrategyManager.php b/library/aik099/PHPUnit/Session/SessionStrategyManager.php index 90af73a..76d5b31 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyManager.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyManager.php @@ -21,16 +21,6 @@ class SessionStrategyManager { - /** - * Strategy, that create new session for each test in a test case. - */ - const ISOLATED_STRATEGY = 'isolated'; - - /** - * Strategy, that allows to share session across all tests in a single test case. - */ - const SHARED_STRATEGY = 'shared'; - /** * Browser configuration used in last executed test. * @@ -77,7 +67,9 @@ public function __construct(ISessionStrategyFactory $session_strategy_factory) public function getDefaultSessionStrategy() { if ( !$this->defaultSessionStrategy ) { - $this->defaultSessionStrategy = $this->_sessionStrategyFactory->createStrategy(self::ISOLATED_STRATEGY); + $this->defaultSessionStrategy = $this->_sessionStrategyFactory->createStrategy( + ISessionStrategyFactory::TYPE_ISOLATED + ); } return $this->defaultSessionStrategy; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 82c14d9..32c8562 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -13,7 +13,7 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Session\SessionStrategyManager; +use aik099\PHPUnit\Session\ISessionStrategyFactory; use Mockery as m; use Mockery\MockInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -80,7 +80,7 @@ protected function setUp() 'browserName' => 'safari', 'desiredCapabilities' => array('platform' => 'Windows 7', 'version' => 10), 'baseUrl' => 'http://other-host', - 'sessionStrategy' => SessionStrategyManager::SHARED_STRATEGY, + 'sessionStrategy' => ISessionStrategyFactory::TYPE_SHARED, ); $this->eventDispatcher = m::mock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); @@ -404,8 +404,8 @@ public function testGetSessionStrategyHashBrowserSharing($session_strategy) public function sessionSharingDataProvider() { return array( - array(SessionStrategyManager::ISOLATED_STRATEGY), - array(SessionStrategyManager::SHARED_STRATEGY), + array(ISessionStrategyFactory::TYPE_ISOLATED), + array(ISessionStrategyFactory::TYPE_SHARED), ); } @@ -418,11 +418,11 @@ public function testGetSessionStrategyHashNotSharing() { $test_case1 = new WithBrowserConfig(); $browser1 = $this->createBrowserConfiguration(array(), true); - $browser1->setSessionStrategy(SessionStrategyManager::SHARED_STRATEGY)->attachToTestCase($test_case1); + $browser1->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED)->attachToTestCase($test_case1); $test_case2 = new WithoutBrowserConfig(); $browser2 = $this->createBrowserConfiguration(array(), true); - $browser2->setSessionStrategy(SessionStrategyManager::SHARED_STRATEGY)->attachToTestCase($test_case2); + $browser2->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED)->attachToTestCase($test_case2); $this->assertNotSame($browser1->getSessionStrategyHash($test_case1), $browser2->getSessionStrategyHash($test_case2)); } @@ -438,7 +438,7 @@ public function testGetTestStatusIsolated() $test_case->shouldReceive('hasFailed')->once()->andReturn(false); $test_result = m::mock('\\PHPUnit_Framework_TestResult'); - $this->browser->setSessionStrategy(SessionStrategyManager::ISOLATED_STRATEGY); + $this->browser->setSessionStrategy(ISessionStrategyFactory::TYPE_ISOLATED); $this->assertTrue($this->browser->getTestStatus($test_case, $test_result)); } @@ -453,7 +453,7 @@ public function testGetTestStatusShared() $test_result = m::mock('\\PHPUnit_Framework_TestResult'); $test_result->shouldReceive('wasSuccessful')->once()->andReturn(true); - $this->browser->setSessionStrategy(SessionStrategyManager::SHARED_STRATEGY); + $this->browser->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED); $this->assertTrue($this->browser->getTestStatus($test_case, $test_result)); } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 827e21f..e758123 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -14,7 +14,7 @@ use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Event\TestEvent; -use aik099\PHPUnit\Session\SessionStrategyManager; +use aik099\PHPUnit\Session\ISessionStrategyFactory; use Mockery\MockInterface; use Symfony\Component\EventDispatcher\EventDispatcher; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; @@ -228,10 +228,10 @@ private function _isAutomaticTestName($test_name) public function setupEventDataProvider() { return array( - 'isolated, name, build' => array(SessionStrategyManager::ISOLATED_STRATEGY, 'TEST_NAME', 'BUILD_NUMBER'), - 'shared, no name, build' => array(SessionStrategyManager::SHARED_STRATEGY, self::AUTOMATIC_TEST_NAME, 'BUILD_NUMBER'), - 'isolated, name, no build' => array(SessionStrategyManager::ISOLATED_STRATEGY, 'TEST_NAME'), - 'shared, no name, no build' => array(SessionStrategyManager::SHARED_STRATEGY, self::AUTOMATIC_TEST_NAME), + 'isolated, name, build' => array(ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME', 'BUILD_NUMBER'), + 'shared, no name, build' => array(ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME, 'BUILD_NUMBER'), + 'isolated, name, no build' => array(ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME'), + 'shared, no name, no build' => array(ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME), ); } diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php index 60e8417..874b852 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php @@ -11,8 +11,8 @@ namespace tests\aik099\PHPUnit\Session; +use aik099\PHPUnit\Session\ISessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyFactory; -use aik099\PHPUnit\Session\SessionStrategyManager; use Mockery as m; use tests\aik099\PHPUnit\TestCase\ApplicationAwareTestCase; @@ -63,8 +63,8 @@ public function testCreateStrategySuccess($strategy_type, $service_id) public function createStrategyDataProvider() { return array( - array(SessionStrategyManager::ISOLATED_STRATEGY, 'isolated_session_strategy'), - array(SessionStrategyManager::SHARED_STRATEGY, 'shared_session_strategy'), + array(ISessionStrategyFactory::TYPE_ISOLATED, 'isolated_session_strategy'), + array(ISessionStrategyFactory::TYPE_SHARED, 'shared_session_strategy'), ); } diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php index 67a9567..4ee884c 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php @@ -12,6 +12,7 @@ use aik099\PHPUnit\Session\ISessionStrategy; +use aik099\PHPUnit\Session\ISessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyManager; use Mockery as m; @@ -85,16 +86,16 @@ public function testGetSessionStrategySharing() }); // sequential identical browser configurations share strategy - $strategy1 = $this->_getStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H1'); - $strategy2 = $this->_getStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H1'); + $strategy1 = $this->_getStrategy(ISessionStrategyFactory::TYPE_ISOLATED, 'H1'); + $strategy2 = $this->_getStrategy(ISessionStrategyFactory::TYPE_ISOLATED, 'H1'); $this->assertSame($strategy1, $strategy2); // different browser configuration use different strategy - $strategy3 = $this->_getStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H2'); + $strategy3 = $this->_getStrategy(ISessionStrategyFactory::TYPE_ISOLATED, 'H2'); $this->assertNotSame($strategy2, $strategy3); // different browser configuration break the sequence - $strategy4 = $this->_getStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'H1'); + $strategy4 = $this->_getStrategy(ISessionStrategyFactory::TYPE_ISOLATED, 'H1'); $this->assertNotSame($strategy1, $strategy4); } @@ -108,7 +109,7 @@ public function testGetSessionStrategyIsolated() $expected = '\\aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'; $this->factory->shouldReceive('createStrategy')->andReturn(m::mock($expected)); - $this->assertInstanceOf($expected, $this->_getStrategy(SessionStrategyManager::ISOLATED_STRATEGY, 'IS1')); + $this->assertInstanceOf($expected, $this->_getStrategy(ISessionStrategyFactory::TYPE_ISOLATED, 'IS1')); } /** @@ -121,7 +122,7 @@ public function testGetSessionStrategyShared() $expected = '\\aik099\\PHPUnit\\Session\\SharedSessionStrategy'; $this->factory->shouldReceive('createStrategy')->andReturn(m::mock($expected)); - $this->assertInstanceOf($expected, $this->_getStrategy(SessionStrategyManager::SHARED_STRATEGY, 'SH1')); + $this->assertInstanceOf($expected, $this->_getStrategy(ISessionStrategyFactory::TYPE_SHARED, 'SH1')); } /** From 410c7c02d8085d9b84f9f46e212f297a271eda04 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Thu, 6 Feb 2014 09:29:48 +0200 Subject: [PATCH 013/204] Inside event listener the session from test case was used instead from even itself --- .../BrowserConfiguration/SauceLabsBrowserConfiguration.php | 7 ++++++- .../SauceLabsBrowserConfigurationTest.php | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index be7aec4..3be8996 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -215,10 +215,15 @@ protected function getJobName(BrowserTestCase $test_case) */ public function onTestEnded(TestEndedEvent $event) { + if ( $event->getSession() === null ) { + // session wasn't used in particular test + return; + } + $test_case = $event->getTestCase(); $this->getAPIClient()->updateJob( - $this->getSessionId($test_case->getSession()), + $this->getSessionId($event->getSession()), array('passed' => $this->getTestStatus($test_case, $event->getTestResult())) ); } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index e758123..77c4199 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -254,7 +254,6 @@ public function testTestEndedEvent() $session->shouldReceive('getDriver')->once()->andReturn(new \stdClass()); $test_case = m::mock(self::TEST_CASE_CLASS); - $test_case->shouldReceive('getSession')->once()->andReturn($session); $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // for shared strategy $test_result = m::mock('PHPUnit_Framework_TestResult'); From d0a6539969d74ee8387c15ea6b936a7e7e432be7 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Thu, 6 Feb 2014 09:53:03 +0200 Subject: [PATCH 014/204] Checking that SauceLabsBrowserConfiguration don't make API call, when no session present 1. also changing dependency to stable Mockery version --- composer.json | 2 +- .../SauceLabsBrowserConfigurationTest.php | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b04a00d..6734997 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ }, "require-dev": { - "mockery/mockery": "dev-master" + "mockery/mockery": "0.9.0" }, "autoload": { diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 77c4199..06c4c9f 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -266,6 +266,28 @@ public function testTestEndedEvent() $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $event); } + /** + * Test description. + * + * @return void + */ + public function testTestEndedWithoutSession() + { + $event_dispatcher = new EventDispatcher(); + $event_dispatcher->addSubscriber($this->browser); + + $event = m::mock('aik099\\PHPUnit\\Event\\TestEndedEvent'); + $event->shouldReceive('getSession')->once(); + $event->shouldReceive('setDispatcher')->once(); // to remove with Symfony 3.0 release + $event->shouldReceive('setName')->once(); // to remove with Symfony 3.0 release + $event->shouldReceive('isPropagationStopped')->once()->andReturn(false); + $event->shouldReceive('getTestCase')->never(); + + $returned_event = $event_dispatcher->dispatch(BrowserTestCase::TEST_ENDED_EVENT, $event); + + $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $returned_event); + } + /** * Creates instance of browser configuration. * From e6bbe83d2a732c285e6a375640c99c32a1ab1ff3 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 8 Feb 2014 16:45:50 +0200 Subject: [PATCH 015/204] Test suite improvements 1. allow to replace services in DIC (for testing) 2. allow to create instances of Application class (for testing) 3. fixing typehint on DIC in Application 4. detaching BrowserConfiguration from BrowserTestCase after test is finished 5. removing pre-event-dispatcher commented-out code 6. minor path change for code coverage collection (for testing) 7. adding tests for Application, DIContainer, 8. create base test case class event dispatcher-based classes testing --- library/aik099/PHPUnit/Application.php | 40 ++++-- .../BrowserConfiguration.php | 28 +++- .../SauceLabsBrowserConfiguration.php | 3 +- library/aik099/PHPUnit/BrowserTestCase.php | 20 +-- .../PHPUnit/Session/SharedSessionStrategy.php | 4 +- .../PHPUnit/TestSuite/AbstractTestSuite.php | 6 +- phpunit.xml.dist | 2 +- tests/aik099/PHPUnit/ApplicationTest.php | 97 +++++++++++++ .../SauceLabsBrowserConfigurationTest.php | 3 + tests/aik099/PHPUnit/BrowserTestCaseTest.php | 42 +++--- .../PHPUnit/Fixture/SetupEventFixture.php | 89 ++++++++++++ .../PHPUnit/Integration/DIContainerTest.php | 79 +++++++++++ .../Integration/EventDispatchingTest.php | 48 +++++++ .../{ => Integration}/SuiteBuildingTest.php | 4 +- .../Session/SharedSessionStrategyTest.php | 2 +- .../TestCase/ApplicationAwareTestCase.php | 7 +- .../TestCase/EventDispatcherAwareTestCase.php | 56 ++++++++ .../TestSuite/BrowserTestSuiteTest.php | 88 ++++++++++++ .../TestSuite/RegularTestSuiteTest.php | 76 +++++++++++ .../TestSuite/TestSuiteBuilderTest.php | 128 ++++++++++++++++++ 20 files changed, 763 insertions(+), 59 deletions(-) create mode 100644 tests/aik099/PHPUnit/ApplicationTest.php create mode 100644 tests/aik099/PHPUnit/Fixture/SetupEventFixture.php create mode 100644 tests/aik099/PHPUnit/Integration/DIContainerTest.php create mode 100644 tests/aik099/PHPUnit/Integration/EventDispatchingTest.php rename tests/aik099/PHPUnit/{ => Integration}/SuiteBuildingTest.php (96%) create mode 100644 tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php create mode 100644 tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php create mode 100644 tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php create mode 100644 tests/aik099/PHPUnit/TestSuite/TestSuiteBuilderTest.php diff --git a/library/aik099/PHPUnit/Application.php b/library/aik099/PHPUnit/Application.php index 41cb1b3..b06b536 100644 --- a/library/aik099/PHPUnit/Application.php +++ b/library/aik099/PHPUnit/Application.php @@ -25,18 +25,18 @@ class Application /** * Dependency injection container. * - * @var \Pimple + * @var DIContainer */ protected $container; /** * Returns instance of strategy manager. * - * @param \Pimple $container Dependency injection container. + * @param DIContainer $container Dependency injection container. * * @return self */ - public static function getInstance(\Pimple $container = null) + public static function getInstance(DIContainer $container = null) { static $instance = null; @@ -50,9 +50,9 @@ public static function getInstance(\Pimple $container = null) /** * Prevents direct instantiation. * - * @param \Pimple $container Dependency injection container. + * @param DIContainer $container Dependency injection container. */ - private function __construct(\Pimple $container = null) + public function __construct(DIContainer $container = null) { if ( !isset($container) ) { $container = new DIContainer(); @@ -76,19 +76,43 @@ public function getTestSuiteBuilder() /** * Returns object from the container. * - * @param string $name Name of the object in the container. + * @param string $serviceId Name of the object in the container. * * @return \stdClass */ - public function getObject($name) + public function getObject($serviceId) { - return $this->container[$name]; + return $this->container[$serviceId]; + } + + /** + * Replaces object in the container. + * + * @param string $service_id Name of the object in the container. + * @param mixed $callable The callable that will return the object. + * @param boolean $is_factory The callable should be considered as a factory. + * + * @return callable Previous service version. + * @throws \InvalidArgumentException When attempt is made to replace non-existing service. + */ + public function replaceObject($service_id, $callable, $is_factory = false) + { + if ( !isset($this->container[$service_id]) ) { + throw new \InvalidArgumentException('Service "' . $service_id . '" not found'); + } + + $backup = $this->container->raw($service_id); + unset($this->container[$service_id]); + $this->container[$service_id] = $is_factory ? $this->container->factory($callable) : $callable; + + return $backup; } /** * Prevents cloning. * * @return void + * @codeCoverageIgnore */ private function __clone() { diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index ce50cfa..8d4ca63 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -12,6 +12,7 @@ use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\IEventDispatcherAware; use aik099\PHPUnit\Session\ISessionStrategyFactory; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -115,7 +116,9 @@ public function __construct() */ public static function getSubscribedEvents() { - return array(); + return array( + BrowserTestCase::TEST_ENDED_EVENT => array('onTestEnded', 100), + ); } /** @@ -145,6 +148,17 @@ public function attachToTestCase(BrowserTestCase $test_case) return $this; } + /** + * Detaches listeners. + * + * @return void + */ + protected function detachFromTestCase() + { + $this->_testCase = null; + $this->_eventDispatcher->removeSubscriber($this); + } + /** * Returns associated test case. * @@ -505,4 +519,16 @@ protected static function arrayMergeRecursive($array1, $array2) return $array1; } + /** + * Hook, called from "BrowserTestCase::run" method. + * + * @param TestEndedEvent $event Test ended event. + * + * @return void + */ + public function onTestEnded(TestEndedEvent $event) + { + $this->detachFromTestCase(); + } + } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 3be8996..cb1fef3 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -62,7 +62,6 @@ public static function getSubscribedEvents() { $events = parent::getSubscribedEvents(); $events[BrowserTestCase::TEST_SETUP_EVENT] = array('onTestSetup', 100); - $events[BrowserTestCase::TEST_ENDED_EVENT] = array('onTestEnded', 100); return $events; } @@ -215,6 +214,8 @@ protected function getJobName(BrowserTestCase $test_case) */ public function onTestEnded(TestEndedEvent $event) { + parent::onTestEnded($event); + if ( $event->getSession() === null ) { // session wasn't used in particular test return; diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 5fcccdd..1e88b5e 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -34,7 +34,7 @@ abstract class BrowserTestCase extends \PHPUnit_Framework_TestCase implements IE const TEST_ENDED_EVENT = 'test.ended'; - const TEST_CASE_ENDED_EVENT = 'test_case.ended'; + const TEST_SUITE_ENDED_EVENT = 'test_suite.ended'; const TEST_FAILED_EVENT = 'test.failed'; @@ -150,13 +150,10 @@ protected function setUp() { parent::setUp(); - // TODO: verify, that still works $this->_eventDispatcher->dispatch( self::TEST_SETUP_EVENT, new TestEvent($this) ); - -// $this->getBrowser()->onTestSetup(new TestEvent($this, $this->_session)); } /** @@ -293,14 +290,15 @@ public function run(\PHPUnit_Framework_TestResult $result = null) $result->getCodeCoverage()->append($this->getRemoteCodeCoverageInformation(), $this); } - // TODO: verify, that still works +// $this->setTestResultObject($result); + // do not call this before to give the time to the Listeners to run $this->_eventDispatcher->dispatch( self::TEST_ENDED_EVENT, new TestEndedEvent($this, $result, $this->_session) ); -// $this->getBrowser()->onTestEnded(new TestEndedEvent($this, $result, $this->_session)); -// $this->getSessionStrategy()->onTestEnd(new TestEndedEvent($this, $result, $this->_session)); + +// $this->setTestResultObject(null); return $result; } @@ -346,14 +344,12 @@ protected function runTest() * * @return self */ - public function endOfTestCase() + public function onTestSuiteEnded() { - // TODO: verify, that still works $this->_eventDispatcher->dispatch( - self::TEST_CASE_ENDED_EVENT, + self::TEST_SUITE_ENDED_EVENT, new TestEvent($this, $this->_session) ); -// $this->getSessionStrategy()->onTestCaseEnd(new TestEvent($this, $this->_session)); return $this; } @@ -393,12 +389,10 @@ public static function suite($class_name) */ protected function onNotSuccessfulTest(\Exception $e) { - // TODO: verify, that still works $this->_eventDispatcher->dispatch( self::TEST_FAILED_EVENT, new TestFailedEvent($e, $this, $this->_session) ); -// $this->getSessionStrategy()->onTestFailed(new TestFailedEvent($this, $e)); parent::onNotSuccessfulTest($e); } diff --git a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php index 75ea4ee..5883dbd 100644 --- a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -66,7 +66,7 @@ public static function getSubscribedEvents() { return array( BrowserTestCase::TEST_FAILED_EVENT => array('onTestFailed', 0), - BrowserTestCase::TEST_CASE_ENDED_EVENT => array('onTestCaseEnd', 0), + BrowserTestCase::TEST_SUITE_ENDED_EVENT => array('onTestSuiteEnd', 0), ); } @@ -157,7 +157,7 @@ public function onTestFailed(TestFailedEvent $event) * * @return void */ - public function onTestCaseEnd(TestEvent $event) + public function onTestSuiteEnd(TestEvent $event) { if ( $event->getSession() !== null ) { $event->getSession()->stop(); diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index c1b41bb..8fad7fd 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -104,7 +104,7 @@ protected function tearDown() /* @var $test BrowserTestCase */ foreach ( $this->tests() as $test ) { - $test->endOfTestCase(); + $test->onTestSuiteEnded(); } } @@ -114,9 +114,9 @@ protected function tearDown() * @return void * @codeCoverageIgnore */ - public function endOfTestCase() + /*public function onTestSuiteEnded() { // method created just to simplify tearDown method - } + }*/ } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a10bbf7..517af0a 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -29,7 +29,7 @@ - library/aik099 + library/aik099/PHPUnit diff --git a/tests/aik099/PHPUnit/ApplicationTest.php b/tests/aik099/PHPUnit/ApplicationTest.php new file mode 100644 index 0000000..1745337 --- /dev/null +++ b/tests/aik099/PHPUnit/ApplicationTest.php @@ -0,0 +1,97 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit; + + +use aik099\PHPUnit\Application; +use Mockery as m; + +class ApplicationTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Application. + * + * @var Application + */ + private $_application; + + /** + * Creates container for testing. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->_application = new Application(); + } + + /** + * Test description. + * + * @return void + */ + public function testInstanceIsShared() + { + $this->assertSame(Application::getInstance(), Application::getInstance()); + } + + /** + * Test description. + * + * @return void + */ + public function testGetTestSuiteBuilder() + { + $this->assertInstanceOf('aik099\\PHPUnit\\TestSuite\\TestSuiteBuilder', $this->_application->getTestSuiteBuilder()); + } + + /** + * Test description. + * + * @return void + */ + public function testGetObject() + { + $this->assertInstanceOf('aik099\\PHPUnit\\Application', $this->_application->getObject('application')); + } + + /** + * Test description. + * + * @return void + */ + public function testReplaceObjectSuccess() + { + $object = new \stdClass(); + $this->_application->replaceObject('application', function ($c) use ($object) { + return $object; + }); + + $this->assertSame($object, $this->_application->getObject('application')); + } + + /** + * Test description. + * + * @return void + * @expectedException \InvalidArgumentException + */ + public function testReplaceObjectFailure() + { + $this->_application->replaceObject('bad_service', function () { + + }); + } + +} diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 06c4c9f..34bcb50 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -258,6 +258,8 @@ public function testTestEndedEvent() $test_result = m::mock('PHPUnit_Framework_TestResult'); + $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); + $event = $event_dispatcher->dispatch( BrowserTestCase::TEST_ENDED_EVENT, new TestEndedEvent($test_case, $test_result, $session) @@ -283,6 +285,7 @@ public function testTestEndedWithoutSession() $event->shouldReceive('isPropagationStopped')->once()->andReturn(false); $event->shouldReceive('getTestCase')->never(); + $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); $returned_event = $event_dispatcher->dispatch(BrowserTestCase::TEST_ENDED_EVENT, $event); $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $returned_event); diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 1fe56be..bd230c6 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -21,8 +21,9 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; +use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; -class BrowserTestCaseTest extends \PHPUnit_Framework_TestCase +class BrowserTestCaseTest extends EventDispatcherAwareTestCase { const BROWSER_CLASS = '\\aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; @@ -38,13 +39,6 @@ class BrowserTestCaseTest extends \PHPUnit_Framework_TestCase */ protected $browserConfigurationFactory; - /** - * Event dispatcher. - * - * @var EventDispatcherInterface|MockInterface - */ - protected $eventDispatcher; - /** * Configures all tests. * @@ -55,7 +49,6 @@ protected function setUp() parent::setUp(); $this->browserConfigurationFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); - $this->eventDispatcher = m::mock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); } /** @@ -342,7 +335,7 @@ public function testRunWithCoverage() */ public function testEndOfTestCase() { - $this->expectEvent(BrowserTestCase::TEST_CASE_ENDED_EVENT); + $this->expectEvent(BrowserTestCase::TEST_SUITE_ENDED_EVENT); /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); @@ -351,7 +344,7 @@ public function testEndOfTestCase() $test_case->setEventDispatcher($this->eventDispatcher); $test_case->setSessionStrategy($session_strategy); - $this->assertSame($test_case, $test_case->endOfTestCase()); + $this->assertSame($test_case, $test_case->onTestSuiteEnded()); } /** @@ -377,6 +370,18 @@ public function testOnTestFailed() $reflection_method->invokeArgs($test_case, array(new \Exception('MSG_TEST'))); } + /** + * Test description. + * + * @return void + */ + public function testGetBrowserAliases() + { + $test_case = $this->getFixture(); + + $this->assertEmpty($test_case->getBrowserAliases(), 'Browser configuration aliases are empty by default'); + } + /** * Prepares test case to be used by "run" method. * @@ -454,19 +459,4 @@ protected function getFixture(ISessionStrategy $session_strategy = null, array $ return $test_case; } - /** - * Expects a specific event to be called. - * - * @param string $event_name Event name. - * - * @return void - */ - protected function expectEvent($event_name) - { - $this->eventDispatcher - ->shouldReceive('dispatch') - ->with($event_name, m::any()) - ->once(); - } - } diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php new file mode 100644 index 0000000..2b4cc83 --- /dev/null +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -0,0 +1,89 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Fixture; + + +use aik099\PHPUnit\Application; +use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use aik099\PHPUnit\BrowserTestCase; +use Behat\Mink\Session; +use Mockery as m; + +class SetupEventFixture extends BrowserTestCase +{ + + /** + * Creating browser configuration that would listen for events. + * + * @return void + */ + protected function setUp() + { + $api_client = m::mock('WebDriver\\SauceLabs\\SauceRest'); + $api_client->shouldReceive('updateJob')->withAnyArgs()->once(); + + $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + $factory->shouldReceive('createAPIClient')->once()->andReturn($api_client); + + $application = Application::getInstance(); + $service_backup = $application->replaceObject('sauce_labs_browser_configuration', function ($c) use ($factory) { + $browser = new SauceLabsBrowserConfiguration($factory); + $browser->setEventDispatcher($c['event_dispatcher']); + + return $browser; + }, true); + + $this->setBrowserFromConfiguration(array( + 'sauce' => array('username' => 'a', 'api_key' => 'b'), + )); + + $application->replaceObject('sauce_labs_browser_configuration', $service_backup, true); + + parent::setUp(); + } + + /** + * Test description. + * + * @return void + */ + public function testEvents() + { + $session = m::mock('Behat\\Mink\\Session'); + + // for SauceLabsBrowserConfiguration::onTestEnded + $session->shouldReceive('getDriver')->once()->andReturn(new \stdClass()); + + // for IsolatedSessionStrategy::onTestEnd + $session->shouldReceive('stop')->once(); + + $this->_setSession($session); + + // for SauceLabsBrowserConfiguration::onTestSetup + $desired_capabilities = $this->getBrowser()->getDesiredCapabilities(); + $this->assertArrayHasKey(SauceLabsBrowserConfiguration::NAME_CAPABILITY, $desired_capabilities); + } + + /** + * Replaces session with a given one. + * + * @param Session $session Session. + * + * @return void + */ + private function _setSession(Session $session) + { + $property = new \ReflectionProperty('aik099\\PHPUnit\\BrowserTestCase', '_session'); + $property->setAccessible(true); + $property->setValue($this, $session); + } + +} diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php new file mode 100644 index 0000000..a0104c4 --- /dev/null +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -0,0 +1,79 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Integration; + + +use aik099\PHPUnit\Application; +use aik099\PHPUnit\DIContainer; +use Mockery as m; + +class DIContainerTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Container. + * + * @var DIContainer + */ + private $_container; + + /** + * Creates container for testing. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->_container = new DIContainer(); + $this->_container->setApplication(new Application()); + } + + /** + * Test description. + * + * @param string $service_id Service ID. + * @param string $class_name Class name. + * + * @return void + * @dataProvider serviceDefinitionsDataProvider + */ + public function testServiceDefinitions($service_id, $class_name) + { + $this->assertInstanceOf($class_name, $this->_container[$service_id]); + } + + /** + * Provides expectations for service definitions. + * + * @return array + */ + public function serviceDefinitionsDataProvider() + { + return array( + array('application', 'aik099\\PHPUnit\\Application'), + array('event_dispatcher', 'Symfony\\Component\\EventDispatcher\\EventDispatcher'), + array('session_factory', 'aik099\\PHPUnit\\Session\\SessionFactory'), + array('session_strategy_factory', 'aik099\\PHPUnit\\Session\\SessionStrategyFactory'), + array('session_strategy_manager', 'aik099\\PHPUnit\\Session\\SessionStrategyManager'), + array('isolated_session_strategy', 'aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'), + array('shared_session_strategy', 'aik099\\PHPUnit\\Session\\SharedSessionStrategy'), + array('test_suite_builder', 'aik099\\PHPUnit\\TestSuite\\TestSuiteBuilder'), + array('regular_test_suite', 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'), + array('browser_test_suite', 'aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'), + array('browser_configuration_factory', 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfigurationFactory'), + array('browser_configuration', 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'), + array('sauce_labs_browser_configuration', 'aik099\\PHPUnit\\BrowserConfiguration\\SauceLabsBrowserConfiguration'), + ); + } + +} diff --git a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php new file mode 100644 index 0000000..61427ba --- /dev/null +++ b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php @@ -0,0 +1,48 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Integration; + + +use Mockery as m; +use tests\aik099\PHPUnit\Fixture\SetupEventFixture; + +class EventDispatchingTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Test description. + * + * @return void + */ + public function testSetupEvent() + { + // BrowserTestCase::TEST_SETUP_EVENT + // - SauceLabsBrowserConfiguration::onTestSetup (called, verified) + + // BrowserTestCase::TEST_ENDED_EVENT + // - IsolatedSessionStrategy::onTestEnd (called, verified) + // - SauceLabsBrowserConfiguration::onTestEnded (called, verified) + + // BrowserTestCase::TEST_SUITE_ENDED_EVENT + // - SharedSessionStrategy::onTestSuiteEnd + + // BrowserTestCase::TEST_FAILED_EVENT + // - SharedSessionStrategy::onTestFailed + + $result = new \PHPUnit_Framework_TestResult(); + + $suite = SetupEventFixture::suite('tests\\aik099\\PHPUnit\\Fixture\\SetupEventFixture'); + $suite->run($result); + + $this->assertTrue($result->wasSuccessful(), 'All sub-tests passed'); + } + +} diff --git a/tests/aik099/PHPUnit/SuiteBuildingTest.php b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php similarity index 96% rename from tests/aik099/PHPUnit/SuiteBuildingTest.php rename to tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php index 14ca51b..5613aad 100644 --- a/tests/aik099/PHPUnit/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php @@ -8,7 +8,7 @@ * @link https://github.com/aik099/phpunit-mink */ -namespace tests\aik099\PHPUnit; +namespace tests\aik099\PHPUnit\Integration; use aik099\PHPUnit\TestSuite\BrowserTestSuite; @@ -102,7 +102,7 @@ protected function createTestSuite($class_name) $suite->shouldReceive('setBackupStaticAttributes')->andReturnNull(); $suite->shouldReceive('run')->once()->andReturnNull(); - $suite->shouldReceive('endOfTestCase')->once()->andReturnNull(); + $suite->shouldReceive('onTestSuiteEnded')->once()->andReturnNull(); return $suite; } diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index 69abd1c..cb5637e 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -169,7 +169,7 @@ public function testEndOfTestCaseWithSession() $session->shouldReceive('stop')->withNoArgs()->once(); $event = $this->eventDispatcher->dispatch( - BrowserTestCase::TEST_CASE_ENDED_EVENT, + BrowserTestCase::TEST_SUITE_ENDED_EVENT, new TestEvent(m::mock(self::TEST_CASE_CLASS), $session) ); diff --git a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php index 789f8bf..9bb006c 100644 --- a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php +++ b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php @@ -47,7 +47,12 @@ protected function setUp() */ protected function expectFactoryCall($service_id, $returned_object) { - $this->application->shouldReceive('getObject')->with($service_id)->andReturn($returned_object); + if ( is_array($returned_object) ) { + $this->application->shouldReceive('getObject')->with($service_id)->andReturnValues($returned_object); + } + else { + $this->application->shouldReceive('getObject')->with($service_id)->andReturn($returned_object); + } } } \ No newline at end of file diff --git a/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php new file mode 100644 index 0000000..41a8d92 --- /dev/null +++ b/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php @@ -0,0 +1,56 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\TestCase; + + +use aik099\PHPUnit\Application; +use Mockery\MockInterface; +use Mockery as m; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +class EventDispatcherAwareTestCase extends \PHPUnit_Framework_TestCase +{ + + /** + * Event dispatcher. + * + * @var EventDispatcherInterface|MockInterface + */ + protected $eventDispatcher; + + /** + * Configures the tests. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->eventDispatcher = m::mock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); + } + + /** + * Expects a specific event to be called. + * + * @param string $event_name Event name. + * + * @return void + */ + protected function expectEvent($event_name) + { + $this->eventDispatcher + ->shouldReceive('dispatch') + ->with($event_name, m::any()) + ->once(); + } + +} diff --git a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php new file mode 100644 index 0000000..303d713 --- /dev/null +++ b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php @@ -0,0 +1,88 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\TestSuite; + + +use aik099\PHPUnit\TestSuite\BrowserTestSuite; +use Mockery as m; +use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; + +class BrowserTestSuiteTest extends EventDispatcherAwareTestCase +{ + + /** + * Suite. + * + * @var BrowserTestSuite + */ + private $_suite; + + /** + * Creates suite for testing. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->_suite = new BrowserTestSuite(); + $this->_suite->setEventDispatcher($this->eventDispatcher); + } + + /** + * Test description. + * + * @param array $browser Browser configuration array. + * @param string $expected_name Expected test name. + * + * @return void + * @dataProvider nameFromBrowserDataProvider + */ + public function testNameFromBrowser(array $browser, $expected_name) + { + $this->assertEquals($expected_name, $this->_suite->nameFromBrowser($browser)); + } + + /** + * Returns various browser configurations. + * + * @return array + */ + public function nameFromBrowserDataProvider() + { + return array( + array(array('alias' => 'match'), 'match'), + array(array('alias' => 'match', 'browserName' => 'no-match'), 'match'), + array(array('browserName' => 'match'), 'match'), + array(array('browserName' => 'match', 'name' => 'no-match'), 'match'), + array(array('name' => 'match'), 'match'), + array(array(), 'undefined'), + ); + } + + /** + * Test description. + * + * @return void + */ + public function testSetBrowserFromConfiguration() + { + $browser = array('name' => 'safari'); + $test = m::mock('PHPUnit_Framework_Test'); + $test->shouldReceive('setBrowserFromConfiguration')->with($browser)->once(); + + $this->_suite->addTest($test); + + $this->assertSame($this->_suite, $this->_suite->setBrowserFromConfiguration($browser)); + } + +} diff --git a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php new file mode 100644 index 0000000..300f306 --- /dev/null +++ b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php @@ -0,0 +1,76 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\TestSuite; + + +use aik099\PHPUnit\TestSuite\RegularTestSuite; +use Mockery as m; +use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; + +class RegularTestSuiteTest extends EventDispatcherAwareTestCase +{ + + /** + * Test description. + * + * @return void + */ + public function testAddTestMethods() + { + $suite = $this->_createSuite(array('addTest')); + $suite->shouldReceive('addTest')->twice(); + + $actual = $suite->addTestMethods('tests\\aik099\\PHPUnit\\Fixture\\WithoutBrowserConfig'); + $this->assertSame($suite, $actual); + } + + /** + * Test description. + * + * @return void + */ + public function testSetTestDependencies() + { + $manager = m::mock('aik099\\PHPUnit\\Session\\SessionStrategyManager'); + $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + + $test = m::mock('PHPUnit_Framework_Test'); + $test->shouldReceive('setEventDispatcher')->with($this->eventDispatcher)->once(); + $test->shouldReceive('setSessionStrategyManager')->with($manager)->once(); + $test->shouldReceive('setBrowserConfigurationFactory')->with($factory)->once(); + + $suite = $this->_createSuite(); + $suite->addTest($test); + $this->assertSame($suite, $suite->setTestDependencies($manager, $factory)); + } + + /** + * Creates suite. + * + * @param array $mock_methods Mock methods. + * + * @return RegularTestSuite + */ + private function _createSuite(array $mock_methods = array()) + { + if ( $mock_methods ) { + $suite = m::mock('aik099\\PHPUnit\\TestSuite\\RegularTestSuite[' . implode(',', $mock_methods) . ']'); + } + else { + $suite = new RegularTestSuite(); + } + + $suite->setEventDispatcher($this->eventDispatcher); + + return $suite; + } + +} diff --git a/tests/aik099/PHPUnit/TestSuite/TestSuiteBuilderTest.php b/tests/aik099/PHPUnit/TestSuite/TestSuiteBuilderTest.php new file mode 100644 index 0000000..fe2f25f --- /dev/null +++ b/tests/aik099/PHPUnit/TestSuite/TestSuiteBuilderTest.php @@ -0,0 +1,128 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\TestSuite; + + +use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; +use aik099\PHPUnit\Session\SessionStrategyManager; +use aik099\PHPUnit\TestSuite\BrowserTestSuite; +use aik099\PHPUnit\TestSuite\TestSuiteBuilder; +use Mockery as m; +use tests\aik099\PHPUnit\TestCase\ApplicationAwareTestCase; + +class TestSuiteBuilderTest extends ApplicationAwareTestCase +{ + + /** + * Suite. + * + * @var TestSuiteBuilder + */ + private $_builder; + + /** + * Session strategy manager. + * + * @var SessionStrategyManager + */ + private $_manager; + + /** + * Browser configuration factory. + * + * @var IBrowserConfigurationFactory + */ + private $_factory; + + /** + * Creates suite for testing. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->_manager = m::mock('aik099\\PHPUnit\\Session\\SessionStrategyManager'); + $this->_factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + $this->_builder = new TestSuiteBuilder($this->_manager, $this->_factory); + $this->_builder->setApplication($this->application); + } + + /** + * Test description. + * + * @return void + */ + public function testCreateSuiteFromTestCaseWithoutBrowsers() + { + $suite_class_name = 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'; + $test_case_class_name = 'tests\\aik099\\PHPUnit\\Fixture\\WithoutBrowserConfig'; + + $suite = m::mock($suite_class_name); + $suite->shouldReceive('setName')->with($test_case_class_name)->once(); + $suite->shouldReceive('addTestMethods')->with($test_case_class_name)->once(); + $suite->shouldReceive('setTestDependencies')->with($this->_manager, $this->_factory)->once(); + $this->expectFactoryCall('regular_test_suite', $suite); + + $actual_suite = $this->_builder->createSuiteFromTestCase($test_case_class_name); + $this->assertInstanceOf($suite_class_name, $actual_suite); + } + + /** + * Test description. + * + * @return void + */ + public function testCreateSuiteFromTestCaseWithBrowsers() + { + $suite_class_name = 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'; + $test_case_class_name = 'tests\\aik099\\PHPUnit\\Fixture\\WithBrowserConfig'; + + $browser_suite1 = $this->_createBrowserTestSuiteMock($test_case_class_name, array( + 'browserName' => 'firefox', 'host' => 'localhost', + )); + $browser_suite2 = $this->_createBrowserTestSuiteMock($test_case_class_name, array( + 'browserName' => 'chrome', 'host' => '127.0.0.1', + )); + $this->expectFactoryCall('browser_test_suite', array($browser_suite1, $browser_suite2)); + + $suite = m::mock($suite_class_name); + $suite->shouldReceive('setName')->with($test_case_class_name)->once(); + $suite->shouldReceive('addTest')->with($browser_suite1)->once(); + $suite->shouldReceive('addTest')->with($browser_suite2)->once(); + $this->expectFactoryCall('regular_test_suite', $suite); + + $actual_suite = $this->_builder->createSuiteFromTestCase($test_case_class_name); + $this->assertInstanceOf($suite_class_name, $actual_suite); + } + + /** + * Creates browser suite mock. + * + * @param string $class_name Descendant of TestCase class. + * @param array $browser Browser configuration. + * + * @return BrowserTestSuite + */ + private function _createBrowserTestSuiteMock($class_name, array $browser) + { + $suite = m::mock('aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'); + $suite->shouldReceive('nameFromBrowser')->with($browser)->once()->andReturn('OK'); + $suite->shouldReceive('setName')->with($class_name . ': OK')->once(); + $suite->shouldReceive('addTestMethods')->with($class_name)->once(); + $suite->shouldReceive('setTestDependencies')->with($this->_manager, $this->_factory)->once(); + $suite->shouldReceive('setBrowserFromConfiguration')->with($browser)->once(); + + return $suite; + } + +} From d1a15c7d338899ad63a3d71a06be19b278f8ffdf Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 9 Feb 2014 12:04:04 +0200 Subject: [PATCH 016/204] Renaming "TestSuiteBuilder" to "TestSuiteFactory" --- library/aik099/PHPUnit/Application.php | 8 +++---- library/aik099/PHPUnit/BrowserTestCase.php | 2 +- library/aik099/PHPUnit/DIContainer.php | 10 ++++---- ...tSuiteBuilder.php => TestSuiteFactory.php} | 2 +- tests/aik099/PHPUnit/ApplicationTest.php | 4 ++-- .../PHPUnit/Integration/DIContainerTest.php | 2 +- ...ilderTest.php => TestSuiteFactoryTest.php} | 24 +++++++++---------- 7 files changed, 26 insertions(+), 26 deletions(-) rename library/aik099/PHPUnit/TestSuite/{TestSuiteBuilder.php => TestSuiteFactory.php} (98%) rename tests/aik099/PHPUnit/TestSuite/{TestSuiteBuilderTest.php => TestSuiteFactoryTest.php} (85%) diff --git a/library/aik099/PHPUnit/Application.php b/library/aik099/PHPUnit/Application.php index b06b536..552fc36 100644 --- a/library/aik099/PHPUnit/Application.php +++ b/library/aik099/PHPUnit/Application.php @@ -11,7 +11,7 @@ namespace aik099\PHPUnit; -use aik099\PHPUnit\TestSuite\TestSuiteBuilder; +use aik099\PHPUnit\TestSuite\TestSuiteFactory; /** @@ -65,12 +65,12 @@ public function __construct(DIContainer $container = null) /** * Returns test suite builder. * - * @return TestSuiteBuilder + * @return TestSuiteFactory * @see BrowserTestCase::suite() */ - public function getTestSuiteBuilder() + public function getTestSuiteFactory() { - return $this->getObject('test_suite_builder'); + return $this->getObject('test_suite_factory'); } /** diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 1e88b5e..ec1ffa5 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -377,7 +377,7 @@ public static function suite($class_name) { $application = Application::getInstance(); - return $application->getTestSuiteBuilder()->createSuiteFromTestCase($class_name); + return $application->getTestSuiteFactory()->createSuiteFromTestCase($class_name); } /** diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index 4d61f54..4db67c7 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -21,7 +21,7 @@ use aik099\PHPUnit\Session\SharedSessionStrategy; use aik099\PHPUnit\TestSuite\BrowserTestSuite; use aik099\PHPUnit\TestSuite\RegularTestSuite; -use aik099\PHPUnit\TestSuite\TestSuiteBuilder; +use aik099\PHPUnit\TestSuite\TestSuiteFactory; use Symfony\Component\EventDispatcher\EventDispatcher; class DIContainer extends \Pimple implements IApplicationAware @@ -83,11 +83,11 @@ public function __construct(array $values = array()) return $session_strategy; }); - $this['test_suite_builder'] = function ($c) { - $test_suite_builder = new TestSuiteBuilder($c['session_strategy_manager'], $c['browser_configuration_factory']); - $test_suite_builder->setApplication($c['application']); + $this['test_suite_factory'] = function ($c) { + $test_suite_factory = new TestSuiteFactory($c['session_strategy_manager'], $c['browser_configuration_factory']); + $test_suite_factory->setApplication($c['application']); - return $test_suite_builder; + return $test_suite_factory; }; $this['regular_test_suite'] = $this->factory(function ($c) { diff --git a/library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php similarity index 98% rename from library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php rename to library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php index c244a96..1597092 100644 --- a/library/aik099/PHPUnit/TestSuite/TestSuiteBuilder.php +++ b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php @@ -22,7 +22,7 @@ * * @method \Mockery\Expectation shouldReceive */ -class TestSuiteBuilder implements IApplicationAware +class TestSuiteFactory implements IApplicationAware { /** diff --git a/tests/aik099/PHPUnit/ApplicationTest.php b/tests/aik099/PHPUnit/ApplicationTest.php index 1745337..ba44ca1 100644 --- a/tests/aik099/PHPUnit/ApplicationTest.php +++ b/tests/aik099/PHPUnit/ApplicationTest.php @@ -51,9 +51,9 @@ public function testInstanceIsShared() * * @return void */ - public function testGetTestSuiteBuilder() + public function testGetTestSuiteFactory() { - $this->assertInstanceOf('aik099\\PHPUnit\\TestSuite\\TestSuiteBuilder', $this->_application->getTestSuiteBuilder()); + $this->assertInstanceOf('aik099\\PHPUnit\\TestSuite\\TestSuiteFactory', $this->_application->getTestSuiteFactory()); } /** diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index a0104c4..7821933 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -67,7 +67,7 @@ public function serviceDefinitionsDataProvider() array('session_strategy_manager', 'aik099\\PHPUnit\\Session\\SessionStrategyManager'), array('isolated_session_strategy', 'aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'), array('shared_session_strategy', 'aik099\\PHPUnit\\Session\\SharedSessionStrategy'), - array('test_suite_builder', 'aik099\\PHPUnit\\TestSuite\\TestSuiteBuilder'), + array('test_suite_factory', 'aik099\\PHPUnit\\TestSuite\\TestSuiteFactory'), array('regular_test_suite', 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'), array('browser_test_suite', 'aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'), array('browser_configuration_factory', 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfigurationFactory'), diff --git a/tests/aik099/PHPUnit/TestSuite/TestSuiteBuilderTest.php b/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php similarity index 85% rename from tests/aik099/PHPUnit/TestSuite/TestSuiteBuilderTest.php rename to tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php index fe2f25f..95e109d 100644 --- a/tests/aik099/PHPUnit/TestSuite/TestSuiteBuilderTest.php +++ b/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php @@ -14,19 +14,19 @@ use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\Session\SessionStrategyManager; use aik099\PHPUnit\TestSuite\BrowserTestSuite; -use aik099\PHPUnit\TestSuite\TestSuiteBuilder; +use aik099\PHPUnit\TestSuite\TestSuiteFactory; use Mockery as m; use tests\aik099\PHPUnit\TestCase\ApplicationAwareTestCase; -class TestSuiteBuilderTest extends ApplicationAwareTestCase +class TestSuiteFactoryTest extends ApplicationAwareTestCase { /** * Suite. * - * @var TestSuiteBuilder + * @var TestSuiteFactory */ - private $_builder; + private $_factory; /** * Session strategy manager. @@ -40,7 +40,7 @@ class TestSuiteBuilderTest extends ApplicationAwareTestCase * * @var IBrowserConfigurationFactory */ - private $_factory; + private $_browserFactory; /** * Creates suite for testing. @@ -52,9 +52,9 @@ protected function setUp() parent::setUp(); $this->_manager = m::mock('aik099\\PHPUnit\\Session\\SessionStrategyManager'); - $this->_factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); - $this->_builder = new TestSuiteBuilder($this->_manager, $this->_factory); - $this->_builder->setApplication($this->application); + $this->_browserFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + $this->_factory = new TestSuiteFactory($this->_manager, $this->_browserFactory); + $this->_factory->setApplication($this->application); } /** @@ -70,10 +70,10 @@ public function testCreateSuiteFromTestCaseWithoutBrowsers() $suite = m::mock($suite_class_name); $suite->shouldReceive('setName')->with($test_case_class_name)->once(); $suite->shouldReceive('addTestMethods')->with($test_case_class_name)->once(); - $suite->shouldReceive('setTestDependencies')->with($this->_manager, $this->_factory)->once(); + $suite->shouldReceive('setTestDependencies')->with($this->_manager, $this->_browserFactory)->once(); $this->expectFactoryCall('regular_test_suite', $suite); - $actual_suite = $this->_builder->createSuiteFromTestCase($test_case_class_name); + $actual_suite = $this->_factory->createSuiteFromTestCase($test_case_class_name); $this->assertInstanceOf($suite_class_name, $actual_suite); } @@ -101,7 +101,7 @@ public function testCreateSuiteFromTestCaseWithBrowsers() $suite->shouldReceive('addTest')->with($browser_suite2)->once(); $this->expectFactoryCall('regular_test_suite', $suite); - $actual_suite = $this->_builder->createSuiteFromTestCase($test_case_class_name); + $actual_suite = $this->_factory->createSuiteFromTestCase($test_case_class_name); $this->assertInstanceOf($suite_class_name, $actual_suite); } @@ -119,7 +119,7 @@ private function _createBrowserTestSuiteMock($class_name, array $browser) $suite->shouldReceive('nameFromBrowser')->with($browser)->once()->andReturn('OK'); $suite->shouldReceive('setName')->with($class_name . ': OK')->once(); $suite->shouldReceive('addTestMethods')->with($class_name)->once(); - $suite->shouldReceive('setTestDependencies')->with($this->_manager, $this->_factory)->once(); + $suite->shouldReceive('setTestDependencies')->with($this->_manager, $this->_browserFactory)->once(); $suite->shouldReceive('setBrowserFromConfiguration')->with($browser)->once(); return $suite; From 68e273b707fdddf1ddc5b6ffca0a203c4c09bb8a Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 9 Feb 2014 14:20:30 +0200 Subject: [PATCH 017/204] Adding contribution instructions --- CONTRIBUTING.md | 21 +++++++++++++++++++++ README.md | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..1dca36f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,21 @@ +# Contributing +PHPUnit-Mink is an open source, community-driven project. If you'd like to contribute, feel free to do this, but remember to follow these few simple rules: + +## Submitting an issues +- A reproducible example is required for every bug report, otherwise it will most probably be __closed without warning__. +- If you are going to make a big, substantial change, let's discuss it first. + +## Working with Pull Requests +1. Create your feature addition or a bug fix branch based on `master` branch in your repository's fork. +2. Make necessary changes, but __don't mix__ code reformatting with code changes on topic. +3. Add tests for those changes (please look into `tests/` folder for some examples). This is important so we don't break it in a future version unintentionally. +4. Commit your code. +5. Squash your commits by topic to preserve a clean and readable log. +6. Create Pull Request. + +# Running tests +Make sure that you don't break anything with your changes by running: + +```bash +$> phpunit +``` diff --git a/README.md b/README.md index 1810e09..268f185 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# phpunit-mink +# PHPUnit-Mink [![Build Status](https://travis-ci.org/aik099/phpunit-mink.png?branch=master)](https://travis-ci.org/aik099/phpunit-mink) [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/aik099/phpunit-mink/badges/quality-score.png?s=57e408500d59e10ce44b604df678ec8b59a1b8f8)](https://scrutinizer-ci.com/g/aik099/phpunit-mink/) [![Coverage Status](https://coveralls.io/repos/aik099/phpunit-mink/badge.png?branch=master)](https://coveralls.io/r/aik099/phpunit-mink?branch=master) From 80c1ca5d5d0ac0d2a55187838aad00b314cb8d3c Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 19 Feb 2014 21:47:19 +0200 Subject: [PATCH 018/204] Improvements to SauceLabsBrowserConfiguration 1. uses only Selenium2Driver and throws exception if session uses other driver 2. uses dedicated `getWebDriverSessionId` method (added in Mink 1.6) for Session ID detection --- composer.json | 4 +- .../SauceLabsBrowserConfiguration.php | 9 ++-- .../SauceLabsBrowserConfigurationTest.php | 42 +++++++++++++++---- .../PHPUnit/Fixture/SetupEventFixture.php | 5 ++- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/composer.json b/composer.json index 6734997..bf22f74 100644 --- a/composer.json +++ b/composer.json @@ -14,8 +14,8 @@ "require": { "php": ">=5.3.2", - "behat/mink": "~1.5", - "behat/mink-selenium2-driver": "~1.1", + "behat/mink": "~1.5@dev", + "behat/mink-selenium2-driver": "~1.1@dev", "symfony/event-dispatcher": "~2.4", "pimple/pimple": "~2.0@dev", "phpunit/phpunit": "3.7.*" diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index cb1fef3..1eeae7a 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -14,6 +14,7 @@ use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Event\TestEvent; +use Behat\Mink\Driver\Selenium2Driver; use Behat\Mink\Session; use WebDriver\SauceLabs\SauceRest; @@ -251,13 +252,11 @@ protected function getSessionId(Session $session) { $driver = $session->getDriver(); - if ( method_exists($driver, 'getWebDriverSession') ) { - $wd_session = $driver->getWebDriverSession(); - - return $wd_session ? basename($wd_session->getUrl()) : ''; + if ( $driver instanceof Selenium2Driver ) { + return $driver->getWebDriverSessionId(); } - return ''; + throw new \RuntimeException('Unsupported session driver'); } } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 34bcb50..049d656 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -15,6 +15,7 @@ use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Event\TestEvent; use aik099\PHPUnit\Session\ISessionStrategyFactory; +use Behat\Mink\Driver\DriverInterface; use Mockery\MockInterface; use Symfony\Component\EventDispatcher\EventDispatcher; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; @@ -238,23 +239,35 @@ public function setupEventDataProvider() /** * Test description. * + * @param string $driver_type Driver. + * * @return void + * @dataProvider theTestEndedEventDataProvider */ - public function testTestEndedEvent() + public function testTestEndedEvent($driver_type) { - $sauce_rest = m::mock('WebDriver\\SauceLabs\\SauceRest'); - $sauce_rest->shouldReceive('updateJob')->with('', array('passed' => true))->once(); + $test_case = m::mock(self::TEST_CASE_CLASS); + $sauce_rest = m::mock('WebDriver\\SauceLabs\\SauceRest'); $this->_browserConfigurationFactory->shouldReceive('createAPIClient')->with($this->browser)->andReturn($sauce_rest); - $event_dispatcher = new EventDispatcher(); - $event_dispatcher->addSubscriber($this->browser); + if ( $driver_type == 'selenium' ) { + $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); + $driver->shouldReceive('getWebDriverSessionId')->once()->andReturn('SID'); + + $sauce_rest->shouldReceive('updateJob')->with('SID', array('passed' => true))->once(); + $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // for shared strategy + } + else { + $driver = m::mock('\\Behat\\Mink\\Driver\\DriverInterface'); + $this->setExpectedException('RuntimeException'); + } $session = m::mock('Behat\\Mink\\Session'); - $session->shouldReceive('getDriver')->once()->andReturn(new \stdClass()); + $session->shouldReceive('getDriver')->once()->andReturn($driver); - $test_case = m::mock(self::TEST_CASE_CLASS); - $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // for shared strategy + $event_dispatcher = new EventDispatcher(); + $event_dispatcher->addSubscriber($this->browser); $test_result = m::mock('PHPUnit_Framework_TestResult'); @@ -268,6 +281,19 @@ public function testTestEndedEvent() $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $event); } + /** + * Returns possible drivers for session creation. + * + * @return array + */ + public function theTestEndedEventDataProvider() + { + return array( + array('selenium'), + array('other'), + ); + } + /** * Test description. * diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index 2b4cc83..08e58b5 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -57,10 +57,13 @@ protected function setUp() */ public function testEvents() { + $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); + $driver->shouldReceive('getWebDriverSessionId')->once()->andReturn('SID'); + $session = m::mock('Behat\\Mink\\Session'); // for SauceLabsBrowserConfiguration::onTestEnded - $session->shouldReceive('getDriver')->once()->andReturn(new \stdClass()); + $session->shouldReceive('getDriver')->once()->andReturn($driver); // for IsolatedSessionStrategy::onTestEnd $session->shouldReceive('stop')->once(); From f1d448f0173c3d45fcf3c2d1b10eca3554352549 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 23 Feb 2014 20:41:07 +0200 Subject: [PATCH 019/204] Improving remote code coverage collection code Related to #13 --- README.md | 21 +- .../BrowserConfiguration.php | 15 ++ .../SauceLabsBrowserConfiguration.php | 15 +- library/aik099/PHPUnit/BrowserTestCase.php | 47 +++- library/aik099/PHPUnit/Common/append.php | 81 ------- .../PHPUnit/Common/phpunit_coverage.php | 100 -------- library/aik099/PHPUnit/Common/prepend.php | 72 ------ library/aik099/PHPUnit/DIContainer.php | 16 +- .../RemoteCoverageHelper.php} | 81 ++++--- .../RemoteCoverage/RemoteCoverageTool.php | 221 ++++++++++++++++++ .../PHPUnit/RemoteCoverage/RemoteUrl.php | 34 +++ .../PHPUnit/TestSuite/AbstractTestSuite.php | 6 +- .../PHPUnit/TestSuite/TestSuiteFactory.php | 25 +- .../BrowserConfigurationTest.php | 4 +- .../SauceLabsBrowserConfigurationTest.php | 1 - tests/aik099/PHPUnit/BrowserTestCaseTest.php | 63 ++++- .../PHPUnit/Common/RemoteCoverageTest.php | 70 ------ .../PHPUnit/Integration/DIContainerTest.php | 2 + .../RemoteCoverageHelperTest.php | 159 +++++++++++++ .../PHPUnit/RemoteCoverage/RemoteUrlTest.php | 32 +++ .../TestCase/ApplicationAwareTestCase.php | 2 +- .../TestCase/EventDispatcherAwareTestCase.php | 1 - .../TestSuite/RegularTestSuiteTest.php | 4 +- .../TestSuite/TestSuiteFactoryTest.php | 22 +- 24 files changed, 686 insertions(+), 408 deletions(-) delete mode 100644 library/aik099/PHPUnit/Common/append.php delete mode 100644 library/aik099/PHPUnit/Common/phpunit_coverage.php delete mode 100644 library/aik099/PHPUnit/Common/prepend.php rename library/aik099/PHPUnit/{Common/RemoteCoverage.php => RemoteCoverage/RemoteCoverageHelper.php} (65%) create mode 100644 library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php create mode 100644 library/aik099/PHPUnit/RemoteCoverage/RemoteUrl.php delete mode 100644 tests/aik099/PHPUnit/Common/RemoteCoverageTest.php create mode 100644 tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php create mode 100644 tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php diff --git a/README.md b/README.md index 268f185..53253e9 100644 --- a/README.md +++ b/README.md @@ -211,18 +211,27 @@ Browser tests are executed on different machine, then one, where code coverage i Remote server is web-server, where website used in tests is located. 1. Install [Xdebug](http://xdebug.org/) PHP extension on web-server -2. Copy `library/aik099/PHPUnit/Common/phpunit_coverage.php` into web-server's DocumentRoot directory. -3. In web-server's `php.ini` configuration file (or `.htaccess` file), configure `library/aik099/PHPUnit/Common/prepend.php` and `library/aik099/PHPUnit/Common/append.php` as the `auto_prepend_file` and `auto_append_file` setting values, respectively. +2. Copy `library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php` into web-server's DocumentRoot directory. +3. Include following code before your application bootstraps: + +```php +require_once 'RemoteCoverageTool.php'; +\aik099\PHPUnit\RemoteCoverage\RemoteCoverageTool::init(); +``` ### On Test Machine This is machine, where PHPUnit tests are being executed. -1. In test case class that extends `BrowserTestCase` class, add `protected $coverageScriptUrl = 'http://host/phpunit_coverage.php';` to specify the URL for the `phpunit_coverage.php` script (`host` should be replaced with web server's url). +By default the `baseUrl` setting from browser configuration is used as the `remote code coverage information url`. However if a need exists to set alternative url on per-test basis, then place following code in the `setUp` method of the test case class, that extends `BrowserTestCase` class: + +```php + $this->setRemoteCoverageScriptUrl('http://host/'); // `host` should be replaced with web server's url +``` ### How This Works 1. each test sets a special cookie on website under test -2. when cookie is present, then `prepend.php` script collects coverage information and `append.php` stores it on disk -3. once test finishes it queries `phpunit_coverage.php` script on remote server, which in turn returns collected coverage information +2. when cookie is present, then `RemoteCoverageTool.php` script collects coverage information and stores it on disk +3. once test finishes, then `http://host/?rct_mode=output` url is accessed on remote server, which in turn returns collected coverage information 4. remote coverage information is then joined with coverage information collected locally on test machine ## Browser Configuration in Details @@ -259,4 +268,4 @@ There are also corresponding `set` and `get` methods for each of mentioned above ```bash $ curl http://getcomposer.org/installer | php $ php composer.phar install -``` \ No newline at end of file +``` diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 8d4ca63..4dcddc2 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -13,6 +13,7 @@ use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\Event\TestEndedEvent; +use aik099\PHPUnit\Event\TestEvent; use aik099\PHPUnit\IEventDispatcherAware; use aik099\PHPUnit\Session\ISessionStrategyFactory; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -117,6 +118,7 @@ public function __construct() public static function getSubscribedEvents() { return array( + BrowserTestCase::TEST_SETUP_EVENT => array('onTestSetup', 100), BrowserTestCase::TEST_ENDED_EVENT => array('onTestEnded', 100), ); } @@ -143,6 +145,7 @@ public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) public function attachToTestCase(BrowserTestCase $test_case) { $this->_testCase = $test_case; + $this->_testCase->setRemoteCoverageScriptUrl($this->getBaseUrl()); $this->_eventDispatcher->addSubscriber($this); return $this; @@ -519,6 +522,18 @@ protected static function arrayMergeRecursive($array1, $array2) return $array1; } + /** + * Hook, called from "BrowserTestCase::setUp" method. + * + * @param TestEvent $event Test event. + * + * @return void + */ + public function onTestSetup(TestEvent $event) + { + + } + /** * Hook, called from "BrowserTestCase::run" method. * diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 1eeae7a..b2333f5 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -54,19 +54,6 @@ public function __construct(IBrowserConfigurationFactory $browser_configuration_ parent::__construct(); } - /** - * Returns an array of event names this subscriber wants to listen to. - * - * @return array The event names to listen to - */ - public static function getSubscribedEvents() - { - $events = parent::getSubscribedEvents(); - $events[BrowserTestCase::TEST_SETUP_EVENT] = array('onTestSetup', 100); - - return $events; - } - /** * Initializes a browser with given configuration. * @@ -178,6 +165,8 @@ public function getDesiredCapabilities() */ public function onTestSetup(TestEvent $event) { + parent::onTestSetup($event); + $desired_capabilities = $this->getDesiredCapabilities(); $desired_capabilities[self::NAME_CAPABILITY] = $this->getJobName($event->getTestCase()); diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index ec1ffa5..37b24ff 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -13,7 +13,8 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; -use aik099\PHPUnit\Common\RemoteCoverage; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageTool; use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Event\TestEvent; use aik099\PHPUnit\Event\TestFailedEvent; @@ -66,7 +67,7 @@ abstract class BrowserTestCase extends \PHPUnit_Framework_TestCase implements IE * * @var string Override to provide code coverage data from the server */ - protected $coverageScriptUrl; + private $_remoteCoverageScriptUrl; /** * Current browser configuration. @@ -89,6 +90,13 @@ abstract class BrowserTestCase extends \PHPUnit_Framework_TestCase implements IE */ protected $sessionStrategyManager; + /** + * Remote coverage helper. + * + * @var RemoteCoverageHelper + */ + protected $remoteCoverageHelper; + /** * Session strategy, used currently. * @@ -141,6 +149,30 @@ public function setSessionStrategyManager(SessionStrategyManager $session_strate return $this; } + /** + * Sets remote coverage helper. + * + * @param RemoteCoverageHelper $remote_coverage_helper Remote coverage helper. + * + * @return void + */ + public function setRemoteCoverageHelper(RemoteCoverageHelper $remote_coverage_helper) + { + $this->remoteCoverageHelper = $remote_coverage_helper; + } + + /** + * Sets base url for remote coverage information collection. + * + * @param string $url URL. + * + * @return void + */ + public function setRemoteCoverageScriptUrl($url) + { + $this->_remoteCoverageScriptUrl = $url; + } + /** * Set session meta-info for "Sauce Labs". * @@ -332,8 +364,8 @@ protected function runTest() $this->_testId = get_class($this) . '__' . $this->getName(); $session = $this->getSession(); - $session->setCookie('PHPUNIT_SELENIUM_TEST_ID', null); - $session->setCookie('PHPUNIT_SELENIUM_TEST_ID', $this->_testId); + $session->setCookie(RemoteCoverageTool::TEST_ID_VARIABLE, null); + $session->setCookie(RemoteCoverageTool::TEST_ID_VARIABLE, $this->_testId); } return parent::runTest(); @@ -358,12 +390,15 @@ public function onTestSuiteEnded() * Returns remote code coverage information. * * @return array + * @throws \RuntimeException When no remote coverage script URL set. */ public function getRemoteCodeCoverageInformation() { - $remote_coverage = new RemoteCoverage($this->coverageScriptUrl, $this->_testId); + if ( $this->_remoteCoverageScriptUrl == '' ) { + throw new \RuntimeException('Remote coverage script url not set'); + } - return $remote_coverage->get(); + return $this->remoteCoverageHelper->get($this->_remoteCoverageScriptUrl, $this->_testId); } /** diff --git a/library/aik099/PHPUnit/Common/append.php b/library/aik099/PHPUnit/Common/append.php deleted file mode 100644 index 172d404..0000000 --- a/library/aik099/PHPUnit/Common/append.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -/** - * PHPUnit - * - * Copyright (c) 2010-2013, Sebastian Bergmann . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package PHPUnit_Selenium - * @author Sebastian Bergmann - * @copyright 2010-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://www.phpunit.de/ - * @since File available since Release 1.0.0 - */ - -if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && - !isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) && - extension_loaded('xdebug') -) { - $GLOBALS['PHPUNIT_FILTERED_FILES'][] = __FILE__; - - $data = xdebug_get_code_coverage(); - xdebug_stop_code_coverage(); - - foreach ($GLOBALS['PHPUNIT_FILTERED_FILES'] as $file) { - unset($data[$file]); - } - - if ( is_string($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']) && - is_dir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']) - ) { - $file = $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] . - DIRECTORY_SEPARATOR . md5($_SERVER['SCRIPT_FILENAME']); - } - else { - $file = $_SERVER['SCRIPT_FILENAME']; - } - - file_put_contents( - $name = $file . '.' . md5(uniqid(rand(), true)) . '.' . $_COOKIE['PHPUNIT_SELENIUM_TEST_ID'], - serialize($data) - ); -} diff --git a/library/aik099/PHPUnit/Common/phpunit_coverage.php b/library/aik099/PHPUnit/Common/phpunit_coverage.php deleted file mode 100644 index f2031ca..0000000 --- a/library/aik099/PHPUnit/Common/phpunit_coverage.php +++ /dev/null @@ -1,100 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -/** - * PHPUnit - * - * Copyright (c) 2010-2013, Sebastian Bergmann . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package PHPUnit_Selenium - * @author Sebastian Bergmann - * @copyright 2010-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://www.phpunit.de/ - * @since File available since Release 1.0.0 - */ - -require_once 'File/Iterator/Autoload.php'; -require_once 'PHP/CodeCoverage/Autoload.php'; - -// Set this to the directory that contains the code coverage files. -// It defaults to getcwd(). If you have configured a different directory -// in prepend.php, you need to configure the same directory here. - -if ( !isset($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']) ) { - $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = getcwd(); -} - -if ( isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) ) { - $facade = new File_Iterator_Facade(); - - $files = $facade->getFilesAsArray( - $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'], - $_GET['PHPUNIT_SELENIUM_TEST_ID'] - ); - - $coverage = array(); - - foreach ($files as $file) { - $data = unserialize(file_get_contents($file)); - unlink($file); - unset($file); - $filter = new PHP_CodeCoverage_Filter(); - - foreach ($data as $file => $lines) { - if ( $filter->isFile($file) ) { - if ( !isset($coverage[$file]) ) { - $coverage[$file] = array('md5' => md5_file($file), 'coverage' => $lines); - } - else { - foreach ($lines as $line => $flag) { - if ( !isset($coverage[$file]['coverage'][$line]) || - $flag > $coverage[$file]['coverage'][$line] - ) { - $coverage[$file]['coverage'][$line] = $flag; - } - } - } - } - } - } - - print serialize($coverage); -} diff --git a/library/aik099/PHPUnit/Common/prepend.php b/library/aik099/PHPUnit/Common/prepend.php deleted file mode 100644 index 05171b6..0000000 --- a/library/aik099/PHPUnit/Common/prepend.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -/** - * PHPUnit - * - * Copyright (c) 2010-2013, Sebastian Bergmann . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * * Neither the name of Sebastian Bergmann nor the names of his - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package PHPUnit_Selenium - * @author Sebastian Bergmann - * @copyright 2010-2013 Sebastian Bergmann - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://www.phpunit.de/ - * @since File available since Release 1.0.0 - */ - -// By default the code coverage files are written to the same directory -// that contains the covered sourcecode files. Use this setting to change -// the default behaviour and set a specific directory to write the files to. -// If you change the default setting, please make sure to also configure -// the same directory in phpunit_coverage.php. Also note that the webserver -// needs write access to the directory. - -if ( !isset($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']) ) { - $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = false; -} - -if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && - !isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) && - extension_loaded('xdebug') -) { - $GLOBALS['PHPUNIT_FILTERED_FILES'] = array(__FILE__); - - xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); -} diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index 4db67c7..086d3e8 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -14,6 +14,8 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; +use aik099\PHPUnit\RemoteCoverage\RemoteUrl; use aik099\PHPUnit\Session\IsolatedSessionStrategy; use aik099\PHPUnit\Session\SessionFactory; use aik099\PHPUnit\Session\SessionStrategyFactory; @@ -83,8 +85,20 @@ public function __construct(array $values = array()) return $session_strategy; }); + $this['remote_url'] = function ($c) { + return new RemoteUrl(); + }; + + $this['remote_coverage_helper'] = function ($c) { + return new RemoteCoverageHelper($c['remote_url']); + }; + $this['test_suite_factory'] = function ($c) { - $test_suite_factory = new TestSuiteFactory($c['session_strategy_manager'], $c['browser_configuration_factory']); + $test_suite_factory = new TestSuiteFactory( + $c['session_strategy_manager'], + $c['browser_configuration_factory'], + $c['remote_coverage_helper'] + ); $test_suite_factory->setApplication($c['application']); return $test_suite_factory; diff --git a/library/aik099/PHPUnit/Common/RemoteCoverage.php b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php similarity index 65% rename from library/aik099/PHPUnit/Common/RemoteCoverage.php rename to library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php index 4156100..7ec9f24 100644 --- a/library/aik099/PHPUnit/Common/RemoteCoverage.php +++ b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php @@ -8,7 +8,7 @@ * @link https://github.com/aik099/phpunit-mink */ -namespace aik099\PHPUnit\Common; +namespace aik099\PHPUnit\RemoteCoverage; /** @@ -16,61 +16,39 @@ * * @method \Mockery\Expectation shouldReceive */ -class RemoteCoverage +class RemoteCoverageHelper { /** - * Url to a script, that will provide remote coverage information. + * Remote URL. * - * @var string + * @var RemoteUrl */ - private $_coverageScriptUrl; - - /** - * ID of test, that to look for. - * - * @var string - */ - private $_testId; + private $_remoteUrl; /** * Creates an instance of remote coverage class. * - * @param string $coverage_script_url Coverage script irl. - * @param string $test_id Test ID. - * - * @throws \InvalidArgumentException When empty coverage script url given. - */ - public function __construct($coverage_script_url, $test_id) - { - if ( empty($coverage_script_url) ) { - throw new \InvalidArgumentException('Coverage script url is empty'); - } - - $this->_coverageScriptUrl = $coverage_script_url; - $this->_testId = $test_id; - } - - /** - * Returns raw remote coverage information. - * - * @return string + * @param RemoteUrl $remote_url Remote URL. */ - public function getFetchUrl() + public function __construct(RemoteUrl $remote_url) { - return sprintf('%s?PHPUNIT_SELENIUM_TEST_ID=%s', $this->_coverageScriptUrl, $this->_testId); + $this->_remoteUrl = $remote_url; } /** * Retrieves remote coverage information. * + * @param string $coverage_script_url Coverage script irl. + * @param string $test_id Test ID. + * + * @throws \RuntimeException Broken code coverage retrieved. * @return array - * @throws \Exception When no data was retrieved. */ - public function get() + public function get($coverage_script_url, $test_id) { - $url = $this->getFetchUrl(); - $buffer = file_get_contents($url); + $url = $this->createUrl($coverage_script_url, $test_id); + $buffer = $this->_remoteUrl->getPageContent($url); if ( $buffer !== false ) { $coverage_data = unserialize($buffer); @@ -79,12 +57,39 @@ public function get() return $this->matchLocalAndRemotePaths($coverage_data); } - throw new \RuntimeException(sprintf('Empty or invalid code coverage data received from url "%s"', $url)); + throw new \RuntimeException('Empty or invalid code coverage data received from url "' . $url . '"'); } return array(); } + /** + * Returns url for remote code coverage collection. + * + * @param string $coverage_script_url Coverage script irl. + * @param string $test_id Test ID. + * + * @return string + * @throws \InvalidArgumentException When empty coverage script url given. + */ + protected function createUrl($coverage_script_url, $test_id) + { + if ( !$coverage_script_url || !$test_id ) { + throw new \InvalidArgumentException('Both Coverage script URL and Test ID must be filled in'); + } + + $query_string = array( + 'rct_mode' => 'output', + RemoteCoverageTool::TEST_ID_VARIABLE => $test_id, + ); + + $url = $coverage_script_url; + $url .= strpos($url, '?') === false ? '?' : '&'; + $url .= http_build_query($query_string); + + return $url; + } + /** * Returns only files from remote server, that are matching files on test machine. * diff --git a/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php new file mode 100644 index 0000000..1aad083 --- /dev/null +++ b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php @@ -0,0 +1,221 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\RemoteCoverage; + + +require_once 'File/Iterator/Autoload.php'; +require_once 'PHP/CodeCoverage/Autoload.php'; + +class RemoteCoverageTool +{ + + const TEST_ID_VARIABLE = 'PHPUNIT_MINK_TEST_ID'; + + const DATA_DIRECTORY_VARIABLE = 'PHPUNIT_MINK_COVERAGE_DATA_DIRECTORY'; + + /** + * Directory for coverage information collection. + * + * @var string + */ + protected $dataDirectory; + + /** + * Files, excluded from coverage collection. + * + * @var array + */ + protected $excludedFiles = array(__FILE__); + + /** + * Collects & reports coverage information. + * + * @param string|null $data_directory Directory for coverage information collection. + * + * @return void + */ + public static function init($data_directory = null) + { + $coverage_tool = new self($data_directory); + $mode = isset($_GET['rct_mode']) ? $_GET['rct_mode'] : ''; + + if ( $mode == 'output' ) { + echo $coverage_tool->aggregateCoverageInformation(); + } + else { + $coverage_tool->startCollection(); + register_shutdown_function(array($coverage_tool, 'stopCollection')); + } + } + + /** + * Creates an instance of remove coverage tool. + * + * @param string|null $data_directory Directory for coverage information collection. + */ + public function __construct($data_directory = null) + { + if ( !isset($data_directory) ) { + if ( isset($GLOBALS[self::DATA_DIRECTORY_VARIABLE]) ) { + $this->dataDirectory = $this->assertDirectory($GLOBALS[self::DATA_DIRECTORY_VARIABLE]); + } + else { + $this->dataDirectory = getcwd(); + } + } + else { + $this->dataDirectory = $this->assertDirectory($data_directory); + } + } + + /** + * Checks that a directory is valid. + * + * @param string $directory Directory. + * + * @throws \InvalidArgumentException When directory is invalid. + * @return string + */ + protected function assertDirectory($directory) + { + if ( !is_string($directory) || !is_dir($directory) || !file_exists($directory) ) { + throw new \InvalidArgumentException('Directory "' . $directory . '" is invalid'); + } + + return $directory; + } + + /** + * Excludes a file from coverage. + * + * @param string $file Path to file, that needs to be excluded. + * + * @return void + */ + public function excludeFile($file) + { + $this->excludedFiles[] = $file; + } + + /** + * Starts coverage information collection. + * + * @return void + */ + public function startCollection() + { + if ( !$this->enabled() ) { + return; + } + + xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); + } + + /** + * Stops coverage information collection. + * + * @return void + */ + public function stopCollection() + { + if ( !$this->enabled() ) { + return; + } + + $data = xdebug_get_code_coverage(); + xdebug_stop_code_coverage(); + + foreach ( $this->excludedFiles as $file ) { + unset($data[$file]); + } + + file_put_contents( + $name = $this->getStorageLocationPrefix() . '.' . md5(uniqid(rand(), true)) . '.' . $_COOKIE[self::TEST_ID_VARIABLE], + serialize($data) + ); + } + + /** + * Determines if coverage information collection can be started. + * + * @return string + * @throws \RuntimeException When Xdebug extension not enabled. + */ + protected function enabled() + { + if ( !extension_loaded('xdebug') ) { + throw new \RuntimeException('Xdebug extension must be enabled for coverage collection'); + } + + return isset($_COOKIE[self::TEST_ID_VARIABLE]) && !isset($_GET[self::TEST_ID_VARIABLE]); + } + + /** + * Returns name of the file, where coverage information will be stored. + * + * @return string + */ + protected function getStorageLocationPrefix() + { + return $this->dataDirectory . DIRECTORY_SEPARATOR . md5($_SERVER['SCRIPT_FILENAME']); + } + + /** + * Aggregates previously collected coverage information. + * + * @return string + */ + public function aggregateCoverageInformation() + { + if ( !isset($_GET[self::TEST_ID_VARIABLE]) ) { + return ''; + } + + $coverage = array(); + $filter = new \PHP_CodeCoverage_Filter(); + + foreach ( $this->getDataDirectoryFiles() as $data_directory_file ) { + $raw_coverage_data = unserialize(file_get_contents($data_directory_file)); + + foreach ( $raw_coverage_data as $file => $lines ) { + if ( !$filter->isFile($file) ) { + continue; + } + + if ( !isset($coverage[$file]) ) { + $coverage[$file] = array('md5' => md5_file($file), 'coverage' => $lines); + } + else { + foreach ( $lines as $line => $flag ) { + if ( !isset($coverage[$file]['coverage'][$line]) || $flag > $coverage[$file]['coverage'][$line] ) { + $coverage[$file]['coverage'][$line] = $flag; + } + } + } + } + } + + return serialize($coverage); + } + + /** + * Returns contents of data directory for a current test. + * + * @return array + */ + protected function getDataDirectoryFiles() + { + $facade = new \File_Iterator_Facade(); + + return $facade->getFilesAsArray($this->dataDirectory, $_GET[self::TEST_ID_VARIABLE]); + } + +} diff --git a/library/aik099/PHPUnit/RemoteCoverage/RemoteUrl.php b/library/aik099/PHPUnit/RemoteCoverage/RemoteUrl.php new file mode 100644 index 0000000..b54020c --- /dev/null +++ b/library/aik099/PHPUnit/RemoteCoverage/RemoteUrl.php @@ -0,0 +1,34 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\RemoteCoverage; + + +/** + * Class makes request to remote server and returns url. + * + * @method \Mockery\Expectation shouldReceive + */ +class RemoteUrl +{ + + /** + * Returns content of the page from given URL. + * + * @param string $url Page URL. + * + * @return string + */ + public function getPageContent($url) + { + return file_get_contents($url); + } + +} diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index 8fad7fd..808bcea 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -14,6 +14,7 @@ use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\IEventDispatcherAware; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\Session\SessionStrategyManager; use ReflectionClass; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -76,12 +77,14 @@ public function addTestMethods($class_name) * * @param SessionStrategyManager $session_strategy_manager Session strategy manager. * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. + * @param RemoteCoverageHelper $remote_coverage_helper Remote coverage helper. * * @return self */ public function setTestDependencies( SessionStrategyManager $session_strategy_manager, - IBrowserConfigurationFactory $browser_configuration_factory + IBrowserConfigurationFactory $browser_configuration_factory, + RemoteCoverageHelper $remote_coverage_helper ) { /* @var $test BrowserTestCase */ @@ -89,6 +92,7 @@ public function setTestDependencies( $test->setEventDispatcher($this->_eventDispatcher); $test->setSessionStrategyManager($session_strategy_manager); $test->setBrowserConfigurationFactory($browser_configuration_factory); + $test->setRemoteCoverageHelper($remote_coverage_helper); } return $this; diff --git a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php index 1597092..ae2e36c 100644 --- a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php +++ b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php @@ -13,6 +13,7 @@ use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\IApplicationAware; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\Session\SessionStrategyManager; use aik099\PHPUnit\Application; @@ -46,19 +47,29 @@ class TestSuiteFactory implements IApplicationAware */ private $_browserConfigurationFactory; + /** + * Remote coverage helper. + * + * @var RemoteCoverageHelper + */ + private $_remoteCoverageHelper; + /** * Creates test suite builder instance. * * @param SessionStrategyManager $session_strategy_manager Session strategy manager. * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. + * @param RemoteCoverageHelper $remote_coverage_helper Remote coverage helper. */ public function __construct( SessionStrategyManager $session_strategy_manager, - IBrowserConfigurationFactory $browser_configuration_factory + IBrowserConfigurationFactory $browser_configuration_factory, + RemoteCoverageHelper $remote_coverage_helper ) { $this->_sessionStrategyManager = $session_strategy_manager; $this->_browserConfigurationFactory = $browser_configuration_factory; + $this->_remoteCoverageHelper = $remote_coverage_helper; } /** @@ -97,7 +108,11 @@ public function createSuiteFromTestCase($class_name) else { // create tests from test methods for single browser $suite->addTestMethods($class_name); - $suite->setTestDependencies($this->_sessionStrategyManager, $this->_browserConfigurationFactory); + $suite->setTestDependencies( + $this->_sessionStrategyManager, + $this->_browserConfigurationFactory, + $this->_remoteCoverageHelper + ); } return $suite; @@ -133,7 +148,11 @@ private function _createBrowserSuite($class_name, array $browser) $suite->setName($class_name . ': ' . $suite->nameFromBrowser($browser)); $suite->addTestMethods($class_name); - $suite->setTestDependencies($this->_sessionStrategyManager, $this->_browserConfigurationFactory); + $suite->setTestDependencies( + $this->_sessionStrategyManager, + $this->_browserConfigurationFactory, + $this->_remoteCoverageHelper + ); $suite->setBrowserFromConfiguration($browser); return $suite; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 32c8562..c05b991 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -185,6 +185,7 @@ public function testAttachToTestCase() /* @var $test_case BrowserTestCase */ $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('setRemoteCoverageScriptUrl')->with('')->once(); $this->assertSame($browser, $browser->attachToTestCase($test_case)); $this->assertSame($test_case, $browser->getTestCase()); @@ -384,8 +385,9 @@ public function testSetSessionStrategy($expected) */ public function testGetSessionStrategyHashBrowserSharing($session_strategy) { - $test_case = m::mock(self::TEST_CASE_CLASS); /* @var $test_case BrowserTestCase */ + $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('setRemoteCoverageScriptUrl')->with('')->twice(); $browser1 = $this->createBrowserConfiguration(array(), true); $browser1->setSessionStrategy($session_strategy)->attachToTestCase($test_case); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 049d656..584f4fd 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -15,7 +15,6 @@ use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Event\TestEvent; use aik099\PHPUnit\Session\ISessionStrategyFactory; -use Behat\Mink\Driver\DriverInterface; use Mockery\MockInterface; use Symfony\Component\EventDispatcher\EventDispatcher; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index bd230c6..3ae4330 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -14,11 +14,11 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageTool; use aik099\PHPUnit\Session\ISessionStrategy; use aik099\PHPUnit\Session\SessionStrategyManager; use Mockery as m; use Mockery\MockInterface; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; @@ -293,16 +293,57 @@ public function testRunCreateResult() * Test description. * * @return void + * @expectedException \RuntimeException */ - public function testRunWithCoverage() + public function testRunWithCoverageWithoutRemoteUrl() { /* @var $test_case BrowserTestCase */ /* @var $session_strategy ISessionStrategy */ - list($test_case, $session_strategy) = $this->prepareForRun(array('getRemoteCodeCoverageInformation')); + list($test_case, $session_strategy) = $this->prepareForRun(array(), false); $test_case->setName('getTestId'); + $result = $this->getTestResult($test_case, 1, true); + $result->shouldReceive('getCodeCoverage')->once()->andReturn(m::mock('\\PHP_CodeCoverage')); + + $test_id = $test_case->getTestId(); + $this->assertEmpty($test_id); + + $browser = $test_case->getBrowser(); + $browser->shouldReceive('getBaseUrl')->once()->andReturn('A'); + + $session = m::mock('\\Behat\\Mink\\Session'); + $session->shouldReceive('visit')->with('A')->once()->andReturnNull(); + $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, null)->once()->andReturnNull(); + $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, m::not(''))->once()->andReturnNull(); + + $session_strategy->shouldReceive('session')->once()->andReturn($session); + + $test_case->run($result); + + $this->assertNotEmpty($test_case->getTestId()); + } + + /** + * Test description. + * + * @return void + */ + public function testRunWithCoverage() + { $expected_coverage = array('test1' => 'test2'); - $test_case->shouldReceive('getRemoteCodeCoverageInformation')->andReturn($expected_coverage); + + $remote_coverage_helper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); + $remote_coverage_helper + ->shouldReceive('get') + ->with('some-url', 'tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig__getTestId') + ->andReturn($expected_coverage); + + /* @var $test_case BrowserTestCase */ + /* @var $session_strategy ISessionStrategy */ + list($test_case, $session_strategy) = $this->prepareForRun(); + $test_case->setName('getTestId'); + $test_case->setRemoteCoverageHelper($remote_coverage_helper); + $test_case->setRemoteCoverageScriptUrl('some-url'); $code_coverage = m::mock('\\PHP_CodeCoverage'); $code_coverage->shouldReceive('append')->with($expected_coverage, $test_case)->once()->andReturnNull(); @@ -318,8 +359,8 @@ public function testRunWithCoverage() $session = m::mock('\\Behat\\Mink\\Session'); $session->shouldReceive('visit')->with('A')->once()->andReturnNull(); - $session->shouldReceive('setCookie')->with('PHPUNIT_SELENIUM_TEST_ID', null)->once()->andReturnNull(); - $session->shouldReceive('setCookie')->with('PHPUNIT_SELENIUM_TEST_ID', m::not(''))->once()->andReturnNull(); + $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, null)->once()->andReturnNull(); + $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, m::not(''))->once()->andReturnNull(); $session_strategy->shouldReceive('session')->once()->andReturn($session); @@ -385,14 +426,18 @@ public function testGetBrowserAliases() /** * Prepares test case to be used by "run" method. * - * @param array $mock_methods Method names to mock. + * @param array $mock_methods Method names to mock. + * @param boolean $expect_test_ended Tells, that we should expect "test.ended" event. * * @return array */ - protected function prepareForRun(array $mock_methods = array()) + protected function prepareForRun(array $mock_methods = array(), $expect_test_ended = true) { $this->expectEvent(BrowserTestCase::TEST_SETUP_EVENT); - $this->expectEvent(BrowserTestCase::TEST_ENDED_EVENT); + + if ( $expect_test_ended ) { + $this->expectEvent(BrowserTestCase::TEST_ENDED_EVENT); + } /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); diff --git a/tests/aik099/PHPUnit/Common/RemoteCoverageTest.php b/tests/aik099/PHPUnit/Common/RemoteCoverageTest.php deleted file mode 100644 index 6b0d929..0000000 --- a/tests/aik099/PHPUnit/Common/RemoteCoverageTest.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace tests\aik099\PHPUnit\Common; - - -use aik099\PHPUnit\Common\RemoteCoverage; -use Mockery as m; - -class RemoteCoverageTest extends \PHPUnit_Framework_TestCase -{ - - /** - * Test description. - * - * @return void - * @expectedException \InvalidArgumentException - */ - public function testIncorrectScriptUrl() - { - new RemoteCoverage('', 'test_id'); - } - - /** - * Test description. - * - * @return void - */ - public function testGetFetchUrl() - { - $remote_coverage = new RemoteCoverage('A', 'B'); - - $this->assertEquals('A?PHPUNIT_SELENIUM_TEST_ID=B', $remote_coverage->getFetchUrl()); - } - - /** - * Test description. - * - * @return void - */ - public function testGet() - { - $remote_coverage = m::mock('\\aik099\\PHPUnit\\Common\\RemoteCoverage[getFetchUrl]', array('url', 'test_id')); - /* @var $remote_coverage RemoteCoverage */ - - $remote_coverage->shouldReceive('getFetchUrl')->andReturn(__DIR__ . '/../Fixture/coverage_data.txt'); - - $content = $remote_coverage->get(); - $class_source_file = realpath(__DIR__ . '/../Fixture/DummyClass.php'); - - $expected = array( - 3 => 1, - 6 => 1, - 7 => -2, - 11 => -1, - 12 => -2, - 14 => 1, - ); - - $this->assertEquals($expected, $content[$class_source_file]); - } - -} diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index 7821933..165d5b1 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -67,6 +67,8 @@ public function serviceDefinitionsDataProvider() array('session_strategy_manager', 'aik099\\PHPUnit\\Session\\SessionStrategyManager'), array('isolated_session_strategy', 'aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'), array('shared_session_strategy', 'aik099\\PHPUnit\\Session\\SharedSessionStrategy'), + array('remote_url', 'aik099\\PHPUnit\\RemoteCoverage\\RemoteUrl'), + array('remote_coverage_helper', 'aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'), array('test_suite_factory', 'aik099\\PHPUnit\\TestSuite\\TestSuiteFactory'), array('regular_test_suite', 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'), array('browser_test_suite', 'aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'), diff --git a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php new file mode 100644 index 0000000..53f09f8 --- /dev/null +++ b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php @@ -0,0 +1,159 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\RemoteCoverage; + + +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; +use aik099\PHPUnit\RemoteCoverage\RemoteUrl; +use Mockery as m; +use Mockery\MockInterface; + +class RemoteCoverageHelperTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Remote URL. + * + * @var RemoteUrl|MockInterface + */ + private $_remoteUrl; + + /** + * Remote coverage helper. + * + * @var RemoteCoverageHelper + */ + private $_remoteCoverageHelper; + + /** + * Prepares test. + * + * @return void + */ + protected function setUp() + { + parent::setUp(); + + $this->_remoteUrl = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteUrl'); + $this->_remoteCoverageHelper = new RemoteCoverageHelper($this->_remoteUrl); + } + + /** + * Test description. + * + * @param string $coverage_script_url Url. + * @param string $test_id Test ID. + * + * @return void + * @dataProvider createUrlErrorDataProvider + * @expectedException \InvalidArgumentException + */ + public function testCreateUrlError($coverage_script_url, $test_id) + { + $this->_remoteCoverageHelper->get($coverage_script_url, $test_id); + } + + /** + * Returns url that end up badly. + * + * @return array + */ + public function createUrlErrorDataProvider() + { + return array( + array('', 'test-id'), + array('coverage-url', ''), + array('', ''), + ); + } + + /** + * Test description. + * + * @param string $coverage_script_url Coverage script URL. + * @param string $test_id Test ID. + * @param string $expected_url Expected URL to be queried. + * + * @return void + * @dataProvider createUrlDataProvider + */ + public function testCreateUrl($coverage_script_url, $test_id, $expected_url) + { + $this->_remoteUrl + ->shouldReceive('getPageContent') + ->with($expected_url) + ->once() + ->andReturn(false); + + $result = $this->_remoteCoverageHelper->get($coverage_script_url, $test_id); + $this->assertInternalType('array', $result); + $this->assertCount(0, $result); + } + + /** + * Returns url that does valid call. + * + * @return array + */ + public function createUrlDataProvider() + { + return array( + array('http://host', 'test-id', 'http://host?rct_mode=output&PHPUNIT_MINK_TEST_ID=test-id'), + array('http://host?p1=v1', 'test-id', 'http://host?p1=v1&rct_mode=output&PHPUNIT_MINK_TEST_ID=test-id'), + ); + } + + /** + * Test description. + * + * @return void + * @expectedException \RuntimeException + */ + public function testReturnedCoverageNotASerializedArray() + { + $this->_remoteUrl + ->shouldReceive('getPageContent') + ->once() + ->andReturn(''); + + $this->_remoteCoverageHelper->get('A', 'B'); + } + + /** + * Test description. + * + * @return void + */ + public function testValidCoverageIsReturned() + { + $fixture_folder = __DIR__ . '/../Fixture'; + + $this->_remoteUrl + ->shouldReceive('getPageContent') + ->once() + ->andReturn(file_get_contents($fixture_folder . '/coverage_data.txt')); + + $content = $this->_remoteCoverageHelper->get('A', 'B'); + $class_source_file = realpath($fixture_folder . '/DummyClass.php'); + + $expected = array( + 3 => 1, + 6 => 1, + 7 => -2, + 11 => -1, + 12 => -2, + 14 => 1, + ); + + $this->assertEquals($expected, $content[$class_source_file]); + } + +} diff --git a/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php b/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php new file mode 100644 index 0000000..544c06d --- /dev/null +++ b/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php @@ -0,0 +1,32 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\RemoteCoverage; + + +use aik099\PHPUnit\RemoteCoverage\RemoteUrl; + +class RemoteUrlTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Test description. + * + * @return void + */ + public function testGetPageContent() + { + $file = __DIR__ . '/../Fixture/coverage_data.txt'; + + $remote_url = new RemoteUrl(); + $this->assertEquals(file_get_contents($file), $remote_url->getPageContent($file)); + } + +} diff --git a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php index 9bb006c..365decf 100644 --- a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php +++ b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php @@ -55,4 +55,4 @@ protected function expectFactoryCall($service_id, $returned_object) } } -} \ No newline at end of file +} diff --git a/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php index 41a8d92..213a545 100644 --- a/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php +++ b/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php @@ -11,7 +11,6 @@ namespace tests\aik099\PHPUnit\TestCase; -use aik099\PHPUnit\Application; use Mockery\MockInterface; use Mockery as m; use Symfony\Component\EventDispatcher\EventDispatcherInterface; diff --git a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php index 300f306..730e15e 100644 --- a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php @@ -41,15 +41,17 @@ public function testSetTestDependencies() { $manager = m::mock('aik099\\PHPUnit\\Session\\SessionStrategyManager'); $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + $helper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); $test = m::mock('PHPUnit_Framework_Test'); $test->shouldReceive('setEventDispatcher')->with($this->eventDispatcher)->once(); $test->shouldReceive('setSessionStrategyManager')->with($manager)->once(); $test->shouldReceive('setBrowserConfigurationFactory')->with($factory)->once(); + $test->shouldReceive('setRemoteCoverageHelper')->with($helper)->once(); $suite = $this->_createSuite(); $suite->addTest($test); - $this->assertSame($suite, $suite->setTestDependencies($manager, $factory)); + $this->assertSame($suite, $suite->setTestDependencies($manager, $factory, $helper)); } /** diff --git a/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php b/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php index 95e109d..43b992c 100644 --- a/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php +++ b/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php @@ -12,6 +12,7 @@ use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\Session\SessionStrategyManager; use aik099\PHPUnit\TestSuite\BrowserTestSuite; use aik099\PHPUnit\TestSuite\TestSuiteFactory; @@ -42,6 +43,13 @@ class TestSuiteFactoryTest extends ApplicationAwareTestCase */ private $_browserFactory; + /** + * Remote coverage helper. + * + * @var RemoteCoverageHelper + */ + private $_remoteCoverageHelper; + /** * Creates suite for testing. * @@ -53,7 +61,9 @@ protected function setUp() $this->_manager = m::mock('aik099\\PHPUnit\\Session\\SessionStrategyManager'); $this->_browserFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); - $this->_factory = new TestSuiteFactory($this->_manager, $this->_browserFactory); + $this->_remoteCoverageHelper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); + + $this->_factory = new TestSuiteFactory($this->_manager, $this->_browserFactory, $this->_remoteCoverageHelper); $this->_factory->setApplication($this->application); } @@ -70,7 +80,10 @@ public function testCreateSuiteFromTestCaseWithoutBrowsers() $suite = m::mock($suite_class_name); $suite->shouldReceive('setName')->with($test_case_class_name)->once(); $suite->shouldReceive('addTestMethods')->with($test_case_class_name)->once(); - $suite->shouldReceive('setTestDependencies')->with($this->_manager, $this->_browserFactory)->once(); + $suite + ->shouldReceive('setTestDependencies') + ->with($this->_manager, $this->_browserFactory, $this->_remoteCoverageHelper) + ->once(); $this->expectFactoryCall('regular_test_suite', $suite); $actual_suite = $this->_factory->createSuiteFromTestCase($test_case_class_name); @@ -119,7 +132,10 @@ private function _createBrowserTestSuiteMock($class_name, array $browser) $suite->shouldReceive('nameFromBrowser')->with($browser)->once()->andReturn('OK'); $suite->shouldReceive('setName')->with($class_name . ': OK')->once(); $suite->shouldReceive('addTestMethods')->with($class_name)->once(); - $suite->shouldReceive('setTestDependencies')->with($this->_manager, $this->_browserFactory)->once(); + $suite + ->shouldReceive('setTestDependencies') + ->with($this->_manager, $this->_browserFactory, $this->_remoteCoverageHelper) + ->once(); $suite->shouldReceive('setBrowserFromConfiguration')->with($browser)->once(); return $suite; From 31803f2c5bfbe05ff2384e06002d856cfdfe3066 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 2 Mar 2014 14:49:47 +0200 Subject: [PATCH 020/204] Improvements to coding standard 1. inline PSR1.ClassDeclaration sniff (part about "each class must be namespaced") into the "CodingStandard.ClassDeclaration" sniff 2. fixed typo errors and indentation problems in Drupal Sniffs 3. added sniffs to verify that namespace/use statements are being used correctly (from PSR2) --- CodingStandard/Sniffs/Array/ArraySniff.php | 52 ++++++------- .../Sniffs/Classes/ClassDeclarationSniff.php | 15 +++- .../Sniffs/ControlStructures/ElseIfSniff.php | 27 +++---- .../Sniffs/Formatting/ItemAssignmentSniff.php | 76 ++++++++++--------- .../Sniffs/Formatting/SpaceOperatorSniff.php | 4 +- .../Formatting/SpaceUnaryOperatorSniff.php | 4 +- CodingStandard/ruleset.xml | 5 +- 7 files changed, 97 insertions(+), 86 deletions(-) diff --git a/CodingStandard/Sniffs/Array/ArraySniff.php b/CodingStandard/Sniffs/Array/ArraySniff.php index 895d7b5..a644716 100644 --- a/CodingStandard/Sniffs/Array/ArraySniff.php +++ b/CodingStandard/Sniffs/Array/ArraySniff.php @@ -48,10 +48,8 @@ public function register() */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { - - $tokens = $phpcsFile->getTokens(); - $this->sniffItemClosings($phpcsFile, $stackPtr, $tokens); - + $tokens = $phpcsFile->getTokens(); + $this->sniffItemClosings($phpcsFile, $stackPtr, $tokens); }//end process() /** @@ -61,31 +59,33 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) * * @param $tokens */ - function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens){ - $lastItem = $phpcsFile->findPrevious( - array(T_WHITESPACE), - $tokens[$stackPtr]['parenthesis_closer']-1, - $stackPtr, - true - ); + function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens) + { + $lastItem = $phpcsFile->findPrevious( + array(T_WHITESPACE), + $tokens[$stackPtr]['parenthesis_closer']-1, + $stackPtr, + true + ); + + //empty array + if ($lastItem == $tokens[$stackPtr]['parenthesis_opener']) { + return; + } - //empty array - if ($lastItem == $tokens[$stackPtr]['parenthesis_opener'] ) { - return; - } - //Inline array - $isInlineArray = $tokens[$tokens[$stackPtr]['parenthesis_opener']]['line'] == $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line']; + //Inline array + $isInlineArray = $tokens[$tokens[$stackPtr]['parenthesis_opener']]['line'] == $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line']; - //Check if the last item in a multiline array has a "closing" comma. - if ($tokens[$lastItem]['code'] !== T_COMMA && !$isInlineArray) { - $phpcsFile->addWarning('A comma should follow the last multiline array item. Found: ' . $tokens[$lastItem]['content'], $lastItem); - return; - } + //Check if the last item in a multiline array has a "closing" comma. + if ($tokens[$lastItem]['code'] !== T_COMMA && !$isInlineArray) { + $phpcsFile->addWarning('A comma should follow the last multiline array item. Found: ' . $tokens[$lastItem]['content'], $lastItem); + return; + } - if($tokens[$lastItem]['code'] == T_COMMA && $isInlineArray){ - $phpcsFile->addWarning('Last item of an inline array must not followed by a comma', $lastItem); - return; - } + if ($tokens[$lastItem]['code'] == T_COMMA && $isInlineArray) { + $phpcsFile->addWarning('Last item of an inline array must not followed by a comma', $lastItem); + return; + } } diff --git a/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php b/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php index 2e7bdf3..c075f84 100644 --- a/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php +++ b/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php @@ -35,6 +35,12 @@ class CodingStandard_Sniffs_Classes_ClassDeclarationSniff extends PSR2_Sniffs_Classes_ClassDeclarationSniff { + /** + * Requires each class declaration to be namespaced. + * + * @var bool + */ + public $requireNamespaces = true; /** * Processes this test, when one of its tokens is encountered. @@ -50,8 +56,6 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) // We want all the errors from the PSR2 standard, plus some of our own. parent::process($phpcsFile, $stackPtr); - $tokens = $phpcsFile->getTokens(); - // Check that this is the only class or interface in the file. $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE), ($stackPtr + 1)); if ($nextClass !== false) { @@ -60,6 +64,13 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) $phpcsFile->addError($error, $nextClass, 'MultipleClasses'); } + if ($this->requireNamespaces && version_compare(PHP_VERSION, '5.3.0') >= 0) { + $namespace = $phpcsFile->findPrevious(T_NAMESPACE, ($stackPtr - 1)); + if ($namespace === false) { + $error = 'Each class must be in a namespace of at least one level (a top-level vendor name)'; + $phpcsFile->addError($error, $stackPtr, 'MissingNamespace'); + } + } }//end process() diff --git a/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php b/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php index ad340cc..e6ca05e 100644 --- a/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php +++ b/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php @@ -56,23 +56,20 @@ public function register() */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { + $tokens = $phpcsFile->getTokens(); - $tokens = $phpcsFile->getTokens(); - - $nextNonWhiteSpace = $phpcsFile->findNext( - T_WHITESPACE, - $stackPtr + 1, - null, - true, - null, - true - ); - - if($tokens[$nextNonWhiteSpace]['code'] == T_IF){ - $phpcsFile->addError('Use "elseif" in place of "else if"', $nextNonWhiteSpace); - } - + $nextNonWhiteSpace = $phpcsFile->findNext( + T_WHITESPACE, + $stackPtr + 1, + null, + true, + null, + true + ); + if ($tokens[$nextNonWhiteSpace]['code'] == T_IF) { + $phpcsFile->addError('Use "elseif" in place of "else if"', $nextNonWhiteSpace); + } }//end process() }//end class diff --git a/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php b/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php index ab85f1a..1744178 100644 --- a/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php +++ b/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php @@ -48,10 +48,8 @@ public function register() */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { - - $tokens = $phpcsFile->getTokens(); - $this->sniffElementItemAssignmentOperator($phpcsFile, $stackPtr, $tokens); - + $tokens = $phpcsFile->getTokens(); + $this->sniffElementItemAssignmentOperator($phpcsFile, $stackPtr, $tokens); }//end process() /** @@ -60,13 +58,14 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) * Enter description here ... * @param $tokens */ - function sniffElementItemAssignmentOperator(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens) { - if ($tokens[$stackPtr - 1]['code'] !== T_WHITESPACE) { - $phpcsFile->addError('A whitespace must prefix the item assignment operator =>', $stackPtr); - } - if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { - $phpcsFile->addError('A whitespace must follow to the item assignemtn operator =>', $stackPtr); - } + function sniffElementItemAssignmentOperator(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens) + { + if ($tokens[$stackPtr - 1]['code'] !== T_WHITESPACE) { + $phpcsFile->addError('A whitespace must prefix the item assignment operator =>', $stackPtr); + } + if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { + $phpcsFile->addError('A whitespace must follow to the item assignment operator =>', $stackPtr); + } } /** @@ -76,35 +75,38 @@ function sniffElementItemAssignmentOperator(PHP_CodeSniffer_File $phpcsFile, $st * * @param $tokens */ - function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens){ - $lastItem = $phpcsFile->findPrevious( - array(T_WHITESPACE), - $tokens[$stackPtr]['parenthesis_closer']-1, - $stackPtr, - true - ); + function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens) + { + $lastItem = $phpcsFile->findPrevious( + array(T_WHITESPACE), + $tokens[$stackPtr]['parenthesis_closer'] - 1, + $stackPtr, + true + ); - //empty array - if ($lastItem == $tokens[$stackPtr]['parenthesis_opener'] ) { - return; - } - //Check if the last item in the array has a "closing" comma. - if ($tokens[$lastItem]['code'] !== T_COMMA) { - $phpcsFile->addWarning('A comma followed by a whitespace should follow the last array item. Found: ' . $tokens[$lastItem]['content'], $lastItem); - return; - } + //empty array + if ($lastItem == $tokens[$stackPtr]['parenthesis_opener']) { + return; + } - //If the closing parenthesis is on the - //same line as the last item there has to be a whitespace - //after the comma - if ($tokens[$lastItem]['line'] == $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line'] - && $tokens[$lastItem+1]['code'] !== T_WHITESPACE - ) { - $phpcsFile->addWarning('Afther the last comma in an array must be a whitespace', $lastItem); - return; - } - } + //Check if the last item in the array has a "closing" comma. + if ($tokens[$lastItem]['code'] !== T_COMMA) { + $phpcsFile->addWarning('A comma followed by a whitespace should follow the last array item. Found: ' . $tokens[$lastItem]['content'], $lastItem); + + return; + } + //If the closing parenthesis is on the + //same line as the last item there has to be a whitespace + //after the comma + if ($tokens[$lastItem]['line'] == $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line'] + && $tokens[$lastItem + 1]['code'] !== T_WHITESPACE + ) { + $phpcsFile->addWarning('Afther the last comma in an array must be a whitespace', $lastItem); + + return; + } + } }//end class diff --git a/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php b/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php index db35ff5..66efdd0 100644 --- a/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php +++ b/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php @@ -59,13 +59,13 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE || $tokens[($stackPtr + 1)]['content'] != ' ' ) { - $error = 'A opeator statement must be followed by a single space'; + $error = 'A operator statement must be followed by a single space'; $phpcsFile->addError($error, $stackPtr); } if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE || $tokens[($stackPtr - 1)]['content'] != ' ' ) { - $error = 'There must be a single space befora a opeator statement'; + $error = 'There must be a single space before an operator statement'; $phpcsFile->addError($error, $stackPtr); } diff --git a/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php b/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php index 9c1dd50..c108f6e 100644 --- a/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php +++ b/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php @@ -54,12 +54,12 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) $tokens[($stackPtr + 1)]['content'] == ';'; if ($modifyLeft && $tokens[($stackPtr - 1)]['code'] === T_WHITESPACE) { - $error = 'There must not be a single space befora a unary opeator statement'; + $error = 'There must not be a single space before an unary operator statement'; $phpcsFile->addError($error, $stackPtr); } if (!$modifyLeft && substr($tokens[($stackPtr + 1)]['content'], 0, 1) != '$') { - $error = 'A unary opeator statement must not followed by a single space'; + $error = 'A unary operator statement must not followed by a single space'; $phpcsFile->addError($error, $stackPtr); } diff --git a/CodingStandard/ruleset.xml b/CodingStandard/ruleset.xml index ec165f4..33cd8a5 100644 --- a/CodingStandard/ruleset.xml +++ b/CodingStandard/ruleset.xml @@ -2,8 +2,6 @@ Alexander Obuhovich's coding standard. - - @@ -62,6 +60,9 @@ + + + From ab26ea64c49dfd68aee2f45b1642ab1ae3d6f8d2 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 2 Mar 2014 14:50:09 +0200 Subject: [PATCH 021/204] Code updated to follow changed coding standards --- library/aik099/PHPUnit/Application.php | 1 - library/aik099/PHPUnit/IEventDispatcherAware.php | 1 - library/aik099/PHPUnit/Session/ISessionFactory.php | 1 - library/aik099/PHPUnit/Session/SessionStrategyFactory.php | 1 - library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php | 1 - library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php | 1 - library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php | 1 - 7 files changed, 7 deletions(-) diff --git a/library/aik099/PHPUnit/Application.php b/library/aik099/PHPUnit/Application.php index 552fc36..aef3a99 100644 --- a/library/aik099/PHPUnit/Application.php +++ b/library/aik099/PHPUnit/Application.php @@ -13,7 +13,6 @@ use aik099\PHPUnit\TestSuite\TestSuiteFactory; - /** * Main application class. * diff --git a/library/aik099/PHPUnit/IEventDispatcherAware.php b/library/aik099/PHPUnit/IEventDispatcherAware.php index dec3e31..dd3ff9f 100644 --- a/library/aik099/PHPUnit/IEventDispatcherAware.php +++ b/library/aik099/PHPUnit/IEventDispatcherAware.php @@ -13,7 +13,6 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; - /** * Interface to indicate that class is capable of using event dispatcher. */ diff --git a/library/aik099/PHPUnit/Session/ISessionFactory.php b/library/aik099/PHPUnit/Session/ISessionFactory.php index 41c9770..74ed084 100644 --- a/library/aik099/PHPUnit/Session/ISessionFactory.php +++ b/library/aik099/PHPUnit/Session/ISessionFactory.php @@ -14,7 +14,6 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use Behat\Mink\Session; - /** * Specifies how to create Session objects for running tests. * diff --git a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php index 05e47d9..53f1335 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php @@ -14,7 +14,6 @@ use aik099\PHPUnit\IApplicationAware; use aik099\PHPUnit\Application; - /** * Produces sessions. * diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index 808bcea..5040a81 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -19,7 +19,6 @@ use ReflectionClass; use Symfony\Component\EventDispatcher\EventDispatcherInterface; - /** * Base Test Suite class for browser tests. * diff --git a/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php b/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php index 6113389..61afce1 100644 --- a/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php @@ -13,7 +13,6 @@ use aik099\PHPUnit\BrowserTestCase; - /** * Test Suite class for a set of tests from a single Test Case Class executed with a particular browser. */ diff --git a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php index ae2e36c..c1d55f2 100644 --- a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php +++ b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php @@ -17,7 +17,6 @@ use aik099\PHPUnit\Session\SessionStrategyManager; use aik099\PHPUnit\Application; - /** * Creates test suites based on test case class configuration. * From d9318b77a4251d750788b37b2bf0e4152e7dcbf0 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 2 Mar 2014 19:30:25 +0200 Subject: [PATCH 022/204] Improvements to coding standard 1. making coding standard sniff to follow PHPCS standard 2. added more advanced inline comment validation 3. adding more advanced class property scope validation (also forces "_" prefix for private properties) --- CodingStandard/Sniffs/Array/ArraySniff.php | 49 ++-- .../Classes/ClassCreateInstanceSniff.php | 42 +-- .../Sniffs/Classes/ClassDeclarationSniff.php | 12 +- .../Classes/PropertyDeclarationSniff.php | 115 ++++++++ .../Sniffs/Commenting/InlineCommentSniff.php | 272 ++++++++++++++++++ .../Sniffs/ControlStructures/ElseIfSniff.php | 7 +- .../Sniffs/Formatting/ItemAssignmentSniff.php | 73 +++-- .../Sniffs/Formatting/SpaceOperatorSniff.php | 51 ++-- .../Formatting/SpaceUnaryOperatorSniff.php | 31 +- .../Strings/ConcatenationSpacingSniff.php | 16 +- CodingStandard/ruleset.xml | 49 ++-- 11 files changed, 575 insertions(+), 142 deletions(-) create mode 100644 CodingStandard/Sniffs/Classes/PropertyDeclarationSniff.php create mode 100644 CodingStandard/Sniffs/Commenting/InlineCommentSniff.php diff --git a/CodingStandard/Sniffs/Array/ArraySniff.php b/CodingStandard/Sniffs/Array/ArraySniff.php index a644716..3c72340 100644 --- a/CodingStandard/Sniffs/Array/ArraySniff.php +++ b/CodingStandard/Sniffs/Array/ArraySniff.php @@ -4,10 +4,10 @@ * * PHP version 5 * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer */ /** @@ -16,10 +16,10 @@ * Checks if the array's are styled in the Drupal way. * - Comma after the last array element * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer */ class CodingStandard_Sniffs_Array_ArraySniff implements PHP_CodeSniffer_Sniff { @@ -50,43 +50,52 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $this->sniffItemClosings($phpcsFile, $stackPtr, $tokens); + }//end process() + /** - * Checks if the last item in the array is closed with a comma + * Checks if the last item in the array is closed with a comma. + * * If the array is written on one line there must also be a space - * after the comma + * after the comma. * - * @param $tokens + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the + * stack passed in $tokens. + * @param array $tokens Tokens. + * + * @return void */ - function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens) + protected function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, array $tokens) { $lastItem = $phpcsFile->findPrevious( array(T_WHITESPACE), - $tokens[$stackPtr]['parenthesis_closer']-1, + ($tokens[$stackPtr]['parenthesis_closer'] - 1), $stackPtr, true ); - //empty array - if ($lastItem == $tokens[$stackPtr]['parenthesis_opener']) { + // Empty array. + if ($lastItem === $tokens[$stackPtr]['parenthesis_opener']) { return; } - //Inline array + // Inline array. $isInlineArray = $tokens[$tokens[$stackPtr]['parenthesis_opener']]['line'] == $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line']; - //Check if the last item in a multiline array has a "closing" comma. - if ($tokens[$lastItem]['code'] !== T_COMMA && !$isInlineArray) { + // Check if the last item in a multiline array has a "closing" comma. + if ($tokens[$lastItem]['code'] !== T_COMMA && $isInlineArray === false) { $phpcsFile->addWarning('A comma should follow the last multiline array item. Found: ' . $tokens[$lastItem]['content'], $lastItem); return; } - if ($tokens[$lastItem]['code'] == T_COMMA && $isInlineArray) { + if ($tokens[$lastItem]['code'] === T_COMMA && $isInlineArray === true) { $phpcsFile->addWarning('Last item of an inline array must not followed by a comma', $lastItem); return; } - } + + }//end sniffItemClosings() }//end class diff --git a/CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php b/CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php index 9f71fc9..068a5c6 100644 --- a/CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php +++ b/CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php @@ -4,10 +4,10 @@ * * PHP version 5 * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer */ /** @@ -15,10 +15,10 @@ * * Checks the declaration of the class is correct. * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer */ class CodingStandard_Sniffs_Classes_ClassCreateInstanceSniff implements PHP_CodeSniffer_Sniff { @@ -31,9 +31,7 @@ class CodingStandard_Sniffs_Classes_ClassCreateInstanceSniff implements PHP_Code */ public function register() { - return array( - T_NEW, - ); + return array(T_NEW); }//end register() @@ -51,18 +49,30 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); - $nextParenthesis = $phpcsFile->findNext(array(T_OPEN_PARENTHESIS,T_SEMICOLON), $stackPtr, null, false, null, true); + $nextParenthesis = $phpcsFile->findNext( + array( + T_OPEN_PARENTHESIS, + T_SEMICOLON, + ), + $stackPtr, + null, + false, + null, + true + ); + if ($tokens[$nextParenthesis]['code'] != T_OPEN_PARENTHESIS || $tokens[$nextParenthesis]['line'] != $tokens[$stackPtr]['line']) { - $error = 'Calling class constructors must always include parentheses'; + $error = 'Calling class constructors must always include parentheses'; $phpcsFile->addError($error, $nextParenthesis); return; } - if ($tokens[$nextParenthesis-1]['code'] == T_WHITESPACE) { - $error = 'Between the class name and the opening parenthesis spaces are not welcome'; - $phpcsFile->addError($error, $nextParenthesis-1); + if ($tokens[($nextParenthesis - 1)]['code'] === T_WHITESPACE) { + $error = 'Between the class name and the opening parenthesis spaces are not welcome'; + $phpcsFile->addError($error, ($nextParenthesis - 1)); return; } + }//end process() diff --git a/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php b/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php index c075f84..842e0a6 100644 --- a/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php +++ b/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php @@ -42,6 +42,7 @@ class CodingStandard_Sniffs_Classes_ClassDeclarationSniff extends PSR2_Sniffs_Cl */ public $requireNamespaces = true; + /** * Processes this test, when one of its tokens is encountered. * @@ -64,13 +65,14 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) $phpcsFile->addError($error, $nextClass, 'MultipleClasses'); } - if ($this->requireNamespaces && version_compare(PHP_VERSION, '5.3.0') >= 0) { + if ($this->requireNamespaces === true && version_compare(PHP_VERSION, '5.3.0') >= 0) { $namespace = $phpcsFile->findPrevious(T_NAMESPACE, ($stackPtr - 1)); if ($namespace === false) { $error = 'Each class must be in a namespace of at least one level (a top-level vendor name)'; $phpcsFile->addError($error, $stackPtr, 'MissingNamespace'); } } + }//end process() @@ -146,13 +148,7 @@ public function processClose(PHP_CodeSniffer_File $phpcsFile, $stackPtr) // Check that the closing brace has one blank line after it. $nextContent = $phpcsFile->findNext(array(T_WHITESPACE, T_COMMENT), ($closeBrace + 1), null, true); - if ($nextContent === false) { - // No content found, so we reached the end of the file. - // That means there was no closing tag either. - /*$error = 'Closing brace of a %s must be followed by a blank line and then a closing PHP tag'; - $data = array($tokens[$stackPtr]['content']); - $phpcsFile->addError($error, $closeBrace, 'EndFileAfterCloseBrace', $data);*/ - } else { + if ($nextContent !== false) { $nextLine = $tokens[$nextContent]['line']; $braceLine = $tokens[$closeBrace]['line']; if ($braceLine === $nextLine) { diff --git a/CodingStandard/Sniffs/Classes/PropertyDeclarationSniff.php b/CodingStandard/Sniffs/Classes/PropertyDeclarationSniff.php new file mode 100644 index 0000000..cb228cf --- /dev/null +++ b/CodingStandard/Sniffs/Classes/PropertyDeclarationSniff.php @@ -0,0 +1,115 @@ + + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +if (class_exists('PHP_CodeSniffer_Standards_AbstractVariableSniff', true) === false) { + throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractVariableSniff not found'); +} + +/** + * Verifies that properties are declared correctly. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Greg Sherwood + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @version Release: @package_version@ + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_Classes_PropertyDeclarationSniff extends PHP_CodeSniffer_Standards_AbstractVariableSniff +{ + + + /** + * Processes the function tokens within the class. + * + * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. + * @param int $stackPtr The position where the token was found. + * + * @return void + */ + protected function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + // Detect multiple properties defined at the same time. Throw an error + // for this, but also only process the first property in the list so we don't + // repeat errors. + $find = PHP_CodeSniffer_Tokens::$scopeModifiers; + $find = array_merge($find, array(T_VARIABLE, T_VAR, T_SEMICOLON)); + $prev = $phpcsFile->findPrevious($find, ($stackPtr - 1)); + if ($tokens[$prev]['code'] === T_VARIABLE) { + return; + } + + if ($tokens[$prev]['code'] === T_VAR) { + $error = 'The var keyword must not be used to declare a property'; + $phpcsFile->addError($error, $stackPtr, 'VarUsed'); + } + + $next = $phpcsFile->findNext(array(T_VARIABLE, T_SEMICOLON), ($stackPtr + 1)); + if ($tokens[$next]['code'] === T_VARIABLE) { + $error = 'There must not be more than one property declared per statement'; + $phpcsFile->addError($error, $stackPtr, 'Multiple'); + } + + $modifier = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$scopeModifiers, $stackPtr); + if (($modifier === false) || ($tokens[$modifier]['line'] !== $tokens[$stackPtr]['line'])) { + $error = 'Visibility must be declared on property "%s"'; + $data = array($tokens[$stackPtr]['content']); + $phpcsFile->addError($error, $stackPtr, 'ScopeMissing', $data); + } + + if (($modifier !== false) && ($modifier['code'] === T_PRIVATE) && ($tokens[$stackPtr]['content'][1] !== '_')) { + $error = 'Private property name "%s" should be prefixed with an underscore to indicate visibility'; + $data = array($tokens[$stackPtr]['content']); + $phpcsFile->addWarning($error, $stackPtr, 'Underscore', $data); + } + + }//end processMemberVar() + + + /** + * Processes normal variables. + * + * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. + * @param int $stackPtr The position where the token was found. + * + * @return void + */ + protected function processVariable(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + // We don't care about normal variables. + + }//end processVariable() + + + /** + * Processes variables in double quoted strings. + * + * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. + * @param int $stackPtr The position where the token was found. + * + * @return void + */ + protected function processVariableInString(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + // We don't care about normal variables. + + }//end processVariableInString() + + +}//end class + +?> diff --git a/CodingStandard/Sniffs/Commenting/InlineCommentSniff.php b/CodingStandard/Sniffs/Commenting/InlineCommentSniff.php new file mode 100644 index 0000000..35d7b00 --- /dev/null +++ b/CodingStandard/Sniffs/Commenting/InlineCommentSniff.php @@ -0,0 +1,272 @@ + + * @author Marc McIntyre + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +/** + * CodingStandard_Sniffs_Commenting_InlineCommentSniff. + * + * Checks that there is adequate spacing between comments. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Greg Sherwood + * @author Marc McIntyre + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @version Release: @package_version@ + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_Commenting_InlineCommentSniff implements PHP_CodeSniffer_Sniff +{ + + /** + * A list of tokenizers this sniff supports. + * + * @var array + */ + public $supportedTokenizers = array( + 'PHP', + 'JS', + ); + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return array( + T_COMMENT, + T_DOC_COMMENT, + ); + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the + * stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + // If this is a function/class/interface doc block comment, skip it. + // We are only interested in inline doc block comments, which are + // not allowed. + if ($tokens[$stackPtr]['code'] === T_DOC_COMMENT) { + $nextToken = $phpcsFile->findNext( + PHP_CodeSniffer_Tokens::$emptyTokens, + ($stackPtr + 1), + null, + true + ); + + $ignore = array( + T_CLASS, + T_INTERFACE, + T_TRAIT, + T_FUNCTION, + T_PUBLIC, + T_PRIVATE, + T_PROTECTED, + T_FINAL, + T_STATIC, + T_ABSTRACT, + T_CONST, + T_OBJECT, + T_PROPERTY, + ); + + if (in_array($tokens[$nextToken]['code'], $ignore) === true) { + return; + } else { + if ($phpcsFile->tokenizerType === 'JS') { + // We allow block comments if a function is being assigned + // to a variable. + $ignore = PHP_CodeSniffer_Tokens::$emptyTokens; + $ignore[] = T_EQUAL; + $ignore[] = T_STRING; + $ignore[] = T_OBJECT_OPERATOR; + $nextToken = $phpcsFile->findNext($ignore, ($nextToken + 1), null, true); + if ($tokens[$nextToken]['code'] === T_FUNCTION) { + return; + } + } + + $prevToken = $phpcsFile->findPrevious( + PHP_CodeSniffer_Tokens::$emptyTokens, + ($stackPtr - 1), + null, + true + ); + + if ($tokens[$prevToken]['code'] === T_OPEN_TAG) { + return; + } + + // Only error once per comment. +// if (substr($tokens[$stackPtr]['content'], 0, 3) === '/**') { +// $error = 'Inline doc block comments are not allowed; use "/* Comment */" or "// Comment" instead'; +// $phpcsFile->addError($error, $stackPtr, 'DocBlock'); +// } + }//end if + }//end if + + if ($tokens[$stackPtr]['content']{0} === '#') { + $error = 'Perl-style comments are not allowed; use "// Comment" instead'; + $phpcsFile->addError($error, $stackPtr, 'WrongStyle'); + } + + // We don't want end of block comments. If the last comment is a closing + // curly brace. + $previousContent = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); + if ($tokens[$previousContent]['line'] === $tokens[$stackPtr]['line']) { + if ($tokens[$previousContent]['code'] === T_CLOSE_CURLY_BRACKET) { + return; + } + + // Special case for JS files. + if ($tokens[$previousContent]['code'] === T_COMMA + || $tokens[$previousContent]['code'] === T_SEMICOLON + ) { + $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, ($previousContent - 1), null, true); + if ($tokens[$lastContent]['code'] === T_CLOSE_CURLY_BRACKET) { + return; + } + } + } + + $comment = rtrim($tokens[$stackPtr]['content']); + + // Only want inline comments. + if (substr($comment, 0, 2) !== '//') { + return; + } + + $spaceCount = 0; + for ($i = 2; $i < strlen($comment); $i++) { + if ($comment[$i] !== ' ') { + break; + } + + $spaceCount++; + } + + if ($spaceCount === 0) { + $error = 'No space before comment text; expected "// %s" but found "%s"'; + $data = array( + substr($comment, 2), + $comment, + ); + $phpcsFile->addError($error, $stackPtr, 'NoSpaceBefore', $data); + } + + if ($spaceCount > 1) { + $error = '%s spaces found before inline comment line; use block comment if you need indentation'; + $data = array( + $spaceCount, + substr($comment, (2 + $spaceCount)), + $comment, + ); + $phpcsFile->addError($error, $stackPtr, 'SpacingBefore', $data); + } + + + // The below section determines if a comment block is correctly capitalised, + // and ends in a full-stop. It will find the last comment in a block, and + // work its way up. + $nextComment = $phpcsFile->findNext(array(T_COMMENT), ($stackPtr + 1), null, false); + + if (($nextComment !== false) && (($tokens[$nextComment]['line']) === ($tokens[$stackPtr]['line'] + 1))) { + return; + } + + $topComment = $stackPtr; + $lastComment = $stackPtr; + while (($topComment = $phpcsFile->findPrevious(array(T_COMMENT), ($lastComment - 1), null, false)) !== false) { + if ($tokens[$topComment]['line'] !== ($tokens[$lastComment]['line'] - 1)) { + break; + } + + $lastComment = $topComment; + } + + $topComment = $lastComment; + $commentText = ''; + + for ($i = $topComment; $i <= $stackPtr; $i++) { + if ($tokens[$i]['code'] === T_COMMENT) { + $commentText .= trim(substr($tokens[$i]['content'], 2)); + } + } + + if ($commentText === '') { + $error = 'Blank comments are not allowed'; + $phpcsFile->addError($error, $stackPtr, 'Empty'); + return; + } + + if (preg_match('|\p{Lu}|u', $commentText[0]) === 0) { + $error = 'Inline comments must start with a capital letter'; + $phpcsFile->addError($error, $topComment, 'NotCapital'); + } + + $commentCloser = $commentText[(strlen($commentText) - 1)]; + $acceptedClosers = array( + 'full-stops' => '.', + 'exclamation marks' => '!', + 'or question marks' => '?', + ); + + if (in_array($commentCloser, $acceptedClosers) === false) { + $error = 'Inline comments must end in %s'; + $ender = ''; + foreach ($acceptedClosers as $closerName => $symbol) { + $ender .= ' '.$closerName.','; + } + + $ender = rtrim($ender, ','); + $data = array($ender); + $phpcsFile->addError($error, $stackPtr, 'InvalidEndChar', $data); + } + + // Finally, the line below the last comment cannot be empty. + $start = false; + for ($i = ($stackPtr + 1); $i < $phpcsFile->numTokens; $i++) { + if ($tokens[$i]['line'] === ($tokens[$stackPtr]['line'] + 1)) { + if ($tokens[$i]['code'] !== T_WHITESPACE) { + return; + } + } else if ($tokens[$i]['line'] > ($tokens[$stackPtr]['line'] + 1)) { + break; + } + } + + $error = 'There must be no blank line following an inline comment'; + $phpcsFile->addError($error, $stackPtr, 'SpacingAfter'); + + }//end process() + + +}//end class + + +?> diff --git a/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php b/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php index e6ca05e..54a0c64 100644 --- a/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php +++ b/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php @@ -33,6 +33,7 @@ class CodingStandard_Sniffs_ControlStructures_ElseIfSniff implements PHP_CodeSniffer_Sniff { + /** * Returns an array of tokens this test wants to listen for. * @@ -60,18 +61,20 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) $nextNonWhiteSpace = $phpcsFile->findNext( T_WHITESPACE, - $stackPtr + 1, + ($stackPtr + 1), null, true, null, true ); - if ($tokens[$nextNonWhiteSpace]['code'] == T_IF) { + if ($tokens[$nextNonWhiteSpace]['code'] === T_IF) { $phpcsFile->addError('Use "elseif" in place of "else if"', $nextNonWhiteSpace); } + }//end process() + }//end class ?> diff --git a/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php b/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php index 1744178..188ef7d 100644 --- a/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php +++ b/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php @@ -4,22 +4,22 @@ * * PHP version 5 * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer */ /** * CodingStandard_Sniffs_Formatting_ItemAssignmentSniff. * - * Checks if the item assignemnt operator (=>) has + * Checks if the item assignment operator (=>) has * - a space before and after * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer */ class CodingStandard_Sniffs_Formatting_ItemAssignmentSniff implements PHP_CodeSniffer_Sniff { @@ -50,63 +50,80 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $this->sniffElementItemAssignmentOperator($phpcsFile, $stackPtr, $tokens); + }//end process() + /** * Checks if there are spaces before and after the Assignment operators in the array - * * Enter description here ... - * @param $tokens + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the + * stack passed in $tokens. + * @param array $tokens Tokens. + * + * @return void */ - function sniffElementItemAssignmentOperator(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens) + protected function sniffElementItemAssignmentOperator(PHP_CodeSniffer_File $phpcsFile, $stackPtr, array $tokens) { - if ($tokens[$stackPtr - 1]['code'] !== T_WHITESPACE) { + if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE) { $phpcsFile->addError('A whitespace must prefix the item assignment operator =>', $stackPtr); } - if ($tokens[$stackPtr + 1]['code'] !== T_WHITESPACE) { + + if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE) { $phpcsFile->addError('A whitespace must follow to the item assignment operator =>', $stackPtr); } - } + + }//end sniffElementItemAssignmentOperator() + /** * Checks if the last item in the array is closed with a comma * If the array is written on one line there must also be a space * after the comma * - * @param $tokens + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token in the + * stack passed in $tokens. + * @param array $tokens Tokens. + * + * @return void */ - function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens) + protected function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, array $tokens) { $lastItem = $phpcsFile->findPrevious( array(T_WHITESPACE), - $tokens[$stackPtr]['parenthesis_closer'] - 1, + ($tokens[$stackPtr]['parenthesis_closer'] - 1), $stackPtr, true ); - //empty array - if ($lastItem == $tokens[$stackPtr]['parenthesis_opener']) { + // Empty array. + if ($lastItem === $tokens[$stackPtr]['parenthesis_opener']) { return; } - //Check if the last item in the array has a "closing" comma. + // Check if the last item in the array has a "closing" comma. if ($tokens[$lastItem]['code'] !== T_COMMA) { $phpcsFile->addWarning('A comma followed by a whitespace should follow the last array item. Found: ' . $tokens[$lastItem]['content'], $lastItem); return; } - //If the closing parenthesis is on the - //same line as the last item there has to be a whitespace - //after the comma - if ($tokens[$lastItem]['line'] == $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line'] - && $tokens[$lastItem + 1]['code'] !== T_WHITESPACE + // If the closing parenthesis is on the + // same line as the last item there has to be a whitespace + // after the comma. + if ($tokens[$lastItem]['line'] === $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line'] + && $tokens[($lastItem + 1)]['code'] !== T_WHITESPACE ) { - $phpcsFile->addWarning('Afther the last comma in an array must be a whitespace', $lastItem); + $phpcsFile->addWarning('After the last comma in an array must be a whitespace', $lastItem); return; } - } + + }//end sniffItemClosings() + }//end class diff --git a/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php b/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php index 66efdd0..cc17450 100644 --- a/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php +++ b/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php @@ -4,10 +4,10 @@ * * PHP version 5 * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer */ /** @@ -15,11 +15,11 @@ * * Ensures there is a single space after a operator * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @version Release: 1.2.2 - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @version Release: 1.2.2 + * @link http://pear.php.net/package/PHP_CodeSniffer */ class CodingStandard_Sniffs_Formatting_SpaceOperatorSniff implements PHP_CodeSniffer_Sniff { @@ -54,21 +54,30 @@ public function register() */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); + $tokens = $phpcsFile->getTokens(); + $operator = $tokens[$stackPtr]['content']; - if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE - || $tokens[($stackPtr + 1)]['content'] != ' ' - ) { - $error = 'A operator statement must be followed by a single space'; - $phpcsFile->addError($error, $stackPtr); - } - if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE - || $tokens[($stackPtr - 1)]['content'] != ' ' - ) { - $error = 'There must be a single space before an operator statement'; - $phpcsFile->addError($error, $stackPtr); + if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE || $tokens[($stackPtr - 1)]['content'] !== ' ') { + $found = strlen($tokens[($stackPtr - 1)]['content']); + $error = 'Expected 1 space before "%s"; %s found'; + $data = array( + $operator, + $found, + ); + $phpcsFile->addError($error, $stackPtr, 'SpacingBefore', $data); } + // is handled by "Squiz.WhiteSpace.OperatorSpacing" + /*if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE || $tokens[($stackPtr + 1)]['content'] != ' ') { + $found = strlen($tokens[($stackPtr + 1)]['content']); + $error = 'Expected 1 space after "%s"; %s found'; + $data = array( + $operator, + $found, + ); + $phpcsFile->addError($error, $stackPtr, 'SpacingAfter', $data); + }*/ + }//end process() diff --git a/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php b/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php index c108f6e..b52bbff 100644 --- a/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php +++ b/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php @@ -4,10 +4,10 @@ * * PHP version 5 * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer */ /** @@ -15,11 +15,11 @@ * * Ensures there are no spaces on increment / decrement statements. * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @version Release: 1.2.2 - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @version Release: 1.2.2 + * @link http://pear.php.net/package/PHP_CodeSniffer */ class CodingStandard_Sniffs_Formatting_SpaceUnaryOperatorSniff implements PHP_CodeSniffer_Sniff { @@ -32,7 +32,10 @@ class CodingStandard_Sniffs_Formatting_SpaceUnaryOperatorSniff implements PHP_Co */ public function register() { - return array(T_DEC, T_INC); + return array( + T_DEC, + T_INC, + ); }//end register() @@ -50,15 +53,15 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); - $modifyLeft = substr($tokens[($stackPtr - 1)]['content'], 0, 1) == '$' || - $tokens[($stackPtr + 1)]['content'] == ';'; + $modifyLeft = substr($tokens[($stackPtr - 1)]['content'], 0, 1) === '$' || + $tokens[($stackPtr + 1)]['content'] === ';'; - if ($modifyLeft && $tokens[($stackPtr - 1)]['code'] === T_WHITESPACE) { + if ($modifyLeft === true && $tokens[($stackPtr - 1)]['code'] === T_WHITESPACE) { $error = 'There must not be a single space before an unary operator statement'; $phpcsFile->addError($error, $stackPtr); } - if (!$modifyLeft && substr($tokens[($stackPtr + 1)]['content'], 0, 1) != '$') { + if ($modifyLeft === false && substr($tokens[($stackPtr + 1)]['content'], 0, 1) !== '$') { $error = 'A unary operator statement must not followed by a single space'; $phpcsFile->addError($error, $stackPtr); } diff --git a/CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php b/CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php index 16164ab..b636a6f 100644 --- a/CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php +++ b/CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php @@ -4,10 +4,10 @@ * * PHP version 5 * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer */ /** @@ -16,10 +16,10 @@ * Makes sure there are the needed spaces between the concatenation operator (.) and * the strings being concatenated. * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer + * @category PHP + * @package PHP_CodeSniffer + * @author Peter Philipp + * @link http://pear.php.net/package/PHP_CodeSniffer */ class CodingStandard_Sniffs_Strings_ConcatenationSpacingSniff implements PHP_CodeSniffer_Sniff { diff --git a/CodingStandard/ruleset.xml b/CodingStandard/ruleset.xml index 33cd8a5..8dc4d3a 100644 --- a/CodingStandard/ruleset.xml +++ b/CodingStandard/ruleset.xml @@ -3,6 +3,7 @@ Alexander Obuhovich's coding standard. + @@ -31,28 +32,18 @@ - + + - @@ -65,19 +56,21 @@ - - + + + + - - - + + + @@ -94,7 +87,7 @@ @@ -104,8 +97,9 @@ - + + @@ -120,6 +114,11 @@ + + From 37572f78cd8f87132079196d19b044d400d9f7c9 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 2 Mar 2014 19:44:25 +0200 Subject: [PATCH 023/204] Code updated to follow changed coding standards --- .../BrowserConfiguration.php | 10 +++---- .../SauceLabsBrowserConfiguration.php | 2 +- library/aik099/PHPUnit/BrowserTestCase.php | 10 +++---- .../aik099/PHPUnit/Session/SessionFactory.php | 2 +- .../Session/SessionStrategyManager.php | 9 ++++--- .../PHPUnit/TestSuite/TestSuiteFactory.php | 4 +-- .../SauceLabsBrowserConfigurationTest.php | 6 ++--- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 6 ++--- .../PHPUnit/Fixture/SetupEventFixture.php | 6 ++--- .../Integration/EventDispatchingTest.php | 26 ++++++++++--------- .../Session/SessionStrategyManagerTest.php | 6 ++--- 11 files changed, 45 insertions(+), 42 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 4dcddc2..f5e04e4 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -33,17 +33,17 @@ class BrowserConfiguration implements EventSubscriberInterface, IEventDispatcher * @var array */ protected $defaultParameters = array( - // server related + // Server related. 'host' => 'localhost', 'port' => 4444, 'timeout' => 60, - // browser related + // Browser related. 'browserName' => 'firefox', 'desiredCapabilities' => array(), 'baseUrl' => '', - // test related + // Test related. 'sessionStrategy' => ISessionStrategyFactory::TYPE_ISOLATED, ); @@ -474,11 +474,11 @@ public function getSessionStrategyHash() public function getTestStatus(BrowserTestCase $test_case, \PHPUnit_Framework_TestResult $test_result) { if ( $this->isShared() ) { - // all tests in a test case use same session -> failed even if 1 test fails + // All tests in a test case use same session -> failed even if 1 test fails. return $test_result->wasSuccessful(); } - // each test in a test case are using it's own session -> failed if test fails + // Each test in a test case are using it's own session -> failed if test fails. return !$test_case->hasFailed(); } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index b2333f5..378b9d4 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -207,7 +207,7 @@ public function onTestEnded(TestEndedEvent $event) parent::onTestEnded($event); if ( $event->getSession() === null ) { - // session wasn't used in particular test + // Session wasn't used in particular test. return; } diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 37b24ff..df6608d 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -199,7 +199,7 @@ public function setBrowser(BrowserConfiguration $browser) { $this->_browser = $browser->attachToTestCase($this); - // configure session strategy + // Configure session strategy. return $this->setSessionStrategy($this->sessionStrategyManager->getSessionStrategy($browser)); } @@ -268,7 +268,7 @@ public function getSessionStrategy() return $this->sessionStrategy; } - // default session strategy (not session itself) shared across all test cases + // Default session strategy (not session itself) shared across all test cases. return $this->sessionStrategyManager->getDefaultSessionStrategy(); } @@ -322,15 +322,15 @@ public function run(\PHPUnit_Framework_TestResult $result = null) $result->getCodeCoverage()->append($this->getRemoteCodeCoverageInformation(), $this); } -// $this->setTestResultObject($result); + /*$this->setTestResultObject($result);*/ - // do not call this before to give the time to the Listeners to run + // Do not call this before to give the time to the Listeners to run. $this->_eventDispatcher->dispatch( self::TEST_ENDED_EVENT, new TestEndedEvent($this, $result, $this->_session) ); -// $this->setTestResultObject(null); + /*$this->setTestResultObject(null);*/ return $result; } diff --git a/library/aik099/PHPUnit/Session/SessionFactory.php b/library/aik099/PHPUnit/Session/SessionFactory.php index c7a72a0..0dc5bfe 100644 --- a/library/aik099/PHPUnit/Session/SessionFactory.php +++ b/library/aik099/PHPUnit/Session/SessionFactory.php @@ -49,7 +49,7 @@ private function _createDriver(BrowserConfiguration $browser) $capabilities = $browser->getDesiredCapabilities(); $capabilities['browserName'] = $browser_name; - // TODO: maybe doesn't work + // TODO: maybe doesn't work! ini_set('default_socket_timeout', $browser->getTimeout()); $driver = new Selenium2Driver( diff --git a/library/aik099/PHPUnit/Session/SessionStrategyManager.php b/library/aik099/PHPUnit/Session/SessionStrategyManager.php index 76d5b31..375b373 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyManager.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyManager.php @@ -84,10 +84,11 @@ public function getDefaultSessionStrategy() */ public function getSessionStrategy(BrowserConfiguration $browser) { - // This logic creates separate strategy for: - // - each browser configuration in BrowserTestCase::$browsers (for isolated strategy) - // - each browser configuration in BrowserTestCase::$browsers for each test case class (for shared strategy) - + /** + * This logic creates separate strategy for: + * - each browser configuration in BrowserTestCase::$browsers (for isolated strategy) + * - each browser configuration in BrowserTestCase::$browsers for each test case class (for shared strategy) + */ $strategy_type = $browser->getSessionStrategy(); $strategy_hash = $browser->getSessionStrategyHash(); diff --git a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php index c1d55f2..5fce75a 100644 --- a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php +++ b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php @@ -99,13 +99,13 @@ public function createSuiteFromTestCase($class_name) $browsers = $this->_getBrowsers($class_name); if ( $browsers ) { - // create tests from test methods for multiple browsers + // Create tests from test methods for multiple browsers. foreach ( $browsers as $browser ) { $suite->addTest($this->_createBrowserSuite($class_name, $browser)); } } else { - // create tests from test methods for single browser + // Create tests from test methods for single browser. $suite->addTestMethods($class_name); $suite->setTestDependencies( $this->_sessionStrategyManager, diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 584f4fd..fda9431 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -255,7 +255,7 @@ public function testTestEndedEvent($driver_type) $driver->shouldReceive('getWebDriverSessionId')->once()->andReturn('SID'); $sauce_rest->shouldReceive('updateJob')->with('SID', array('passed' => true))->once(); - $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // for shared strategy + $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // For shared strategy. } else { $driver = m::mock('\\Behat\\Mink\\Driver\\DriverInterface'); @@ -305,8 +305,8 @@ public function testTestEndedWithoutSession() $event = m::mock('aik099\\PHPUnit\\Event\\TestEndedEvent'); $event->shouldReceive('getSession')->once(); - $event->shouldReceive('setDispatcher')->once(); // to remove with Symfony 3.0 release - $event->shouldReceive('setName')->once(); // to remove with Symfony 3.0 release + $event->shouldReceive('setDispatcher')->once(); // To remove with Symfony 3.0 release. + $event->shouldReceive('setName')->once(); // To remove with Symfony 3.0 release. $event->shouldReceive('isPropagationStopped')->once()->andReturn(false); $event->shouldReceive('getTestCase')->never(); diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 3ae4330..fb3b813 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -185,15 +185,15 @@ public function testGetSession() $test_case->setBrowser($browser); $test_case->setTestResultObject($this->getTestResult($test_case, 0)); - // create session when missing + // Create session when missing. $session1 = $test_case->getSession(); $this->assertSame($expected_session1, $session1); - // create session when present, but stopped + // Create session when present, but stopped. $session2 = $test_case->getSession(); $this->assertSame($expected_session2, $session2); - // reuse created session, when started + // Reuse created session, when started. $session3 = $test_case->getSession(); $this->assertSame($session2, $session3); } diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index 08e58b5..c5fcfe7 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -62,15 +62,15 @@ public function testEvents() $session = m::mock('Behat\\Mink\\Session'); - // for SauceLabsBrowserConfiguration::onTestEnded + // For SauceLabsBrowserConfiguration::onTestEnded. $session->shouldReceive('getDriver')->once()->andReturn($driver); - // for IsolatedSessionStrategy::onTestEnd + // For IsolatedSessionStrategy::onTestEnd. $session->shouldReceive('stop')->once(); $this->_setSession($session); - // for SauceLabsBrowserConfiguration::onTestSetup + // For SauceLabsBrowserConfiguration::onTestSetup. $desired_capabilities = $this->getBrowser()->getDesiredCapabilities(); $this->assertArrayHasKey(SauceLabsBrowserConfiguration::NAME_CAPABILITY, $desired_capabilities); } diff --git a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php index 61427ba..6681e3c 100644 --- a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php +++ b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php @@ -24,18 +24,20 @@ class EventDispatchingTest extends \PHPUnit_Framework_TestCase */ public function testSetupEvent() { - // BrowserTestCase::TEST_SETUP_EVENT - // - SauceLabsBrowserConfiguration::onTestSetup (called, verified) - - // BrowserTestCase::TEST_ENDED_EVENT - // - IsolatedSessionStrategy::onTestEnd (called, verified) - // - SauceLabsBrowserConfiguration::onTestEnded (called, verified) - - // BrowserTestCase::TEST_SUITE_ENDED_EVENT - // - SharedSessionStrategy::onTestSuiteEnd - - // BrowserTestCase::TEST_FAILED_EVENT - // - SharedSessionStrategy::onTestFailed + /** + * BrowserTestCase::TEST_SETUP_EVENT + * - SauceLabsBrowserConfiguration::onTestSetup (called, verified) + * + * BrowserTestCase::TEST_ENDED_EVENT + * - IsolatedSessionStrategy::onTestEnd (called, verified) + * - SauceLabsBrowserConfiguration::onTestEnded (called, verified) + * + * BrowserTestCase::TEST_SUITE_ENDED_EVENT + * - SharedSessionStrategy::onTestSuiteEnd + * + * BrowserTestCase::TEST_FAILED_EVENT + * - SharedSessionStrategy::onTestFailed + */ $result = new \PHPUnit_Framework_TestResult(); diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php index 4ee884c..f68e368 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php @@ -85,16 +85,16 @@ public function testGetSessionStrategySharing() return m::mock('aik099\\PHPUnit\\Session\\ISessionStrategy'); }); - // sequential identical browser configurations share strategy + // Sequential identical browser configurations share strategy. $strategy1 = $this->_getStrategy(ISessionStrategyFactory::TYPE_ISOLATED, 'H1'); $strategy2 = $this->_getStrategy(ISessionStrategyFactory::TYPE_ISOLATED, 'H1'); $this->assertSame($strategy1, $strategy2); - // different browser configuration use different strategy + // Different browser configuration use different strategy. $strategy3 = $this->_getStrategy(ISessionStrategyFactory::TYPE_ISOLATED, 'H2'); $this->assertNotSame($strategy2, $strategy3); - // different browser configuration break the sequence + // Different browser configuration break the sequence. $strategy4 = $this->_getStrategy(ISessionStrategyFactory::TYPE_ISOLATED, 'H1'); $this->assertNotSame($strategy1, $strategy4); } From a9a77872cde4188ac1230a4f9b9ffd16031430cd Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Mon, 3 Mar 2014 23:51:58 +0200 Subject: [PATCH 024/204] Removing duplicate sniffs --- .../Sniffs/Classes/ClassDeclarationSniff.php | 5 + .../ValidFunctionNameSniff.php | 197 ++++++++++++++++++ CodingStandard/ruleset.xml | 5 +- 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php diff --git a/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php b/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php index 842e0a6..de732c9 100644 --- a/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php +++ b/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php @@ -57,6 +57,11 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) // We want all the errors from the PSR2 standard, plus some of our own. parent::process($phpcsFile, $stackPtr); + if (basename($phpcsFile->getFilename()) === 'constants.php') { + // Multiple class constant definitions allowed in this particular file. + return; + } + // Check that this is the only class or interface in the file. $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE), ($stackPtr + 1)); if ($nextClass !== false) { diff --git a/CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php b/CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php new file mode 100644 index 0000000..aff8f91 --- /dev/null +++ b/CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php @@ -0,0 +1,197 @@ + + * @author Marc McIntyre + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +if (class_exists('PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff', true) === false) { + throw new PHP_CodeSniffer_Exception('Class PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff not found'); +} + +/** + * CodingStandard_Sniffs_NamingConventions_ValidFunctionNameSniff. + * + * Ensures method names are correct depending on whether they are public + * or private, and that functions are named correctly. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Greg Sherwood + * @author Marc McIntyre + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @version Release: @package_version@ + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_NamingConventions_ValidFunctionNameSniff extends PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff +{ + + protected $eventHandlerExclusions = array( + 'SetCustomQuery', + 'CheckPermission', + 'LoadItem', + ); + + protected $tagProcessorExclusions = array(); + + /** + * Processes the tokens within the scope. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being processed. + * @param int $stackPtr The position where this token was + * found. + * @param int $currScope The position of the current scope. + * + * @return void + */ + protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope) + { + $methodName = $phpcsFile->getDeclarationName($stackPtr); + if ($methodName === null) { + // Ignore closures. + return; + } + + $className = $phpcsFile->getDeclarationName($currScope); + $errorData = array($className.'::'.$methodName); + + // Is this a magic method. i.e., is prefixed with "__" ? + if (preg_match('|^__|', $methodName) !== 0) { + $magicPart = strtolower(substr($methodName, 2)); + if (in_array($magicPart, $this->magicMethods) === false) { + $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore'; + $phpcsFile->addError($error, $stackPtr, 'MethodDoubleUnderscore', $errorData); + } + + return; + } + + // PHP4 constructors are allowed to break our rules. + if ($methodName === $className) { + return; + } + + // PHP4 destructors are allowed to break our rules. + if ($methodName === '_'.$className) { + return; + } + + $methodProps = $phpcsFile->getMethodProperties($stackPtr); + $isPublic = ($methodProps['scope'] === 'private') ? false : true; + $scope = $methodProps['scope']; + $scopeSpecified = $methodProps['scope_specified']; + + // If it's a private method, it must have an underscore on the front. + if ($isPublic === false && $methodName{0} !== '_') { + $error = 'Private method name "%s" must be prefixed with an underscore'; + $phpcsFile->addError($error, $stackPtr, 'PrivateNoUnderscore', $errorData); + return; + } + + // If it's not a private method, it must not have an underscore on the front. + if ($isPublic === true && $scopeSpecified === true && $methodName{0} === '_') { + $error = '%s method name "%s" must not be prefixed with an underscore'; + $data = array( + ucfirst($scope), + $errorData[0], + ); + $phpcsFile->addError($error, $stackPtr, 'PublicUnderscore', $data); + return; + } + + // If the scope was specified on the method, then the method must be + // camel caps and an underscore should be checked for. If it wasn't + // specified, treat it like a public method and remove the underscore + // prefix if there is one because we cant determine if it is private or + // public. + $testMethodName = $methodName; + if ($scopeSpecified === false && $methodName{0} === '_') { + $testMethodName = substr($methodName, 1); + } + + $methodParams = $phpcsFile->getMethodParameters($stackPtr); + + if ( + $this->isEventHandlerExclusion($className, $methodName, $methodParams) || + $this->isTagProcessorExclusion($className, $methodName, $methodParams) + ) { + return; + } + + if (PHP_CodeSniffer::isCamelCaps($testMethodName, false, $isPublic, false) === false) { + if ($scopeSpecified === true) { + $error = '%s method name "%s" is not in camel caps format'; + $data = array( + ucfirst($scope), + $errorData[0], + ); + $phpcsFile->addError($error, $stackPtr, 'ScopeNotCamelCaps', $data); + } else { + $error = 'Method name "%s" is not in camel caps format'; + $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData); + } + + return; + } + + }//end processTokenWithinScope() + + + /** + * Determines if a method is an event in the event handler class. + * + * @param string $className Class name. + * @param string $methodName Method name. + * @param array $methodParams Method parameters. + * + * @return bool + */ + protected function isEventHandlerExclusion($className, $methodName, array $methodParams) + { + if (substr($className, -12) !== 'EventHandler') { + // Not EventHandler class. + return false; + } + + $isEvent = substr($methodName, 0, 2) == 'On' && count($methodParams) === 1 && $methodParams[0]['name'] === '$event'; + + return in_array($methodName, $this->eventHandlerExclusions) || $isEvent === true; + + }//end isEventHandlerExclusion() + + + /** + * Determines if a method is an event in the event handler class. + * + * @param string $className Class name. + * @param string $methodName Method name. + * @param array $methodParams Method parameters. + * + * @return bool + */ + protected function isTagProcessorExclusion($className, $methodName, array $methodParams) + { + if (substr($className, -12) !== 'TagProcessor') { + // Not TagProcessor class. + return false; + } + + $isTag = count($methodParams) === 1 && $methodParams[0]['name'] === '$params'; + + return in_array($methodName, $this->tagProcessorExclusions) || $isTag === true; + + }//end isTagProcessorExclusion() + + +}//end class + +?> diff --git a/CodingStandard/ruleset.xml b/CodingStandard/ruleset.xml index 8dc4d3a..4fcecd3 100644 --- a/CodingStandard/ruleset.xml +++ b/CodingStandard/ruleset.xml @@ -21,6 +21,10 @@ + + + + @@ -49,7 +53,6 @@ - From 0690cec7f84e5723a95df45cde95ac4bf5909c75 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 4 Mar 2014 11:06:31 +0200 Subject: [PATCH 025/204] Improvements to coding standard 1. condition needs to be enclosed with spaces inside control structures --- CodingStandard/ruleset.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CodingStandard/ruleset.xml b/CodingStandard/ruleset.xml index 4fcecd3..c1923f4 100644 --- a/CodingStandard/ruleset.xml +++ b/CodingStandard/ruleset.xml @@ -78,6 +78,13 @@ --> + + + + + + + From 1d663e24964309d274fdece063fd916f76a24052 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 4 Mar 2014 11:06:46 +0200 Subject: [PATCH 026/204] Code updated to follow changed coding standards --- library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php index 7ec9f24..508d434 100644 --- a/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php +++ b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php @@ -102,7 +102,7 @@ protected function matchLocalAndRemotePaths(array $coverage) { $coverage_with_local_paths = array(); - foreach ($coverage as $original_remote_path => $data) { + foreach ( $coverage as $original_remote_path => $data ) { $remote_path = $original_remote_path; $separator = $this->findDirectorySeparator($remote_path); From 60181afed65717f6bbfd3354c815d8f8d2c60be8 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Mon, 17 Mar 2014 19:56:07 +0200 Subject: [PATCH 027/204] CodingStandard improvements 1. support for Traits 2. inline comments now allowed to begin with a digit 3. multi-line function declaration/call validation 4. check scope indent 5. added protection against wrong "echo" calls 6. added protection against wrong agressive double quote usage 7. added check for trailing whitespaces --- .../Sniffs/Classes/ClassDeclarationSniff.php | 6 +- .../Sniffs/Commenting/InlineCommentSniff.php | 4 +- .../Functions/FunctionDeclarationSniff.php | 119 ++++++++++++++++++ .../ValidFunctionNameSniff.php | 9 +- CodingStandard/ruleset.xml | 46 +++++-- 5 files changed, 170 insertions(+), 14 deletions(-) create mode 100644 CodingStandard/Sniffs/Functions/FunctionDeclarationSniff.php diff --git a/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php b/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php index de732c9..70d8bcd 100644 --- a/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php +++ b/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php @@ -62,11 +62,11 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) return; } - // Check that this is the only class or interface in the file. - $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE), ($stackPtr + 1)); + // Check that this is the only class, interface or trait in the file. + $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_TRAIT), ($stackPtr + 1)); if ($nextClass !== false) { // We have another, so an error is thrown. - $error = 'Only one interface or class is allowed in a file'; + $error = 'Only one class, interface or trait is allowed in a file'; $phpcsFile->addError($error, $nextClass, 'MultipleClasses'); } diff --git a/CodingStandard/Sniffs/Commenting/InlineCommentSniff.php b/CodingStandard/Sniffs/Commenting/InlineCommentSniff.php index 35d7b00..4ccbd21 100644 --- a/CodingStandard/Sniffs/Commenting/InlineCommentSniff.php +++ b/CodingStandard/Sniffs/Commenting/InlineCommentSniff.php @@ -224,8 +224,8 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) return; } - if (preg_match('|\p{Lu}|u', $commentText[0]) === 0) { - $error = 'Inline comments must start with a capital letter'; + if (preg_match('/(\p{Lu}|\d)/u', $commentText[0]) === 0) { + $error = 'Inline comments must start with a capital letter or digit'; $phpcsFile->addError($error, $topComment, 'NotCapital'); } diff --git a/CodingStandard/Sniffs/Functions/FunctionDeclarationSniff.php b/CodingStandard/Sniffs/Functions/FunctionDeclarationSniff.php new file mode 100644 index 0000000..785a692 --- /dev/null +++ b/CodingStandard/Sniffs/Functions/FunctionDeclarationSniff.php @@ -0,0 +1,119 @@ + + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +if (class_exists('PEAR_Sniffs_Functions_FunctionDeclarationSniff', true) === false) { + $error = 'Class PEAR_Sniffs_Functions_FunctionDeclarationSniff not found'; + throw new PHP_CodeSniffer_Exception($error); +} + +/** + * CodingStandard_Sniffs_Functions_FunctionDeclarationSniff. + * + * Ensure single and multi-line function declarations are defined correctly. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Greg Sherwood + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @version Release: @package_version@ + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_Functions_FunctionDeclarationSniff extends PEAR_Sniffs_Functions_FunctionDeclarationSniff +{ + + /** + * The number of spaces code should be indented. + * + * @var int + */ + public $indent = 1; + + + /** + * Processes mutli-line declarations. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token + * in the stack passed in $tokens. + * @param array $tokens The stack of tokens that make up + * the file. + * + * @return void + */ + public function processMultiLineDeclaration(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens) + { + // We need to work out how far indented the function + // declaration itself is, so we can work out how far to + // indent parameters. + $functionIndent = 0; + for ($i = ($stackPtr - 1); $i >= 0; $i--) { + if ($tokens[$i]['line'] !== $tokens[$stackPtr]['line']) { + $i++; + break; + } + } + + if ($tokens[$i]['code'] === T_WHITESPACE) { + $functionIndent = strlen($tokens[$i]['content']); + } + + // The closing parenthesis must be on a new line, even + // when checking abstract function definitions. + $closeBracket = $tokens[$stackPtr]['parenthesis_closer']; + $prev = $phpcsFile->findPrevious( + T_WHITESPACE, + ($closeBracket - 1), + null, + true + ); + + if ($tokens[$closeBracket]['line'] !== $tokens[$tokens[$closeBracket]['parenthesis_opener']]['line']) { + if ($tokens[$prev]['line'] === $tokens[$closeBracket]['line']) { + $error = 'The closing parenthesis of a multi-line function declaration must be on a new line'; + $phpcsFile->addError($error, $closeBracket, 'CloseBracketLine'); + } + } + + // If this is a closure and is using a USE statement, the closing + // parenthesis we need to look at from now on is the closing parenthesis + // of the USE statement. + if ($tokens[$stackPtr]['code'] === T_CLOSURE) { + $use = $phpcsFile->findNext(T_USE, ($closeBracket + 1), $tokens[$stackPtr]['scope_opener']); + if ($use !== false) { + $open = $phpcsFile->findNext(T_OPEN_PARENTHESIS, ($use + 1)); + $closeBracket = $tokens[$open]['parenthesis_closer']; + + $prev = $phpcsFile->findPrevious( + T_WHITESPACE, + ($closeBracket - 1), + null, + true + ); + + if ($tokens[$closeBracket]['line'] !== $tokens[$tokens[$closeBracket]['parenthesis_opener']]['line']) { + if ($tokens[$prev]['line'] === $tokens[$closeBracket]['line']) { + $error = 'The closing parenthesis of a multi-line use declaration must be on a new line'; + $phpcsFile->addError($error, $closeBracket, 'CloseBracketLine'); + } + } + }//end if + }//end if + + }//end processMultiLineDeclaration() + + +}//end class + +?> diff --git a/CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php b/CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php index aff8f91..063f6ac 100644 --- a/CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php +++ b/CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php @@ -39,9 +39,14 @@ class CodingStandard_Sniffs_NamingConventions_ValidFunctionNameSniff extends PEA 'SetCustomQuery', 'CheckPermission', 'LoadItem', + 'ListPrepareQuery', + 'ItemPrepareQuery', + 'SetPagination', + 'SetSorting', ); - protected $tagProcessorExclusions = array(); + protected $tagProcessorExclusions = array('PrepareListElementParams'); + /** * Processes the tokens within the scope. @@ -170,7 +175,7 @@ protected function isEventHandlerExclusion($className, $methodName, array $metho /** - * Determines if a method is an event in the event handler class. + * Determines if a method is an tag in the tag processor class. * * @param string $className Class name. * @param string $methodName Method name. diff --git a/CodingStandard/ruleset.xml b/CodingStandard/ruleset.xml index c1923f4..ce09535 100644 --- a/CodingStandard/ruleset.xml +++ b/CodingStandard/ruleset.xml @@ -14,19 +14,30 @@ - + + + + + + + + + + + + @@ -34,6 +45,7 @@ + **/*_config.php @@ -41,16 +53,20 @@ + + - - + + + + + + + @@ -111,6 +127,8 @@ + + @@ -122,14 +140,28 @@ + + + + + + + + + + + - + From 4498ca0e29f8bc09e0ed9373cb18cae0a9b6114e Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Mon, 17 Mar 2014 19:56:15 +0200 Subject: [PATCH 028/204] Code updated to follow updated CodingStadard --- tests/bootstrap.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index e980713..9033e2c 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -20,6 +20,6 @@ require_once ($vendor_path . '/autoload.php'); $auto_loader = new \Composer\Autoload\ClassLoader(); -$auto_loader->add("aik099\\", FULL_PATH . '/library/'); -$auto_loader->add("tests\\aik099\\", FULL_PATH . '/'); +$auto_loader->add('aik099\\', FULL_PATH . '/library/'); +$auto_loader->add('tests\\aik099\\', FULL_PATH . '/'); $auto_loader->register(); From fae4b698f59d4ed8dcfc0458e517e821d94cded5 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Mon, 17 Mar 2014 23:15:39 +0200 Subject: [PATCH 029/204] Bumping up PHPUnit dependency to 4.x and updating test suite to pass --- composer.json | 2 +- tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bf22f74..b292744 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "behat/mink-selenium2-driver": "~1.1@dev", "symfony/event-dispatcher": "~2.4", "pimple/pimple": "~2.0@dev", - "phpunit/phpunit": "3.7.*" + "phpunit/phpunit": "~4.0" }, "require-dev": { diff --git a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php index 5613aad..7293092 100644 --- a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php @@ -100,10 +100,13 @@ protected function createTestSuite($class_name) $suite->shouldReceive('getGroups')->once()->andReturn(array()); $suite->shouldReceive('setBackupGlobals')->andReturnNull(); $suite->shouldReceive('setBackupStaticAttributes')->andReturnNull(); + $suite->shouldReceive('setRunTestInSeparateProcess')->andReturnNull(); $suite->shouldReceive('run')->once()->andReturnNull(); $suite->shouldReceive('onTestSuiteEnded')->once()->andReturnNull(); + $suite->shouldReceive('count')->once()->andReturn(1); + return $suite; } From e061c5384a149c77aac900db9b3c6d84c2e6f196 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 18 Mar 2014 09:56:44 +0200 Subject: [PATCH 030/204] Allow using either of PHPUnit 3.7.* or PHPUnit 4.0.* --- composer.json | 2 +- tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index b292744..177ebc4 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "behat/mink-selenium2-driver": "~1.1@dev", "symfony/event-dispatcher": "~2.4", "pimple/pimple": "~2.0@dev", - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "~3.7|~4.0" }, "require-dev": { diff --git a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php index 7293092..bd58f08 100644 --- a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php @@ -105,7 +105,9 @@ protected function createTestSuite($class_name) $suite->shouldReceive('run')->once()->andReturnNull(); $suite->shouldReceive('onTestSuiteEnded')->once()->andReturnNull(); - $suite->shouldReceive('count')->once()->andReturn(1); + if ( version_compare(\PHPUnit_Runner_Version::id(), '4.0.0', '>=') ) { + $suite->shouldReceive('count')->once()->andReturn(1); + } return $suite; } From fb917f13e972d2a086b5cdbf6cd4c19d1f5326d0 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 18 Mar 2014 10:12:38 +0200 Subject: [PATCH 031/204] Fixing branch alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 177ebc4..8e29060 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } } } From 194e5cbb1d10e00327c8a114a27d8386e194a63f Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 22 Mar 2014 16:37:08 +0200 Subject: [PATCH 032/204] Allow using either of PHPUnit 3.7.* or PHPUnit 4.0.* --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8e29060..8e34534 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "behat/mink-selenium2-driver": "~1.1@dev", "symfony/event-dispatcher": "~2.4", "pimple/pimple": "~2.0@dev", - "phpunit/phpunit": "~3.7|~4.0" + "phpunit/phpunit": ">=3.7.8" }, "require-dev": { From f8c5888c9f63df7d65a4bf34b802531b8ce4767f Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 23 Mar 2014 14:05:32 +0200 Subject: [PATCH 033/204] Change BrowserConfigurationFactory to allow adding browser configurations --- README.md | 9 +- .../BrowserConfiguration.php | 34 ++++---- .../BrowserConfigurationFactory.php | 62 +++++++++----- .../IBrowserConfigurationFactory.php | 15 ++++ .../SauceLabsBrowserConfiguration.php | 67 ++++++++++----- library/aik099/PHPUnit/DIContainer.php | 21 ++--- .../BrowserConfigurationFactoryTest.php | 85 +++++++++++++++---- .../BrowserConfigurationTest.php | 16 +--- .../SauceLabsBrowserConfigurationTest.php | 31 +++---- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 3 +- .../PHPUnit/Fixture/SetupEventFixture.php | 19 ++--- .../PHPUnit/Integration/DIContainerTest.php | 2 - tests/bootstrap.php | 3 + 13 files changed, 226 insertions(+), 141 deletions(-) diff --git a/README.md b/README.md index 53253e9..6ac26a9 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,11 @@ class PerBrowserConfigTest extends BrowserTestCase // to create "Sauce Labs" browser configuration via BrowserConfigurationFactory $browser = $this->createBrowserConfiguration(array( - 'sauce' => array('username' => 'sauce_username', 'api_key' => 'sauce_api_key'), // required - // options goes here (optional) + // required + 'type' => 'saucelabs', + 'api_username' => 'sauce_username', + 'api_key' => 'sauce_api_key', + // options (optional) goes here )); // options can be changed later (optional) @@ -202,7 +205,7 @@ class ConcreteTest extends BrowserAliasTest ``` ## Using "Sauce Labs" -When using "Sauce Labs" account to perform Selenium server-based testing you need to specify `'sauce' => array('username' => '...', 'api_key' => '...')` instead of `host` or `port` settings. In all other aspects all will work the same as if all tests are running locally. +When using "Sauce Labs" account to perform Selenium server-based testing you need to specify `'type' => 'saucelabs', 'api_username' => '...', 'api_key' => '...'` instead of `host` or `port` settings. In all other aspects all will work the same as if all tests are running locally. ## Remote Code Coverage Browser tests are executed on different machine, then one, where code coverage information is collected (and tests are executed). To solve that problem this library uses remote coverage collection. Following steps needs to be performed before using this feature: diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index f5e04e4..abec817 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -24,7 +24,7 @@ * * @method \Mockery\Expectation shouldReceive */ -class BrowserConfiguration implements EventSubscriberInterface, IEventDispatcherAware +class BrowserConfiguration implements EventSubscriberInterface { /** @@ -44,6 +44,7 @@ class BrowserConfiguration implements EventSubscriberInterface, IEventDispatcher 'baseUrl' => '', // Test related. + 'type' => 'default', 'sessionStrategy' => ISessionStrategyFactory::TYPE_ISOLATED, ); @@ -104,10 +105,23 @@ public static function resolveAliases(array $parameters, array $aliases) /** * Creates browser configuration. + * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. */ - public function __construct() + public function __construct(EventDispatcherInterface $event_dispatcher) { $this->parameters = $this->defaultParameters; + $this->_eventDispatcher = $event_dispatcher; + } + + /** + * Returns type of browser configuration. + * + * @return string + */ + public function getType() + { + return $this->parameters['type']; } /** @@ -123,18 +137,6 @@ public static function getSubscribedEvents() ); } - /** - * Sets event dispatcher. - * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * - * @return void - */ - public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) - { - $this->_eventDispatcher = $event_dispatcher; - } - /** * Attaches listeners. * @@ -182,11 +184,13 @@ public function getTestCase() * * @param array $aliases Browser configuration aliases. * - * @return void + * @return self */ public function setAliases(array $aliases = array()) { $this->aliases = $aliases; + + return $this; } /** diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php index fb11369..3ffce45 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php @@ -12,30 +12,40 @@ use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\IApplicationAware; -use aik099\PHPUnit\Application; use WebDriver\SauceLabs\SauceRest; -class BrowserConfigurationFactory implements IBrowserConfigurationFactory, IApplicationAware +/** + * Browser configuration factory. + * + * @method \Mockery\Expectation shouldReceive + */ +class BrowserConfigurationFactory implements IBrowserConfigurationFactory { /** - * Application. + * Browser configurations. * - * @var Application + * @var array */ - protected $application; + protected $browserConfigurations = array(); /** - * Sets application. + * Registers a browser configuration. * - * @param Application $application The application. + * @param BrowserConfiguration $browser Browser configuration. * * @return void + * @throws \InvalidArgumentException When browser configuration is already registered. */ - public function setApplication(Application $application) + public function register(BrowserConfiguration $browser) { - $this->application = $application; + $type = $browser->getType(); + + if ( isset($this->browserConfigurations[$type]) ) { + throw new \InvalidArgumentException('Browser configuration with type "' . $type . '" is already registered'); + } + + $this->browserConfigurations[$type] = $browser; } /** @@ -51,18 +61,26 @@ public function createBrowserConfiguration(array $config, BrowserTestCase $test_ $aliases = $test_case->getBrowserAliases(); $config = BrowserConfiguration::resolveAliases($config, $aliases); - /** @var BrowserConfiguration $browser */ - if ( isset($config['sauce']) ) { - $browser = $this->application->getObject('sauce_labs_browser_configuration'); - } - else { - $browser = $this->application->getObject('browser_configuration'); - } + $type = isset($config['type']) ? $config['type'] : 'default'; - $browser->setAliases($aliases); - $browser->setup($config); + return $this->create($type)->setAliases($aliases)->setup($config); + } - return $browser; + /** + * Creates browser configuration based on give type. + * + * @param string $type Type. + * + * @return BrowserConfiguration + * @throws \InvalidArgumentException When browser configuration not registered. + */ + protected function create($type) + { + if ( !isset($this->browserConfigurations[$type]) ) { + throw new \InvalidArgumentException('Browser configuration type "' . $type . '" not registered'); + } + + return clone $this->browserConfigurations[$type]; } /** @@ -76,9 +94,7 @@ public function createBrowserConfiguration(array $config, BrowserTestCase $test_ public function createAPIClient(BrowserConfiguration $browser) { if ( $browser instanceof SauceLabsBrowserConfiguration ) { - $sauce = $browser->getSauce(); - - return new SauceRest($sauce['username'], $sauce['api_key']); + return new SauceRest($browser->getApiUsername(), $browser->getApiKey()); } throw new \LogicException('Unsupported browser configuration given'); diff --git a/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php index ad1ec10..935e801 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php @@ -13,6 +13,11 @@ use aik099\PHPUnit\BrowserTestCase; +/** + * Interface for browser factory creation. + * + * @method \Mockery\Expectation shouldReceive + */ interface IBrowserConfigurationFactory { @@ -26,6 +31,16 @@ interface IBrowserConfigurationFactory */ public function createBrowserConfiguration(array $config, BrowserTestCase $test_case); + /** + * Registers a browser configuration. + * + * @param BrowserConfiguration $browser Browser configuration. + * + * @return void + * @throws \InvalidArgumentException When browser configuration is already registered. + */ + public function register(BrowserConfiguration $browser); + /** * Creates API client. * diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 378b9d4..801f987 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -16,6 +16,7 @@ use aik099\PHPUnit\Event\TestEvent; use Behat\Mink\Driver\Selenium2Driver; use Behat\Mink\Session; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; use WebDriver\SauceLabs\SauceRest; /** @@ -44,14 +45,20 @@ class SauceLabsBrowserConfiguration extends BrowserConfiguration /** * Creates browser configuration. * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. */ - public function __construct(IBrowserConfigurationFactory $browser_configuration_factory) + public function __construct( + EventDispatcherInterface $event_dispatcher, + IBrowserConfigurationFactory $browser_configuration_factory + ) { $this->_browserConfigurationFactory = $browser_configuration_factory; - $this->defaultParameters['sauce'] = array('username' => '', 'api_key' => ''); + $this->defaultParameters['api_username'] = ''; + $this->defaultParameters['api_key'] = ''; + $this->defaultParameters['type'] = 'saucelabs'; - parent::__construct(); + parent::__construct($event_dispatcher); } /** @@ -64,42 +71,66 @@ public function __construct(IBrowserConfigurationFactory $browser_configuration_ public function setup(array $parameters) { $prepared_parameters = $this->prepareParameters($parameters); - $this->setSauce($prepared_parameters['sauce']); + $this->setApiUsername($prepared_parameters['api_username']); + $this->setApiKey($prepared_parameters['api_key']); return parent::setup($parameters); } /** - * Sets "Sauce Labs" connection details. + * Sets "Sauce Labs" API username. * * To be called from TestCase::setUp(). * - * @param array $sauce Connection details. + * @param string $api_username API username. * * @return self - * @throws \InvalidArgumentException When incorrect sauce is given. * @link https://saucelabs.com/php */ - public function setSauce(array $sauce) + public function setApiUsername($api_username) { - if ( !isset($sauce['username']) || !isset($sauce['api_key']) ) { - throw new \InvalidArgumentException('Incorrect sauce'); - } + $this->parameters['api_username'] = $api_username; + + return $this; + } + + /** + * Returns "Sauce Labs" api username. + * + * @return string + * @link https://saucelabs.com/php + */ + public function getApiUsername() + { + return $this->parameters['api_username']; + } - $this->parameters['sauce'] = $sauce; + /** + * Sets "Sauce Labs" API key. + * + * To be called from TestCase::setUp(). + * + * @param string $api_key API key. + * + * @return self + * @link https://saucelabs.com/php + */ + public function setApiKey($api_key) + { + $this->parameters['api_key'] = $api_key; return $this; } /** - * Returns "Sauce Labs" connection details. + * Returns "Sauce Labs" api key. * - * @return array + * @return string * @link https://saucelabs.com/php */ - public function getSauce() + public function getApiKey() { - return $this->parameters['sauce']; + return $this->parameters['api_key']; } /** @@ -109,9 +140,7 @@ public function getSauce() */ public function getHost() { - $sauce = $this->getSauce(); - - return $sauce['username'] . ':' . $sauce['api_key'] . '@ondemand.saucelabs.com'; + return $this->getApiUsername() . ':' . $this->getApiKey() . '@ondemand.saucelabs.com'; } /** diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index 086d3e8..f52819d 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -120,24 +120,15 @@ public function __construct(array $values = array()) $this['browser_configuration_factory'] = function ($c) { $browser_configuration_factory = new BrowserConfigurationFactory(); - $browser_configuration_factory->setApplication($c['application']); + $browser_configuration_factory->register( + new BrowserConfiguration($c['event_dispatcher']) + ); + $browser_configuration_factory->register( + new SauceLabsBrowserConfiguration($c['event_dispatcher'], $browser_configuration_factory) + ); return $browser_configuration_factory; }; - - $this['browser_configuration'] = $this->factory(function ($c) { - $browser = new BrowserConfiguration(); - $browser->setEventDispatcher($c['event_dispatcher']); - - return $browser; - }); - - $this['sauce_labs_browser_configuration'] = $this->factory(function ($c) { - $browser = new SauceLabsBrowserConfiguration($c['browser_configuration_factory']); - $browser->setEventDispatcher($c['event_dispatcher']); - - return $browser; - }); } } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index 974ef9b..6eb5854 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -15,9 +15,9 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use Mockery as m; -use tests\aik099\PHPUnit\TestCase\ApplicationAwareTestCase; +use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; -class BrowserConfigurationFactoryTest extends ApplicationAwareTestCase +class BrowserConfigurationFactoryTest extends EventDispatcherAwareTestCase { /** @@ -37,33 +37,40 @@ protected function setUp() parent::setUp(); $this->_factory = new BrowserConfigurationFactory(); - $this->_factory->setApplication($this->application); } /** * Test description. * - * @param array $browser_config Browser config. - * @param string $service_id Service ID in factory. + * @param array $browser_config Browser configuration. + * @param string $type Type. * * @return void * @dataProvider createBrowserConfigurationDataProvider */ - public function testCreateBrowserConfiguration(array $browser_config, $service_id) + public function testCreateBrowserConfiguration(array $browser_config, $type) { $browser_aliases = array('alias-one' => array()); - $browser_class = 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; - - $browser = m::mock($browser_class); - $browser->shouldReceive('setAliases')->with($browser_aliases)->once(); - $browser->shouldReceive('setup')->with($browser_config)->once(); - $this->expectFactoryCall($service_id, $browser); $test_case = m::mock('aik099\\PHPUnit\\BrowserTestCase'); $test_case->shouldReceive('getBrowserAliases')->once()->andReturn($browser_aliases); + $browser_configuration = $this->_createBrowserConfiguration($type); + $browser_configuration + ->shouldReceive('setAliases') + ->with($browser_aliases) + ->once() + ->andReturn($browser_configuration); + $browser_configuration + ->shouldReceive('setup') + ->with($browser_config) + ->once() + ->andReturn($browser_configuration); + $this->_factory->register($browser_configuration); + $actual_browser = $this->_factory->createBrowserConfiguration($browser_config, $test_case); - $this->assertInstanceOf($browser_class, $actual_browser); + $this->assertEquals($type, $actual_browser->getType()); + $this->assertInstanceOf('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration', $actual_browser); } /** @@ -74,11 +81,40 @@ public function testCreateBrowserConfiguration(array $browser_config, $service_i public function createBrowserConfigurationDataProvider() { return array( - array(array('port' => 9999), 'browser_configuration'), - array(array('port' => 9999, 'sauce' => array()), 'sauce_labs_browser_configuration'), + array(array('type' => 'test'), 'test'), + array(array(), 'default'), ); } + /** + * Test description. + * + * @return void + * @expectedException \InvalidArgumentException + */ + public function testCreateBrowserConfigurationError() + { + $browser_aliases = array('alias-one' => array()); + + $test_case = m::mock('aik099\\PHPUnit\\BrowserTestCase'); + $test_case->shouldReceive('getBrowserAliases')->once()->andReturn($browser_aliases); + + $this->_factory->createBrowserConfiguration(array('type' => 'test'), $test_case); + } + + /** + * Test description. + * + * @return void + * @expectedException \InvalidArgumentException + */ + public function testRegisterFailure() + { + $browser_configuration = $this->_createBrowserConfiguration('new-one'); + $this->_factory->register($browser_configuration); + $this->_factory->register($browser_configuration); + } + /** * Test description. * @@ -86,7 +122,7 @@ public function createBrowserConfigurationDataProvider() */ public function testCreateAPIClientSuccess() { - $browser = new SauceLabsBrowserConfiguration($this->_factory); + $browser = new SauceLabsBrowserConfiguration($this->eventDispatcher, $this->_factory); $api_client = $this->_factory->createAPIClient($browser); $this->assertInstanceOf('WebDriver\\SauceLabs\\SauceRest', $api_client); @@ -100,8 +136,23 @@ public function testCreateAPIClientSuccess() */ public function testCreateAPIClientFailure() { - $browser = new BrowserConfiguration(); + $browser = new BrowserConfiguration($this->eventDispatcher); $this->_factory->createAPIClient($browser); } + /** + * Creates browser configuration. + * + * @param string $type Type. + * + * @return BrowserConfiguration + */ + private function _createBrowserConfiguration($type) + { + $browser_configuration = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser_configuration->shouldReceive('getType')->andReturn($type); + + return $browser_configuration; + } + } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index c05b991..85a23df 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -19,8 +19,9 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; +use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; -class BrowserConfigurationTest extends \PHPUnit_Framework_TestCase +class BrowserConfigurationTest extends EventDispatcherAwareTestCase { const TEST_CASE_CLASS = '\\aik099\\PHPUnit\\BrowserTestCase'; @@ -57,13 +58,6 @@ class BrowserConfigurationTest extends \PHPUnit_Framework_TestCase */ protected $browser; - /** - * Event dispatcher. - * - * @var EventDispatcherInterface|MockInterface - */ - protected $eventDispatcher; - /** * Configures all tests. * @@ -83,7 +77,6 @@ protected function setUp() 'sessionStrategy' => ISessionStrategyFactory::TYPE_SHARED, ); - $this->eventDispatcher = m::mock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); $this->browser = $this->createBrowserConfiguration(); } @@ -99,7 +92,7 @@ protected function setUp() */ public function testAliasResolution(array $aliases, array $browser_config, array $expected_config) { - $this->browser->setAliases($aliases); + $this->assertSame($this->browser, $this->browser->setAliases($aliases)); $this->browser->setup($browser_config); $this->assertEquals($expected_config['host'], $this->browser->getHost()); @@ -469,10 +462,9 @@ public function testGetTestStatusShared() */ protected function createBrowserConfiguration(array $aliases = array(), $add_subscriber = false) { - $browser = new BrowserConfiguration(); + $browser = new BrowserConfiguration($this->eventDispatcher); $browser->setAliases($aliases); - $browser->setEventDispatcher($this->eventDispatcher); $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); return $browser; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index fda9431..1a996fb 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -50,7 +50,8 @@ protected function setUp() $this->setup['host'] = 'UN:AK@ondemand.saucelabs.com'; $this->setup['port'] = 80; - $this->setup['sauce'] = array('username' => 'UN', 'api_key' => 'AK'); + $this->setup['api_username'] = 'UN'; + $this->setup['api_key'] = 'AK'; } /** @@ -62,33 +63,21 @@ public function testSetup() { parent::testSetup(); - $this->assertSame($this->setup['sauce'], $this->browser->getSauce()); + $this->assertSame($this->setup['api_username'], $this->browser->getApiUsername()); + $this->assertSame($this->setup['api_key'], $this->browser->getApiKey()); } /** * Test description. * * @return void - * @expectedException \InvalidArgumentException */ - public function testSetSauceIncorrect() + public function testSetAPICorrect() { $browser = $this->createBrowserConfiguration(); - $browser->setSauce(array()); - } - - /** - * Test description. - * - * @return void - */ - public function testSetSauceCorrect() - { - $expected = array('username' => '', 'api_key' => ''); - $browser = $this->createBrowserConfiguration(); - $this->assertSame($browser, $browser->setSauce($expected)); - $this->assertSame($expected, $browser->getSauce()); + $this->assertEmpty($browser->getApiUsername()); + $this->assertEmpty($browser->getApiKey()); } /** @@ -327,14 +316,14 @@ public function testTestEndedWithoutSession() */ protected function createBrowserConfiguration(array $aliases = array(), $add_subscriber = false, $with_sauce = false) { - $browser = new SauceLabsBrowserConfiguration($this->_browserConfigurationFactory); + $browser = new SauceLabsBrowserConfiguration($this->eventDispatcher, $this->_browserConfigurationFactory); $browser->setAliases($aliases); - $browser->setEventDispatcher($this->eventDispatcher); $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); if ( $with_sauce ) { - $browser->setSauce(array('username' => 'A', 'api_key' => 'B')); + $browser->setApiUsername('A'); + $browser->setApiKey('B'); } return $browser; diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index fb3b813..2218e33 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -82,8 +82,7 @@ public function testSetBrowserCorrect() $test_case = $this->getFixture($session_strategy); - $browser = new BrowserConfiguration(); - $browser->setEventDispatcher($this->eventDispatcher); + $browser = new BrowserConfiguration($this->eventDispatcher); $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->once(); $this->assertSame($test_case, $test_case->setBrowser($browser)); diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index c5fcfe7..3757d02 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -12,6 +12,7 @@ use aik099\PHPUnit\Application; +use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; use Behat\Mink\Session; @@ -30,22 +31,16 @@ protected function setUp() $api_client = m::mock('WebDriver\\SauceLabs\\SauceRest'); $api_client->shouldReceive('updateJob')->withAnyArgs()->once(); + /** @var IBrowserConfigurationFactory $factory */ $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); $factory->shouldReceive('createAPIClient')->once()->andReturn($api_client); - $application = Application::getInstance(); - $service_backup = $application->replaceObject('sauce_labs_browser_configuration', function ($c) use ($factory) { - $browser = new SauceLabsBrowserConfiguration($factory); - $browser->setEventDispatcher($c['event_dispatcher']); + $browser_config = array('api_username' => 'a', 'api_key' => 'b'); + $browser = new SauceLabsBrowserConfiguration($this->readAttribute($this, '_eventDispatcher'), $factory); + $factory->shouldReceive('createBrowserConfiguration')->with($browser_config, $this)->once()->andReturn($browser); + $this->setBrowserConfigurationFactory($factory); - return $browser; - }, true); - - $this->setBrowserFromConfiguration(array( - 'sauce' => array('username' => 'a', 'api_key' => 'b'), - )); - - $application->replaceObject('sauce_labs_browser_configuration', $service_backup, true); + $this->setBrowserFromConfiguration($browser_config); parent::setUp(); } diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index 165d5b1..df98353 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -73,8 +73,6 @@ public function serviceDefinitionsDataProvider() array('regular_test_suite', 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'), array('browser_test_suite', 'aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'), array('browser_configuration_factory', 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfigurationFactory'), - array('browser_configuration', 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'), - array('sauce_labs_browser_configuration', 'aik099\\PHPUnit\\BrowserConfiguration\\SauceLabsBrowserConfiguration'), ); } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 9033e2c..e8c1003 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -10,6 +10,9 @@ define('FULL_PATH', realpath(__DIR__ . '/..')); +// TODO: until https://github.com/padraic/mockery/issues/160 is fixed. +ini_set('xdebug.scream', 0); + $vendor_path = FULL_PATH . '/vendor'; if ( !is_dir($vendor_path) ) { From 09dc7b55e0899bc75c915ca6a20fddb6fc9cbaeb Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 23 Mar 2014 16:49:56 +0200 Subject: [PATCH 034/204] Initial support for BrowserStack browser configuration Related to #8 --- .../APIClient/BrowserStackAPIClient.php | 56 +++ .../aik099/PHPUnit/APIClient/IAPIClient.php | 30 ++ .../PHPUnit/APIClient/SauceLabsAPIClient.php | 49 +++ .../ApiBrowserConfiguration.php | 246 +++++++++++++ .../BrowserConfigurationFactory.php | 12 +- .../BrowserStackBrowserConfiguration.php | 72 ++++ .../IBrowserConfigurationFactory.php | 3 +- .../SauceLabsBrowserConfiguration.php | 218 +----------- library/aik099/PHPUnit/DIContainer.php | 5 + .../ApiBrowserConfigurationTestCase.php | 325 ++++++++++++++++++ .../BrowserConfigurationFactoryTest.php | 8 +- .../BrowserConfigurationTest.php | 4 +- .../BrowserStackBrowserConfigurationTest.php | 71 ++++ .../SauceLabsBrowserConfigurationTest.php | 271 +-------------- .../PHPUnit/Fixture/SetupEventFixture.php | 5 +- 15 files changed, 882 insertions(+), 493 deletions(-) create mode 100644 library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php create mode 100644 library/aik099/PHPUnit/APIClient/IAPIClient.php create mode 100644 library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php create mode 100644 library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php create mode 100644 library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php create mode 100644 tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php create mode 100644 tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php diff --git a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php new file mode 100644 index 0000000..d26f934 --- /dev/null +++ b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php @@ -0,0 +1,56 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\APIClient; + + +class BrowserStackAPIClient implements IAPIClient +{ + + /** + * API username. + * + * @var string + */ + private $_apiUsername; + + /** + * API key. + * + * @var string + */ + private $_apiKey; + + /** + * Creates instance of API client. + * + * @param string $api_username API Username. + * @param string $api_key API Password. + */ + public function __construct($api_username, $api_key) + { + $this->_apiUsername = $api_username; + $this->_apiKey = $api_key; + } + + /** + * Update status of the test, that was executed in the given session. + * + * @param string $session_id Session ID. + * @param boolean $test_status Test status. + * + * @return void + */ + public function updateStatus($session_id, $test_status) + { + // TODO: to implement + } + +} diff --git a/library/aik099/PHPUnit/APIClient/IAPIClient.php b/library/aik099/PHPUnit/APIClient/IAPIClient.php new file mode 100644 index 0000000..12ba26f --- /dev/null +++ b/library/aik099/PHPUnit/APIClient/IAPIClient.php @@ -0,0 +1,30 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\APIClient; + + +/** + * Interface that each API client must implement. + */ +interface IAPIClient +{ + + /** + * Update status of the test, that was executed in the given session. + * + * @param string $session_id Session ID. + * @param boolean $test_status Test status. + * + * @return void + */ + public function updateStatus($session_id, $test_status); + +} diff --git a/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php b/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php new file mode 100644 index 0000000..175bf5e --- /dev/null +++ b/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php @@ -0,0 +1,49 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\APIClient; + + +use WebDriver\SauceLabs\SauceRest; + +class SauceLabsAPIClient implements IAPIClient +{ + + /** + * API client for SauceLabs service. + * + * @var SauceRest + */ + private $_sauceRest; + + /** + * Creates instance of API client. + * + * @param SauceRest $sauce_rest SauceRest client. + */ + public function __construct(SauceRest $sauce_rest) + { + $this->_sauceRest = $sauce_rest; + } + + /** + * Update status of the test, that was executed in the given session. + * + * @param string $session_id Session ID. + * @param boolean $test_status Test status. + * + * @return void + */ + public function updateStatus($session_id, $test_status) + { + $this->_sauceRest->updateJob($session_id, array('passed' => $test_status)); + } + +} diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php new file mode 100644 index 0000000..af98f8a --- /dev/null +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -0,0 +1,246 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\BrowserConfiguration; + + +use aik099\PHPUnit\APIClient\IAPIClient; +use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Event\TestEndedEvent; +use aik099\PHPUnit\Event\TestEvent; +use Behat\Mink\Driver\Selenium2Driver; +use Behat\Mink\Session; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use WebDriver\SauceLabs\SauceRest; + +/** + * Browser configuration tailored to use with API-based service. + */ +abstract class ApiBrowserConfiguration extends BrowserConfiguration +{ + + /** + * The build number. + */ + const BUILD_NUMBER_CAPABILITY = 'build'; + + /** + * The test name. + */ + const NAME_CAPABILITY = 'name'; + + /** + * Browser configuration factory. + * + * @var IBrowserConfigurationFactory + */ + protected $browserConfigurationFactory; + + /** + * Creates browser configuration. + * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. + */ + public function __construct( + EventDispatcherInterface $event_dispatcher, + IBrowserConfigurationFactory $browser_configuration_factory + ) + { + $this->browserConfigurationFactory = $browser_configuration_factory; + $this->defaultParameters['api_username'] = ''; + $this->defaultParameters['api_key'] = ''; + + parent::__construct($event_dispatcher); + } + + /** + * Initializes a browser with given configuration. + * + * @param array $parameters Browser configuration parameters. + * + * @return self + */ + public function setup(array $parameters) + { + $prepared_parameters = $this->prepareParameters($parameters); + $this->setApiUsername($prepared_parameters['api_username']); + $this->setApiKey($prepared_parameters['api_key']); + + return parent::setup($parameters); + } + + /** + * Sets API username. + * + * To be called from TestCase::setUp(). + * + * @param string $api_username API username. + * + * @return self + */ + public function setApiUsername($api_username) + { + $this->parameters['api_username'] = $api_username; + + return $this; + } + + /** + * Returns API username. + * + * @return string + */ + public function getApiUsername() + { + return $this->parameters['api_username']; + } + + /** + * Sets API key. + * + * To be called from TestCase::setUp(). + * + * @param string $api_key API key. + * + * @return self + */ + public function setApiKey($api_key) + { + $this->parameters['api_key'] = $api_key; + + return $this; + } + + /** + * Returns API key. + * + * @return string + */ + public function getApiKey() + { + return $this->parameters['api_key']; + } + + /** + * Returns port from browser configuration. + * + * @return integer + */ + public function getPort() + { + return 80; + } + + /** + * Returns browser name from browser configuration. + * + * @return string + */ + public function getBrowserName() + { + $browser_name = parent::getBrowserName(); + + return strlen($browser_name) ? $browser_name : 'chrome'; + } + + /** + * Hook, called from "BrowserTestCase::setUp" method. + * + * @param TestEvent $event Test event. + * + * @return void + */ + public function onTestSetup(TestEvent $event) + { + parent::onTestSetup($event); + + $desired_capabilities = $this->getDesiredCapabilities(); + $desired_capabilities[self::NAME_CAPABILITY] = $this->getJobName($event->getTestCase()); + + $jenkins_build_number = getenv('BUILD_NUMBER'); + + if ( $jenkins_build_number ) { + $desired_capabilities[self::BUILD_NUMBER_CAPABILITY] = $jenkins_build_number; + } + + $this->setDesiredCapabilities($desired_capabilities); + } + + /** + * Returns Job name for API service. + * + * @param BrowserTestCase $test_case Browser test case. + * + * @return string + */ + protected function getJobName(BrowserTestCase $test_case) + { + if ( $this->isShared() ) { + return get_class($test_case); + } + + return $test_case->toString(); + } + + /** + * Hook, called from "BrowserTestCase::run" method. + * + * @param TestEndedEvent $event Test ended event. + * + * @return void + */ + public function onTestEnded(TestEndedEvent $event) + { + parent::onTestEnded($event); + + if ( $event->getSession() === null ) { + // Session wasn't used in particular test. + return; + } + + $test_case = $event->getTestCase(); + + $this->getAPIClient()->updateStatus( + $this->getSessionId($event->getSession()), + $this->getTestStatus($test_case, $event->getTestResult()) + ); + } + + /** + * Returns API class for service interaction. + * + * @return IAPIClient + */ + protected function getAPIClient() + { + return $this->browserConfigurationFactory->createAPIClient($this); + } + + /** + * Get Selenium2 current session id. + * + * @param Session $session Session. + * + * @return string + * @throws \RuntimeException When session was created using an unsupported driver. + */ + protected function getSessionId(Session $session) + { + $driver = $session->getDriver(); + + if ( $driver instanceof Selenium2Driver ) { + return $driver->getWebDriverSessionId(); + } + + throw new \RuntimeException('Unsupported session driver'); + } + +} diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php index 3ffce45..5525926 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php @@ -11,6 +11,9 @@ namespace aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\APIClient\BrowserStackAPIClient; +use aik099\PHPUnit\APIClient\IAPIClient; +use aik099\PHPUnit\APIClient\SauceLabsAPIClient; use aik099\PHPUnit\BrowserTestCase; use WebDriver\SauceLabs\SauceRest; @@ -88,13 +91,18 @@ protected function create($type) * * @param BrowserConfiguration $browser Browser configuration. * - * @return \stdClass + * @return IAPIClient * @throws \LogicException When unsupported browser configuration given. */ public function createAPIClient(BrowserConfiguration $browser) { if ( $browser instanceof SauceLabsBrowserConfiguration ) { - return new SauceRest($browser->getApiUsername(), $browser->getApiKey()); + $sauce_rest = new SauceRest($browser->getApiUsername(), $browser->getApiKey()); + + return new SauceLabsAPIClient($sauce_rest); + } + elseif ( $browser instanceof BrowserStackBrowserConfiguration ) { + return new BrowserStackAPIClient($browser->getApiUsername(), $browser->getApiKey()); } throw new \LogicException('Unsupported browser configuration given'); diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php new file mode 100644 index 0000000..9137100 --- /dev/null +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php @@ -0,0 +1,72 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\BrowserConfiguration; + + +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * Browser configuration tailored to use with "BrowserStack" service. + * + * @link https://www.browserstack.com/automate + */ +class BrowserStackBrowserConfiguration extends ApiBrowserConfiguration +{ + + /** + * Creates browser configuration. + * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. + */ + public function __construct( + EventDispatcherInterface $event_dispatcher, + IBrowserConfigurationFactory $browser_configuration_factory + ) + { + $this->defaultParameters['type'] = 'browserstack'; + + parent::__construct($event_dispatcher, $browser_configuration_factory); + } + + /** + * Returns hostname from browser configuration. + * + * @return string + */ + public function getHost() + { + return $this->getApiUsername() . ':' . $this->getApiKey() . '@hub.browserstack.com'; + } + + /** + * Returns desired capabilities from browser configuration. + * + * @return array + * @link http://www.browserstack.com/automate/capabilities + */ + public function getDesiredCapabilities() + { + $capabilities = parent::getDesiredCapabilities(); + + if ( !isset($capabilities['os']) ) { + $capabilities['os'] = 'Windows'; + $capabilities['os_version'] = 'XP'; + } + + if ( !isset($capabilities['acceptSslCerts']) ) { + $capabilities['acceptSslCerts'] = 'true'; + } + + return $capabilities; + } + +} diff --git a/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php index 935e801..0a65a41 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php @@ -11,6 +11,7 @@ namespace aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserTestCase; /** @@ -46,7 +47,7 @@ public function register(BrowserConfiguration $browser); * * @param BrowserConfiguration $browser Browser configuration. * - * @return \stdClass + * @return IAPIClient * @throws \LogicException When unsupported browser configuration given. */ public function createAPIClient(BrowserConfiguration $browser); diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 801f987..72679ad 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -11,37 +11,16 @@ namespace aik099\PHPUnit\BrowserConfiguration; -use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEndedEvent; -use aik099\PHPUnit\Event\TestEvent; -use Behat\Mink\Driver\Selenium2Driver; -use Behat\Mink\Session; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use WebDriver\SauceLabs\SauceRest; /** * Browser configuration tailored to use with "Sauce Labs" service. + * + * @link https://saucelabs.com/php */ -class SauceLabsBrowserConfiguration extends BrowserConfiguration +class SauceLabsBrowserConfiguration extends ApiBrowserConfiguration { - /** - * The build number. - */ - const BUILD_NUMBER_CAPABILITY = 'build'; - - /** - * The test name. - */ - const NAME_CAPABILITY = 'name'; - - /** - * Browser configuration factory. - * - * @var IBrowserConfigurationFactory - */ - private $_browserConfigurationFactory; - /** * Creates browser configuration. * @@ -53,84 +32,9 @@ public function __construct( IBrowserConfigurationFactory $browser_configuration_factory ) { - $this->_browserConfigurationFactory = $browser_configuration_factory; - $this->defaultParameters['api_username'] = ''; - $this->defaultParameters['api_key'] = ''; $this->defaultParameters['type'] = 'saucelabs'; - parent::__construct($event_dispatcher); - } - - /** - * Initializes a browser with given configuration. - * - * @param array $parameters Browser configuration parameters. - * - * @return self - */ - public function setup(array $parameters) - { - $prepared_parameters = $this->prepareParameters($parameters); - $this->setApiUsername($prepared_parameters['api_username']); - $this->setApiKey($prepared_parameters['api_key']); - - return parent::setup($parameters); - } - - /** - * Sets "Sauce Labs" API username. - * - * To be called from TestCase::setUp(). - * - * @param string $api_username API username. - * - * @return self - * @link https://saucelabs.com/php - */ - public function setApiUsername($api_username) - { - $this->parameters['api_username'] = $api_username; - - return $this; - } - - /** - * Returns "Sauce Labs" api username. - * - * @return string - * @link https://saucelabs.com/php - */ - public function getApiUsername() - { - return $this->parameters['api_username']; - } - - /** - * Sets "Sauce Labs" API key. - * - * To be called from TestCase::setUp(). - * - * @param string $api_key API key. - * - * @return self - * @link https://saucelabs.com/php - */ - public function setApiKey($api_key) - { - $this->parameters['api_key'] = $api_key; - - return $this; - } - - /** - * Returns "Sauce Labs" api key. - * - * @return string - * @link https://saucelabs.com/php - */ - public function getApiKey() - { - return $this->parameters['api_key']; + parent::__construct($event_dispatcher, $browser_configuration_factory); } /** @@ -143,28 +47,6 @@ public function getHost() return $this->getApiUsername() . ':' . $this->getApiKey() . '@ondemand.saucelabs.com'; } - /** - * Returns port from browser configuration. - * - * @return integer - */ - public function getPort() - { - return 80; - } - - /** - * Returns browser name from browser configuration. - * - * @return string - */ - public function getBrowserName() - { - $browser_name = parent::getBrowserName(); - - return strlen($browser_name) ? $browser_name : 'chrome'; - } - /** * Returns desired capabilities from browser configuration. * @@ -185,96 +67,4 @@ public function getDesiredCapabilities() return $capabilities; } - /** - * Hook, called from "BrowserTestCase::setUp" method. - * - * @param TestEvent $event Test event. - * - * @return void - */ - public function onTestSetup(TestEvent $event) - { - parent::onTestSetup($event); - - $desired_capabilities = $this->getDesiredCapabilities(); - $desired_capabilities[self::NAME_CAPABILITY] = $this->getJobName($event->getTestCase()); - - $jenkins_build_number = getenv('BUILD_NUMBER'); - - if ( $jenkins_build_number ) { - $desired_capabilities[self::BUILD_NUMBER_CAPABILITY] = $jenkins_build_number; - } - - $this->setDesiredCapabilities($desired_capabilities); - } - - /** - * Returns Job name for "Sauce Labs" service. - * - * @param BrowserTestCase $test_case Browser test case. - * - * @return string - */ - protected function getJobName(BrowserTestCase $test_case) - { - if ( $this->isShared() ) { - return get_class($test_case); - } - - return $test_case->toString(); - } - - /** - * Hook, called from "BrowserTestCase::run" method. - * - * @param TestEndedEvent $event Test ended event. - * - * @return void - */ - public function onTestEnded(TestEndedEvent $event) - { - parent::onTestEnded($event); - - if ( $event->getSession() === null ) { - // Session wasn't used in particular test. - return; - } - - $test_case = $event->getTestCase(); - - $this->getAPIClient()->updateJob( - $this->getSessionId($event->getSession()), - array('passed' => $this->getTestStatus($test_case, $event->getTestResult())) - ); - } - - /** - * Returns API class for "Sauce Labs" service interaction. - * - * @return SauceRest - */ - protected function getAPIClient() - { - return $this->_browserConfigurationFactory->createAPIClient($this); - } - - /** - * Get Selenium2 current session id. - * - * @param Session $session Session. - * - * @return string - * @throws \RuntimeException When session was created using an unsupported driver. - */ - protected function getSessionId(Session $session) - { - $driver = $session->getDriver(); - - if ( $driver instanceof Selenium2Driver ) { - return $driver->getWebDriverSessionId(); - } - - throw new \RuntimeException('Unsupported session driver'); - } - } diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index f52819d..b0ff045 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -13,6 +13,7 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; +use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteUrl; @@ -120,12 +121,16 @@ public function __construct(array $values = array()) $this['browser_configuration_factory'] = function ($c) { $browser_configuration_factory = new BrowserConfigurationFactory(); + $browser_configuration_factory->register( new BrowserConfiguration($c['event_dispatcher']) ); $browser_configuration_factory->register( new SauceLabsBrowserConfiguration($c['event_dispatcher'], $browser_configuration_factory) ); + $browser_configuration_factory->register( + new BrowserStackBrowserConfiguration($c['event_dispatcher'], $browser_configuration_factory) + ); return $browser_configuration_factory; }; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php new file mode 100644 index 0000000..29cd162 --- /dev/null +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -0,0 +1,325 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\BrowserConfiguration; + + +use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; +use aik099\PHPUnit\Event\TestEndedEvent; +use aik099\PHPUnit\Event\TestEvent; +use aik099\PHPUnit\Session\ISessionStrategyFactory; +use Mockery\MockInterface; +use Symfony\Component\EventDispatcher\EventDispatcher; +use aik099\PHPUnit\BrowserTestCase; +use Mockery as m; + +abstract class ApiBrowserConfigurationTestCase extends BrowserConfigurationTest +{ + + const PORT = 80; + + const AUTOMATIC_TEST_NAME = 'AUTOMATIC'; + + /** + * Browser configuration class. + * + * @var string + */ + protected $browserConfigurationClass = ''; + + /** + * Browser configuration factory. + * + * @var IBrowserConfigurationFactory|MockInterface + */ + protected $browserConfigurationFactory; + + /** + * Configures all tests. + * + * @return void + */ + protected function setUp() + { + $this->browserConfigurationFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + + parent::setUp(); + + $this->setup['port'] = 80; + $this->setup['api_username'] = 'UN'; + $this->setup['api_key'] = 'AK'; + } + + /** + * Test description. + * + * @return void + */ + public function testSetup() + { + parent::testSetup(); + + $this->assertSame($this->setup['api_username'], $this->browser->getApiUsername()); + $this->assertSame($this->setup['api_key'], $this->browser->getApiKey()); + } + + /** + * Test description. + * + * @return void + */ + public function testSetAPICorrect() + { + $browser = $this->createBrowserConfiguration(); + + $this->assertEmpty($browser->getApiUsername()); + $this->assertEmpty($browser->getApiKey()); + } + + /** + * Test description. + * + * @return void + */ + public function testSetHostCorrect() + { + $browser = $this->createBrowserConfiguration(array(), false, true); + + $this->assertSame($browser, $browser->setHost('EXAMPLE_HOST')); + $this->assertSame('A:B@ondemand.saucelabs.com', $browser->getHost()); + } + + /** + * Test description. + * + * @return void + */ + public function testSetPortCorrect() + { + $browser = $this->createBrowserConfiguration(array(), false, true); + $this->assertSame($browser, $browser->setPort(5555)); + $this->assertSame(80, $browser->getPort()); + } + + /** + * Test description. + * + * @return void + */ + public function testSetBrowserNameCorrect() + { + $browser = $this->createBrowserConfiguration(array(), false, true); + $this->assertSame($browser, $browser->setBrowserName('')); + $this->assertSame('chrome', $browser->getBrowserName()); + } + + /** + * Test description. + * + * @param array|null $desired_capabilities Desired capabilities. + * @param array|null $expected Expected capabilities. + * + * @return void + * @dataProvider desiredCapabilitiesDataProvider + */ + public function testSetDesiredCapabilitiesCorrect(array $desired_capabilities = null, array $expected = null) + { + $browser = $this->createBrowserConfiguration(array(), false, true); + $this->assertSame($browser, $browser->setDesiredCapabilities($desired_capabilities)); + $this->assertSame($expected, $browser->getDesiredCapabilities()); + } + + /** + * Desired capability data provider. + * + * @return array + */ + abstract public function desiredCapabilitiesDataProvider(); + + /** + * Test description. + * + * @param string $session_strategy Session strategy. + * @param string $test_name Expected job name. + * @param string $build_number Build number. + * + * @return void + * @dataProvider setupEventDataProvider + */ + public function testTestSetupEvent($session_strategy, $test_name, $build_number = null) + { + putenv('BUILD_NUMBER' . ($build_number ? '=' . $build_number : '')); + + $this->browser->setSessionStrategy($session_strategy); + + $event_dispatcher = new EventDispatcher(); + $event_dispatcher->addSubscriber($this->browser); + + $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('toString')->times($this->_isAutomaticTestName($test_name) ? 0 : 1)->andReturn($test_name); + + if ( $this->_isAutomaticTestName($test_name) ) { + $test_name = get_class($test_case); + } + + $event_dispatcher->dispatch( + BrowserTestCase::TEST_SETUP_EVENT, + new TestEvent($test_case, m::mock('Behat\\Mink\\Session')) + ); + + $desired_capabilities = $this->browser->getDesiredCapabilities(); + + $this->assertArrayHasKey(ApiBrowserConfiguration::NAME_CAPABILITY, $desired_capabilities); + $this->assertEquals($test_name, $desired_capabilities[ApiBrowserConfiguration::NAME_CAPABILITY]); + + if ( isset($build_number) ) { + $this->assertArrayHasKey(ApiBrowserConfiguration::BUILD_NUMBER_CAPABILITY, $desired_capabilities); + $this->assertEquals($build_number, $desired_capabilities[ApiBrowserConfiguration::BUILD_NUMBER_CAPABILITY]); + } + else { + $this->assertArrayNotHasKey(ApiBrowserConfiguration::BUILD_NUMBER_CAPABILITY, $desired_capabilities); + } + } + + /** + * Checks that test name is automatic. + * + * @param string $test_name Expected job name. + * + * @return boolean + */ + private function _isAutomaticTestName($test_name) + { + return $test_name == self::AUTOMATIC_TEST_NAME; + } + + /** + * Data provider for TestSetup event handler. + * + * @return array + */ + public function setupEventDataProvider() + { + return array( + 'isolated, name, build' => array(ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME', 'BUILD_NUMBER'), + 'shared, no name, build' => array(ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME, 'BUILD_NUMBER'), + 'isolated, name, no build' => array(ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME'), + 'shared, no name, no build' => array(ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME), + ); + } + + /** + * Test description. + * + * @param string $driver_type Driver. + * + * @return void + * @dataProvider theTestEndedEventDataProvider + */ + public function testTestEndedEvent($driver_type) + { + $test_case = m::mock(self::TEST_CASE_CLASS); + + $sauce_rest = m::mock('WebDriver\\SauceLabs\\SauceRest'); + $this->browserConfigurationFactory->shouldReceive('createAPIClient')->with($this->browser)->andReturn($sauce_rest); + + if ( $driver_type == 'selenium' ) { + $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); + $driver->shouldReceive('getWebDriverSessionId')->once()->andReturn('SID'); + + $sauce_rest->shouldReceive('updateStatus')->with('SID', true)->once(); + $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // For shared strategy. + } + else { + $driver = m::mock('\\Behat\\Mink\\Driver\\DriverInterface'); + $this->setExpectedException('RuntimeException'); + } + + $session = m::mock('Behat\\Mink\\Session'); + $session->shouldReceive('getDriver')->once()->andReturn($driver); + + $event_dispatcher = new EventDispatcher(); + $event_dispatcher->addSubscriber($this->browser); + + $test_result = m::mock('PHPUnit_Framework_TestResult'); + + $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); + + $event = $event_dispatcher->dispatch( + BrowserTestCase::TEST_ENDED_EVENT, + new TestEndedEvent($test_case, $test_result, $session) + ); + + $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $event); + } + + /** + * Returns possible drivers for session creation. + * + * @return array + */ + public function theTestEndedEventDataProvider() + { + return array( + array('selenium'), + array('other'), + ); + } + + /** + * Test description. + * + * @return void + */ + public function testTestEndedWithoutSession() + { + $event_dispatcher = new EventDispatcher(); + $event_dispatcher->addSubscriber($this->browser); + + $event = m::mock('aik099\\PHPUnit\\Event\\TestEndedEvent'); + $event->shouldReceive('getSession')->once(); + $event->shouldReceive('setDispatcher')->once(); // To remove with Symfony 3.0 release. + $event->shouldReceive('setName')->once(); // To remove with Symfony 3.0 release. + $event->shouldReceive('isPropagationStopped')->once()->andReturn(false); + $event->shouldReceive('getTestCase')->never(); + + $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); + $returned_event = $event_dispatcher->dispatch(BrowserTestCase::TEST_ENDED_EVENT, $event); + + $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $returned_event); + } + + /** + * Creates instance of browser configuration. + * + * @param array $aliases Aliases. + * @param boolean $add_subscriber Expect addition of subscriber to event dispatcher. + * @param boolean $with_api Include test API configuration. + * + * @return ApiBrowserConfiguration + */ + protected function createBrowserConfiguration(array $aliases = array(), $add_subscriber = false, $with_api = false) + { + /** @var ApiBrowserConfiguration $browser */ + $browser = new $this->browserConfigurationClass($this->eventDispatcher, $this->browserConfigurationFactory); + $browser->setAliases($aliases); + + $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); + + if ( $with_api ) { + $browser->setApiUsername('A'); + $browser->setApiKey('B'); + } + + return $browser; + } + +} diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index 6eb5854..9239a86 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -8,11 +8,12 @@ * @link https://github.com/aik099/phpunit-mink */ -namespace tests\aik099\PHPUnit; +namespace tests\aik099\PHPUnit\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; +use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use Mockery as m; use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; @@ -124,8 +125,11 @@ public function testCreateAPIClientSuccess() { $browser = new SauceLabsBrowserConfiguration($this->eventDispatcher, $this->_factory); $api_client = $this->_factory->createAPIClient($browser); + $this->assertInstanceOf('aik099\\PHPUnit\\APIClient\\SauceLabsAPIClient', $api_client); - $this->assertInstanceOf('WebDriver\\SauceLabs\\SauceRest', $api_client); + $browser = new BrowserStackBrowserConfiguration($this->eventDispatcher, $this->_factory); + $api_client = $this->_factory->createAPIClient($browser); + $this->assertInstanceOf('aik099\\PHPUnit\\APIClient\\BrowserStackAPIClient', $api_client); } /** diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 85a23df..6499a1a 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -8,15 +8,13 @@ * @link https://github.com/aik099/phpunit-mink */ -namespace tests\aik099\PHPUnit; +namespace tests\aik099\PHPUnit\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\Session\ISessionStrategyFactory; use Mockery as m; -use Mockery\MockInterface; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php new file mode 100644 index 0000000..7c184e1 --- /dev/null +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -0,0 +1,71 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\BrowserConfiguration; + + +use Mockery as m; + +class BrowserStackBrowserConfigurationTest extends ApiBrowserConfigurationTestCase +{ + + const HOST = ':@hub.browserstack.com'; + + /** + * Configures all tests. + * + * @return void + */ + protected function setUp() + { + $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserStackBrowserConfiguration'; + + parent::setUp(); + + $this->setup['desiredCapabilities'] = array( + 'os' => 'Windows', 'os_version' => '7', 'version' => 10, + 'acceptSslCerts' => 'true', + ); + $this->setup['host'] = 'UN:AK@hub.browserstack.com'; + } + + /** + * Test description. + * + * @return void + */ + public function testSetHostCorrect() + { + $browser = $this->createBrowserConfiguration(array(), false, true); + + $this->assertSame($browser, $browser->setHost('EXAMPLE_HOST')); + $this->assertSame('A:B@hub.browserstack.com', $browser->getHost()); + } + + /** + * Desired capability data provider. + * + * @return array + */ + public function desiredCapabilitiesDataProvider() + { + return array( + array( + array('os' => 'os-name', 'os_version' => 'os-version'), + array('os' => 'os-name', 'os_version' => 'os-version', 'acceptSslCerts' => 'true'), + ), + array( + array('acceptSslCerts' => 'false'), + array('acceptSslCerts' => 'false', 'os' => 'Windows', 'os_version' => 'XP'), + ), + ); + } + +} diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 1a996fb..a847cb6 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -8,35 +8,16 @@ * @link https://github.com/aik099/phpunit-mink */ -namespace tests\aik099\PHPUnit; +namespace tests\aik099\PHPUnit\BrowserConfiguration; -use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; -use aik099\PHPUnit\Event\TestEndedEvent; -use aik099\PHPUnit\Event\TestEvent; -use aik099\PHPUnit\Session\ISessionStrategyFactory; -use Mockery\MockInterface; -use Symfony\Component\EventDispatcher\EventDispatcher; -use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; -use aik099\PHPUnit\BrowserTestCase; use Mockery as m; -class SauceLabsBrowserConfigurationTest extends BrowserConfigurationTest +class SauceLabsBrowserConfigurationTest extends ApiBrowserConfigurationTestCase { const HOST = ':@ondemand.saucelabs.com'; - const PORT = 80; - - const AUTOMATIC_TEST_NAME = 'AUTOMATIC'; - - /** - * Browser configuration factory. - * - * @var IBrowserConfigurationFactory|MockInterface - */ - private $_browserConfigurationFactory; - /** * Configures all tests. * @@ -44,40 +25,11 @@ class SauceLabsBrowserConfigurationTest extends BrowserConfigurationTest */ protected function setUp() { - $this->_browserConfigurationFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\SauceLabsBrowserConfiguration'; parent::setUp(); $this->setup['host'] = 'UN:AK@ondemand.saucelabs.com'; - $this->setup['port'] = 80; - $this->setup['api_username'] = 'UN'; - $this->setup['api_key'] = 'AK'; - } - - /** - * Test description. - * - * @return void - */ - public function testSetup() - { - parent::testSetup(); - - $this->assertSame($this->setup['api_username'], $this->browser->getApiUsername()); - $this->assertSame($this->setup['api_key'], $this->browser->getApiKey()); - } - - /** - * Test description. - * - * @return void - */ - public function testSetAPICorrect() - { - $browser = $this->createBrowserConfiguration(); - - $this->assertEmpty($browser->getApiUsername()); - $this->assertEmpty($browser->getApiKey()); } /** @@ -93,46 +45,6 @@ public function testSetHostCorrect() $this->assertSame('A:B@ondemand.saucelabs.com', $browser->getHost()); } - /** - * Test description. - * - * @return void - */ - public function testSetPortCorrect() - { - $browser = $this->createBrowserConfiguration(array(), false, true); - $this->assertSame($browser, $browser->setPort(5555)); - $this->assertSame(80, $browser->getPort()); - } - - /** - * Test description. - * - * @return void - */ - public function testSetBrowserNameCorrect() - { - $browser = $this->createBrowserConfiguration(array(), false, true); - $this->assertSame($browser, $browser->setBrowserName('')); - $this->assertSame('chrome', $browser->getBrowserName()); - } - - /** - * Test description. - * - * @param array|null $desired_capabilities Desired capabilities. - * @param array|null $expected Expected capabilities. - * - * @return void - * @dataProvider desiredCapabilitiesDataProvider - */ - public function testSetDesiredCapabilitiesCorrect(array $desired_capabilities = null, array $expected = null) - { - $browser = $this->createBrowserConfiguration(array(), false, true); - $this->assertSame($browser, $browser->setDesiredCapabilities($desired_capabilities)); - $this->assertSame($expected, $browser->getDesiredCapabilities()); - } - /** * Desired capability data provider. * @@ -152,181 +64,4 @@ public function desiredCapabilitiesDataProvider() ); } - /** - * Test description. - * - * @param string $session_strategy Session strategy. - * @param string $test_name Expected job name. - * @param string $build_number Build number. - * - * @return void - * @dataProvider setupEventDataProvider - */ - public function testTestSetupEvent($session_strategy, $test_name, $build_number = null) - { - putenv('BUILD_NUMBER' . ($build_number ? '=' . $build_number : '')); - - $this->browser->setSessionStrategy($session_strategy); - - $event_dispatcher = new EventDispatcher(); - $event_dispatcher->addSubscriber($this->browser); - - $test_case = m::mock(self::TEST_CASE_CLASS); - $test_case->shouldReceive('toString')->times($this->_isAutomaticTestName($test_name) ? 0 : 1)->andReturn($test_name); - - if ( $this->_isAutomaticTestName($test_name) ) { - $test_name = get_class($test_case); - } - - $event_dispatcher->dispatch( - BrowserTestCase::TEST_SETUP_EVENT, - new TestEvent($test_case, m::mock('Behat\\Mink\\Session')) - ); - - $desired_capabilities = $this->browser->getDesiredCapabilities(); - - $this->assertArrayHasKey(SauceLabsBrowserConfiguration::NAME_CAPABILITY, $desired_capabilities); - $this->assertEquals($test_name, $desired_capabilities[SauceLabsBrowserConfiguration::NAME_CAPABILITY]); - - if ( isset($build_number) ) { - $this->assertArrayHasKey(SauceLabsBrowserConfiguration::BUILD_NUMBER_CAPABILITY, $desired_capabilities); - $this->assertEquals($build_number, $desired_capabilities[SauceLabsBrowserConfiguration::BUILD_NUMBER_CAPABILITY]); - } - else { - $this->assertArrayNotHasKey(SauceLabsBrowserConfiguration::BUILD_NUMBER_CAPABILITY, $desired_capabilities); - } - } - - /** - * Checks that test name is automatic. - * - * @param string $test_name Expected job name. - * - * @return boolean - */ - private function _isAutomaticTestName($test_name) - { - return $test_name == self::AUTOMATIC_TEST_NAME; - } - - /** - * Data provider for TestSetup event handler. - * - * @return array - */ - public function setupEventDataProvider() - { - return array( - 'isolated, name, build' => array(ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME', 'BUILD_NUMBER'), - 'shared, no name, build' => array(ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME, 'BUILD_NUMBER'), - 'isolated, name, no build' => array(ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME'), - 'shared, no name, no build' => array(ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME), - ); - } - - /** - * Test description. - * - * @param string $driver_type Driver. - * - * @return void - * @dataProvider theTestEndedEventDataProvider - */ - public function testTestEndedEvent($driver_type) - { - $test_case = m::mock(self::TEST_CASE_CLASS); - - $sauce_rest = m::mock('WebDriver\\SauceLabs\\SauceRest'); - $this->_browserConfigurationFactory->shouldReceive('createAPIClient')->with($this->browser)->andReturn($sauce_rest); - - if ( $driver_type == 'selenium' ) { - $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); - $driver->shouldReceive('getWebDriverSessionId')->once()->andReturn('SID'); - - $sauce_rest->shouldReceive('updateJob')->with('SID', array('passed' => true))->once(); - $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // For shared strategy. - } - else { - $driver = m::mock('\\Behat\\Mink\\Driver\\DriverInterface'); - $this->setExpectedException('RuntimeException'); - } - - $session = m::mock('Behat\\Mink\\Session'); - $session->shouldReceive('getDriver')->once()->andReturn($driver); - - $event_dispatcher = new EventDispatcher(); - $event_dispatcher->addSubscriber($this->browser); - - $test_result = m::mock('PHPUnit_Framework_TestResult'); - - $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); - - $event = $event_dispatcher->dispatch( - BrowserTestCase::TEST_ENDED_EVENT, - new TestEndedEvent($test_case, $test_result, $session) - ); - - $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $event); - } - - /** - * Returns possible drivers for session creation. - * - * @return array - */ - public function theTestEndedEventDataProvider() - { - return array( - array('selenium'), - array('other'), - ); - } - - /** - * Test description. - * - * @return void - */ - public function testTestEndedWithoutSession() - { - $event_dispatcher = new EventDispatcher(); - $event_dispatcher->addSubscriber($this->browser); - - $event = m::mock('aik099\\PHPUnit\\Event\\TestEndedEvent'); - $event->shouldReceive('getSession')->once(); - $event->shouldReceive('setDispatcher')->once(); // To remove with Symfony 3.0 release. - $event->shouldReceive('setName')->once(); // To remove with Symfony 3.0 release. - $event->shouldReceive('isPropagationStopped')->once()->andReturn(false); - $event->shouldReceive('getTestCase')->never(); - - $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); - $returned_event = $event_dispatcher->dispatch(BrowserTestCase::TEST_ENDED_EVENT, $event); - - $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $returned_event); - } - - /** - * Creates instance of browser configuration. - * - * @param array $aliases Aliases. - * @param boolean $add_subscriber Expect addition of subscriber to event dispatcher. - * @param boolean $with_sauce Include test sauce configuration. - * - * @return SauceLabsBrowserConfiguration - */ - protected function createBrowserConfiguration(array $aliases = array(), $add_subscriber = false, $with_sauce = false) - { - $browser = new SauceLabsBrowserConfiguration($this->eventDispatcher, $this->_browserConfigurationFactory); - $browser->setAliases($aliases); - - $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); - - if ( $with_sauce ) { - $browser->setApiUsername('A'); - $browser->setApiKey('B'); - } - - return $browser; - } - } diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index 3757d02..5117d08 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -11,7 +11,6 @@ namespace tests\aik099\PHPUnit\Fixture; -use aik099\PHPUnit\Application; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; @@ -28,8 +27,8 @@ class SetupEventFixture extends BrowserTestCase */ protected function setUp() { - $api_client = m::mock('WebDriver\\SauceLabs\\SauceRest'); - $api_client->shouldReceive('updateJob')->withAnyArgs()->once(); + $api_client = m::mock('aik099\\PHPUnit\\APIClient\\IAPIClient'); + $api_client->shouldReceive('updateStatus')->withAnyArgs()->once(); /** @var IBrowserConfigurationFactory $factory */ $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); From bd7b11c7cdaf41fa8bb939c6ce11368c0a7e9635 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 23 Mar 2014 22:53:33 +0200 Subject: [PATCH 035/204] Integration with SauceConnect 1. allow to run SauceLabs tests on Travis 2. solved problem where BrowserConfiguration's from ALL tests in test case file were disconnected from EventDispatcher once first test finished execution 3. the IAPIClient::updateStatus now returns operation result 4. a way to report test status back to BrowserStack (not tested yet) 5. support for running tests on Travis 6. don't attempt to stop not started sessions from strategies --- .travis.yml | 10 +- .../APIClient/BrowserStackAPIClient.php | 47 ++++++- .../aik099/PHPUnit/APIClient/IAPIClient.php | 2 +- .../PHPUnit/APIClient/SauceLabsAPIClient.php | 4 +- .../ApiBrowserConfiguration.php | 18 ++- .../BrowserConfiguration.php | 22 +++ .../BrowserConfigurationFactory.php | 7 +- .../SauceLabsBrowserConfiguration.php | 27 +++- .../Session/IsolatedSessionStrategy.php | 6 +- .../PHPUnit/Session/SharedSessionStrategy.php | 6 +- .../PHPUnit/TestSuite/AbstractTestSuite.php | 6 +- phpunit.xml.dist | 5 + .../ApiBrowserConfigurationTestCase.php | 38 ++++-- .../BrowserConfigurationTest.php | 9 +- .../SauceLabsBrowserConfigurationTest.php | 2 +- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 128 ++++++++++++++++++ .../PHPUnit/Fixture/SetupEventFixture.php | 5 +- .../Integration/ApiIntegrationTest.php | 35 +++++ .../Session/IsolatedSessionStrategyTest.php | 1 + .../Session/SharedSessionStrategyTest.php | 1 + 20 files changed, 344 insertions(+), 35 deletions(-) create mode 100644 tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php create mode 100644 tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php diff --git a/.travis.yml b/.travis.yml index 80a9fa4..7524523 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,14 @@ php: - 5.4 - 5.5 +env: + global: + - secure: XTlGGWYR/0OwJLQMHHvTopTj37OL97wiFIMMmiZQtmyf2neNia/Se9ASftgeFHI6WeSxcjC0hYF9LtPNHCHW30Qv8E2/L6PtENxZY8tBGUq0O/4XaCIhGUdc9NxkteZ3M5rgTWkLbs8Sctl31/vqG4bYstNwgLvHnw2Jh4TBHuU= + - secure: KIgQ3vADaLcuzlRNNjq3veFp9p4Vq30GYbYyqaEpz7eUI/t7r/THhSmsUc04+tcmc6iXXfMzjQmylUerE8pDNBBtBfBsmUkuVvXDQTeIv8WYgBVMalFR0rfI/v3mzn9gzRHbtEEJMtsRenvfBJPqrrAdI4W4vyEOCSTIKklumck= + +addons: + sauce_connect: true + before_script: - composer require satooshi/php-coveralls:dev-master --dev --prefer-source @@ -15,4 +23,4 @@ script: after_script: - php vendor/bin/coveralls -v - wget https://scrutinizer-ci.com/ocular.phar - - php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml \ No newline at end of file + - php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml diff --git a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php index d26f934..47e5ed5 100644 --- a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php @@ -11,6 +11,8 @@ namespace aik099\PHPUnit\APIClient; +use WebDriver\Service\CurlServiceInterface; + class BrowserStackAPIClient implements IAPIClient { @@ -28,16 +30,25 @@ class BrowserStackAPIClient implements IAPIClient */ private $_apiKey; + /** + * Curl service. + * + * @var CurlServiceInterface + */ + private $_curlService; + /** * Creates instance of API client. * - * @param string $api_username API Username. - * @param string $api_key API Password. + * @param string $api_username API Username. + * @param string $api_key API Password. + * @param CurlServiceInterface $curl_service Curl service. */ - public function __construct($api_username, $api_key) + public function __construct($api_username, $api_key, CurlServiceInterface $curl_service) { $this->_apiUsername = $api_username; $this->_apiKey = $api_key; + $this->_curlService = $curl_service; } /** @@ -46,11 +57,37 @@ public function __construct($api_username, $api_key) * @param string $session_id Session ID. * @param boolean $test_status Test status. * - * @return void + * @return boolean */ public function updateStatus($session_id, $test_status) { - // TODO: to implement + $data = array('status' => $test_status ? 'completed' : 'error'); + + return $this->execute('PUT', 'sessions/' . $session_id . '.json', json_encode($data)); + } + + /** + * Execute BrowserStack REST API command. + * + * @param string $requestMethod HTTP request method. + * @param string $url URL. + * @param mixed $parameters Parameters. + * + * @return mixed + * @see http://www.browserstack.com/automate/rest-api + */ + protected function execute($requestMethod, $url, $parameters = null) + { + $extraOptions = array( + CURLOPT_HTTPAUTH => CURLAUTH_BASIC, + CURLOPT_USERPWD => $this->_apiUsername . ':' . $this->_apiKey, + ); + + $url = 'https://www.browserstack.com/automate/' . $url; + + list($rawResults, $info) = $this->_curlService->execute($requestMethod, $url, $parameters, $extraOptions); + + return json_decode($rawResults, true); } } diff --git a/library/aik099/PHPUnit/APIClient/IAPIClient.php b/library/aik099/PHPUnit/APIClient/IAPIClient.php index 12ba26f..61d76e8 100644 --- a/library/aik099/PHPUnit/APIClient/IAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/IAPIClient.php @@ -23,7 +23,7 @@ interface IAPIClient * @param string $session_id Session ID. * @param boolean $test_status Test status. * - * @return void + * @return boolean */ public function updateStatus($session_id, $test_status); diff --git a/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php b/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php index 175bf5e..ee0b6fa 100644 --- a/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php @@ -39,11 +39,11 @@ public function __construct(SauceRest $sauce_rest) * @param string $session_id Session ID. * @param boolean $test_status Test status. * - * @return void + * @return boolean */ public function updateStatus($session_id, $test_status) { - $this->_sauceRest->updateJob($session_id, array('passed' => $test_status)); + return $this->_sauceRest->updateJob($session_id, array('passed' => $test_status)); } } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index af98f8a..172ac7e 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -18,7 +18,6 @@ use Behat\Mink\Driver\Selenium2Driver; use Behat\Mink\Session; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use WebDriver\SauceLabs\SauceRest; /** * Browser configuration tailored to use with API-based service. @@ -160,15 +159,20 @@ public function getBrowserName() */ public function onTestSetup(TestEvent $event) { + if ( !$this->isEventForMe($event) ) { + return; + } + parent::onTestSetup($event); $desired_capabilities = $this->getDesiredCapabilities(); $desired_capabilities[self::NAME_CAPABILITY] = $this->getJobName($event->getTestCase()); - $jenkins_build_number = getenv('BUILD_NUMBER'); - - if ( $jenkins_build_number ) { - $desired_capabilities[self::BUILD_NUMBER_CAPABILITY] = $jenkins_build_number; + if ( getenv('BUILD_NUMBER') ) { + $desired_capabilities[self::BUILD_NUMBER_CAPABILITY] = getenv('BUILD_NUMBER'); // Jenkins. + } + elseif ( getenv('TRAVIS_BUILD_NUMBER') ) { + $desired_capabilities[self::BUILD_NUMBER_CAPABILITY] = getenv('TRAVIS_BUILD_NUMBER'); } $this->setDesiredCapabilities($desired_capabilities); @@ -199,6 +203,10 @@ protected function getJobName(BrowserTestCase $test_case) */ public function onTestEnded(TestEndedEvent $event) { + if ( !$this->isEventForMe($event) ) { + return; + } + parent::onTestEnded($event); if ( $event->getSession() === null ) { diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index abec817..8be95f6 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -535,7 +535,11 @@ protected static function arrayMergeRecursive($array1, $array2) */ public function onTestSetup(TestEvent $event) { + if ( !$this->isEventForMe($event) ) { + return; + } + // Place code here. } /** @@ -547,7 +551,25 @@ public function onTestSetup(TestEvent $event) */ public function onTestEnded(TestEndedEvent $event) { + if ( !$this->isEventForMe($event) ) { + return; + } + $this->detachFromTestCase(); } + /** + * Determines if received event is designed for this recipient. + * + * @param TestEvent $event Event. + * + * @return boolean + */ + protected function isEventForMe(TestEvent $event) + { + $test_case = $event->getTestCase(); + + return get_class($test_case) === get_class($this->_testCase) && $test_case->getName() === $this->_testCase->getName(); + } + } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php index 5525926..dbc3dc9 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php @@ -16,6 +16,7 @@ use aik099\PHPUnit\APIClient\SauceLabsAPIClient; use aik099\PHPUnit\BrowserTestCase; use WebDriver\SauceLabs\SauceRest; +use WebDriver\ServiceFactory; /** * Browser configuration factory. @@ -102,7 +103,11 @@ public function createAPIClient(BrowserConfiguration $browser) return new SauceLabsAPIClient($sauce_rest); } elseif ( $browser instanceof BrowserStackBrowserConfiguration ) { - return new BrowserStackAPIClient($browser->getApiUsername(), $browser->getApiKey()); + return new BrowserStackAPIClient( + $browser->getApiUsername(), + $browser->getApiKey(), + ServiceFactory::getInstance()->getService('service.curl') + ); } throw new \LogicException('Unsupported browser configuration given'); diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 72679ad..dd17253 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -11,6 +11,7 @@ namespace aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\Event\TestEvent; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** @@ -37,6 +38,30 @@ public function __construct( parent::__construct($event_dispatcher, $browser_configuration_factory); } + /** + * Hook, called from "BrowserTestCase::setUp" method. + * + * @param TestEvent $event Test event. + * + * @return void + */ + public function onTestSetup(TestEvent $event) + { + if ( !$this->isEventForMe($event) ) { + return; + } + + parent::onTestSetup($event); + + $desired_capabilities = $this->getDesiredCapabilities(); + + if ( getenv('TRAVIS_JOB_NUMBER') ) { + $desired_capabilities['tunnel-identifier'] = getenv('TRAVIS_JOB_NUMBER'); + } + + $this->setDesiredCapabilities($desired_capabilities); + } + /** * Returns hostname from browser configuration. * @@ -57,7 +82,7 @@ public function getDesiredCapabilities() $capabilities = parent::getDesiredCapabilities(); if ( !isset($capabilities['platform']) ) { - $capabilities['platform'] = 'Windows XP'; + $capabilities['platform'] = 'Windows 7'; } if ( !isset($capabilities['version']) ) { diff --git a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php index b00df40..7757dba 100644 --- a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php @@ -90,8 +90,10 @@ public function session(BrowserConfiguration $browser) */ public function onTestEnd(TestEvent $event) { - if ( $event->getSession() !== null ) { - $event->getSession()->stop(); + $session = $event->getSession(); + + if ( $session !== null && $session->isStarted() ) { + $session->stop(); } } diff --git a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php index 5883dbd..ca7a5ce 100644 --- a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -159,8 +159,10 @@ public function onTestFailed(TestFailedEvent $event) */ public function onTestSuiteEnd(TestEvent $event) { - if ( $event->getSession() !== null ) { - $event->getSession()->stop(); + $session = $event->getSession(); + + if ( $session !== null && $session->isStarted() ) { + $session->stop(); } } diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index 5040a81..ee6f6b6 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -117,9 +117,9 @@ protected function tearDown() * @return void * @codeCoverageIgnore */ - /*public function onTestSuiteEnded() + public function onTestSuiteEnded() { - // method created just to simplify tearDown method - }*/ + // Method created just to simplify tearDown method. + } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 517af0a..1b120eb 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -23,6 +23,11 @@ lowUpperBound="35" highLowerBound="70"/> --> + + + + + diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 29cd162..b4764d5 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -49,6 +49,9 @@ abstract class ApiBrowserConfigurationTestCase extends BrowserConfigurationTest */ protected function setUp() { + $this->testsRequireSubscriber[] = 'testTestSetupEvent'; + $this->testsRequireSubscriber[] = 'testTestEndedEvent'; + $this->testsRequireSubscriber[] = 'testTestEndedWithoutSession'; $this->browserConfigurationFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); parent::setUp(); @@ -160,12 +163,12 @@ public function testTestSetupEvent($session_strategy, $test_name, $build_number $this->browser->setSessionStrategy($session_strategy); + $test_case = $this->createTestCase($test_name); + $test_case->shouldReceive('toString')->times($this->_isAutomaticTestName($test_name) ? 0 : 1)->andReturn($test_name); + $event_dispatcher = new EventDispatcher(); $event_dispatcher->addSubscriber($this->browser); - $test_case = m::mock(self::TEST_CASE_CLASS); - $test_case->shouldReceive('toString')->times($this->_isAutomaticTestName($test_name) ? 0 : 1)->andReturn($test_name); - if ( $this->_isAutomaticTestName($test_name) ) { $test_name = get_class($test_case); } @@ -226,16 +229,16 @@ public function setupEventDataProvider() */ public function testTestEndedEvent($driver_type) { - $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case = $this->createTestCase('TEST_NAME'); - $sauce_rest = m::mock('WebDriver\\SauceLabs\\SauceRest'); - $this->browserConfigurationFactory->shouldReceive('createAPIClient')->with($this->browser)->andReturn($sauce_rest); + $api_client = m::mock('aik099\\PHPUnit\\APIClient\\IAPIClient'); + $this->browserConfigurationFactory->shouldReceive('createAPIClient')->with($this->browser)->andReturn($api_client); if ( $driver_type == 'selenium' ) { $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); $driver->shouldReceive('getWebDriverSessionId')->once()->andReturn('SID'); - $sauce_rest->shouldReceive('updateStatus')->with('SID', true)->once(); + $api_client->shouldReceive('updateStatus')->with('SID', true)->once(); $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // For shared strategy. } else { @@ -281,6 +284,8 @@ public function theTestEndedEventDataProvider() */ public function testTestEndedWithoutSession() { + $test_case = $this->createTestCase('TEST_NAME'); + $event_dispatcher = new EventDispatcher(); $event_dispatcher->addSubscriber($this->browser); @@ -289,7 +294,7 @@ public function testTestEndedWithoutSession() $event->shouldReceive('setDispatcher')->once(); // To remove with Symfony 3.0 release. $event->shouldReceive('setName')->once(); // To remove with Symfony 3.0 release. $event->shouldReceive('isPropagationStopped')->once()->andReturn(false); - $event->shouldReceive('getTestCase')->never(); + $event->shouldReceive('getTestCase')->andReturn($test_case); $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); $returned_event = $event_dispatcher->dispatch(BrowserTestCase::TEST_ENDED_EVENT, $event); @@ -297,6 +302,23 @@ public function testTestEndedWithoutSession() $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $returned_event); } + /** + * Create TestCase with Browser. + * + * @param string $name Test case name. + * + * @return BrowserTestCase + */ + protected function createTestCase($name) + { + $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('setRemoteCoverageScriptUrl')->once(); + $test_case->shouldReceive('getName')->andReturn($name); + $this->browser->attachToTestCase($test_case); + + return $test_case; + } + /** * Creates instance of browser configuration. * diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 6499a1a..350f22c 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -56,6 +56,13 @@ class BrowserConfigurationTest extends EventDispatcherAwareTestCase */ protected $browser; + /** + * Tests names, that require subscriber. + * + * @var array + */ + protected $testsRequireSubscriber = array(); + /** * Configures all tests. * @@ -75,7 +82,7 @@ protected function setUp() 'sessionStrategy' => ISessionStrategyFactory::TYPE_SHARED, ); - $this->browser = $this->createBrowserConfiguration(); + $this->browser = $this->createBrowserConfiguration(array(), in_array($this->getName(false), $this->testsRequireSubscriber)); } /** diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index a847cb6..7540fdf 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -59,7 +59,7 @@ public function desiredCapabilitiesDataProvider() ), array( array('version' => 'ver1'), - array('version' => 'ver1', 'platform' => 'Windows XP'), + array('version' => 'ver1', 'platform' => 'Windows 7'), ), ); } diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php new file mode 100644 index 0000000..0be0416 --- /dev/null +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -0,0 +1,128 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Fixture; + + +use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Event\TestEvent; +use Mockery as m; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use WebDriver\SauceLabs\SauceRest; + +class ApiIntegrationFixture extends BrowserTestCase +{ + + /** + * Browser list to be used in tests. + * + * @var array + */ + public static $browsers = array( + array('alias' => 'saucelabs'), +// array('alias' => 'browserstack'), + ); + + /** + * Sets event dispatcher. + * + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * + * @return void + */ + public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) + { + parent::setEventDispatcher($event_dispatcher); + + $event_dispatcher->addListener(self::TEST_ENDED_EVENT, array($this, 'verifyRemoteAPICalls')); + } + + /** + * Verify how the API calls were made. + * + * @param TestEvent $event Event. + * + * @return void + */ + public function verifyRemoteAPICalls(TestEvent $event) + { + $test_case = $event->getTestCase(); + + if ( get_class($test_case) !== get_class($this) || $test_case->getName() !== $this->getName() ) { + return; + } + + $browser = $this->getBrowser(); + + if ( $browser instanceof SauceLabsBrowserConfiguration ) { + $sauce_rest = new SauceRest($browser->getApiUsername(), $browser->getApiKey()); + $job_info = $sauce_rest->getJob($event->getSession()->getDriver()->getWebDriverSessionId()); + + $passed_mapping = array( + 'testSuccess' => true, + 'testFailure' => false, + ); + + $this->assertSame($passed_mapping[$test_case->getName()], $job_info['passed']); + } + } + + /** + * Test description. + * + * @return void + */ + public function testSuccess() + { + $session = $this->getSession(); + $session->visit('http://www.google.com'); + + $this->assertTrue(true); + } + + /** + * Test description. + * + * @return void + */ + public function testFailure() + { + $session = $this->getSession(); + $session->visit('http://www.google.com'); + + $this->assertTrue(false); + } + + /** + * Gets browser configuration aliases. + * + * Allows to decouple actual test server connection details from test cases. + * + * @return array + */ + public function getBrowserAliases() + { + return array( + 'saucelabs' => array( + 'type' => 'saucelabs', + 'api_username' => getenv('SAUCE_USERNAME'), + 'api_key' => getenv('SAUCE_ACCESS_KEY'), + + 'browserName' => 'chrome', + 'desiredCapabilities' => array('version' => 28), + ), + /*'browserstack' => array( + 'type' => 'browserstack', + ),*/ + ); + } + +} diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index 5117d08..723fd85 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -59,8 +59,9 @@ public function testEvents() // For SauceLabsBrowserConfiguration::onTestEnded. $session->shouldReceive('getDriver')->once()->andReturn($driver); - // For IsolatedSessionStrategy::onTestEnd. - $session->shouldReceive('stop')->once(); + // For IsolatedSessionStrategy::onTestEnd (twice because we have 2 strategies listening for test end). + $session->shouldReceive('stop')->twice(); + $session->shouldReceive('isStarted')->andReturn(true); $this->_setSession($session); diff --git a/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php b/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php new file mode 100644 index 0000000..7203f71 --- /dev/null +++ b/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php @@ -0,0 +1,35 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Integration; + + +use Mockery as m; +use tests\aik099\PHPUnit\Fixture\ApiIntegrationFixture; + +class ApiIntegrationTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Test description. + * + * @return void + */ + public function testAPICalls() + { + $result = new \PHPUnit_Framework_TestResult(); + + $suite = ApiIntegrationFixture::suite('tests\\aik099\\PHPUnit\\Fixture\\ApiIntegrationFixture'); + $suite->run($result); + + $this->assertTrue(true); + } + +} diff --git a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php index 0c2b487..df746b4 100644 --- a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php @@ -75,6 +75,7 @@ public function testOnTestEnd() { $session = m::mock(self::SESSION_CLASS); $session->shouldReceive('stop')->once(); + $session->shouldReceive('isStarted')->once()->andReturn(true); $event = $this->eventDispatcher->dispatch( BrowserTestCase::TEST_ENDED_EVENT, diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index cb5637e..ddae231 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -167,6 +167,7 @@ public function testEndOfTestCaseWithSession() { $session = $this->createSession(); $session->shouldReceive('stop')->withNoArgs()->once(); + $session->shouldReceive('isStarted')->once()->andReturn(true); $event = $this->eventDispatcher->dispatch( BrowserTestCase::TEST_SUITE_ENDED_EVENT, From ac18bfb2843d9287344d6e5744002c774675e850 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 23 Mar 2014 22:58:53 +0200 Subject: [PATCH 036/204] Integration with SauceConnect 1. don't let PHPUnit override Travis connection details --- phpunit.xml.dist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 1b120eb..d589bc6 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -23,10 +23,10 @@ lowUpperBound="35" highLowerBound="70"/> --> - + From 86a20a880c55cd0e2a8ddc533e336a9d57f3f8ba Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 29 Mar 2014 21:00:02 +0200 Subject: [PATCH 037/204] Changes to coding standard 1. more strict array formatting validation: - empty arrays must not have whitespaces between parenthesis - checking that no whitespace is present between array keyword and opening parenthesis - checking that no whitespaces present in inline array declaration after/before array parenthesis 3. more strict whitespace check before/after/within control structures --- CodingStandard/Sniffs/Array/ArraySniff.php | 54 ++- .../Commenting/FunctionCommentSniff.php | 319 ++++++++++++++++++ .../ControlStructureSpacingSniff.php | 231 +++++++++++++ CodingStandard/ruleset.xml | 8 - 4 files changed, 592 insertions(+), 20 deletions(-) create mode 100644 CodingStandard/Sniffs/Commenting/FunctionCommentSniff.php create mode 100644 CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php diff --git a/CodingStandard/Sniffs/Array/ArraySniff.php b/CodingStandard/Sniffs/Array/ArraySniff.php index 3c72340..b9257ca 100644 --- a/CodingStandard/Sniffs/Array/ArraySniff.php +++ b/CodingStandard/Sniffs/Array/ArraySniff.php @@ -69,30 +69,60 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) */ protected function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, array $tokens) { - $lastItem = $phpcsFile->findPrevious( - array(T_WHITESPACE), - ($tokens[$stackPtr]['parenthesis_closer'] - 1), - $stackPtr, - true - ); + $arrayStart = $tokens[$stackPtr]['parenthesis_opener']; + $arrayEnd = $tokens[$arrayStart]['parenthesis_closer']; + + if ($arrayStart !== ($stackPtr + 1)) { + $error = 'There must be no space between the Array keyword and the opening parenthesis'; + $phpcsFile->addError($error, $stackPtr, 'SpaceAfterKeyword'); + } + + // Check for empty arrays. + $content = $phpcsFile->findNext(array(T_WHITESPACE), ($arrayStart + 1), ($arrayEnd + 1), true); + if ($content === $arrayEnd) { + // Empty array, but if the brackets aren't together, there's a problem. + if (($arrayEnd - $arrayStart) !== 1) { + $error = 'Empty array declaration must have no space between the parentheses'; + $phpcsFile->addError($error, $stackPtr, 'SpaceInEmptyArray'); + + // We can return here because there is nothing else to check. All code + // below can assume that the array is not empty. + return; + } + } + + $lastItem = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($arrayEnd - 1), $stackPtr, true); // Empty array. - if ($lastItem === $tokens[$stackPtr]['parenthesis_opener']) { + if ($lastItem === $arrayStart) { return; } // Inline array. - $isInlineArray = $tokens[$tokens[$stackPtr]['parenthesis_opener']]['line'] == $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line']; + $isInlineArray = $tokens[$arrayStart]['line'] === $tokens[$arrayEnd]['line']; // Check if the last item in a multiline array has a "closing" comma. if ($tokens[$lastItem]['code'] !== T_COMMA && $isInlineArray === false) { - $phpcsFile->addWarning('A comma should follow the last multiline array item. Found: ' . $tokens[$lastItem]['content'], $lastItem); + $phpcsFile->addWarning('A comma should follow the last multiline array item. Found: '.$tokens[$lastItem]['content'], $lastItem); return; } - if ($tokens[$lastItem]['code'] === T_COMMA && $isInlineArray === true) { - $phpcsFile->addWarning('Last item of an inline array must not followed by a comma', $lastItem); - return; + if ($isInlineArray === true) { + if ($tokens[$lastItem]['code'] === T_COMMA) { + $phpcsFile->addWarning('Comma not allowed after last value in single-line array declaration', $lastItem); + return; + } + + // Inline array must not have spaces within parenthesis. + if ($content !== ($arrayStart + 1)) { + $error = 'Space found after opening parenthesis of Array'; + $phpcsFile->addError($error, $stackPtr, 'SpaceAfterOpen'); + } + + if ($lastItem !== ($arrayEnd - 1)) { + $error = 'Space found before closing parenthesis of Array'; + $phpcsFile->addError($error, $stackPtr, 'SpaceAfterClose'); + } } }//end sniffItemClosings() diff --git a/CodingStandard/Sniffs/Commenting/FunctionCommentSniff.php b/CodingStandard/Sniffs/Commenting/FunctionCommentSniff.php new file mode 100644 index 0000000..82a35e6 --- /dev/null +++ b/CodingStandard/Sniffs/Commenting/FunctionCommentSniff.php @@ -0,0 +1,319 @@ + + * @author Marc McIntyre + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +if (class_exists('Squiz_Sniffs_Commenting_FunctionCommentSniff', true) === false) { + $error = 'Class Squiz_Sniffs_Commenting_FunctionCommentSniff not found'; + throw new PHP_CodeSniffer_Exception($error); +} + +/** + * Parses and verifies the doc comments for functions. + * + * Same as the Squiz standard, but adds support for API tags. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Greg Sherwood + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @version Release: @package_version@ + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_Commenting_FunctionCommentSniff extends Squiz_Sniffs_Commenting_FunctionCommentSniff +{ + + /** + * Reflection of parent sniff private property. + * + * @var ReflectionProperty + */ + private $_functionTokenReflection; + + /** + * Reflection of parent sniff private property. + * + * @var ReflectionProperty + */ + private $_classTokenReflection; + + /** + * Reflection of parent sniff private property. + * + * @var ReflectionProperty + */ + private $_methodNameReflection; + + + /** + * Stores class reflection. + */ + public function __construct() + { + $parentClass = 'Squiz_Sniffs_Commenting_FunctionCommentSniff'; + + $this->_functionTokenReflection = new ReflectionProperty($parentClass, '_functionToken'); + $this->_functionTokenReflection->setAccessible(true); + + $this->_classTokenReflection = new ReflectionProperty($parentClass, '_classToken'); + $this->_classTokenReflection->setAccessible(true); + + $this->_methodNameReflection = new ReflectionProperty($parentClass, '_methodName'); + $this->_methodNameReflection->setAccessible(true); + + }//end __construct() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token + * in the stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $this->currentFile = $phpcsFile; + + $tokens = $phpcsFile->getTokens(); + + $find = array( + T_COMMENT, + T_DOC_COMMENT, + T_CLASS, + T_FUNCTION, + T_OPEN_TAG, + ); + + $commentEnd = $phpcsFile->findPrevious($find, ($stackPtr - 1)); + + if ($commentEnd === false) { + return; + } + + // If the token that we found was a class or a function, then this + // function has no doc comment. + $code = $tokens[$commentEnd]['code']; + + if ($code === T_COMMENT) { + // The function might actually be missing a comment, and this last comment + // found is just commenting a bit of code on a line. So if it is not the + // only thing on the line, assume we found nothing. + $prevContent = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $commentEnd); + if ($tokens[$commentEnd]['line'] === $tokens[$commentEnd]['line']) { + $error = 'Missing function doc comment'; + $phpcsFile->addError($error, $stackPtr, 'Missing'); + } else { + $error = 'You must use "/**" style comments for a function comment'; + $phpcsFile->addError($error, $stackPtr, 'WrongStyle'); + } + + return; + } else if ($code !== T_DOC_COMMENT) { + $error = 'Missing function doc comment'; + $phpcsFile->addError($error, $stackPtr, 'Missing'); + return; + } else if (trim($tokens[$commentEnd]['content']) !== '*/') { + $error = 'You must use "*/" to end a function comment; found "%s"'; + $phpcsFile->addError($error, $commentEnd, 'WrongEnd', array(trim($tokens[$commentEnd]['content']))); + return; + }//end if + + // If there is any code between the function keyword and the doc block + // then the doc block is not for us. + $ignore = PHP_CodeSniffer_Tokens::$scopeModifiers; + $ignore[] = T_STATIC; + $ignore[] = T_WHITESPACE; + $ignore[] = T_ABSTRACT; + $ignore[] = T_FINAL; + $prevToken = $phpcsFile->findPrevious($ignore, ($stackPtr - 1), null, true); + if ($prevToken !== $commentEnd) { + $phpcsFile->addError('Missing function doc comment', $stackPtr, 'Missing'); + return; + } + + $this->_functionTokenReflection->setValue($this, $stackPtr); + + $this->_classTokenReflection->setValue($this, null); + foreach ($tokens[$stackPtr]['conditions'] as $condPtr => $condition) { + if ($condition === T_CLASS || $condition === T_INTERFACE) { + $this->_classTokenReflection->setValue($this, $condPtr); + break; + } + } + + // Find the first doc comment. + $commentStart = ($phpcsFile->findPrevious(T_DOC_COMMENT, ($commentEnd - 1), null, true) + 1); + $commentString = $phpcsFile->getTokensAsString($commentStart, ($commentEnd - $commentStart + 1)); + $this->_methodNameReflection->setValue($this, $phpcsFile->getDeclarationName($stackPtr)); + + try { + $this->commentParser = new PHP_CodeSniffer_CommentParser_FunctionCommentParser($commentString, $phpcsFile); + $this->commentParser->parse(); + } catch (PHP_CodeSniffer_CommentParser_ParserException $e) { + $line = ($e->getLineWithinComment() + $commentStart); + $phpcsFile->addError($e->getMessage(), $line, 'FailedParse'); + return; + } + + $comment = $this->commentParser->getComment(); + if (is_null($comment) === true) { + $error = 'Function doc comment is empty'; + $phpcsFile->addError($error, $commentStart, 'Empty'); + return; + } + + // The first line of the comment should just be the /** code. + $eolPos = strpos($commentString, $phpcsFile->eolChar); + $firstLine = substr($commentString, 0, $eolPos); + if ($firstLine !== '/**') { + $error = 'The open comment tag must be the only content on the line'; + $phpcsFile->addError($error, $commentStart, 'ContentAfterOpen'); + } + + $this->processParams($commentStart, $commentEnd); + $this->processSees($commentStart); + $this->processReturn($commentStart, $commentEnd); + $this->processThrows($commentStart); + + // Check for a comment description. + $short = $comment->getShortComment(); + if (trim($short) === '') { + $error = 'Missing short description in function doc comment'; + $phpcsFile->addError($error, $commentStart, 'MissingShort'); + return; + } + + // No extra newline before short description. + $newlineCount = 0; + $newlineSpan = strspn($short, $phpcsFile->eolChar); + if ($short !== '' && $newlineSpan > 0) { + $error = 'Extra newline(s) found before function comment short description'; + $phpcsFile->addError($error, ($commentStart + 1), 'SpacingBeforeShort'); + } + + $newlineCount = (substr_count($short, $phpcsFile->eolChar) + 1); + + // Exactly one blank line between short and long description. + $long = $comment->getLongComment(); + if (empty($long) === false) { + $between = $comment->getWhiteSpaceBetween(); + $newlineBetween = substr_count($between, $phpcsFile->eolChar); + if ($newlineBetween !== 2) { + $error = 'There must be exactly one blank line between descriptions in function comment'; + $phpcsFile->addError($error, ($commentStart + $newlineCount + 1), 'SpacingBetween'); + } + + $newlineCount += $newlineBetween; + + $testLong = trim($long); + if (preg_match('|\p{Lu}|u', $testLong[0]) === 0) { + $error = 'Function comment long description must start with a capital letter'; + $phpcsFile->addError($error, ($commentStart + $newlineCount), 'LongNotCapital'); + } + }//end if + + // Exactly one blank line before tags. + $params = $this->commentParser->getTagOrders(); + if (count($params) > 1) { + $newlineSpan = $comment->getNewlineAfter(); + if ($newlineSpan !== 2) { + $error = 'There must be exactly one blank line before the tags in function comment'; + if ($long !== '') { + $newlineCount += (substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1); + } + + $phpcsFile->addError($error, ($commentStart + $newlineCount), 'SpacingBeforeTags'); + $short = rtrim($short, $phpcsFile->eolChar.' '); + } + } + + // Short description must be single line and end with a full stop. + $testShort = trim($short); + $lastChar = $testShort[(strlen($testShort) - 1)]; + if (substr_count($testShort, $phpcsFile->eolChar) !== 0) { + $error = 'Function comment short description must be on a single line'; + $phpcsFile->addError($error, ($commentStart + 1), 'ShortSingleLine'); + } + + $isEvent = $this->isEvent(); + + if ($isEvent === true && preg_match('/(\p{Lu}|\[)/u', $testShort[0]) === 0) { + $error = 'Event comment short description must start with a capital letter or an ['; + $phpcsFile->addError($error, ($commentStart + 1), 'ShortNotCapital'); + } else if ($isEvent === false && preg_match('/\p{Lu}/u', $testShort[0]) === 0) { + $error = 'Function comment short description must start with a capital letter'; + $phpcsFile->addError($error, ($commentStart + 1), 'ShortNotCapital'); + } + + if ($lastChar !== '.') { + $error = 'Function comment short description must end with a full stop'; + $phpcsFile->addError($error, ($commentStart + 1), 'ShortFullStop'); + } + + // Check for unknown/deprecated tags. + $this->processUnknownTags($commentStart, $commentEnd); + + // The last content should be a newline and the content before + // that should not be blank. If there is more blank space + // then they have additional blank lines at the end of the comment. + $words = $this->commentParser->getWords(); + $lastPos = (count($words) - 1); + if (trim($words[($lastPos - 1)]) !== '' + || strpos($words[($lastPos - 1)], $this->currentFile->eolChar) === false + || trim($words[($lastPos - 2)]) === '' + ) { + $error = 'Additional blank lines found at end of function comment'; + $this->currentFile->addError($error, $commentEnd, 'SpacingAfter'); + } + + }//end process() + + + /** + * Determines if a method is an event in the event handler class. + * + * @return bool + */ + protected function isEvent() + { + if (substr($this->getClassName(), -12) === 'EventHandler') { + return substr($this->_methodNameReflection->getValue($this), 0, 2) == 'On'; + } + + return false; + }//end isEvent() + + + /** + * Returns class name to which current method belongs. + * + * @return string + */ + protected function getClassName() + { + if ($this->_classTokenReflection->getValue($this) !== null) { + return $this->currentFile->getDeclarationName($this->_classTokenReflection->getValue($this)); + } + + return ''; + + }//end getClassName() + + +}//end class + +?> diff --git a/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php new file mode 100644 index 0000000..9544de5 --- /dev/null +++ b/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -0,0 +1,231 @@ + + * @author Marc McIntyre + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @link http://pear.php.net/package/PHP_CodeSniffer + */ + +/** + * CodingStandard_Sniffs_WhiteSpace_ControlStructureSpacingSniff. + * + * Checks that control structures have the correct spacing around brackets. + * + * @category PHP + * @package PHP_CodeSniffer + * @author Greg Sherwood + * @author Marc McIntyre + * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) + * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence + * @version Release: @package_version@ + * @link http://pear.php.net/package/PHP_CodeSniffer + */ +class CodingStandard_Sniffs_WhiteSpace_ControlStructureSpacingSniff implements PHP_CodeSniffer_Sniff +{ + + /** + * A list of tokenizers this sniff supports. + * + * @var array + */ + public $supportedTokenizers = array( + 'PHP', + 'JS', + ); + + /** + * How many spaces should follow the opening bracket. + * + * @var int + */ + public $requiredSpacesAfterOpen = 1; + + /** + * How many spaces should precede the closing bracket. + * + * @var int + */ + public $requiredSpacesBeforeClose = 1; + + + /** + * Returns an array of tokens this test wants to listen for. + * + * @return array + */ + public function register() + { + return array( + T_IF, + T_WHILE, + T_FOREACH, + T_FOR, + T_SWITCH, + T_DO, + T_ELSE, + T_ELSEIF, + ); + + }//end register() + + + /** + * Processes this test, when one of its tokens is encountered. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token + * in the stack passed in $tokens. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $this->requiredSpacesAfterOpen = (int) $this->requiredSpacesAfterOpen; + $this->requiredSpacesBeforeClose = (int) $this->requiredSpacesBeforeClose; + $tokens = $phpcsFile->getTokens(); + + if (isset($tokens[$stackPtr]['scope_closer']) === false) { + return; + } + + if (isset($tokens[$stackPtr]['parenthesis_opener']) === true) { + $parenOpener = $tokens[$stackPtr]['parenthesis_opener']; + $parenCloser = $tokens[$stackPtr]['parenthesis_closer']; + $spaceAfterOpen = 0; + if ($tokens[($parenOpener + 1)]['code'] === T_WHITESPACE) { + $spaceAfterOpen = strlen($tokens[($parenOpener + 1)]['content']); + } + + if ($spaceAfterOpen !== $this->requiredSpacesAfterOpen) { + $error = 'Expected %s spaces after opening bracket; %s found'; + $data = array( + $this->requiredSpacesAfterOpen, + $spaceAfterOpen, + ); + $phpcsFile->addError($error, ($parenOpener + 1), 'SpacingAfterOpenBrace', $data); + } + + if ($tokens[$parenOpener]['line'] === $tokens[$parenCloser]['line']) { + $spaceBeforeClose = 0; + if ($tokens[($parenCloser - 1)]['code'] === T_WHITESPACE) { + $spaceBeforeClose = strlen($tokens[($parenCloser - 1)]['content']); + } + + if ($spaceBeforeClose !== $this->requiredSpacesBeforeClose) { + $error = 'Expected %s spaces before closing bracket; %s found'; + $data = array( + $this->requiredSpacesBeforeClose, + $spaceBeforeClose, + ); + $phpcsFile->addError($error, ($parenCloser - 1), 'SpaceBeforeCloseBrace', $data); + } + } + }//end if + + $scopeOpener = $tokens[$stackPtr]['scope_opener']; + $scopeCloser = $tokens[$stackPtr]['scope_closer']; + + $firstContent = $phpcsFile->findNext( + T_WHITESPACE, + ($scopeOpener + 1), + null, + true + ); + + if ($tokens[$firstContent]['line'] !== ($tokens[$scopeOpener]['line'] + 1)) { + $error = 'Blank line found at start of control structure'; + $phpcsFile->addError($error, $scopeOpener, 'SpacingBeforeOpen'); + } + + $lastContent = $phpcsFile->findPrevious( + T_WHITESPACE, + ($scopeCloser - 1), + null, + true + ); + + if ($tokens[$lastContent]['line'] !== ($tokens[$scopeCloser]['line'] - 1)) { + $error = 'Blank line found at end of control structure'; + $phpcsFile->addError($error, $scopeCloser, 'SpacingAfterClose'); + } + + $trailingContent = $phpcsFile->findNext( + T_WHITESPACE, + ($scopeCloser + 1), + null, + true + ); + + if ($tokens[$trailingContent]['code'] === T_ELSE) { + if ($tokens[$stackPtr]['code'] === T_IF) { + // IF with ELSE. + return; + } + } + + if ($tokens[$trailingContent]['code'] === T_COMMENT) { + if ($tokens[$trailingContent]['line'] === $tokens[$scopeCloser]['line']) { + if (substr($tokens[$trailingContent]['content'], 0, 5) === '//end') { + // There is an end comment, so we have to get the next piece + // of content. + $trailingContent = $phpcsFile->findNext( + T_WHITESPACE, + ($trailingContent + 1), + null, + true + ); + } + } + } + + // If this token is closing a CASE or DEFAULT, we don't need the + // blank line after this control structure. + if (isset($tokens[$trailingContent]['scope_condition']) === true) { + $condition = $tokens[$trailingContent]['scope_condition']; + if ($tokens[$condition]['code'] === T_CASE + || $tokens[$condition]['code'] === T_DEFAULT + ) { + return; + } + } + + if ($tokens[$trailingContent]['code'] === T_CLOSE_TAG) { + // At the end of the script or embedded code. + return; + } + + if ($tokens[$trailingContent]['code'] === T_CLOSE_CURLY_BRACKET) { + // Another control structure's closing brace. + if (isset($tokens[$trailingContent]['scope_condition']) === true) { + $owner = $tokens[$trailingContent]['scope_condition']; + if ($tokens[$owner]['code'] === T_FUNCTION) { + // The next content is the closing brace of a function + // so normal function rules apply and we can ignore it. + return; + } + } + + if ($tokens[$trailingContent]['line'] !== ($tokens[$scopeCloser]['line'] + 1)) { + $error = 'Blank line found after control structure'; + $phpcsFile->addError($error, $scopeCloser, 'LineAfterClose'); + } + } else { + if ($tokens[$trailingContent]['line'] === ($tokens[$scopeCloser]['line'] + 1)) { + $error = 'No blank line found after control structure'; + $phpcsFile->addError($error, $scopeCloser, 'NoLineAfterClose'); + } + }//end if + + }//end process() + + +}//end class + +?> diff --git a/CodingStandard/ruleset.xml b/CodingStandard/ruleset.xml index ce09535..bfb6eff 100644 --- a/CodingStandard/ruleset.xml +++ b/CodingStandard/ruleset.xml @@ -85,7 +85,6 @@ --> - - - - - - - - From 57357130eb15224b738bde9ed5c90584d9738110 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 29 Mar 2014 21:36:39 +0200 Subject: [PATCH 038/204] Changes to coding standard 1. bug fixes --- .../Sniffs/WhiteSpace/ControlStructureSpacingSniff.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php index 9544de5..b7c5b55 100644 --- a/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ b/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -217,6 +217,13 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) $phpcsFile->addError($error, $scopeCloser, 'LineAfterClose'); } } else { + $trailingCode = $tokens[$trailingContent]['code']; + + if ($trailingCode === T_ELSE || $trailingCode === T_ELSEIF || $trailingCode === T_COMMENT) { + // Allow else/elseif/comment to come right after 'if' closing brace. + return; + } + if ($tokens[$trailingContent]['line'] === ($tokens[$scopeCloser]['line'] + 1)) { $error = 'No blank line found after control structure'; $phpcsFile->addError($error, $scopeCloser, 'NoLineAfterClose'); From c6be205003c0a90a140a13990069bc223ecd8d0b Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 2 Apr 2014 13:57:03 +0300 Subject: [PATCH 039/204] Adding tests for Travis integration --- .../ApiBrowserConfigurationTestCase.php | 27 +++++++-- .../SauceLabsBrowserConfigurationTest.php | 59 +++++++++++++++++++ .../PHPUnit/Fixture/ApiIntegrationFixture.php | 8 ++- 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index b4764d5..588769d 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -152,14 +152,21 @@ abstract public function desiredCapabilitiesDataProvider(); * * @param string $session_strategy Session strategy. * @param string $test_name Expected job name. + * @param string $build_env_name Name of ENV variable to set build number to. * @param string $build_number Build number. * * @return void * @dataProvider setupEventDataProvider */ - public function testTestSetupEvent($session_strategy, $test_name, $build_number = null) + public function testTestSetupEvent($session_strategy, $test_name, $build_env_name = null, $build_number = null) { - putenv('BUILD_NUMBER' . ($build_number ? '=' . $build_number : '')); + // Reset any global env vars that might be left from previous tests. + putenv('BUILD_NUMBER'); + putenv('TRAVIS_BUILD_NUMBER'); + + if ( isset($build_number) ) { + putenv($build_env_name . '=' . $build_number); + } $this->browser->setSessionStrategy($session_strategy); @@ -211,9 +218,21 @@ private function _isAutomaticTestName($test_name) */ public function setupEventDataProvider() { + $seed = uniqid(); + return array( - 'isolated, name, build' => array(ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME', 'BUILD_NUMBER'), - 'shared, no name, build' => array(ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME, 'BUILD_NUMBER'), + 'isolated, name, jenkins' => array( + ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME', 'BUILD_NUMBER', 'JENKINS ' . $seed, + ), + 'shared, no name, jenkins' => array( + ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME, 'BUILD_NUMBER', 'JENKINS ' . $seed, + ), + 'isolated, name, travis' => array( + ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME', 'TRAVIS_BUILD_NUMBER', 'TRAVIS ' . $seed, + ), + 'shared, no name, travis' => array( + ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME, 'TRAVIS_BUILD_NUMBER', 'TRAVIS ' . $seed, + ), 'isolated, name, no build' => array(ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME'), 'shared, no name, no build' => array(ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME), ); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 7540fdf..51cd5c3 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -11,7 +11,11 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Event\TestEvent; +use aik099\PHPUnit\Session\ISessionStrategyFactory; use Mockery as m; +use Symfony\Component\EventDispatcher\EventDispatcher; class SauceLabsBrowserConfigurationTest extends ApiBrowserConfigurationTestCase { @@ -25,6 +29,7 @@ class SauceLabsBrowserConfigurationTest extends ApiBrowserConfigurationTestCase */ protected function setUp() { + $this->testsRequireSubscriber[] = 'testTunnelIdentifier'; $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\SauceLabsBrowserConfiguration'; parent::setUp(); @@ -32,6 +37,60 @@ protected function setUp() $this->setup['host'] = 'UN:AK@ondemand.saucelabs.com'; } + /** + * Test description. + * + * @param string|null $travis_job_number Travis Job Number. + * + * @return void + * @dataProvider tunnelIdentifierDataProvider + */ + public function testTunnelIdentifier($travis_job_number = null) + { + // Reset any global env vars that might be left from previous tests. + putenv('TRAVIS_JOB_NUMBER'); + + if ( isset($travis_job_number) ) { + putenv('TRAVIS_JOB_NUMBER=' . $travis_job_number); + } + + $this->browser->setSessionStrategy(ISessionStrategyFactory::TYPE_ISOLATED); + + $test_case = $this->createTestCase('TEST_NAME'); + $test_case->shouldReceive('toString')->andReturn('TEST_NAME'); + + $event_dispatcher = new EventDispatcher(); + $event_dispatcher->addSubscriber($this->browser); + + $event_dispatcher->dispatch( + BrowserTestCase::TEST_SETUP_EVENT, + new TestEvent($test_case, m::mock('Behat\\Mink\\Session')) + ); + + $desired_capabilities = $this->browser->getDesiredCapabilities(); + + if ( isset($travis_job_number) ) { + $this->assertArrayHasKey('tunnel-identifier', $desired_capabilities); + $this->assertEquals($travis_job_number, $desired_capabilities['tunnel-identifier']); + } + else { + $this->assertArrayNotHasKey('tunnel-identifier', $desired_capabilities); + } + } + + /** + * Provides Travis job numbers. + * + * @return array + */ + public function tunnelIdentifierDataProvider() + { + return array( + array('AAA'), + array(null), + ); + } + /** * Test description. * diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index 0be0416..0b61c5c 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -63,8 +63,14 @@ public function verifyRemoteAPICalls(TestEvent $event) $browser = $this->getBrowser(); if ( $browser instanceof SauceLabsBrowserConfiguration ) { + $session = $event->getSession(); + + if ( $session === null ) { + $this->markTestSkipped('Unable to connect to SauceLabs. Please check Internet connection.'); + } + $sauce_rest = new SauceRest($browser->getApiUsername(), $browser->getApiKey()); - $job_info = $sauce_rest->getJob($event->getSession()->getDriver()->getWebDriverSessionId()); + $job_info = $sauce_rest->getJob($session->getDriver()->getWebDriverSessionId()); $passed_mapping = array( 'testSuccess' => true, From ddc99dc74fab175e8197b4839d8e75f7ab136a68 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 2 Apr 2014 14:12:07 +0300 Subject: [PATCH 040/204] Verify that SauceLabs really uses the job name we provide --- tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index 0b61c5c..92cb98d 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -72,6 +72,8 @@ public function verifyRemoteAPICalls(TestEvent $event) $sauce_rest = new SauceRest($browser->getApiUsername(), $browser->getApiKey()); $job_info = $sauce_rest->getJob($session->getDriver()->getWebDriverSessionId()); + $this->assertEquals(get_class($test_case) . '::' . $test_case->getName(), $job_info['name']); + $passed_mapping = array( 'testSuccess' => true, 'testFailure' => false, From c19f9a63bf7183fd03617ef7ef3441868a187e01 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 2 Apr 2014 14:12:30 +0300 Subject: [PATCH 041/204] Update keywords to increase visibility on Packagist --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 8e34534..38eefb5 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "aik099/phpunit-mink", - "description": "Library for using Mink in PHPUnit tests. Supports test case-wide session sharing.", - "keywords": ["PHPUnit", "Selenium", "Mink", "Tests"], + "description": "Library for using Mink in PHPUnit tests. Supports session sharing between tests in a test case.", + "keywords": ["PHPUnit", "Selenium", "SauceLabs", "Sauce", "BrowserStack", "Mink", "Tests"], "homepage": "http://github.com/aik099/phpunit-mink", "license": "BSD-3-Clause", From 03958be50c4badb3fc42aed1bbb9825af84fcdc4 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 13 Apr 2014 13:10:19 +0300 Subject: [PATCH 042/204] Changes to coding standard --- .../ControlStructureSpacingSniff.php | 195 ++++++++++++------ 1 file changed, 136 insertions(+), 59 deletions(-) diff --git a/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php index b7c5b55..095fd7a 100644 --- a/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ b/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php @@ -95,40 +95,78 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) return; } - if (isset($tokens[$stackPtr]['parenthesis_opener']) === true) { - $parenOpener = $tokens[$stackPtr]['parenthesis_opener']; - $parenCloser = $tokens[$stackPtr]['parenthesis_closer']; - $spaceAfterOpen = 0; - if ($tokens[($parenOpener + 1)]['code'] === T_WHITESPACE) { - $spaceAfterOpen = strlen($tokens[($parenOpener + 1)]['content']); + $this->checkBracketSpacing($phpcsFile, $stackPtr); + $this->checkContentInside($phpcsFile, $stackPtr); + $this->checkLeadingContent($phpcsFile, $stackPtr); + $this->checkTrailingContent($phpcsFile, $stackPtr); + + }//end process() + + + /** + * Checks bracket spacing. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token + * in the stack passed in $tokens. + * + * @return void + */ + protected function checkBracketSpacing(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + if (isset($tokens[$stackPtr]['parenthesis_opener']) === false) { + return; + } + + $parenOpener = $tokens[$stackPtr]['parenthesis_opener']; + $parenCloser = $tokens[$stackPtr]['parenthesis_closer']; + $spaceAfterOpen = 0; + if ($tokens[($parenOpener + 1)]['code'] === T_WHITESPACE) { + $spaceAfterOpen = strlen($tokens[($parenOpener + 1)]['content']); + } + + if ($spaceAfterOpen !== $this->requiredSpacesAfterOpen) { + $error = 'Expected %s spaces after opening bracket; %s found'; + $data = array( + $this->requiredSpacesAfterOpen, + $spaceAfterOpen, + ); + $phpcsFile->addError($error, ($parenOpener + 1), 'SpacingAfterOpenBrace', $data); + } + + if ($tokens[$parenOpener]['line'] === $tokens[$parenCloser]['line']) { + $spaceBeforeClose = 0; + if ($tokens[($parenCloser - 1)]['code'] === T_WHITESPACE) { + $spaceBeforeClose = strlen($tokens[($parenCloser - 1)]['content']); } - if ($spaceAfterOpen !== $this->requiredSpacesAfterOpen) { - $error = 'Expected %s spaces after opening bracket; %s found'; + if ($spaceBeforeClose !== $this->requiredSpacesBeforeClose) { + $error = 'Expected %s spaces before closing bracket; %s found'; $data = array( - $this->requiredSpacesAfterOpen, - $spaceAfterOpen, + $this->requiredSpacesBeforeClose, + $spaceBeforeClose, ); - $phpcsFile->addError($error, ($parenOpener + 1), 'SpacingAfterOpenBrace', $data); + $phpcsFile->addError($error, ($parenCloser - 1), 'SpaceBeforeCloseBrace', $data); } + } - if ($tokens[$parenOpener]['line'] === $tokens[$parenCloser]['line']) { - $spaceBeforeClose = 0; - if ($tokens[($parenCloser - 1)]['code'] === T_WHITESPACE) { - $spaceBeforeClose = strlen($tokens[($parenCloser - 1)]['content']); - } + }//end checkBracketSpacing() - if ($spaceBeforeClose !== $this->requiredSpacesBeforeClose) { - $error = 'Expected %s spaces before closing bracket; %s found'; - $data = array( - $this->requiredSpacesBeforeClose, - $spaceBeforeClose, - ); - $phpcsFile->addError($error, ($parenCloser - 1), 'SpaceBeforeCloseBrace', $data); - } - } - }//end if + /** + * Checks content inside. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token + * in the stack passed in $tokens. + * + * @return void + */ + protected function checkContentInside(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); $scopeOpener = $tokens[$stackPtr]['scope_opener']; $scopeCloser = $tokens[$stackPtr]['scope_closer']; @@ -156,34 +194,79 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) $phpcsFile->addError($error, $scopeCloser, 'SpacingAfterClose'); } - $trailingContent = $phpcsFile->findNext( - T_WHITESPACE, - ($scopeCloser + 1), + }//end checkContentInside() + + + /** + * Checks leading content. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token + * in the stack passed in $tokens. + * + * @return void + */ + protected function checkLeadingContent(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + + $leadingContent = $phpcsFile->findPrevious( + PHP_CodeSniffer_Tokens::$emptyTokens, + ($stackPtr - 1), null, true ); - if ($tokens[$trailingContent]['code'] === T_ELSE) { - if ($tokens[$stackPtr]['code'] === T_IF) { - // IF with ELSE. - return; - } + if ($tokens[$leadingContent]['code'] === T_OPEN_TAG) { + // At the beginning of the script or embedded code. + return; } - if ($tokens[$trailingContent]['code'] === T_COMMENT) { - if ($tokens[$trailingContent]['line'] === $tokens[$scopeCloser]['line']) { - if (substr($tokens[$trailingContent]['content'], 0, 5) === '//end') { - // There is an end comment, so we have to get the next piece - // of content. - $trailingContent = $phpcsFile->findNext( - T_WHITESPACE, - ($trailingContent + 1), - null, - true - ); + if ($tokens[$leadingContent]['code'] === T_OPEN_CURLY_BRACKET) { + // Another control structure's opening brace. + if (isset($tokens[$leadingContent]['scope_condition']) === true) { + $owner = $tokens[$leadingContent]['scope_condition']; + if ($tokens[$owner]['code'] === T_FUNCTION) { + // The previous content is the opening brace of a function + // so normal function rules apply and we can ignore it. + return; } } - } + + if ($tokens[$leadingContent]['line'] !== ($tokens[$stackPtr]['line'] - 1)) { + $error = 'Blank line found before control structure'; + $phpcsFile->addError($error, $stackPtr, 'LineBeforeOpen'); + } + } else if ($tokens[$leadingContent]['code'] !== T_CLOSE_CURLY_BRACKET + && $tokens[$leadingContent]['line'] === ($tokens[$stackPtr]['line'] - 1) + ) { + $error = 'No blank line found before control structure'; + $phpcsFile->addError($error, $stackPtr, 'NoLineBeforeOpen'); + }//end if + + }//end checkLeadingContent() + + + /** + * Checks trailing content. + * + * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the current token + * in the stack passed in $tokens. + * + * @return void + */ + protected function checkTrailingContent(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + $scopeCloser = $tokens[$stackPtr]['scope_closer']; + + $trailingContent = $phpcsFile->findNext( + PHP_CodeSniffer_Tokens::$emptyTokens, + ($scopeCloser + 1), + null, + true + ); // If this token is closing a CASE or DEFAULT, we don't need the // blank line after this control structure. @@ -216,21 +299,15 @@ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) $error = 'Blank line found after control structure'; $phpcsFile->addError($error, $scopeCloser, 'LineAfterClose'); } - } else { - $trailingCode = $tokens[$trailingContent]['code']; - - if ($trailingCode === T_ELSE || $trailingCode === T_ELSEIF || $trailingCode === T_COMMENT) { - // Allow else/elseif/comment to come right after 'if' closing brace. - return; - } - - if ($tokens[$trailingContent]['line'] === ($tokens[$scopeCloser]['line'] + 1)) { - $error = 'No blank line found after control structure'; - $phpcsFile->addError($error, $scopeCloser, 'NoLineAfterClose'); - } + } else if ($tokens[$trailingContent]['code'] !== T_ELSE + && $tokens[$trailingContent]['code'] !== T_ELSEIF + && $tokens[$trailingContent]['line'] === ($tokens[$scopeCloser]['line'] + 1) + ) { + $error = 'No blank line found after control structure'; + $phpcsFile->addError($error, $scopeCloser, 'NoLineAfterClose'); }//end if - }//end process() + }//end checkTrailingContent() }//end class From 354056c55e31253ade4b6187da0d660b4f0ccd41 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Thu, 17 Apr 2014 20:42:44 +0300 Subject: [PATCH 043/204] Switching to centrally stored CodingStandard --- CodingStandard/Sniffs/Array/ArraySniff.php | 133 -------- .../Classes/ClassCreateInstanceSniff.php | 81 ----- .../Sniffs/Classes/ClassDeclarationSniff.php | 187 ---------- .../Classes/PropertyDeclarationSniff.php | 115 ------- .../Commenting/FunctionCommentSniff.php | 319 ------------------ .../Sniffs/Commenting/InlineCommentSniff.php | 272 --------------- .../ControlSignatureSniff.php | 72 ---- .../Sniffs/ControlStructures/ElseIfSniff.php | 80 ----- .../Sniffs/Formatting/ItemAssignmentSniff.php | 130 ------- .../Sniffs/Formatting/SpaceOperatorSniff.php | 86 ----- .../Formatting/SpaceUnaryOperatorSniff.php | 74 ---- .../Functions/FunctionDeclarationSniff.php | 119 ------- .../ValidFunctionNameSniff.php | 202 ----------- .../Strings/ConcatenationSpacingSniff.php | 92 ----- .../ControlStructureSpacingSniff.php | 315 ----------------- CodingStandard/ruleset.xml | 162 --------- composer.json | 1 + 17 files changed, 1 insertion(+), 2439 deletions(-) delete mode 100644 CodingStandard/Sniffs/Array/ArraySniff.php delete mode 100644 CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php delete mode 100644 CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php delete mode 100644 CodingStandard/Sniffs/Classes/PropertyDeclarationSniff.php delete mode 100644 CodingStandard/Sniffs/Commenting/FunctionCommentSniff.php delete mode 100644 CodingStandard/Sniffs/Commenting/InlineCommentSniff.php delete mode 100644 CodingStandard/Sniffs/ControlStructures/ControlSignatureSniff.php delete mode 100644 CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php delete mode 100644 CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php delete mode 100644 CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php delete mode 100644 CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php delete mode 100644 CodingStandard/Sniffs/Functions/FunctionDeclarationSniff.php delete mode 100644 CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php delete mode 100644 CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php delete mode 100644 CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php delete mode 100644 CodingStandard/ruleset.xml diff --git a/CodingStandard/Sniffs/Array/ArraySniff.php b/CodingStandard/Sniffs/Array/ArraySniff.php deleted file mode 100644 index b9257ca..0000000 --- a/CodingStandard/Sniffs/Array/ArraySniff.php +++ /dev/null @@ -1,133 +0,0 @@ - - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -/** - * CodingStandard_Sniffs_Array_ArraySniff. - * - * Checks if the array's are styled in the Drupal way. - * - Comma after the last array element - * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Array_ArraySniff implements PHP_CodeSniffer_Sniff -{ - - - /** - * Returns an array of tokens this test wants to listen for. - * - * @return array - */ - public function register() - { - return array(T_ARRAY); - - }//end register() - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - $this->sniffItemClosings($phpcsFile, $stackPtr, $tokens); - - }//end process() - - - /** - * Checks if the last item in the array is closed with a comma. - * - * If the array is written on one line there must also be a space - * after the comma. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. - * @param array $tokens Tokens. - * - * @return void - */ - protected function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, array $tokens) - { - $arrayStart = $tokens[$stackPtr]['parenthesis_opener']; - $arrayEnd = $tokens[$arrayStart]['parenthesis_closer']; - - if ($arrayStart !== ($stackPtr + 1)) { - $error = 'There must be no space between the Array keyword and the opening parenthesis'; - $phpcsFile->addError($error, $stackPtr, 'SpaceAfterKeyword'); - } - - // Check for empty arrays. - $content = $phpcsFile->findNext(array(T_WHITESPACE), ($arrayStart + 1), ($arrayEnd + 1), true); - if ($content === $arrayEnd) { - // Empty array, but if the brackets aren't together, there's a problem. - if (($arrayEnd - $arrayStart) !== 1) { - $error = 'Empty array declaration must have no space between the parentheses'; - $phpcsFile->addError($error, $stackPtr, 'SpaceInEmptyArray'); - - // We can return here because there is nothing else to check. All code - // below can assume that the array is not empty. - return; - } - } - - $lastItem = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($arrayEnd - 1), $stackPtr, true); - - // Empty array. - if ($lastItem === $arrayStart) { - return; - } - - // Inline array. - $isInlineArray = $tokens[$arrayStart]['line'] === $tokens[$arrayEnd]['line']; - - // Check if the last item in a multiline array has a "closing" comma. - if ($tokens[$lastItem]['code'] !== T_COMMA && $isInlineArray === false) { - $phpcsFile->addWarning('A comma should follow the last multiline array item. Found: '.$tokens[$lastItem]['content'], $lastItem); - return; - } - - if ($isInlineArray === true) { - if ($tokens[$lastItem]['code'] === T_COMMA) { - $phpcsFile->addWarning('Comma not allowed after last value in single-line array declaration', $lastItem); - return; - } - - // Inline array must not have spaces within parenthesis. - if ($content !== ($arrayStart + 1)) { - $error = 'Space found after opening parenthesis of Array'; - $phpcsFile->addError($error, $stackPtr, 'SpaceAfterOpen'); - } - - if ($lastItem !== ($arrayEnd - 1)) { - $error = 'Space found before closing parenthesis of Array'; - $phpcsFile->addError($error, $stackPtr, 'SpaceAfterClose'); - } - } - - }//end sniffItemClosings() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php b/CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php deleted file mode 100644 index 068a5c6..0000000 --- a/CodingStandard/Sniffs/Classes/ClassCreateInstanceSniff.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -/** - * Class create instance Test. - * - * Checks the declaration of the class is correct. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Classes_ClassCreateInstanceSniff implements PHP_CodeSniffer_Sniff -{ - - - /** - * Returns an array of tokens this test wants to listen for. - * - * @return array - */ - public function register() - { - return array(T_NEW); - - }//end register() - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - $nextParenthesis = $phpcsFile->findNext( - array( - T_OPEN_PARENTHESIS, - T_SEMICOLON, - ), - $stackPtr, - null, - false, - null, - true - ); - - if ($tokens[$nextParenthesis]['code'] != T_OPEN_PARENTHESIS || $tokens[$nextParenthesis]['line'] != $tokens[$stackPtr]['line']) { - $error = 'Calling class constructors must always include parentheses'; - $phpcsFile->addError($error, $nextParenthesis); - return; - } - - if ($tokens[($nextParenthesis - 1)]['code'] === T_WHITESPACE) { - $error = 'Between the class name and the opening parenthesis spaces are not welcome'; - $phpcsFile->addError($error, ($nextParenthesis - 1)); - return; - } - - }//end process() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php b/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php deleted file mode 100644 index 70d8bcd..0000000 --- a/CodingStandard/Sniffs/Classes/ClassDeclarationSniff.php +++ /dev/null @@ -1,187 +0,0 @@ - - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -if (class_exists('PSR2_Sniffs_Classes_ClassDeclarationSniff', true) === false) { - $error = 'Class PSR2_Sniffs_Classes_ClassDeclarationSniff not found'; - throw new PHP_CodeSniffer_Exception($error); -} - -/** - * Class Declaration Test. - * - * Checks the declaration of the class and its inheritance is correct. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Greg Sherwood - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @version Release: 1.4.5 - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Classes_ClassDeclarationSniff extends PSR2_Sniffs_Classes_ClassDeclarationSniff -{ - - /** - * Requires each class declaration to be namespaced. - * - * @var bool - */ - public $requireNamespaces = true; - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - // We want all the errors from the PSR2 standard, plus some of our own. - parent::process($phpcsFile, $stackPtr); - - if (basename($phpcsFile->getFilename()) === 'constants.php') { - // Multiple class constant definitions allowed in this particular file. - return; - } - - // Check that this is the only class, interface or trait in the file. - $nextClass = $phpcsFile->findNext(array(T_CLASS, T_INTERFACE, T_TRAIT), ($stackPtr + 1)); - if ($nextClass !== false) { - // We have another, so an error is thrown. - $error = 'Only one class, interface or trait is allowed in a file'; - $phpcsFile->addError($error, $nextClass, 'MultipleClasses'); - } - - if ($this->requireNamespaces === true && version_compare(PHP_VERSION, '5.3.0') >= 0) { - $namespace = $phpcsFile->findPrevious(T_NAMESPACE, ($stackPtr - 1)); - if ($namespace === false) { - $error = 'Each class must be in a namespace of at least one level (a top-level vendor name)'; - $phpcsFile->addError($error, $stackPtr, 'MissingNamespace'); - } - } - - }//end process() - - - /** - * Processes the opening section of a class declaration. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void - */ - public function processOpen(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - parent::processOpen($phpcsFile, $stackPtr); - - $tokens = $phpcsFile->getTokens(); - - if ($tokens[($stackPtr - 1)]['code'] === T_WHITESPACE) { - $prevContent = $tokens[($stackPtr - 1)]['content']; - if ($prevContent !== $phpcsFile->eolChar) { - $blankSpace = substr($prevContent, strpos($prevContent, $phpcsFile->eolChar)); - $spaces = strlen($blankSpace); - - if (in_array($tokens[($stackPtr - 2)]['code'], array(T_ABSTRACT, T_FINAL)) === false) { - if ($spaces !== 0) { - $type = strtolower($tokens[$stackPtr]['content']); - $error = 'Expected 0 spaces before %s keyword; %s found'; - $data = array( - $type, - $spaces, - ); - $phpcsFile->addError($error, $stackPtr, 'SpaceBeforeKeyword', $data); - } - } - } - }//end if - - }//end processOpen() - - - /** - * Processes the closing section of a class declaration. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void - */ - public function processClose(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - $closeBrace = $tokens[$stackPtr]['scope_closer']; - if ($tokens[($closeBrace - 1)]['code'] === T_WHITESPACE) { - $prevContent = $tokens[($closeBrace - 1)]['content']; - if ($prevContent !== $phpcsFile->eolChar) { - $blankSpace = substr($prevContent, strpos($prevContent, $phpcsFile->eolChar)); - $spaces = strlen($blankSpace); - if ($spaces !== 0) { - if ($tokens[($closeBrace - 1)]['line'] !== $tokens[$closeBrace]['line']) { - $error = 'Expected 0 spaces before closing brace; newline found'; - $phpcsFile->addError($error, $closeBrace, 'NewLineBeforeCloseBrace'); - } else { - $error = 'Expected 0 spaces before closing brace; %s found'; - $data = array($spaces); - $phpcsFile->addError($error, $closeBrace, 'SpaceBeforeCloseBrace', $data); - } - } - } - } - - // Check that the closing brace has one blank line after it. - $nextContent = $phpcsFile->findNext(array(T_WHITESPACE, T_COMMENT), ($closeBrace + 1), null, true); - if ($nextContent !== false) { - $nextLine = $tokens[$nextContent]['line']; - $braceLine = $tokens[$closeBrace]['line']; - if ($braceLine === $nextLine) { - $error = 'Closing brace of a %s must be followed by a single blank line'; - $data = array($tokens[$stackPtr]['content']); - $phpcsFile->addError($error, $closeBrace, 'NoNewlineAfterCloseBrace', $data); - } else if ($nextLine !== ($braceLine + 2)) { - $difference = ($nextLine - $braceLine - 1); - $error = 'Closing brace of a %s must be followed by a single blank line; found %s'; - $data = array( - $tokens[$stackPtr]['content'], - $difference, - ); - $phpcsFile->addError($error, $closeBrace, 'NewlinesAfterCloseBrace', $data); - } - }//end if - - // Check the closing brace is on it's own line, but allow - // for comments like "//end class". - $nextContent = $phpcsFile->findNext(T_COMMENT, ($closeBrace + 1), null, true); - if ($tokens[$nextContent]['content'] !== $phpcsFile->eolChar && $tokens[$nextContent]['line'] === $tokens[$closeBrace]['line']) { - $type = strtolower($tokens[$stackPtr]['content']); - $error = 'Closing %s brace must be on a line by itself'; - $data = array($tokens[$stackPtr]['content']); - $phpcsFile->addError($error, $closeBrace, 'CloseBraceSameLine', $data); - } - - }//end processClose() - - -}//end class diff --git a/CodingStandard/Sniffs/Classes/PropertyDeclarationSniff.php b/CodingStandard/Sniffs/Classes/PropertyDeclarationSniff.php deleted file mode 100644 index cb228cf..0000000 --- a/CodingStandard/Sniffs/Classes/PropertyDeclarationSniff.php +++ /dev/null @@ -1,115 +0,0 @@ - - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -if (class_exists('PHP_CodeSniffer_Standards_AbstractVariableSniff', true) === false) { - throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractVariableSniff not found'); -} - -/** - * Verifies that properties are declared correctly. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Greg Sherwood - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @version Release: @package_version@ - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Classes_PropertyDeclarationSniff extends PHP_CodeSniffer_Standards_AbstractVariableSniff -{ - - - /** - * Processes the function tokens within the class. - * - * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. - * @param int $stackPtr The position where the token was found. - * - * @return void - */ - protected function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - // Detect multiple properties defined at the same time. Throw an error - // for this, but also only process the first property in the list so we don't - // repeat errors. - $find = PHP_CodeSniffer_Tokens::$scopeModifiers; - $find = array_merge($find, array(T_VARIABLE, T_VAR, T_SEMICOLON)); - $prev = $phpcsFile->findPrevious($find, ($stackPtr - 1)); - if ($tokens[$prev]['code'] === T_VARIABLE) { - return; - } - - if ($tokens[$prev]['code'] === T_VAR) { - $error = 'The var keyword must not be used to declare a property'; - $phpcsFile->addError($error, $stackPtr, 'VarUsed'); - } - - $next = $phpcsFile->findNext(array(T_VARIABLE, T_SEMICOLON), ($stackPtr + 1)); - if ($tokens[$next]['code'] === T_VARIABLE) { - $error = 'There must not be more than one property declared per statement'; - $phpcsFile->addError($error, $stackPtr, 'Multiple'); - } - - $modifier = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$scopeModifiers, $stackPtr); - if (($modifier === false) || ($tokens[$modifier]['line'] !== $tokens[$stackPtr]['line'])) { - $error = 'Visibility must be declared on property "%s"'; - $data = array($tokens[$stackPtr]['content']); - $phpcsFile->addError($error, $stackPtr, 'ScopeMissing', $data); - } - - if (($modifier !== false) && ($modifier['code'] === T_PRIVATE) && ($tokens[$stackPtr]['content'][1] !== '_')) { - $error = 'Private property name "%s" should be prefixed with an underscore to indicate visibility'; - $data = array($tokens[$stackPtr]['content']); - $phpcsFile->addWarning($error, $stackPtr, 'Underscore', $data); - } - - }//end processMemberVar() - - - /** - * Processes normal variables. - * - * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. - * @param int $stackPtr The position where the token was found. - * - * @return void - */ - protected function processVariable(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - // We don't care about normal variables. - - }//end processVariable() - - - /** - * Processes variables in double quoted strings. - * - * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. - * @param int $stackPtr The position where the token was found. - * - * @return void - */ - protected function processVariableInString(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - // We don't care about normal variables. - - }//end processVariableInString() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/Commenting/FunctionCommentSniff.php b/CodingStandard/Sniffs/Commenting/FunctionCommentSniff.php deleted file mode 100644 index 82a35e6..0000000 --- a/CodingStandard/Sniffs/Commenting/FunctionCommentSniff.php +++ /dev/null @@ -1,319 +0,0 @@ - - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -if (class_exists('Squiz_Sniffs_Commenting_FunctionCommentSniff', true) === false) { - $error = 'Class Squiz_Sniffs_Commenting_FunctionCommentSniff not found'; - throw new PHP_CodeSniffer_Exception($error); -} - -/** - * Parses and verifies the doc comments for functions. - * - * Same as the Squiz standard, but adds support for API tags. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Greg Sherwood - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @version Release: @package_version@ - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Commenting_FunctionCommentSniff extends Squiz_Sniffs_Commenting_FunctionCommentSniff -{ - - /** - * Reflection of parent sniff private property. - * - * @var ReflectionProperty - */ - private $_functionTokenReflection; - - /** - * Reflection of parent sniff private property. - * - * @var ReflectionProperty - */ - private $_classTokenReflection; - - /** - * Reflection of parent sniff private property. - * - * @var ReflectionProperty - */ - private $_methodNameReflection; - - - /** - * Stores class reflection. - */ - public function __construct() - { - $parentClass = 'Squiz_Sniffs_Commenting_FunctionCommentSniff'; - - $this->_functionTokenReflection = new ReflectionProperty($parentClass, '_functionToken'); - $this->_functionTokenReflection->setAccessible(true); - - $this->_classTokenReflection = new ReflectionProperty($parentClass, '_classToken'); - $this->_classTokenReflection->setAccessible(true); - - $this->_methodNameReflection = new ReflectionProperty($parentClass, '_methodName'); - $this->_methodNameReflection->setAccessible(true); - - }//end __construct() - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $this->currentFile = $phpcsFile; - - $tokens = $phpcsFile->getTokens(); - - $find = array( - T_COMMENT, - T_DOC_COMMENT, - T_CLASS, - T_FUNCTION, - T_OPEN_TAG, - ); - - $commentEnd = $phpcsFile->findPrevious($find, ($stackPtr - 1)); - - if ($commentEnd === false) { - return; - } - - // If the token that we found was a class or a function, then this - // function has no doc comment. - $code = $tokens[$commentEnd]['code']; - - if ($code === T_COMMENT) { - // The function might actually be missing a comment, and this last comment - // found is just commenting a bit of code on a line. So if it is not the - // only thing on the line, assume we found nothing. - $prevContent = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $commentEnd); - if ($tokens[$commentEnd]['line'] === $tokens[$commentEnd]['line']) { - $error = 'Missing function doc comment'; - $phpcsFile->addError($error, $stackPtr, 'Missing'); - } else { - $error = 'You must use "/**" style comments for a function comment'; - $phpcsFile->addError($error, $stackPtr, 'WrongStyle'); - } - - return; - } else if ($code !== T_DOC_COMMENT) { - $error = 'Missing function doc comment'; - $phpcsFile->addError($error, $stackPtr, 'Missing'); - return; - } else if (trim($tokens[$commentEnd]['content']) !== '*/') { - $error = 'You must use "*/" to end a function comment; found "%s"'; - $phpcsFile->addError($error, $commentEnd, 'WrongEnd', array(trim($tokens[$commentEnd]['content']))); - return; - }//end if - - // If there is any code between the function keyword and the doc block - // then the doc block is not for us. - $ignore = PHP_CodeSniffer_Tokens::$scopeModifiers; - $ignore[] = T_STATIC; - $ignore[] = T_WHITESPACE; - $ignore[] = T_ABSTRACT; - $ignore[] = T_FINAL; - $prevToken = $phpcsFile->findPrevious($ignore, ($stackPtr - 1), null, true); - if ($prevToken !== $commentEnd) { - $phpcsFile->addError('Missing function doc comment', $stackPtr, 'Missing'); - return; - } - - $this->_functionTokenReflection->setValue($this, $stackPtr); - - $this->_classTokenReflection->setValue($this, null); - foreach ($tokens[$stackPtr]['conditions'] as $condPtr => $condition) { - if ($condition === T_CLASS || $condition === T_INTERFACE) { - $this->_classTokenReflection->setValue($this, $condPtr); - break; - } - } - - // Find the first doc comment. - $commentStart = ($phpcsFile->findPrevious(T_DOC_COMMENT, ($commentEnd - 1), null, true) + 1); - $commentString = $phpcsFile->getTokensAsString($commentStart, ($commentEnd - $commentStart + 1)); - $this->_methodNameReflection->setValue($this, $phpcsFile->getDeclarationName($stackPtr)); - - try { - $this->commentParser = new PHP_CodeSniffer_CommentParser_FunctionCommentParser($commentString, $phpcsFile); - $this->commentParser->parse(); - } catch (PHP_CodeSniffer_CommentParser_ParserException $e) { - $line = ($e->getLineWithinComment() + $commentStart); - $phpcsFile->addError($e->getMessage(), $line, 'FailedParse'); - return; - } - - $comment = $this->commentParser->getComment(); - if (is_null($comment) === true) { - $error = 'Function doc comment is empty'; - $phpcsFile->addError($error, $commentStart, 'Empty'); - return; - } - - // The first line of the comment should just be the /** code. - $eolPos = strpos($commentString, $phpcsFile->eolChar); - $firstLine = substr($commentString, 0, $eolPos); - if ($firstLine !== '/**') { - $error = 'The open comment tag must be the only content on the line'; - $phpcsFile->addError($error, $commentStart, 'ContentAfterOpen'); - } - - $this->processParams($commentStart, $commentEnd); - $this->processSees($commentStart); - $this->processReturn($commentStart, $commentEnd); - $this->processThrows($commentStart); - - // Check for a comment description. - $short = $comment->getShortComment(); - if (trim($short) === '') { - $error = 'Missing short description in function doc comment'; - $phpcsFile->addError($error, $commentStart, 'MissingShort'); - return; - } - - // No extra newline before short description. - $newlineCount = 0; - $newlineSpan = strspn($short, $phpcsFile->eolChar); - if ($short !== '' && $newlineSpan > 0) { - $error = 'Extra newline(s) found before function comment short description'; - $phpcsFile->addError($error, ($commentStart + 1), 'SpacingBeforeShort'); - } - - $newlineCount = (substr_count($short, $phpcsFile->eolChar) + 1); - - // Exactly one blank line between short and long description. - $long = $comment->getLongComment(); - if (empty($long) === false) { - $between = $comment->getWhiteSpaceBetween(); - $newlineBetween = substr_count($between, $phpcsFile->eolChar); - if ($newlineBetween !== 2) { - $error = 'There must be exactly one blank line between descriptions in function comment'; - $phpcsFile->addError($error, ($commentStart + $newlineCount + 1), 'SpacingBetween'); - } - - $newlineCount += $newlineBetween; - - $testLong = trim($long); - if (preg_match('|\p{Lu}|u', $testLong[0]) === 0) { - $error = 'Function comment long description must start with a capital letter'; - $phpcsFile->addError($error, ($commentStart + $newlineCount), 'LongNotCapital'); - } - }//end if - - // Exactly one blank line before tags. - $params = $this->commentParser->getTagOrders(); - if (count($params) > 1) { - $newlineSpan = $comment->getNewlineAfter(); - if ($newlineSpan !== 2) { - $error = 'There must be exactly one blank line before the tags in function comment'; - if ($long !== '') { - $newlineCount += (substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1); - } - - $phpcsFile->addError($error, ($commentStart + $newlineCount), 'SpacingBeforeTags'); - $short = rtrim($short, $phpcsFile->eolChar.' '); - } - } - - // Short description must be single line and end with a full stop. - $testShort = trim($short); - $lastChar = $testShort[(strlen($testShort) - 1)]; - if (substr_count($testShort, $phpcsFile->eolChar) !== 0) { - $error = 'Function comment short description must be on a single line'; - $phpcsFile->addError($error, ($commentStart + 1), 'ShortSingleLine'); - } - - $isEvent = $this->isEvent(); - - if ($isEvent === true && preg_match('/(\p{Lu}|\[)/u', $testShort[0]) === 0) { - $error = 'Event comment short description must start with a capital letter or an ['; - $phpcsFile->addError($error, ($commentStart + 1), 'ShortNotCapital'); - } else if ($isEvent === false && preg_match('/\p{Lu}/u', $testShort[0]) === 0) { - $error = 'Function comment short description must start with a capital letter'; - $phpcsFile->addError($error, ($commentStart + 1), 'ShortNotCapital'); - } - - if ($lastChar !== '.') { - $error = 'Function comment short description must end with a full stop'; - $phpcsFile->addError($error, ($commentStart + 1), 'ShortFullStop'); - } - - // Check for unknown/deprecated tags. - $this->processUnknownTags($commentStart, $commentEnd); - - // The last content should be a newline and the content before - // that should not be blank. If there is more blank space - // then they have additional blank lines at the end of the comment. - $words = $this->commentParser->getWords(); - $lastPos = (count($words) - 1); - if (trim($words[($lastPos - 1)]) !== '' - || strpos($words[($lastPos - 1)], $this->currentFile->eolChar) === false - || trim($words[($lastPos - 2)]) === '' - ) { - $error = 'Additional blank lines found at end of function comment'; - $this->currentFile->addError($error, $commentEnd, 'SpacingAfter'); - } - - }//end process() - - - /** - * Determines if a method is an event in the event handler class. - * - * @return bool - */ - protected function isEvent() - { - if (substr($this->getClassName(), -12) === 'EventHandler') { - return substr($this->_methodNameReflection->getValue($this), 0, 2) == 'On'; - } - - return false; - }//end isEvent() - - - /** - * Returns class name to which current method belongs. - * - * @return string - */ - protected function getClassName() - { - if ($this->_classTokenReflection->getValue($this) !== null) { - return $this->currentFile->getDeclarationName($this->_classTokenReflection->getValue($this)); - } - - return ''; - - }//end getClassName() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/Commenting/InlineCommentSniff.php b/CodingStandard/Sniffs/Commenting/InlineCommentSniff.php deleted file mode 100644 index 4ccbd21..0000000 --- a/CodingStandard/Sniffs/Commenting/InlineCommentSniff.php +++ /dev/null @@ -1,272 +0,0 @@ - - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -/** - * CodingStandard_Sniffs_Commenting_InlineCommentSniff. - * - * Checks that there is adequate spacing between comments. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Greg Sherwood - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @version Release: @package_version@ - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Commenting_InlineCommentSniff implements PHP_CodeSniffer_Sniff -{ - - /** - * A list of tokenizers this sniff supports. - * - * @var array - */ - public $supportedTokenizers = array( - 'PHP', - 'JS', - ); - - /** - * Returns an array of tokens this test wants to listen for. - * - * @return array - */ - public function register() - { - return array( - T_COMMENT, - T_DOC_COMMENT, - ); - - }//end register() - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - // If this is a function/class/interface doc block comment, skip it. - // We are only interested in inline doc block comments, which are - // not allowed. - if ($tokens[$stackPtr]['code'] === T_DOC_COMMENT) { - $nextToken = $phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, - ($stackPtr + 1), - null, - true - ); - - $ignore = array( - T_CLASS, - T_INTERFACE, - T_TRAIT, - T_FUNCTION, - T_PUBLIC, - T_PRIVATE, - T_PROTECTED, - T_FINAL, - T_STATIC, - T_ABSTRACT, - T_CONST, - T_OBJECT, - T_PROPERTY, - ); - - if (in_array($tokens[$nextToken]['code'], $ignore) === true) { - return; - } else { - if ($phpcsFile->tokenizerType === 'JS') { - // We allow block comments if a function is being assigned - // to a variable. - $ignore = PHP_CodeSniffer_Tokens::$emptyTokens; - $ignore[] = T_EQUAL; - $ignore[] = T_STRING; - $ignore[] = T_OBJECT_OPERATOR; - $nextToken = $phpcsFile->findNext($ignore, ($nextToken + 1), null, true); - if ($tokens[$nextToken]['code'] === T_FUNCTION) { - return; - } - } - - $prevToken = $phpcsFile->findPrevious( - PHP_CodeSniffer_Tokens::$emptyTokens, - ($stackPtr - 1), - null, - true - ); - - if ($tokens[$prevToken]['code'] === T_OPEN_TAG) { - return; - } - - // Only error once per comment. -// if (substr($tokens[$stackPtr]['content'], 0, 3) === '/**') { -// $error = 'Inline doc block comments are not allowed; use "/* Comment */" or "// Comment" instead'; -// $phpcsFile->addError($error, $stackPtr, 'DocBlock'); -// } - }//end if - }//end if - - if ($tokens[$stackPtr]['content']{0} === '#') { - $error = 'Perl-style comments are not allowed; use "// Comment" instead'; - $phpcsFile->addError($error, $stackPtr, 'WrongStyle'); - } - - // We don't want end of block comments. If the last comment is a closing - // curly brace. - $previousContent = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); - if ($tokens[$previousContent]['line'] === $tokens[$stackPtr]['line']) { - if ($tokens[$previousContent]['code'] === T_CLOSE_CURLY_BRACKET) { - return; - } - - // Special case for JS files. - if ($tokens[$previousContent]['code'] === T_COMMA - || $tokens[$previousContent]['code'] === T_SEMICOLON - ) { - $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, ($previousContent - 1), null, true); - if ($tokens[$lastContent]['code'] === T_CLOSE_CURLY_BRACKET) { - return; - } - } - } - - $comment = rtrim($tokens[$stackPtr]['content']); - - // Only want inline comments. - if (substr($comment, 0, 2) !== '//') { - return; - } - - $spaceCount = 0; - for ($i = 2; $i < strlen($comment); $i++) { - if ($comment[$i] !== ' ') { - break; - } - - $spaceCount++; - } - - if ($spaceCount === 0) { - $error = 'No space before comment text; expected "// %s" but found "%s"'; - $data = array( - substr($comment, 2), - $comment, - ); - $phpcsFile->addError($error, $stackPtr, 'NoSpaceBefore', $data); - } - - if ($spaceCount > 1) { - $error = '%s spaces found before inline comment line; use block comment if you need indentation'; - $data = array( - $spaceCount, - substr($comment, (2 + $spaceCount)), - $comment, - ); - $phpcsFile->addError($error, $stackPtr, 'SpacingBefore', $data); - } - - - // The below section determines if a comment block is correctly capitalised, - // and ends in a full-stop. It will find the last comment in a block, and - // work its way up. - $nextComment = $phpcsFile->findNext(array(T_COMMENT), ($stackPtr + 1), null, false); - - if (($nextComment !== false) && (($tokens[$nextComment]['line']) === ($tokens[$stackPtr]['line'] + 1))) { - return; - } - - $topComment = $stackPtr; - $lastComment = $stackPtr; - while (($topComment = $phpcsFile->findPrevious(array(T_COMMENT), ($lastComment - 1), null, false)) !== false) { - if ($tokens[$topComment]['line'] !== ($tokens[$lastComment]['line'] - 1)) { - break; - } - - $lastComment = $topComment; - } - - $topComment = $lastComment; - $commentText = ''; - - for ($i = $topComment; $i <= $stackPtr; $i++) { - if ($tokens[$i]['code'] === T_COMMENT) { - $commentText .= trim(substr($tokens[$i]['content'], 2)); - } - } - - if ($commentText === '') { - $error = 'Blank comments are not allowed'; - $phpcsFile->addError($error, $stackPtr, 'Empty'); - return; - } - - if (preg_match('/(\p{Lu}|\d)/u', $commentText[0]) === 0) { - $error = 'Inline comments must start with a capital letter or digit'; - $phpcsFile->addError($error, $topComment, 'NotCapital'); - } - - $commentCloser = $commentText[(strlen($commentText) - 1)]; - $acceptedClosers = array( - 'full-stops' => '.', - 'exclamation marks' => '!', - 'or question marks' => '?', - ); - - if (in_array($commentCloser, $acceptedClosers) === false) { - $error = 'Inline comments must end in %s'; - $ender = ''; - foreach ($acceptedClosers as $closerName => $symbol) { - $ender .= ' '.$closerName.','; - } - - $ender = rtrim($ender, ','); - $data = array($ender); - $phpcsFile->addError($error, $stackPtr, 'InvalidEndChar', $data); - } - - // Finally, the line below the last comment cannot be empty. - $start = false; - for ($i = ($stackPtr + 1); $i < $phpcsFile->numTokens; $i++) { - if ($tokens[$i]['line'] === ($tokens[$stackPtr]['line'] + 1)) { - if ($tokens[$i]['code'] !== T_WHITESPACE) { - return; - } - } else if ($tokens[$i]['line'] > ($tokens[$stackPtr]['line'] + 1)) { - break; - } - } - - $error = 'There must be no blank line following an inline comment'; - $phpcsFile->addError($error, $stackPtr, 'SpacingAfter'); - - }//end process() - - -}//end class - - -?> diff --git a/CodingStandard/Sniffs/ControlStructures/ControlSignatureSniff.php b/CodingStandard/Sniffs/ControlStructures/ControlSignatureSniff.php deleted file mode 100644 index 1057b89..0000000 --- a/CodingStandard/Sniffs/ControlStructures/ControlSignatureSniff.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @author Marc McIntyre - * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) - * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence - * @version CVS: $Id: ControlSignatureSniff.php,v 1.7 2007/10/23 06:05:14 squiz Exp $ - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -if (class_exists('PHP_CodeSniffer_Standards_AbstractPatternSniff', true) === false) { - throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractPatternSniff not found'); -} - -/** - * Verifies that control statements conform to their coding standards. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Greg Sherwood - * @author Marc McIntyre - * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) - * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence - * @version Release: 1.2.0RC3 - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_ControlStructures_ControlSignatureSniff extends PHP_CodeSniffer_Standards_AbstractPatternSniff -{ - - - /** - * Constructs a PEAR_Sniffs_ControlStructures_ControlSignatureSniff. - */ - public function __construct() - { - parent::__construct(true); - - }//end __construct() - - - /** - * Returns the patterns that this test wishes to verify. - * - * @return array(string) - */ - protected function getPatterns() - { - return array( - 'do {EOL...} while (...);EOL', - 'while (...) {EOL', - 'switch (...) {EOL', - 'for (...) {EOL', - 'if (...) {EOL', - 'foreach (...) {EOL', - //'} else if (...) {EOL', - '}EOLelseif (...) {EOL', - '}EOLelse {EOL', - 'do {EOL', - ); - - }//end getPatterns() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php b/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php deleted file mode 100644 index 54a0c64..0000000 --- a/CodingStandard/Sniffs/ControlStructures/ElseIfSniff.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @author Marc McIntyre - * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) - * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence - * @version CVS: $Id: ElseIfSniff.php,v 1.7 2007/10/23 06:05:14 squiz Exp $ - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -if (class_exists('PHP_CodeSniffer_Standards_AbstractPatternSniff', true) === false) { - throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractPatternSniff not found'); -} - -/** - * Verifies that control statements conform to their coding standards. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Greg Sherwood - * @author Marc McIntyre - * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) - * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence - * @version Release: 1.2.0RC3 - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_ControlStructures_ElseIfSniff implements PHP_CodeSniffer_Sniff -{ - - - /** - * Returns an array of tokens this test wants to listen for. - * - * @return array - */ - public function register() - { - return array(T_ELSE); - - }//end register() - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - $nextNonWhiteSpace = $phpcsFile->findNext( - T_WHITESPACE, - ($stackPtr + 1), - null, - true, - null, - true - ); - - if ($tokens[$nextNonWhiteSpace]['code'] === T_IF) { - $phpcsFile->addError('Use "elseif" in place of "else if"', $nextNonWhiteSpace); - } - - }//end process() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php b/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php deleted file mode 100644 index 188ef7d..0000000 --- a/CodingStandard/Sniffs/Formatting/ItemAssignmentSniff.php +++ /dev/null @@ -1,130 +0,0 @@ - - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -/** - * CodingStandard_Sniffs_Formatting_ItemAssignmentSniff. - * - * Checks if the item assignment operator (=>) has - * - a space before and after - * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Formatting_ItemAssignmentSniff implements PHP_CodeSniffer_Sniff -{ - - - /** - * Returns an array of tokens this test wants to listen for. - * - * @return array - */ - public function register() - { - return array(T_DOUBLE_ARROW); - - }//end register() - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - $this->sniffElementItemAssignmentOperator($phpcsFile, $stackPtr, $tokens); - - }//end process() - - - /** - * Checks if there are spaces before and after the Assignment operators in the array - * Enter description here ... - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. - * @param array $tokens Tokens. - * - * @return void - */ - protected function sniffElementItemAssignmentOperator(PHP_CodeSniffer_File $phpcsFile, $stackPtr, array $tokens) - { - if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE) { - $phpcsFile->addError('A whitespace must prefix the item assignment operator =>', $stackPtr); - } - - if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE) { - $phpcsFile->addError('A whitespace must follow to the item assignment operator =>', $stackPtr); - } - - }//end sniffElementItemAssignmentOperator() - - - /** - * Checks if the last item in the array is closed with a comma - * If the array is written on one line there must also be a space - * after the comma - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. - * @param array $tokens Tokens. - * - * @return void - */ - protected function sniffItemClosings(PHP_CodeSniffer_File $phpcsFile, $stackPtr, array $tokens) - { - $lastItem = $phpcsFile->findPrevious( - array(T_WHITESPACE), - ($tokens[$stackPtr]['parenthesis_closer'] - 1), - $stackPtr, - true - ); - - // Empty array. - if ($lastItem === $tokens[$stackPtr]['parenthesis_opener']) { - return; - } - - // Check if the last item in the array has a "closing" comma. - if ($tokens[$lastItem]['code'] !== T_COMMA) { - $phpcsFile->addWarning('A comma followed by a whitespace should follow the last array item. Found: ' . $tokens[$lastItem]['content'], $lastItem); - - return; - } - - // If the closing parenthesis is on the - // same line as the last item there has to be a whitespace - // after the comma. - if ($tokens[$lastItem]['line'] === $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line'] - && $tokens[($lastItem + 1)]['code'] !== T_WHITESPACE - ) { - $phpcsFile->addWarning('After the last comma in an array must be a whitespace', $lastItem); - - return; - } - - }//end sniffItemClosings() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php b/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php deleted file mode 100644 index cc17450..0000000 --- a/CodingStandard/Sniffs/Formatting/SpaceOperatorSniff.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -/** - * CodingStandard_Sniffs_Formatting_SpaceOperatorSniff. - * - * Ensures there is a single space after a operator - * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @version Release: 1.2.2 - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Formatting_SpaceOperatorSniff implements PHP_CodeSniffer_Sniff -{ - - - /** - * Returns an array of tokens this test wants to listen for. - * - * @return array - */ - public function register() - { - $tokens = array_merge( - PHP_CodeSniffer_Tokens::$assignmentTokens, - PHP_CodeSniffer_Tokens::$equalityTokens, - PHP_CodeSniffer_Tokens::$comparisonTokens - ); - - return $tokens; - - }//end register() - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in - * the stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - $operator = $tokens[$stackPtr]['content']; - - if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE || $tokens[($stackPtr - 1)]['content'] !== ' ') { - $found = strlen($tokens[($stackPtr - 1)]['content']); - $error = 'Expected 1 space before "%s"; %s found'; - $data = array( - $operator, - $found, - ); - $phpcsFile->addError($error, $stackPtr, 'SpacingBefore', $data); - } - - // is handled by "Squiz.WhiteSpace.OperatorSpacing" - /*if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE || $tokens[($stackPtr + 1)]['content'] != ' ') { - $found = strlen($tokens[($stackPtr + 1)]['content']); - $error = 'Expected 1 space after "%s"; %s found'; - $data = array( - $operator, - $found, - ); - $phpcsFile->addError($error, $stackPtr, 'SpacingAfter', $data); - }*/ - - }//end process() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php b/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php deleted file mode 100644 index b52bbff..0000000 --- a/CodingStandard/Sniffs/Formatting/SpaceUnaryOperatorSniff.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -/** - * CodingStandard_Sniffs_Formatting_SpaceUnaryOperatorSniff. - * - * Ensures there are no spaces on increment / decrement statements. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @version Release: 1.2.2 - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Formatting_SpaceUnaryOperatorSniff implements PHP_CodeSniffer_Sniff -{ - - - /** - * Returns an array of tokens this test wants to listen for. - * - * @return array - */ - public function register() - { - return array( - T_DEC, - T_INC, - ); - - }//end register() - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in - * the stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - $modifyLeft = substr($tokens[($stackPtr - 1)]['content'], 0, 1) === '$' || - $tokens[($stackPtr + 1)]['content'] === ';'; - - if ($modifyLeft === true && $tokens[($stackPtr - 1)]['code'] === T_WHITESPACE) { - $error = 'There must not be a single space before an unary operator statement'; - $phpcsFile->addError($error, $stackPtr); - } - - if ($modifyLeft === false && substr($tokens[($stackPtr + 1)]['content'], 0, 1) !== '$') { - $error = 'A unary operator statement must not followed by a single space'; - $phpcsFile->addError($error, $stackPtr); - } - - }//end process() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/Functions/FunctionDeclarationSniff.php b/CodingStandard/Sniffs/Functions/FunctionDeclarationSniff.php deleted file mode 100644 index 785a692..0000000 --- a/CodingStandard/Sniffs/Functions/FunctionDeclarationSniff.php +++ /dev/null @@ -1,119 +0,0 @@ - - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -if (class_exists('PEAR_Sniffs_Functions_FunctionDeclarationSniff', true) === false) { - $error = 'Class PEAR_Sniffs_Functions_FunctionDeclarationSniff not found'; - throw new PHP_CodeSniffer_Exception($error); -} - -/** - * CodingStandard_Sniffs_Functions_FunctionDeclarationSniff. - * - * Ensure single and multi-line function declarations are defined correctly. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Greg Sherwood - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @version Release: @package_version@ - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Functions_FunctionDeclarationSniff extends PEAR_Sniffs_Functions_FunctionDeclarationSniff -{ - - /** - * The number of spaces code should be indented. - * - * @var int - */ - public $indent = 1; - - - /** - * Processes mutli-line declarations. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * @param array $tokens The stack of tokens that make up - * the file. - * - * @return void - */ - public function processMultiLineDeclaration(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $tokens) - { - // We need to work out how far indented the function - // declaration itself is, so we can work out how far to - // indent parameters. - $functionIndent = 0; - for ($i = ($stackPtr - 1); $i >= 0; $i--) { - if ($tokens[$i]['line'] !== $tokens[$stackPtr]['line']) { - $i++; - break; - } - } - - if ($tokens[$i]['code'] === T_WHITESPACE) { - $functionIndent = strlen($tokens[$i]['content']); - } - - // The closing parenthesis must be on a new line, even - // when checking abstract function definitions. - $closeBracket = $tokens[$stackPtr]['parenthesis_closer']; - $prev = $phpcsFile->findPrevious( - T_WHITESPACE, - ($closeBracket - 1), - null, - true - ); - - if ($tokens[$closeBracket]['line'] !== $tokens[$tokens[$closeBracket]['parenthesis_opener']]['line']) { - if ($tokens[$prev]['line'] === $tokens[$closeBracket]['line']) { - $error = 'The closing parenthesis of a multi-line function declaration must be on a new line'; - $phpcsFile->addError($error, $closeBracket, 'CloseBracketLine'); - } - } - - // If this is a closure and is using a USE statement, the closing - // parenthesis we need to look at from now on is the closing parenthesis - // of the USE statement. - if ($tokens[$stackPtr]['code'] === T_CLOSURE) { - $use = $phpcsFile->findNext(T_USE, ($closeBracket + 1), $tokens[$stackPtr]['scope_opener']); - if ($use !== false) { - $open = $phpcsFile->findNext(T_OPEN_PARENTHESIS, ($use + 1)); - $closeBracket = $tokens[$open]['parenthesis_closer']; - - $prev = $phpcsFile->findPrevious( - T_WHITESPACE, - ($closeBracket - 1), - null, - true - ); - - if ($tokens[$closeBracket]['line'] !== $tokens[$tokens[$closeBracket]['parenthesis_opener']]['line']) { - if ($tokens[$prev]['line'] === $tokens[$closeBracket]['line']) { - $error = 'The closing parenthesis of a multi-line use declaration must be on a new line'; - $phpcsFile->addError($error, $closeBracket, 'CloseBracketLine'); - } - } - }//end if - }//end if - - }//end processMultiLineDeclaration() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php b/CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php deleted file mode 100644 index 063f6ac..0000000 --- a/CodingStandard/Sniffs/NamingConventions/ValidFunctionNameSniff.php +++ /dev/null @@ -1,202 +0,0 @@ - - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -if (class_exists('PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff', true) === false) { - throw new PHP_CodeSniffer_Exception('Class PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff not found'); -} - -/** - * CodingStandard_Sniffs_NamingConventions_ValidFunctionNameSniff. - * - * Ensures method names are correct depending on whether they are public - * or private, and that functions are named correctly. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Greg Sherwood - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @version Release: @package_version@ - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_NamingConventions_ValidFunctionNameSniff extends PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff -{ - - protected $eventHandlerExclusions = array( - 'SetCustomQuery', - 'CheckPermission', - 'LoadItem', - 'ListPrepareQuery', - 'ItemPrepareQuery', - 'SetPagination', - 'SetSorting', - ); - - protected $tagProcessorExclusions = array('PrepareListElementParams'); - - - /** - * Processes the tokens within the scope. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being processed. - * @param int $stackPtr The position where this token was - * found. - * @param int $currScope The position of the current scope. - * - * @return void - */ - protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope) - { - $methodName = $phpcsFile->getDeclarationName($stackPtr); - if ($methodName === null) { - // Ignore closures. - return; - } - - $className = $phpcsFile->getDeclarationName($currScope); - $errorData = array($className.'::'.$methodName); - - // Is this a magic method. i.e., is prefixed with "__" ? - if (preg_match('|^__|', $methodName) !== 0) { - $magicPart = strtolower(substr($methodName, 2)); - if (in_array($magicPart, $this->magicMethods) === false) { - $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore'; - $phpcsFile->addError($error, $stackPtr, 'MethodDoubleUnderscore', $errorData); - } - - return; - } - - // PHP4 constructors are allowed to break our rules. - if ($methodName === $className) { - return; - } - - // PHP4 destructors are allowed to break our rules. - if ($methodName === '_'.$className) { - return; - } - - $methodProps = $phpcsFile->getMethodProperties($stackPtr); - $isPublic = ($methodProps['scope'] === 'private') ? false : true; - $scope = $methodProps['scope']; - $scopeSpecified = $methodProps['scope_specified']; - - // If it's a private method, it must have an underscore on the front. - if ($isPublic === false && $methodName{0} !== '_') { - $error = 'Private method name "%s" must be prefixed with an underscore'; - $phpcsFile->addError($error, $stackPtr, 'PrivateNoUnderscore', $errorData); - return; - } - - // If it's not a private method, it must not have an underscore on the front. - if ($isPublic === true && $scopeSpecified === true && $methodName{0} === '_') { - $error = '%s method name "%s" must not be prefixed with an underscore'; - $data = array( - ucfirst($scope), - $errorData[0], - ); - $phpcsFile->addError($error, $stackPtr, 'PublicUnderscore', $data); - return; - } - - // If the scope was specified on the method, then the method must be - // camel caps and an underscore should be checked for. If it wasn't - // specified, treat it like a public method and remove the underscore - // prefix if there is one because we cant determine if it is private or - // public. - $testMethodName = $methodName; - if ($scopeSpecified === false && $methodName{0} === '_') { - $testMethodName = substr($methodName, 1); - } - - $methodParams = $phpcsFile->getMethodParameters($stackPtr); - - if ( - $this->isEventHandlerExclusion($className, $methodName, $methodParams) || - $this->isTagProcessorExclusion($className, $methodName, $methodParams) - ) { - return; - } - - if (PHP_CodeSniffer::isCamelCaps($testMethodName, false, $isPublic, false) === false) { - if ($scopeSpecified === true) { - $error = '%s method name "%s" is not in camel caps format'; - $data = array( - ucfirst($scope), - $errorData[0], - ); - $phpcsFile->addError($error, $stackPtr, 'ScopeNotCamelCaps', $data); - } else { - $error = 'Method name "%s" is not in camel caps format'; - $phpcsFile->addError($error, $stackPtr, 'NotCamelCaps', $errorData); - } - - return; - } - - }//end processTokenWithinScope() - - - /** - * Determines if a method is an event in the event handler class. - * - * @param string $className Class name. - * @param string $methodName Method name. - * @param array $methodParams Method parameters. - * - * @return bool - */ - protected function isEventHandlerExclusion($className, $methodName, array $methodParams) - { - if (substr($className, -12) !== 'EventHandler') { - // Not EventHandler class. - return false; - } - - $isEvent = substr($methodName, 0, 2) == 'On' && count($methodParams) === 1 && $methodParams[0]['name'] === '$event'; - - return in_array($methodName, $this->eventHandlerExclusions) || $isEvent === true; - - }//end isEventHandlerExclusion() - - - /** - * Determines if a method is an tag in the tag processor class. - * - * @param string $className Class name. - * @param string $methodName Method name. - * @param array $methodParams Method parameters. - * - * @return bool - */ - protected function isTagProcessorExclusion($className, $methodName, array $methodParams) - { - if (substr($className, -12) !== 'TagProcessor') { - // Not TagProcessor class. - return false; - } - - $isTag = count($methodParams) === 1 && $methodParams[0]['name'] === '$params'; - - return in_array($methodName, $this->tagProcessorExclusions) || $isTag === true; - - }//end isTagProcessorExclusion() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php b/CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php deleted file mode 100644 index b636a6f..0000000 --- a/CodingStandard/Sniffs/Strings/ConcatenationSpacingSniff.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -/** - * CodingStandard_Sniffs_Strings_ConcatenationSpacingSniff. - * - * Makes sure there are the needed spaces between the concatenation operator (.) and - * the strings being concatenated. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Peter Philipp - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_Strings_ConcatenationSpacingSniff implements PHP_CodeSniffer_Sniff -{ - - - /** - * Returns an array of tokens this test wants to listen for. - * - * @return array - */ - public function register() - { - return array(T_STRING_CONCAT); - - }//end register() - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token in the - * stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - $found = ''; - $expected = ''; - $error = false; - - if ($tokens[($stackPtr - 1)]['code'] !== T_WHITESPACE) { - $expected .= '...'.substr($tokens[($stackPtr - 2)]['content'], -5).$tokens[$stackPtr]['content']; - $found .= '...'.substr($tokens[($stackPtr - 2)]['content'], -5).$tokens[($stackPtr - 1)]['content'].$tokens[$stackPtr]['content']; - $error = true; - } else { - $found .= '...'.substr($tokens[($stackPtr - 1)]['content'], -5).$tokens[$stackPtr]['content']; - $expected .= '...'.substr($tokens[($stackPtr - 1)]['content'], -5).$tokens[$stackPtr]['content']; - } - - if ($tokens[($stackPtr + 1)]['code'] !== T_WHITESPACE) { - $expected .= substr($tokens[($stackPtr + 2)]['content'], 0, 5).'...'; - $found .= $tokens[($stackPtr + 1)]['content'].substr($tokens[($stackPtr + 2)]['content'], 0, 5).'...'; - $error = true; - } else { - $found .= $tokens[($stackPtr + 1)]['content']; - $expected .= $tokens[($stackPtr + 1)]['content']; - } - - if ($error === true) { - $found = str_replace("\r\n", '\n', $found); - $found = str_replace("\n", '\n', $found); - $found = str_replace("\r", '\n', $found); - $expected = str_replace("\r\n", '\n', $expected); - $expected = str_replace("\n", '\n', $expected); - $expected = str_replace("\r", '\n', $expected); - - $message = "Concat operator must be surrounded by spaces. Found \"$found\"; expected \"$expected\""; - $phpcsFile->addError($message, $stackPtr); - } - - }//end process() - - -}//end class - -?> diff --git a/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php b/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php deleted file mode 100644 index 095fd7a..0000000 --- a/CodingStandard/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php +++ /dev/null @@ -1,315 +0,0 @@ - - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -/** - * CodingStandard_Sniffs_WhiteSpace_ControlStructureSpacingSniff. - * - * Checks that control structures have the correct spacing around brackets. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Greg Sherwood - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @version Release: @package_version@ - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -class CodingStandard_Sniffs_WhiteSpace_ControlStructureSpacingSniff implements PHP_CodeSniffer_Sniff -{ - - /** - * A list of tokenizers this sniff supports. - * - * @var array - */ - public $supportedTokenizers = array( - 'PHP', - 'JS', - ); - - /** - * How many spaces should follow the opening bracket. - * - * @var int - */ - public $requiredSpacesAfterOpen = 1; - - /** - * How many spaces should precede the closing bracket. - * - * @var int - */ - public $requiredSpacesBeforeClose = 1; - - - /** - * Returns an array of tokens this test wants to listen for. - * - * @return array - */ - public function register() - { - return array( - T_IF, - T_WHILE, - T_FOREACH, - T_FOR, - T_SWITCH, - T_DO, - T_ELSE, - T_ELSEIF, - ); - - }//end register() - - - /** - * Processes this test, when one of its tokens is encountered. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void - */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $this->requiredSpacesAfterOpen = (int) $this->requiredSpacesAfterOpen; - $this->requiredSpacesBeforeClose = (int) $this->requiredSpacesBeforeClose; - $tokens = $phpcsFile->getTokens(); - - if (isset($tokens[$stackPtr]['scope_closer']) === false) { - return; - } - - $this->checkBracketSpacing($phpcsFile, $stackPtr); - $this->checkContentInside($phpcsFile, $stackPtr); - $this->checkLeadingContent($phpcsFile, $stackPtr); - $this->checkTrailingContent($phpcsFile, $stackPtr); - - }//end process() - - - /** - * Checks bracket spacing. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void - */ - protected function checkBracketSpacing(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - if (isset($tokens[$stackPtr]['parenthesis_opener']) === false) { - return; - } - - $parenOpener = $tokens[$stackPtr]['parenthesis_opener']; - $parenCloser = $tokens[$stackPtr]['parenthesis_closer']; - $spaceAfterOpen = 0; - if ($tokens[($parenOpener + 1)]['code'] === T_WHITESPACE) { - $spaceAfterOpen = strlen($tokens[($parenOpener + 1)]['content']); - } - - if ($spaceAfterOpen !== $this->requiredSpacesAfterOpen) { - $error = 'Expected %s spaces after opening bracket; %s found'; - $data = array( - $this->requiredSpacesAfterOpen, - $spaceAfterOpen, - ); - $phpcsFile->addError($error, ($parenOpener + 1), 'SpacingAfterOpenBrace', $data); - } - - if ($tokens[$parenOpener]['line'] === $tokens[$parenCloser]['line']) { - $spaceBeforeClose = 0; - if ($tokens[($parenCloser - 1)]['code'] === T_WHITESPACE) { - $spaceBeforeClose = strlen($tokens[($parenCloser - 1)]['content']); - } - - if ($spaceBeforeClose !== $this->requiredSpacesBeforeClose) { - $error = 'Expected %s spaces before closing bracket; %s found'; - $data = array( - $this->requiredSpacesBeforeClose, - $spaceBeforeClose, - ); - $phpcsFile->addError($error, ($parenCloser - 1), 'SpaceBeforeCloseBrace', $data); - } - } - - }//end checkBracketSpacing() - - - /** - * Checks content inside. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void - */ - protected function checkContentInside(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - $scopeOpener = $tokens[$stackPtr]['scope_opener']; - $scopeCloser = $tokens[$stackPtr]['scope_closer']; - - $firstContent = $phpcsFile->findNext( - T_WHITESPACE, - ($scopeOpener + 1), - null, - true - ); - - if ($tokens[$firstContent]['line'] !== ($tokens[$scopeOpener]['line'] + 1)) { - $error = 'Blank line found at start of control structure'; - $phpcsFile->addError($error, $scopeOpener, 'SpacingBeforeOpen'); - } - - $lastContent = $phpcsFile->findPrevious( - T_WHITESPACE, - ($scopeCloser - 1), - null, - true - ); - - if ($tokens[$lastContent]['line'] !== ($tokens[$scopeCloser]['line'] - 1)) { - $error = 'Blank line found at end of control structure'; - $phpcsFile->addError($error, $scopeCloser, 'SpacingAfterClose'); - } - - }//end checkContentInside() - - - /** - * Checks leading content. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void - */ - protected function checkLeadingContent(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - - $leadingContent = $phpcsFile->findPrevious( - PHP_CodeSniffer_Tokens::$emptyTokens, - ($stackPtr - 1), - null, - true - ); - - if ($tokens[$leadingContent]['code'] === T_OPEN_TAG) { - // At the beginning of the script or embedded code. - return; - } - - if ($tokens[$leadingContent]['code'] === T_OPEN_CURLY_BRACKET) { - // Another control structure's opening brace. - if (isset($tokens[$leadingContent]['scope_condition']) === true) { - $owner = $tokens[$leadingContent]['scope_condition']; - if ($tokens[$owner]['code'] === T_FUNCTION) { - // The previous content is the opening brace of a function - // so normal function rules apply and we can ignore it. - return; - } - } - - if ($tokens[$leadingContent]['line'] !== ($tokens[$stackPtr]['line'] - 1)) { - $error = 'Blank line found before control structure'; - $phpcsFile->addError($error, $stackPtr, 'LineBeforeOpen'); - } - } else if ($tokens[$leadingContent]['code'] !== T_CLOSE_CURLY_BRACKET - && $tokens[$leadingContent]['line'] === ($tokens[$stackPtr]['line'] - 1) - ) { - $error = 'No blank line found before control structure'; - $phpcsFile->addError($error, $stackPtr, 'NoLineBeforeOpen'); - }//end if - - }//end checkLeadingContent() - - - /** - * Checks trailing content. - * - * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. - * @param int $stackPtr The position of the current token - * in the stack passed in $tokens. - * - * @return void - */ - protected function checkTrailingContent(PHP_CodeSniffer_File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - $scopeCloser = $tokens[$stackPtr]['scope_closer']; - - $trailingContent = $phpcsFile->findNext( - PHP_CodeSniffer_Tokens::$emptyTokens, - ($scopeCloser + 1), - null, - true - ); - - // If this token is closing a CASE or DEFAULT, we don't need the - // blank line after this control structure. - if (isset($tokens[$trailingContent]['scope_condition']) === true) { - $condition = $tokens[$trailingContent]['scope_condition']; - if ($tokens[$condition]['code'] === T_CASE - || $tokens[$condition]['code'] === T_DEFAULT - ) { - return; - } - } - - if ($tokens[$trailingContent]['code'] === T_CLOSE_TAG) { - // At the end of the script or embedded code. - return; - } - - if ($tokens[$trailingContent]['code'] === T_CLOSE_CURLY_BRACKET) { - // Another control structure's closing brace. - if (isset($tokens[$trailingContent]['scope_condition']) === true) { - $owner = $tokens[$trailingContent]['scope_condition']; - if ($tokens[$owner]['code'] === T_FUNCTION) { - // The next content is the closing brace of a function - // so normal function rules apply and we can ignore it. - return; - } - } - - if ($tokens[$trailingContent]['line'] !== ($tokens[$scopeCloser]['line'] + 1)) { - $error = 'Blank line found after control structure'; - $phpcsFile->addError($error, $scopeCloser, 'LineAfterClose'); - } - } else if ($tokens[$trailingContent]['code'] !== T_ELSE - && $tokens[$trailingContent]['code'] !== T_ELSEIF - && $tokens[$trailingContent]['line'] === ($tokens[$scopeCloser]['line'] + 1) - ) { - $error = 'No blank line found after control structure'; - $phpcsFile->addError($error, $scopeCloser, 'NoLineAfterClose'); - }//end if - - }//end checkTrailingContent() - - -}//end class - -?> diff --git a/CodingStandard/ruleset.xml b/CodingStandard/ruleset.xml deleted file mode 100644 index bfb6eff..0000000 --- a/CodingStandard/ruleset.xml +++ /dev/null @@ -1,162 +0,0 @@ - - - Alexander Obuhovich's coding standard. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - **/*_config.php - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/composer.json b/composer.json index 38eefb5..abfcb5d 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ }, "require-dev": { + "aik099/coding-standard": "dev-master", "mockery/mockery": "0.9.0" }, From a8a2470e4e4988195f5a7e7c2ea83ecbfaf60f46 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 10 May 2014 21:28:54 +0300 Subject: [PATCH 044/204] Simplifying test suite bootstrap by using "autoload-dev" for tests --- composer.json | 6 ++++ .../RemoteCoverage/RemoteCoverageTool.php | 3 +- phpunit.xml.dist | 13 +++++---- tests/bootstrap.php | 28 ------------------- 4 files changed, 16 insertions(+), 34 deletions(-) delete mode 100644 tests/bootstrap.php diff --git a/composer.json b/composer.json index abfcb5d..cddb242 100644 --- a/composer.json +++ b/composer.json @@ -32,6 +32,12 @@ } }, + "autoload-dev": { + "psr-0": { + "tests\\aik099\\": "./" + } + }, + "extra": { "branch-alias": { "dev-master": "1.1.x-dev" diff --git a/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php index 1aad083..d980745 100644 --- a/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php +++ b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php @@ -11,8 +11,9 @@ namespace aik099\PHPUnit\RemoteCoverage; +/* Include file from PEAR. require_once 'File/Iterator/Autoload.php'; -require_once 'PHP/CodeCoverage/Autoload.php'; +require_once 'PHP/CodeCoverage/Autoload.php';*/ class RemoteCoverageTool { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d589bc6..2da3c06 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ --> - + + + + diff --git a/tests/bootstrap.php b/tests/bootstrap.php deleted file mode 100644 index e8c1003..0000000 --- a/tests/bootstrap.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -define('FULL_PATH', realpath(__DIR__ . '/..')); - -// TODO: until https://github.com/padraic/mockery/issues/160 is fixed. -ini_set('xdebug.scream', 0); - -$vendor_path = FULL_PATH . '/vendor'; - -if ( !is_dir($vendor_path) ) { - echo 'Install dependencies first' . PHP_EOL; - exit(1); -} - -require_once ($vendor_path . '/autoload.php'); - -$auto_loader = new \Composer\Autoload\ClassLoader(); -$auto_loader->add('aik099\\', FULL_PATH . '/library/'); -$auto_loader->add('tests\\aik099\\', FULL_PATH . '/'); -$auto_loader->register(); From 5f16a72a6e7b1f3bf384e4a25fecf6941903c209 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 20 May 2014 13:16:19 +0300 Subject: [PATCH 045/204] Use latest stable Mockery version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index cddb242..bf680d1 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "require-dev": { "aik099/coding-standard": "dev-master", - "mockery/mockery": "0.9.0" + "mockery/mockery": "~0.9" }, "autoload": { From 101e83519eb932fe086e3887ef8b8d29c884ced6 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 20 May 2014 14:25:03 +0300 Subject: [PATCH 046/204] Don't let Scrutinizer connection issues result in 20 minute long builds --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7524523..0994eb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,5 +22,5 @@ script: after_script: - php vendor/bin/coveralls -v - - wget https://scrutinizer-ci.com/ocular.phar + - wget https://scrutinizer-ci.com/ocular.phar -t 3 - php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml From 3c0b85359b7b9fa65f9478a1e3d2702b6f45aeed Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Fri, 27 Jun 2014 12:04:05 +0300 Subject: [PATCH 047/204] Coding standard fixes --- .../PHPUnit/APIClient/BrowserStackAPIClient.php | 14 +++++++------- library/aik099/PHPUnit/Application.php | 6 +++--- .../PHPUnit/Session/SessionStrategyManager.php | 2 +- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 2 +- .../PHPUnit/Integration/EventDispatchingTest.php | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php index 47e5ed5..e6237c7 100644 --- a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php @@ -69,25 +69,25 @@ public function updateStatus($session_id, $test_status) /** * Execute BrowserStack REST API command. * - * @param string $requestMethod HTTP request method. - * @param string $url URL. - * @param mixed $parameters Parameters. + * @param string $request_method HTTP request method. + * @param string $url URL. + * @param mixed $parameters Parameters. * * @return mixed * @see http://www.browserstack.com/automate/rest-api */ - protected function execute($requestMethod, $url, $parameters = null) + protected function execute($request_method, $url, $parameters = null) { - $extraOptions = array( + $extra_options = array( CURLOPT_HTTPAUTH => CURLAUTH_BASIC, CURLOPT_USERPWD => $this->_apiUsername . ':' . $this->_apiKey, ); $url = 'https://www.browserstack.com/automate/' . $url; - list($rawResults, $info) = $this->_curlService->execute($requestMethod, $url, $parameters, $extraOptions); + list($raw_results, $info) = $this->_curlService->execute($request_method, $url, $parameters, $extra_options); - return json_decode($rawResults, true); + return json_decode($raw_results, true); } } diff --git a/library/aik099/PHPUnit/Application.php b/library/aik099/PHPUnit/Application.php index aef3a99..90e0db0 100644 --- a/library/aik099/PHPUnit/Application.php +++ b/library/aik099/PHPUnit/Application.php @@ -75,13 +75,13 @@ public function getTestSuiteFactory() /** * Returns object from the container. * - * @param string $serviceId Name of the object in the container. + * @param string $service_id Name of the object in the container. * * @return \stdClass */ - public function getObject($serviceId) + public function getObject($service_id) { - return $this->container[$serviceId]; + return $this->container[$service_id]; } /** diff --git a/library/aik099/PHPUnit/Session/SessionStrategyManager.php b/library/aik099/PHPUnit/Session/SessionStrategyManager.php index 375b373..e412149 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyManager.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyManager.php @@ -84,7 +84,7 @@ public function getDefaultSessionStrategy() */ public function getSessionStrategy(BrowserConfiguration $browser) { - /** + /* * This logic creates separate strategy for: * - each browser configuration in BrowserTestCase::$browsers (for isolated strategy) * - each browser configuration in BrowserTestCase::$browsers for each test case class (for shared strategy) diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index 92cb98d..ab58b80 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -28,7 +28,7 @@ class ApiIntegrationFixture extends BrowserTestCase */ public static $browsers = array( array('alias' => 'saucelabs'), -// array('alias' => 'browserstack'), + // array('alias' => 'browserstack'), ); /** diff --git a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php index 6681e3c..b55869e 100644 --- a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php +++ b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php @@ -24,7 +24,7 @@ class EventDispatchingTest extends \PHPUnit_Framework_TestCase */ public function testSetupEvent() { - /** + /* * BrowserTestCase::TEST_SETUP_EVENT * - SauceLabsBrowserConfiguration::onTestSetup (called, verified) * From af950341a95360d6e622a25a680f73954c408877 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Fri, 27 Jun 2014 12:04:24 +0300 Subject: [PATCH 048/204] Changing Pimple dependency to stable version --- composer.json | 2 +- library/aik099/PHPUnit/DIContainer.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index bf680d1..15bee98 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "behat/mink": "~1.5@dev", "behat/mink-selenium2-driver": "~1.1@dev", "symfony/event-dispatcher": "~2.4", - "pimple/pimple": "~2.0@dev", + "pimple/pimple": "~2.0", "phpunit/phpunit": ">=3.7.8" }, diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index b0ff045..e5b30f1 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -25,9 +25,10 @@ use aik099\PHPUnit\TestSuite\BrowserTestSuite; use aik099\PHPUnit\TestSuite\RegularTestSuite; use aik099\PHPUnit\TestSuite\TestSuiteFactory; +use Pimple\Container; use Symfony\Component\EventDispatcher\EventDispatcher; -class DIContainer extends \Pimple implements IApplicationAware +class DIContainer extends Container implements IApplicationAware { /** From a9d57b05ce225a4a39b0fc85c3a4cd4a17e668de Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Fri, 27 Jun 2014 12:16:08 +0300 Subject: [PATCH 049/204] Fixing "shouldReceive" method definition --- library/aik099/PHPUnit/Application.php | 2 +- .../PHPUnit/BrowserConfiguration/BrowserConfiguration.php | 2 +- .../BrowserConfiguration/BrowserConfigurationFactory.php | 2 +- .../BrowserConfiguration/IBrowserConfigurationFactory.php | 2 +- library/aik099/PHPUnit/BrowserTestCase.php | 2 +- library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php | 2 +- library/aik099/PHPUnit/RemoteCoverage/RemoteUrl.php | 2 +- library/aik099/PHPUnit/Session/ISessionFactory.php | 2 +- library/aik099/PHPUnit/Session/ISessionStrategy.php | 2 +- library/aik099/PHPUnit/Session/ISessionStrategyFactory.php | 2 +- library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php | 2 +- library/aik099/PHPUnit/Session/SessionFactory.php | 2 +- library/aik099/PHPUnit/Session/SessionStrategyFactory.php | 2 +- library/aik099/PHPUnit/Session/SessionStrategyManager.php | 2 +- library/aik099/PHPUnit/Session/SharedSessionStrategy.php | 2 +- library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php | 2 +- library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/library/aik099/PHPUnit/Application.php b/library/aik099/PHPUnit/Application.php index 90e0db0..e76a435 100644 --- a/library/aik099/PHPUnit/Application.php +++ b/library/aik099/PHPUnit/Application.php @@ -16,7 +16,7 @@ /** * Main application class. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class Application { diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 8be95f6..76355dd 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -22,7 +22,7 @@ /** * Browser configuration for browser. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class BrowserConfiguration implements EventSubscriberInterface { diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php index dbc3dc9..4b17c6f 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php @@ -21,7 +21,7 @@ /** * Browser configuration factory. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class BrowserConfigurationFactory implements IBrowserConfigurationFactory { diff --git a/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php index 0a65a41..699af6a 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php @@ -17,7 +17,7 @@ /** * Interface for browser factory creation. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ interface IBrowserConfigurationFactory { diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index df6608d..dd85e09 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -28,7 +28,7 @@ /** * Test Case class for writing browser-based tests. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ abstract class BrowserTestCase extends \PHPUnit_Framework_TestCase implements IEventDispatcherAware { diff --git a/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php index 508d434..5a26325 100644 --- a/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php +++ b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelper.php @@ -14,7 +14,7 @@ /** * Class collects remove code coverage information and maps patch from remote to local server. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class RemoteCoverageHelper { diff --git a/library/aik099/PHPUnit/RemoteCoverage/RemoteUrl.php b/library/aik099/PHPUnit/RemoteCoverage/RemoteUrl.php index b54020c..34a2350 100644 --- a/library/aik099/PHPUnit/RemoteCoverage/RemoteUrl.php +++ b/library/aik099/PHPUnit/RemoteCoverage/RemoteUrl.php @@ -14,7 +14,7 @@ /** * Class makes request to remote server and returns url. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class RemoteUrl { diff --git a/library/aik099/PHPUnit/Session/ISessionFactory.php b/library/aik099/PHPUnit/Session/ISessionFactory.php index 74ed084..1f9fd8a 100644 --- a/library/aik099/PHPUnit/Session/ISessionFactory.php +++ b/library/aik099/PHPUnit/Session/ISessionFactory.php @@ -17,7 +17,7 @@ /** * Specifies how to create Session objects for running tests. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ interface ISessionFactory { diff --git a/library/aik099/PHPUnit/Session/ISessionStrategy.php b/library/aik099/PHPUnit/Session/ISessionStrategy.php index e27aef3..8d1864b 100644 --- a/library/aik099/PHPUnit/Session/ISessionStrategy.php +++ b/library/aik099/PHPUnit/Session/ISessionStrategy.php @@ -19,7 +19,7 @@ /** * Specifies how to create Session objects for running tests. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ interface ISessionStrategy extends EventSubscriberInterface, IEventDispatcherAware { diff --git a/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php b/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php index fd44eee..b3fb4cf 100644 --- a/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php +++ b/library/aik099/PHPUnit/Session/ISessionStrategyFactory.php @@ -14,7 +14,7 @@ /** * Specifies how to create Session objects for running tests. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ interface ISessionStrategyFactory { diff --git a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php index 7757dba..f6d2c8c 100644 --- a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php @@ -20,7 +20,7 @@ /** * Produces a new Session object shared for each test. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class IsolatedSessionStrategy implements ISessionStrategy { diff --git a/library/aik099/PHPUnit/Session/SessionFactory.php b/library/aik099/PHPUnit/Session/SessionFactory.php index 0dc5bfe..dde2135 100644 --- a/library/aik099/PHPUnit/Session/SessionFactory.php +++ b/library/aik099/PHPUnit/Session/SessionFactory.php @@ -19,7 +19,7 @@ /** * Produces sessions. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class SessionFactory implements ISessionFactory { diff --git a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php index 53f1335..b94ff55 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php @@ -17,7 +17,7 @@ /** * Produces sessions. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class SessionStrategyFactory implements ISessionStrategyFactory, IApplicationAware { diff --git a/library/aik099/PHPUnit/Session/SessionStrategyManager.php b/library/aik099/PHPUnit/Session/SessionStrategyManager.php index e412149..7b7c9fa 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyManager.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyManager.php @@ -16,7 +16,7 @@ /** * Manages session strategies used across browser tests. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class SessionStrategyManager { diff --git a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php index ca7a5ce..cc4ebdb 100644 --- a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -21,7 +21,7 @@ /** * Keeps a Session object shared between test runs to save time. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class SharedSessionStrategy implements ISessionStrategy { diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index ee6f6b6..9609d26 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -22,7 +22,7 @@ /** * Base Test Suite class for browser tests. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ abstract class AbstractTestSuite extends \PHPUnit_Framework_TestSuite implements IEventDispatcherAware { diff --git a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php index 5fce75a..8335114 100644 --- a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php +++ b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php @@ -20,7 +20,7 @@ /** * Creates test suites based on test case class configuration. * - * @method \Mockery\Expectation shouldReceive + * @method \Mockery\Expectation shouldReceive(string $name) */ class TestSuiteFactory implements IApplicationAware { From 056f0a7226197b33c6bf6c546c56a43f64a98cf9 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Fri, 27 Jun 2014 12:33:32 +0300 Subject: [PATCH 050/204] Removing useless "->andReturnNull()" calls --- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 18 +++++++++--------- .../PHPUnit/Integration/SuiteBuildingTest.php | 14 +++++++------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 2218e33..ea57179 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -229,8 +229,8 @@ public function testGetSessionDriverError() protected function getBrowser($times) { $browser = m::mock(self::BROWSER_CLASS); - $browser->shouldReceive('getHost')->times($times)->andReturnNull(); - $browser->shouldReceive('getPort')->times($times)->andReturnNull(); + $browser->shouldReceive('getHost')->times($times); + $browser->shouldReceive('getPort')->times($times); $browser->shouldReceive('attachToTestCase')->once()->andReturn($browser); return $browser; @@ -311,9 +311,9 @@ public function testRunWithCoverageWithoutRemoteUrl() $browser->shouldReceive('getBaseUrl')->once()->andReturn('A'); $session = m::mock('\\Behat\\Mink\\Session'); - $session->shouldReceive('visit')->with('A')->once()->andReturnNull(); - $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, null)->once()->andReturnNull(); - $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, m::not(''))->once()->andReturnNull(); + $session->shouldReceive('visit')->with('A')->once(); + $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, null)->once(); + $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, m::not(''))->once(); $session_strategy->shouldReceive('session')->once()->andReturn($session); @@ -345,7 +345,7 @@ public function testRunWithCoverage() $test_case->setRemoteCoverageScriptUrl('some-url'); $code_coverage = m::mock('\\PHP_CodeCoverage'); - $code_coverage->shouldReceive('append')->with($expected_coverage, $test_case)->once()->andReturnNull(); + $code_coverage->shouldReceive('append')->with($expected_coverage, $test_case)->once(); $result = $this->getTestResult($test_case, 1, true); $result->shouldReceive('getCodeCoverage')->once()->andReturn($code_coverage); @@ -357,9 +357,9 @@ public function testRunWithCoverage() $browser->shouldReceive('getBaseUrl')->once()->andReturn('A'); $session = m::mock('\\Behat\\Mink\\Session'); - $session->shouldReceive('visit')->with('A')->once()->andReturnNull(); - $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, null)->once()->andReturnNull(); - $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, m::not(''))->once()->andReturnNull(); + $session->shouldReceive('visit')->with('A')->once(); + $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, null)->once(); + $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, m::not(''))->once(); $session_strategy->shouldReceive('session')->once()->andReturn($session); diff --git a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php index bd58f08..2b344dd 100644 --- a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php @@ -79,9 +79,9 @@ public function testSuiteTearDown() $suite->addTest($sub_test_suite); $result = m::mock('\\PHPUnit_Framework_TestResult'); - $result->shouldReceive('startTestSuite')->andReturnNull(); + $result->shouldReceive('startTestSuite'); $result->shouldReceive('shouldStop')->andReturn(false); - $result->shouldReceive('endTestSuite')->andReturnNull(); + $result->shouldReceive('endTestSuite'); $this->assertSame($result, $suite->run($result)); } @@ -98,12 +98,12 @@ protected function createTestSuite($class_name) $suite = m::mock($class_name); $suite->shouldReceive('getGroups')->once()->andReturn(array()); - $suite->shouldReceive('setBackupGlobals')->andReturnNull(); - $suite->shouldReceive('setBackupStaticAttributes')->andReturnNull(); - $suite->shouldReceive('setRunTestInSeparateProcess')->andReturnNull(); + $suite->shouldReceive('setBackupGlobals'); + $suite->shouldReceive('setBackupStaticAttributes'); + $suite->shouldReceive('setRunTestInSeparateProcess'); - $suite->shouldReceive('run')->once()->andReturnNull(); - $suite->shouldReceive('onTestSuiteEnded')->once()->andReturnNull(); + $suite->shouldReceive('run')->once(); + $suite->shouldReceive('onTestSuiteEnded')->once(); if ( version_compare(\PHPUnit_Runner_Version::id(), '4.0.0', '>=') ) { $suite->shouldReceive('count')->once()->andReturn(1); From ed009d53b6822ac1f9b6678eaa8b537dd1610ca8 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Fri, 27 Jun 2014 12:39:32 +0300 Subject: [PATCH 051/204] Browser config parameter reformatting --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6ac26a9..1d9d351 100644 --- a/README.md +++ b/README.md @@ -240,13 +240,15 @@ By default the `baseUrl` setting from browser configuration is used as the `remo ## Browser Configuration in Details Each browser configuration consists of the following settings: -* `host` - host, where Selenium Server is located (defaults to `localhost`) -* `port` - port, on which Selenium Server is listening for incoming connections (defaults to `4444`) -* `timeout` - connection timeout of the server in seconds (defaults to `60`) -* `browserName` - name of browser to use (e.g. `firefox`, `chrome`, etc., defaults to `firefox`) -* `desiredCapabilities` - parameters, that specify additional browser configuration (e.g. browser version, platform, etc.) -* `baseUrl` - base url of website, that is tested -* `sauce` - Sauce Labs connection configuration (e.g. `array('username' => 'username_here', 'api_key' => 'api_key_here')`) +| Name | Description | +|---|---| +| `host` | host, where Selenium Server is located (defaults to `localhost`) | +| `port` | port, on which Selenium Server is listening for incoming connections (defaults to `4444`) | +| `timeout` | connection timeout of the server in seconds (defaults to `60`) | +| `browserName` | name of browser to use (e.g. `firefox`, `chrome`, etc., defaults to `firefox`) | +| `desiredCapabilities` | parameters, that specify additional browser configuration (e.g. browser version, platform, etc.) | +| `baseUrl` | base url of website, that is tested | +| `sauce` | Sauce Labs connection configuration (e.g. `array('username' => 'username_here', 'api_key' => 'api_key_here')`) | There are also corresponding `set` and `get` methods for each of mentioned above settings, that allow to individually change them before test has started (from `setUp` method). From d77a4498a0cee0bb00ec99ad29b0b3aabcbaba79 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 28 Jun 2014 14:11:10 +0300 Subject: [PATCH 052/204] Fixing PhpAnalyzer findings --- library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php | 2 +- library/aik099/PHPUnit/Application.php | 6 +++--- .../PHPUnit/BrowserConfiguration/BrowserConfiguration.php | 2 +- library/aik099/PHPUnit/DIContainer.php | 6 +++--- tests/aik099/PHPUnit/ApplicationTest.php | 2 +- .../BrowserConfiguration/BrowserConfigurationTest.php | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php index e6237c7..5ec84fa 100644 --- a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php @@ -85,7 +85,7 @@ protected function execute($request_method, $url, $parameters = null) $url = 'https://www.browserstack.com/automate/' . $url; - list($raw_results, $info) = $this->_curlService->execute($request_method, $url, $parameters, $extra_options); + list($raw_results, ) = $this->_curlService->execute($request_method, $url, $parameters, $extra_options); return json_decode($raw_results, true); } diff --git a/library/aik099/PHPUnit/Application.php b/library/aik099/PHPUnit/Application.php index e76a435..52c2ea2 100644 --- a/library/aik099/PHPUnit/Application.php +++ b/library/aik099/PHPUnit/Application.php @@ -87,9 +87,9 @@ public function getObject($service_id) /** * Replaces object in the container. * - * @param string $service_id Name of the object in the container. - * @param mixed $callable The callable that will return the object. - * @param boolean $is_factory The callable should be considered as a factory. + * @param string $service_id Name of the object in the container. + * @param callable $callable The callable that will return the object. + * @param boolean $is_factory The callable should be considered as a factory. * * @return callable Previous service version. * @throws \InvalidArgumentException When attempt is made to replace non-existing service. diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 76355dd..3fdd2f1 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -452,7 +452,7 @@ public function isShared() /** * Returns session strategy hash based on given test case and current browser configuration. * - * @return integer + * @return string */ public function getSessionStrategyHash() { diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index e5b30f1..694779e 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -54,11 +54,11 @@ public function __construct(array $values = array()) { parent::__construct($values); - $this['event_dispatcher'] = function ($c) { + $this['event_dispatcher'] = function () { return new EventDispatcher(); }; - $this['session_factory'] = function ($c) { + $this['session_factory'] = function () { return new SessionFactory(); }; @@ -87,7 +87,7 @@ public function __construct(array $values = array()) return $session_strategy; }); - $this['remote_url'] = function ($c) { + $this['remote_url'] = function () { return new RemoteUrl(); }; diff --git a/tests/aik099/PHPUnit/ApplicationTest.php b/tests/aik099/PHPUnit/ApplicationTest.php index ba44ca1..63b9660 100644 --- a/tests/aik099/PHPUnit/ApplicationTest.php +++ b/tests/aik099/PHPUnit/ApplicationTest.php @@ -74,7 +74,7 @@ public function testGetObject() public function testReplaceObjectSuccess() { $object = new \stdClass(); - $this->_application->replaceObject('application', function ($c) use ($object) { + $this->_application->replaceObject('application', function () use ($object) { return $object; }); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 350f22c..9bba090 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -424,7 +424,7 @@ public function testGetSessionStrategyHashNotSharing() $browser2 = $this->createBrowserConfiguration(array(), true); $browser2->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED)->attachToTestCase($test_case2); - $this->assertNotSame($browser1->getSessionStrategyHash($test_case1), $browser2->getSessionStrategyHash($test_case2)); + $this->assertNotSame($browser1->getSessionStrategyHash(), $browser2->getSessionStrategyHash()); } /** From c8c362f12873c13ca54e8816d2ae724c12063108 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 6 Jul 2014 13:45:03 +0300 Subject: [PATCH 053/204] Adding HHVM to Travis and to badge list --- .travis.yml | 1 + README.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0994eb9..eedafad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ php: - 5.3 - 5.4 - 5.5 + - hhvm env: global: diff --git a/README.md b/README.md index 1d9d351..a4baa99 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # PHPUnit-Mink [![Build Status](https://travis-ci.org/aik099/phpunit-mink.png?branch=master)](https://travis-ci.org/aik099/phpunit-mink) +[![HHVM Status](http://hhvm.h4cc.de/badge/aik099/phpunit-mink.png)](http://hhvm.h4cc.de/package/aik099/phpunit-mink) + [![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/aik099/phpunit-mink/badges/quality-score.png?s=57e408500d59e10ce44b604df678ec8b59a1b8f8)](https://scrutinizer-ci.com/g/aik099/phpunit-mink/) [![Coverage Status](https://coveralls.io/repos/aik099/phpunit-mink/badge.png?branch=master)](https://coveralls.io/r/aik099/phpunit-mink?branch=master) [![Dependency Status](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049/badge.png)](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049) From 0578d5f245aa21f2db5cbb7232b5e7b6c2f4c5d1 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 6 Jul 2014 14:11:06 +0300 Subject: [PATCH 054/204] Clear ENV vars instead of removing on HHVM --- .../BrowserConfiguration/ApiBrowserConfigurationTestCase.php | 5 +++-- .../SauceLabsBrowserConfigurationTest.php | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 588769d..94a6563 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -161,8 +161,9 @@ abstract public function desiredCapabilitiesDataProvider(); public function testTestSetupEvent($session_strategy, $test_name, $build_env_name = null, $build_number = null) { // Reset any global env vars that might be left from previous tests. - putenv('BUILD_NUMBER'); - putenv('TRAVIS_BUILD_NUMBER'); + $hhvm_hack = defined('HHVM_VERSION') ? '=' : ''; + putenv('BUILD_NUMBER' . $hhvm_hack); + putenv('TRAVIS_BUILD_NUMBER' . $hhvm_hack); if ( isset($build_number) ) { putenv($build_env_name . '=' . $build_number); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 51cd5c3..771f131 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -48,7 +48,8 @@ protected function setUp() public function testTunnelIdentifier($travis_job_number = null) { // Reset any global env vars that might be left from previous tests. - putenv('TRAVIS_JOB_NUMBER'); + $hhvm_hack = defined('HHVM_VERSION') ? '=' : ''; + putenv('TRAVIS_JOB_NUMBER' . $hhvm_hack); if ( isset($travis_job_number) ) { putenv('TRAVIS_JOB_NUMBER=' . $travis_job_number); From c7da1ce589c530601f420835f40eeffe5b6ecabf Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 9 Aug 2014 13:29:59 +0300 Subject: [PATCH 055/204] Adding `composer.lock` --- .gitignore | 1 - composer.lock | 1265 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1265 insertions(+), 1 deletion(-) create mode 100644 composer.lock diff --git a/.gitignore b/.gitignore index 592e632..adcef07 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ vendor composer.phar -composer.lock phpunit.xml build diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..55d6bc2 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1265 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "547eead4779920ff7fe59e1f87c8d3dc", + "packages": [ + { + "name": "behat/mink", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/Behat/Mink.git", + "reference": "b887dadf216cc780c95536e6bdbb50011b638e88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Mink/zipball/b887dadf216cc780c95536e6bdbb50011b638e88", + "reference": "b887dadf216cc780c95536e6bdbb50011b638e88", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/css-selector": "~2.0" + }, + "suggest": { + "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)", + "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation", + "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)", + "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Mink": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Web acceptance testing framework for PHP 5.3", + "homepage": "http://mink.behat.org/", + "keywords": [ + "browser", + "testing", + "web" + ], + "time": "2014-07-13 10:06:32" + }, + { + "name": "behat/mink-selenium2-driver", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/Behat/MinkSelenium2Driver.git", + "reference": "fef36e8cc6793d072deb9645935c800a58923b92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/MinkSelenium2Driver/zipball/fef36e8cc6793d072deb9645935c800a58923b92", + "reference": "fef36e8cc6793d072deb9645935c800a58923b92", + "shasum": "" + }, + "require": { + "behat/mink": "~1.6@dev", + "instaclick/php-webdriver": "~1.1", + "php": ">=5.3.1" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Mink\\Driver": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Pete Otaqui", + "email": "pete@otaqui.com", + "homepage": "https://github.com/pete-otaqui" + } + ], + "description": "Selenium2 (WebDriver) driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "ajax", + "browser", + "javascript", + "selenium", + "testing", + "webdriver" + ], + "time": "2014-07-13 09:59:06" + }, + { + "name": "instaclick/php-webdriver", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/instaclick/php-webdriver.git", + "reference": "3cf130283b054b50119f887e11b9b5a648d785a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/3cf130283b054b50119f887e11b9b5a648d785a9", + "reference": "3cf130283b054b50119f887e11b9b5a648d785a9", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.2" + }, + "require-dev": { + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "WebDriver": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Justin Bishop", + "email": "jubishop@gmail.com", + "role": "Developer" + }, + { + "name": "Anthon Pang", + "email": "apang@softwaredevelopment.ca", + "role": "Fork Maintainer" + } + ], + "description": "PHP WebDriver for Selenium 2", + "homepage": "http://instaclick.com/", + "keywords": [ + "browser", + "selenium", + "webdriver", + "webtest" + ], + "time": "2014-05-08 04:19:19" + }, + { + "name": "ocramius/instantiator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/Instantiator.git", + "reference": "cc754c2289ffd4483c319f6ed6ee88ce21676f64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/Instantiator/zipball/cc754c2289ffd4483c319f6ed6ee88ce21676f64", + "reference": "cc754c2289ffd4483c319f6ed6ee88ce21676f64", + "shasum": "" + }, + "require": { + "ocramius/lazy-map": "1.0.*", + "php": "~5.3" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "2.0.*@ALPHA" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Instantiator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/", + "role": "Developer" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/Ocramius/Instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2014-06-15 11:44:46" + }, + { + "name": "ocramius/lazy-map", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/LazyMap.git", + "reference": "7fe3d347f5e618bcea7d39345ff83f3651d8b752" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/LazyMap/zipball/7fe3d347f5e618bcea7d39345ff83f3651d8b752", + "reference": "7fe3d347f5e618bcea7d39345ff83f3651d8b752", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "athletic/athletic": "~0.1.6", + "phpmd/phpmd": "1.5.*", + "phpunit/phpunit": ">=3.7", + "satooshi/php-coveralls": "~0.6", + "squizlabs/php_codesniffer": "1.4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "LazyMap\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/", + "role": "Developer" + } + ], + "description": "A library that provides lazy instantiation logic for a map of objects", + "homepage": "https://github.com/Ocramius/LazyMap", + "keywords": [ + "lazy", + "lazy instantiation", + "lazy loading", + "map", + "service location" + ], + "time": "2013-11-09 22:30:54" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.0.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "6d196af48e8c100a3ae881940123e693da5a9217" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6d196af48e8c100a3ae881940123e693da5a9217", + "reference": "6d196af48e8c100a3ae881940123e693da5a9217", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3.1", + "phpunit/php-text-template": "~1.2.0", + "phpunit/php-token-stream": "~1.2.2", + "sebastian/environment": "~1.0.0", + "sebastian/version": "~1.0.3" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4.0.14" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2014-08-06 06:39:42" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "File/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2013-10-10 15:34:57" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2014-01-30 17:20:04" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2013-08-02 07:42:54" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32", + "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2014-03-03 05:10:30" + }, + { + "name": "phpunit/phpunit", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "58db726aa45fe26bca93f692cb3d77e9a46b7830" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/58db726aa45fe26bca93f692cb3d77e9a46b7830", + "reference": "58db726aa45fe26bca93f692cb3d77e9a46b7830", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpunit/php-code-coverage": "~2.0", + "phpunit/php-file-iterator": "~1.3.1", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0.2", + "phpunit/phpunit-mock-objects": "~2.2", + "sebastian/comparator": "~1.0", + "sebastian/diff": "~1.1", + "sebastian/environment": "~1.0", + "sebastian/exporter": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2014-08-08 05:13:30" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "42e589e08bc86e3e9bdf20d385e948347788505b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/42e589e08bc86e3e9bdf20d385e948347788505b", + "reference": "42e589e08bc86e3e9bdf20d385e948347788505b", + "shasum": "" + }, + "require": { + "ocramius/instantiator": "~1.0", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "4.2.*@dev" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2014-08-02 13:50:58" + }, + { + "name": "pimple/pimple", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/fabpot/Pimple.git", + "reference": "ea22fb2880faf7b7b0e17c9809c6fe25b071fd76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fabpot/Pimple/zipball/ea22fb2880faf7b7b0e17c9809c6fe25b071fd76", + "reference": "ea22fb2880faf7b7b0e17c9809c6fe25b071fd76", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", + "homepage": "http://pimple.sensiolabs.org", + "keywords": [ + "container", + "dependency injection" + ], + "time": "2014-07-24 07:10:08" + }, + { + "name": "sebastian/comparator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", + "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.1", + "sebastian/exporter": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2014-05-02 07:05:58" + }, + { + "name": "sebastian/diff", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", + "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2013-08-03 16:46:33" + }, + { + "name": "sebastian/environment", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/79517609ec01139cd7e9fded0dd7ce08c952ef6a", + "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "4.0.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2014-02-18 16:17:19" + }, + { + "name": "sebastian/exporter", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", + "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "4.0.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2014-02-16 08:26:31" + }, + { + "name": "sebastian/version", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2014-03-07 15:35:33" + }, + { + "name": "symfony/css-selector", + "version": "v2.5.3", + "target-dir": "Symfony/Component/CssSelector", + "source": { + "type": "git", + "url": "https://github.com/symfony/CssSelector.git", + "reference": "e24b8215bf39a6a2ce0c262bc5b000724077afa9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/CssSelector/zipball/e24b8215bf39a6a2ce0c262bc5b000724077afa9", + "reference": "e24b8215bf39a6a2ce0c262bc5b000724077afa9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\CssSelector\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "http://symfony.com", + "time": "2014-07-09 09:05:48" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.5.3", + "target-dir": "Symfony/Component/EventDispatcher", + "source": { + "type": "git", + "url": "https://github.com/symfony/EventDispatcher.git", + "reference": "8faf5cc7e80fde74a650a36e60d32ce3c3e0457b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/8faf5cc7e80fde74a650a36e60d32ce3c3e0457b", + "reference": "8faf5cc7e80fde74a650a36e60d32ce3c3e0457b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.0", + "symfony/dependency-injection": "~2.0", + "symfony/stopwatch": "~2.2" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "http://symfony.com", + "time": "2014-07-28 13:20:46" + }, + { + "name": "symfony/yaml", + "version": "v2.5.3", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f", + "reference": "5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2014-08-05 09:00:40" + } + ], + "packages-dev": [ + { + "name": "aik099/coding-standard", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/aik099/CodingStandard.git", + "reference": "bd65e0e95a59d54fb75b8d772eacdfa849bbcf19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/bd65e0e95a59d54fb75b8d772eacdfa849bbcf19", + "reference": "bd65e0e95a59d54fb75b8d772eacdfa849bbcf19", + "shasum": "" + }, + "require-dev": { + "squizlabs/php_codesniffer": "~1.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Alexander Obuhovich", + "email": "aik.bold@gmail.com" + } + ], + "description": "The PHP_CodeSniffer coding standard I'm using on all of my projects.", + "keywords": [ + "PHP_CodeSniffer", + "codesniffer" + ], + "time": "2014-08-06 08:15:06" + }, + { + "name": "mockery/mockery", + "version": "0.9.1", + "source": { + "type": "git", + "url": "https://github.com/padraic/mockery.git", + "reference": "17f63ee40ed14a8afb7ba1f0ae15cc4491d719d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/padraic/mockery/zipball/17f63ee40ed14a8afb7ba1f0ae15cc4491d719d1", + "reference": "17f63ee40ed14a8afb7ba1f0ae15cc4491d719d1", + "shasum": "" + }, + "require": { + "lib-pcre": ">=7.0", + "php": ">=5.3.2" + }, + "require-dev": { + "hamcrest/hamcrest-php": "~1.1", + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "~0.7@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.9.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succint API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", + "homepage": "http://github.com/padraic/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2014-05-02 12:16:45" + } + ], + "aliases": [ + + ], + "minimum-stability": "stable", + "stability-flags": { + "behat/mink": 20, + "behat/mink-selenium2-driver": 20, + "aik099/coding-standard": 20 + }, + "platform": { + "php": ">=5.3.2" + }, + "platform-dev": [ + + ] +} From 4c48bf54cb093462d8237d6515ad4e304dab469b Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 9 Aug 2014 13:35:40 +0300 Subject: [PATCH 056/204] Adding PHP 5.6 to Travis CI build matrix --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index eedafad..81f0a96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ php: - 5.3 - 5.4 - 5.5 + - 5.6 - hhvm env: From 2ef91f638cb7d9a30fdc505f6ff0870a450a1eb5 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 9 Aug 2014 15:13:08 +0300 Subject: [PATCH 057/204] Change branch alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 15bee98..81002d7 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "2.0.x-dev" } } } From 0c1367b2bf401253ffcdd29ceaee4f1ec9ddbcf2 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 7 Sep 2014 12:45:15 +0300 Subject: [PATCH 058/204] Updating badges to use SVG format --- README.md | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a4baa99..884dc7a 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ # PHPUnit-Mink -[![Build Status](https://travis-ci.org/aik099/phpunit-mink.png?branch=master)](https://travis-ci.org/aik099/phpunit-mink) -[![HHVM Status](http://hhvm.h4cc.de/badge/aik099/phpunit-mink.png)](http://hhvm.h4cc.de/package/aik099/phpunit-mink) +[![Build Status](https://travis-ci.org/aik099/phpunit-mink.svg?branch=master)](https://travis-ci.org/aik099/phpunit-mink) +[![HHVM Status](http://hhvm.h4cc.de/badge/aik099/phpunit-mink.svg)](http://hhvm.h4cc.de/package/aik099/phpunit-mink) -[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/aik099/phpunit-mink/badges/quality-score.png?s=57e408500d59e10ce44b604df678ec8b59a1b8f8)](https://scrutinizer-ci.com/g/aik099/phpunit-mink/) -[![Coverage Status](https://coveralls.io/repos/aik099/phpunit-mink/badge.png?branch=master)](https://coveralls.io/r/aik099/phpunit-mink?branch=master) -[![Dependency Status](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049/badge.png)](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/aik099/phpunit-mink/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/aik099/phpunit-mink/?branch=master) +[![Coverage Status](https://img.shields.io/coveralls/aik099/phpunit-mink.svg)](https://coveralls.io/r/aik099/phpunit-mink?branch=master) +[![Dependency Status](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049/badge.svg?style=flat)](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049) -[![Latest Stable Version](https://poser.pugx.org/aik099/phpunit-mink/v/stable.png)](https://packagist.org/packages/aik099/phpunit-mink) -[![Total Downloads](https://poser.pugx.org/aik099/phpunit-mink/downloads.png)](https://packagist.org/packages/aik099/phpunit-mink) +[![Latest Stable Version](https://poser.pugx.org/aik099/phpunit-mink/v/stable.svg)](https://packagist.org/packages/aik099/phpunit-mink) [![Total Downloads](https://poser.pugx.org/aik099/phpunit-mink/downloads.svg)](https://packagist.org/packages/aik099/phpunit-mink) [![Latest Unstable Version](https://poser.pugx.org/aik099/phpunit-mink/v/unstable.svg)](https://packagist.org/packages/aik099/phpunit-mink) [![License](https://poser.pugx.org/aik099/phpunit-mink/license.svg)](https://packagist.org/packages/aik099/phpunit-mink) This library is an extension for [PHPUnit](sebastianbergmann/phpunit), that allows to write tests with help of [Mink](Behat/Mink). @@ -260,14 +259,8 @@ There are also corresponding `set` and `get` methods for each of mentioned above ```json { "require": { - "aik099/phpunit-mink": "~1.0" - }, - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/aik099/phpunit-mink" - }, - ] + "aik099/phpunit-mink": "~2.0" + } } ``` From ddad29300813347ea4756459ff7c5752df9946ef Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Mon, 8 Sep 2014 20:35:28 +0200 Subject: [PATCH 059/204] Migrating documentation to ReadTheDocs.Org --- .travis.yml | 3 + README.md | 249 +----------------- docs/.gitignore | 1 + docs/Makefile | 180 +++++++++++++ docs/README.md | 20 ++ docs/browser-aliases.rst | 22 ++ docs/conf.py | 135 ++++++++++ docs/configuration.rst | 63 +++++ docs/examples/browser_aliases.php | 35 +++ .../config_via_browsers_property.php | 23 ++ .../configuration/config_via_setup_method.php | 37 +++ .../per_test_case_browser_config.php | 18 ++ .../examples/getting-started/general_test.php | 38 +++ docs/examples/getting-started/sauce_labs.php | 26 ++ docs/getting-started.rst | 53 ++++ docs/index.rst | 28 ++ docs/remote-code-coverage.rst | 43 +++ 17 files changed, 730 insertions(+), 244 deletions(-) create mode 100644 docs/.gitignore create mode 100644 docs/Makefile create mode 100644 docs/README.md create mode 100644 docs/browser-aliases.rst create mode 100644 docs/conf.py create mode 100644 docs/configuration.rst create mode 100644 docs/examples/browser_aliases.php create mode 100644 docs/examples/configuration/config_via_browsers_property.php create mode 100644 docs/examples/configuration/config_via_setup_method.php create mode 100644 docs/examples/configuration/per_test_case_browser_config.php create mode 100644 docs/examples/getting-started/general_test.php create mode 100644 docs/examples/getting-started/sauce_labs.php create mode 100644 docs/getting-started.rst create mode 100644 docs/index.rst create mode 100644 docs/remote-code-coverage.rst diff --git a/.travis.yml b/.travis.yml index 81f0a96..2f70f6b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,10 +17,13 @@ addons: before_script: - composer require satooshi/php-coveralls:dev-master --dev --prefer-source + - sudo easy_install -U Sphinx + - sudo pip install sphinx_rtd_theme script: - mkdir -p build/logs - phpunit -v --coverage-clover build/logs/clover.xml + - sphinx-build -nW -b html -d docs/build/doctrees docs docs/build/html after_script: - php vendor/bin/coveralls -v diff --git a/README.md b/README.md index 884dc7a..7a60a8f 100644 --- a/README.md +++ b/README.md @@ -10,252 +10,13 @@ This library is an extension for [PHPUnit](sebastianbergmann/phpunit), that allows to write tests with help of [Mink](Behat/Mink). -## Overview -This library allows to perform following things: +## Documentation -* use [Mink](Behat/Mink) for browser session control -* each test in a test case can use independent browser session -* all tests in a test case can share session between them -* Selenium server connection details are decoupled from tests using them -* perform individual browser configuration for each test in a test case -* support for "[Sauce Labs](https://saucelabs.com/)" -* remote code coverage collection +* http://phpunit-mink.readthedocs.org -Each mentioned above features is described in more detail below. +## Installation using Composer -## Basic Usage -1. create subclass from `\aik099\PHPUnit\BrowserTestCase` class -2. define used browser configurations in static `$browsers` property of that class -3. use `$this->getSession()` method in your tests to access [Mink](Behat/Mink) session - -## Using Mink -Call `$this->getSession()` from a test to get running `\Behat\Mink\Session` object, which is already configured from test configuration. - -```php -getSession(); - - $session->visit('http://www.google.com'); - - $this->assertTrue($session->getPage()->hasContent('Google')); - } - -} -``` - - -## Per-test Browser Configuration -It is possible to set individual browser configuration for each test in a test case by creating a `\aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration` class instance in `setUp` method of the test case. - -```php -createBrowserConfiguration(array( - // options goes here (optional) - )); - - // to create "Sauce Labs" browser configuration via BrowserConfigurationFactory - $browser = $this->createBrowserConfiguration(array( - // required - 'type' => 'saucelabs', - 'api_username' => 'sauce_username', - 'api_key' => 'sauce_api_key', - // options (optional) goes here - )); - - // options can be changed later (optional) - $browser->setHost('selenium_host')->setPort('selenium_port')->setTimeout(30); - $browser->setBrowserName('browser name')->setDesiredCapabilities(array('version' => '6.5')); - $browser->setBaseUrl('http://www.test-host.com'); - - // set browser configuration to test case - $this->setBrowser($browser); - - parent::setUp(); - } - -} -``` - -## Sharing Browser Configuration Between Tests -It is possible to define a single browser configuration to be used for each test in test case. This can be done by defining static `$browsers` class variable as an array, where each item represents a single browser configuration. In that case each of the tests in a test case would be executed using each of defined browser configurations. - -```php - 'localhost', - 'port' => 4444, - 'browserName' => 'firefox', - 'baseUrl' => 'http://www.google.com', - ), - array( - 'host' => 'localhost', - 'port' => 4444, - 'browserName' => 'chrome', - 'baseUrl' => 'http://www.google.com', - ), - ); - - public function testUsingBrowsersArray() - { - echo sprintf("I'm executed using '%s' browser", $this->getBrowser()->getBrowserName()); - } - -} -``` - -## Sharing Session Between Tests -As a benefit of shared browser configuration, that was described above is an ability to not only share browser configuration, that is used to create [Mink](Behat/Mink) session, but to actually share created sessions between all tests in a test case. This can be done by adding `sessionStrategy` option to browser configuration. - -```php - 'localhost', - 'port' => 4444, - 'browserName' => 'firefox', - 'baseUrl' => 'http://www.google.com', - 'sessionStrategy' => 'shared', - ), - ); - -} -``` - -## Using Browser Aliases -All previous examples demonstrate various ways how browser configuration can be defined, but they all have same downside - server connection details stay hard-coded in test case classes. This could become very problematic if: - -* same test cases needs to be executed on different servers (e.g. each developer runs them on his own machine) -* due change of server connection details each test case class needs to be changed - -To solve this problem a browser aliases were introduced. Basically a browser alias is predefined browser configuration, that is available in the test case by it's alias. How it can be used: - -1. create base test case class, by extending BrowserTestCase class in the project with `getBrowserAliases` method in it. That method will return an associative array of a browser configurations (array key acts as alias name) -2. in any place, where browser configuration is defined use `'alias' => 'alias_name_here'` instead of actual browser configuration -3. feel free to override any part of configuration defined in alias -4. nested aliases are also supported - -```php - array( - 'host' => 'localhost', - 'port' => 4444, - 'browserName' => 'firefox', - 'baseUrl' => 'http://www.google.com', - ), - ); - } - -} - - -class ConcreteTest extends BrowserAliasTest -{ - - public static $browsers = array( - array( - 'alias' => 'example_alias', - - ), - array( - 'alias' => 'example_alias', - 'browserName' => 'chrome', - ), - ); -} - -``` - -## Using "Sauce Labs" -When using "Sauce Labs" account to perform Selenium server-based testing you need to specify `'type' => 'saucelabs', 'api_username' => '...', 'api_key' => '...'` instead of `host` or `port` settings. In all other aspects all will work the same as if all tests are running locally. - -## Remote Code Coverage -Browser tests are executed on different machine, then one, where code coverage information is collected (and tests are executed). To solve that problem this library uses remote coverage collection. Following steps needs to be performed before using this feature: - -### On Remote Server -Remote server is web-server, where website used in tests is located. - -1. Install [Xdebug](http://xdebug.org/) PHP extension on web-server -2. Copy `library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php` into web-server's DocumentRoot directory. -3. Include following code before your application bootstraps: - -```php -require_once 'RemoteCoverageTool.php'; -\aik099\PHPUnit\RemoteCoverage\RemoteCoverageTool::init(); -``` - -### On Test Machine -This is machine, where PHPUnit tests are being executed. - -By default the `baseUrl` setting from browser configuration is used as the `remote code coverage information url`. However if a need exists to set alternative url on per-test basis, then place following code in the `setUp` method of the test case class, that extends `BrowserTestCase` class: - -```php - $this->setRemoteCoverageScriptUrl('http://host/'); // `host` should be replaced with web server's url -``` - -### How This Works -1. each test sets a special cookie on website under test -2. when cookie is present, then `RemoteCoverageTool.php` script collects coverage information and stores it on disk -3. once test finishes, then `http://host/?rct_mode=output` url is accessed on remote server, which in turn returns collected coverage information -4. remote coverage information is then joined with coverage information collected locally on test machine - -## Browser Configuration in Details -Each browser configuration consists of the following settings: - -| Name | Description | -|---|---| -| `host` | host, where Selenium Server is located (defaults to `localhost`) | -| `port` | port, on which Selenium Server is listening for incoming connections (defaults to `4444`) | -| `timeout` | connection timeout of the server in seconds (defaults to `60`) | -| `browserName` | name of browser to use (e.g. `firefox`, `chrome`, etc., defaults to `firefox`) | -| `desiredCapabilities` | parameters, that specify additional browser configuration (e.g. browser version, platform, etc.) | -| `baseUrl` | base url of website, that is tested | -| `sauce` | Sauce Labs connection configuration (e.g. `array('username' => 'username_here', 'api_key' => 'api_key_here')`) | - -There are also corresponding `set` and `get` methods for each of mentioned above settings, that allow to individually change them before test has started (from `setUp` method). - -## Using Composer - -1. Define the dependencies in your ```composer.json```: +Define the dependencies in your ```composer.json```: ```json { "require": { @@ -264,7 +25,7 @@ There are also corresponding `set` and `get` methods for each of mentioned above } ``` -2. Install/update your vendors: +Install/update your vendors: ```bash $ curl http://getcomposer.org/installer | php $ php composer.phar install diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..c795b05 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..f669162 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,180 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +livehtml: + sphinx-autobuild -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PHPUnit-Mink.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PHPUnit-Mink.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/PHPUnit-Mink" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PHPUnit-Mink" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..72da0b4 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,20 @@ +# PHPUnit-Mink Documentation + +## Preparations + +1. install [Sphinx](http://sphinx-doc.org/): `easy_install -U Sphinx` +2. install [Read the Docs Sphinx Theme](https://github.com/snide/sphinx_rtd_theme): `pip install sphinx_rtd_theme` +3. install [sphinx-autobuild](https://pypi.python.org/pypi/sphinx-autobuild/0.2.3): `pip install sphinx-autobuild` + +## Automatic building + +1. run `make livehtml` in the `docs` folder +2. open `http://localhost:8000/` to view the documentation + +Thanks to the __sphinx-autobuild__ the documentation will be automatically built on every change and all browsers, +where it's opened will be reloaded automatically as well. + +## One-time building + +1. run `make html` in the `docs` folder +2. open `docs/build/html` folder in your browser diff --git a/docs/browser-aliases.rst b/docs/browser-aliases.rst new file mode 100644 index 0000000..33997b7 --- /dev/null +++ b/docs/browser-aliases.rst @@ -0,0 +1,22 @@ +Browser Aliases +=============== +All previous examples demonstrate various ways how browser configuration can be defined, but they all have +same downside - server connection details stay hard-coded in test case classes. This could become very +problematic if: + +* same test cases needs to be executed on different servers (e.g. each developer runs them on his own machine) +* due change in server connection details each test case class needs to be changed + +To solve this problem a browser aliases were introduced. Basically a browser alias is predefined browser +configuration, that is available in the test case by it's alias. Here is how it can be used: + +#. create base test case class, by extending ``BrowserTestCase`` class in the project + with ``getBrowserAliases`` method in it +#. the ``getBrowserAliases`` method will return an associative array of a browser configurations (array key acts as alias name) +#. in any place, where browser configuration is defined use ``'alias' => 'alias_name_here'`` instead of actual browser configuration +#. feel free to override any part of configuration defined in alias + +.. note:: Nested aliases are also supported. + +.. literalinclude:: examples/browser_aliases.php + :linenos: diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..882401c --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +if not on_rtd: # only import and set the theme if we're building docs locally + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# otherwise, readthedocs.org uses their theme by default, so no need to specify it + +# -- General configuration ------------------------------------------------ + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'PHPUnit-Mink' +copyright = u'2014, Alexander Obuhovich' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '1.0.0' +# The full version, including alpha/beta/rc tags. +release = '1.0.0' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['build'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +highlight_language = 'php' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# -- Options for HTML output ---------------------------------------------- + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# Output file base name for HTML help builder. +htmlhelp_basename = 'PHPUnit-Minkdoc' + +# -- Options for LaTeX output --------------------------------------------- + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'PHPUnit-Mink.tex', u'PHPUnit-Mink Documentation', + u'Alexander Obuhovich', 'manual'), +] + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'phpunit-mink', u'PHPUnit-Mink Documentation', + [u'Alexander Obuhovich'], 1) +] + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'PHPUnit-Mink', u'PHPUnit-Mink Documentation', + u'Alexander Obuhovich', 'PHPUnit-Mink', 'One line description of project.', + 'Miscellaneous'), +] diff --git a/docs/configuration.rst b/docs/configuration.rst new file mode 100644 index 0000000..e06e7b4 --- /dev/null +++ b/docs/configuration.rst @@ -0,0 +1,63 @@ +Configuring Browser +=================== +The browser needs to be configured in a test case before being able to access `Mink`_ session. +All possible ways of browser configuration are described below. + +Per Test Configuration +^^^^^^^^^^^^^^^^^^^^^^ +It is possible to configure browser individually for each test within a test case by creating +an instance of ``\aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration`` class in ``setUp`` +method in of test case class and setting it via ``setBrowser`` method. + +.. literalinclude:: examples/configuration/config_via_setup_method.php + :linenos: + :emphasize-lines: 11,16,25-29,32 + +Per Test Case Configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +In case, when all tests in a test case share same browser configuration it's easier to specify it via +static ``$browsers`` property (array, where each item represents a single browser +configuration) in that test case class. + +.. literalinclude:: examples/configuration/config_via_browsers_property.php + :linenos: + :emphasize-lines: 8,9,15 + +.. note:: When several browser configurations are specified in ``$browsers`` array, then each test + in a test case will be executed against each of browser configurations. + +Browser Session Sharing +^^^^^^^^^^^^^^^^^^^^^^^ +As a benefit of shared (per test case) browser configuration, that was described above is an ability +to not only share browser configuration, that is used to create `Mink`_ session, but to actually share +created sessions between all tests in a single test case. This can be done by adding ``sessionStrategy`` +option (line 14) to the browser configuration. + +.. literalinclude:: examples/configuration/per_test_case_browser_config.php + :linenos: + :emphasize-lines: 14 + +Configuration Options +^^^^^^^^^^^^^^^^^^^^^ +Each browser configuration consists of the following settings (all optional): + +======================= ================================================================================================= +Name Description +======================= ================================================================================================= +``host`` host, where Selenium Server is located (defaults to ``localhost``) +``port`` port, on which Selenium Server is listening for incoming connections (defaults to ``4444``) +``timeout`` connection timeout of the server in seconds (defaults to ``60``) +``browserName`` name of browser to use (e.g. ``firefox``, ``chrome``, etc., defaults to ``firefox``) +``desiredCapabilities`` parameters, that specify additional browser configuration (e.g. browser version, platform, etc.), + that will be used by Selenium server +``baseUrl`` base url of website, that is tested +``sessionStrategy`` used session strategy (defaults to ``isolated``) +``type`` type of configuration (defaults to ``default``, but can also be ``saucelabs``) +``api_username`` API username of used service (applicable to any but ``default`` configuration type) +``api_key`` API key of used service (applicable to any but ``default`` configuration type) +======================= ================================================================================================= + +There are also corresponding setters (e.g. ``setHost``) and getters (e.g. ``getHost``) for each of mentioned +above settings, that allow to individually change them from ``setUp`` method before test has started. + +.. _`Mink`: https://github.com/Behat/Mink diff --git a/docs/examples/browser_aliases.php b/docs/examples/browser_aliases.php new file mode 100644 index 0000000..3aa7288 --- /dev/null +++ b/docs/examples/browser_aliases.php @@ -0,0 +1,35 @@ + array( + 'host' => 'localhost', + 'port' => 4444, + 'browserName' => 'firefox', + 'baseUrl' => 'http://www.google.com', + ), + ); + } + +} + + +class ConcreteTest extends BrowserAliasTestCase +{ + + public static $browsers = array( + array( + 'alias' => 'example_alias', + ), + array( + 'alias' => 'example_alias', + 'browserName' => 'chrome', + ), + ); +} diff --git a/docs/examples/configuration/config_via_browsers_property.php b/docs/examples/configuration/config_via_browsers_property.php new file mode 100644 index 0000000..54863da --- /dev/null +++ b/docs/examples/configuration/config_via_browsers_property.php @@ -0,0 +1,23 @@ + 'localhost', + 'port' => 4444, + 'browserName' => 'firefox', + 'baseUrl' => 'http://www.google.com', + ), + array( + 'host' => 'localhost', + 'port' => 4444, + 'browserName' => 'chrome', + 'baseUrl' => 'http://www.google.com', + ), + ); + +} diff --git a/docs/examples/configuration/config_via_setup_method.php b/docs/examples/configuration/config_via_setup_method.php new file mode 100644 index 0000000..4ecc534 --- /dev/null +++ b/docs/examples/configuration/config_via_setup_method.php @@ -0,0 +1,37 @@ +createBrowserConfiguration(array( + // options goes here (optional) + )); + + // To create "Sauce Labs" browser configuration via BrowserConfigurationFactory. + $browser = $this->createBrowserConfiguration(array( + // required + 'type' => 'saucelabs', + 'api_username' => 'sauce_username', + 'api_key' => 'sauce_api_key', + // optional options goes here + )); + + // Options can be changed later (optional). + $browser->setHost('selenium_host')->setPort('selenium_port')->setTimeout(30); + $browser->setBrowserName('browser name')->setDesiredCapabilities(array( + 'version' => '6.5' + )); + $browser->setBaseUrl('http://www.test-host.com'); + + // Set browser configuration to test case. + $this->setBrowser($browser); + + parent::setUp(); + } + +} diff --git a/docs/examples/configuration/per_test_case_browser_config.php b/docs/examples/configuration/per_test_case_browser_config.php new file mode 100644 index 0000000..37710ed --- /dev/null +++ b/docs/examples/configuration/per_test_case_browser_config.php @@ -0,0 +1,18 @@ + 'localhost', + 'port' => 4444, + 'browserName' => 'firefox', + 'baseUrl' => 'http://www.google.com', + 'sessionStrategy' => 'shared', + ), + ); + +} diff --git a/docs/examples/getting-started/general_test.php b/docs/examples/getting-started/general_test.php new file mode 100644 index 0000000..bc1ac56 --- /dev/null +++ b/docs/examples/getting-started/general_test.php @@ -0,0 +1,38 @@ + 'localhost', + 'port' => 4444, + 'browserName' => 'firefox', + 'baseUrl' => 'http://www.google.com', + ), + ); + + public function testUsingSession() + { + // This is Mink's Session. + $session = $this->getSession(); + + // Go to a page. + $session->visit('http://www.google.com'); + + // Validate text presence on a page. + $this->assertTrue($session->getPage()->hasContent('Google')); + } + + public function testUsingBrowser() + { + // Prints the name of used browser. + echo sprintf( + "I'm executed using '%s' browser", + $this->getBrowser()->getBrowserName() + ); + } + +} diff --git a/docs/examples/getting-started/sauce_labs.php b/docs/examples/getting-started/sauce_labs.php new file mode 100644 index 0000000..c7e609b --- /dev/null +++ b/docs/examples/getting-started/sauce_labs.php @@ -0,0 +1,26 @@ + 'saucelabs', + 'api_username' => '...', + 'api_key' => '...', + 'browserName' => 'firefox', + 'baseUrl' => 'http://www.google.com', + ), + // Regular browser configuration. + array( + 'host' => 'localhost', + 'port' => 4444, + 'browserName' => 'chrome', + 'baseUrl' => 'http://www.google.com', + ), + ); + +} diff --git a/docs/getting-started.rst b/docs/getting-started.rst new file mode 100644 index 0000000..15e32d7 --- /dev/null +++ b/docs/getting-started.rst @@ -0,0 +1,53 @@ +Getting Started +=============== +Below you'll find all needed information to find your way across the library. + +Installation +^^^^^^^^^^^^ +Library can be installed using Composer like so: + +1. define the dependencies in your ``composer.json``: + +.. code-block:: json + + { + "require": { + "aik099/phpunit-mink": "~2.0" + } + } + +2. install/update your vendors: + +.. code-block:: bash + + $ curl http://getcomposer.org/installer | php + $ php composer.phar install + +Basic Usage +^^^^^^^^^^^ +#. sub-class test case class from ``\aik099\PHPUnit\BrowserTestCase`` class (line 5) +#. define used browser configurations in static ``$browsers`` property of that class (line 8-21) +#. access `Mink`_ session by calling ``$this->getSession()`` method in your test (line 26) +#. access browser configuration by calling ``$this->getBrowser()`` method in your test (line 40) + +.. literalinclude:: examples/getting-started/general_test.php + :linenos: + :emphasize-lines: 5,8,20,34 + +Using "Sauce Labs" +^^^^^^^^^^^^^^^^^^ +When using `Sauce Labs `_ account to perform Selenium server-based testing you need to +specify following settings: + +* ``'type' => 'saucelabs'`` +* ``'api_username' => '...'`` +* ``'api_key' => '...'`` + +instead of ``host`` and ``port`` settings. In all other aspects everything will work the same as if all +tests were running locally. + +.. literalinclude:: examples/getting-started/sauce_labs.php + :linenos: + :emphasize-lines: 11-13 + +.. _`Mink`: https://github.com/Behat/Mink diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..ff20ce6 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,28 @@ +PHPUnit-Mink Documentation +========================== +This library is an extension for `PHPUnit `_, that allows to write tests +with help of `Mink`_. + +Overview +-------- +This library allows to perform following things: + +* use `Mink`_ for browser session control +* each test in a test case can use independent browser session +* all tests in a test case can share browser session between them +* Selenium server connection details are decoupled from tests using them +* perform individual browser configuration for each test in a test case +* support for `Sauce Labs `_ +* remote code coverage collection + +Each mentioned above features is described in more detail below. + +.. _`Mink`: https://github.com/Behat/Mink + +.. toctree:: + :maxdepth: 2 + + getting-started + configuration + browser-aliases + remote-code-coverage diff --git a/docs/remote-code-coverage.rst b/docs/remote-code-coverage.rst new file mode 100644 index 0000000..62dcd63 --- /dev/null +++ b/docs/remote-code-coverage.rst @@ -0,0 +1,43 @@ +Remote Code Coverage +==================== +Browser tests are executed on different machine, then one, where code coverage information is collected +(and tests are executed). To solve that problem this library uses remote coverage collection. Following +steps needs to be performed before using this feature: + +On Remote Server +^^^^^^^^^^^^^^^^ +This is web-server, where website used in tests is located. + +#. Install `Xdebug `_ PHP extension on web-server +#. Copy ``library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php`` into web-server's DocumentRoot directory. +#. Include following code before your application bootstraps: + +.. code-block:: php + + setRemoteCoverageScriptUrl('http://host/'); + +How This Works +^^^^^^^^^^^^^^ +#. each test sets a special cookie on website under test +#. when cookie is present, then ``RemoteCoverageTool.php`` script collects coverage information and stores it on disk +#. once test finishes, then ``http://host/?rct_mode=output`` url is accessed on remote server, which in turn returns collected coverage information +#. remote coverage information is then joined with coverage information collected locally on test machine From 5f134821502603f1d99c382df0b4f1e0497453be Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Mon, 8 Sep 2014 20:41:34 +0200 Subject: [PATCH 060/204] Adding ReadTheDocs.Org badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7a60a8f..ad3594f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # PHPUnit-Mink [![Build Status](https://travis-ci.org/aik099/phpunit-mink.svg?branch=master)](https://travis-ci.org/aik099/phpunit-mink) [![HHVM Status](http://hhvm.h4cc.de/badge/aik099/phpunit-mink.svg)](http://hhvm.h4cc.de/package/aik099/phpunit-mink) +[![Documentation Status](https://readthedocs.org/projects/phpunit-mink/badge/?version=latest)](https://readthedocs.org/projects/phpunit-mink/?badge=latest) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/aik099/phpunit-mink/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/aik099/phpunit-mink/?branch=master) [![Coverage Status](https://img.shields.io/coveralls/aik099/phpunit-mink.svg)](https://coveralls.io/r/aik099/phpunit-mink?branch=master) From d37c1139fabdecf8b6ad238a2f308990e4c42f92 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Thu, 27 Nov 2014 17:14:08 +0200 Subject: [PATCH 061/204] Support for Data Providers Closes #25 --- .../PHPUnit/TestSuite/AbstractTestSuite.php | 48 ++++++++++++++----- .../PHPUnit/TestSuite/BrowserTestSuite.php | 18 +++++-- .../PHPUnit/Integration/DataProviderTest.php | 48 +++++++++++++++++++ 3 files changed, 99 insertions(+), 15 deletions(-) create mode 100644 tests/aik099/PHPUnit/Integration/DataProviderTest.php diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index 9609d26..7d8e27c 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -77,21 +77,37 @@ public function addTestMethods($class_name) * @param SessionStrategyManager $session_strategy_manager Session strategy manager. * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. * @param RemoteCoverageHelper $remote_coverage_helper Remote coverage helper. + * @param array $tests Tests to process. * * @return self */ public function setTestDependencies( SessionStrategyManager $session_strategy_manager, IBrowserConfigurationFactory $browser_configuration_factory, - RemoteCoverageHelper $remote_coverage_helper + RemoteCoverageHelper $remote_coverage_helper, + array $tests = null ) { - /* @var $test BrowserTestCase */ - foreach ( $this->tests() as $test ) { - $test->setEventDispatcher($this->_eventDispatcher); - $test->setSessionStrategyManager($session_strategy_manager); - $test->setBrowserConfigurationFactory($browser_configuration_factory); - $test->setRemoteCoverageHelper($remote_coverage_helper); + if ( !isset($tests) ) { + $tests = $this->tests(); + } + + foreach ( $tests as $test ) { + if ( $test instanceof \PHPUnit_Framework_TestSuite_DataProvider ) { + $this->setTestDependencies( + $session_strategy_manager, + $browser_configuration_factory, + $remote_coverage_helper, + $test->tests() + ); + } + else { + /** @var BrowserTestCase $test */ + $test->setEventDispatcher($this->_eventDispatcher); + $test->setSessionStrategyManager($session_strategy_manager); + $test->setBrowserConfigurationFactory($browser_configuration_factory); + $test->setRemoteCoverageHelper($remote_coverage_helper); + } } return $this; @@ -100,14 +116,24 @@ public function setTestDependencies( /** * Report back suite ending to each it's test. * + * @param array $tests Tests to process. + * * @return void */ - protected function tearDown() + protected function tearDown(array $tests = null) { - /* @var $test BrowserTestCase */ + if ( !isset($tests) ) { + $tests = $this->tests(); + } - foreach ( $this->tests() as $test ) { - $test->onTestSuiteEnded(); + foreach ( $tests as $test ) { + if ( $test instanceof \PHPUnit_Framework_TestSuite_DataProvider ) { + $this->tearDown($test->tests()); + } + else { + /* @var $test BrowserTestCase */ + $test->onTestSuiteEnded(); + } } } diff --git a/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php b/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php index 61afce1..acd676d 100644 --- a/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php @@ -43,14 +43,24 @@ public function nameFromBrowser(array $browser) * Sets given browser to be used in each underlying test cases and test suites. * * @param array $browser Browser configuration. + * @param array $tests Tests to process. * * @return self */ - public function setBrowserFromConfiguration(array $browser) + public function setBrowserFromConfiguration(array $browser, array $tests = null) { - /* @var $test BrowserTestCase */ - foreach ( $this->tests() as $test ) { - $test->setBrowserFromConfiguration($browser); + if ( !isset($tests) ) { + $tests = $this->tests(); + } + + foreach ( $tests as $test ) { + if ( $test instanceof \PHPUnit_Framework_TestSuite_DataProvider ) { + $this->setBrowserFromConfiguration($browser, $test->tests()); + } + else { + /* @var $test BrowserTestCase */ + $test->setBrowserFromConfiguration($browser); + } } return $this; diff --git a/tests/aik099/PHPUnit/Integration/DataProviderTest.php b/tests/aik099/PHPUnit/Integration/DataProviderTest.php new file mode 100644 index 0000000..18c98ec --- /dev/null +++ b/tests/aik099/PHPUnit/Integration/DataProviderTest.php @@ -0,0 +1,48 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Integration; + + +use aik099\PHPUnit\BrowserTestCase; +use Mockery as m; + +class DataProviderTest extends BrowserTestCase +{ + + public function sampleDataProvider() + { + return array( + array('case1'), + array('case2'), + ); + } + + /** + * @dataProvider sampleDataProvider + */ + public function testDataProvider($case) + { + $this->customMethod(); + + if ( $case === 'case1' || $case === 'case2' ) { + $this->assertTrue(true); + } + else { + $this->fail('Unknown $case: ' . $case); + } + } + + protected function customMethod() + { + return 5; + } + +} From 137af5fcca0946de6d1b94c3fc0fa1b5012a03ab Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Thu, 27 Nov 2014 17:46:39 +0200 Subject: [PATCH 062/204] Don't automatically enable remote code coverage collection --- docs/remote-code-coverage.rst | 6 ++-- .../BrowserConfiguration.php | 1 - library/aik099/PHPUnit/BrowserTestCase.php | 9 +++-- .../ApiBrowserConfigurationTestCase.php | 1 - .../BrowserConfigurationTest.php | 2 -- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 19 +++------- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 1 + .../PHPUnit/Integration/DataProviderTest.php | 35 +++++++++++++++++++ 8 files changed, 47 insertions(+), 27 deletions(-) diff --git a/docs/remote-code-coverage.rst b/docs/remote-code-coverage.rst index 62dcd63..9a12e81 100644 --- a/docs/remote-code-coverage.rst +++ b/docs/remote-code-coverage.rst @@ -23,10 +23,8 @@ On Test Machine ^^^^^^^^^^^^^^^ This is machine, where PHPUnit tests are being executed. -By default the ``baseUrl`` setting from browser configuration is used as the -"remote code coverage information url". However if a need exists to set alternative url on -per-test basis, then place following code in the ``setUp`` method of the test case class, -that extends ``BrowserTestCase`` class: +Following code needs to be placed in the ``setUp`` method of the test case class (that extends ``BrowserTestCase`` +class) to enable remote coverage information collection: .. code-block:: php diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 3fdd2f1..815a612 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -147,7 +147,6 @@ public static function getSubscribedEvents() public function attachToTestCase(BrowserTestCase $test_case) { $this->_testCase = $test_case; - $this->_testCase->setRemoteCoverageScriptUrl($this->getBaseUrl()); $this->_eventDispatcher->addSubscriber($this); return $this; diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index dd85e09..2c77393 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -387,18 +387,17 @@ public function onTestSuiteEnded() } /** - * Returns remote code coverage information. + * Returns remote code coverage information, when enabled. * * @return array - * @throws \RuntimeException When no remote coverage script URL set. */ public function getRemoteCodeCoverageInformation() { - if ( $this->_remoteCoverageScriptUrl == '' ) { - throw new \RuntimeException('Remote coverage script url not set'); + if ( $this->_remoteCoverageScriptUrl ) { + return $this->remoteCoverageHelper->get($this->_remoteCoverageScriptUrl, $this->_testId); } - return $this->remoteCoverageHelper->get($this->_remoteCoverageScriptUrl, $this->_testId); + return array(); } /** diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 94a6563..b512ba5 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -332,7 +332,6 @@ public function testTestEndedWithoutSession() protected function createTestCase($name) { $test_case = m::mock(self::TEST_CASE_CLASS); - $test_case->shouldReceive('setRemoteCoverageScriptUrl')->once(); $test_case->shouldReceive('getName')->andReturn($name); $this->browser->attachToTestCase($test_case); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 9bba090..e5f729d 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -183,7 +183,6 @@ public function testAttachToTestCase() /* @var $test_case BrowserTestCase */ $test_case = m::mock(self::TEST_CASE_CLASS); - $test_case->shouldReceive('setRemoteCoverageScriptUrl')->with('')->once(); $this->assertSame($browser, $browser->attachToTestCase($test_case)); $this->assertSame($test_case, $browser->getTestCase()); @@ -385,7 +384,6 @@ public function testGetSessionStrategyHashBrowserSharing($session_strategy) { /* @var $test_case BrowserTestCase */ $test_case = m::mock(self::TEST_CASE_CLASS); - $test_case->shouldReceive('setRemoteCoverageScriptUrl')->with('')->twice(); $browser1 = $this->createBrowserConfiguration(array(), true); $browser1->setSessionStrategy($session_strategy)->attachToTestCase($test_case); diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index ea57179..2cb98b7 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -250,17 +250,6 @@ public function testGetCollectCodeCoverageInformationSuccess() $this->assertTrue($test_case->getCollectCodeCoverageInformation()); } - /** - * Test description. - * - * @return void - * @expectedException \RuntimeException - */ - public function testGetCollectCodeCoverageInformationFailure() - { - $this->getFixture()->getCollectCodeCoverageInformation(); - } - /** * Test description. * @@ -292,17 +281,19 @@ public function testRunCreateResult() * Test description. * * @return void - * @expectedException \RuntimeException */ public function testRunWithCoverageWithoutRemoteUrl() { /* @var $test_case BrowserTestCase */ /* @var $session_strategy ISessionStrategy */ - list($test_case, $session_strategy) = $this->prepareForRun(array(), false); + list($test_case, $session_strategy) = $this->prepareForRun(array()); $test_case->setName('getTestId'); + $code_coverage = m::mock('\\PHP_CodeCoverage'); + $code_coverage->shouldReceive('append')->with(m::mustBe(array()), $test_case)->once(); + $result = $this->getTestResult($test_case, 1, true); - $result->shouldReceive('getCodeCoverage')->once()->andReturn(m::mock('\\PHP_CodeCoverage')); + $result->shouldReceive('getCodeCoverage')->once()->andReturn($code_coverage); $test_id = $test_case->getTestId(); $this->assertEmpty($test_id); diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index ab58b80..39d9640 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -126,6 +126,7 @@ public function getBrowserAliases() 'browserName' => 'chrome', 'desiredCapabilities' => array('version' => 28), + 'baseUrl' => 'http://www.google.com', ), /*'browserstack' => array( 'type' => 'browserstack', diff --git a/tests/aik099/PHPUnit/Integration/DataProviderTest.php b/tests/aik099/PHPUnit/Integration/DataProviderTest.php index 18c98ec..c8891cc 100644 --- a/tests/aik099/PHPUnit/Integration/DataProviderTest.php +++ b/tests/aik099/PHPUnit/Integration/DataProviderTest.php @@ -17,6 +17,16 @@ class DataProviderTest extends BrowserTestCase { + /** + * Browser list to be used in tests. + * + * @var array + */ + public static $browsers = array( + array('alias' => 'saucelabs'), + // array('alias' => 'browserstack'), + ); + public function sampleDataProvider() { return array( @@ -45,4 +55,29 @@ protected function customMethod() return 5; } + /** + * Gets browser configuration aliases. + * + * Allows to decouple actual test server connection details from test cases. + * + * @return array + */ + public function getBrowserAliases() + { + return array( + 'saucelabs' => array( + 'type' => 'saucelabs', + 'api_username' => getenv('SAUCE_USERNAME'), + 'api_key' => getenv('SAUCE_ACCESS_KEY'), + + 'browserName' => 'chrome', + 'desiredCapabilities' => array('version' => 28), + 'baseUrl' => 'http://www.google.com', + ), + /*'browserstack' => array( + 'type' => 'browserstack', + ),*/ + ); + } + } From 147d25b30ff19a9a5648e5bd5e7637c761fafedd Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 17 Dec 2014 13:53:17 +0200 Subject: [PATCH 063/204] Adding external service logos to GitHub and ReadTheDocs Closes #26 --- README.md | 5 +++++ docs/assets/images/browserstack_logo.png | Bin 0 -> 11022 bytes docs/assets/images/saucelabs_logo.png | Bin 0 -> 1296 bytes docs/index.rst | 5 +++++ 4 files changed, 10 insertions(+) create mode 100644 docs/assets/images/browserstack_logo.png create mode 100644 docs/assets/images/saucelabs_logo.png diff --git a/README.md b/README.md index ad3594f..2db7956 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,11 @@ This library is an extension for [PHPUnit](sebastianbergmann/phpunit), that allo * http://phpunit-mink.readthedocs.org +## Service Integrations + +[![SauceLabs](docs/assets/images/saucelabs_logo.png)](https://saucelabs.com/) +[![BrowserStack](docs/assets/images/browserstack_logo.png)](http://www.browserstack.com/) + ## Installation using Composer Define the dependencies in your ```composer.json```: diff --git a/docs/assets/images/browserstack_logo.png b/docs/assets/images/browserstack_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0a64d379d737a2f2f385a6355d82a7d8da77dee9 GIT binary patch literal 11022 zcmV+pEAiBcP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z001C4NklUH#faPAcPVUAXGuX6~R@pEaK`aVp$Ot6$BI% zMO0L*fT%PD1ruz(Z==`{%nNk~X9_a?WOx6OS2xELcMu>0Npm5=xNE1!AW%$ess zbIx<-y+M>xh$4#r8^BQ$L=h!l6n{Ff|K4R(X;)k=#4m%$fs6nsPyj@+QN<>wM>!qE zf1Z3&T~VlLi&%0}Dr=T2T1mSM0tXTT0w4iG6kFA7*9^XQH{IA_ssTd*v{4gB@kc<1-`d6nwg9R0mxwPPj# zSfhrH;@=^k)L7wJJ11PSm9zsiWl*;c%Lsdcm_)IUAomQ(Sqh4i36Er8k;oz^$5t`i zafbcQ&kAAfKf0S2OlFdAjoLbje~o;B-RoSdW>Tpc$(iJog@zF81HkU!HO=DnEGpmy ztx=YVPhc2D(X$@Jc-0)0u{G>dvBjKrqe`_hsL3Xl55}nmJ^_#vwRjYlMLzGwMeYw~ zGjV1JCMbuslwiKiD`qvjpGYNt9qy3^oT*J|a2tKH7?K$lfd)I(P?pH;NaKD?FcF9~ z1rXx)s*KZlgEwsXFh_Oe9ANuJjUL4%$miR#wEgV|xr`JLP4Ye+NDSZF6u5$Eee*7q z`H!;llmiXm6vA4hXc#O55hxJK@rXxM;FT>Y%*%PE%1pB# zMf$?1-J|$J@`aCWYkl^wjMav925G;JwyRXmTK|aThUKrRECUankajjT=^13@nFd8Z zBg*ZH;-eG+STIUpbxB;JPN`->5BD^l9AZ;3HqnQ%wsxjL2@noKookbASL40-`{` z2Y#0hLxC>44^tKNPD#=NEgaw}bF8lkYXCSFf2KCKIh#y}zvpXDiweO&IkPp8KQhp* zAGn+l@Z=hEuVFX1Jqr@_x*HN5G+mZI$64QJTc#>RTgdf&K5G3xInEcErMl9mBTegaTYb3igRerUZr_A6F)pU0e@zkUkCI5 z@Bs<9kV*>*qU|i>^NC$E-Qy={yoy_p>Vw3};ghDg=I_>K&6^0PkB7{*a6*!jlaKn zbvs&{+uIyOQT~7Rd^F@2PVU5dD@Wc}{UG44ttk%$qdH#oArw*x9PQD5=RE8ptA;T3?az($# zXY{1Yq@1+=d~xUJYICf9?@d7n^Sr8ayP_y8%i8P-xxM=K?LYX>OuNk+*ZsVE+nI_| zzt79@ygfd#N6-AR<0oWy@A-eYC$2W%xmKsk?UkR9m?Dbd%JR}3-)-IW*$30-y!6)_ zZ|gX@xv75biY1v{yWKe9uK$+z^?BE>TAE)_IO&1M{~hv))h9ra03kpWM1({_Od7=+ zizJ{xF#<-V5*llj(!*fVAxb(M!fZB0{(fia;##LC4JqNW!_aMbFsKQGjzeCbtZoXc zk|iXXLNuWXw|ZHOHSXT2 zGyZJkd++U+*Q{K2#mLc9r$3$3vv1`6tgk)0ZR@5LOJ05csYg=Nv-;$plT;n8P4B$^ z(pBUB`rjiT%d#n{>2dLi|K_qQH&;R=`9&0D1QN)4EE@q!AXCsVNUh>MjV?(HBbMuY zp~VtYR#vub*-}bj{`~nCvk5{Trlk%9iDQroLr4Y;;F35=Lade007Xbmgf{A}K(lC)^S?AW-3a5&i7+z=sOC>RKbLKLW0 zt5<6@08m20l7_6v?n6v9O(jrFa`WxkEgv)eqjgmI^){$6F*$BxU~3$ z5Du%<>VV(pXldejUXmoQ#|=PrdIQ6-ordfvFFo1b=2WRviOFd_di`MupzPF%nyN}l zX+mO3@B9Imxx6;k)rg{ynvsPu^T$$4$1w`PQ(zes4nW978BhoqIh3NM6>1~TvVKMG zd>cXt!!Sun=k^WAgsNpC#wLLp_eNeC5)jg206{?t03!ep06;)x5^lYmU=3p|by{;H zh)+x*L=l9rR;!JRPmVNxyn5NDPgYY(7rgd&o3Nu|HHFwaq$4~{^Esuc7Bf;X7tt9KRol<$ZgM5ls)z6 zWQ33?3eUc>tY`0nNc+ln7Jap0Eg@vc@T;Dj|GJ_mOJASAXV$7M8G&a+HrcJ~iAY$ud*JYQCF;@;cF z8H~oH-p4-E*I7LIs|6|NTqFKmvhYdbv6)qdcpRc&1Wiv{G`R#2z6C`movT%j^?}VX(HU$|nH>1ds|- z%u?(?NCJrDuZnniS~w_#bZ%&^w6d;9huY%rQSy{k;mymK2kG+N#0G1rH~!IGk5F;-ij`~etYy}|fPH(p%$ z?32Ssj(&9Z{PfIhr=xlMH(zdAzq+xZX4#s}@d-)41UV-sPrSy}=D2t2%t6COu`IiH z_qGq-d*i`7$1hv+<$%E>E;woRwP){{cuiSJ+5AOs-!yU3C6--;f06wZgfv94$hy-8 zXTu(eI1(9CNcNgIIx3m3y>(jM?ytfwhuUI0pMMAeA!?_)VZ!~8d*x$>W^fz`QQ?o+Dh4V*tzQNN{;s8}4nkgx%Y>mYg`M5Cvl_3PM9|wcFj!FzkJg%)0NPS-%DV zYK_rsiBC-a=8I43>#F+?8s4RAj;zQrv2lcuh0i_V^Lq3;eb??i@4Eldl(fu>vXYg{ z7PU0ipRKBR>Dd{JmaZLh-7TN2d7lDlX>K@Ge7vA=C;$|nJZd&uHCnwjHme@mOQ_4_Rw6OvN3I^9#xznR~Eu%gKOf7&s7+T>6uxa!?EuD|6U z-E(^bz~0^4KX~^Ivn57vFg-kDUcW)Z+MSNID;DqCzNMkA=CuX0UtRi9WJS~JbTKhD zwMP5N+U2fx#}y;TSZ#K_!N76cv{}zLHP&zaa?`GDUw7-#JGWPUx7^-o8C`RF=5=1> z(=xg|vv5gcL+y=M_3M*g`1Fg5I}V+xD1G_aCwuhFUAFcswOSKt96oBSB1@Y-T~l=Y zP=tJvB)&9nx}&A(?d6~S<=UGfrxg?qP0Q%=(BywCTJYqWO*=cZFiI)L7y!yki|(Fq zwcFMH{>K}y8aw{dF&{Q?0G(FxSXssE)s^M7tzTzqCkZn6WJnNPlW!Utu6gU5c@G%E zwI+KKLg#996k#0pqgGc<{xE6c%x5$CeBTeByNWe@0ss&Ivs&UMMdj0=7>0rb06@v* zkWZ)6pRKAq@bhkr5Tz7htkvpcZE+04y4#$M^|gt~shwW{S(2QN=F!*OFk|k*jznbZ zm!FoG7R6X?TAksAH&>cW766D(OioNredNBs+3X32_U$e?c{I0oes1sl{d;!EvRr)f zNI~JyP$*b&y4Yl~#Kk8B1HOu~Vz1Y2G@4HyJLva$F~js4TEMbgL)}?Q2*WT4;W&FD z05A+YWW-;VtlD_0_&6aX;%{VGUjN}cEU%JfdB)s@gNBU+0KMM$S|7x79BaT z_sD@g{RR#@Hz^1U;czhEzh}yfJMWvuvTS6It+u!&t2b`hwEp0}-Q}f4TfSKT!Tax9 zVzen~nSJ{YzG>p5yn=xpCJFex7-L0|f1|90L)YGT^VsYD*1^08y7$Zz*RE3Jb0vU% zKkeB4!?u4+exQSS5nO-E9lN$~t*R_*YN$)g=o0Bwq&Z=d>jyxL~+2t;Q)}Do@KGx94$>O$4#Gdd;WmI=^0%! zv%B{z9M-FE|6hZrs`AS6GK;L4 zaL9J%%zYqYZRO%aVz3awX@A7)w6=lU|t13<&J$UTMzK>VG_rtee&X~J!{DeC@ z5~B_u(SaVl^50tiS?9pr=k=T_I=cOvFXQ9mJ2H|Jhxa1{S6+SX@8{+9ch`xcfPY!O zFh&NWdGD_8=S;u9slMi=w?4QC^Ufz9pPYepDk>?6V}Jmtsn{c&wZ|A+)cjrSoLgg8 z=vB6W;BW^7o#MIsuA7Dp9dhJ{t*1+h+PppmA%i_JdCZ9o!X5W@ZY(W6KKJqaV&mfLYtOEF z_w{FAe&^RBq2D+7icy`J2LK*d8_RJNAUQ4by!)r5Wl&03j&rm$0l>haBdxJ<3Q^8h zl}nP;+*t2(yYxA|MqYj0PdmR0_cM!C*ufKlRu>q9{a^1I%EaSM!|8+0s;1 zUixbs4j_tRzrtY`v5(PYE+`yYP&o9aiIbWd>o%?bVC~8!uRcF3E4xSUPQ1S$jvd;! zYx|a}ic*iq)zZ`u3FS`3jjjs_vH{pkpU1o z=TIOiC9QkUyrT#Aih@v4R@_)$8wdpA6OxisGh%J_h?ZMfe#+6(EQvzT-UUgi=aiaZ zS6i7PdmPSZP~i6-E#?{D54J_l-0Ed%QA|h zMAj^h;~AE*#n}^*Qhzgigftpm=a!=f_ZFWxI`ZmklT$O!8%siB%9O|EI33MvRxa83 z{pO31PnM)t=Fj}}qvd9EOmsW)@MkokDF%$@3hG8+!F&GQr5Q7KXzCBU@woj3>0l5XP7gqI9aMBZSEBGI68XEK8E2$c^1?%Tt zS!T1xM`8(#na;A}c_6<{_P^e^ZsEcutJi35x&59Cp5Lcn;Ocjm_5yYnLy1 z{cm?ndTjOrn?0eU{rHjnp-|}83PMb*tF5ig+4}oC6rVV9ru@{PVWT324WGxAnvu2e z?bRl8%)~qYx#PR9)_=Hc(6EtL|2A0sqg^c)P2M2hj!8fSga82um}rSS$Up9DA^%uX zoz?ww)!gl6_a3Wzx52&NC)A0GUyyvRKy{6C-{IO7+e+`VB=%M zLsDF(HN@bxumfx)AOQdsz1Y-5i`}8-*SeqK^_U+k$F=MgB77jTlH0=Ct^X)f`n0)J)(M(uAr|)R`u>jwTUvCKVZd%r>|`+7Sy%>uy}P#=O@@c2Khv3c0N`wGQK|S20XZi( zFBFvb@7eMDr!1H=ZT7UuexLVT1|tY|d!or40|4e2>m#$~^StVD$hxeJxme!`mNF9aa_;EMfx?t|KSet$EtIr{X`W6fd z1_Rr+Ze05Mf|ka5lO^VcTkg2{SVoPxE-%0T58rKGv|#p~_f0#mg0gwzy015_PfSi8 zF?w7_!a*q!giz1PkX96Yj|D+P$L|Ac_JZB%-zq9r2gjCOxq9wbzy`dT!prrI#ij7zV0) z_0u-}>_6aQ%xZ)YAV2}^OQKfJd;dmxQ=4wz&^Ry?&MO9lMnYsj6eEtoY8?~*i=%=7 zVHGXyp5hxFcBgy{@=sJfGEv>bruYOvhzf1kl#Syqu^Wm~5)K7Jp`bx;tg0wGdF)`P z@PgB5bRM@$6vOvFJnO1!ZaBBaK@>y5fGo?uj}i3-N&3x$2U?8w}*S3>K560T; zO-=PeC@hHKl+=uAv*vfM7xgO~c3{s=UafYtHs=)#j3megqbW11TSZw(d_t1j)z+(1 ziK$?~kiSowvTpS|qA1LN^5Jedy;zQ`JzM2;Gza{?F5P0gwe!`ta#}94Zv@RI% zKQrTjjI8W%ICS<*xgdmN)A!K9+|Y{wU-X; z*)?Fui1dsu9M8L5ZAHfqf4_AT0L)$RX4jl^8>oHy5B&YG*sDRaCtqEep$b`49HE>DKqvtq zfFwW?gLn-|#GwMgUvN02J;H>l1+KtqxH6N3Wl$&}3UZLixD{dU5_JuPHCi2^lvk-@ zRJNE{TgNyFA$o%;IW>LMnCq^*>Q@zj<9V%4ugLOwTL90kyafZ_c>j}kUSCjoy2Rsl zH8#{53?`$=JT(8R2d6*Xxvm8O0|sC5*~f`I$7^-EzWoPvwD;{lc-Qu=EXUd76Ng+e zy7MKEKlOrMZ`ieMtJB%MbNd#eCy5!d4gmr+CVGX~1S!KWbZHkXXF+JiK`G2< zo6X~Lv4$l95im;wwT%4=E`RF*2Jln{+p_xm`{@AHO&0RT{Iw4EzX z=b^l`sHVEo@An#w=B(_T^vvuFOFT{oAp{UuVyqnj6CtF%%@Gk)FSwP)>1e4aD{-|u z6h$!@Oc`0(X_*(!tJ<8crA5bF?QIC7q?Gi$euK^%r`y#oNg`0HH<~mW?H|=otIwQn zZ*$19Y%rJ-lT)*EdR?&OfBMwP*5*cyR@W=9pXwK3xuUGNwB&>=Nr}m6g@Z>Ri~!(F zd1*u4*`9g*Vyw2#n!u5Rd+Tee8J0~=&+6N6(0P;9?rh~a{`cC7+tu!Ix0@|ili6}< z^3gzpbbKmM;@jIEI9i9*EY@-zAuq+iQK}0QHVl5A3F?u^AV8EuR86T)RFDsaC=&)* zQ6x2r$MxgIFAi1%D%l$b?D?l?h`|sj^~qeG^%`p7=#75x|%V zZ9rtM?{iGtps3xWfJ^>RkkYhUDt-m?3N|E2&VYEfU95M@?LiU{siXj)h-gA7#Tu9(Ygm$0`APkfMW`VaLwH@nIaZGP)=>@DVYT_vVW90h{5k)tM zZlDArTW$~oybEy{=&xijR0I=>+OrP9Z#sB~S07*qo IM6N<$f-0VJo&W#< literal 0 HcmV?d00001 diff --git a/docs/assets/images/saucelabs_logo.png b/docs/assets/images/saucelabs_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0babcc0769168fcc5ad379f014ac6f6e32c8e2e4 GIT binary patch literal 1296 zcmV+r1@HQaP)!qB(fGg73SN%!301!QS$*}@)v5Rl zP&|(7lR>TJ%hbf@fvQU|=KLg3bx5r2Bv2|&#S%r&QJK9{K&6VQ&6Mua9P&L><4HAe zo8)ls7XELDhCv$g!~*Dp;C2AG1wl~Q_evH)G5Wq=_3xmRdr_w4OZ#j?HIruN8iQ@U zgy$sWjAk#UGV~qKAZ><~X1t$e(VnTuq((4+gW`@1zR zMdd$0r5XUCN>1w74OM}+0A(b$sNS>83FX6)8-+5-SWB0ilxsI?zOwKV<|=-P14=XT zl`+<&*K%X3WxNwbySku^$HIcT2f?V!9b!jSP~FA&9%=!oK>AOihU<0GG@VEhcDn$eY@u2%iKo`_QGE|Uhzkphy zrAvt&{VIJcKaK?U8H(>i9GW7;8wZq1J(WKF9!ipm!X#+c79XK_a-qGVyZcJj1+s__ z`{~noYaBbFN;D$wWIvJ5P?ATys%F_iEka+7!(H&hn$$l;MifEmNKGEeq#U++2UKpZ zv<9i%P|K@NKa?Gzx+sDIf#hndj|;8Ighg0T(En((N;8Xph?MugprpT*o}R^iPPGu6 zLffL-0m|MEis%TX#)?vk^D}+zJ^vkQ@~A%7RAFd@Vxy6gu(Tys9Zq9}LQT0&uqQ&H z5)Zb58XCthpkmwd5vo!Fkx~=auBkqPriWM^tz4~vUrB-$-5v@8#IgR}P}{ZKkE!Wj zLOnB(pirhSwlt{s48lnjPPAcE2t~y-f`^_V%N9i%p~M(bCGFyFDB7_`go37Lr7HHr z-7}W43`J; z-V9GFJ+!~l35DxK3u|qMP@75EozjAWwH#Z?}Y zZm1629F2nrHNvaLSirJA?x6xV)XZ0A+F!akmP4Co=zrWWCXKa%LcnQY32Ro)^unh& z)r$)o=GuZ1kyd41?rzxI7xL;+skR_`Xt*7q9`I$lGK$QCN`WD?76a~GRxJF+_#cNC zfWpH#+{+k~BKZW>;&f7gS@HID{{g{F9@Zva&M05PbJAP$LSyu6UM+A z=4m{8rJjD;goiz1Nd_;TrG*w-AAppD`l3~AKfm<&IexbIzW&sP+9ns9`IIL1@ck>b zOG#*=Cx8MfU^)SmlHbF6cmgO;8%YT;oB#^+Td1$T`syEo3#PgZbl#l+0000 Date: Wed, 17 Dec 2014 14:08:01 +0200 Subject: [PATCH 064/204] Adding links to external service providers to docs --- docs/index.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 6570c13..94d1e42 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -19,8 +19,13 @@ Each mentioned above features is described in more detail below. Service Integrations -------------------- -.. image:: assets/images/saucelabs_logo.png -.. image:: assets/images/browserstack_logo.png +|SauceLabs|_ |BrowserStack|_ + +.. |SauceLabs| image:: /assets/images/saucelabs_logo.png +.. _SauceLabs: https://saucelabs.com/ + +.. |BrowserStack| image:: /assets/images/browserstack_logo.png +.. _BrowserStack: http://www.browserstack.com/ .. _`Mink`: https://github.com/Behat/Mink From 1b99ebc5dd3f100bb033e114496053ea37262ef6 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 17 Dec 2014 14:08:16 +0200 Subject: [PATCH 065/204] Updating dependencies --- composer.lock | 452 ++++++++++++++++++++++++-------------------------- 1 file changed, 217 insertions(+), 235 deletions(-) diff --git a/composer.lock b/composer.lock index 55d6bc2..8f71e10 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "547eead4779920ff7fe59e1f87c8d3dc", + "hash": "1923bc8aba01c2a37529ca4cf07dc902", "packages": [ { "name": "behat/mink", @@ -12,12 +12,12 @@ "source": { "type": "git", "url": "https://github.com/Behat/Mink.git", - "reference": "b887dadf216cc780c95536e6bdbb50011b638e88" + "reference": "d99b94af22d34b12d4417512538f13890c7fa5be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Mink/zipball/b887dadf216cc780c95536e6bdbb50011b638e88", - "reference": "b887dadf216cc780c95536e6bdbb50011b638e88", + "url": "https://api.github.com/repos/Behat/Mink/zipball/d99b94af22d34b12d4417512538f13890c7fa5be", + "reference": "d99b94af22d34b12d4417512538f13890c7fa5be", "shasum": "" }, "require": { @@ -59,7 +59,7 @@ "testing", "web" ], - "time": "2014-07-13 10:06:32" + "time": "2014-10-27 11:35:27" }, { "name": "behat/mink-selenium2-driver", @@ -67,12 +67,12 @@ "source": { "type": "git", "url": "https://github.com/Behat/MinkSelenium2Driver.git", - "reference": "fef36e8cc6793d072deb9645935c800a58923b92" + "reference": "8018fee80bf6573f909ece3e0dfc07d0eb352210" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/MinkSelenium2Driver/zipball/fef36e8cc6793d072deb9645935c800a58923b92", - "reference": "fef36e8cc6793d072deb9645935c800a58923b92", + "url": "https://api.github.com/repos/Behat/MinkSelenium2Driver/zipball/8018fee80bf6573f909ece3e0dfc07d0eb352210", + "reference": "8018fee80bf6573f909ece3e0dfc07d0eb352210", "shasum": "" }, "require": { @@ -117,86 +117,28 @@ "testing", "webdriver" ], - "time": "2014-07-13 09:59:06" + "time": "2014-09-29 13:12:12" }, { - "name": "instaclick/php-webdriver", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/instaclick/php-webdriver.git", - "reference": "3cf130283b054b50119f887e11b9b5a648d785a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/3cf130283b054b50119f887e11b9b5a648d785a9", - "reference": "3cf130283b054b50119f887e11b9b5a648d785a9", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=5.3.2" - }, - "require-dev": { - "satooshi/php-coveralls": "dev-master" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "WebDriver": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Justin Bishop", - "email": "jubishop@gmail.com", - "role": "Developer" - }, - { - "name": "Anthon Pang", - "email": "apang@softwaredevelopment.ca", - "role": "Fork Maintainer" - } - ], - "description": "PHP WebDriver for Selenium 2", - "homepage": "http://instaclick.com/", - "keywords": [ - "browser", - "selenium", - "webdriver", - "webtest" - ], - "time": "2014-05-08 04:19:19" - }, - { - "name": "ocramius/instantiator", - "version": "1.0.0", + "name": "doctrine/instantiator", + "version": "1.0.4", "source": { "type": "git", - "url": "https://github.com/Ocramius/Instantiator.git", - "reference": "cc754c2289ffd4483c319f6ed6ee88ce21676f64" + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Ocramius/Instantiator/zipball/cc754c2289ffd4483c319f6ed6ee88ce21676f64", - "reference": "cc754c2289ffd4483c319f6ed6ee88ce21676f64", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", "shasum": "" }, "require": { - "ocramius/lazy-map": "1.0.*", - "php": "~5.3" + "php": ">=5.3,<8.0-DEV" }, "require-dev": { "athletic/athletic": "~0.1.8", + "ext-pdo": "*", "ext-phar": "*", "phpunit/phpunit": "~4.0", "squizlabs/php_codesniffer": "2.0.*@ALPHA" @@ -204,12 +146,12 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { "psr-0": { - "Instantiator\\": "src" + "Doctrine\\Instantiator\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -220,101 +162,100 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/", - "role": "Developer" + "homepage": "http://ocramius.github.com/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/Ocramius/Instantiator", + "homepage": "https://github.com/doctrine/instantiator", "keywords": [ "constructor", "instantiate" ], - "time": "2014-06-15 11:44:46" + "time": "2014-10-13 12:58:55" }, { - "name": "ocramius/lazy-map", - "version": "1.0.0", + "name": "instaclick/php-webdriver", + "version": "1.4.1", "source": { "type": "git", - "url": "https://github.com/Ocramius/LazyMap.git", - "reference": "7fe3d347f5e618bcea7d39345ff83f3651d8b752" + "url": "https://github.com/instaclick/php-webdriver.git", + "reference": "a57b2bcd9467e217134a2248b261b8b3a90ccea0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Ocramius/LazyMap/zipball/7fe3d347f5e618bcea7d39345ff83f3651d8b752", - "reference": "7fe3d347f5e618bcea7d39345ff83f3651d8b752", + "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/a57b2bcd9467e217134a2248b261b8b3a90ccea0", + "reference": "a57b2bcd9467e217134a2248b261b8b3a90ccea0", "shasum": "" }, "require": { - "php": ">=5.3.3" + "ext-curl": "*", + "php": ">=5.3.2" }, "require-dev": { - "athletic/athletic": "~0.1.6", - "phpmd/phpmd": "1.5.*", - "phpunit/phpunit": ">=3.7", - "satooshi/php-coveralls": "~0.6", - "squizlabs/php_codesniffer": "1.4.*" + "satooshi/php-coveralls": "dev-master" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.4.x-dev" } }, "autoload": { "psr-0": { - "LazyMap\\": "src" + "WebDriver": "lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "Apache-2.0" ], "authors": [ { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/", + "name": "Justin Bishop", + "email": "jubishop@gmail.com", "role": "Developer" + }, + { + "name": "Anthon Pang", + "email": "apang@softwaredevelopment.ca", + "role": "Fork Maintainer" } ], - "description": "A library that provides lazy instantiation logic for a map of objects", - "homepage": "https://github.com/Ocramius/LazyMap", + "description": "PHP WebDriver for Selenium 2", + "homepage": "http://instaclick.com/", "keywords": [ - "lazy", - "lazy instantiation", - "lazy loading", - "map", - "service location" + "browser", + "selenium", + "webdriver", + "webtest" ], - "time": "2013-11-09 22:30:54" + "time": "2014-05-12 21:03:05" }, { "name": "phpunit/php-code-coverage", - "version": "2.0.10", + "version": "2.0.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6d196af48e8c100a3ae881940123e693da5a9217" + "reference": "0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6d196af48e8c100a3ae881940123e693da5a9217", - "reference": "6d196af48e8c100a3ae881940123e693da5a9217", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5", + "reference": "0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5", "shasum": "" }, "require": { "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3.1", - "phpunit/php-text-template": "~1.2.0", - "phpunit/php-token-stream": "~1.2.2", - "sebastian/environment": "~1.0.0", - "sebastian/version": "~1.0.3" + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "~1.0", + "sebastian/version": "~1.0" }, "require-dev": { "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4.0.14" + "phpunit/phpunit": "~4.1" }, "suggest": { "ext-dom": "*", @@ -353,7 +294,7 @@ "testing", "xunit" ], - "time": "2014-08-06 06:39:42" + "time": "2014-12-03 06:41:44" }, { "name": "phpunit/php-file-iterator", @@ -490,45 +431,44 @@ }, { "name": "phpunit/php-token-stream", - "version": "1.2.2", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32" + "reference": "f8d5d08c56de5cfd592b3340424a81733259a876" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/f8d5d08c56de5cfd592b3340424a81733259a876", + "reference": "f8d5d08c56de5cfd592b3340424a81733259a876", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=5.3.3" }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { "classmap": [ - "PHP/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], "description": "Wrapper around PHP's tokenizer extension.", @@ -536,20 +476,20 @@ "keywords": [ "tokenizer" ], - "time": "2014-03-03 05:10:30" + "time": "2014-08-31 06:12:13" }, { "name": "phpunit/phpunit", - "version": "4.2.0", + "version": "4.4.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "58db726aa45fe26bca93f692cb3d77e9a46b7830" + "reference": "bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/58db726aa45fe26bca93f692cb3d77e9a46b7830", - "reference": "58db726aa45fe26bca93f692cb3d77e9a46b7830", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0", + "reference": "bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0", "shasum": "" }, "require": { @@ -560,14 +500,15 @@ "ext-spl": "*", "php": ">=5.3.3", "phpunit/php-code-coverage": "~2.0", - "phpunit/php-file-iterator": "~1.3.1", + "phpunit/php-file-iterator": "~1.3.2", "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "~1.0.2", - "phpunit/phpunit-mock-objects": "~2.2", + "phpunit/phpunit-mock-objects": "~2.3", "sebastian/comparator": "~1.0", "sebastian/diff": "~1.1", - "sebastian/environment": "~1.0", + "sebastian/environment": "~1.1", "sebastian/exporter": "~1.0", + "sebastian/global-state": "~1.0", "sebastian/version": "~1.0", "symfony/yaml": "~2.0" }, @@ -580,7 +521,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2.x-dev" + "dev-master": "4.4.x-dev" } }, "autoload": { @@ -589,10 +530,6 @@ ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], "license": [ "BSD-3-Clause" ], @@ -604,35 +541,35 @@ } ], "description": "The PHP Unit Testing framework.", - "homepage": "http://www.phpunit.de/", + "homepage": "https://phpunit.de/", "keywords": [ "phpunit", "testing", "xunit" ], - "time": "2014-08-08 05:13:30" + "time": "2014-12-05 06:49:03" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.2.0", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "42e589e08bc86e3e9bdf20d385e948347788505b" + "reference": "c63d2367247365f688544f0d500af90a11a44c65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/42e589e08bc86e3e9bdf20d385e948347788505b", - "reference": "42e589e08bc86e3e9bdf20d385e948347788505b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65", + "reference": "c63d2367247365f688544f0d500af90a11a44c65", "shasum": "" }, "require": { - "ocramius/instantiator": "~1.0", + "doctrine/instantiator": "~1.0,>=1.0.1", "php": ">=5.3.3", "phpunit/php-text-template": "~1.2" }, "require-dev": { - "phpunit/phpunit": "4.2.*@dev" + "phpunit/phpunit": "~4.3" }, "suggest": { "ext-soap": "*" @@ -640,7 +577,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2.x-dev" + "dev-master": "2.3.x-dev" } }, "autoload": { @@ -649,9 +586,6 @@ ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -668,7 +602,7 @@ "mock", "xunit" ], - "time": "2014-08-02 13:50:58" + "time": "2014-10-03 05:12:11" }, { "name": "pimple/pimple", @@ -718,16 +652,16 @@ }, { "name": "sebastian/comparator", - "version": "1.0.0", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2" + "reference": "c484a80f97573ab934e37826dba0135a3301b26a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", - "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c484a80f97573ab934e37826dba0135a3301b26a", + "reference": "c484a80f97573ab934e37826dba0135a3301b26a", "shasum": "" }, "require": { @@ -741,7 +675,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -754,11 +688,6 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -770,6 +699,10 @@ { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", @@ -779,29 +712,32 @@ "compare", "equality" ], - "time": "2014-05-02 07:05:58" + "time": "2014-11-16 21:32:38" }, { "name": "sebastian/diff", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d" + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", - "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "1.2-dev" } }, "autoload": { @@ -814,14 +750,13 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - }, { "name": "Kore Nordmann", "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], "description": "Diff implementation", @@ -829,32 +764,32 @@ "keywords": [ "diff" ], - "time": "2013-08-03 16:46:33" + "time": "2014-08-15 10:29:00" }, { "name": "sebastian/environment", - "version": "1.0.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a" + "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/79517609ec01139cd7e9fded0dd7ce08c952ef6a", - "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7", + "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "4.0.*@dev" + "phpunit/phpunit": "~4.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -869,8 +804,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], "description": "Provides functionality to handle HHVM/PHP environments", @@ -880,27 +814,27 @@ "environment", "hhvm" ], - "time": "2014-02-18 16:17:19" + "time": "2014-10-25 08:00:45" }, { "name": "sebastian/exporter", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529" + "reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", - "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c7d59948d6e82818e1bdff7cadb6c34710eb7dc0", + "reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "4.0.*@dev" + "phpunit/phpunit": "~4.0" }, "type": "library", "extra": { @@ -918,11 +852,6 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -931,13 +860,17 @@ "name": "Volker Dusch", "email": "github@wallbash.com" }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], "description": "Provides the functionality to export PHP variables for visualization", @@ -946,7 +879,58 @@ "export", "exporter" ], - "time": "2014-02-16 08:26:31" + "time": "2014-09-10 00:51:36" + }, + { + "name": "sebastian/global-state", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2014-10-06 09:23:50" }, { "name": "sebastian/version", @@ -985,17 +969,17 @@ }, { "name": "symfony/css-selector", - "version": "v2.5.3", + "version": "v2.6.1", "target-dir": "Symfony/Component/CssSelector", "source": { "type": "git", "url": "https://github.com/symfony/CssSelector.git", - "reference": "e24b8215bf39a6a2ce0c262bc5b000724077afa9" + "reference": "93eb315b545b60a908271762fb4bfa1f9954b851" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/CssSelector/zipball/e24b8215bf39a6a2ce0c262bc5b000724077afa9", - "reference": "e24b8215bf39a6a2ce0c262bc5b000724077afa9", + "url": "https://api.github.com/repos/symfony/CssSelector/zipball/93eb315b545b60a908271762fb4bfa1f9954b851", + "reference": "93eb315b545b60a908271762fb4bfa1f9954b851", "shasum": "" }, "require": { @@ -1004,7 +988,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.6-dev" } }, "autoload": { @@ -1032,21 +1016,21 @@ ], "description": "Symfony CssSelector Component", "homepage": "http://symfony.com", - "time": "2014-07-09 09:05:48" + "time": "2014-12-02 20:19:20" }, { "name": "symfony/event-dispatcher", - "version": "v2.5.3", + "version": "v2.6.1", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "8faf5cc7e80fde74a650a36e60d32ce3c3e0457b" + "reference": "720fe9bca893df7ad1b4546649473b5afddf0216" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/8faf5cc7e80fde74a650a36e60d32ce3c3e0457b", - "reference": "8faf5cc7e80fde74a650a36e60d32ce3c3e0457b", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/720fe9bca893df7ad1b4546649473b5afddf0216", + "reference": "720fe9bca893df7ad1b4546649473b5afddf0216", "shasum": "" }, "require": { @@ -1055,7 +1039,8 @@ "require-dev": { "psr/log": "~1.0", "symfony/config": "~2.0", - "symfony/dependency-injection": "~2.0", + "symfony/dependency-injection": "~2.6", + "symfony/expression-language": "~2.6", "symfony/stopwatch": "~2.2" }, "suggest": { @@ -1065,7 +1050,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.6-dev" } }, "autoload": { @@ -1089,21 +1074,21 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "http://symfony.com", - "time": "2014-07-28 13:20:46" + "time": "2014-12-02 20:19:20" }, { "name": "symfony/yaml", - "version": "v2.5.3", + "version": "v2.6.1", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f" + "reference": "3346fc090a3eb6b53d408db2903b241af51dcb20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f", - "reference": "5a75366ae9ca8b4792cd0083e4ca4dff9fe96f1f", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/3346fc090a3eb6b53d408db2903b241af51dcb20", + "reference": "3346fc090a3eb6b53d408db2903b241af51dcb20", "shasum": "" }, "require": { @@ -1112,7 +1097,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev" + "dev-master": "2.6-dev" } }, "autoload": { @@ -1136,7 +1121,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2014-08-05 09:00:40" + "time": "2014-12-02 20:19:20" } ], "packages-dev": [ @@ -1146,12 +1131,12 @@ "source": { "type": "git", "url": "https://github.com/aik099/CodingStandard.git", - "reference": "bd65e0e95a59d54fb75b8d772eacdfa849bbcf19" + "reference": "97775a1ab890b080b52da3739e3c4c584315c215" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/bd65e0e95a59d54fb75b8d772eacdfa849bbcf19", - "reference": "bd65e0e95a59d54fb75b8d772eacdfa849bbcf19", + "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/97775a1ab890b080b52da3739e3c4c584315c215", + "reference": "97775a1ab890b080b52da3739e3c4c584315c215", "shasum": "" }, "require-dev": { @@ -1178,20 +1163,20 @@ "PHP_CodeSniffer", "codesniffer" ], - "time": "2014-08-06 08:15:06" + "time": "2014-12-07 22:16:34" }, { "name": "mockery/mockery", - "version": "0.9.1", + "version": "0.9.2", "source": { "type": "git", "url": "https://github.com/padraic/mockery.git", - "reference": "17f63ee40ed14a8afb7ba1f0ae15cc4491d719d1" + "reference": "95a4855380dc70176c51807c678fb3bd6198529a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/padraic/mockery/zipball/17f63ee40ed14a8afb7ba1f0ae15cc4491d719d1", - "reference": "17f63ee40ed14a8afb7ba1f0ae15cc4491d719d1", + "url": "https://api.github.com/repos/padraic/mockery/zipball/95a4855380dc70176c51807c678fb3bd6198529a", + "reference": "95a4855380dc70176c51807c678fb3bd6198529a", "shasum": "" }, "require": { @@ -1244,22 +1229,19 @@ "test double", "testing" ], - "time": "2014-05-02 12:16:45" + "time": "2014-09-03 10:11:10" } ], - "aliases": [ - - ], + "aliases": [], "minimum-stability": "stable", "stability-flags": { "behat/mink": 20, "behat/mink-selenium2-driver": 20, "aik099/coding-standard": 20 }, + "prefer-stable": false, "platform": { "php": ">=5.3.2" }, - "platform-dev": [ - - ] + "platform-dev": [] } From 63ecc21f9ca10fd1e0e55a7808f0b80ba132fc63 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 17 Dec 2014 15:33:54 +0200 Subject: [PATCH 066/204] Using higher quality BrowserStack logo --- docs/assets/images/browserstack_logo.png | Bin 11022 -> 19198 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/assets/images/browserstack_logo.png b/docs/assets/images/browserstack_logo.png index 0a64d379d737a2f2f385a6355d82a7d8da77dee9..0ac14742fb1c1fca795eee01e3d7c5d10f4dca02 100644 GIT binary patch delta 16597 zcmWk$by!qg6JL6P1r`BWIwTe8W@(U+4uw~`QKVzZOSg1)Nhz(;-3=lo4I)T)$9KPf z_t|~!x#!H8`Nhn}ym?4Qi=%*ILm-eDS^2>lh8#RVid{)gS_k!euhk>TU^-d6<(TW%pR^)P=SnYzBUUNUXs`SAyn8^Ws$;yxGo@ z-8?&KUZI;#@b4TMxg_9gcX*loefhtN&pVZGs}9<>vV1Q@Qf+7yj-{Wulb;>1APiMa zn(zQP`WRIx@qPf$FWee0JSoqyAwo_e?T`3hE!=bFOVli##7BN&s-!?LAPf*RlXS=? zB0iX~jj>uiORwc^8to#BD!Z6m4zEldR^gDewr3KP>)cW~VC6%yk5 z8g`=&HN=pdtimztYb)a68>6a6*Y|W@6@X>Bh6PqCa6pL}$S`nCZD21{UfxfSzzf=7 z)6wn4xO{}L{+FSl{VuHWl)S5!KKAZdGdK1jyuzBT;x zy{a|1VEswbTb+V0br{23O_-LOWN}Qm4pqis7c<&<)M3j9_R*Q##8k^ZG?9!OF0+gN zYx&Y}nbiwaXIe-~vH3uec4-A2ejf)D2`;$7PdVEl+9l&sqRHsvry8UHR*4!dj`>rs z=H}INoDL5BVoOE@%sj81=vjAADXn%`W*h1SDo26iX-MU+u-CS)tA`sS0?!oug89xa z!`2Dv!{{z}g4E+^5QI7S8XM;Uab4|?&%BR633UP|uMr)Ha2pJ_8;BwP2b!>h+LI+? zfv{IHb{gnZH9?#EfIl-DHJT-6R+khE+bmwwF&$Hd&RmeW&tf*W;i;v&;ucx`+*=it zR@UYtzGXmgGI6IKE#}r<*8Mnw0aMv1)P5Tw>4|QaKvHZAfe6P06_;)Q+X=8mm_!G} zJ)+!Ba-l4co=qG+{_TpeHU}90eRw=l?mJVwXM_V+rBq=)qQ}IawiR=Fs9D0VI5qa5*A4>R*G~kR#r=BYN*dVzUj#))V zdzW4JIan8{j6M&CtFqmNij^9!?ADAyGOGMcYl!dI*nG*yBrThaP@U(v@+qB&pvr%7 zr@XxBq@h_TuH7XuuJb z8YbOzeEVk7!kwpA&}rnLIx+9%FwBg>gK@FZ;V#SfrVo+U+cEcV7~LF}V9`CX3eieu z3k2F2(~5DG|FJ?MZz07TB)|S)Y(>%6uN~uj{~>#+k&4m7*@@giqe|-VVd)`8AETCA zF~q}mNJHoOhIs$T#GieX|E&L6#k+}@_)mo$Cm4P*-JKzx2Y)QB5qOs69;Csw-U~Ba zsgBd@E8J61n{eohpCwu}GfqyIt40yKk?sO1PpHn{{7DR4bHQKF@_k=CgjZhvf!ps+ z$IhUhFhJud*NZ)8bIMvg(IPDQHADS%m85Q_`(iiNYpF%*5%Wq-Zk{=pT@fXacC0f3}Bk91@E5>r?ltEhOMsA^V^qFL^ zq*Ukyv^Kj-k8PROEl5iE@YgwIwb3gMwBG-zXjBE-Qt?xQ8btKO1*?sy(r~KJnN6>; zj~_NXOe}iqsxJ+KJ=7>sg(U>ft~p78V_bek{e~;jP<`0TH>98b!qxP%6%z$fa)bqr z;xX@I&G#qdzS2cAd^}>Ks)mH*Z^V*z&+;KIGr7G(`*xOMTZaFXN>TTQOvK{RxhQdS zp!acP6+*}7OM03MF&j@-5Eb`E+fp@_a)jS)*W5P&VT6`O36oXrQq=7VY%s@Br{ zBP4nH!ODi-U8p0|M4Yf1iKDEecx;+=HB-+c{79MP%3LiZ8i>JzZyHe$Ub6j5pv5f1 z=2#()>kC@skiQ~@hS9qQYWsoEfQ^ip+0#*BOHX3gdwBU~@2;=teUDWw zJc@sBF)Qg;;`RQ~r>*Gesw@3)H)R3@XLWB+?owbjf4}&h#$u{mE{D1LFaNhpP|d)^ zrqIykKe;T4z4eK_1?eKN^X*@5TJOuXk1$4u)P8_dv9+=#wB50nv7Wx0ru7 z!PNLjtAp04@|4`*+mmLG11ZkTkfpUN=&%Ab+J@-YUmD{QLiGSZg9I_>4=r|te?pvW zlG!w$6GADlGdT-+Y#AN6bzYNVKm^HkAqtmyCuO-EjR1aL29`_?9G)1UK~GsGcUSDt z)o}BI{@AoyhuS-tHrS5bq^W_pbqBgk;cn)p|MbBxw1*5Cx}sj_RYhkJh+POQ+^-ic zaN(Fk`0)MLMS#+bP**jK@$6HL$9n6_l4+X~@~uar<6sNk0G@NVG%-M88MQB<^X6@L z?N}r+8)Tr_s8RRO&Mt2mDupnCSEoVX*gQE>v*$t#d_Sn$;-z8lrM&xs!&o5?ok1WY@u5_8s09ezVh58tZ&jMpS=kG)16*WB^9suVc?JJ5w(f_ zQz%1T(yiWqi98)#la{cgE-$K(G#HL*HA1x*&FvE& zA&pD#fjcfg5*XW`e{a@mRY;QH8Zlk`Fh^wU`cGcc)RfMD&KrLh+9GR6Sm={g{N`kN zR6~{*PCOZZhG%;?1n2O~5atU+z zufLHtff=QB4pYC2&BqVDfmrx8AGZkY^dFzv15JOlIyPl@jQt2*H{pD4-+nreFfjTA zMkG?8kt~WbI+4^+z?9_Wm9l~e(F;9>msX4F({r#oI?6hZ=mT)kkT^#zkZx{aU0u#C z;T?=TAAZ8Wo&mdiHgD_Z?Gk6V#QvV*betLlF!wZ8AGh;Glq7W-#_d7H4YR)}gobhs z0Y%!(#kOV}nY*u~6wRHK{=G}qomOZyqJuJ2BQQ3F{WTq_abmWl*{^km8KZd|le!KZ zrRb*jBLu0OuUlSEeH-2<40}DcrSPNe^gUXV-%tt-Fo7>+XVV8~&3AaV9-<;B z_A_5o=b)>xV`z&=mB4G+d&b3xt|OJhfk7rH)(N%=kAI!mWTslj`GD^#MPBG@e3Kjh z&k5{FDM{;PCAruTj@GLuztnRhyVWJ3w*^rQvAMV~_U*bZlPoGmo;V))Zx)zIzhQa| zk>6zH|K$;Ct)nG|y_JcW)v{KinsR|)?YZMMf0BYzWT~;5O%kh%Cf~i_3LgXdfeuG% zJ3%UU`xW#UXGc%uzp^Q7zpb5JiAT0gVVexXZtk(`uaC3%Q-N%e)ne2jxPfBJ>eXLN zQ{8%bKV*dWmzI}S&+q3YnXTj)7Um3}yR=JA2-vR|<@UdNmBalq5f@3MtBdO9Mio|f z2q;I$Lp$g3A3xF;CdtH;{c#on8pLUB%JJ&^gYr8AcpB|4=B2oU^<0HL58Ic%2k@j6 zQp-P2@A+0%r@6vSc#PVE<&}#3Z2dLVC(o!@2xOx@$KvqUJ{gFnAzIpk@VG+!ZFw}f zEo6yp4%@IjPEBnrbsq^;Al#%;>*dp5G~XKIKonV?gzvxvArAuTXhd~ynqa#L_c_$Wi!cR=qKR*zZy{K4tDrkI52uT~e=Im|46AI>hZPwVgt*w4b=DCmS z6$Ec9+XyoS+ai|4>K{K}>lNNTJouihu6CqCKUb$=b@S&@QF25D+zBz81;e@Zws&lT zvc`ipt|nVbAx6WsQn;4(shOUOv`0w_nnj3IqZ&LBW&&N!j#HqEEziu?#WbBxxy1zD zfsWvkVt@X?oq;RGj-x8naR`RR8p*jkVgG#O3I4cbY@fNp8s3$O!*8PeQ%tblj0=}W zW8h%N^ZrqZYfGvOxLYB9~Y-RM6$++jaD_a{tFc{Hg*|r`d+1KV{0#G?7$_b zBpMd;cv8S&r)QYGk3ekqF6_>dwO`e@Ka>|0k&c*^(uvvk4-HF*ZPX4|!8rBX3Q)(j zn{`}GfB1}Fyr>e+e~$OY*n6YCvgz*)2}mlPw(p->0Cn?m99waNMR{fAui^3o&b0G( z*iFUcIxCN#da%cF!BcHr$~G~{3-%N4X2hf(mxasADTF$K1g*woQtMlNj?|;nECpV6 zz1A}l1|JJFeavbEhqS+~hrdt9wIVf|9IlTYw97=uA{Ap%(zY=iGf?j~RzR<2o$>7A zVzmu8^d*w-gqx5^*RdZ>N^di3`!9y2la8W4p_H#6WV6RMw1Nwucj20ZA|q@mh=ku| zP_QtWN#`Lgf^x8l*^%g>b}XMlqEZhur#-#t9ybmzE@CWr%x9>5{zi`HmwSzjwTs{X zxec{7v&o}VAZ!JceD53n`bZGPyojSrB8>!kk^SBK?%i}SGYb^d4C&Pu#A6kpffuHV zz6q6C<9>3CP#F%ksQc7bNpHx0_KUQLBamLIc7XxPhzba!SBl$n2NN*1|Ar@+Cx`hv zIj~h{P1CRkw%hD@umi~Hm9^Hy5g->`a}-%S_9BLbt~!dEdI(FlNms^&1Z{`_C|`-R zVziiz)${8$*T%T;{*JF*zRgSaS9g95;yGP>KjtW6xgr@`jOf7CIM2gSIbj|6+Xs7k zDT77(ob@=g^ ze4R2T>!4o0<|y2GiXNC>ojwk1PRuWdY6zoClPYve;7wWuEo=l>W`M_TluJ}*v7TGr zh2Mh{)V<~pel7{;IFo0`1M90+856%Q)-g)bUDdjdBA8LWVP|JIe$u*Qz^%B457upfjQPe<3VXVMfDw&5(CDA{^-x4Q0GVqt;_%#Q!XuRlak9Wm*F&c_3 z_@19~VyfnCZ8B0KEO@2KIgKKz?Ax%w`c_(5)_eSyCAceIb~9P`Hj^@T?5P~FY!HT# z8XV5~{O`&2ok7e7fXpZ^{wR3sUCVJBQ_t^PSzliwoUUlW#;}ViZO2DIVgx|!Q>nz4 z3=_f3MNUWnyE2i)r|;`3sXh`$y{LbcV7 zV*^vZ$#3kKrIsV2O6(tbRY`*3j!7~JOpZvQ93CAwTmdk47>^jc_>tlSLJTc~z)PaN zid{Pg$@caV)`_VlC9uk9H5IoT>+9A@lEz3qVPf9Xr$E7h8d`xrE z`7hj5pzdyaF`pSSR_HM#AKV&RTU$jbaERitelLS zSkjWN#_UwkNKyB91dJ7S&-30b#-_^d1IN6Ia|>1E)0g?w$wSYdixDjO_wNSf?i;#>aHdO}cJw^0)*NQ+e5YH^uf}_9vdw!M$m--G>5!{)cPj5gU(Lo!gRxg^cFD9Q8 zSIUDh6gIO^gfL;Cne2!bCUyT`u9D*R?|T+Du`-KOGQ1hyZ%!7-CN=8@UPn3y2l0@L zABpjHEUnX<&iE;o=NFgf4|$)j=VF0dZ|@<5xub9vf|l~mP*Z7eR(WWMc7NwRQR`jT zN)81jb%UNRDO)6-CTWKg^~L`3XTzqQ$SNa`4f5O+CfrVq1{rv-KmnWC%JL=lvahu{ zLB0-|JaK#hG*iGwJ&)dz_YywMfRfe;q zAisXiR2o&Il%jh5Q*(if8k%=P09J4Z@5}8bY)w+9mPXw8f`XJm?P75r_pTyITx9O1 zCn57^OArcu$J(7~xzJMgux4k#4Auf48@MGBEEAvqrLy&5CyMLc_xt_x-J_tx#h}RY zon*qWQ-|X5o>h~_l()t{z`^(Ig?ePts0AKo4ZTVKk5QoMZz$Ism!8vcfXB)_G^{%! z;GvD(S)$!%=ZxZzpH>9c&AnPJw(8nAG2`{bJ&c4);ua?O5k->k*pQ|5+p=D))D%%Y zzc=@AAm%|tM6}#`boco&P1Lt9Ibpje=hA&~;^(icB|UyoiPTXkKvNfr#K|EytzSTs zxd~i5`V=7L_@$BxK|v8ZydTOIx!9a3_)ydQW#h}W0bxe*(>b}A{(#m)(=ktczi$@v zA(CgPR;iD_>Pn0RO(C-mjkV#vse^G6r=#l zF(g;pSxDs#n|?X~g9`^96O#DQ!xTm_5!YSzr%HWJi~8g$&;~oaSEUGLC$hZEQu44k zA!mBJ!CnM&9yUe^PxaKJJX>1ESJM-C8a37*25#AaLA=32%Nk8?GB!PU16GcL`rEL_ zxyiydJ^uG}dxtN)9@0yUqdrBGmT0pFKZ_q*IB3}Y{IeF|WlB`y?t}I_%b0Ke;NYap-u`TJeUAJYQSVwF_bzu&1R!-xoscrABaLB<6Q{J-!`?&{$#7x`Kl zOd{+p05E=_>t2HI-i%@1uP(i^9OU7UsG3m!M#(Syqz(U@u2;1VZ7yL{nVHk zli0q#Kb(~8drHdNZy{Z#+L{)73#|@!8E=iRRoO_NbH1p;Dagg#gxfQG7r|!d87MGl-K$C??=G9 zzeHQ<>JCk3Hah;b^01o>)Ix+vK7M$nyp~)81$c;xW z>$qVUpu*09z~dX{jaOkgPA$o~?~M8Q&dR4zTOQsI+$#hs-_K<(YL?_dG&z8n=z9E&+$&&LDiihbB zf$~Vjp$+4AU_z}i5*1or-66t12NjB@tp#I^v*mF(XEYw8TIL#kcO5QUfcjJNrb=xY z_Ck98Y_)liQ4q_aofB-tEO|U)45#&;1>IhBnbzgzTO~#aZ=K%GC*X6o@Z^rS+vvaf zw6K4DJbTczb?A0(PUUdh<))r3>e*7>Qh=AhwE1`JonzRjz3~gBA5z}CgE&;Nw2d<1 z(5utL*oSJr#Vc~oHrMG0Ahc$~NX*q_r4>0|cs)0nTsNNiNHoj~<^!j_?X_|CNOTz} zY^tY>VQVZL;Jgn62T%S>jc2|^ut7xsJ9!Qsls)|0{~K+3+e zptsJusrf%UL9ycTjD1P)3E7_%2v>Y>4Obf8PwUQp%Rw$j$6Nq{$cqUFKUwyWmBaoX z_9>$i6w)}2&mrLF&tHn(-c7kS67FXy+XK+HTZhM!p4?pT&-Q<_JimUa3(BtK>fPYs z_1yVZ34#Zs%<%q;1-lDokiXYIF0@KsY3j=}%VqLAj}i#o@0In_w$+ywky7`Y_s@8= zThxoSF)2Th(*(XDX&t@{Z+O1eO;#AsY~TK~Zb_c^rLd4Icl?-Y#m86H*mzt%82)QU z;LfLaX!zj#`kpq%InGXS@wn>p?lmKECUpd9`?{kj-OUiqW5SM&LpSK~j3GT+t{o~$ z)O7j_p6T80ynZW6Jr?x+oZzbe1=nJe@9^KxpDiunn8d&qSLDGt z=M+ZNQ=z>q375YPZiZo&pZ?O*4{W)VmVOmAaEt}Yu=qyRu}S)6_YQ;q)BP0xx(!;uZD7nFJhv(hAM=<|LU(k08a`n1nmC*? zM2*4(UFCHEzN$Oa?F-sVtmn>-KbSkuKX;xQ9U(nLH88oL;h&o?rKyYw@?3s$OXyZLzv8dI4qe?v1X@21E7T5M-8Du&%u zyDvr$7x~R+vJP|F&jQ;&E;l?ZyNZTXR>t%e+e#(a3A?RhivIqOyh)svtrk|l@QLK* zC^_Kn<~p}W7?z;M0+v(fMz%;eCYt&CU1L=i5|ii;odqKrl** zJ}FJiVJ$Y*u;HZtt)YuJA4%=9gmAhExH4L<@ zu6-W3Bpn|wKh&jmy(XzrrX{RR}04ZUt63{ zhh9rId)^f(g}({|*^%RX`Ij~^;fa+Q)Sn}5a8G5}V4!xJ0Seck3_}HFCg_i$zL`aF zT&%{@U7fej)2OxFUSKNcc0&nS;&l~F+6l_0@LbFXjqtu$K3Hj@h4-~Mgzs3jjO);_RESdm5mRx z?G2B&8oIiTcP_Jc>n)!6xrv)TTD9|agBE7|zHDEM!NR-jH!JkZ*L%77pv?g|4a;|g zGFw_MNnQm;q2f#Q9G>J8jAJjJr=g<0r4v&@T^n`-R$;`(I@>;E_rIYYCPMv9u!m zfMZ^JidJM9pHvqb&7~9(;|KsE5=I*ZLh%Wme495$px7K3+ zB@j)+>xxmp#`u&b2fR4rd*x*n#u#w{ZOb_f^$Wfn0BH=2TFeWx%oT4C1zR$tF;`<< zbZ>60FZnXXuB>H(Si(c#G9cU5)j4~m5PEqM z=wF_}qgav<-d`|aRZAaCpRGcl9&LWHcnws3Ex-1DtI)3%vz0-vVp_o5D-;{Y-tcq?Up@GlX?Q`n@!iFm zuFKZTaPjl)ZW}SToo~Mv`36*$?(=&c;Bo%g^A57I#>7VNm;6a`@Oh@&&})3?*w*5H z;t+EZ`t2di^lBBcd&GkMfz*}r#Ayzt+kDld*W*($-Cl>eGnx9L@8vU zvmA+EotBZWk#<=xFIf10GCvaK(8DEJ{)+MDJ2dUTwPh8uUvHBC`Vjc%U~IywTcB3& zO;WDVL^DAL(DB&vi{GwubFPS63zk|vRhh*TP<-CvYBX5`k$c-~Tw*Y~IDo55qKBgl zD*L8>t2%uXSg~z~ef={7oh;z&>aM|YlX-{X)sj;#1dH8LM&k1T+9+-?b1&^)q^l1yy zbcmF#Hn0)@sr!!{GxN{_VFxL|5^raYZ z1hhr?HhWwz(Q+{<$v8M%GPnD!KI~BhY?YpcIaB*QKwgE0LE_eHBk?9QBR-AVhh?Rn zs*68VyEXM_XzCLHMsO2-7CFu5aq30fTX8(aNhzsSbYgy8HwTr3;ek-i+Qyq(uebZl zjr%n^&;Q{mL{|SzPPNY#`EYPgmYghH?Qj_uZa?HSAwV!?Jtm{+#J+y~$zu0!Juu^S z(sSNanfg9sh$=LoEyq5*0MnEoOOtf^JwlAO?(f(OqsJRcAT0lbW1|6>Hk3eD#^>NS z)x;u-bl&diF^V*SscZjOdiI>pFF*r5W{dUE(_yPS-IbCy7H7}`{nq{PKYowpz;41+ z62cM}oobqkY^E*+S87VEMbU50G`-@;_c&Q|IrkV^jeaOQ%WAypU1ZV8>J-KKNM`T&4}s7D;`1J;Xf7o@WnxPd;Vp^LGhQGnGb77*3RJyN!d44 zfjzfl)y^V8jEosaa*$gmnq^F)?or)EcH_uhZR}yDsI3gn-&SWJ;G);ulhQbME4){U~>$O z%iou%#?m64lB9yV){kQmDJ-tv>kZk4@mN&Te|SF>^ct$AeyCb{1r}<-`jTd zx%VhAnuW53On;K5h3c0|J5lrNCWhhQ@D`hvM(aoRa`bY$s>W~Xuw>It>X2D(ZocOx z4Jfv?PQrRx2S%HYuCzp|toH&t6NwX`F+?_}*GI4PM5T_qQ@M5?R6yfYt@GIMeEb0S z^Y22)%MdQ${FUnTs-tlHU=bKJ{V%4R8$r`%A?$r(nH)Nw)o5q5zRSeYy!5h{?`WHc zV9Ry(LFL5|7;-sJ&{G#anFt4(u)&6(|GLM_2`jcmP*8HHuu!;-7O?S31FOVPY)u`l zz=vg8*x7}djUznig-?~WqQH=}E~!NBFkTD2%~SKx?teXWe)k=8%Lccb%tY&poT@>UFwR4#6#?gULj|bG5-A-yOTg+lx-Hzbzo@eQw~aQOvhRB4y}Fw9LV_ ztl>o1pyUmUSDP#TZ^8q4FTesGj5hKwR8xqeO^G1Q%+_XLH~d5p>AfxiEB5GorW^3- zhj~^dN&wSUu_;0$5x1=mcSFU#PpTB!715u+C8bJ%&Bl)bsWW-17(rAj$_94h)NtVA zKjlLEOj=_@n(m61w9$z#6Qd7Xh1w-BH7?OYir@wbQ@`4!`BlRhfnmo+!&2&GR@)3w zJH#u~%XQ()Bnm!}Obb4+@xT(;GpMs;_~>K3q>Os;?C@@$d73|bS`%F7=SvGThDs$XVwMr{#Zo>P<0R(Mqk%}_S* z_S?72novfsv_-CaoC?*ile5?Q^$F6ur7!g3k0Ed}XuMAQ(**7j34bwqE zqqpE&3%W!*9k_kRD41Hwm)`wjsoC$77vaKmFoiJ=8)Y_?DYJ|e90p7U!uD8!sut9{ z*V-E#RpVg=1qp4;iy+rv-GLIz{*mRKV1{2#@g^TBmF%AfN%F(T4=i$88T zK46jQN$v_4rMz=8TEc(|Kabbdo*1R>a0+Jue$pS4W^oGrHLQKIxSh)g%cH=0!$_Ej zzuHh~2F$i@M^=TrD@Ug|XGwxMeJc2AmDiFXJr^g>Z5|{tL&UOMXcvNZbOCcq5tMce zEC=o+&8l6I+`s8OnUFmw1u8T zDy!rO(qsy@G)m19l%~Ump1z@N+~&)bcX&%~Hp%w!~1e^LPZ+|;rz_`79;PVL*y zzewjw!WZr?u*J1>qCxqkW6d>kO;K|aw3Q`)q5k-OHNF%@4_NI_P#pv;&*WQRZ!eSFk6x#D1FE?iq|@pmu8E!*`WoH zlJ4}IJ+d$AFv1Jju`MX1v>b1c#S}z~X#!iwIU0AS^%^Wp%m_W0$MSu}3g^3;lM11k z7CdQE)4F+Xw;L660MwJPh{^{*ajN0$6=ULh~Dg|4h*F8ynD6wU0yIwK)$@&jJreJ?z?aD2J^dTpu$2BHho9 zMz(UUPl>pi&T8pmYJKu)eqOy--4%V_#f^3V(}uEWS5pEMugJs3@3IR#%?Lz$NCxO0 z8CjB-0?Ip>9V3m{Lh+VHy3DXot{2l&T$R~SJHb6-Cd5=XB+V1TN6>=#XO0W+rKCGw z$%@Z2!6~}G{YNuqO2fSCvbrS%ai@)&=94#kk1s&{j((7XCYU^bh%`f~Lpv+K8NXhg zJ{%ns0?C1ch1M^u$;v6(Lp44URhQ?kB7$Gvd3&g<&ys>T&w?>V_id$LTR}PAXn%~~ z-jVtg_o}PtnsZYJLUyo+z5BD}CYAf)Zzp*+(!Lj5$V>8}^1|6bb|LC#gR^F5Ll9pymmeD`QGjGd=nB59h<~&O5C# zQqaIlQq3lbpgU$2IxXoQ(QapQ420eX$=OMSf4u^L%cvnmq-D zC!o=(^ZIq0p5eO%J$?OMD! zbzV6hc8m~1<{(t^;h>%{$Hq2?8c)Hh_2Kt$1Q_keo#UI8Q42o9Yab(8TFOXj&&O2) zFs@pr_K)*QzL0DgyWD>f`0kc&Cy1X4EF@}+{qAr=c5qw&OtNKrQAH0iM{*5>mUZu6 ztmY0){=%6gi|J7drAu-tYkt}rvsToF7@Q(^0X*k7N% zz#C(#&g4IAIP8xL=Qam4{sn(9an^JNSjSuH&38W@+M#xTOodqHY@ull#L8**NC8}& z&3ENnZ$Ybn<>Fu-%WxKoLFIP&6j7%(TMr&xWTY~<-GTYs_SZwR0N~p4`Jc1AuA+kX zyZa!?$4O0qUbtWv)QCPcVQO})N=g2|X8`}j8>1h5$!eVkj`S3<`Q=S4;=X^gQXh_g zuC)L6Ml&F-*zDvN1y{4U5y+urQd~f8|L!AUzlW!E$G`wLC+OwunzO3d(9lu`PyIvx zjOp;zbN_AgB{iN7@HP}wR|sNp0@uP?B#aB$BGWqq9+Zwz96e6dd+s>ky9{mZQ1%6G zp^CK1ZVzrRgl6yp{bv$ctu9>MXx+S#$72_QU_$kx&mCq=R$lAOeYkoszB`Dm!r0r6 z8W)$1jEovbCQk9St4;+o&3ABMcR`a{_EPMA#LaGDKmqCJ$*%TGcVj~GN_WLe2Z+%_ zkc7c9mjXH;B*3n>+@{Sh#_eLHF(AuJ7hd++yWfAe+*o6}i27Ea-Etzf(hww)U72d% zaGmlYrK;iTd;M%x^XQtR*=gUo(EdW}hrc5tTOYN_m>nG-my^3?W!oZ$lx;GwjaGU1 zh5fZz0kzee%(k=4?^SI+uRT1hzZZWP3lOMkBPLW>zi(YK;7vdJTdSXCV|(3oreD{b zrM5+6!93o9V0%fL7KV+(Juw?~zB{vC{=os|b6QN0dNAL3&qt3rE^+@S(O10nwBc~& z)Dr&Zo*U;4qP1}nx%o9UP+AHT`}3>r9&yZY7eKgr4l8yuD9c_!{l@UD#KTnB8&YHN ztf0{xF+?o~c!`OceQP?jUK$FuWQ-RCJ2F1o9@~$;~=M9p*?KYbW?|<%i{|&>tT)e)ad6!US<)Ins#riG2VoNXQbl9JkJsmQAixKqCV9&qN z&7XabWfvE2L|{4F0BD~OV1P3Up_NkrfkS00r|1*V%I=${>vhWV0Vg+PTHre?rnE5V>AQWl-)_lDWf=DK7R&@{hCM0V z!!S0*vf8I6TGnRIlvA3Q>$;mXUoxi#7Ig; z)=dW;0u}XkLATc4+OHACrojYLkk26Er;I@P=u8@GIC2@btv7=8tF57+R+RPAh4v>J zNz=!{js7a($)7q*c#N3RfZV&?!H2$QhmzjokJo;g^w0wgZ;x^7Xol2bxfogr-sZ9z zr-a$V&Hfmg$NKoS{3jy09w&hl%4`qI3sax;UHk27j%46@fJ+{ zURI6=GOyFWTt5GD4t*}YNm$h0sO1P7wH#Nt)w8ZU=@ow#p&nZy1PBOi2{!uHx}rFx z<#o?<3>WJCdTUkM>RKz3(A?w>{cu!1;e72WzF3TTQ+47;*HC@i{gn)^Psa zHAnCgyWXktYLgB6SK#Y^+g6xp+UBc1=Jn8xw(96~-VT+ctdM|cjBb76CvT60i!CP= z{4RH2gW9<-ZPleLO>?LzJaQO zwJN-L{^fz!@^|zPp6>)~oa_MwY&N#L-)@2o?usGXp>(x$f7QY9Ftny6%L6T-?Gcz|Cl>! z!5gI&fg;-kgv~sJ!&;0En?Zk{ocyJ}eM<6MkOF~_l`(ZVzpj-mvS0#?2xD<1e?u4d zsM#>TZhgN?OKthh_Y5Al+te11#yWtX-xyty* zPPrU7aWlKoJBLdWuf|LqL27!KbJ_5Js%6edo9VH=8c-Xu#pU^75Q|(w)T2`d#5qTI zeCp~k@(T8v0&ZEAwkfl_A8ZjqYeb19YP-Kdw{agt=K|(^zdo|Rd|{lcR>I?SLJ9#o zR#zdQO|1r6;|9w!Uga`y`MQ>Z+Q#zon`B(=;`5oA*`O`Vvvc=mBDzK3(>UGH-_vX9 zZtk4%tosgoW@~2gyGaR^Fq>x#BD8Qy0NI z6RHC(vnhgShPf9`Cw2{wI7(l(419alEspIU*!0}5`wubqOZ|y1J}e0d7#}}z62&Tt zuz>A9aQ18WXBno?Lr2&_o<`i);Hmw-fmM2rK5zgm{{y9+I~ArTrnyS9Be3~-TqQ@8 z2J9pXX53Nn@vZVLTbdqMyLAqNB{B}lE0P_5N45|9=%TVA7Q z-vzYD&bqPH78q8WZPtMTV4oP(N?>_8Naz)rNd_zu;LOB?VJ;3z`t!@{2~R);5RQKA zI{O^TuPP7Th~fP=zz$VkD=9S8XlKtRh;1GoBNwOA6F+Jd7p|abVBq{CKSm#PU5>8r z-l%?D!Y5%>_hiT%mC@C?x|0C=?sRo|gePLzr>sl{v0lUtTQ$qX4;-Qg(657Cd)>iH z|2RfWOZG#_tADvZ!PQf-Nskr>sU~6ue)6 zaw&L8@QV7kU*#w>n<7F*K#j5e;==XueE<9~??*nGam)S(#m@=C4Gvs^of_u%bH|Sv zqeWnpY8vTdP4N@QkeY*lHTJ^Qy`Z>~&<}t&+C5De4F#vt{?t+=rRY-AirKHPSv<$B znhi?_>b5{`z+|TRCo+l{8fsFvz()@JJ(2tbj3r5)Pbb$MVrz^JDRFJuyt2#oKL*>*pI1h@m0#r1E`&+Rli{V8a9h3Cn-d7UNp+s% zAN-U(wYQB+68<#k^>_OBPfM|?iJ}`O(FTG6nRqs8!cg{tQ2Ar(zV`T_2^*<+HydKw zoX;Cli-LNCciZ_NNmXdk&SxsOBCRUS-{S>GT3d}kCpvz?bf9pBFuOl4B5dV&@|qGb zHdR^9R4nt5T-9!5Vot!CN+mxM89WvP_5>1itvPmm<3NO>S?RB0qFE2Q7q)*$!#)8T zIT8lD&`e8KQlFp?T8S;_-vm6hkJ*rdawGY}E5`_X3MOUld-yvM9ZoX&@!BtZVhkj3 zmbmHhy5=S5oW1I0*SIMt8hg$t%e%1*#J$lvzUu3#^8rrc%13ATgG~ z*J)r=UKJ)RHYI)PTj@yDXh%2?*ilmV%cgAd3DD(iF&zION)$=K)z!@}qx@q)3l48Y zpkU6Nu@<~&y1J6Z`ZW{PHrt|43aJ9w(6OYy5bC~E%(c*e#gZM!>$L(3sMO=nGKcAt z73mXI$q8+#TGeA`F=W^|qNFwP^6T?$Lol`ylpLu;_{%pfqC5HVJQKTte?8zNSi&G? znq_{&H`tmYrrKN633bM&j~xgeS?np7RrGTVE3>ijh_-(v2T`ogPWy=U*s*@y5^JRU zv%4VJtdGj|7w6LY@BG9lzu4Ijz23&fRTL4~rkfaY#&qPt-wcfzN{V#Ke%{wdI;Zwe z!!q)#Nry9cL#nF328BNbFr3ZIs6v*9e)aPdfK2j<%0y?Cy*us+F8w#5a{L&`pnYYW zyX^9xzN1$O>*KYt*wkjUx+lG|bnNBIZNwvMj)-{(`uEBY!pn=W)PG8A_G{k*c;fDd6f6>`gZ(PSDbPxZyHo|Erq^IIvg%{!hfKeXZP^_oft<<`G`fB9X zk0@okMz23>msgJL2B|6`&JFlGHGXL|255SWkB6k2!DvsRC&)15qdKc6BovpgGVnKQ z&RVBauJO;jo2v?IH%Lm7(%4Kb!a!Oro zOU_4aBb3Db1!#a^KYh_y1B*OBI>Mhr5=grKN~}w1@M23hP^03EB4IDxL!3R$ILO##X3Dd(i0L-jMiZ-5Cx;S$+%_F&Zk?4!mND=i{fUp>s&6{aao4J zsvzfRa!AWhBZ8hfd~S^VcEi8Wfk?{$Fx`^f@HSr$f9h-nOiqrnIkF)n)R6uFul-e- z%C22iY(4APzf9C3FTPEWqT|LVNZ!#F-XPON{OjHsSgaEmm@ML(u%u;R*N|u5z8Rl? zM2~(IwUQE2dxGcsqke5XRsv7Cq0R;V_}X8zbsZONs@7x#lROJWK60~?Ihd#p=wAo) z_RyPzLW_^Aal>MlXIMY+2`0;kVQ)$s>b7r2S^?z#BWFl8^&RB@x9~T|R3LpMR3Q@7 z&%nv=$hSG(wD+y8Y@9EG&gn)}*B(jE`fQ+S7*2A(8wN(0b!c-eH?iBse)XJlTjWFN zd7qbWI{vT`7|P^xIpd%x%mcVtN#)K6HLU;TBIeBH&Mrs>FgS3V(*& zeib(fzUjegm=FiXND^9CfTN)Q5rm6SWBFPFwLq)bMw8Y2o(d|3^J0OZ*t!F@xk&Cc z_AooTaSoal*;lv559n3nIPEL3Cc<~Q=p>LkNesxuDMv@ckQoR900014A<~|)A)X3MCMc5fv2#6cj~NRIGrgGzA3}K}E2D6b0!u2?TFC0`VOIe;M?jaEaD)zR4eVVl6#Xoh`ALHYi6%sKOn?DI zK~0I4P%Q;O;33fL2PKSomFn6Y{k>yTpc$(iJog@zF81HkU!HO=DnEGpmytx=YVPhc2D(X$@Jc-0)0u{G>}Q?bRI zcB4wQGN{QWmJi0M20j6h6t#F1mqkAB#zpQAW;1bS2qq|pwUl7K%`0X#yPrrUe;w|T z2Aru)X>c2TvKW#X7J&vk)linm?MUN(OfV6MH3bmj_Nt82d4o4>`7lRyP&_(SrAk8Nvx_OFc9hIIyM zzmB%6RL)xeh~$Rluc<5p51o*9HZ|!PWaXI#MLr|S?TX@~6aiQ;N?>(=NnD~%sb)eC z_cWdyVpB0T(TB0+Z@NUYSwG)^lNR8ZzERUhaRKrXUt9B|g^J(BCdZL-UM?|ko+csJ zUbTL;)|OpVNEgaw} zbF8lkYXCSFf2KCKIh#y}zvpXDiweO&IkPp8KQhp*AGn+l@Z=hEuVFX1Jqr@_x*HN5 zG+mZI$64QJTc#>RTgdf&K5G3xInEcErMl9Xm0WW!uANP0q$SV?WFL9r-7_J`MsXH3n~HO2&R(T?HxoZRIst!XoL>j?|L_3`xR6Q<3Zm^Sh+XJ(FypEz~^;4TASP397Iw6fAxGcq^rXwAoV5OYap&i1bF6;v zO+g6rysC4%q9`oO+UyCrz54d;Klsl~yUiQd{k(hInTk@s&&%<=JwCBV&-}6DCuDc; z`G2@4t~Td?n=e0;lA3<^l<5eef0=wj#bK$jk}=r;0}Wv+AfP1FqZeg?0UB1Qj93LB z`uP&3-A7VVBFqB-kH^!ycb_MomLKrsSFr4kxzmD0mt z(jiKJIvc`lHbwq^XX)ZvrzZ_5;j+WfZFn%K34@M9UZ1RP3agSOB$`A8DTp-^PZ<^3 zkt*g7JI8VfNh!vFU#rziq997*uVPRrsMYE?o?o|mS&TLA-l;SGY~*|I?U&cATz19C z(Nm{Cozt^#Qh6E=dd{mg{_>#S&9iR<>-}Qc7X| z{P`BM2|^yGr49s%V~`3%NCphxk~m31td-CJMMzDAHtMZFwo7Zy4oB1VH{Cw=`UxF> zEvHYNSi5qG5Dq0IrF{4GhMRAjWQq9`X*aHR=ax{n5D08}g{0htkGhSd`Y0}ueBP=5_v z2KmCFP-0R_*Y3F;EnU0kN|Ll_!R*+$gm5_6+T0K!Unm#|he8ynR;yQQGyqUqay%Fa zhv9#H`LWsSC$0=e!an%p4l}iCB5TNo3oW+SV9z|(adsOr=Z>=i6YB?aYmE5 zbM)zTyAZ~TB6mz}dz5g%C2D%o$nTVr}*dj!P86MJJB5I~^R)r=@3Qbm{iH zOu{2e5(R3BiA4xWqF7RNRBtc^{9cczy-$8&2lG1P+VK-VT(P*c_=FG+tJLa%-{)v) z;&@(?B(KK}Ky`Wp!?2x(>?kjPJ=xyoRH;;n$!R@${b329?9_>xs!B>}LSjnq`~jD_ zyf)U=h@z01k%cky$5KnjF$%y_U>Ot+K*&WIPzV?~l%k~-Y9r6Genswl8$t-fFiA=0 z_6^8{s%0X^CV?9FMqU~c5Yl1*K|u-tBLENpKtN>@ZoQmf4Pz{IT5}_Rh)+x*L=l9r zR;!JRPmVNxyn5NDPgYY(7rgd&o3Nu|HHFwaq$4~{^Esuc7Bf;X7tt9KRol<$ZgM5ls)z6WQ33?3eUc> ztY`0nNc+ln7Jap0Eg@uo$ndM4od3F_C`(_Tzh~FB)}{tWYcs+)Ha5;?PZ)94xO=8d z=T+*?{r_siM_+vQVfC5Qt~MvHQrqJb`xFd(@bS3`i76fDy!_mZjOxoU?9vau=y;QtFL`DChwrsEH!ut%Ns>yXE*x^@)ag&3N5Puv%2%JC_0x`T z2_Xm}K&VgtfCnC(Gid0@i%eWgQ^Vs^Zm+2-pEm3H)Qm0{)%iLEX97s2fS%$;>~@st zFknCefnIvKIxC}pJgbj*rc!0JQgWfh9w7+&u-WX(>=TD!u(qnoCjkQlkP1`GQtUuT z0*K_VigCMBnx^GOazV?%AaO11g(kG6cVzM|}uB#A9e^1TEDunp=Q~d&G89IzXUmdCnrz5#?|Jyck0YR!$z?zyLb1t z58iv@!8^wY4x>d@0oZ_SxMRaMQ`6UandE0U4(y;{S<^WM6t-a(*|e5 z9*H;-8B<91nm9TtnXkQdTHWri!Y+r}VmqII2mv8#r@LXo{g8X*V}@pM90*gD8bBsU z%MzY{BV3SU0L$t~aCuo9?rpY&-P^a8oH(iw1!F7S`zXkwm zjnQn0PfY&ii%;w8s{0Qb-lc1ftjIC3afFbC&pqMudh|Md*X}*e@mOQ_4_Rw6OvN3I^9#xznR~Eu%gKOf7&s7+T>6uxa!?EuD|6U z-E(^bz~0^4KX~^Ivn57vFg-kDUcW)Z+MSNID;DqCzNMkA=CuX0UtRi9WJS~JbTKi1 zHnm3k$=cFwp8{pH%5BBvF96b?)&Bm+8?PEW{?aiYHgEu)R`FO_#p~6T<+ZI}XKE)2GWcXj5L}aQ8XB&7>zjEG z7{awCdlEwDYIGD~9QLDDS55vfY2wUhGx>bq51+e=HGBd95CF4U;w44p)1VlChJpkD zK*{BhPp8wLt*Sim^KOg~r4(VT)#_tyaSX${+nkN{wTa28onHW1lAMm_(bwECWA4I^ zL}cripO%*v#aL}xo#BNySDH)~0EkaaPE1aHS|7x z79BaT_sD@g{RR#@Hz^1U;czhEzh}yfJMWvuvTS6It+u!&t2b`hwEp0KzTM@eMO(gD z|H1q3TVk{+X__23QsZo}-VE@fmrL;L4aL9J%%zYqYZRO%aVz3awX@A7)w6=lU|t13<&J$UTMzK>VG_rtee z&X~J!{DeC@5~B_u(SaVl^50tiS?9pr=k=T_I=cOvFXQ8X<2y2v6NmRB1Xo^t?eFL1 z^>^2aqJV!{zA#1xqj~SH@8?Xvzp1|FrMEt~2=mS-AD^6obt)<;h+}{NsHxZ^oVCXo zTh#nr?3`O;SLju?fZ%Wk1fAl!`>vaY4IOgihpneeirTzB1tEhyF?rC)ltIJC7{KTY ztS+6|9&R#!s*{0|pu(nVL-D47YNuMGF)Ba+C?FQAFDvmxItTR3mJv$aK0&Z)IP|88lbRaqHm(0)?aC#uK0hlf zyGQSTPQ1S$jvd;!Yx|a}ic*iq)zZ`u3T;>4_jm?2YtkmsNpgaKt@yMo!PXD@Kj|eBH`eoBeE6c{mj8V4EV#TCL#% zX$t^C==bFiMUepzI_FRzDJ89Y&%C1t_lkm0QC8eoUmFMn;uDgRQ!`?1_K22SS$@iY z(b6o5LeJg>NvY?QnqgO7-Mer9ZQp!x>g2K7nlp`cH9oJqwME&ue)Uf~zI|=kx~|=G z385&W4GilRi;ERN$Dma)az6OvMYGkkqX+jEpEx@5>T8ozGtL`J zLSo94$L2U4&1+UJ+4=qEi;z#2q*vyD&;0bGA`gCScBR|C3>0l5XP7gqI9aM zBZSEBGI68XEK8E2$c^8)KpgUuxNhOXC9BtHZn^!Q3!dMn zVBqR^m-u|1ix~CG4QrP#dHrv9OnPkg0-HUdqy6}i{h?6k*9t;RtgEemt#U0SK6Ai9Ez27I)iHcv4e6B!sjdS1O+7;VM z@7;Um$&l2h=aVAwidSHN<72}^Qe37r#Nf5C18gK90RR=f*wpKNacSY%* zo!|fb*1pqz!^f$*?n;Po&?b(4bW3j}477jTlH0=Ct^X)f` zn0)J)(M(uAr|)R`u>jwTUvCKVZd%r>|`+7Sy%>uy}P#= zO@@c2Khv3c0N`wYZBeQC4gonQH!l>F_wU*9`=>0JGi~;?$$p>rTm~Zuc6*}990LI6 z80#am=JUMjt(Tv1v^HPb^8o;xGF;bxtNZ(QD$0mw002Tblt2uM?~ae?8e%CMpeW9h zEwzVu)~r?8IYy5FiHa{MGz*HCLA-{yA;18HP~?>udt!KhtlgQqK|w#U>f4jCo>$!A zNJ@?E!!EN9V~dO5wf&otqT`)Yit^GTmg5Mee!uV98z)}!CZorW->_~~L)}?PYM3`` z${mv*vd1S@pDAClbWu1I@_JkYhmP$3OMu+9d(W)wobppeO$~K|5Kd0X$nMb#0DAPw zOUvle*jTH7QfVYf=-#7uM~xxI7I*T*VU0%HSYO+tSKq-`j0S+l`kLd1_nFL=)~3ct z9fjlgaW~w$VD7Y7n|<-C&mn~R77Pjo1KYN4T>AQgmd1LMCFX`(?zs3^Mvb{HFTei} z-)&yBVD_E&O*^lGvU%gWuQ#nvOims#dR#}sK`9Y`giz1PkX96Yj|D+P$L|Ac_JZB%-zq z9r2gjCOxq9wbzy`dT!prrI#ij7zV0)_0u-}>_6aQ%xZ)YAV2}^OQKfJd;dmxQ=4wz z&^R!E6V59JghoPSKold6!D<~7|BIu70AUp^?VjQr9d@UD4DwG@Ju*?0HIK!^%$ z*p!XqF0mVmQW6dYL!qESZ>*{)J9+G2r|^Q)XmlR8OBBQRKRoNIYi>BV#X%H9!GJ8w zzmF012IKU(FU@@D&R`(0ch|O)M-Rr@>`hI7^+G5th~bpfjA^sxcdi%pD;#!U&rV*g zcCSPnxoB^*f>{%zyIXZaKYJj;lRe z<#aR${Jt*TdffPn&^ms?okhnFZQisl81O$c~J`A_Ds1Tgk$64pMCkAjyjuv zAcRA~fGml!{2P_T5)(V?*+sJ+nY84!mk#XNHDJhy^o%YX&%0f1MaK_+zjYG;%w6zi z*PL@3s|*ICTB|#L_`oM?-ixu?`t~0jYqJl&V$@fkuYK*sr|xpLre${Zc|DsqetdB6 z?xd8ohT591Hhg3-n!EStZ8TY?KlS2&KkvL@%AGgdGxdqS{RR<5*}r$^^2INwq@_=J zbWVq74Fv;2_&5Ci=fh7P{Q1YVE8ofQKlr+vZ@(1zuo}mY*XNfiK0Z|1!kX295dfed z@>oHy5B&YG*sDRaCtqEep$b`49HE>DKqvtqfFwW?gLn-|#GwMgUvN02J;H>4ss*mV zYPd3!gk?}DAPRDj$+#6^?h00RbJ z@!7|TJjZKwy1xAfb+q^GKX})F_N^?(+2a$3Trs-yC67P#f?jXfwQZ}@*}QZ67NRHy zli6yG>p$p-})Xc44e&T3p+P7y1%d%#RHMd*--48rIXxOMuMRSc- zrh%2zhu$`6%IGnF*Z-Q%r)J)K z>!eTCzCU;R{VJ9Evv2mt+U(ce{P&uwiqAe?@x;_Sbq1p(i3y1*FTJ%YEdGoN{-L*YUQX?1#)`Zo%LImY_X z^m((VOm7aP1Gk;ruyuR?)YjV+S(stOp%NHzZV$2%E;z+VXF)$1y5!d4gmr+CVGX~1S!KWbZHkXXF+JiK`G2F*2Jln{+p_xm`{@AHO&0RT{Iw4EzX=b^l`sHVDq((m^gjpnTEob=4> z3rjps2O$IySYoUl0TUslz0DC3R4=%d#_4FOC@XQbI}}AR7)%*i*=d;<&a2v-t))fB zTidVE=eL#syCW68tos|Ppi+IZf|qQvTQJz5|dN2b9!B{K!bFADp2Cv+a5Stht(|B zavdQr#lTUj3llaBex3>Hk;ouGltWZasZLao4}~Zb23b*mBux*yX;d~+F~lzbW@*>~ ztVT8X{piBT zf+Ay5>-wc=`zC=xNk|0Dg6N`3nD75e^t;_C;Nm}*p)~E3i=SsqX4$U_9;**mIu%a{ zFvdKCSR9Fe1%D%l$b?D?l?h`|sj^~qeG^%`p7=#75x|%VZ9rtM?{iGtps3xWfJ^>R zkkYhUDt-m?3N|E2&VYEfU95M@?LiU{siXj)h-gA7#T5!_F?n3>W0zS>iy}(C&P%E&SAU|^eoezINM%GC6XIEf z5hWy&g&+n4p+r)sqyVAk^bpAhk{@Xkn3U_-jK2Y5qUMg`UngILO~EFmev9JRPXl#8 zB)}|xVzj{U00=0Jtgb*rDu;k7fH|a3V{8MNlyOKM7d3Pg|10vHqoCv??I)?bi1_Ph zxD|wUpb8)ilmKRdw;;70>r-(|Z*1uWtS)NeDE?#Q`wbCAH;8Va1R`5*5Cgms@s_Ar vqxi3rFN!GsH;Dejj3}byi{j6R{}}+V?omt-pWIr;00000NkvXXu0mjf3SoI| From b79bbcc3f13cc38d52862bb73be6ad42f9966748 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 7 Jan 2015 13:32:54 +0200 Subject: [PATCH 067/204] Updating to latest coding standard and fixing reported issues --- composer.lock | 50 +++++++++---------- library/aik099/PHPUnit/Application.php | 1 + .../ApiBrowserConfiguration.php | 3 +- .../BrowserConfiguration.php | 5 +- .../BrowserConfigurationFactory.php | 4 +- .../BrowserStackBrowserConfiguration.php | 5 +- .../SauceLabsBrowserConfiguration.php | 3 +- .../aik099/PHPUnit/Event/TestEndedEvent.php | 3 +- .../RemoteCoverage/RemoteCoverageTool.php | 7 ++- .../Session/SessionStrategyManager.php | 4 +- .../PHPUnit/TestSuite/AbstractTestSuite.php | 4 +- .../PHPUnit/TestSuite/TestSuiteFactory.php | 3 +- 12 files changed, 48 insertions(+), 44 deletions(-) diff --git a/composer.lock b/composer.lock index 8f71e10..11cd8ec 100644 --- a/composer.lock +++ b/composer.lock @@ -233,16 +233,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "2.0.13", + "version": "2.0.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5" + "reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5", - "reference": "0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca158276c1200cc27f5409a5e338486bc0b4fc94", + "reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94", "shasum": "" }, "require": { @@ -294,7 +294,7 @@ "testing", "xunit" ], - "time": "2014-12-03 06:41:44" + "time": "2014-12-26 13:28:33" }, { "name": "phpunit/php-file-iterator", @@ -480,16 +480,16 @@ }, { "name": "phpunit/phpunit", - "version": "4.4.0", + "version": "4.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0" + "reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0", - "reference": "bbe7bcb83b6ec1a9eaabbe1b70d4795027c53ee0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6a5e49a86ce5e33b8d0657abe145057fc513543a", + "reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a", "shasum": "" }, "require": { @@ -547,7 +547,7 @@ "testing", "xunit" ], - "time": "2014-12-05 06:49:03" + "time": "2014-12-28 07:57:05" }, { "name": "phpunit/phpunit-mock-objects", @@ -934,16 +934,16 @@ }, { "name": "sebastian/version", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43" + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b", + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b", "shasum": "" }, "type": "library", @@ -965,7 +965,7 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2014-03-07 15:35:33" + "time": "2014-12-15 14:25:24" }, { "name": "symfony/css-selector", @@ -1131,16 +1131,16 @@ "source": { "type": "git", "url": "https://github.com/aik099/CodingStandard.git", - "reference": "97775a1ab890b080b52da3739e3c4c584315c215" + "reference": "8e14991f692bdf66def663e0310a81e6d4734832" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/97775a1ab890b080b52da3739e3c4c584315c215", - "reference": "97775a1ab890b080b52da3739e3c4c584315c215", + "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/8e14991f692bdf66def663e0310a81e6d4734832", + "reference": "8e14991f692bdf66def663e0310a81e6d4734832", "shasum": "" }, "require-dev": { - "squizlabs/php_codesniffer": "~1.5" + "squizlabs/php_codesniffer": "~2.0" }, "type": "library", "extra": { @@ -1163,20 +1163,20 @@ "PHP_CodeSniffer", "codesniffer" ], - "time": "2014-12-07 22:16:34" + "time": "2015-01-03 20:25:25" }, { "name": "mockery/mockery", - "version": "0.9.2", + "version": "0.9.3", "source": { "type": "git", "url": "https://github.com/padraic/mockery.git", - "reference": "95a4855380dc70176c51807c678fb3bd6198529a" + "reference": "686f85fa5b3b079cc0157d7cd3e9adb97f0b41e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/padraic/mockery/zipball/95a4855380dc70176c51807c678fb3bd6198529a", - "reference": "95a4855380dc70176c51807c678fb3bd6198529a", + "url": "https://api.github.com/repos/padraic/mockery/zipball/686f85fa5b3b079cc0157d7cd3e9adb97f0b41e1", + "reference": "686f85fa5b3b079cc0157d7cd3e9adb97f0b41e1", "shasum": "" }, "require": { @@ -1229,7 +1229,7 @@ "test double", "testing" ], - "time": "2014-09-03 10:11:10" + "time": "2014-12-22 10:06:19" } ], "aliases": [], diff --git a/library/aik099/PHPUnit/Application.php b/library/aik099/PHPUnit/Application.php index 52c2ea2..fc66ab1 100644 --- a/library/aik099/PHPUnit/Application.php +++ b/library/aik099/PHPUnit/Application.php @@ -111,6 +111,7 @@ public function replaceObject($service_id, $callable, $is_factory = false) * Prevents cloning. * * @return void + * * @codeCoverageIgnore */ private function __clone() diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index 172ac7e..c14dc65 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -51,8 +51,7 @@ abstract class ApiBrowserConfiguration extends BrowserConfiguration public function __construct( EventDispatcherInterface $event_dispatcher, IBrowserConfigurationFactory $browser_configuration_factory - ) - { + ) { $this->browserConfigurationFactory = $browser_configuration_factory; $this->defaultParameters['api_username'] = ''; $this->defaultParameters['api_key'] = ''; diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 815a612..72b165a 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -363,7 +363,7 @@ public function getBaseUrl() * @param array $capabilities Desired capabilities. * * @return self - * @link http://code.google.com/p/selenium/wiki/JsonWireProtocol + * @link http://code.google.com/p/selenium/wiki/JsonWireProtocol */ public function setDesiredCapabilities(array $capabilities) { @@ -568,7 +568,8 @@ protected function isEventForMe(TestEvent $event) { $test_case = $event->getTestCase(); - return get_class($test_case) === get_class($this->_testCase) && $test_case->getName() === $this->_testCase->getName(); + return get_class($test_case) === get_class($this->_testCase) + && $test_case->getName() === $this->_testCase->getName(); } } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php index 4b17c6f..01c6913 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php @@ -46,7 +46,9 @@ public function register(BrowserConfiguration $browser) $type = $browser->getType(); if ( isset($this->browserConfigurations[$type]) ) { - throw new \InvalidArgumentException('Browser configuration with type "' . $type . '" is already registered'); + throw new \InvalidArgumentException( + 'Browser configuration with type "' . $type . '" is already registered' + ); } $this->browserConfigurations[$type] = $browser; diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php index 9137100..3d8a7ad 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php @@ -30,8 +30,7 @@ class BrowserStackBrowserConfiguration extends ApiBrowserConfiguration public function __construct( EventDispatcherInterface $event_dispatcher, IBrowserConfigurationFactory $browser_configuration_factory - ) - { + ) { $this->defaultParameters['type'] = 'browserstack'; parent::__construct($event_dispatcher, $browser_configuration_factory); @@ -51,7 +50,7 @@ public function getHost() * Returns desired capabilities from browser configuration. * * @return array - * @link http://www.browserstack.com/automate/capabilities + * @link http://www.browserstack.com/automate/capabilities */ public function getDesiredCapabilities() { diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index dd17253..8e0a5fe 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -31,8 +31,7 @@ class SauceLabsBrowserConfiguration extends ApiBrowserConfiguration public function __construct( EventDispatcherInterface $event_dispatcher, IBrowserConfigurationFactory $browser_configuration_factory - ) - { + ) { $this->defaultParameters['type'] = 'saucelabs'; parent::__construct($event_dispatcher, $browser_configuration_factory); diff --git a/library/aik099/PHPUnit/Event/TestEndedEvent.php b/library/aik099/PHPUnit/Event/TestEndedEvent.php index 56c4da6..d33f533 100644 --- a/library/aik099/PHPUnit/Event/TestEndedEvent.php +++ b/library/aik099/PHPUnit/Event/TestEndedEvent.php @@ -35,8 +35,7 @@ public function __construct( BrowserTestCase $test_case, \PHPUnit_Framework_TestResult $test_result, Session $session = null - ) - { + ) { parent::__construct($test_case, $session); $this->_testResult = $test_result; } diff --git a/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php index d980745..6ce7b80 100644 --- a/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php +++ b/library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php @@ -138,8 +138,9 @@ public function stopCollection() unset($data[$file]); } + $unique_id = md5(uniqid(rand(), true)); file_put_contents( - $name = $this->getStorageLocationPrefix() . '.' . md5(uniqid(rand(), true)) . '.' . $_COOKIE[self::TEST_ID_VARIABLE], + $name = $this->getStorageLocationPrefix() . '.' . $unique_id . '.' . $_COOKIE[self::TEST_ID_VARIABLE], serialize($data) ); } @@ -196,7 +197,9 @@ public function aggregateCoverageInformation() } else { foreach ( $lines as $line => $flag ) { - if ( !isset($coverage[$file]['coverage'][$line]) || $flag > $coverage[$file]['coverage'][$line] ) { + if ( !isset($coverage[$file]['coverage'][$line]) + || $flag > $coverage[$file]['coverage'][$line] + ) { $coverage[$file]['coverage'][$line] = $flag; } } diff --git a/library/aik099/PHPUnit/Session/SessionStrategyManager.php b/library/aik099/PHPUnit/Session/SessionStrategyManager.php index 7b7c9fa..4a96fd0 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyManager.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyManager.php @@ -93,7 +93,9 @@ public function getSessionStrategy(BrowserConfiguration $browser) $strategy_hash = $browser->getSessionStrategyHash(); if ( $strategy_hash !== $this->lastUsedSessionStrategyHash ) { - $this->sessionStrategiesInUse[$strategy_hash] = $this->_sessionStrategyFactory->createStrategy($strategy_type); + $this->sessionStrategiesInUse[$strategy_hash] = $this->_sessionStrategyFactory->createStrategy( + $strategy_type + ); } $this->lastUsedSessionStrategyHash = $strategy_hash; diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index 7d8e27c..715bf36 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -86,8 +86,7 @@ public function setTestDependencies( IBrowserConfigurationFactory $browser_configuration_factory, RemoteCoverageHelper $remote_coverage_helper, array $tests = null - ) - { + ) { if ( !isset($tests) ) { $tests = $this->tests(); } @@ -141,6 +140,7 @@ protected function tearDown(array $tests = null) * Indicates end of the test suite. * * @return void + * * @codeCoverageIgnore */ public function onTestSuiteEnded() diff --git a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php index 8335114..a199875 100644 --- a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php +++ b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php @@ -64,8 +64,7 @@ public function __construct( SessionStrategyManager $session_strategy_manager, IBrowserConfigurationFactory $browser_configuration_factory, RemoteCoverageHelper $remote_coverage_helper - ) - { + ) { $this->_sessionStrategyManager = $session_strategy_manager; $this->_browserConfigurationFactory = $browser_configuration_factory; $this->_remoteCoverageHelper = $remote_coverage_helper; From 20b2b75eecc4ccd5a4a6a924f8ef3ac50c0c91cd Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Thu, 8 Jan 2015 12:07:08 +0200 Subject: [PATCH 068/204] Change homepage url for Composer --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 81002d7..39f4258 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "aik099/phpunit-mink", "description": "Library for using Mink in PHPUnit tests. Supports session sharing between tests in a test case.", "keywords": ["PHPUnit", "Selenium", "SauceLabs", "Sauce", "BrowserStack", "Mink", "Tests"], - "homepage": "http://github.com/aik099/phpunit-mink", + "homepage": "http://github.com/minkphp/phpunit-mink", "license": "BSD-3-Clause", "authors": [ From b9c41fbd052610545869948483a64b225ad30786 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Thu, 8 Jan 2015 11:16:45 +0100 Subject: [PATCH 069/204] Update URLs for the move to the new organization --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2db7956..9a563a6 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # PHPUnit-Mink -[![Build Status](https://travis-ci.org/aik099/phpunit-mink.svg?branch=master)](https://travis-ci.org/aik099/phpunit-mink) +[![Build Status](https://travis-ci.org/minkphp/phpunit-mink.svg?branch=master)](https://travis-ci.org/minkphp/phpunit-mink) [![HHVM Status](http://hhvm.h4cc.de/badge/aik099/phpunit-mink.svg)](http://hhvm.h4cc.de/package/aik099/phpunit-mink) [![Documentation Status](https://readthedocs.org/projects/phpunit-mink/badge/?version=latest)](https://readthedocs.org/projects/phpunit-mink/?badge=latest) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/aik099/phpunit-mink/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/aik099/phpunit-mink/?branch=master) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/minkphp/phpunit-mink/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/minkphp/phpunit-mink/?branch=master) [![Coverage Status](https://img.shields.io/coveralls/aik099/phpunit-mink.svg)](https://coveralls.io/r/aik099/phpunit-mink?branch=master) [![Dependency Status](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049/badge.svg?style=flat)](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049) [![Latest Stable Version](https://poser.pugx.org/aik099/phpunit-mink/v/stable.svg)](https://packagist.org/packages/aik099/phpunit-mink) [![Total Downloads](https://poser.pugx.org/aik099/phpunit-mink/downloads.svg)](https://packagist.org/packages/aik099/phpunit-mink) [![Latest Unstable Version](https://poser.pugx.org/aik099/phpunit-mink/v/unstable.svg)](https://packagist.org/packages/aik099/phpunit-mink) [![License](https://poser.pugx.org/aik099/phpunit-mink/license.svg)](https://packagist.org/packages/aik099/phpunit-mink) -This library is an extension for [PHPUnit](sebastianbergmann/phpunit), that allows to write tests with help of [Mink](Behat/Mink). +This library is an extension for [PHPUnit](https://phpunit.de), that allows to write tests with help of [Mink](https://github.com/minkphp/Mink). ## Documentation From e5c293fb589784fb7d5161cb72505151321ef869 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Thu, 8 Jan 2015 12:28:19 +0200 Subject: [PATCH 070/204] Updating SauceLabs encrypted keys (using personal SauceLabs account) --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2f70f6b..3b527e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,8 @@ php: env: global: - - secure: XTlGGWYR/0OwJLQMHHvTopTj37OL97wiFIMMmiZQtmyf2neNia/Se9ASftgeFHI6WeSxcjC0hYF9LtPNHCHW30Qv8E2/L6PtENxZY8tBGUq0O/4XaCIhGUdc9NxkteZ3M5rgTWkLbs8Sctl31/vqG4bYstNwgLvHnw2Jh4TBHuU= - - secure: KIgQ3vADaLcuzlRNNjq3veFp9p4Vq30GYbYyqaEpz7eUI/t7r/THhSmsUc04+tcmc6iXXfMzjQmylUerE8pDNBBtBfBsmUkuVvXDQTeIv8WYgBVMalFR0rfI/v3mzn9gzRHbtEEJMtsRenvfBJPqrrAdI4W4vyEOCSTIKklumck= + - secure: HhIy0kN0+UbuLeaVBk7O/utAYo038a9Emr8cdcfU+LQTu6CfGEbifH+LddXs6M/bSLTdNUSwQSnwycbeNYZ6iHCO/JI/vEgKxCTSecPerMXBIVCQjFZaCp3Tev8JJ40hKe78WJ/d0G4bGtIR6atR5V+H8Z29iwJeFtCj6doEt3o= + - secure: oLadQTqg8HSEmUC0qEtChKd/R0ZiFNhzoZjIaa8kAJ0fjln/2xfNCBQIg4YstyjFy2kLiP6Lg8xW/RZljzyTHC+MCB9NNqTYjKLqFNRvFOlZUOnrAwc4sl4qjMYu9klWKa+rfyZzsuVWn++g829s2lFopkImqa6EB9DOR2TOT6w= addons: sauce_connect: true From bacab62b2f678249f7966711505696489f31fb6d Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Thu, 8 Jan 2015 20:48:00 +0200 Subject: [PATCH 071/204] Documentation badge links to generated documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a563a6..6b6c2fc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # PHPUnit-Mink [![Build Status](https://travis-ci.org/minkphp/phpunit-mink.svg?branch=master)](https://travis-ci.org/minkphp/phpunit-mink) [![HHVM Status](http://hhvm.h4cc.de/badge/aik099/phpunit-mink.svg)](http://hhvm.h4cc.de/package/aik099/phpunit-mink) -[![Documentation Status](https://readthedocs.org/projects/phpunit-mink/badge/?version=latest)](https://readthedocs.org/projects/phpunit-mink/?badge=latest) +[![Documentation](https://readthedocs.org/projects/phpunit-mink/badge/?version=latest)](http://phpunit-mink.readthedocs.org/en/latest/) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/minkphp/phpunit-mink/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/minkphp/phpunit-mink/?branch=master) [![Coverage Status](https://img.shields.io/coveralls/aik099/phpunit-mink.svg)](https://coveralls.io/r/aik099/phpunit-mink?branch=master) From 340a0b16211c90e6e2f051a268cef34401bf47cb Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 17 Jan 2015 19:42:40 +0200 Subject: [PATCH 072/204] Adding coding standard usage instructions --- CONTRIBUTING.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1dca36f..f63b2db 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,3 +19,13 @@ Make sure that you don't break anything with your changes by running: ```bash $> phpunit ``` + +## Checking coding standard violations + +This library uses [Coding Standard](https://github.com/aik099/CodingStandard) to ensure consistent formatting across the code base. Make sure you haven't introduced any Coding Standard violations by running following command in the root folder of the library: + +```bash +$> phpcs --standard="vendor/aik099/coding-standard/CodingStandard" library tests +``` + +or by making your IDE ([instructions for PhpStorm](http://www.jetbrains.com/phpstorm/webhelp/using-php-code-sniffer-tool.html)) to check them automatically. From 0f50173ce2df889e58ccbae2b475b7cbd7682080 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 17 Jan 2015 22:33:05 +0200 Subject: [PATCH 073/204] Don't run SauceLabs tests, when no API credentials are specified --- .../ApiBrowserConfiguration.php | 6 +- .../ApiBrowserConfigurationTestCase.php | 26 +++++- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 91 +++++++++++++++++-- .../PHPUnit/Integration/DataProviderTest.php | 12 +++ 4 files changed, 119 insertions(+), 16 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index c14dc65..a3c5fe3 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -208,7 +208,9 @@ public function onTestEnded(TestEndedEvent $event) parent::onTestEnded($event); - if ( $event->getSession() === null ) { + $session = $event->getSession(); + + if ( $session === null || !$session->isStarted() ) { // Session wasn't used in particular test. return; } @@ -216,7 +218,7 @@ public function onTestEnded(TestEndedEvent $event) $test_case = $event->getTestCase(); $this->getAPIClient()->updateStatus( - $this->getSessionId($event->getSession()), + $this->getSessionId($session), $this->getTestStatus($test_case, $event->getTestResult()) ); } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index b512ba5..34195f9 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -268,6 +268,7 @@ public function testTestEndedEvent($driver_type) $session = m::mock('Behat\\Mink\\Session'); $session->shouldReceive('getDriver')->once()->andReturn($driver); + $session->shouldReceive('isStarted')->once()->andReturn(true); $event_dispatcher = new EventDispatcher(); $event_dispatcher->addSubscriber($this->browser); @@ -298,11 +299,9 @@ public function theTestEndedEventDataProvider() } /** - * Test description. - * - * @return void + * @dataProvider sessionStateDataProvider */ - public function testTestEndedWithoutSession() + public function testTestEndedWithoutSession($stopped_or_missing) { $test_case = $this->createTestCase('TEST_NAME'); @@ -310,7 +309,16 @@ public function testTestEndedWithoutSession() $event_dispatcher->addSubscriber($this->browser); $event = m::mock('aik099\\PHPUnit\\Event\\TestEndedEvent'); - $event->shouldReceive('getSession')->once(); + + if ( $stopped_or_missing ) { + $session = m::mock('Behat\\Mink\\Session'); + $session->shouldReceive('isStarted')->once()->andReturn(false); + $event->shouldReceive('getSession')->once()->andReturn($session); + } + else { + $event->shouldReceive('getSession')->once(); + } + $event->shouldReceive('setDispatcher')->once(); // To remove with Symfony 3.0 release. $event->shouldReceive('setName')->once(); // To remove with Symfony 3.0 release. $event->shouldReceive('isPropagationStopped')->once()->andReturn(false); @@ -322,6 +330,14 @@ public function testTestEndedWithoutSession() $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $returned_event); } + public function sessionStateDataProvider() + { + return array( + array(true), + array(false), + ); + } + /** * Create TestCase with Browser. * diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index 39d9640..be186d4 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -31,6 +31,13 @@ class ApiIntegrationFixture extends BrowserTestCase // array('alias' => 'browserstack'), ); + /** + * Record IDs of WebDriver session, that needs to be verified. + * + * @var array + */ + private $_sessionIds = array(); + /** * Sets event dispatcher. * @@ -42,9 +49,38 @@ public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) { parent::setEventDispatcher($event_dispatcher); + // Use priority for this listener to be called before one, that stops the session. + $event_dispatcher->addListener(self::TEST_ENDED_EVENT, array($this, 'recordSessionId'), 200); $event_dispatcher->addListener(self::TEST_ENDED_EVENT, array($this, 'verifyRemoteAPICalls')); } + /** + * Record WebDriver session ID of the test. + * + * @param TestEvent $event Event. + * + * @return void + */ + public function recordSessionId(TestEvent $event) + { + $test_case = $event->getTestCase(); + + if ( get_class($test_case) !== get_class($this) + || $test_case->getName() !== $this->getName() + || $this->_getTestSkipMessage() + ) { + return; + } + + $session = $event->getSession(); + + if ( $session === null ) { + $this->markTestSkipped('Unable to connect to SauceLabs. Please check Internet connection.'); + } + + $this->_sessionIds[$test_case->getName(false)] = $session->getDriver()->getWebDriverSessionId(); + } + /** * Verify how the API calls were made. * @@ -60,29 +96,41 @@ public function verifyRemoteAPICalls(TestEvent $event) return; } - $browser = $this->getBrowser(); + $test_name = $test_case->getName(false); - if ( $browser instanceof SauceLabsBrowserConfiguration ) { - $session = $event->getSession(); + if ( !isset($this->_sessionIds[$test_name]) ) { + return; + } - if ( $session === null ) { - $this->markTestSkipped('Unable to connect to SauceLabs. Please check Internet connection.'); - } + $browser = $this->getBrowser(); + if ( $browser instanceof SauceLabsBrowserConfiguration ) { $sauce_rest = new SauceRest($browser->getApiUsername(), $browser->getApiKey()); - $job_info = $sauce_rest->getJob($session->getDriver()->getWebDriverSessionId()); + $job_info = $sauce_rest->getJob($this->_sessionIds[$test_name]); - $this->assertEquals(get_class($test_case) . '::' . $test_case->getName(), $job_info['name']); + $this->assertEquals(get_class($test_case) . '::' . $test_name, $job_info['name']); $passed_mapping = array( 'testSuccess' => true, 'testFailure' => false, ); - $this->assertSame($passed_mapping[$test_case->getName()], $job_info['passed']); + $this->assertSame($passed_mapping[$test_name], $job_info['passed']); } } + /** + * Whatever or not code coverage information should be gathered. + * + * @return boolean + * @throws \RuntimeException When used before test is started. + */ + public function getCollectCodeCoverageInformation() + { + // FIXME: Workaround for https://github.com/minkphp/phpunit-mink/issues/35 bug. + return false; + } + /** * Test description. * @@ -90,6 +138,12 @@ public function verifyRemoteAPICalls(TestEvent $event) */ public function testSuccess() { + $skip_message = $this->_getTestSkipMessage(); + + if ( $skip_message ) { + $this->markTestSkipped($skip_message); + } + $session = $this->getSession(); $session->visit('http://www.google.com'); @@ -103,6 +157,12 @@ public function testSuccess() */ public function testFailure() { + $skip_message = $this->_getTestSkipMessage(); + + if ( $skip_message ) { + $this->markTestSkipped($skip_message); + } + $session = $this->getSession(); $session->visit('http://www.google.com'); @@ -134,4 +194,17 @@ public function getBrowserAliases() ); } + private function _getTestSkipMessage() + { + $browser = $this->getBrowser(); + + if ( $browser->getType() == 'saucelabs' ) { + if ( !getenv('SAUCE_USERNAME') || !getenv('SAUCE_ACCESS_KEY') ) { + return 'SauceLabs integration is not configured'; + } + } + + return ''; + } + } diff --git a/tests/aik099/PHPUnit/Integration/DataProviderTest.php b/tests/aik099/PHPUnit/Integration/DataProviderTest.php index c8891cc..15eeeb4 100644 --- a/tests/aik099/PHPUnit/Integration/DataProviderTest.php +++ b/tests/aik099/PHPUnit/Integration/DataProviderTest.php @@ -50,6 +50,18 @@ public function testDataProvider($case) } } + /** + * Whatever or not code coverage information should be gathered. + * + * @return boolean + * @throws \RuntimeException When used before test is started. + */ + public function getCollectCodeCoverageInformation() + { + // FIXME: Workaround for https://github.com/minkphp/phpunit-mink/issues/35 bug. + return false; + } + protected function customMethod() { return 5; From 94e8a0e73a96db04bbca4c73956c5a957863b6e3 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 17 Jan 2015 19:54:40 +0200 Subject: [PATCH 074/204] Use stable Composer reps and some CS fixes --- composer.json | 4 +- composer.lock | 79 +++++++++---------- tests/aik099/PHPUnit/ApplicationTest.php | 5 +- .../ApiBrowserConfigurationTestCase.php | 17 +++- .../BrowserConfigurationTest.php | 10 ++- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 13 ++- .../PHPUnit/Fixture/SetupEventFixture.php | 5 +- .../PHPUnit/Integration/DIContainerTest.php | 5 +- 8 files changed, 83 insertions(+), 55 deletions(-) diff --git a/composer.json b/composer.json index 39f4258..3158e42 100644 --- a/composer.json +++ b/composer.json @@ -14,8 +14,8 @@ "require": { "php": ">=5.3.2", - "behat/mink": "~1.5@dev", - "behat/mink-selenium2-driver": "~1.1@dev", + "behat/mink": "~1.6", + "behat/mink-selenium2-driver": "~1.2", "symfony/event-dispatcher": "~2.4", "pimple/pimple": "~2.0", "phpunit/phpunit": ">=3.7.8" diff --git a/composer.lock b/composer.lock index 11cd8ec..0062a94 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "1923bc8aba01c2a37529ca4cf07dc902", + "hash": "c608fcac523a1963334c5daabeaf38ad", "packages": [ { "name": "behat/mink", - "version": "dev-master", + "version": "v1.6.0", "source": { "type": "git", - "url": "https://github.com/Behat/Mink.git", - "reference": "d99b94af22d34b12d4417512538f13890c7fa5be" + "url": "https://github.com/minkphp/Mink.git", + "reference": "090900a0049c441f1e072bbd837db4079b2250c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Mink/zipball/d99b94af22d34b12d4417512538f13890c7fa5be", - "reference": "d99b94af22d34b12d4417512538f13890c7fa5be", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/090900a0049c441f1e072bbd837db4079b2250c5", + "reference": "090900a0049c441f1e072bbd837db4079b2250c5", "shasum": "" }, "require": { @@ -59,19 +59,19 @@ "testing", "web" ], - "time": "2014-10-27 11:35:27" + "time": "2014-09-26 09:25:05" }, { "name": "behat/mink-selenium2-driver", - "version": "dev-master", + "version": "v1.2.0", "source": { "type": "git", - "url": "https://github.com/Behat/MinkSelenium2Driver.git", + "url": "https://github.com/minkphp/MinkSelenium2Driver.git", "reference": "8018fee80bf6573f909ece3e0dfc07d0eb352210" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/MinkSelenium2Driver/zipball/8018fee80bf6573f909ece3e0dfc07d0eb352210", + "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/8018fee80bf6573f909ece3e0dfc07d0eb352210", "reference": "8018fee80bf6573f909ece3e0dfc07d0eb352210", "shasum": "" }, @@ -431,16 +431,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "f8d5d08c56de5cfd592b3340424a81733259a876" + "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/f8d5d08c56de5cfd592b3340424a81733259a876", - "reference": "f8d5d08c56de5cfd592b3340424a81733259a876", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74", + "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74", "shasum": "" }, "require": { @@ -453,7 +453,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -476,20 +476,20 @@ "keywords": [ "tokenizer" ], - "time": "2014-08-31 06:12:13" + "time": "2015-01-17 09:51:32" }, { "name": "phpunit/phpunit", - "version": "4.4.1", + "version": "4.4.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a" + "reference": "e90575c2bb86290d57a262862dab1da125431576" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6a5e49a86ce5e33b8d0657abe145057fc513543a", - "reference": "6a5e49a86ce5e33b8d0657abe145057fc513543a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e90575c2bb86290d57a262862dab1da125431576", + "reference": "e90575c2bb86290d57a262862dab1da125431576", "shasum": "" }, "require": { @@ -547,7 +547,7 @@ "testing", "xunit" ], - "time": "2014-12-28 07:57:05" + "time": "2015-01-17 11:24:41" }, { "name": "phpunit/phpunit-mock-objects", @@ -969,17 +969,17 @@ }, { "name": "symfony/css-selector", - "version": "v2.6.1", + "version": "v2.6.3", "target-dir": "Symfony/Component/CssSelector", "source": { "type": "git", "url": "https://github.com/symfony/CssSelector.git", - "reference": "93eb315b545b60a908271762fb4bfa1f9954b851" + "reference": "3f80ecc614fec68d5b4a84a0703db3fdf5ce8584" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/CssSelector/zipball/93eb315b545b60a908271762fb4bfa1f9954b851", - "reference": "93eb315b545b60a908271762fb4bfa1f9954b851", + "url": "https://api.github.com/repos/symfony/CssSelector/zipball/3f80ecc614fec68d5b4a84a0703db3fdf5ce8584", + "reference": "3f80ecc614fec68d5b4a84a0703db3fdf5ce8584", "shasum": "" }, "require": { @@ -1016,21 +1016,21 @@ ], "description": "Symfony CssSelector Component", "homepage": "http://symfony.com", - "time": "2014-12-02 20:19:20" + "time": "2015-01-03 08:01:59" }, { "name": "symfony/event-dispatcher", - "version": "v2.6.1", + "version": "v2.6.3", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "720fe9bca893df7ad1b4546649473b5afddf0216" + "reference": "40ff70cadea3785d83cac1c8309514b36113064e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/720fe9bca893df7ad1b4546649473b5afddf0216", - "reference": "720fe9bca893df7ad1b4546649473b5afddf0216", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/40ff70cadea3785d83cac1c8309514b36113064e", + "reference": "40ff70cadea3785d83cac1c8309514b36113064e", "shasum": "" }, "require": { @@ -1038,10 +1038,10 @@ }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.0", + "symfony/config": "~2.0,>=2.0.5", "symfony/dependency-injection": "~2.6", "symfony/expression-language": "~2.6", - "symfony/stopwatch": "~2.2" + "symfony/stopwatch": "~2.3" }, "suggest": { "symfony/dependency-injection": "", @@ -1074,21 +1074,21 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "http://symfony.com", - "time": "2014-12-02 20:19:20" + "time": "2015-01-05 14:28:40" }, { "name": "symfony/yaml", - "version": "v2.6.1", + "version": "v2.6.3", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "3346fc090a3eb6b53d408db2903b241af51dcb20" + "reference": "82462a90848a52c2533aa6b598b107d68076b018" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/3346fc090a3eb6b53d408db2903b241af51dcb20", - "reference": "3346fc090a3eb6b53d408db2903b241af51dcb20", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/82462a90848a52c2533aa6b598b107d68076b018", + "reference": "82462a90848a52c2533aa6b598b107d68076b018", "shasum": "" }, "require": { @@ -1121,7 +1121,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2014-12-02 20:19:20" + "time": "2015-01-03 15:33:07" } ], "packages-dev": [ @@ -1235,11 +1235,10 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "behat/mink": 20, - "behat/mink-selenium2-driver": 20, "aik099/coding-standard": 20 }, "prefer-stable": false, + "prefer-lowest": false, "platform": { "php": ">=5.3.2" }, diff --git a/tests/aik099/PHPUnit/ApplicationTest.php b/tests/aik099/PHPUnit/ApplicationTest.php index 63b9660..80cf439 100644 --- a/tests/aik099/PHPUnit/ApplicationTest.php +++ b/tests/aik099/PHPUnit/ApplicationTest.php @@ -53,7 +53,10 @@ public function testInstanceIsShared() */ public function testGetTestSuiteFactory() { - $this->assertInstanceOf('aik099\\PHPUnit\\TestSuite\\TestSuiteFactory', $this->_application->getTestSuiteFactory()); + $this->assertInstanceOf( + 'aik099\\PHPUnit\\TestSuite\\TestSuiteFactory', + $this->_application->getTestSuiteFactory() + ); } /** diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 34195f9..50681ea 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -52,7 +52,9 @@ protected function setUp() $this->testsRequireSubscriber[] = 'testTestSetupEvent'; $this->testsRequireSubscriber[] = 'testTestEndedEvent'; $this->testsRequireSubscriber[] = 'testTestEndedWithoutSession'; - $this->browserConfigurationFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + $this->browserConfigurationFactory = m::mock( + 'aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory' + ); parent::setUp(); @@ -172,7 +174,9 @@ public function testTestSetupEvent($session_strategy, $test_name, $build_env_nam $this->browser->setSessionStrategy($session_strategy); $test_case = $this->createTestCase($test_name); - $test_case->shouldReceive('toString')->times($this->_isAutomaticTestName($test_name) ? 0 : 1)->andReturn($test_name); + $test_case->shouldReceive('toString') + ->times($this->_isAutomaticTestName($test_name) ? 0 : 1) + ->andReturn($test_name); $event_dispatcher = new EventDispatcher(); $event_dispatcher->addSubscriber($this->browser); @@ -232,7 +236,10 @@ public function setupEventDataProvider() ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME', 'TRAVIS_BUILD_NUMBER', 'TRAVIS ' . $seed, ), 'shared, no name, travis' => array( - ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME, 'TRAVIS_BUILD_NUMBER', 'TRAVIS ' . $seed, + ISessionStrategyFactory::TYPE_SHARED, + self::AUTOMATIC_TEST_NAME, + 'TRAVIS_BUILD_NUMBER', + 'TRAVIS ' . $seed, ), 'isolated, name, no build' => array(ISessionStrategyFactory::TYPE_ISOLATED, 'TEST_NAME'), 'shared, no name, no build' => array(ISessionStrategyFactory::TYPE_SHARED, self::AUTOMATIC_TEST_NAME), @@ -252,7 +259,9 @@ public function testTestEndedEvent($driver_type) $test_case = $this->createTestCase('TEST_NAME'); $api_client = m::mock('aik099\\PHPUnit\\APIClient\\IAPIClient'); - $this->browserConfigurationFactory->shouldReceive('createAPIClient')->with($this->browser)->andReturn($api_client); + $this->browserConfigurationFactory->shouldReceive('createAPIClient') + ->with($this->browser) + ->andReturn($api_client); if ( $driver_type == 'selenium' ) { $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index e5f729d..a7d93a2 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -82,7 +82,10 @@ protected function setUp() 'sessionStrategy' => ISessionStrategyFactory::TYPE_SHARED, ); - $this->browser = $this->createBrowserConfiguration(array(), in_array($this->getName(false), $this->testsRequireSubscriber)); + $this->browser = $this->createBrowserConfiguration( + array(), + in_array($this->getName(false), $this->testsRequireSubscriber) + ); } /** @@ -130,7 +133,10 @@ public function aliasResolutionDataProvider() ), array('alias' => 'a1'), array( - 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'safari', 'baseUrl' => 'http://example_host', + 'host' => static::HOST, + 'port' => static::PORT, + 'browserName' => 'safari', + 'baseUrl' => 'http://example_host', ), ), 'alias merging' => array( diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 2cb98b7..cf62810 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -48,7 +48,9 @@ protected function setUp() { parent::setUp(); - $this->browserConfigurationFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + $this->browserConfigurationFactory = m::mock( + 'aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory' + ); } /** @@ -455,9 +457,12 @@ protected function getTestResult(BrowserTestCase $test_case, $run_count, $collec $result = m::mock('\\PHPUnit_Framework_TestResult'); $result->shouldReceive('getCollectCodeCoverageInformation')->withNoArgs()->andReturn($collect_coverage); - $result->shouldReceive('run')->with($test_case)->times($run_count)->andReturnUsing(function () use ($test_case) { - $test_case->runBare(); - }); + $result->shouldReceive('run') + ->with($test_case) + ->times($run_count) + ->andReturnUsing(function () use ($test_case) { + $test_case->runBare(); + }); return $result; } diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index 723fd85..5ec3cb3 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -36,7 +36,10 @@ protected function setUp() $browser_config = array('api_username' => 'a', 'api_key' => 'b'); $browser = new SauceLabsBrowserConfiguration($this->readAttribute($this, '_eventDispatcher'), $factory); - $factory->shouldReceive('createBrowserConfiguration')->with($browser_config, $this)->once()->andReturn($browser); + $factory->shouldReceive('createBrowserConfiguration') + ->with($browser_config, $this) + ->once() + ->andReturn($browser); $this->setBrowserConfigurationFactory($factory); $this->setBrowserFromConfiguration($browser_config); diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index df98353..f51267e 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -72,7 +72,10 @@ public function serviceDefinitionsDataProvider() array('test_suite_factory', 'aik099\\PHPUnit\\TestSuite\\TestSuiteFactory'), array('regular_test_suite', 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'), array('browser_test_suite', 'aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'), - array('browser_configuration_factory', 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfigurationFactory'), + array( + 'browser_configuration_factory', + 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfigurationFactory', + ), ); } From 60815bd7966cbd9361b8702166d645f8e3329d30 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 18 Jan 2015 14:44:02 +0200 Subject: [PATCH 075/204] Allow usage of both Pimple 2.x and 3.x versions --- composer.json | 2 +- composer.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 3158e42..4d0b49c 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "behat/mink": "~1.6", "behat/mink-selenium2-driver": "~1.2", "symfony/event-dispatcher": "~2.4", - "pimple/pimple": "~2.0", + "pimple/pimple": "~2.0|~3.0", "phpunit/phpunit": ">=3.7.8" }, diff --git a/composer.lock b/composer.lock index 0062a94..eb1e9e1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "c608fcac523a1963334c5daabeaf38ad", + "hash": "9677a9d73bf451ae1e4314bfe7e9991e", "packages": [ { "name": "behat/mink", @@ -606,16 +606,16 @@ }, { "name": "pimple/pimple", - "version": "v2.1.1", + "version": "v3.0.0", "source": { "type": "git", - "url": "https://github.com/fabpot/Pimple.git", - "reference": "ea22fb2880faf7b7b0e17c9809c6fe25b071fd76" + "url": "https://github.com/silexphp/Pimple.git", + "reference": "876bf0899d01feacd2a2e83f04641e51350099ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fabpot/Pimple/zipball/ea22fb2880faf7b7b0e17c9809c6fe25b071fd76", - "reference": "ea22fb2880faf7b7b0e17c9809c6fe25b071fd76", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/876bf0899d01feacd2a2e83f04641e51350099ef", + "reference": "876bf0899d01feacd2a2e83f04641e51350099ef", "shasum": "" }, "require": { @@ -624,7 +624,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -648,7 +648,7 @@ "container", "dependency injection" ], - "time": "2014-07-24 07:10:08" + "time": "2014-07-24 09:48:15" }, { "name": "sebastian/comparator", From e997589318b3f9bbbdfba4670c3a8042fdfa5c97 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 20 Jan 2015 10:01:42 +0200 Subject: [PATCH 076/204] Change url of Coveralls.Io badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b6c2fc..29ba101 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Documentation](https://readthedocs.org/projects/phpunit-mink/badge/?version=latest)](http://phpunit-mink.readthedocs.org/en/latest/) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/minkphp/phpunit-mink/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/minkphp/phpunit-mink/?branch=master) -[![Coverage Status](https://img.shields.io/coveralls/aik099/phpunit-mink.svg)](https://coveralls.io/r/aik099/phpunit-mink?branch=master) +[![Coverage Status](https://coveralls.io/repos/minkphp/phpunit-mink/badge.svg?branch=master)](https://coveralls.io/r/minkphp/phpunit-mink?branch=master) [![Dependency Status](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049/badge.svg?style=flat)](https://www.versioneye.com/user/projects/52ad65e0ec1375ead3000049) [![Latest Stable Version](https://poser.pugx.org/aik099/phpunit-mink/v/stable.svg)](https://packagist.org/packages/aik099/phpunit-mink) [![Total Downloads](https://poser.pugx.org/aik099/phpunit-mink/downloads.svg)](https://packagist.org/packages/aik099/phpunit-mink) [![Latest Unstable Version](https://poser.pugx.org/aik099/phpunit-mink/v/unstable.svg)](https://packagist.org/packages/aik099/phpunit-mink) [![License](https://poser.pugx.org/aik099/phpunit-mink/license.svg)](https://packagist.org/packages/aik099/phpunit-mink) From 6e478718b80b7f62445580c83712dd96eec4ca6e Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 24 Jan 2015 11:58:58 +0200 Subject: [PATCH 077/204] Increase timeout for `testCreateBrowserConfiguration` test --- .../BrowserConfiguration/BrowserConfigurationFactoryTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index 9239a86..8137eff 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -47,6 +47,7 @@ protected function setUp() * @param string $type Type. * * @return void + * @medium * @dataProvider createBrowserConfigurationDataProvider */ public function testCreateBrowserConfiguration(array $browser_config, $type) From 730fa32a05f4cf9888a012c3337cb142d0680658 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 14 Mar 2015 19:54:40 +0200 Subject: [PATCH 078/204] Update used PHPUnit version to prevent "Class 'SebastianBergmann\Exporter\Context' not found" error --- composer.lock | 274 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 217 insertions(+), 57 deletions(-) diff --git a/composer.lock b/composer.lock index eb1e9e1..bf5a03b 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "behat/mink", - "version": "v1.6.0", + "version": "v1.6.1", "source": { "type": "git", "url": "https://github.com/minkphp/Mink.git", - "reference": "090900a0049c441f1e072bbd837db4079b2250c5" + "reference": "8b68523a339ec991bcd638b39dc8f04f808da88a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/Mink/zipball/090900a0049c441f1e072bbd837db4079b2250c5", - "reference": "090900a0049c441f1e072bbd837db4079b2250c5", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/8b68523a339ec991bcd638b39dc8f04f808da88a", + "reference": "8b68523a339ec991bcd638b39dc8f04f808da88a", "shasum": "" }, "require": { @@ -37,8 +37,8 @@ } }, "autoload": { - "psr-0": { - "Behat\\Mink": "src/" + "psr-4": { + "Behat\\Mink\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -52,14 +52,14 @@ "homepage": "http://everzet.com" } ], - "description": "Web acceptance testing framework for PHP 5.3", + "description": "Browser controller/emulator abstraction for PHP", "homepage": "http://mink.behat.org/", "keywords": [ "browser", "testing", "web" ], - "time": "2014-09-26 09:25:05" + "time": "2015-02-04 17:02:06" }, { "name": "behat/mink-selenium2-driver", @@ -231,18 +231,126 @@ ], "time": "2014-05-12 21:03:05" }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2015-02-03 12:10:50" + }, + { + "name": "phpspec/prophecy", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.2", + "phpdocumentor/reflection-docblock": "~2.0" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "http://phpspec.org", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2014-11-17 16:23:49" + }, { "name": "phpunit/php-code-coverage", - "version": "2.0.14", + "version": "2.0.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94" + "reference": "34cc484af1ca149188d0d9e91412191e398e0b67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca158276c1200cc27f5409a5e338486bc0b4fc94", - "reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67", + "reference": "34cc484af1ca149188d0d9e91412191e398e0b67", "shasum": "" }, "require": { @@ -255,7 +363,7 @@ }, "require-dev": { "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4.1" + "phpunit/phpunit": "~4" }, "suggest": { "ext-dom": "*", @@ -274,9 +382,6 @@ ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -294,7 +399,7 @@ "testing", "xunit" ], - "time": "2014-12-26 13:28:33" + "time": "2015-01-24 10:06:35" }, { "name": "phpunit/php-file-iterator", @@ -480,16 +585,16 @@ }, { "name": "phpunit/phpunit", - "version": "4.4.2", + "version": "4.5.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e90575c2bb86290d57a262862dab1da125431576" + "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e90575c2bb86290d57a262862dab1da125431576", - "reference": "e90575c2bb86290d57a262862dab1da125431576", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5b578d3865a9128b9c209b011fda6539ec06e7a5", + "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5", "shasum": "" }, "require": { @@ -499,15 +604,16 @@ "ext-reflection": "*", "ext-spl": "*", "php": ">=5.3.3", + "phpspec/prophecy": "~1.3.1", "phpunit/php-code-coverage": "~2.0", "phpunit/php-file-iterator": "~1.3.2", "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "~1.0.2", "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.0", + "sebastian/comparator": "~1.1", "sebastian/diff": "~1.1", - "sebastian/environment": "~1.1", - "sebastian/exporter": "~1.0", + "sebastian/environment": "~1.2", + "sebastian/exporter": "~1.2", "sebastian/global-state": "~1.0", "sebastian/version": "~1.0", "symfony/yaml": "~2.0" @@ -521,7 +627,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4.x-dev" + "dev-master": "4.5.x-dev" } }, "autoload": { @@ -547,7 +653,7 @@ "testing", "xunit" ], - "time": "2015-01-17 11:24:41" + "time": "2015-02-05 15:51:19" }, { "name": "phpunit/phpunit-mock-objects", @@ -652,25 +758,25 @@ }, { "name": "sebastian/comparator", - "version": "1.1.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "c484a80f97573ab934e37826dba0135a3301b26a" + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c484a80f97573ab934e37826dba0135a3301b26a", - "reference": "c484a80f97573ab934e37826dba0135a3301b26a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", "shasum": "" }, "require": { "php": ">=5.3.3", - "sebastian/diff": "~1.1", - "sebastian/exporter": "~1.0" + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" }, "require-dev": { - "phpunit/phpunit": "~4.1" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { @@ -712,7 +818,7 @@ "compare", "equality" ], - "time": "2014-11-16 21:32:38" + "time": "2015-01-29 16:28:08" }, { "name": "sebastian/diff", @@ -818,28 +924,29 @@ }, { "name": "sebastian/exporter", - "version": "1.0.2", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0" + "reference": "84839970d05254c73cde183a721c7af13aede943" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c7d59948d6e82818e1bdff7cadb6c34710eb7dc0", - "reference": "c7d59948d6e82818e1bdff7cadb6c34710eb7dc0", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", + "reference": "84839970d05254c73cde183a721c7af13aede943", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -879,7 +986,7 @@ "export", "exporter" ], - "time": "2014-09-10 00:51:36" + "time": "2015-01-27 07:23:06" }, { "name": "sebastian/global-state", @@ -932,6 +1039,59 @@ ], "time": "2014-10-06 09:23:50" }, + { + "name": "sebastian/recursion-context", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-01-24 09:48:32" + }, { "name": "sebastian/version", "version": "1.0.4", @@ -969,7 +1129,7 @@ }, { "name": "symfony/css-selector", - "version": "v2.6.3", + "version": "v2.6.4", "target-dir": "Symfony/Component/CssSelector", "source": { "type": "git", @@ -1020,17 +1180,17 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.6.3", + "version": "v2.6.4", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "40ff70cadea3785d83cac1c8309514b36113064e" + "reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/40ff70cadea3785d83cac1c8309514b36113064e", - "reference": "40ff70cadea3785d83cac1c8309514b36113064e", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/f75989f3ab2743a82fe0b03ded2598a2b1546813", + "reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813", "shasum": "" }, "require": { @@ -1074,21 +1234,21 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "http://symfony.com", - "time": "2015-01-05 14:28:40" + "time": "2015-02-01 16:10:57" }, { "name": "symfony/yaml", - "version": "v2.6.3", + "version": "v2.6.4", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "82462a90848a52c2533aa6b598b107d68076b018" + "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/82462a90848a52c2533aa6b598b107d68076b018", - "reference": "82462a90848a52c2533aa6b598b107d68076b018", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/60ed7751671113cf1ee7d7778e691642c2e9acd8", + "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8", "shasum": "" }, "require": { @@ -1121,7 +1281,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2015-01-03 15:33:07" + "time": "2015-01-25 04:39:26" } ], "packages-dev": [ @@ -1131,12 +1291,12 @@ "source": { "type": "git", "url": "https://github.com/aik099/CodingStandard.git", - "reference": "8e14991f692bdf66def663e0310a81e6d4734832" + "reference": "57a48b92960025a747a1de75aa2f5cc49f9f06e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/8e14991f692bdf66def663e0310a81e6d4734832", - "reference": "8e14991f692bdf66def663e0310a81e6d4734832", + "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/57a48b92960025a747a1de75aa2f5cc49f9f06e7", + "reference": "57a48b92960025a747a1de75aa2f5cc49f9f06e7", "shasum": "" }, "require-dev": { @@ -1163,7 +1323,7 @@ "PHP_CodeSniffer", "codesniffer" ], - "time": "2015-01-03 20:25:25" + "time": "2015-03-13 08:39:29" }, { "name": "mockery/mockery", From b44ff1711135e7a37c3df7595144f3a495580cba Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 14 Mar 2015 19:59:46 +0200 Subject: [PATCH 079/204] Check for browser configuration checksum in event listeners --- .../ApiBrowserConfiguration.php | 4 +-- .../BrowserConfiguration.php | 25 ++++--------------- .../SauceLabsBrowserConfiguration.php | 2 +- library/aik099/PHPUnit/Event/TestEvent.php | 16 ++++++++++++ .../ApiBrowserConfigurationTestCase.php | 13 +++++++--- .../BrowserConfigurationTest.php | 22 ++++++++++++++++ .../PHPUnit/Fixture/ApiIntegrationFixture.php | 2 +- 7 files changed, 57 insertions(+), 27 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index a3c5fe3..6816e05 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -158,7 +158,7 @@ public function getBrowserName() */ public function onTestSetup(TestEvent $event) { - if ( !$this->isEventForMe($event) ) { + if ( !$event->validateSubscriber($this->getTestCase()) ) { return; } @@ -202,7 +202,7 @@ protected function getJobName(BrowserTestCase $test_case) */ public function onTestEnded(TestEndedEvent $event) { - if ( !$this->isEventForMe($event) ) { + if ( !$event->validateSubscriber($this->getTestCase()) ) { return; } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 72b165a..7ee4fd2 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -455,7 +455,7 @@ public function isShared() */ public function getSessionStrategyHash() { - $ret = $this->getBrowserHash(); + $ret = $this->getChecksum(); if ( $this->isShared() ) { $ret .= '::' . get_class($this->getTestCase()); @@ -486,11 +486,11 @@ public function getTestStatus(BrowserTestCase $test_case, \PHPUnit_Framework_Tes } /** - * Returns hash from current configuration. + * Returns checksum from current configuration. * * @return integer */ - protected function getBrowserHash() + public function getChecksum() { ksort($this->parameters); @@ -534,7 +534,7 @@ protected static function arrayMergeRecursive($array1, $array2) */ public function onTestSetup(TestEvent $event) { - if ( !$this->isEventForMe($event) ) { + if ( !$event->validateSubscriber($this->getTestCase()) ) { return; } @@ -550,26 +550,11 @@ public function onTestSetup(TestEvent $event) */ public function onTestEnded(TestEndedEvent $event) { - if ( !$this->isEventForMe($event) ) { + if ( !$event->validateSubscriber($this->getTestCase()) ) { return; } $this->detachFromTestCase(); } - /** - * Determines if received event is designed for this recipient. - * - * @param TestEvent $event Event. - * - * @return boolean - */ - protected function isEventForMe(TestEvent $event) - { - $test_case = $event->getTestCase(); - - return get_class($test_case) === get_class($this->_testCase) - && $test_case->getName() === $this->_testCase->getName(); - } - } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 8e0a5fe..94618aa 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -46,7 +46,7 @@ public function __construct( */ public function onTestSetup(TestEvent $event) { - if ( !$this->isEventForMe($event) ) { + if ( !$event->validateSubscriber($this->getTestCase()) ) { return; } diff --git a/library/aik099/PHPUnit/Event/TestEvent.php b/library/aik099/PHPUnit/Event/TestEvent.php index 6540830..ce8622e 100644 --- a/library/aik099/PHPUnit/Event/TestEvent.php +++ b/library/aik099/PHPUnit/Event/TestEvent.php @@ -64,4 +64,20 @@ public function getSession() return $this->_session; } + /** + * Determines if received event is designed for given test case. + * + * @param BrowserTestCase $test_case Test case for comparison. + * + * @return boolean + */ + public function validateSubscriber(BrowserTestCase $test_case) + { + $event_test_case = $this->getTestCase(); + + return get_class($event_test_case) === get_class($test_case) + && $event_test_case->getName() === $test_case->getName() + && $event_test_case->getBrowser()->getChecksum() === $test_case->getBrowser()->getChecksum(); + } + } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 50681ea..12b15ac 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -312,7 +312,7 @@ public function theTestEndedEventDataProvider() */ public function testTestEndedWithoutSession($stopped_or_missing) { - $test_case = $this->createTestCase('TEST_NAME'); + $test_case = $this->createTestCase('TEST_NAME', false); $event_dispatcher = new EventDispatcher(); $event_dispatcher->addSubscriber($this->browser); @@ -332,6 +332,7 @@ public function testTestEndedWithoutSession($stopped_or_missing) $event->shouldReceive('setName')->once(); // To remove with Symfony 3.0 release. $event->shouldReceive('isPropagationStopped')->once()->andReturn(false); $event->shouldReceive('getTestCase')->andReturn($test_case); + $event->shouldReceive('validateSubscriber')->with($test_case)->atLeast()->once()->andReturn(true); $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); $returned_event = $event_dispatcher->dispatch(BrowserTestCase::TEST_ENDED_EVENT, $event); @@ -350,14 +351,20 @@ public function sessionStateDataProvider() /** * Create TestCase with Browser. * - * @param string $name Test case name. + * @param string $name Test case name. + * @param boolean $get_browser Create browser expectation. * * @return BrowserTestCase */ - protected function createTestCase($name) + protected function createTestCase($name, $get_browser = true) { $test_case = m::mock(self::TEST_CASE_CLASS); $test_case->shouldReceive('getName')->andReturn($name); + + if ( $get_browser ) { + $test_case->shouldReceive('getBrowser')->atLeast()->once()->andReturn($this->browser); + } + $this->browser->attachToTestCase($test_case); return $test_case; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index a7d93a2..a251e81 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -461,6 +461,28 @@ public function testGetTestStatusShared() $this->assertTrue($this->browser->getTestStatus($test_case, $test_result)); } + public function testChecksumMatch() + { + $browser1 = $this->createBrowserConfiguration(); + $browser1->setBrowserName('opera'); + + $browser2 = $this->createBrowserConfiguration(); + $browser2->setBrowserName('opera'); + + $this->assertSame($browser1->getChecksum(), $browser2->getChecksum()); + } + + public function testChecksumMismatch() + { + $browser1 = $this->createBrowserConfiguration(); + $browser1->setBrowserName('opera'); + + $browser2 = $this->createBrowserConfiguration(); + $browser2->setBrowserName('firefox'); + + $this->assertNotSame($browser1->getChecksum(), $browser2->getChecksum()); + } + /** * Creates instance of browser configuration. * diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index be186d4..4cda1d2 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -92,7 +92,7 @@ public function verifyRemoteAPICalls(TestEvent $event) { $test_case = $event->getTestCase(); - if ( get_class($test_case) !== get_class($this) || $test_case->getName() !== $this->getName() ) { + if ( !$event->validateSubscriber($this) ) { return; } From 50f5e2a810300d4778df936c7bfc1adc1406ae3c Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Mon, 16 Mar 2015 11:55:59 +0100 Subject: [PATCH 080/204] Improve the Travis config - split the doc build to a separate job in the matrix - switch to the faster Docker-based infrastructure --- .travis.yml | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3b527e6..afc3ced 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,11 @@ language: php +sudo: false + +cache: + directories: + - $HOME/.composer/cache + php: - 5.3 - 5.4 @@ -7,23 +13,34 @@ php: - 5.6 - hhvm +matrix: + include: + - env: BUILD_TYPE=doc # marker environment variable to make the build matrix more readable in the UI + # Override the different steps of the build config + language: python + before_install: [] + install: pip install Sphinx sphinx_rtd_theme + before_script: [] + script: sphinx-build -nW -b html -d docs/build/doctrees docs docs/build/html + after_script: [] + env: global: + - BUILD_TYPE=code - secure: HhIy0kN0+UbuLeaVBk7O/utAYo038a9Emr8cdcfU+LQTu6CfGEbifH+LddXs6M/bSLTdNUSwQSnwycbeNYZ6iHCO/JI/vEgKxCTSecPerMXBIVCQjFZaCp3Tev8JJ40hKe78WJ/d0G4bGtIR6atR5V+H8Z29iwJeFtCj6doEt3o= - secure: oLadQTqg8HSEmUC0qEtChKd/R0ZiFNhzoZjIaa8kAJ0fjln/2xfNCBQIg4YstyjFy2kLiP6Lg8xW/RZljzyTHC+MCB9NNqTYjKLqFNRvFOlZUOnrAwc4sl4qjMYu9klWKa+rfyZzsuVWn++g829s2lFopkImqa6EB9DOR2TOT6w= addons: sauce_connect: true +install: + - composer require satooshi/php-coveralls:dev-master --dev + before_script: - - composer require satooshi/php-coveralls:dev-master --dev --prefer-source - - sudo easy_install -U Sphinx - - sudo pip install sphinx_rtd_theme + - mkdir -p build/logs script: - - mkdir -p build/logs - phpunit -v --coverage-clover build/logs/clover.xml - - sphinx-build -nW -b html -d docs/build/doctrees docs docs/build/html after_script: - php vendor/bin/coveralls -v From 36c04d59eacb445633212503fe4543844140c7b3 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 14 Mar 2015 20:02:12 +0200 Subject: [PATCH 081/204] Complete support for BrowserStack - complete support for BrowserStack - added "IAPIClient::getInfo" method for getting session-related data from SauceLabs/BrowserStack - updated DocBlock of "IAPIClient::updateStatus" to indicate that in fact array is being returned instead of boolean - the "ApiBrowserConfiguration::getAPIClient" method was made public to allow users interacting with SauceLabs/BrowserStack - update default Windows version to "Windows 7" in BrowserStack browser configuration - added BrowserStack API credentials (only direct pushes can use them) to Travis CI config - added tunneling support to BrowserStackBrowserConfiguration - updated docs to include BrowserStack support/examples --- .travis.yml | 2 + docs/configuration.rst | 4 +- .../configuration/config_via_setup_method.php | 9 +++ ...ce_labs.php => cloud_selenium_configs.php} | 10 ++- docs/getting-started.rst | 14 ++-- .../APIClient/BrowserStackAPIClient.php | 19 ++++- .../aik099/PHPUnit/APIClient/IAPIClient.php | 11 ++- .../PHPUnit/APIClient/SauceLabsAPIClient.php | 14 +++- .../ApiBrowserConfiguration.php | 2 +- .../BrowserStackBrowserConfiguration.php | 28 +++++++- phpunit.xml.dist | 2 + .../ApiBrowserConfigurationTestCase.php | 72 +++++++++++++++++++ .../BrowserStackBrowserConfigurationTest.php | 9 ++- .../SauceLabsBrowserConfigurationTest.php | 60 ++-------------- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 54 +++++++++----- .../PHPUnit/Fixture/SetupEventFixture.php | 5 +- 16 files changed, 223 insertions(+), 92 deletions(-) rename docs/examples/getting-started/{sauce_labs.php => cloud_selenium_configs.php} (64%) diff --git a/.travis.yml b/.travis.yml index afc3ced..9d298b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,8 @@ env: - BUILD_TYPE=code - secure: HhIy0kN0+UbuLeaVBk7O/utAYo038a9Emr8cdcfU+LQTu6CfGEbifH+LddXs6M/bSLTdNUSwQSnwycbeNYZ6iHCO/JI/vEgKxCTSecPerMXBIVCQjFZaCp3Tev8JJ40hKe78WJ/d0G4bGtIR6atR5V+H8Z29iwJeFtCj6doEt3o= - secure: oLadQTqg8HSEmUC0qEtChKd/R0ZiFNhzoZjIaa8kAJ0fjln/2xfNCBQIg4YstyjFy2kLiP6Lg8xW/RZljzyTHC+MCB9NNqTYjKLqFNRvFOlZUOnrAwc4sl4qjMYu9klWKa+rfyZzsuVWn++g829s2lFopkImqa6EB9DOR2TOT6w= + - secure: Tsh/Vvb9auy672eRf0xbN8fKDr8OYzjRkZDHiaYc5yH49UkoromwPaC74mJtM5KxFOYalrC+GzwOSuvzT8RYO/XwTuk6IGw9P/0v0qMCaSLkjaRzerwVH1L3RPgDokqDnCHAgSzkAlg8d5o0MWBlbxaYiaKL4LmEKGwxQjrW590= + - secure: HQQ1FY27tpn0Idy+NDYXdbnMjHKIOsZoE59qYfs18euS0zM559gcuMk4OQ/J2lcDFmdb6vjSFlznwH+6iVyoLuC5WAP3JGQ3UXSJ+7huRV/eDI6WepmEymjEOSWvTT+RYpmQu1lQWC2Y3zBCVbVT7sbVsqXvmuR2daBL11dpU+g= addons: sauce_connect: true diff --git a/docs/configuration.rst b/docs/configuration.rst index e06e7b4..de42d22 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -11,7 +11,7 @@ method in of test case class and setting it via ``setBrowser`` method. .. literalinclude:: examples/configuration/config_via_setup_method.php :linenos: - :emphasize-lines: 11,16,25-29,32 + :emphasize-lines: 11,16,25,34-38,41 Per Test Case Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ Name Description that will be used by Selenium server ``baseUrl`` base url of website, that is tested ``sessionStrategy`` used session strategy (defaults to ``isolated``) -``type`` type of configuration (defaults to ``default``, but can also be ``saucelabs``) +``type`` type of configuration (defaults to ``default``, but can also be ``saucelabs`` or ``browserstack``) ``api_username`` API username of used service (applicable to any but ``default`` configuration type) ``api_key`` API key of used service (applicable to any but ``default`` configuration type) ======================= ================================================================================================= diff --git a/docs/examples/configuration/config_via_setup_method.php b/docs/examples/configuration/config_via_setup_method.php index 4ecc534..bef3198 100644 --- a/docs/examples/configuration/config_via_setup_method.php +++ b/docs/examples/configuration/config_via_setup_method.php @@ -21,6 +21,15 @@ protected function setUp() // optional options goes here )); + // To create "BrowserStack" browser configuration via BrowserConfigurationFactory. + $browser = $this->createBrowserConfiguration(array( + // required + 'type' => 'browserstack', + 'api_username' => 'bs_username', + 'api_key' => 'bs_api_key', + // optional options goes here + )); + // Options can be changed later (optional). $browser->setHost('selenium_host')->setPort('selenium_port')->setTimeout(30); $browser->setBrowserName('browser name')->setDesiredCapabilities(array( diff --git a/docs/examples/getting-started/sauce_labs.php b/docs/examples/getting-started/cloud_selenium_configs.php similarity index 64% rename from docs/examples/getting-started/sauce_labs.php rename to docs/examples/getting-started/cloud_selenium_configs.php index c7e609b..1aae06d 100644 --- a/docs/examples/getting-started/sauce_labs.php +++ b/docs/examples/getting-started/cloud_selenium_configs.php @@ -2,7 +2,7 @@ use aik099\PHPUnit\BrowserTestCase; -class SauceLabsTest extends BrowserTestCase +class BrowserConfigExampleTest extends BrowserTestCase { public static $browsers = array( @@ -14,6 +14,14 @@ class SauceLabsTest extends BrowserTestCase 'browserName' => 'firefox', 'baseUrl' => 'http://www.google.com', ), + // BrowserStack browser configuration. + array( + 'type' => 'browserstack', + 'api_username' => '...', + 'api_key' => '...', + 'browserName' => 'firefox', + 'baseUrl' => 'http://www.google.com', + ), // Regular browser configuration. array( 'host' => 'localhost', diff --git a/docs/getting-started.rst b/docs/getting-started.rst index 15e32d7..0fe1798 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -34,20 +34,22 @@ Basic Usage :linenos: :emphasize-lines: 5,8,20,34 -Using "Sauce Labs" -^^^^^^^^^^^^^^^^^^ -When using `Sauce Labs `_ account to perform Selenium server-based testing you need to +Selenium in Cloud +^^^^^^^^^^^^^^^^^ +When using Selenium-based solution for automated testing in the cloud (e.g. `Sauce Labs`_ or `BrowserStack`_) you need to specify following settings: -* ``'type' => 'saucelabs'`` +* ``'type' => 'saucelabs'`` or ``'type' => 'browserstack'`` * ``'api_username' => '...'`` * ``'api_key' => '...'`` instead of ``host`` and ``port`` settings. In all other aspects everything will work the same as if all tests were running locally. -.. literalinclude:: examples/getting-started/sauce_labs.php +.. literalinclude:: examples/getting-started/cloud_selenium_configs.php :linenos: - :emphasize-lines: 11-13 + :emphasize-lines: 11-13,19-21 .. _`Mink`: https://github.com/Behat/Mink +.. _`Sauce Labs`: https://saucelabs.com/ +.. _`BrowserStack`: http://www.browserstack.com/ diff --git a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php index 5ec84fa..3abe7d5 100644 --- a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php @@ -51,19 +51,34 @@ public function __construct($api_username, $api_key, CurlServiceInterface $curl_ $this->_curlService = $curl_service; } + /** + * Returns information about session. + * + * @param string $session_id Session ID. + * + * @return array + */ + public function getInfo($session_id) + { + $result = $this->execute('GET', 'sessions/' . $session_id . '.json'); + + return $result['automation_session']; + } + /** * Update status of the test, that was executed in the given session. * * @param string $session_id Session ID. * @param boolean $test_status Test status. * - * @return boolean + * @return array */ public function updateStatus($session_id, $test_status) { $data = array('status' => $test_status ? 'completed' : 'error'); + $result = $this->execute('PUT', 'sessions/' . $session_id . '.json', $data); - return $this->execute('PUT', 'sessions/' . $session_id . '.json', json_encode($data)); + return $result['automation_session']; } /** diff --git a/library/aik099/PHPUnit/APIClient/IAPIClient.php b/library/aik099/PHPUnit/APIClient/IAPIClient.php index 61d76e8..294ae98 100644 --- a/library/aik099/PHPUnit/APIClient/IAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/IAPIClient.php @@ -17,13 +17,22 @@ interface IAPIClient { + /** + * Returns information about session. + * + * @param string $session_id Session ID. + * + * @return array + */ + public function getInfo($session_id); + /** * Update status of the test, that was executed in the given session. * * @param string $session_id Session ID. * @param boolean $test_status Test status. * - * @return boolean + * @return array */ public function updateStatus($session_id, $test_status); diff --git a/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php b/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php index ee0b6fa..4875292 100644 --- a/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php @@ -33,13 +33,25 @@ public function __construct(SauceRest $sauce_rest) $this->_sauceRest = $sauce_rest; } + /** + * Returns information about session. + * + * @param string $session_id Session ID. + * + * @return array + */ + public function getInfo($session_id) + { + return $this->_sauceRest->getJob($session_id); + } + /** * Update status of the test, that was executed in the given session. * * @param string $session_id Session ID. * @param boolean $test_status Test status. * - * @return boolean + * @return array */ public function updateStatus($session_id, $test_status) { diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index 6816e05..0dd97f6 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -228,7 +228,7 @@ public function onTestEnded(TestEndedEvent $event) * * @return IAPIClient */ - protected function getAPIClient() + public function getAPIClient() { return $this->browserConfigurationFactory->createAPIClient($this); } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php index 3d8a7ad..dc61bd9 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php @@ -11,6 +11,7 @@ namespace aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\Event\TestEvent; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** @@ -36,6 +37,31 @@ public function __construct( parent::__construct($event_dispatcher, $browser_configuration_factory); } + /** + * Hook, called from "BrowserTestCase::setUp" method. + * + * @param TestEvent $event Test event. + * + * @return void + */ + public function onTestSetup(TestEvent $event) + { + if ( !$event->validateSubscriber($this->getTestCase()) ) { + return; + } + + parent::onTestSetup($event); + + $desired_capabilities = $this->getDesiredCapabilities(); + + if ( getenv('TRAVIS_JOB_NUMBER') ) { + $desired_capabilities['browserstack.local'] = 'true'; + $desired_capabilities['browserstack.localIdentifier'] = getenv('TRAVIS_JOB_NUMBER'); + } + + $this->setDesiredCapabilities($desired_capabilities); + } + /** * Returns hostname from browser configuration. * @@ -58,7 +84,7 @@ public function getDesiredCapabilities() if ( !isset($capabilities['os']) ) { $capabilities['os'] = 'Windows'; - $capabilities['os_version'] = 'XP'; + $capabilities['os_version'] = '7'; } if ( !isset($capabilities['acceptSslCerts']) ) { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 2da3c06..3fdccbf 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -28,6 +28,8 @@ diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 12b15ac..b34290a 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -42,6 +42,13 @@ abstract class ApiBrowserConfigurationTestCase extends BrowserConfigurationTest */ protected $browserConfigurationFactory; + /** + * Desired capabilities use to configure the tunnel. + * + * @var array + */ + protected $tunnelCapabilities = array(); + /** * Configures all tests. * @@ -52,6 +59,7 @@ protected function setUp() $this->testsRequireSubscriber[] = 'testTestSetupEvent'; $this->testsRequireSubscriber[] = 'testTestEndedEvent'; $this->testsRequireSubscriber[] = 'testTestEndedWithoutSession'; + $this->testsRequireSubscriber[] = 'testTunnelIdentifier'; $this->browserConfigurationFactory = m::mock( 'aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory' ); @@ -370,6 +378,70 @@ protected function createTestCase($name, $get_browser = true) return $test_case; } + /** + * Test description. + * + * @param string|null $travis_job_number Travis Job Number. + * + * @return void + * @dataProvider tunnelIdentifierDataProvider + */ + public function testTunnelIdentifier($travis_job_number = null) + { + // Reset any global env vars that might be left from previous tests. + $hhvm_hack = defined('HHVM_VERSION') ? '=' : ''; + + putenv('TRAVIS_JOB_NUMBER' . $hhvm_hack); + + if ( isset($travis_job_number) ) { + putenv('TRAVIS_JOB_NUMBER=' . $travis_job_number); + } + + $this->browser->setSessionStrategy(ISessionStrategyFactory::TYPE_ISOLATED); + + $test_case = $this->createTestCase('TEST_NAME'); + $test_case->shouldReceive('toString')->andReturn('TEST_NAME'); + + $event_dispatcher = new EventDispatcher(); + $event_dispatcher->addSubscriber($this->browser); + + $event_dispatcher->dispatch( + BrowserTestCase::TEST_SETUP_EVENT, + new TestEvent($test_case, m::mock('Behat\\Mink\\Session')) + ); + + $desired_capabilities = $this->browser->getDesiredCapabilities(); + + if ( isset($travis_job_number) ) { + foreach ( $this->tunnelCapabilities as $name => $value ) { + if ( substr($value, 0, 4) === 'env:' ) { + $value = getenv(substr($value, 4)); + } + + $this->assertArrayHasKey($name, $desired_capabilities); + $this->assertEquals($value, $desired_capabilities[$name]); + } + } + else { + foreach ( array_keys($this->tunnelCapabilities) as $name ) { + $this->assertArrayNotHasKey($name, $desired_capabilities); + } + } + } + + /** + * Provides Travis job numbers. + * + * @return array + */ + public function tunnelIdentifierDataProvider() + { + return array( + array('AAA'), + array(null), + ); + } + /** * Creates instance of browser configuration. * diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php index 7c184e1..d858671 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -27,10 +27,15 @@ protected function setUp() { $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserStackBrowserConfiguration'; + $this->tunnelCapabilities = array( + 'browserstack.local' => 'true', + 'browserstack.localIdentifier' => 'env:TRAVIS_JOB_NUMBER', + ); + parent::setUp(); $this->setup['desiredCapabilities'] = array( - 'os' => 'Windows', 'os_version' => '7', 'version' => 10, + 'os' => 'Windows', 'os_version' => 'XP', 'version' => 10, 'acceptSslCerts' => 'true', ); $this->setup['host'] = 'UN:AK@hub.browserstack.com'; @@ -63,7 +68,7 @@ public function desiredCapabilitiesDataProvider() ), array( array('acceptSslCerts' => 'false'), - array('acceptSslCerts' => 'false', 'os' => 'Windows', 'os_version' => 'XP'), + array('acceptSslCerts' => 'false', 'os' => 'Windows', 'os_version' => '7'), ), ); } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 771f131..21949a8 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -29,67 +29,15 @@ class SauceLabsBrowserConfigurationTest extends ApiBrowserConfigurationTestCase */ protected function setUp() { - $this->testsRequireSubscriber[] = 'testTunnelIdentifier'; $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\SauceLabsBrowserConfiguration'; - parent::setUp(); - - $this->setup['host'] = 'UN:AK@ondemand.saucelabs.com'; - } - - /** - * Test description. - * - * @param string|null $travis_job_number Travis Job Number. - * - * @return void - * @dataProvider tunnelIdentifierDataProvider - */ - public function testTunnelIdentifier($travis_job_number = null) - { - // Reset any global env vars that might be left from previous tests. - $hhvm_hack = defined('HHVM_VERSION') ? '=' : ''; - putenv('TRAVIS_JOB_NUMBER' . $hhvm_hack); - - if ( isset($travis_job_number) ) { - putenv('TRAVIS_JOB_NUMBER=' . $travis_job_number); - } - - $this->browser->setSessionStrategy(ISessionStrategyFactory::TYPE_ISOLATED); - - $test_case = $this->createTestCase('TEST_NAME'); - $test_case->shouldReceive('toString')->andReturn('TEST_NAME'); - - $event_dispatcher = new EventDispatcher(); - $event_dispatcher->addSubscriber($this->browser); - - $event_dispatcher->dispatch( - BrowserTestCase::TEST_SETUP_EVENT, - new TestEvent($test_case, m::mock('Behat\\Mink\\Session')) + $this->tunnelCapabilities = array( + 'tunnel-identifier' => 'env:TRAVIS_JOB_NUMBER', ); - $desired_capabilities = $this->browser->getDesiredCapabilities(); - - if ( isset($travis_job_number) ) { - $this->assertArrayHasKey('tunnel-identifier', $desired_capabilities); - $this->assertEquals($travis_job_number, $desired_capabilities['tunnel-identifier']); - } - else { - $this->assertArrayNotHasKey('tunnel-identifier', $desired_capabilities); - } - } + parent::setUp(); - /** - * Provides Travis job numbers. - * - * @return array - */ - public function tunnelIdentifierDataProvider() - { - return array( - array('AAA'), - array(null), - ); + $this->setup['host'] = 'UN:AK@ondemand.saucelabs.com'; } /** diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index 4cda1d2..bc702c5 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -11,12 +11,13 @@ namespace tests\aik099\PHPUnit\Fixture; +use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\Event\TestEvent; use Mockery as m; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use WebDriver\SauceLabs\SauceRest; class ApiIntegrationFixture extends BrowserTestCase { @@ -28,7 +29,7 @@ class ApiIntegrationFixture extends BrowserTestCase */ public static $browsers = array( array('alias' => 'saucelabs'), - // array('alias' => 'browserstack'), + array('alias' => 'browserstack'), ); /** @@ -75,7 +76,7 @@ public function recordSessionId(TestEvent $event) $session = $event->getSession(); if ( $session === null ) { - $this->markTestSkipped('Unable to connect to SauceLabs. Please check Internet connection.'); + $this->markTestSkipped('Unable to connect to SauceLabs/BrowserStack. Please check Internet connection.'); } $this->_sessionIds[$test_case->getName(false)] = $session->getDriver()->getWebDriverSessionId(); @@ -90,12 +91,11 @@ public function recordSessionId(TestEvent $event) */ public function verifyRemoteAPICalls(TestEvent $event) { - $test_case = $event->getTestCase(); - if ( !$event->validateSubscriber($this) ) { return; } + $test_case = $event->getTestCase(); $test_name = $test_case->getName(false); if ( !isset($this->_sessionIds[$test_name]) ) { @@ -104,18 +104,28 @@ public function verifyRemoteAPICalls(TestEvent $event) $browser = $this->getBrowser(); - if ( $browser instanceof SauceLabsBrowserConfiguration ) { - $sauce_rest = new SauceRest($browser->getApiUsername(), $browser->getApiKey()); - $job_info = $sauce_rest->getJob($this->_sessionIds[$test_name]); + if ( $browser instanceof ApiBrowserConfiguration ) { + $api_client = $browser->getAPIClient(); + $session_info = $api_client->getInfo($this->_sessionIds[$test_name]); - $this->assertEquals(get_class($test_case) . '::' . $test_name, $job_info['name']); + $this->assertEquals(get_class($test_case) . '::' . $test_name, $session_info['name']); - $passed_mapping = array( - 'testSuccess' => true, - 'testFailure' => false, - ); + if ( $browser instanceof SauceLabsBrowserConfiguration ) { + $passed_mapping = array( + 'testSuccess' => true, + 'testFailure' => false, + ); - $this->assertSame($passed_mapping[$test_name], $job_info['passed']); + $this->assertSame($passed_mapping[$test_name], $session_info['passed']); + } + elseif ( $browser instanceof BrowserStackBrowserConfiguration ) { + $passed_mapping = array( + 'testSuccess' => 'done', + 'testFailure' => 'error', + ); + + $this->assertSame($passed_mapping[$test_name], $session_info['status']); + } } } @@ -185,12 +195,17 @@ public function getBrowserAliases() 'api_key' => getenv('SAUCE_ACCESS_KEY'), 'browserName' => 'chrome', - 'desiredCapabilities' => array('version' => 28), + 'desiredCapabilities' => array('version' => 38), 'baseUrl' => 'http://www.google.com', ), - /*'browserstack' => array( + 'browserstack' => array( 'type' => 'browserstack', - ),*/ + 'api_username' => getenv('BS_USERNAME'), + 'api_key' => getenv('BS_ACCESS_KEY'), + + 'browserName' => 'chrome', + 'desiredCapabilities' => array('browser_version' => '38.0', 'project' => 'PHPUnit-Mink'), + ), ); } @@ -203,6 +218,11 @@ private function _getTestSkipMessage() return 'SauceLabs integration is not configured'; } } + elseif ( $browser->getType() == 'browserstack' ) { + if ( !getenv('BS_USERNAME') || !getenv('BS_ACCESS_KEY') ) { + return 'BrowserStack integration is not configured'; + } + } return ''; } diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index 5ec3cb3..f3b0cc3 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -62,8 +62,9 @@ public function testEvents() // For SauceLabsBrowserConfiguration::onTestEnded. $session->shouldReceive('getDriver')->once()->andReturn($driver); - // For IsolatedSessionStrategy::onTestEnd (twice because we have 2 strategies listening for test end). - $session->shouldReceive('stop')->twice(); + // For IsolatedSessionStrategy::onTestEnd (twice per each browser because + // we have 2 strategies listening for test end). + $session->shouldReceive('stop')->times(4); $session->shouldReceive('isStarted')->andReturn(true); $this->_setSession($session); From 23040675c67fb6f5abc7a6cc05c00380814c0e02 Mon Sep 17 00:00:00 2001 From: Vinai Kopp Date: Tue, 17 Feb 2015 12:49:29 +0100 Subject: [PATCH 082/204] Allow to specify Mink driver in browser configuration * add option for specifying Mink driver as part of the browser configuration * set driver to 'selenium2' to preserve backwards compatibility * add driver factories for Selenium2, Zombie, Goutte and Sahi drivers (only basic options supported) * allows to register additional Mink drivers For example, to configure a test to run with the Goutte driver, use public static $browsers = array( array( 'driver' => 'goutte', ) ); There also is a new configuration option 'driverOptions' which can be used by driver factories when instantiating the Mink driver. It defaults to an empty arrray, places no restriction on the data structure and is currently not used by any of the driver factories. --- .../BrowserConfiguration.php | 66 ++++++++++++- .../MinkDriver/GoutteDriverFactory.php | 33 +++++++ .../PHPUnit/MinkDriver/IMinkDriverFactory.php | 31 ++++++ .../PHPUnit/MinkDriver/SahiDriverFactory.php | 36 +++++++ .../MinkDriver/Selenium2DriverFactory.php | 46 +++++++++ .../MinkDriver/ZombieDriverFactory.php | 39 ++++++++ .../aik099/PHPUnit/Session/SessionFactory.php | 95 ++++++++++++++++--- .../BrowserConfigurationTest.php | 29 ++++++ .../MinkDriver/GoutteDriverFactoryTest.php | 51 ++++++++++ .../MinkDriver/SahiDriverFactoryTest.php | 54 +++++++++++ .../MinkDriver/Selenium2DriverFactoryTest.php | 56 +++++++++++ .../MinkDriver/ZombieDriverFactoryTest.php | 54 +++++++++++ .../PHPUnit/Session/SessionFactoryTest.php | 54 +++++++++++ 13 files changed, 631 insertions(+), 13 deletions(-) create mode 100644 library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php create mode 100644 library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php create mode 100644 library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php create mode 100644 library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php create mode 100644 library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php create mode 100644 tests/aik099/PHPUnit/MinkDriver/GoutteDriverFactoryTest.php create mode 100644 tests/aik099/PHPUnit/MinkDriver/SahiDriverFactoryTest.php create mode 100644 tests/aik099/PHPUnit/MinkDriver/Selenium2DriverFactoryTest.php create mode 100644 tests/aik099/PHPUnit/MinkDriver/ZombieDriverFactoryTest.php diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 7ee4fd2..90ed6df 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -14,7 +14,6 @@ use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Event\TestEvent; -use aik099\PHPUnit\IEventDispatcherAware; use aik099\PHPUnit\Session\ISessionStrategyFactory; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -42,12 +41,23 @@ class BrowserConfiguration implements EventSubscriberInterface 'browserName' => 'firefox', 'desiredCapabilities' => array(), 'baseUrl' => '', + 'driver' => 'selenium2', + 'driverOptions' => array(), // Test related. 'type' => 'default', 'sessionStrategy' => ISessionStrategyFactory::TYPE_ISOLATED, ); + /** + * List of driver aliases. Used for validation in the setDriver() method. + * + * @var array + */ + protected $driverAliases = array( + 'selenium2', 'goutte', 'sahi', 'zombie', + ); + /** * Browser configuration. * @@ -212,6 +222,7 @@ public function setup(array $parameters) } $this->setHost($parameters['host'])->setPort($parameters['port'])->setTimeout($parameters['timeout']); + $this->setDriver($parameters['driver']); $this->setBrowserName($parameters['browserName'])->setDesiredCapabilities($parameters['desiredCapabilities']); $this->setBaseUrl($parameters['baseUrl']); $this->setSessionStrategy($parameters['sessionStrategy']); @@ -355,6 +366,59 @@ public function getBaseUrl() return $this->parameters['baseUrl']; } + /** + * Set the Mink driver to use. + * + * @param string $driver The driver to use. + * + * @return self + * @throws \InvalidArgumentException When Mink driver is not a string. + */ + public function setDriver($driver) + { + if ( !is_string($driver) ) { + throw new \InvalidArgumentException('The Mink driver must be a string'); + } + + $this->parameters['driver'] = $driver; + + return $this; + } + + /** + * Returns the Mink driver. + * + * @return string + */ + public function getDriver() + { + return $this->parameters['driver']; + } + + /** + * Sets driver options to be used by the driver factory. + * + * @param array $driver_options Set Mink driver specific options. + * + * @return self + */ + public function setDriverOptions(array $driver_options) + { + $this->parameters['driverOptions'] = $driver_options; + + return $this; + } + + /** + * Returns Mink driver options. + * + * @return array + */ + public function getDriverOptions() + { + return $this->parameters['driverOptions']; + } + /** * Sets desired capabilities to browser configuration. * diff --git a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php new file mode 100644 index 0000000..3626fbd --- /dev/null +++ b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php @@ -0,0 +1,33 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use Behat\Mink\Driver\GoutteDriver; + +class GoutteDriverFactory implements IMinkDriverFactory +{ + + /** + * Return a new instance of the Goutte driver. + * + * @param BrowserConfiguration $browser The browser configuration. + * + * @return GoutteDriver + */ + public function getInstance(BrowserConfiguration $browser) + { + return new GoutteDriver(); + } + +} diff --git a/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php new file mode 100644 index 0000000..c18a4a4 --- /dev/null +++ b/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php @@ -0,0 +1,31 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use Behat\Mink\Driver\DriverInterface; + +interface IMinkDriverFactory +{ + + /** + * Return a new driver instance according to the + * browser configuration. + * + * @param BrowserConfiguration $browser The browser configuration. + * + * @return DriverInterface + */ + public function getInstance(BrowserConfiguration $browser); + +} diff --git a/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php new file mode 100644 index 0000000..6e1b1bb --- /dev/null +++ b/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php @@ -0,0 +1,36 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use Behat\Mink\Driver\SahiDriver; + +class SahiDriverFactory implements IMinkDriverFactory +{ + + /** + * Return a new SahiDriver instance + * + * @param BrowserConfiguration $browser The browser configuration. + * + * @return SahiDriver + */ + public function getInstance(BrowserConfiguration $browser) + { + $connection = new \Behat\SahiClient\Connection(null, $browser->getHost(), $browser->getPort()); + $driver = new SahiDriver($browser->getBrowserName(), new \Behat\SahiClient\Client($connection)); + + return $driver; + } + +} diff --git a/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php b/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php new file mode 100644 index 0000000..fd1ea6b --- /dev/null +++ b/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php @@ -0,0 +1,46 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use Behat\Mink\Driver\Selenium2Driver; + +class Selenium2DriverFactory implements IMinkDriverFactory +{ + + /** + * Instantiate and return the selenium 2 driver instance. + * + * @param BrowserConfiguration $browser The browser configuration. + * + * @return Selenium2Driver + */ + public function getInstance(BrowserConfiguration $browser) + { + $browser_name = $browser->getBrowserName(); + $capabilities = $browser->getDesiredCapabilities(); + $capabilities['browserName'] = $browser_name; + + // TODO: maybe doesn't work! + ini_set('default_socket_timeout', $browser->getTimeout()); + + $driver = new Selenium2Driver( + $browser_name, + $capabilities, + 'http://' . $browser->getHost() . ':' . $browser->getPort() . '/wd/hub' + ); + + return $driver; + } + +} diff --git a/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php new file mode 100644 index 0000000..31bb010 --- /dev/null +++ b/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php @@ -0,0 +1,39 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use Behat\Mink\Driver\NodeJS\Server\ZombieServer; +use Behat\Mink\Driver\ZombieDriver; + +class ZombieDriverFactory implements IMinkDriverFactory +{ + + /** + * Return a new instance of the Zombie driver. + * + * @param BrowserConfiguration $browser The browser configuration. + * + * @return ZombieDriver + */ + public function getInstance(BrowserConfiguration $browser) + { + $options = $browser->getDriverOptions(); + $node_bin = isset($options['node_binary']) ? $options['node_binary'] : null; + + return new ZombieDriver( + new ZombieServer($browser->getHost(), $browser->getPort(), $node_bin) + ); + } + +} diff --git a/library/aik099/PHPUnit/Session/SessionFactory.php b/library/aik099/PHPUnit/Session/SessionFactory.php index dde2135..5f05fb2 100644 --- a/library/aik099/PHPUnit/Session/SessionFactory.php +++ b/library/aik099/PHPUnit/Session/SessionFactory.php @@ -12,8 +12,8 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; use Behat\Mink\Driver\DriverInterface; -use Behat\Mink\Driver\Selenium2Driver; use Behat\Mink\Session; /** @@ -24,6 +24,37 @@ class SessionFactory implements ISessionFactory { + /** + * The driver factory registry. + * + * @var IMinkDriverFactory[] + */ + private $_driverFactoryRegistry = array(); + + /** + * The default driver factories. Only those present will be added to the $_driverFactoryRegistry array. + * + * @var string[] + */ + private $_defaultDriverFactories = array( + 'selenium2' => 'aik099\PHPUnit\MinkDriver\Selenium2DriverFactory', + 'sahi' => 'aik099\PHPUnit\MinkDriver\SahiDriverFactory', + 'goutte' => 'aik099\PHPUnit\MinkDriver\GoutteDriverFactory', + 'zombie' => 'aik099\PHPUnit\MinkDriver\ZombieDriverFactory', + ); + + /** + * Initialize the driver factory registry array. + */ + public function __construct() + { + foreach ( $this->_defaultDriverFactories as $alias => $factory_class ) { + if ( class_exists($factory_class) ) { + $this->registerDriverFactory($alias, new $factory_class()); + } + } + } + /** * Creates new session based on browser configuration. * @@ -45,20 +76,60 @@ public function createSession(BrowserConfiguration $browser) */ private function _createDriver(BrowserConfiguration $browser) { - $browser_name = $browser->getBrowserName(); - $capabilities = $browser->getDesiredCapabilities(); - $capabilities['browserName'] = $browser_name; + $driver_alias = $browser->getDriver(); - // TODO: maybe doesn't work! - ini_set('default_socket_timeout', $browser->getTimeout()); + if ( !array_key_exists($driver_alias, $this->_driverFactoryRegistry) ) { + throw new \OutOfBoundsException(sprintf('No driver factory for driver "%s"', $driver_alias)); + } - $driver = new Selenium2Driver( - $browser_name, - $capabilities, - 'http://' . $browser->getHost() . ':' . $browser->getPort() . '/wd/hub' - ); + $factory = $this->_getDriverFactory($driver_alias); - return $driver; + return $factory->getInstance($browser); + } + + /** + * Lazy instantiation of the driver factory. + * + * @param string $driver_alias The driver alias for the driver factory. + * + * @return IMinkDriverFactory + */ + private function _getDriverFactory($driver_alias) + { + if ( is_string($this->_driverFactoryRegistry[$driver_alias]) ) { + $this->_driverFactoryRegistry[$driver_alias] = new $this->_driverFactoryRegistry[$driver_alias](); + } + + return $this->_driverFactoryRegistry[$driver_alias]; + } + + /** + * Register a new mink driver factory by either specifying the class name or an instance. + * + * @param string $driver_alias The driver alias. + * @param IMinkDriverFactory $driver_factory The driver factory class or instance. + * + * @return void + * @throws \InvalidArgumentException If the driver alias is not a string. + */ + public function registerDriverFactory($driver_alias, IMinkDriverFactory $driver_factory) + { + $this->_validateDriverAlias($driver_alias); + $this->_driverFactoryRegistry[$driver_alias] = $driver_factory; + } + + /** + * Validate the driver alias. + * + * @param string $driver_alias The driver alias. + * + * @return void + */ + private function _validateDriverAlias($driver_alias) + { + if ( !is_string($driver_alias) ) { + throw new \InvalidArgumentException('The Mink driver alias must be a string.'); + } } } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index a251e81..756a1fb 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -80,6 +80,8 @@ protected function setUp() 'desiredCapabilities' => array('platform' => 'Windows 7', 'version' => 10), 'baseUrl' => 'http://other-host', 'sessionStrategy' => ISessionStrategyFactory::TYPE_SHARED, + 'driver' => 'selenium2', + 'driverOptions' => array(), ); $this->browser = $this->createBrowserConfiguration( @@ -220,6 +222,8 @@ public function testSetup() $this->assertSame($this->setup['desiredCapabilities'], $this->browser->getDesiredCapabilities()); $this->assertSame($this->setup['baseUrl'], $this->browser->getBaseUrl()); $this->assertSame($this->setup['sessionStrategy'], $this->browser->getSessionStrategy()); + $this->assertSame($this->setup['driver'], $this->browser->getDriver()); + $this->assertSame($this->setup['driverOptions'], $this->browser->getDriverOptions()); } /** @@ -483,6 +487,31 @@ public function testChecksumMismatch() $this->assertNotSame($browser1->getChecksum(), $browser2->getChecksum()); } + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The Mink driver must be a string + * + * @return void + */ + public function testSetDriverMustReceiveString() + { + $this->browser->setDriver(array()); + } + + public function testDriverClassIsCopiedBySetup() + { + $driver_name = 'selenium2'; + $this->browser->setup(array('driver' => $driver_name)); + $this->assertEquals($driver_name, $this->browser->getDriver()); + } + + public function testSetDriverOptions() + { + $driver_options = array('test driver', 'options'); + $this->browser->setDriverOptions($driver_options); + $this->assertSame($driver_options, $this->browser->getDriverOptions()); + } + /** * Creates instance of browser configuration. * diff --git a/tests/aik099/PHPUnit/MinkDriver/GoutteDriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/GoutteDriverFactoryTest.php new file mode 100644 index 0000000..813d651 --- /dev/null +++ b/tests/aik099/PHPUnit/MinkDriver/GoutteDriverFactoryTest.php @@ -0,0 +1,51 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace tests\aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\MinkDriver\GoutteDriverFactory; +use Mockery as m; + +class GoutteDriverFactoryTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var string + */ + private $_driverClass = 'Behat\\Mink\\Driver\\GoutteDriver'; + + /** + * @var GoutteDriverFactory; + */ + private $_factory; + + public function setUp() + { + if ( !class_exists($this->_driverClass) ) { + $this->markTestSkipped(sprintf('Mink driver not installed: "%s"', $this->_driverClass)); + } + + $this->_factory = new GoutteDriverFactory(); + } + + public function testItImplementsTheDriverFactoryInterface() + { + $this->assertInstanceOf('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory', $this->_factory); + } + + public function testItReturnsAGoutteDriver() + { + $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $this->assertInstanceOf($this->_driverClass, $this->_factory->getInstance($browser)); + } + +} diff --git a/tests/aik099/PHPUnit/MinkDriver/SahiDriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/SahiDriverFactoryTest.php new file mode 100644 index 0000000..5e86e33 --- /dev/null +++ b/tests/aik099/PHPUnit/MinkDriver/SahiDriverFactoryTest.php @@ -0,0 +1,54 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace tests\aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\MinkDriver\SahiDriverFactory; +use Mockery as m; + +class SahiDriverFactoryTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var string + */ + private $_driverClass = 'Behat\\Mink\\Driver\\SahiDriver'; + + /** + * @var SahiDriverFactory; + */ + private $_factory; + + public function setUp() + { + if ( !class_exists($this->_driverClass) ) { + $this->markTestSkipped(sprintf('Mink driver not installed: "%s"', $this->_driverClass)); + } + + $this->_factory = new SahiDriverFactory(); + } + + public function testItImplementsTheDriverFactoryInterface() + { + $this->assertInstanceOf('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory', $this->_factory); + } + + public function testItReturnsASahiDriver() + { + $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser->shouldReceive('getBrowserName')->once()->andReturn('firefox'); + $browser->shouldReceive('getHost')->once()->andReturn(''); + $browser->shouldReceive('getPort')->once()->andReturn(0); + $this->assertInstanceOf($this->_driverClass, $this->_factory->getInstance($browser)); + } + +} diff --git a/tests/aik099/PHPUnit/MinkDriver/Selenium2DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/Selenium2DriverFactoryTest.php new file mode 100644 index 0000000..abea84a --- /dev/null +++ b/tests/aik099/PHPUnit/MinkDriver/Selenium2DriverFactoryTest.php @@ -0,0 +1,56 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace tests\aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\MinkDriver\Selenium2DriverFactory; +use Mockery as m; + +class Selenium2DriverFactoryTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var string + */ + private $_driverClass = 'Behat\\Mink\\Driver\\Selenium2Driver'; + + /** + * @var Selenium2DriverFactory; + */ + private $_factory; + + public function setUp() + { + if ( !class_exists($this->_driverClass) ) { + $this->markTestSkipped(sprintf('Mink driver not installed: "%s"', $this->_driverClass)); + } + + $this->_factory = new Selenium2DriverFactory(); + } + + public function testItImplementsTheDriverFactoryInterface() + { + $this->assertInstanceOf('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory', $this->_factory); + } + + public function testItReturnsASelenium2Driver() + { + $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser->shouldReceive('getDesiredCapabilities')->once()->andReturn(array()); + $browser->shouldReceive('getBrowserName')->once()->andReturn(''); + $browser->shouldReceive('getTimeout')->once()->andReturn(0); + $browser->shouldReceive('getHost')->once()->andReturn(''); + $browser->shouldReceive('getPort')->once()->andReturn(0); + $this->assertInstanceOf($this->_driverClass, $this->_factory->getInstance($browser)); + } + +} diff --git a/tests/aik099/PHPUnit/MinkDriver/ZombieDriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/ZombieDriverFactoryTest.php new file mode 100644 index 0000000..70a5268 --- /dev/null +++ b/tests/aik099/PHPUnit/MinkDriver/ZombieDriverFactoryTest.php @@ -0,0 +1,54 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace tests\aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\MinkDriver\ZombieDriverFactory; +use Mockery as m; + +class ZombieDriverFactoryTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var string + */ + private $_driverClass = 'Behat\\Mink\\Driver\\ZombieDriver'; + + /** + * @var ZombieDriverFactory; + */ + private $_factory; + + public function setUp() + { + if ( !class_exists($this->_driverClass) ) { + $this->markTestSkipped(sprintf('Mink driver not installed: "%s"', $this->_driverClass)); + } + + $this->_factory = new ZombieDriverFactory(); + } + + public function testItImplementsTheDriverFactoryInterface() + { + $this->assertInstanceOf('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory', $this->_factory); + } + + public function testItReturnsAZombieDriver() + { + $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser->shouldReceive('getDriverOptions')->once()->andReturn(array()); + $browser->shouldReceive('getHost')->once()->andReturn(''); + $browser->shouldReceive('getPort')->once()->andReturn(0); + $this->assertInstanceOf($this->_driverClass, $this->_factory->getInstance($browser)); + } + +} diff --git a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php index 352a3c8..2702d83 100644 --- a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php +++ b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php @@ -49,6 +49,7 @@ public function testCreateSession() $browser->shouldReceive('getTimeout')->once()->andReturn(0); $browser->shouldReceive('getHost')->once()->andReturn(''); $browser->shouldReceive('getPort')->once()->andReturn(0); + $browser->shouldReceive('getDriver')->once()->andReturn('selenium2'); $session = $this->_factory->createSession($browser); @@ -56,4 +57,57 @@ public function testCreateSession() $this->assertInstanceOf('Behat\\Mink\\Driver\\Selenium2Driver', $session->getDriver()); } + /** + * @expectedException \OutOfBoundsException + * @expectedExceptionMessage No driver factory for driver + */ + public function testItThrowsExceptionForUnknownDriverAlias() + { + $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser->shouldReceive('getDriver')->once()->andReturn('invalid'); + + $this->_factory->createSession($browser); + } + + /** + * @dataProvider driversAvailableByDefaultProvider + */ + public function testDriversRegisteredByDefault($driver, $expected_driver) + { + if ( !class_exists($expected_driver) ) { + $this->markTestSkipped( + sprintf('Test skipped because Mink driver is not installed: "%s"', $expected_driver) + ); + } + + $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser->shouldReceive('getDesiredCapabilities')->andReturn(array()); + $browser->shouldReceive('getBrowserName')->andReturn(''); + $browser->shouldReceive('getTimeout')->andReturn(0); + $browser->shouldReceive('getHost')->andReturn(''); + $browser->shouldReceive('getPort')->andReturn(0); + $browser->shouldReceive('getDriverOptions')->andReturn(array()); + $browser->shouldReceive('getDriver')->once()->andReturn($driver); + + $session = $this->_factory->createSession($browser); + $this->assertInstanceOf($expected_driver, $session->getDriver()); + } + + public function driversAvailableByDefaultProvider() + { + return array( + 'selenium2' => array('selenium2', 'Behat\\Mink\\Driver\\Selenium2Driver'), + 'sahi' => array('sahi', 'Behat\\Mink\\Driver\\SahiDriver'), + 'goutte' => array('goutte', 'Behat\\Mink\\Driver\\GoutteDriver'), + 'zombie' => array('zombie', 'Behat\\Mink\\Driver\\ZombieDriver'), + ); + } + + public function testItRegistersTheDriverFactory() + { + $stub_factory = m::mock('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $this->_factory->registerDriverFactory('test', $stub_factory); + $this->assertAttributeContains($stub_factory, '_driverFactoryRegistry', $this->_factory); + } + } From dc4109f257cdeb3c8fb480b5727f240c36428984 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 21 Mar 2015 10:10:03 +0200 Subject: [PATCH 083/204] Extracting driver factory registry into separate class 1. Extracting driver factory registry into separate `DriverFactoryRegistry` class 2. Simplifying architecture by allowing `BrowserConfiguration` itself to create driver via new `createDriver` method, that uses above create factory to acquire proper driver factory 3. Eliminate getter methods for `BrowserConfiguration` parameters by using "__call" method 4. don't allow internal `type` `BrowserConfiguration` parameter to leave the `BrowserConfigurationFactory` 5. the `BrowserConfiguration::getType` method wasn't covered 6. allow DEV version of Mink to be used for testing purposes 7. allow each driver (via it's factory) to provide defaults for browser configuration 8. the "api_username" and "api_key" browser configuration parameters renamed to "apiUsername" and "apiKey" for consistency, but no BC break because old parameter names still work 9. updated documentation to include description of `driver` and `driverOptions` parameters --- composer.json | 2 +- composer.lock | 60 +-- docs/configuration.rst | 35 +- docs/examples/browser_aliases.php | 1 + .../config_via_browsers_property.php | 2 + .../configuration/config_via_setup_method.php | 4 +- .../configuration/driver_showcase.php | 53 +++ .../per_test_case_browser_config.php | 1 + .../cloud_selenium_configs.php | 5 +- .../examples/getting-started/general_test.php | 1 + docs/getting-started.rst | 6 +- .../ApiBrowserConfiguration.php | 71 ++-- .../BrowserConfiguration.php | 341 +++++++++--------- .../BrowserConfigurationFactory.php | 1 + .../BrowserStackBrowserConfiguration.php | 17 +- .../SauceLabsBrowserConfiguration.php | 17 +- library/aik099/PHPUnit/DIContainer.php | 30 +- .../MinkDriver/DriverFactoryRegistry.php | 60 +++ .../MinkDriver/GoutteDriverFactory.php | 101 +++++- .../PHPUnit/MinkDriver/IMinkDriverFactory.php | 19 +- .../PHPUnit/MinkDriver/SahiDriverFactory.php | 57 ++- .../MinkDriver/Selenium2DriverFactory.php | 41 ++- .../MinkDriver/ZombieDriverFactory.php | 57 ++- .../aik099/PHPUnit/Session/SessionFactory.php | 100 +---- .../ApiBrowserConfigurationTestCase.php | 43 ++- .../BrowserConfigurationFactoryTest.php | 48 ++- .../BrowserConfigurationTest.php | 152 ++++++-- .../BrowserStackBrowserConfigurationTest.php | 5 + .../SauceLabsBrowserConfigurationTest.php | 5 + tests/aik099/PHPUnit/BrowserTestCaseTest.php | 23 +- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 4 +- .../PHPUnit/Fixture/SetupEventFixture.php | 29 +- .../PHPUnit/Integration/DIContainerTest.php | 1 + .../PHPUnit/Integration/DataProviderTest.php | 4 +- .../MinkDriver/DriverFactoryRegistryTest.php | 67 ++++ .../PHPUnit/MinkDriver/DriverFactoryTest.php | 98 +++++ .../MinkDriver/GoutteDriverFactoryTest.php | 51 --- .../MinkDriver/SahiDriverFactoryTest.php | 54 --- .../MinkDriver/Selenium2DriverFactoryTest.php | 56 --- .../MinkDriver/ZombieDriverFactoryTest.php | 54 --- .../PHPUnit/Session/SessionFactoryTest.php | 65 +--- 41 files changed, 1099 insertions(+), 742 deletions(-) create mode 100644 docs/examples/configuration/driver_showcase.php create mode 100644 library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php create mode 100644 tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php create mode 100644 tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php delete mode 100644 tests/aik099/PHPUnit/MinkDriver/GoutteDriverFactoryTest.php delete mode 100644 tests/aik099/PHPUnit/MinkDriver/SahiDriverFactoryTest.php delete mode 100644 tests/aik099/PHPUnit/MinkDriver/Selenium2DriverFactoryTest.php delete mode 100644 tests/aik099/PHPUnit/MinkDriver/ZombieDriverFactoryTest.php diff --git a/composer.json b/composer.json index 4d0b49c..ce048ec 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "require": { "php": ">=5.3.2", - "behat/mink": "~1.6", + "behat/mink": "~1.6@dev", "behat/mink-selenium2-driver": "~1.2", "symfony/event-dispatcher": "~2.4", "pimple/pimple": "~2.0|~3.0", diff --git a/composer.lock b/composer.lock index bf5a03b..07c5da3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "9677a9d73bf451ae1e4314bfe7e9991e", + "hash": "961c9cfcd51f5d93088d7f57ab5a788b", "packages": [ { "name": "behat/mink", - "version": "v1.6.1", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/minkphp/Mink.git", - "reference": "8b68523a339ec991bcd638b39dc8f04f808da88a" + "reference": "30014f0a15579176b7fca879cb461aad900f4db5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/Mink/zipball/8b68523a339ec991bcd638b39dc8f04f808da88a", - "reference": "8b68523a339ec991bcd638b39dc8f04f808da88a", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/30014f0a15579176b7fca879cb461aad900f4db5", + "reference": "30014f0a15579176b7fca879cb461aad900f4db5", "shasum": "" }, "require": { @@ -33,7 +33,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "1.7.x-dev" } }, "autoload": { @@ -59,7 +59,7 @@ "testing", "web" ], - "time": "2015-02-04 17:02:06" + "time": "2015-02-21 12:27:56" }, { "name": "behat/mink-selenium2-driver", @@ -1129,22 +1129,25 @@ }, { "name": "symfony/css-selector", - "version": "v2.6.4", + "version": "v2.6.5", "target-dir": "Symfony/Component/CssSelector", "source": { "type": "git", "url": "https://github.com/symfony/CssSelector.git", - "reference": "3f80ecc614fec68d5b4a84a0703db3fdf5ce8584" + "reference": "86cf0aa16065ffc4545374e9479dd7878bf1d90f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/CssSelector/zipball/3f80ecc614fec68d5b4a84a0703db3fdf5ce8584", - "reference": "3f80ecc614fec68d5b4a84a0703db3fdf5ce8584", + "url": "https://api.github.com/repos/symfony/CssSelector/zipball/86cf0aa16065ffc4545374e9479dd7878bf1d90f", + "reference": "86cf0aa16065ffc4545374e9479dd7878bf1d90f", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -1176,21 +1179,21 @@ ], "description": "Symfony CssSelector Component", "homepage": "http://symfony.com", - "time": "2015-01-03 08:01:59" + "time": "2015-02-24 11:52:21" }, { "name": "symfony/event-dispatcher", - "version": "v2.6.4", + "version": "v2.6.5", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813" + "reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/f75989f3ab2743a82fe0b03ded2598a2b1546813", - "reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/70f7c8478739ad21e3deef0d977b38c77f1fb284", + "reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284", "shasum": "" }, "require": { @@ -1201,6 +1204,7 @@ "symfony/config": "~2.0,>=2.0.5", "symfony/dependency-injection": "~2.6", "symfony/expression-language": "~2.6", + "symfony/phpunit-bridge": "~2.7", "symfony/stopwatch": "~2.3" }, "suggest": { @@ -1234,26 +1238,29 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "http://symfony.com", - "time": "2015-02-01 16:10:57" + "time": "2015-03-13 17:37:22" }, { "name": "symfony/yaml", - "version": "v2.6.4", + "version": "v2.6.5", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8" + "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/60ed7751671113cf1ee7d7778e691642c2e9acd8", - "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/0cd8e72071e46e15fc072270ae39ea1b66b10a9d", + "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { @@ -1281,7 +1288,7 @@ ], "description": "Symfony Yaml Component", "homepage": "http://symfony.com", - "time": "2015-01-25 04:39:26" + "time": "2015-03-12 10:28:44" } ], "packages-dev": [ @@ -1291,12 +1298,12 @@ "source": { "type": "git", "url": "https://github.com/aik099/CodingStandard.git", - "reference": "57a48b92960025a747a1de75aa2f5cc49f9f06e7" + "reference": "f01c2c5cd22381566aa3daf9083deea6d323637a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/57a48b92960025a747a1de75aa2f5cc49f9f06e7", - "reference": "57a48b92960025a747a1de75aa2f5cc49f9f06e7", + "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/f01c2c5cd22381566aa3daf9083deea6d323637a", + "reference": "f01c2c5cd22381566aa3daf9083deea6d323637a", "shasum": "" }, "require-dev": { @@ -1323,7 +1330,7 @@ "PHP_CodeSniffer", "codesniffer" ], - "time": "2015-03-13 08:39:29" + "time": "2015-03-18 08:14:41" }, { "name": "mockery/mockery", @@ -1395,6 +1402,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { + "behat/mink": 20, "aik099/coding-standard": 20 }, "prefer-stable": false, diff --git a/docs/configuration.rst b/docs/configuration.rst index de42d22..a65ff2d 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -21,7 +21,7 @@ configuration) in that test case class. .. literalinclude:: examples/configuration/config_via_browsers_property.php :linenos: - :emphasize-lines: 8,9,15 + :emphasize-lines: 8,9,16 .. note:: When several browser configurations are specified in ``$browsers`` array, then each test in a test case will be executed against each of browser configurations. @@ -35,27 +35,38 @@ option (line 14) to the browser configuration. .. literalinclude:: examples/configuration/per_test_case_browser_config.php :linenos: - :emphasize-lines: 14 + :emphasize-lines: 15 + +Selecting the Mink Driver +^^^^^^^^^^^^^^^^^^^^^^^^^ +With the help of ``driver`` and ``driverOptions`` browser configuration settings (since v2.1.0) it's possible to +specify which `Mink`_ driver to use. This file demonstrates how to use each driver: + +.. literalinclude:: examples/configuration/driver_showcase.php + :linenos: + :emphasize-lines: 10,20,32,40 Configuration Options ^^^^^^^^^^^^^^^^^^^^^ Each browser configuration consists of the following settings (all optional): -======================= ================================================================================================= +======================= ================================================================================================== Name Description -======================= ================================================================================================= -``host`` host, where Selenium Server is located (defaults to ``localhost``) -``port`` port, on which Selenium Server is listening for incoming connections (defaults to ``4444``) -``timeout`` connection timeout of the server in seconds (defaults to ``60``) +======================= ================================================================================================== +``driver`` Mink driver name (defaults to ``selenium2``, since v2.1.0) +``driverOptions`` Mink driver specific options (since v2.1.0) +``host`` host, where driver's server is located (defaults to ``localhost``) +``port`` port, on which driver's server is listening for incoming connections (determined by driver) +``timeout`` connection timeout of the server in seconds ('selenium2' driver only, defaults to ``60``) ``browserName`` name of browser to use (e.g. ``firefox``, ``chrome``, etc., defaults to ``firefox``) -``desiredCapabilities`` parameters, that specify additional browser configuration (e.g. browser version, platform, etc.), - that will be used by Selenium server +``desiredCapabilities`` parameters, that allow to fine-tune browser and other 'selenium2' driver options (e.g. 'tags', + 'project', 'os', 'version') ``baseUrl`` base url of website, that is tested ``sessionStrategy`` used session strategy (defaults to ``isolated``) ``type`` type of configuration (defaults to ``default``, but can also be ``saucelabs`` or ``browserstack``) -``api_username`` API username of used service (applicable to any but ``default`` configuration type) -``api_key`` API key of used service (applicable to any but ``default`` configuration type) -======================= ================================================================================================= +``apiUsername`` API username of used service (applicable to 'saucelabs' and 'browserstack' browser configurations) +``apiKey`` API key of used service (applicable to 'saucelabs' and 'browserstack' browser configurations) +======================= ================================================================================================== There are also corresponding setters (e.g. ``setHost``) and getters (e.g. ``getHost``) for each of mentioned above settings, that allow to individually change them from ``setUp`` method before test has started. diff --git a/docs/examples/browser_aliases.php b/docs/examples/browser_aliases.php index 3aa7288..5c3f782 100644 --- a/docs/examples/browser_aliases.php +++ b/docs/examples/browser_aliases.php @@ -9,6 +9,7 @@ public function getBrowserAliases() { return array( 'example_alias' => array( + 'driver' => 'selenium2', 'host' => 'localhost', 'port' => 4444, 'browserName' => 'firefox', diff --git a/docs/examples/configuration/config_via_browsers_property.php b/docs/examples/configuration/config_via_browsers_property.php index 54863da..604342f 100644 --- a/docs/examples/configuration/config_via_browsers_property.php +++ b/docs/examples/configuration/config_via_browsers_property.php @@ -7,12 +7,14 @@ class PerTestCaseBrowserConfigTest extends BrowserTestCase public static $browsers = array( array( + 'driver' => 'selenium2', 'host' => 'localhost', 'port' => 4444, 'browserName' => 'firefox', 'baseUrl' => 'http://www.google.com', ), array( + 'driver' => 'selenium2', 'host' => 'localhost', 'port' => 4444, 'browserName' => 'chrome', diff --git a/docs/examples/configuration/config_via_setup_method.php b/docs/examples/configuration/config_via_setup_method.php index bef3198..ecd0a9f 100644 --- a/docs/examples/configuration/config_via_setup_method.php +++ b/docs/examples/configuration/config_via_setup_method.php @@ -16,8 +16,8 @@ protected function setUp() $browser = $this->createBrowserConfiguration(array( // required 'type' => 'saucelabs', - 'api_username' => 'sauce_username', - 'api_key' => 'sauce_api_key', + 'apiUsername' => 'sauce_username', + 'apiKey' => 'sauce_api_key', // optional options goes here )); diff --git a/docs/examples/configuration/driver_showcase.php b/docs/examples/configuration/driver_showcase.php new file mode 100644 index 0000000..84b28bc --- /dev/null +++ b/docs/examples/configuration/driver_showcase.php @@ -0,0 +1,53 @@ + 'goutte', + + // Defaults for this driver. + 'driverOptions' => array( + 'server_parameters' => array(), + 'guzzle_parameters' => array(), + ), + + ), + array( + 'driver' => 'sahi', + + // Defaults for this driver. + 'port' => 9999, + 'driverOptions' => array( + 'sid' => null, + 'limit' => 600, + 'browser' => null, + ), + ), + + array( + 'driver' => 'selenium2', + + // Defaults for this driver. + 'port' => 4444, + 'driverOptions' => array(), + ), + + array( + 'driver' => 'zombie', + + // Defaults for this driver. + 'port' => 8124, + 'driverOptions' => array( + 'node_bin' => 'node', + 'server_path' => null, + 'threshold' => 2000000, + 'node_modules_path' => '', + ), + ), + ); + +} diff --git a/docs/examples/configuration/per_test_case_browser_config.php b/docs/examples/configuration/per_test_case_browser_config.php index 37710ed..87f7a1a 100644 --- a/docs/examples/configuration/per_test_case_browser_config.php +++ b/docs/examples/configuration/per_test_case_browser_config.php @@ -7,6 +7,7 @@ class CommonBrowserConfigTest extends BrowserTestCase public static $browsers = array( array( + 'driver' => 'selenium2', 'host' => 'localhost', 'port' => 4444, 'browserName' => 'firefox', diff --git a/docs/examples/getting-started/cloud_selenium_configs.php b/docs/examples/getting-started/cloud_selenium_configs.php index 1aae06d..7d74afa 100644 --- a/docs/examples/getting-started/cloud_selenium_configs.php +++ b/docs/examples/getting-started/cloud_selenium_configs.php @@ -9,8 +9,8 @@ class BrowserConfigExampleTest extends BrowserTestCase // Sauce Labs browser configuration. array( 'type' => 'saucelabs', - 'api_username' => '...', - 'api_key' => '...', + 'apiUsername' => '...', + 'apiKey' => '...', 'browserName' => 'firefox', 'baseUrl' => 'http://www.google.com', ), @@ -24,6 +24,7 @@ class BrowserConfigExampleTest extends BrowserTestCase ), // Regular browser configuration. array( + 'driver' => 'selenium2', 'host' => 'localhost', 'port' => 4444, 'browserName' => 'chrome', diff --git a/docs/examples/getting-started/general_test.php b/docs/examples/getting-started/general_test.php index bc1ac56..5f6bef1 100644 --- a/docs/examples/getting-started/general_test.php +++ b/docs/examples/getting-started/general_test.php @@ -7,6 +7,7 @@ class GeneralTest extends BrowserTestCase public static $browsers = array( array( + 'driver' => 'selenium2', 'host' => 'localhost', 'port' => 4444, 'browserName' => 'firefox', diff --git a/docs/getting-started.rst b/docs/getting-started.rst index 0fe1798..ca7cbe1 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -32,7 +32,7 @@ Basic Usage .. literalinclude:: examples/getting-started/general_test.php :linenos: - :emphasize-lines: 5,8,20,34 + :emphasize-lines: 5,8,21,35 Selenium in Cloud ^^^^^^^^^^^^^^^^^ @@ -40,8 +40,8 @@ When using Selenium-based solution for automated testing in the cloud (e.g. `Sau specify following settings: * ``'type' => 'saucelabs'`` or ``'type' => 'browserstack'`` -* ``'api_username' => '...'`` -* ``'api_key' => '...'`` +* ``'apiUsername' => '...'`` +* ``'apiKey' => '...'`` instead of ``host`` and ``port`` settings. In all other aspects everything will work the same as if all tests were running locally. diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index 0dd97f6..b076616 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -15,12 +15,16 @@ use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Event\TestEvent; +use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Behat\Mink\Driver\Selenium2Driver; use Behat\Mink\Session; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Browser configuration tailored to use with API-based service. + * + * @method string getApiUsername() Returns API username. + * @method string getApiKey() Returns API key. */ abstract class ApiBrowserConfiguration extends BrowserConfiguration { @@ -46,85 +50,78 @@ abstract class ApiBrowserConfiguration extends BrowserConfiguration * Creates browser configuration. * * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * @param DriverFactoryRegistry $driver_factory_registry Driver factory registry. * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. */ public function __construct( EventDispatcherInterface $event_dispatcher, + DriverFactoryRegistry $driver_factory_registry, IBrowserConfigurationFactory $browser_configuration_factory ) { $this->browserConfigurationFactory = $browser_configuration_factory; - $this->defaultParameters['api_username'] = ''; - $this->defaultParameters['api_key'] = ''; + $this->defaults['driver'] = 'selenium2'; + $this->defaults['apiUsername'] = ''; + $this->defaults['apiKey'] = ''; - parent::__construct($event_dispatcher); + parent::__construct($event_dispatcher, $driver_factory_registry); } /** - * Initializes a browser with given configuration. + * Sets API username. + * + * To be called from TestCase::setUp(). * - * @param array $parameters Browser configuration parameters. + * @param string $api_username API username. * * @return self */ - public function setup(array $parameters) + public function setApiUsername($api_username) { - $prepared_parameters = $this->prepareParameters($parameters); - $this->setApiUsername($prepared_parameters['api_username']); - $this->setApiKey($prepared_parameters['api_key']); - - return parent::setup($parameters); + return $this->setParameter('apiUsername', $api_username); } /** - * Sets API username. + * Sets API key. * * To be called from TestCase::setUp(). * - * @param string $api_username API username. + * @param string $api_key API key. * * @return self */ - public function setApiUsername($api_username) + public function setApiKey($api_key) { - $this->parameters['api_username'] = $api_username; - - return $this; + return $this->setParameter('apiKey', $api_key); } /** - * Returns API username. + * Sets API username. * - * @return string + * Used internally to to allow using "api_username" parameter and avoid BC break. + * + * @param string $api_username API username. + * + * @return self + * @deprecated */ - public function getApiUsername() + protected function setApi_username($api_username) { - return $this->parameters['api_username']; + return $this->setApiUsername($api_username); } /** * Sets API key. * - * To be called from TestCase::setUp(). + * Used internally to to allow using "api_key" parameter and avoid BC break. * * @param string $api_key API key. * - * @return self - */ - public function setApiKey($api_key) - { - $this->parameters['api_key'] = $api_key; - - return $this; - } - - /** - * Returns API key. - * - * @return string + * @return self + * @deprecated */ - public function getApiKey() + protected function setApi_key($api_key) { - return $this->parameters['api_key']; + return $this->setApiKey($api_key); } /** diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 90ed6df..dddf2dd 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -14,7 +14,10 @@ use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Event\TestEvent; +use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; +use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; use aik099\PHPUnit\Session\ISessionStrategyFactory; +use Behat\Mink\Driver\DriverInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -22,48 +25,56 @@ * Browser configuration for browser. * * @method \Mockery\Expectation shouldReceive(string $name) + * @method string getDriver() Returns Mink driver name. + * @method array getDriverOptions() Returns Mink driver options. + * @method string getHost() Returns hostname from browser configuration. + * @method integer getPort() Returns port from browser configuration. + * @method string getBrowserName() Returns browser name from browser configuration. + * @method string getBaseUrl() Returns default browser url from browser configuration. + * @method array getDesiredCapabilities() Returns desired capabilities from browser configuration. + * @method integer getTimeout() Returns server timeout. + * @method string getSessionStrategy() Returns session strategy name. */ class BrowserConfiguration implements EventSubscriberInterface { + const TYPE = 'default'; /** - * Default browser configuration. + * User defaults. * * @var array */ - protected $defaultParameters = array( - // Server related. + protected $defaults = array( + // Driver related. 'host' => 'localhost', - 'port' => 4444, + 'driver' => 'selenium2', + 'driverOptions' => array(), + + // TODO: Move under 'driverOptions' of 'selenium2' driver (BC break). + 'desiredCapabilities' => array(), 'timeout' => 60, // Browser related. - 'browserName' => 'firefox', - 'desiredCapabilities' => array(), + 'browserName' => 'firefox', // Have no effect on headless drivers. 'baseUrl' => '', - 'driver' => 'selenium2', - 'driverOptions' => array(), // Test related. - 'type' => 'default', 'sessionStrategy' => ISessionStrategyFactory::TYPE_ISOLATED, ); /** - * List of driver aliases. Used for validation in the setDriver() method. + * User defaults merged with driver defaults. * * @var array */ - protected $driverAliases = array( - 'selenium2', 'goutte', 'sahi', 'zombie', - ); + private $_mergedDefaults = array(); /** - * Browser configuration. + * Manually set browser configuration parameters. * * @var array */ - protected $parameters; + private $_parameters = array(); /** * Browser configuration aliases. @@ -86,6 +97,20 @@ class BrowserConfiguration implements EventSubscriberInterface */ private $_eventDispatcher; + /** + * Driver factory registry. + * + * @var DriverFactoryRegistry + */ + private $_driverFactoryRegistry; + + /** + * Driver factory. + * + * @var IMinkDriverFactory + */ + private $_driverFactory; + /** * Resolves browser alias into corresponding browser configuration. * @@ -116,12 +141,19 @@ public static function resolveAliases(array $parameters, array $aliases) /** * Creates browser configuration. * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * @param DriverFactoryRegistry $driver_factory_registry Driver factory registry. */ - public function __construct(EventDispatcherInterface $event_dispatcher) - { - $this->parameters = $this->defaultParameters; + public function __construct( + EventDispatcherInterface $event_dispatcher, + DriverFactoryRegistry $driver_factory_registry + ) { $this->_eventDispatcher = $event_dispatcher; + $this->_driverFactoryRegistry = $driver_factory_registry; + + if ( $this->defaults['driver'] ) { + $this->setDriver($this->defaults['driver']); + } } /** @@ -131,7 +163,7 @@ public function __construct(EventDispatcherInterface $event_dispatcher) */ public function getType() { - return $this->parameters['type']; + return static::TYPE; } /** @@ -213,19 +245,22 @@ public function setAliases(array $aliases = array()) public function setup(array $parameters) { $parameters = $this->prepareParameters($parameters); - $unknown_parameters = array_diff(array_keys($parameters), array_keys($this->defaultParameters)); - if ( $unknown_parameters ) { - throw new \InvalidArgumentException( - 'Following parameter(-s) are unknown: "' . implode('", "', $unknown_parameters) . '"' - ); + // Make sure, that 'driver' parameter is handled first. + if ( isset($parameters['driver']) ) { + $this->setDriver($parameters['driver']); + unset($parameters['driver']); } - $this->setHost($parameters['host'])->setPort($parameters['port'])->setTimeout($parameters['timeout']); - $this->setDriver($parameters['driver']); - $this->setBrowserName($parameters['browserName'])->setDesiredCapabilities($parameters['desiredCapabilities']); - $this->setBaseUrl($parameters['baseUrl']); - $this->setSessionStrategy($parameters['sessionStrategy']); + foreach ( $parameters as $name => $value ) { + $method = 'set' . ucfirst($name); + + if ( !method_exists($this, $method) ) { + throw new \InvalidArgumentException('Unable to set unknown parameter "' . $name . '"'); + } + + $this->$method($value); + } return $this; } @@ -239,7 +274,39 @@ public function setup(array $parameters) */ protected function prepareParameters(array $parameters) { - return array_merge($this->parameters, self::resolveAliases($parameters, $this->aliases)); + return array_merge($this->_parameters, self::resolveAliases($parameters, $this->aliases)); + } + + /** + * Sets Mink driver to browser configuration. + * + * @param string $driver_name Mink driver name. + * + * @return self + * @throws \InvalidArgumentException When Mink driver name is not a string. + */ + public function setDriver($driver_name) + { + if ( !is_string($driver_name) ) { + throw new \InvalidArgumentException('The Mink driver name must be a string'); + } + + $this->_driverFactory = $this->_driverFactoryRegistry->get($driver_name); + $this->_mergedDefaults = self::arrayMergeRecursive($this->defaults, $this->_driverFactory->getDriverDefaults()); + + return $this->setParameter('driver', $driver_name); + } + + /** + * Sets Mink driver options to browser configuration. + * + * @param array $driver_options Mink driver options. + * + * @return self + */ + public function setDriverOptions(array $driver_options) + { + return $this->setParameter('driverOptions', $driver_options); } /** @@ -258,19 +325,7 @@ public function setHost($host) throw new \InvalidArgumentException('Host must be a string'); } - $this->parameters['host'] = $host; - - return $this; - } - - /** - * Returns hostname from browser configuration. - * - * @return string - */ - public function getHost() - { - return $this->parameters['host']; + return $this->setParameter('host', $host); } /** @@ -289,19 +344,7 @@ public function setPort($port) throw new \InvalidArgumentException('Port must be an integer'); } - $this->parameters['port'] = $port; - - return $this; - } - - /** - * Returns port from browser configuration. - * - * @return integer - */ - public function getPort() - { - return $this->parameters['port']; + return $this->setParameter('port', $port); } /** @@ -320,19 +363,7 @@ public function setBrowserName($browser_name) throw new \InvalidArgumentException('Browser must be a string'); } - $this->parameters['browserName'] = $browser_name; - - return $this; - } - - /** - * Returns browser name from browser configuration. - * - * @return string - */ - public function getBrowserName() - { - return $this->parameters['browserName']; + return $this->setParameter('browserName', $browser_name); } /** @@ -351,72 +382,7 @@ public function setBaseUrl($base_url) throw new \InvalidArgumentException('Base url must be a string'); } - $this->parameters['baseUrl'] = $base_url; - - return $this; - } - - /** - * Returns default browser url from browser configuration. - * - * @return string - */ - public function getBaseUrl() - { - return $this->parameters['baseUrl']; - } - - /** - * Set the Mink driver to use. - * - * @param string $driver The driver to use. - * - * @return self - * @throws \InvalidArgumentException When Mink driver is not a string. - */ - public function setDriver($driver) - { - if ( !is_string($driver) ) { - throw new \InvalidArgumentException('The Mink driver must be a string'); - } - - $this->parameters['driver'] = $driver; - - return $this; - } - - /** - * Returns the Mink driver. - * - * @return string - */ - public function getDriver() - { - return $this->parameters['driver']; - } - - /** - * Sets driver options to be used by the driver factory. - * - * @param array $driver_options Set Mink driver specific options. - * - * @return self - */ - public function setDriverOptions(array $driver_options) - { - $this->parameters['driverOptions'] = $driver_options; - - return $this; - } - - /** - * Returns Mink driver options. - * - * @return array - */ - public function getDriverOptions() - { - return $this->parameters['driverOptions']; + return $this->setParameter('baseUrl', $base_url); } /** @@ -431,24 +397,11 @@ public function getDriverOptions() */ public function setDesiredCapabilities(array $capabilities) { - $this->parameters['desiredCapabilities'] = $capabilities; - - return $this; - } - - /** - * Returns desired capabilities from browser configuration. - * - * @return array - */ - public function getDesiredCapabilities() - { - return $this->parameters['desiredCapabilities']; + return $this->setParameter('desiredCapabilities', $capabilities); } /** * Sets server timeout. - * * To be called from TestCase::setUp(). * * @param integer $timeout Server timeout in seconds. @@ -462,54 +415,80 @@ public function setTimeout($timeout) throw new \InvalidArgumentException('Timeout must be an integer'); } - $this->parameters['timeout'] = $timeout; + return $this->setParameter('timeout', $timeout); + } - return $this; + /** + * Sets session strategy name. + * + * @param string $session_strategy Session strategy name. + * + * @return self + */ + public function setSessionStrategy($session_strategy) + { + return $this->setParameter('sessionStrategy', $session_strategy); } /** - * Returns server timeout. + * Tells if browser configuration requires a session, that is shared across tests in a test case. * - * @return integer + * @return boolean */ - public function getTimeout() + public function isShared() { - return $this->parameters['timeout']; + return $this->getSessionStrategy() == ISessionStrategyFactory::TYPE_SHARED; } /** - * Sets session strategy name. + * Sets parameter. * - * @param string $session_strategy Session strategy name. + * @param string $name Parameter name. + * @param mixed $value Parameter value. * * @return self - * @throws \InvalidArgumentException When unknown session strategy name given. + * @throws \LogicException When driver wasn't set upfront. */ - public function setSessionStrategy($session_strategy) + protected function setParameter($name, $value) { - $this->parameters['sessionStrategy'] = $session_strategy; + if ( !isset($this->_driverFactory) ) { + throw new \LogicException('Please set "driver" parameter first.'); + } + + $this->_parameters[$name] = $value; return $this; } /** - * Returns session strategy name. + * Returns parameter value. * - * @return string + * @param string $name Name. + * + * @return mixed + * @throws \InvalidArgumentException When unknown parameter was requested. */ - public function getSessionStrategy() + protected function getParameter($name) { - return $this->parameters['sessionStrategy']; + $merged = self::arrayMergeRecursive($this->_mergedDefaults, $this->_parameters); + + if ( array_key_exists($name, $merged) ) { + return $merged[$name]; + } + + throw new \InvalidArgumentException('Unable to get unknown parameter "' . $name . '"'); } /** - * Tells if browser configuration requires a session, that is shared across tests in a test case. + * Creates driver based on browser configuration. * - * @return boolean + * @return DriverInterface */ - public function isShared() + public function createDriver() { - return $this->getSessionStrategy() == ISessionStrategyFactory::TYPE_SHARED; + $factory = $this->_driverFactoryRegistry->get($this->getDriver()); + + return $factory->createDriver($this); } /** @@ -556,9 +535,9 @@ public function getTestStatus(BrowserTestCase $test_case, \PHPUnit_Framework_Tes */ public function getChecksum() { - ksort($this->parameters); + ksort($this->_parameters); - return crc32(serialize($this->parameters)); + return crc32(serialize($this->_parameters)); } /** @@ -589,6 +568,26 @@ protected static function arrayMergeRecursive($array1, $array2) return $array1; } + /** + * Allows to retrieve a parameter by name. + * + * @param string $method Method name. + * @param array $args Arguments. + * + * @return mixed + * @throws \BadMethodCallException When non-parameter getter method is invoked. + */ + public function __call($method, array $args) + { + if ( substr($method, 0, 3) === 'get' ) { + return $this->getParameter(lcfirst(substr($method, 3))); + } + + throw new \BadMethodCallException( + 'Method "' . $method . '" does not exist on ' . get_class($this) . ' class' + ); + } + /** * Hook, called from "BrowserTestCase::setUp" method. * diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php index 01c6913..154e80f 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php @@ -68,6 +68,7 @@ public function createBrowserConfiguration(array $config, BrowserTestCase $test_ $config = BrowserConfiguration::resolveAliases($config, $aliases); $type = isset($config['type']) ? $config['type'] : 'default'; + unset($config['type']); return $this->create($type)->setAliases($aliases)->setup($config); } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php index dc61bd9..69e3443 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php @@ -12,7 +12,6 @@ use aik099\PHPUnit\Event\TestEvent; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Browser configuration tailored to use with "BrowserStack" service. @@ -21,21 +20,7 @@ */ class BrowserStackBrowserConfiguration extends ApiBrowserConfiguration { - - /** - * Creates browser configuration. - * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. - */ - public function __construct( - EventDispatcherInterface $event_dispatcher, - IBrowserConfigurationFactory $browser_configuration_factory - ) { - $this->defaultParameters['type'] = 'browserstack'; - - parent::__construct($event_dispatcher, $browser_configuration_factory); - } + const TYPE = 'browserstack'; /** * Hook, called from "BrowserTestCase::setUp" method. diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 94618aa..dcea161 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -12,7 +12,6 @@ use aik099\PHPUnit\Event\TestEvent; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Browser configuration tailored to use with "Sauce Labs" service. @@ -21,21 +20,7 @@ */ class SauceLabsBrowserConfiguration extends ApiBrowserConfiguration { - - /** - * Creates browser configuration. - * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. - */ - public function __construct( - EventDispatcherInterface $event_dispatcher, - IBrowserConfigurationFactory $browser_configuration_factory - ) { - $this->defaultParameters['type'] = 'saucelabs'; - - parent::__construct($event_dispatcher, $browser_configuration_factory); - } + const TYPE = 'saucelabs'; /** * Hook, called from "BrowserTestCase::setUp" method. diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index 694779e..329814b 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -15,6 +15,11 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; +use aik099\PHPUnit\MinkDriver\GoutteDriverFactory; +use aik099\PHPUnit\MinkDriver\SahiDriverFactory; +use aik099\PHPUnit\MinkDriver\Selenium2DriverFactory; +use aik099\PHPUnit\MinkDriver\ZombieDriverFactory; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteUrl; use aik099\PHPUnit\Session\IsolatedSessionStrategy; @@ -120,17 +125,36 @@ public function __construct(array $values = array()) return $test_suite; }); + $this['driver_factory_registry'] = function () { + $registry = new DriverFactoryRegistry(); + + $registry->add(new Selenium2DriverFactory()); + $registry->add(new SahiDriverFactory()); + $registry->add(new GoutteDriverFactory()); + $registry->add(new ZombieDriverFactory()); + + return $registry; + }; + $this['browser_configuration_factory'] = function ($c) { $browser_configuration_factory = new BrowserConfigurationFactory(); $browser_configuration_factory->register( - new BrowserConfiguration($c['event_dispatcher']) + new BrowserConfiguration($c['event_dispatcher'], $c['driver_factory_registry']) ); $browser_configuration_factory->register( - new SauceLabsBrowserConfiguration($c['event_dispatcher'], $browser_configuration_factory) + new SauceLabsBrowserConfiguration( + $c['event_dispatcher'], + $c['driver_factory_registry'], + $browser_configuration_factory + ) ); $browser_configuration_factory->register( - new BrowserStackBrowserConfiguration($c['event_dispatcher'], $browser_configuration_factory) + new BrowserStackBrowserConfiguration( + $c['event_dispatcher'], + $c['driver_factory_registry'], + $browser_configuration_factory + ) ); return $browser_configuration_factory; diff --git a/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php b/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php new file mode 100644 index 0000000..dadb84d --- /dev/null +++ b/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php @@ -0,0 +1,60 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace aik099\PHPUnit\MinkDriver; + + +class DriverFactoryRegistry +{ + + /** + * Driver factory registry. + * + * @var IMinkDriverFactory[] + */ + private $_registry = array(); + + /** + * Registers Mink driver factory. + * + * @param IMinkDriverFactory $driver_factory Driver factory. + * + * @return void + */ + public function add(IMinkDriverFactory $driver_factory) + { + $driver_name = $driver_factory->getDriverName(); + + if ( isset($this->_registry[$driver_name]) ) { + throw new \LogicException('Driver factory for "' . $driver_name . '" driver is already registered.'); + } + + $this->_registry[$driver_name] = $driver_factory; + } + + /** + * Looks up driver factory by name of the driver it can create. + * + * @param string $driver_name Driver name. + * + * @return IMinkDriverFactory + * @throws \OutOfBoundsException When driver not found. + */ + public function get($driver_name) + { + if ( !isset($this->_registry[$driver_name]) ) { + throw new \OutOfBoundsException(sprintf('No driver factory for "%s" driver.', $driver_name)); + } + + return $this->_registry[$driver_name]; + } + +} diff --git a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php index 3626fbd..5e3efac 100644 --- a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php @@ -13,21 +13,112 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Driver\GoutteDriver; +use Behat\Mink\Driver\DriverInterface; class GoutteDriverFactory implements IMinkDriverFactory { /** - * Return a new instance of the Goutte driver. + * Returns driver name, that can be used in browser configuration. + * + * @return string + */ + public function getDriverName() + { + return 'goutte'; + } + + /** + * Returns default values for browser configuration. + * + * @return array + */ + public function getDriverDefaults() + { + return array( + 'driverOptions' => array( + 'server_parameters' => array(), + 'guzzle_parameters' => array(), + ), + ); + } + + /** + * Returns a new driver instance according to the browser configuration. * * @param BrowserConfiguration $browser The browser configuration. * - * @return GoutteDriver + * @return DriverInterface */ - public function getInstance(BrowserConfiguration $browser) + public function createDriver(BrowserConfiguration $browser) { - return new GoutteDriver(); + if ( !class_exists('Behat\Mink\Driver\GoutteDriver') ) { + throw new \RuntimeException( + 'Install MinkGoutteDriver in order to use goutte driver.' + ); + } + + $driver_options = $browser->getDriverOptions(); + + if ( $this->_isGoutte1() ) { + $guzzle_client = $this->_buildGuzzle3Client($driver_options['guzzle_parameters']); + } + else { + $guzzle_client = $this->_buildGuzzle4Client($driver_options['guzzle_parameters']); + } + + $goutte_client = new \Behat\Mink\Driver\Goutte\Client($driver_options['server_parameters']); + $goutte_client->setClient($guzzle_client); + + return new \Behat\Mink\Driver\GoutteDriver($goutte_client); + } + + /** + * Builds Guzzle 4 client. + * + * @param array $parameters Parameters. + * + * @return \GuzzleHttp\Client + */ + private function _buildGuzzle4Client(array $parameters) + { + // Force the parameters set by default in Goutte to reproduce its behavior. + $parameters['allow_redirects'] = false; + $parameters['cookies'] = true; + + return new \GuzzleHttp\Client(array('defaults' => $parameters)); + + } + + /** + * Builds Guzzle 3 client. + * + * @param array $parameters Parameters. + * + * @return \Guzzle\Http\Client + */ + private function _buildGuzzle3Client(array $parameters) + { + // Force the parameters set by default in Goutte to reproduce its behavior. + $parameters['redirect.disable'] = true; + + return new \Guzzle\Http\Client(null, $parameters); + } + + /** + * Determines Goutte client version. + * + * @return boolean + */ + private function _isGoutte1() + { + $reflection = new \ReflectionParameter(array('Goutte\Client', 'setClient'), 0); + + if ( $reflection->getClass() && 'Guzzle\Http\ClientInterface' === $reflection->getClass()->getName() ) { + return true; + } + + return false; } } diff --git a/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php index c18a4a4..9ee6eb9 100644 --- a/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php @@ -19,13 +19,26 @@ interface IMinkDriverFactory { /** - * Return a new driver instance according to the - * browser configuration. + * Returns driver name, that can be used in browser configuration. + * + * @return string + */ + public function getDriverName(); + + /** + * Returns default values for browser configuration. + * + * @return array + */ + public function getDriverDefaults(); + + /** + * Returns a new driver instance according to the browser configuration. * * @param BrowserConfiguration $browser The browser configuration. * * @return DriverInterface */ - public function getInstance(BrowserConfiguration $browser); + public function createDriver(BrowserConfiguration $browser); } diff --git a/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php index 6e1b1bb..152bf5c 100644 --- a/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php @@ -13,24 +13,67 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Driver\SahiDriver; +use Behat\Mink\Driver\DriverInterface; class SahiDriverFactory implements IMinkDriverFactory { /** - * Return a new SahiDriver instance + * Returns driver name, that can be used in browser configuration. + * + * @return string + */ + public function getDriverName() + { + return 'sahi'; + } + + /** + * Returns default values for browser configuration. + * + * @return array + */ + public function getDriverDefaults() + { + return array( + 'port' => 9999, + 'driverOptions' => array( + 'sid' => null, + 'limit' => 600, + 'browser' => null, + ), + ); + } + + /** + * Returns a new driver instance according to the browser configuration. * * @param BrowserConfiguration $browser The browser configuration. * - * @return SahiDriver + * @return DriverInterface */ - public function getInstance(BrowserConfiguration $browser) + public function createDriver(BrowserConfiguration $browser) { - $connection = new \Behat\SahiClient\Connection(null, $browser->getHost(), $browser->getPort()); - $driver = new SahiDriver($browser->getBrowserName(), new \Behat\SahiClient\Client($connection)); + if ( !class_exists('Behat\Mink\Driver\SahiDriver') ) { + throw new \RuntimeException( + 'Install MinkSahiDriver in order to use sahi driver.' + ); + } + + $driver_options = $browser->getDriverOptions(); + + $connection = new \Behat\SahiClient\Connection( + $driver_options['sid'], + $browser->getHost(), + $browser->getPort(), + $driver_options['browser'], + $driver_options['limit'] + ); - return $driver; + return new \Behat\Mink\Driver\SahiDriver( + $browser->getBrowserName(), + new \Behat\SahiClient\Client($connection) + ); } } diff --git a/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php b/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php index fd1ea6b..7de9072 100644 --- a/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php @@ -13,28 +13,57 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Driver\Selenium2Driver; +use Behat\Mink\Driver\DriverInterface; class Selenium2DriverFactory implements IMinkDriverFactory { /** - * Instantiate and return the selenium 2 driver instance. + * Returns driver name, that can be used in browser configuration. + * + * @return string + */ + public function getDriverName() + { + return 'selenium2'; + } + + /** + * Returns default values for browser configuration. + * + * @return array + */ + public function getDriverDefaults() + { + return array( + 'port' => 4444, + 'driverOptions' => array(), + ); + } + + /** + * Returns a new driver instance according to the browser configuration. * * @param BrowserConfiguration $browser The browser configuration. * - * @return Selenium2Driver + * @return DriverInterface */ - public function getInstance(BrowserConfiguration $browser) + public function createDriver(BrowserConfiguration $browser) { + if ( !class_exists('Behat\Mink\Driver\Selenium2Driver') ) { + throw new \RuntimeException( + 'Install MinkSelenium2Driver in order to use selenium2 driver.' + ); + } + $browser_name = $browser->getBrowserName(); $capabilities = $browser->getDesiredCapabilities(); $capabilities['browserName'] = $browser_name; - // TODO: maybe doesn't work! + // TODO: Maybe doesn't work! ini_set('default_socket_timeout', $browser->getTimeout()); - $driver = new Selenium2Driver( + $driver = new \Behat\Mink\Driver\Selenium2Driver( $browser_name, $capabilities, 'http://' . $browser->getHost() . ':' . $browser->getPort() . '/wd/hub' diff --git a/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php index 31bb010..dee21bc 100644 --- a/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php @@ -13,26 +13,65 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Driver\NodeJS\Server\ZombieServer; -use Behat\Mink\Driver\ZombieDriver; +use Behat\Mink\Driver\DriverInterface; class ZombieDriverFactory implements IMinkDriverFactory { /** - * Return a new instance of the Zombie driver. + * Returns driver name, that can be used in browser configuration. + * + * @return string + */ + public function getDriverName() + { + return 'zombie'; + } + + /** + * Returns default values for browser configuration. + * + * @return array + */ + public function getDriverDefaults() + { + return array( + 'port' => 8124, + 'driverOptions' => array( + 'node_bin' => 'node', + 'server_path' => null, + 'threshold' => 2000000, + 'node_modules_path' => '', + ), + ); + } + + /** + * Returns a new driver instance according to the browser configuration. * * @param BrowserConfiguration $browser The browser configuration. * - * @return ZombieDriver + * @return DriverInterface */ - public function getInstance(BrowserConfiguration $browser) + public function createDriver(BrowserConfiguration $browser) { - $options = $browser->getDriverOptions(); - $node_bin = isset($options['node_binary']) ? $options['node_binary'] : null; + if ( !class_exists('Behat\Mink\Driver\ZombieDriver') ) { + throw new \RuntimeException( + 'Install MinkZombieDriver in order to use zombie driver.' + ); + } + + $driver_options = $browser->getDriverOptions(); - return new ZombieDriver( - new ZombieServer($browser->getHost(), $browser->getPort(), $node_bin) + return new \Behat\Mink\Driver\ZombieDriver( + new \Behat\Mink\Driver\NodeJS\Server\ZombieServer( + $browser->getHost(), + $browser->getPort(), + $driver_options['node_bin'], + $driver_options['server_path'], + $driver_options['threshold'], + $driver_options['node_modules_path'] + ) ); } diff --git a/library/aik099/PHPUnit/Session/SessionFactory.php b/library/aik099/PHPUnit/Session/SessionFactory.php index 5f05fb2..80a6e1e 100644 --- a/library/aik099/PHPUnit/Session/SessionFactory.php +++ b/library/aik099/PHPUnit/Session/SessionFactory.php @@ -12,8 +12,6 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; -use Behat\Mink\Driver\DriverInterface; use Behat\Mink\Session; /** @@ -24,37 +22,6 @@ class SessionFactory implements ISessionFactory { - /** - * The driver factory registry. - * - * @var IMinkDriverFactory[] - */ - private $_driverFactoryRegistry = array(); - - /** - * The default driver factories. Only those present will be added to the $_driverFactoryRegistry array. - * - * @var string[] - */ - private $_defaultDriverFactories = array( - 'selenium2' => 'aik099\PHPUnit\MinkDriver\Selenium2DriverFactory', - 'sahi' => 'aik099\PHPUnit\MinkDriver\SahiDriverFactory', - 'goutte' => 'aik099\PHPUnit\MinkDriver\GoutteDriverFactory', - 'zombie' => 'aik099\PHPUnit\MinkDriver\ZombieDriverFactory', - ); - - /** - * Initialize the driver factory registry array. - */ - public function __construct() - { - foreach ( $this->_defaultDriverFactories as $alias => $factory_class ) { - if ( class_exists($factory_class) ) { - $this->registerDriverFactory($alias, new $factory_class()); - } - } - } - /** * Creates new session based on browser configuration. * @@ -64,72 +31,7 @@ public function __construct() */ public function createSession(BrowserConfiguration $browser) { - return new Session($this->_createDriver($browser)); - } - - /** - * Creates driver based on browser configuration. - * - * @param BrowserConfiguration $browser Browser configuration. - * - * @return DriverInterface - */ - private function _createDriver(BrowserConfiguration $browser) - { - $driver_alias = $browser->getDriver(); - - if ( !array_key_exists($driver_alias, $this->_driverFactoryRegistry) ) { - throw new \OutOfBoundsException(sprintf('No driver factory for driver "%s"', $driver_alias)); - } - - $factory = $this->_getDriverFactory($driver_alias); - - return $factory->getInstance($browser); - } - - /** - * Lazy instantiation of the driver factory. - * - * @param string $driver_alias The driver alias for the driver factory. - * - * @return IMinkDriverFactory - */ - private function _getDriverFactory($driver_alias) - { - if ( is_string($this->_driverFactoryRegistry[$driver_alias]) ) { - $this->_driverFactoryRegistry[$driver_alias] = new $this->_driverFactoryRegistry[$driver_alias](); - } - - return $this->_driverFactoryRegistry[$driver_alias]; - } - - /** - * Register a new mink driver factory by either specifying the class name or an instance. - * - * @param string $driver_alias The driver alias. - * @param IMinkDriverFactory $driver_factory The driver factory class or instance. - * - * @return void - * @throws \InvalidArgumentException If the driver alias is not a string. - */ - public function registerDriverFactory($driver_alias, IMinkDriverFactory $driver_factory) - { - $this->_validateDriverAlias($driver_alias); - $this->_driverFactoryRegistry[$driver_alias] = $driver_factory; - } - - /** - * Validate the driver alias. - * - * @param string $driver_alias The driver alias. - * - * @return void - */ - private function _validateDriverAlias($driver_alias) - { - if ( !is_string($driver_alias) ) { - throw new \InvalidArgumentException('The Mink driver alias must be a string.'); - } + return new Session($browser->createDriver()); } } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index b34290a..f5d3722 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -67,8 +67,8 @@ protected function setUp() parent::setUp(); $this->setup['port'] = 80; - $this->setup['api_username'] = 'UN'; - $this->setup['api_key'] = 'AK'; + $this->setup['apiUsername'] = 'UN'; + $this->setup['apiKey'] = 'AK'; } /** @@ -80,8 +80,37 @@ public function testSetup() { parent::testSetup(); - $this->assertSame($this->setup['api_username'], $this->browser->getApiUsername()); - $this->assertSame($this->setup['api_key'], $this->browser->getApiKey()); + $this->assertSame($this->setup['apiUsername'], $this->browser->getApiUsername()); + $this->assertSame($this->setup['apiKey'], $this->browser->getApiKey()); + } + + public function testSnakeCaseParameters() + { + $this->browser->setup(array( + 'api_username' => 'old-user', + 'api_key' => 'old-key', + )); + + $this->assertEquals('old-user', $this->browser->getApiUsername()); + $this->assertEquals('old-key', $this->browser->getApiKey()); + + $this->browser->setup(array( + 'api_username' => 'old-user', + 'api_key' => 'old-key', + 'apiUsername' => 'new-user', + 'apiKey' => 'new-key', + )); + + $this->assertEquals('old-user', $this->browser->getApiUsername()); + $this->assertEquals('old-key', $this->browser->getApiKey()); + + $this->browser->setup(array( + 'apiUsername' => 'new-user', + 'apiKey' => 'new-key', + )); + + $this->assertEquals('new-user', $this->browser->getApiUsername()); + $this->assertEquals('new-key', $this->browser->getApiKey()); } /** @@ -454,7 +483,11 @@ public function tunnelIdentifierDataProvider() protected function createBrowserConfiguration(array $aliases = array(), $add_subscriber = false, $with_api = false) { /** @var ApiBrowserConfiguration $browser */ - $browser = new $this->browserConfigurationClass($this->eventDispatcher, $this->browserConfigurationFactory); + $browser = new $this->browserConfigurationClass( + $this->eventDispatcher, + $this->driverFactoryRegistry, + $this->browserConfigurationFactory + ); $browser->setAliases($aliases); $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index 8137eff..1263fd1 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -15,6 +15,7 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Mockery as m; use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; @@ -28,6 +29,13 @@ class BrowserConfigurationFactoryTest extends EventDispatcherAwareTestCase */ private $_factory; + /** + * Driver factory registry. + * + * @var DriverFactoryRegistry|m\MockInterface + */ + private $_driverFactoryRegistry; + /** * Configures the tests. * @@ -38,6 +46,27 @@ protected function setUp() parent::setUp(); $this->_factory = new BrowserConfigurationFactory(); + $this->_driverFactoryRegistry = $this->createDriverFactoryRegistry(); + } + + /** + * Creates driver factory registry. + * + * @return DriverFactoryRegistry + */ + protected function createDriverFactoryRegistry() + { + $registry = m::mock('\\aik099\\PHPUnit\\MinkDriver\\DriverFactoryRegistry'); + + $driver_factory = m::mock('\\aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $driver_factory->shouldReceive('getDriverDefaults')->andReturn(array()); + + $registry + ->shouldReceive('get') + ->with('selenium2') + ->andReturn($driver_factory); + + return $registry; } /** @@ -57,6 +86,9 @@ public function testCreateBrowserConfiguration(array $browser_config, $type) $test_case = m::mock('aik099\\PHPUnit\\BrowserTestCase'); $test_case->shouldReceive('getBrowserAliases')->once()->andReturn($browser_aliases); + $cleaned_browser_config = $browser_config; + unset($cleaned_browser_config['type']); + $browser_configuration = $this->_createBrowserConfiguration($type); $browser_configuration ->shouldReceive('setAliases') @@ -65,7 +97,7 @@ public function testCreateBrowserConfiguration(array $browser_config, $type) ->andReturn($browser_configuration); $browser_configuration ->shouldReceive('setup') - ->with($browser_config) + ->with($cleaned_browser_config) ->once() ->andReturn($browser_configuration); $this->_factory->register($browser_configuration); @@ -124,11 +156,19 @@ public function testRegisterFailure() */ public function testCreateAPIClientSuccess() { - $browser = new SauceLabsBrowserConfiguration($this->eventDispatcher, $this->_factory); + $browser = new SauceLabsBrowserConfiguration( + $this->eventDispatcher, + $this->_driverFactoryRegistry, + $this->_factory + ); $api_client = $this->_factory->createAPIClient($browser); $this->assertInstanceOf('aik099\\PHPUnit\\APIClient\\SauceLabsAPIClient', $api_client); - $browser = new BrowserStackBrowserConfiguration($this->eventDispatcher, $this->_factory); + $browser = new BrowserStackBrowserConfiguration( + $this->eventDispatcher, + $this->_driverFactoryRegistry, + $this->_factory + ); $api_client = $this->_factory->createAPIClient($browser); $this->assertInstanceOf('aik099\\PHPUnit\\APIClient\\BrowserStackAPIClient', $api_client); } @@ -141,7 +181,7 @@ public function testCreateAPIClientSuccess() */ public function testCreateAPIClientFailure() { - $browser = new BrowserConfiguration($this->eventDispatcher); + $browser = new BrowserConfiguration($this->eventDispatcher, $this->_driverFactoryRegistry); $this->_factory->createAPIClient($browser); } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 756a1fb..4ba51bf 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -11,8 +11,10 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use aik099\PHPUnit\Session\ISessionStrategyFactory; use Mockery as m; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; @@ -52,10 +54,17 @@ class BrowserConfigurationTest extends EventDispatcherAwareTestCase /** * Browser configuration. * - * @var BrowserConfiguration + * @var BrowserConfiguration|ApiBrowserConfiguration */ protected $browser; + /** + * Driver factory registry. + * + * @var DriverFactoryRegistry|m\MockInterface + */ + protected $driverFactoryRegistry; + /** * Tests names, that require subscriber. * @@ -80,16 +89,49 @@ protected function setUp() 'desiredCapabilities' => array('platform' => 'Windows 7', 'version' => 10), 'baseUrl' => 'http://other-host', 'sessionStrategy' => ISessionStrategyFactory::TYPE_SHARED, - 'driver' => 'selenium2', - 'driverOptions' => array(), + 'driver' => 'zombie', + 'driverOptions' => array('customSetting' => 'customValue'), ); + $this->driverFactoryRegistry = $this->createDriverFactoryRegistry(); + $this->browser = $this->createBrowserConfiguration( array(), in_array($this->getName(false), $this->testsRequireSubscriber) ); } + /** + * Creates driver factory registry. + * + * @return DriverFactoryRegistry + */ + protected function createDriverFactoryRegistry() + { + $registry = m::mock('\\aik099\\PHPUnit\\MinkDriver\\DriverFactoryRegistry'); + + $selenium2_driver_factory = m::mock('\\aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $selenium2_driver_factory->shouldReceive('getDriverDefaults')->andReturn(array( + 'baseUrl' => 'http://www.super-url.com', + 'driverOptions' => array( + 'driverParam1' => 'driverParamValue1', + ), + )); + $registry + ->shouldReceive('get') + ->with('selenium2') + ->andReturn($selenium2_driver_factory); + + $zombie_driver_factory = m::mock('\\aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $zombie_driver_factory->shouldReceive('getDriverDefaults')->andReturn(array()); + $registry + ->shouldReceive('get') + ->with('zombie') + ->andReturn($zombie_driver_factory); + + return $registry; + } + /** * Test description. * @@ -125,7 +167,8 @@ public function aliasResolutionDataProvider() ), array('alias' => 'a1'), array( - 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'firefox', 'baseUrl' => '', + 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'firefox', + 'baseUrl' => 'http://www.super-url.com', // Comes from driver defaults. ), ), 'recursive alias' => array( @@ -147,7 +190,8 @@ public function aliasResolutionDataProvider() ), array('alias' => 'a1', 'browserName' => 'firefox'), array( - 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'firefox', 'baseUrl' => '', + 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'firefox', + 'baseUrl' => 'http://www.super-url.com', // Comes from driver defaults. ), ), 'with overwrite' => array( @@ -156,14 +200,16 @@ public function aliasResolutionDataProvider() ), array('alias' => 'a1', 'host' => static::HOST), array( - 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'firefox', 'baseUrl' => '', + 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'firefox', + 'baseUrl' => 'http://www.super-url.com', // Comes from driver defaults. ), ), 'without alias given' => array( array(), array('host' => static::HOST, 'port' => static::PORT, 'browserName' => 'safari'), array( - 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'safari', 'baseUrl' => '', + 'host' => static::HOST, 'port' => static::PORT, 'browserName' => 'safari', + 'baseUrl' => 'http://www.super-url.com', // Comes from driver defaults. ), ), ); @@ -237,6 +283,43 @@ public function testSetupScreamsAboutUnknownParameters() $this->browser->setup(array('unknown-parameter' => 'value')); } + public function testGetType() + { + $this->assertEquals('default', $this->browser->getType()); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The Mink driver name must be a string + */ + public function testSetDriverIncorrect() + { + $this->browser->setDriver(array()); + } + + public function testSetDriverCorrect() + { + $expected = 'zombie'; + $this->assertEquals($this->browser, $this->browser->setDriver($expected)); + $this->assertSame($expected, $this->browser->getDriver()); + } + + public function testSetDriverOptionsCorrect() + { + $user_driver_options = array('o1' => 'v1', 'o2' => 'v2'); + $expected_driver_options = array('driverParam1' => 'driverParamValue1') + $user_driver_options; + + $this->assertSame($this->browser, $this->browser->setDriverOptions($user_driver_options)); + $this->assertSame($expected_driver_options, $this->browser->getDriverOptions()); + } + + public function testDriverFactoryDefaultsApplied() + { + $this->browser->setup(array('driver' => 'selenium2')); + + $this->assertEquals('http://www.super-url.com', $this->browser->getBaseUrl()); + } + /** * Test description. * @@ -382,6 +465,34 @@ public function testSetSessionStrategy($expected) $this->assertSame($expected, $this->browser->getSessionStrategy()); } + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Unable to get unknown parameter "nonExisting" + */ + public function testGetParameterIncorrect() + { + $this->browser->getNonExisting(); + } + + public function testCreateDriver() + { + /** @var m\MockInterface $driver_factory */ + $driver_factory = $this->driverFactoryRegistry->get('selenium2'); + $driver_factory->shouldReceive('createDriver')->with($this->browser)->once()->andReturn('OK'); + + $this->assertEquals('OK', $this->browser->createDriver()); + } + + public function testNonExistingMethod() + { + $this->setExpectedException( + '\BadMethodCallException', + 'Method "nonExistingMethod" does not exist on ' . get_class($this->browser) . ' class' + ); + + $this->browser->nonExistingMethod(); + } + /** * Test description. * @@ -487,31 +598,6 @@ public function testChecksumMismatch() $this->assertNotSame($browser1->getChecksum(), $browser2->getChecksum()); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage The Mink driver must be a string - * - * @return void - */ - public function testSetDriverMustReceiveString() - { - $this->browser->setDriver(array()); - } - - public function testDriverClassIsCopiedBySetup() - { - $driver_name = 'selenium2'; - $this->browser->setup(array('driver' => $driver_name)); - $this->assertEquals($driver_name, $this->browser->getDriver()); - } - - public function testSetDriverOptions() - { - $driver_options = array('test driver', 'options'); - $this->browser->setDriverOptions($driver_options); - $this->assertSame($driver_options, $this->browser->getDriverOptions()); - } - /** * Creates instance of browser configuration. * @@ -522,7 +608,7 @@ public function testSetDriverOptions() */ protected function createBrowserConfiguration(array $aliases = array(), $add_subscriber = false) { - $browser = new BrowserConfiguration($this->eventDispatcher); + $browser = new BrowserConfiguration($this->eventDispatcher, $this->driverFactoryRegistry); $browser->setAliases($aliases); $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php index d858671..3b1f94b 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -41,6 +41,11 @@ protected function setUp() $this->setup['host'] = 'UN:AK@hub.browserstack.com'; } + public function testGetType() + { + $this->assertEquals('browserstack', $this->browser->getType()); + } + /** * Test description. * diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 21949a8..d69619e 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -40,6 +40,11 @@ protected function setUp() $this->setup['host'] = 'UN:AK@ondemand.saucelabs.com'; } + public function testGetType() + { + $this->assertEquals('saucelabs', $this->browser->getType()); + } + /** * Test description. * diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index cf62810..63e0f22 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -14,6 +14,7 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageTool; use aik099\PHPUnit\Session\ISessionStrategy; use aik099\PHPUnit\Session\SessionStrategyManager; @@ -84,7 +85,7 @@ public function testSetBrowserCorrect() $test_case = $this->getFixture($session_strategy); - $browser = new BrowserConfiguration($this->eventDispatcher); + $browser = new BrowserConfiguration($this->eventDispatcher, $this->createDriverFactoryRegistry()); $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->once(); $this->assertSame($test_case, $test_case->setBrowser($browser)); @@ -92,6 +93,26 @@ public function testSetBrowserCorrect() $this->assertSame($session_strategy, $test_case->getSessionStrategy()); } + /** + * Creates driver factory registry. + * + * @return DriverFactoryRegistry + */ + protected function createDriverFactoryRegistry() + { + $registry = m::mock('\\aik099\\PHPUnit\\MinkDriver\\DriverFactoryRegistry'); + + $driver_factory = m::mock('\\aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $driver_factory->shouldReceive('getDriverDefaults')->andReturn(array()); + + $registry + ->shouldReceive('get') + ->with('selenium2') + ->andReturn($driver_factory); + + return $registry; + } + /** * Test description. * diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index bc702c5..9fec6ca 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -191,8 +191,8 @@ public function getBrowserAliases() return array( 'saucelabs' => array( 'type' => 'saucelabs', - 'api_username' => getenv('SAUCE_USERNAME'), - 'api_key' => getenv('SAUCE_ACCESS_KEY'), + 'apiUsername' => getenv('SAUCE_USERNAME'), + 'apiKey' => getenv('SAUCE_ACCESS_KEY'), 'browserName' => 'chrome', 'desiredCapabilities' => array('version' => 38), diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index f3b0cc3..02c52f5 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -14,6 +14,7 @@ use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Behat\Mink\Session; use Mockery as m; @@ -34,8 +35,12 @@ protected function setUp() $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); $factory->shouldReceive('createAPIClient')->once()->andReturn($api_client); - $browser_config = array('api_username' => 'a', 'api_key' => 'b'); - $browser = new SauceLabsBrowserConfiguration($this->readAttribute($this, '_eventDispatcher'), $factory); + $browser_config = array('apiUsername' => 'a', 'apiKey' => 'b'); + $browser = new SauceLabsBrowserConfiguration( + $this->readAttribute($this, '_eventDispatcher'), + $this->createDriverFactoryRegistry(), + $factory + ); $factory->shouldReceive('createBrowserConfiguration') ->with($browser_config, $this) ->once() @@ -47,6 +52,26 @@ protected function setUp() parent::setUp(); } + /** + * Creates driver factory registry. + * + * @return DriverFactoryRegistry + */ + protected function createDriverFactoryRegistry() + { + $registry = m::mock('\\aik099\\PHPUnit\\MinkDriver\\DriverFactoryRegistry'); + + $driver_factory = m::mock('\\aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $driver_factory->shouldReceive('getDriverDefaults')->andReturn(array()); + + $registry + ->shouldReceive('get') + ->with('selenium2') + ->andReturn($driver_factory); + + return $registry; + } + /** * Test description. * diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index f51267e..13bf59e 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -76,6 +76,7 @@ public function serviceDefinitionsDataProvider() 'browser_configuration_factory', 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfigurationFactory', ), + array('driver_factory_registry', 'aik099\\PHPUnit\\MinkDriver\\DriverFactoryRegistry'), ); } diff --git a/tests/aik099/PHPUnit/Integration/DataProviderTest.php b/tests/aik099/PHPUnit/Integration/DataProviderTest.php index 15eeeb4..f934b2c 100644 --- a/tests/aik099/PHPUnit/Integration/DataProviderTest.php +++ b/tests/aik099/PHPUnit/Integration/DataProviderTest.php @@ -79,8 +79,8 @@ public function getBrowserAliases() return array( 'saucelabs' => array( 'type' => 'saucelabs', - 'api_username' => getenv('SAUCE_USERNAME'), - 'api_key' => getenv('SAUCE_ACCESS_KEY'), + 'apiUsername' => getenv('SAUCE_USERNAME'), + 'apiKey' => getenv('SAUCE_ACCESS_KEY'), 'browserName' => 'chrome', 'desiredCapabilities' => array('version' => 28), diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php new file mode 100644 index 0000000..97ca139 --- /dev/null +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php @@ -0,0 +1,67 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace tests\aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; +use Mockery as m; + +class DriverFactoryRegistryTest extends \PHPUnit_Framework_TestCase +{ + + /** + * Driver factory registry. + * + * @var DriverFactoryRegistry|m\MockInterface + */ + private $_driverFactoryRegistry; + + public function setUp() + { + parent::setUp(); + + $this->_driverFactoryRegistry = new DriverFactoryRegistry(); + } + + public function testAddingAndGetting() + { + $factory = m::mock('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $factory->shouldReceive('getDriverName')->andReturn('test'); + + $this->_driverFactoryRegistry->add($factory); + + $this->assertSame($factory, $this->_driverFactoryRegistry->get('test')); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Driver factory for "test" driver is already registered. + */ + public function testAddingExisting() + { + $factory = m::mock('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $factory->shouldReceive('getDriverName')->andReturn('test'); + + $this->_driverFactoryRegistry->add($factory); + $this->_driverFactoryRegistry->add($factory); + } + + /** + * @expectedException \OutOfBoundsException + * @expectedExceptionMessage No driver factory for "test" driver. + */ + public function testGettingNonExisting() + { + $this->_driverFactoryRegistry->get('test'); + } + +} diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php new file mode 100644 index 0000000..d22d84f --- /dev/null +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php @@ -0,0 +1,98 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace tests\aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\DIContainer; +use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; +use Mockery as m; + +class DriverFactoryTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @dataProvider driverDataProvider + */ + public function testProperDriverReturned($driver_class, $factory_class) + { + if ( !class_exists($driver_class) ) { + $this->markTestSkipped(sprintf('Mink driver "%s" is not installed.', $driver_class)); + } + + /** @var IMinkDriverFactory $factory */ + $factory = new $factory_class(); + + $this->assertInstanceOf($driver_class, $factory->createDriver($this->createBrowserConfiguration($factory))); + } + + /** + * @dataProvider driverDataProvider + */ + public function testMinkDriverMissingError($driver_class, $factory_class) + { + if ( class_exists($driver_class) ) { + $this->markTestSkipped(sprintf('Mink driver "%s" is installed.', $driver_class)); + } + + /** @var IMinkDriverFactory $factory */ + $factory = new $factory_class(); + $driver_class_parts = explode('\\', $driver_class); + + $this->setExpectedException( + '\RuntimeException', + 'Install Mink' . end($driver_class_parts) . ' in order to use ' . $factory->getDriverName() . ' driver.' + ); + $factory->createDriver($this->createBrowserConfiguration($factory)); + } + + /** + * Creates the browser configuration. + * + * @param IMinkDriverFactory $factory Driver factory. + * + * @return BrowserConfiguration + */ + protected function createBrowserConfiguration(IMinkDriverFactory $factory) + { + $di = new DIContainer(); + + $event_dispatcher = m::mock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); + $browser_configuration = new BrowserConfiguration($event_dispatcher, $di['driver_factory_registry']); + $browser_configuration->setDriver($factory->getDriverName()); + + return $browser_configuration; + } + + public function driverDataProvider() + { + return array( + 'goutte' => array( + 'Behat\\Mink\\Driver\\GoutteDriver', + 'aik099\PHPUnit\MinkDriver\GoutteDriverFactory', + ), + 'sahi' => array( + 'Behat\\Mink\\Driver\\SahiDriver', + 'aik099\PHPUnit\MinkDriver\SahiDriverFactory', + ), + 'selenium2' => array( + 'Behat\\Mink\\Driver\\Selenium2Driver', + 'aik099\PHPUnit\MinkDriver\Selenium2DriverFactory', + ), + 'zombie' => array( + 'Behat\\Mink\\Driver\\ZombieDriver', + 'aik099\PHPUnit\MinkDriver\ZombieDriverFactory', + ), + ); + } + +} diff --git a/tests/aik099/PHPUnit/MinkDriver/GoutteDriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/GoutteDriverFactoryTest.php deleted file mode 100644 index 813d651..0000000 --- a/tests/aik099/PHPUnit/MinkDriver/GoutteDriverFactoryTest.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - - -namespace tests\aik099\PHPUnit\MinkDriver; - - -use aik099\PHPUnit\MinkDriver\GoutteDriverFactory; -use Mockery as m; - -class GoutteDriverFactoryTest extends \PHPUnit_Framework_TestCase -{ - - /** - * @var string - */ - private $_driverClass = 'Behat\\Mink\\Driver\\GoutteDriver'; - - /** - * @var GoutteDriverFactory; - */ - private $_factory; - - public function setUp() - { - if ( !class_exists($this->_driverClass) ) { - $this->markTestSkipped(sprintf('Mink driver not installed: "%s"', $this->_driverClass)); - } - - $this->_factory = new GoutteDriverFactory(); - } - - public function testItImplementsTheDriverFactoryInterface() - { - $this->assertInstanceOf('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory', $this->_factory); - } - - public function testItReturnsAGoutteDriver() - { - $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); - $this->assertInstanceOf($this->_driverClass, $this->_factory->getInstance($browser)); - } - -} diff --git a/tests/aik099/PHPUnit/MinkDriver/SahiDriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/SahiDriverFactoryTest.php deleted file mode 100644 index 5e86e33..0000000 --- a/tests/aik099/PHPUnit/MinkDriver/SahiDriverFactoryTest.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - - -namespace tests\aik099\PHPUnit\MinkDriver; - - -use aik099\PHPUnit\MinkDriver\SahiDriverFactory; -use Mockery as m; - -class SahiDriverFactoryTest extends \PHPUnit_Framework_TestCase -{ - - /** - * @var string - */ - private $_driverClass = 'Behat\\Mink\\Driver\\SahiDriver'; - - /** - * @var SahiDriverFactory; - */ - private $_factory; - - public function setUp() - { - if ( !class_exists($this->_driverClass) ) { - $this->markTestSkipped(sprintf('Mink driver not installed: "%s"', $this->_driverClass)); - } - - $this->_factory = new SahiDriverFactory(); - } - - public function testItImplementsTheDriverFactoryInterface() - { - $this->assertInstanceOf('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory', $this->_factory); - } - - public function testItReturnsASahiDriver() - { - $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); - $browser->shouldReceive('getBrowserName')->once()->andReturn('firefox'); - $browser->shouldReceive('getHost')->once()->andReturn(''); - $browser->shouldReceive('getPort')->once()->andReturn(0); - $this->assertInstanceOf($this->_driverClass, $this->_factory->getInstance($browser)); - } - -} diff --git a/tests/aik099/PHPUnit/MinkDriver/Selenium2DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/Selenium2DriverFactoryTest.php deleted file mode 100644 index abea84a..0000000 --- a/tests/aik099/PHPUnit/MinkDriver/Selenium2DriverFactoryTest.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - - -namespace tests\aik099\PHPUnit\MinkDriver; - - -use aik099\PHPUnit\MinkDriver\Selenium2DriverFactory; -use Mockery as m; - -class Selenium2DriverFactoryTest extends \PHPUnit_Framework_TestCase -{ - - /** - * @var string - */ - private $_driverClass = 'Behat\\Mink\\Driver\\Selenium2Driver'; - - /** - * @var Selenium2DriverFactory; - */ - private $_factory; - - public function setUp() - { - if ( !class_exists($this->_driverClass) ) { - $this->markTestSkipped(sprintf('Mink driver not installed: "%s"', $this->_driverClass)); - } - - $this->_factory = new Selenium2DriverFactory(); - } - - public function testItImplementsTheDriverFactoryInterface() - { - $this->assertInstanceOf('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory', $this->_factory); - } - - public function testItReturnsASelenium2Driver() - { - $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); - $browser->shouldReceive('getDesiredCapabilities')->once()->andReturn(array()); - $browser->shouldReceive('getBrowserName')->once()->andReturn(''); - $browser->shouldReceive('getTimeout')->once()->andReturn(0); - $browser->shouldReceive('getHost')->once()->andReturn(''); - $browser->shouldReceive('getPort')->once()->andReturn(0); - $this->assertInstanceOf($this->_driverClass, $this->_factory->getInstance($browser)); - } - -} diff --git a/tests/aik099/PHPUnit/MinkDriver/ZombieDriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/ZombieDriverFactoryTest.php deleted file mode 100644 index 70a5268..0000000 --- a/tests/aik099/PHPUnit/MinkDriver/ZombieDriverFactoryTest.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - - -namespace tests\aik099\PHPUnit\MinkDriver; - - -use aik099\PHPUnit\MinkDriver\ZombieDriverFactory; -use Mockery as m; - -class ZombieDriverFactoryTest extends \PHPUnit_Framework_TestCase -{ - - /** - * @var string - */ - private $_driverClass = 'Behat\\Mink\\Driver\\ZombieDriver'; - - /** - * @var ZombieDriverFactory; - */ - private $_factory; - - public function setUp() - { - if ( !class_exists($this->_driverClass) ) { - $this->markTestSkipped(sprintf('Mink driver not installed: "%s"', $this->_driverClass)); - } - - $this->_factory = new ZombieDriverFactory(); - } - - public function testItImplementsTheDriverFactoryInterface() - { - $this->assertInstanceOf('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory', $this->_factory); - } - - public function testItReturnsAZombieDriver() - { - $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); - $browser->shouldReceive('getDriverOptions')->once()->andReturn(array()); - $browser->shouldReceive('getHost')->once()->andReturn(''); - $browser->shouldReceive('getPort')->once()->andReturn(0); - $this->assertInstanceOf($this->_driverClass, $this->_factory->getInstance($browser)); - } - -} diff --git a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php index 2702d83..c1229c9 100644 --- a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php +++ b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php @@ -43,71 +43,16 @@ protected function setUp() */ public function testCreateSession() { - $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); - $browser->shouldReceive('getDesiredCapabilities')->once()->andReturn(array()); - $browser->shouldReceive('getBrowserName')->once()->andReturn(''); - $browser->shouldReceive('getTimeout')->once()->andReturn(0); - $browser->shouldReceive('getHost')->once()->andReturn(''); - $browser->shouldReceive('getPort')->once()->andReturn(0); - $browser->shouldReceive('getDriver')->once()->andReturn('selenium2'); - - $session = $this->_factory->createSession($browser); - - $this->assertInstanceOf('Behat\\Mink\\Session', $session); - $this->assertInstanceOf('Behat\\Mink\\Driver\\Selenium2Driver', $session->getDriver()); - } + $driver = m::mock('Behat\\Mink\\Driver\\DriverInterface'); + $driver->shouldReceive('setSession')->with(m::any())->once(); - /** - * @expectedException \OutOfBoundsException - * @expectedExceptionMessage No driver factory for driver - */ - public function testItThrowsExceptionForUnknownDriverAlias() - { $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); - $browser->shouldReceive('getDriver')->once()->andReturn('invalid'); - - $this->_factory->createSession($browser); - } - - /** - * @dataProvider driversAvailableByDefaultProvider - */ - public function testDriversRegisteredByDefault($driver, $expected_driver) - { - if ( !class_exists($expected_driver) ) { - $this->markTestSkipped( - sprintf('Test skipped because Mink driver is not installed: "%s"', $expected_driver) - ); - } - - $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); - $browser->shouldReceive('getDesiredCapabilities')->andReturn(array()); - $browser->shouldReceive('getBrowserName')->andReturn(''); - $browser->shouldReceive('getTimeout')->andReturn(0); - $browser->shouldReceive('getHost')->andReturn(''); - $browser->shouldReceive('getPort')->andReturn(0); - $browser->shouldReceive('getDriverOptions')->andReturn(array()); - $browser->shouldReceive('getDriver')->once()->andReturn($driver); + $browser->shouldReceive('createDriver')->once()->andReturn($driver); $session = $this->_factory->createSession($browser); - $this->assertInstanceOf($expected_driver, $session->getDriver()); - } - public function driversAvailableByDefaultProvider() - { - return array( - 'selenium2' => array('selenium2', 'Behat\\Mink\\Driver\\Selenium2Driver'), - 'sahi' => array('sahi', 'Behat\\Mink\\Driver\\SahiDriver'), - 'goutte' => array('goutte', 'Behat\\Mink\\Driver\\GoutteDriver'), - 'zombie' => array('zombie', 'Behat\\Mink\\Driver\\ZombieDriver'), - ); - } - - public function testItRegistersTheDriverFactory() - { - $stub_factory = m::mock('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); - $this->_factory->registerDriverFactory('test', $stub_factory); - $this->assertAttributeContains($stub_factory, '_driverFactoryRegistry', $this->_factory); + $this->assertInstanceOf('Behat\\Mink\\Session', $session); + $this->assertSame($driver, $session->getDriver()); } } From b5ab689a1b5b5fc9dc0bf71678eb6cf197d62487 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 14 Mar 2015 20:34:13 +0200 Subject: [PATCH 084/204] Make tunnel identifier user-configurable - disable tunneling by default - update docs to include tunnel identifier environment variable name --- .travis.yml | 3 --- docs/getting-started.rst | 14 ++++++++++++++ .../BrowserStackBrowserConfiguration.php | 4 ++-- .../SauceLabsBrowserConfiguration.php | 4 ++-- .../ApiBrowserConfigurationTestCase.php | 12 ++++++------ .../BrowserStackBrowserConfigurationTest.php | 2 +- .../SauceLabsBrowserConfigurationTest.php | 2 +- 7 files changed, 26 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9d298b0..ceefd56 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,9 +32,6 @@ env: - secure: Tsh/Vvb9auy672eRf0xbN8fKDr8OYzjRkZDHiaYc5yH49UkoromwPaC74mJtM5KxFOYalrC+GzwOSuvzT8RYO/XwTuk6IGw9P/0v0qMCaSLkjaRzerwVH1L3RPgDokqDnCHAgSzkAlg8d5o0MWBlbxaYiaKL4LmEKGwxQjrW590= - secure: HQQ1FY27tpn0Idy+NDYXdbnMjHKIOsZoE59qYfs18euS0zM559gcuMk4OQ/J2lcDFmdb6vjSFlznwH+6iVyoLuC5WAP3JGQ3UXSJ+7huRV/eDI6WepmEymjEOSWvTT+RYpmQu1lQWC2Y3zBCVbVT7sbVsqXvmuR2daBL11dpU+g= -addons: - sauce_connect: true - install: - composer require satooshi/php-coveralls:dev-master --dev diff --git a/docs/getting-started.rst b/docs/getting-started.rst index 0fe1798..cf3e577 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -50,6 +50,20 @@ tests were running locally. :linenos: :emphasize-lines: 11-13,19-21 +Continuous Integration +^^^^^^^^^^^^^^^^^^^^^^ +When website under test isn't publicly accessible, then: + +#. secure tunnel needs to be created from website under test to server, that runs the tests +#. created tunnel identifier needs to specified in the ``PHPUNIT_MINK_TUNNEL_ID`` environment variable + +.. note:: Before v2.1.0 the environment variable was called ``TRAVIS_JOB_NUMBER``. + +How to Create a Tunnel +---------------------- +* SauceLabs: https://docs.saucelabs.com/reference/sauce-connect/ +* BrowserStack: http://www.browserstack.com/automate/php#setting-local-tunnel + .. _`Mink`: https://github.com/Behat/Mink .. _`Sauce Labs`: https://saucelabs.com/ .. _`BrowserStack`: http://www.browserstack.com/ diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php index dc61bd9..3816664 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php @@ -54,9 +54,9 @@ public function onTestSetup(TestEvent $event) $desired_capabilities = $this->getDesiredCapabilities(); - if ( getenv('TRAVIS_JOB_NUMBER') ) { + if ( getenv('PHPUNIT_MINK_TUNNEL_ID') ) { $desired_capabilities['browserstack.local'] = 'true'; - $desired_capabilities['browserstack.localIdentifier'] = getenv('TRAVIS_JOB_NUMBER'); + $desired_capabilities['browserstack.localIdentifier'] = getenv('PHPUNIT_MINK_TUNNEL_ID'); } $this->setDesiredCapabilities($desired_capabilities); diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 94618aa..2343a9e 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -54,8 +54,8 @@ public function onTestSetup(TestEvent $event) $desired_capabilities = $this->getDesiredCapabilities(); - if ( getenv('TRAVIS_JOB_NUMBER') ) { - $desired_capabilities['tunnel-identifier'] = getenv('TRAVIS_JOB_NUMBER'); + if ( getenv('PHPUNIT_MINK_TUNNEL_ID') ) { + $desired_capabilities['tunnel-identifier'] = getenv('PHPUNIT_MINK_TUNNEL_ID'); } $this->setDesiredCapabilities($desired_capabilities); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index b34290a..926b5ee 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -381,20 +381,20 @@ protected function createTestCase($name, $get_browser = true) /** * Test description. * - * @param string|null $travis_job_number Travis Job Number. + * @param string|null $tunnel_id Tunnel ID. * * @return void * @dataProvider tunnelIdentifierDataProvider */ - public function testTunnelIdentifier($travis_job_number = null) + public function testTunnelIdentifier($tunnel_id = null) { // Reset any global env vars that might be left from previous tests. $hhvm_hack = defined('HHVM_VERSION') ? '=' : ''; - putenv('TRAVIS_JOB_NUMBER' . $hhvm_hack); + putenv('PHPUNIT_MINK_TUNNEL_ID' . $hhvm_hack); - if ( isset($travis_job_number) ) { - putenv('TRAVIS_JOB_NUMBER=' . $travis_job_number); + if ( isset($tunnel_id) ) { + putenv('PHPUNIT_MINK_TUNNEL_ID=' . $tunnel_id); } $this->browser->setSessionStrategy(ISessionStrategyFactory::TYPE_ISOLATED); @@ -412,7 +412,7 @@ public function testTunnelIdentifier($travis_job_number = null) $desired_capabilities = $this->browser->getDesiredCapabilities(); - if ( isset($travis_job_number) ) { + if ( isset($tunnel_id) ) { foreach ( $this->tunnelCapabilities as $name => $value ) { if ( substr($value, 0, 4) === 'env:' ) { $value = getenv(substr($value, 4)); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php index d858671..d2a0fee 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -29,7 +29,7 @@ protected function setUp() $this->tunnelCapabilities = array( 'browserstack.local' => 'true', - 'browserstack.localIdentifier' => 'env:TRAVIS_JOB_NUMBER', + 'browserstack.localIdentifier' => 'env:PHPUNIT_MINK_TUNNEL_ID', ); parent::setUp(); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 21949a8..b93082b 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -32,7 +32,7 @@ protected function setUp() $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\SauceLabsBrowserConfiguration'; $this->tunnelCapabilities = array( - 'tunnel-identifier' => 'env:TRAVIS_JOB_NUMBER', + 'tunnel-identifier' => 'env:PHPUNIT_MINK_TUNNEL_ID', ); parent::setUp(); From 4dff5b0228381026226bd667db8a666da176d473 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 28 Mar 2015 14:06:48 +0200 Subject: [PATCH 085/204] Move creation of API clients to corresponding browser configurations --- .../ApiBrowserConfiguration.php | 21 +---- .../BrowserConfigurationFactory.php | 31 ------- .../BrowserStackBrowserConfiguration.php | 17 ++++ .../IBrowserConfigurationFactory.php | 11 --- .../SauceLabsBrowserConfiguration.php | 15 ++++ library/aik099/PHPUnit/DIContainer.php | 12 +-- .../ApiBrowserConfigurationTestCase.php | 81 +++++++------------ .../BrowserConfigurationFactoryTest.php | 38 --------- .../BrowserConfigurationTest.php | 44 +++++++++- .../BrowserStackBrowserConfigurationTest.php | 9 ++- .../SauceLabsBrowserConfigurationTest.php | 13 +-- .../PHPUnit/Fixture/SetupEventFixture.php | 18 +++-- 12 files changed, 134 insertions(+), 176 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index b076616..8649091 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -39,26 +39,16 @@ abstract class ApiBrowserConfiguration extends BrowserConfiguration */ const NAME_CAPABILITY = 'name'; - /** - * Browser configuration factory. - * - * @var IBrowserConfigurationFactory - */ - protected $browserConfigurationFactory; - /** * Creates browser configuration. * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * @param DriverFactoryRegistry $driver_factory_registry Driver factory registry. - * @param IBrowserConfigurationFactory $browser_configuration_factory Browser configuration factory. + * @param EventDispatcherInterface $event_dispatcher Event dispatcher. + * @param DriverFactoryRegistry $driver_factory_registry Driver factory registry. */ public function __construct( EventDispatcherInterface $event_dispatcher, - DriverFactoryRegistry $driver_factory_registry, - IBrowserConfigurationFactory $browser_configuration_factory + DriverFactoryRegistry $driver_factory_registry ) { - $this->browserConfigurationFactory = $browser_configuration_factory; $this->defaults['driver'] = 'selenium2'; $this->defaults['apiUsername'] = ''; $this->defaults['apiKey'] = ''; @@ -225,10 +215,7 @@ public function onTestEnded(TestEndedEvent $event) * * @return IAPIClient */ - public function getAPIClient() - { - return $this->browserConfigurationFactory->createAPIClient($this); - } + public abstract function getAPIClient(); /** * Get Selenium2 current session id. diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php index 154e80f..e1f23d2 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactory.php @@ -11,12 +11,7 @@ namespace aik099\PHPUnit\BrowserConfiguration; -use aik099\PHPUnit\APIClient\BrowserStackAPIClient; -use aik099\PHPUnit\APIClient\IAPIClient; -use aik099\PHPUnit\APIClient\SauceLabsAPIClient; use aik099\PHPUnit\BrowserTestCase; -use WebDriver\SauceLabs\SauceRest; -use WebDriver\ServiceFactory; /** * Browser configuration factory. @@ -90,30 +85,4 @@ protected function create($type) return clone $this->browserConfigurations[$type]; } - /** - * Creates API client. - * - * @param BrowserConfiguration $browser Browser configuration. - * - * @return IAPIClient - * @throws \LogicException When unsupported browser configuration given. - */ - public function createAPIClient(BrowserConfiguration $browser) - { - if ( $browser instanceof SauceLabsBrowserConfiguration ) { - $sauce_rest = new SauceRest($browser->getApiUsername(), $browser->getApiKey()); - - return new SauceLabsAPIClient($sauce_rest); - } - elseif ( $browser instanceof BrowserStackBrowserConfiguration ) { - return new BrowserStackAPIClient( - $browser->getApiUsername(), - $browser->getApiKey(), - ServiceFactory::getInstance()->getService('service.curl') - ); - } - - throw new \LogicException('Unsupported browser configuration given'); - } - } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php index 8a71af6..e9072d7 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php @@ -11,7 +11,10 @@ namespace aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\APIClient\BrowserStackAPIClient; +use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\Event\TestEvent; +use WebDriver\ServiceFactory; /** * Browser configuration tailored to use with "BrowserStack" service. @@ -22,6 +25,20 @@ class BrowserStackBrowserConfiguration extends ApiBrowserConfiguration { const TYPE = 'browserstack'; + /** + * Returns API class for service interaction. + * + * @return IAPIClient + */ + public function getAPIClient() + { + return new BrowserStackAPIClient( + $this->getApiUsername(), + $this->getApiKey(), + ServiceFactory::getInstance()->getService('service.curl') + ); + } + /** * Hook, called from "BrowserTestCase::setUp" method. * diff --git a/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php b/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php index 699af6a..69e1570 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/IBrowserConfigurationFactory.php @@ -11,7 +11,6 @@ namespace aik099\PHPUnit\BrowserConfiguration; -use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserTestCase; /** @@ -42,14 +41,4 @@ public function createBrowserConfiguration(array $config, BrowserTestCase $test_ */ public function register(BrowserConfiguration $browser); - /** - * Creates API client. - * - * @param BrowserConfiguration $browser Browser configuration. - * - * @return IAPIClient - * @throws \LogicException When unsupported browser configuration given. - */ - public function createAPIClient(BrowserConfiguration $browser); - } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 7f1a03c..02ebf8b 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -11,7 +11,10 @@ namespace aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\APIClient\IAPIClient; +use aik099\PHPUnit\APIClient\SauceLabsAPIClient; use aik099\PHPUnit\Event\TestEvent; +use WebDriver\SauceLabs\SauceRest; /** * Browser configuration tailored to use with "Sauce Labs" service. @@ -22,6 +25,18 @@ class SauceLabsBrowserConfiguration extends ApiBrowserConfiguration { const TYPE = 'saucelabs'; + /** + * Returns API class for service interaction. + * + * @return IAPIClient + */ + public function getAPIClient() + { + $sauce_rest = new SauceRest($this->getApiUsername(), $this->getApiKey()); + + return new SauceLabsAPIClient($sauce_rest); + } + /** * Hook, called from "BrowserTestCase::setUp" method. * diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index 329814b..9bd56ad 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -143,18 +143,10 @@ public function __construct(array $values = array()) new BrowserConfiguration($c['event_dispatcher'], $c['driver_factory_registry']) ); $browser_configuration_factory->register( - new SauceLabsBrowserConfiguration( - $c['event_dispatcher'], - $c['driver_factory_registry'], - $browser_configuration_factory - ) + new SauceLabsBrowserConfiguration($c['event_dispatcher'], $c['driver_factory_registry']) ); $browser_configuration_factory->register( - new BrowserStackBrowserConfiguration( - $c['event_dispatcher'], - $c['driver_factory_registry'], - $browser_configuration_factory - ) + new BrowserStackBrowserConfiguration($c['event_dispatcher'], $c['driver_factory_registry']) ); return $browser_configuration_factory; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index b700567..9b17a91 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -11,12 +11,11 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; -use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Event\TestEvent; use aik099\PHPUnit\Session\ISessionStrategyFactory; -use Mockery\MockInterface; use Symfony\Component\EventDispatcher\EventDispatcher; use aik099\PHPUnit\BrowserTestCase; use Mockery as m; @@ -29,25 +28,18 @@ abstract class ApiBrowserConfigurationTestCase extends BrowserConfigurationTest const AUTOMATIC_TEST_NAME = 'AUTOMATIC'; /** - * Browser configuration class. - * - * @var string - */ - protected $browserConfigurationClass = ''; - - /** - * Browser configuration factory. + * Desired capabilities use to configure the tunnel. * - * @var IBrowserConfigurationFactory|MockInterface + * @var array */ - protected $browserConfigurationFactory; + protected $tunnelCapabilities = array(); /** - * Desired capabilities use to configure the tunnel. + * API client. * - * @var array + * @var IAPIClient */ - protected $tunnelCapabilities = array(); + protected $apiClient; /** * Configures all tests. @@ -60,9 +52,10 @@ protected function setUp() $this->testsRequireSubscriber[] = 'testTestEndedEvent'; $this->testsRequireSubscriber[] = 'testTestEndedWithoutSession'; $this->testsRequireSubscriber[] = 'testTunnelIdentifier'; - $this->browserConfigurationFactory = m::mock( - 'aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory' - ); + + if ( $this->getName(false) === 'testTestEndedEvent' ) { + $this->mockBrowserMethods[] = 'getAPIClient'; + } parent::setUp(); @@ -133,7 +126,9 @@ public function testSetAPICorrect() */ public function testSetHostCorrect() { - $browser = $this->createBrowserConfiguration(array(), false, true); + $browser = $this->createBrowserConfiguration(); + $browser->setApiUsername('A'); + $browser->setApiKey('B'); $this->assertSame($browser, $browser->setHost('EXAMPLE_HOST')); $this->assertSame('A:B@ondemand.saucelabs.com', $browser->getHost()); @@ -146,7 +141,10 @@ public function testSetHostCorrect() */ public function testSetPortCorrect() { - $browser = $this->createBrowserConfiguration(array(), false, true); + $browser = $this->createBrowserConfiguration(); + $browser->setApiUsername('A'); + $browser->setApiKey('B'); + $this->assertSame($browser, $browser->setPort(5555)); $this->assertSame(80, $browser->getPort()); } @@ -158,7 +156,10 @@ public function testSetPortCorrect() */ public function testSetBrowserNameCorrect() { - $browser = $this->createBrowserConfiguration(array(), false, true); + $browser = $this->createBrowserConfiguration(); + $browser->setApiUsername('A'); + $browser->setApiKey('B'); + $this->assertSame($browser, $browser->setBrowserName('')); $this->assertSame('chrome', $browser->getBrowserName()); } @@ -174,7 +175,10 @@ public function testSetBrowserNameCorrect() */ public function testSetDesiredCapabilitiesCorrect(array $desired_capabilities = null, array $expected = null) { - $browser = $this->createBrowserConfiguration(array(), false, true); + $browser = $this->createBrowserConfiguration(); + $browser->setApiUsername('A'); + $browser->setApiKey('B'); + $this->assertSame($browser, $browser->setDesiredCapabilities($desired_capabilities)); $this->assertSame($expected, $browser->getDesiredCapabilities()); } @@ -296,9 +300,7 @@ public function testTestEndedEvent($driver_type) $test_case = $this->createTestCase('TEST_NAME'); $api_client = m::mock('aik099\\PHPUnit\\APIClient\\IAPIClient'); - $this->browserConfigurationFactory->shouldReceive('createAPIClient') - ->with($this->browser) - ->andReturn($api_client); + $this->browser->shouldReceive('getAPIClient')->andReturn($api_client); if ( $driver_type == 'selenium' ) { $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); @@ -471,33 +473,4 @@ public function tunnelIdentifierDataProvider() ); } - /** - * Creates instance of browser configuration. - * - * @param array $aliases Aliases. - * @param boolean $add_subscriber Expect addition of subscriber to event dispatcher. - * @param boolean $with_api Include test API configuration. - * - * @return ApiBrowserConfiguration - */ - protected function createBrowserConfiguration(array $aliases = array(), $add_subscriber = false, $with_api = false) - { - /** @var ApiBrowserConfiguration $browser */ - $browser = new $this->browserConfigurationClass( - $this->eventDispatcher, - $this->driverFactoryRegistry, - $this->browserConfigurationFactory - ); - $browser->setAliases($aliases); - - $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); - - if ( $with_api ) { - $browser->setApiUsername('A'); - $browser->setApiKey('B'); - } - - return $browser; - } - } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index 1263fd1..f2e8d3c 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -13,8 +13,6 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; -use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; -use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Mockery as m; use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; @@ -149,42 +147,6 @@ public function testRegisterFailure() $this->_factory->register($browser_configuration); } - /** - * Test description. - * - * @return void - */ - public function testCreateAPIClientSuccess() - { - $browser = new SauceLabsBrowserConfiguration( - $this->eventDispatcher, - $this->_driverFactoryRegistry, - $this->_factory - ); - $api_client = $this->_factory->createAPIClient($browser); - $this->assertInstanceOf('aik099\\PHPUnit\\APIClient\\SauceLabsAPIClient', $api_client); - - $browser = new BrowserStackBrowserConfiguration( - $this->eventDispatcher, - $this->_driverFactoryRegistry, - $this->_factory - ); - $api_client = $this->_factory->createAPIClient($browser); - $this->assertInstanceOf('aik099\\PHPUnit\\APIClient\\BrowserStackAPIClient', $api_client); - } - - /** - * Test description. - * - * @return void - * @expectedException \LogicException - */ - public function testCreateAPIClientFailure() - { - $browser = new BrowserConfiguration($this->eventDispatcher, $this->_driverFactoryRegistry); - $this->_factory->createAPIClient($browser); - } - /** * Creates browser configuration. * diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 4ba51bf..331b5f9 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -17,6 +17,7 @@ use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use aik099\PHPUnit\Session\ISessionStrategyFactory; use Mockery as m; +use Mockery\Generator\MockConfigurationBuilder; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; @@ -30,6 +31,13 @@ class BrowserConfigurationTest extends EventDispatcherAwareTestCase const PORT = 1234; + /** + * Browser configuration class. + * + * @var string + */ + protected $browserConfigurationClass = ''; + /** * Hostname. * @@ -58,6 +66,13 @@ class BrowserConfigurationTest extends EventDispatcherAwareTestCase */ protected $browser; + /** + * Browser methods, that needs to be mocked. + * + * @var array + */ + protected $mockBrowserMethods = array(); + /** * Driver factory registry. * @@ -81,6 +96,10 @@ protected function setUp() { parent::setUp(); + if ( !$this->browserConfigurationClass ) { + $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; + } + $this->setup = array( 'host' => self::HOST, 'port' => self::PORT, @@ -97,7 +116,8 @@ protected function setUp() $this->browser = $this->createBrowserConfiguration( array(), - in_array($this->getName(false), $this->testsRequireSubscriber) + in_array($this->getName(false), $this->testsRequireSubscriber), + $this->mockBrowserMethods ); } @@ -603,12 +623,28 @@ public function testChecksumMismatch() * * @param array $aliases Aliases. * @param boolean $add_subscriber Expect addition of subscriber to event dispatcher. + * @param array $mock_methods Mock methods. * * @return BrowserConfiguration */ - protected function createBrowserConfiguration(array $aliases = array(), $add_subscriber = false) - { - $browser = new BrowserConfiguration($this->eventDispatcher, $this->driverFactoryRegistry); + protected function createBrowserConfiguration( + array $aliases = array(), + $add_subscriber = false, + $mock_methods = array() + ) { + if ( $mock_methods ) { + /** @var BrowserConfiguration $browser */ + $browser = m::mock( + $this->browserConfigurationClass . '[' . implode(',', $mock_methods) . ']', + array($this->eventDispatcher, $this->driverFactoryRegistry), + array('getSessionStrategy' => 'isolated') + ); + } + else { + /** @var BrowserConfiguration $browser */ + $browser = new $this->browserConfigurationClass($this->eventDispatcher, $this->driverFactoryRegistry); + } + $browser->setAliases($aliases); $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php index ac0353a..8ea93b5 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -53,7 +53,9 @@ public function testGetType() */ public function testSetHostCorrect() { - $browser = $this->createBrowserConfiguration(array(), false, true); + $browser = $this->createBrowserConfiguration(); + $browser->setApiUsername('A'); + $browser->setApiKey('B'); $this->assertSame($browser, $browser->setHost('EXAMPLE_HOST')); $this->assertSame('A:B@hub.browserstack.com', $browser->getHost()); @@ -78,4 +80,9 @@ public function desiredCapabilitiesDataProvider() ); } + public function testGetAPIClient() + { + $this->assertInstanceOf('aik099\\PHPUnit\\APIClient\\BrowserStackAPIClient', $this->browser->getAPIClient()); + } + } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index efb3ba5..a8e9c75 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -11,11 +11,7 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; -use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEvent; -use aik099\PHPUnit\Session\ISessionStrategyFactory; use Mockery as m; -use Symfony\Component\EventDispatcher\EventDispatcher; class SauceLabsBrowserConfigurationTest extends ApiBrowserConfigurationTestCase { @@ -52,7 +48,9 @@ public function testGetType() */ public function testSetHostCorrect() { - $browser = $this->createBrowserConfiguration(array(), false, true); + $browser = $this->createBrowserConfiguration(); + $browser->setApiUsername('A'); + $browser->setApiKey('B'); $this->assertSame($browser, $browser->setHost('EXAMPLE_HOST')); $this->assertSame('A:B@ondemand.saucelabs.com', $browser->getHost()); @@ -77,4 +75,9 @@ public function desiredCapabilitiesDataProvider() ); } + public function testGetAPIClient() + { + $this->assertInstanceOf('aik099\\PHPUnit\\APIClient\\SauceLabsAPIClient', $this->browser->getAPIClient()); + } + } diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index 02c52f5..a0d8c5c 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -33,14 +33,22 @@ protected function setUp() /** @var IBrowserConfigurationFactory $factory */ $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); - $factory->shouldReceive('createAPIClient')->once()->andReturn($api_client); $browser_config = array('apiUsername' => 'a', 'apiKey' => 'b'); - $browser = new SauceLabsBrowserConfiguration( - $this->readAttribute($this, '_eventDispatcher'), - $this->createDriverFactoryRegistry(), - $factory + + $browser = m::mock( + 'aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration[getAPIClient]', + array($this->readAttribute($this, '_eventDispatcher'), $this->createDriverFactoryRegistry()) ); + + // These magic methods can't be properly passed through to mocked object otherwise. + $browser->shouldReceive('getSessionStrategy')->andReturn('isolated'); + $browser->shouldReceive('getDesiredCapabilities')->andReturn(array( + SauceLabsBrowserConfiguration::NAME_CAPABILITY => 'something', + )); + + $browser->shouldReceive('getAPIClient')->once()->andReturn($api_client); + $factory->shouldReceive('createBrowserConfiguration') ->with($browser_config, $this) ->once() From e46e9e770432f63763ffc270863ef7a4eb2aeae7 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sat, 1 Aug 2015 14:25:08 +0300 Subject: [PATCH 086/204] Don't collect code coverage on HHVM because it doesn't have xdebug --- .travis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ceefd56..497a095 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,9 +39,10 @@ before_script: - mkdir -p build/logs script: - - phpunit -v --coverage-clover build/logs/clover.xml + - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then phpunit --coverage-clover build/logs/clover.xml; fi; + - if [ "$TRAVIS_PHP_VERSION" = "hhvm" ]; then phpunit; fi; after_script: - - php vendor/bin/coveralls -v - - wget https://scrutinizer-ci.com/ocular.phar -t 3 - - php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml + - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php vendor/bin/coveralls -v; fi; + - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then wget https://scrutinizer-ci.com/ocular.phar -t 3; fi; + - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php ocular.phar code-coverage:upload --format=php-clover build/logs/clover.xml; fi; From 140d2c6314b4e912eaba523958f21241ae712f63 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Mon, 27 Jul 2015 19:40:55 +0300 Subject: [PATCH 087/204] Session sharing wasn't working, when non-shared sessions were present --- .../Session/IsolatedSessionStrategy.php | 16 ++++ .../PHPUnit/Session/SharedSessionStrategy.php | 16 ++++ .../PHPUnit/Fixture/SetupEventFixture.php | 4 +- .../PHPUnit/Integration/DataProviderTest.php | 52 +------------ .../IsolatedSessionStrategyTest.php | 48 ++++++++++++ .../Integration/SauceLabsAwareTestCase.php | 76 +++++++++++++++++++ .../Integration/SharedSessionStrategyTest.php | 48 ++++++++++++ .../Session/IsolatedSessionStrategyTest.php | 5 +- .../Session/SharedSessionStrategyTest.php | 5 +- 9 files changed, 215 insertions(+), 55 deletions(-) create mode 100644 tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php create mode 100644 tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php create mode 100644 tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php diff --git a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php index f6d2c8c..fe01a1e 100644 --- a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php @@ -90,6 +90,10 @@ public function session(BrowserConfiguration $browser) */ public function onTestEnd(TestEvent $event) { + if ( !$this->_isEventForMe($event) ) { + return; + } + $session = $event->getSession(); if ( $session !== null && $session->isStarted() ) { @@ -97,4 +101,16 @@ public function onTestEnd(TestEvent $event) } } + /** + * Checks, that event can be handled by this class. + * + * @param TestEvent $event Test event. + * + * @return boolean + */ + private function _isEventForMe(TestEvent $event) + { + return $event->getTestCase()->getSessionStrategy() instanceof self; + } + } diff --git a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php index cc4ebdb..eba95ba 100644 --- a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -159,6 +159,10 @@ public function onTestFailed(TestFailedEvent $event) */ public function onTestSuiteEnd(TestEvent $event) { + if ( !$this->_isEventForMe($event) ) { + return; + } + $session = $event->getSession(); if ( $session !== null && $session->isStarted() ) { @@ -166,4 +170,16 @@ public function onTestSuiteEnd(TestEvent $event) } } + /** + * Checks, that event can be handled by this class. + * + * @param TestEvent $event Test event. + * + * @return boolean + */ + private function _isEventForMe(TestEvent $event) + { + return $event->getTestCase()->getSessionStrategy() instanceof self; + } + } diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index a0d8c5c..23c8699 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -96,8 +96,8 @@ public function testEvents() $session->shouldReceive('getDriver')->once()->andReturn($driver); // For IsolatedSessionStrategy::onTestEnd (twice per each browser because - // we have 2 strategies listening for test end). - $session->shouldReceive('stop')->times(4); + // we have 2 strategies listening for test end + IsolatedSessionStrategyTest with 2 tests). + $session->shouldReceive('stop')->times(6); $session->shouldReceive('isStarted')->andReturn(true); $this->_setSession($session); diff --git a/tests/aik099/PHPUnit/Integration/DataProviderTest.php b/tests/aik099/PHPUnit/Integration/DataProviderTest.php index f934b2c..ae24a49 100644 --- a/tests/aik099/PHPUnit/Integration/DataProviderTest.php +++ b/tests/aik099/PHPUnit/Integration/DataProviderTest.php @@ -11,22 +11,9 @@ namespace tests\aik099\PHPUnit\Integration; -use aik099\PHPUnit\BrowserTestCase; -use Mockery as m; - -class DataProviderTest extends BrowserTestCase +class DataProviderTest extends SauceLabsAwareTestCase { - /** - * Browser list to be used in tests. - * - * @var array - */ - public static $browsers = array( - array('alias' => 'saucelabs'), - // array('alias' => 'browserstack'), - ); - public function sampleDataProvider() { return array( @@ -50,46 +37,9 @@ public function testDataProvider($case) } } - /** - * Whatever or not code coverage information should be gathered. - * - * @return boolean - * @throws \RuntimeException When used before test is started. - */ - public function getCollectCodeCoverageInformation() - { - // FIXME: Workaround for https://github.com/minkphp/phpunit-mink/issues/35 bug. - return false; - } - protected function customMethod() { return 5; } - /** - * Gets browser configuration aliases. - * - * Allows to decouple actual test server connection details from test cases. - * - * @return array - */ - public function getBrowserAliases() - { - return array( - 'saucelabs' => array( - 'type' => 'saucelabs', - 'apiUsername' => getenv('SAUCE_USERNAME'), - 'apiKey' => getenv('SAUCE_ACCESS_KEY'), - - 'browserName' => 'chrome', - 'desiredCapabilities' => array('version' => 28), - 'baseUrl' => 'http://www.google.com', - ), - /*'browserstack' => array( - 'type' => 'browserstack', - ),*/ - ); - } - } diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php new file mode 100644 index 0000000..7dee4d7 --- /dev/null +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -0,0 +1,48 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Integration; + + +class IsolatedSessionStrategyTest extends SauceLabsAwareTestCase +{ + + /** + * Browser list to be used in tests. + * + * @var array + */ + public static $browsers = array( + array( + 'alias' => 'saucelabs', + 'sessionStrategy' => 'isolated', + ), + ); + + public function testOne() + { + $session = $this->getSession(); + $session->visit('https://www.google.com'); + + $this->assertTrue(true); + } + + /** + * @depends testOne + */ + public function testTwo() + { + $session = $this->getSession(); + $url = $session->getCurrentUrl(); + + $this->assertNotContains('https://www.google.com', $url); + } + +} diff --git a/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php b/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php new file mode 100644 index 0000000..f46a054 --- /dev/null +++ b/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php @@ -0,0 +1,76 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Integration; + + +use aik099\PHPUnit\BrowserTestCase; + +abstract class SauceLabsAwareTestCase extends BrowserTestCase +{ + + /** + * Browser list to be used in tests. + * + * @var array + */ + public static $browsers = array( + array('alias' => 'saucelabs'), + ); + + /** + * Set session meta-info for "Sauce Labs". + * + * @return void + */ + protected function setUp() + { + if ( !getenv('SAUCE_USERNAME') || !getenv('SAUCE_ACCESS_KEY') ) { + $this->markTestSkipped('SauceLabs integration is not configured'); + } + + parent::setUp(); + } + + /** + * Whatever or not code coverage information should be gathered. + * + * @return boolean + * @throws \RuntimeException When used before test is started. + */ + public function getCollectCodeCoverageInformation() + { + // FIXME: Workaround for https://github.com/minkphp/phpunit-mink/issues/35 bug. + return false; + } + + /** + * Gets browser configuration aliases. + * + * Allows to decouple actual test server connection details from test cases. + * + * @return array + */ + public function getBrowserAliases() + { + return array( + 'saucelabs' => array( + 'type' => 'saucelabs', + 'apiUsername' => getenv('SAUCE_USERNAME'), + 'apiKey' => getenv('SAUCE_ACCESS_KEY'), + + 'browserName' => 'chrome', + 'desiredCapabilities' => array('version' => 28), + 'baseUrl' => 'http://www.google.com', + ), + ); + } + +} diff --git a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php new file mode 100644 index 0000000..bd46b29 --- /dev/null +++ b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php @@ -0,0 +1,48 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\Integration; + + +class SharedSessionStrategyTest extends SauceLabsAwareTestCase +{ + + /** + * Browser list to be used in tests. + * + * @var array + */ + public static $browsers = array( + array( + 'alias' => 'saucelabs', + 'sessionStrategy' => 'shared', + ), + ); + + public function testOne() + { + $session = $this->getSession(); + $session->visit('https://www.google.com'); + + $this->assertTrue(true); + } + + /** + * @depends testOne + */ + public function testTwo() + { + $session = $this->getSession(); + $url = $session->getCurrentUrl(); + + $this->assertContains('https://www.google.com', $url); + } + +} diff --git a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php index df746b4..df52eb3 100644 --- a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php @@ -77,10 +77,13 @@ public function testOnTestEnd() $session->shouldReceive('stop')->once(); $session->shouldReceive('isStarted')->once()->andReturn(true); + $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('getSessionStrategy')->once()->andReturn($this->strategy); + $event = $this->eventDispatcher->dispatch( BrowserTestCase::TEST_ENDED_EVENT, new TestEndedEvent( - m::mock(self::TEST_CASE_CLASS), + $test_case, m::mock('PHPUnit_Framework_TestResult'), $session ) diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index ddae231..a81cb26 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -169,9 +169,12 @@ public function testEndOfTestCaseWithSession() $session->shouldReceive('stop')->withNoArgs()->once(); $session->shouldReceive('isStarted')->once()->andReturn(true); + $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('getSessionStrategy')->once()->andReturn($this->strategy); + $event = $this->eventDispatcher->dispatch( BrowserTestCase::TEST_SUITE_ENDED_EVENT, - new TestEvent(m::mock(self::TEST_CASE_CLASS), $session) + new TestEvent($test_case, $session) ); $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEvent', $event); From d783f8407853b51bf359660886c2c0b1602ba51f Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Mon, 31 Aug 2015 12:16:25 +0200 Subject: [PATCH 088/204] Cache only the composer downloads on Travis This avoids invalidating the cache for all builds because of the update of Packagist metadata --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 497a095..5dbb9d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ sudo: false cache: directories: - - $HOME/.composer/cache + - $HOME/.composer/cache/files php: - 5.3 From f0b12aa439866f3fe7f3d84550d228fdb24a4cdc Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 18 Oct 2015 21:07:42 +0300 Subject: [PATCH 089/204] Start session only, when page is visited --- library/aik099/PHPUnit/BrowserTestCase.php | 2 +- .../Session/IsolatedSessionStrategy.php | 5 +-- .../aik099/PHPUnit/Session/SessionFactory.php | 2 +- .../aik099/PHPUnit/Session/SessionProxy.php | 35 +++++++++++++++++++ tests/aik099/PHPUnit/BrowserTestCaseTest.php | 11 ++---- .../IsolatedSessionStrategyTest.php | 2 +- .../Session/IsolatedSessionStrategyTest.php | 3 -- 7 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 library/aik099/PHPUnit/Session/SessionProxy.php diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 2c77393..ffa0c8e 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -279,7 +279,7 @@ public function getSessionStrategy() */ public function getSession() { - if ( $this->_session && $this->_session->isStarted() ) { + if ( $this->_session ) { return $this->_session; } diff --git a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php index fe01a1e..43701eb 100644 --- a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php @@ -75,10 +75,7 @@ public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) */ public function session(BrowserConfiguration $browser) { - $session = $this->_sessionFactory->createSession($browser); - $session->start(); - - return $session; + return $this->_sessionFactory->createSession($browser); } /** diff --git a/library/aik099/PHPUnit/Session/SessionFactory.php b/library/aik099/PHPUnit/Session/SessionFactory.php index 80a6e1e..5a6c064 100644 --- a/library/aik099/PHPUnit/Session/SessionFactory.php +++ b/library/aik099/PHPUnit/Session/SessionFactory.php @@ -31,7 +31,7 @@ class SessionFactory implements ISessionFactory */ public function createSession(BrowserConfiguration $browser) { - return new Session($browser->createDriver()); + return new SessionProxy($browser->createDriver()); } } diff --git a/library/aik099/PHPUnit/Session/SessionProxy.php b/library/aik099/PHPUnit/Session/SessionProxy.php new file mode 100644 index 0000000..e6c0e57 --- /dev/null +++ b/library/aik099/PHPUnit/Session/SessionProxy.php @@ -0,0 +1,35 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\Session; + + +use Behat\Mink\Session; + +class SessionProxy extends Session +{ + + /** + * Visit specified URL. + * + * @param string $url Url of the page. + * + * @return void + */ + public function visit($url) + { + if ( !$this->isStarted() ) { + $this->start(); + } + + parent::visit($url); + } + +} diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 63e0f22..beb0dad 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -194,10 +194,7 @@ public function testGetSession() $browser = $this->getBrowser(0); $expected_session1 = m::mock('\\Behat\\Mink\\Session'); - $expected_session1->shouldReceive('isStarted')->withNoArgs()->once()->andReturn(false); - $expected_session2 = m::mock('\\Behat\\Mink\\Session'); - $expected_session2->shouldReceive('isStarted')->withNoArgs()->once()->andReturn(true); /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); @@ -211,13 +208,9 @@ public function testGetSession() $session1 = $test_case->getSession(); $this->assertSame($expected_session1, $session1); - // Create session when present, but stopped. + // Always reuse created session. $session2 = $test_case->getSession(); - $this->assertSame($expected_session2, $session2); - - // Reuse created session, when started. - $session3 = $test_case->getSession(); - $this->assertSame($session2, $session3); + $this->assertSame($session1, $session2); } /** diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index 7dee4d7..11e64e9 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -40,7 +40,7 @@ public function testOne() public function testTwo() { $session = $this->getSession(); - $url = $session->getCurrentUrl(); + $url = $session->isStarted() ? $session->getCurrentUrl() : null; $this->assertNotContains('https://www.google.com', $url); } diff --git a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php index df52eb3..c768be7 100644 --- a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php @@ -51,10 +51,7 @@ public function testSession() $browser = m::mock(self::BROWSER_CLASS); $session1 = m::mock(self::SESSION_CLASS); - $session1->shouldReceive('start')->once(); - $session2 = m::mock(self::SESSION_CLASS); - $session2->shouldReceive('start')->once(); $this->_factory ->shouldReceive('createSession') From 98d49b3a4b99f74875d0a4e72f5137f54e3f5330 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 18 Oct 2015 21:07:59 +0300 Subject: [PATCH 090/204] Mark long tests to please php-invoker --- .../PHPUnit/Integration/IsolatedSessionStrategyTest.php | 4 ++++ .../aik099/PHPUnit/Integration/SharedSessionStrategyTest.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index 11e64e9..5a1ee18 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -26,6 +26,9 @@ class IsolatedSessionStrategyTest extends SauceLabsAwareTestCase ), ); + /** + * @medium + */ public function testOne() { $session = $this->getSession(); @@ -35,6 +38,7 @@ public function testOne() } /** + * @medium * @depends testOne */ public function testTwo() diff --git a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php index bd46b29..be3054d 100644 --- a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php @@ -26,6 +26,9 @@ class SharedSessionStrategyTest extends SauceLabsAwareTestCase ), ); + /** + * @medium + */ public function testOne() { $session = $this->getSession(); @@ -35,6 +38,7 @@ public function testOne() } /** + * @medium * @depends testOne */ public function testTwo() From 540b918da21e3296ca2caa52df6a15ef6fb87b82 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 18 Oct 2015 21:35:03 +0300 Subject: [PATCH 091/204] Use BrowserStack instead of SauceLabs for integration tests (because it's faster) --- ...tCase.php => BrowserStackAwareTestCase.php} | 18 +++++++++--------- .../PHPUnit/Integration/DataProviderTest.php | 2 +- .../IsolatedSessionStrategyTest.php | 4 ++-- .../Integration/SharedSessionStrategyTest.php | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) rename tests/aik099/PHPUnit/Integration/{SauceLabsAwareTestCase.php => BrowserStackAwareTestCase.php} (72%) diff --git a/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php similarity index 72% rename from tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php rename to tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php index f46a054..b163582 100644 --- a/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php +++ b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php @@ -13,7 +13,7 @@ use aik099\PHPUnit\BrowserTestCase; -abstract class SauceLabsAwareTestCase extends BrowserTestCase +abstract class BrowserStackAwareTestCase extends BrowserTestCase { /** @@ -22,7 +22,7 @@ abstract class SauceLabsAwareTestCase extends BrowserTestCase * @var array */ public static $browsers = array( - array('alias' => 'saucelabs'), + array('alias' => 'browserstack'), ); /** @@ -32,8 +32,8 @@ abstract class SauceLabsAwareTestCase extends BrowserTestCase */ protected function setUp() { - if ( !getenv('SAUCE_USERNAME') || !getenv('SAUCE_ACCESS_KEY') ) { - $this->markTestSkipped('SauceLabs integration is not configured'); + if ( !getenv('BS_USERNAME') || !getenv('BS_ACCESS_KEY') ) { + $this->markTestSkipped('BrowserStack integration is not configured'); } parent::setUp(); @@ -61,13 +61,13 @@ public function getCollectCodeCoverageInformation() public function getBrowserAliases() { return array( - 'saucelabs' => array( - 'type' => 'saucelabs', - 'apiUsername' => getenv('SAUCE_USERNAME'), - 'apiKey' => getenv('SAUCE_ACCESS_KEY'), + 'browserstack' => array( + 'type' => 'browserstack', + 'api_username' => getenv('BS_USERNAME'), + 'api_key' => getenv('BS_ACCESS_KEY'), 'browserName' => 'chrome', - 'desiredCapabilities' => array('version' => 28), + 'desiredCapabilities' => array('browser_version' => '38.0', 'project' => 'PHPUnit-Mink'), 'baseUrl' => 'http://www.google.com', ), ); diff --git a/tests/aik099/PHPUnit/Integration/DataProviderTest.php b/tests/aik099/PHPUnit/Integration/DataProviderTest.php index ae24a49..cd2615e 100644 --- a/tests/aik099/PHPUnit/Integration/DataProviderTest.php +++ b/tests/aik099/PHPUnit/Integration/DataProviderTest.php @@ -11,7 +11,7 @@ namespace tests\aik099\PHPUnit\Integration; -class DataProviderTest extends SauceLabsAwareTestCase +class DataProviderTest extends BrowserStackAwareTestCase { public function sampleDataProvider() diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index 5a1ee18..c795c4c 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -11,7 +11,7 @@ namespace tests\aik099\PHPUnit\Integration; -class IsolatedSessionStrategyTest extends SauceLabsAwareTestCase +class IsolatedSessionStrategyTest extends BrowserStackAwareTestCase { /** @@ -21,7 +21,7 @@ class IsolatedSessionStrategyTest extends SauceLabsAwareTestCase */ public static $browsers = array( array( - 'alias' => 'saucelabs', + 'alias' => 'browserstack', 'sessionStrategy' => 'isolated', ), ); diff --git a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php index be3054d..b0621dc 100644 --- a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php @@ -11,7 +11,7 @@ namespace tests\aik099\PHPUnit\Integration; -class SharedSessionStrategyTest extends SauceLabsAwareTestCase +class SharedSessionStrategyTest extends BrowserStackAwareTestCase { /** @@ -21,7 +21,7 @@ class SharedSessionStrategyTest extends SauceLabsAwareTestCase */ public static $browsers = array( array( - 'alias' => 'saucelabs', + 'alias' => 'browserstack', 'sessionStrategy' => 'shared', ), ); From 7f7aed5c1b9a85e0c67e546362fe11e501ff13cf Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 18 Oct 2015 21:42:09 +0300 Subject: [PATCH 092/204] Fix wrong branch-alias in composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ce048ec..7c06c1a 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "2.1.x-dev" } } } From 283ae44cdf0a90094b714b72ec4fc12e8a3ec917 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Sun, 18 Oct 2015 22:03:20 +0300 Subject: [PATCH 093/204] The "assertNotContains" doesn't like "null" --- .../aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index c795c4c..ea62bc3 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -44,7 +44,7 @@ public function testOne() public function testTwo() { $session = $this->getSession(); - $url = $session->isStarted() ? $session->getCurrentUrl() : null; + $url = $session->isStarted() ? $session->getCurrentUrl() : ''; $this->assertNotContains('https://www.google.com', $url); } From c401d2c639d08b3c0d75db7ee97b50ecfd88363c Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 20 Oct 2015 16:41:23 +0300 Subject: [PATCH 094/204] Use Firefox in tests, because due ChromeDriver bug switching to main window is impossible --- .../PHPUnit/Integration/BrowserStackAwareTestCase.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php index b163582..2842183 100644 --- a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php +++ b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php @@ -65,9 +65,13 @@ public function getBrowserAliases() 'type' => 'browserstack', 'api_username' => getenv('BS_USERNAME'), 'api_key' => getenv('BS_ACCESS_KEY'), - - 'browserName' => 'chrome', - 'desiredCapabilities' => array('browser_version' => '38.0', 'project' => 'PHPUnit-Mink'), + 'browserName' => 'Firefox', + 'desiredCapabilities' => array( + 'browser_version' => '41.0', + 'os' => 'Windows', + 'os_version' => '7', + 'project' => 'PHPUnit-Mink', + ), 'baseUrl' => 'http://www.google.com', ), ); From 829911fcd11997568bba97b2caf34d2105b42627 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 20 Oct 2015 17:39:38 +0300 Subject: [PATCH 095/204] Revert "Use BrowserStack instead of SauceLabs for integration tests" --- .../PHPUnit/Integration/DataProviderTest.php | 2 +- .../IsolatedSessionStrategyTest.php | 6 ++--- ...estCase.php => SauceLabsAwareTestCase.php} | 26 ++++++++----------- .../Integration/SharedSessionStrategyTest.php | 4 +-- 4 files changed, 17 insertions(+), 21 deletions(-) rename tests/aik099/PHPUnit/Integration/{BrowserStackAwareTestCase.php => SauceLabsAwareTestCase.php} (68%) diff --git a/tests/aik099/PHPUnit/Integration/DataProviderTest.php b/tests/aik099/PHPUnit/Integration/DataProviderTest.php index cd2615e..ae24a49 100644 --- a/tests/aik099/PHPUnit/Integration/DataProviderTest.php +++ b/tests/aik099/PHPUnit/Integration/DataProviderTest.php @@ -11,7 +11,7 @@ namespace tests\aik099\PHPUnit\Integration; -class DataProviderTest extends BrowserStackAwareTestCase +class DataProviderTest extends SauceLabsAwareTestCase { public function sampleDataProvider() diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index ea62bc3..5a1ee18 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -11,7 +11,7 @@ namespace tests\aik099\PHPUnit\Integration; -class IsolatedSessionStrategyTest extends BrowserStackAwareTestCase +class IsolatedSessionStrategyTest extends SauceLabsAwareTestCase { /** @@ -21,7 +21,7 @@ class IsolatedSessionStrategyTest extends BrowserStackAwareTestCase */ public static $browsers = array( array( - 'alias' => 'browserstack', + 'alias' => 'saucelabs', 'sessionStrategy' => 'isolated', ), ); @@ -44,7 +44,7 @@ public function testOne() public function testTwo() { $session = $this->getSession(); - $url = $session->isStarted() ? $session->getCurrentUrl() : ''; + $url = $session->isStarted() ? $session->getCurrentUrl() : null; $this->assertNotContains('https://www.google.com', $url); } diff --git a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php b/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php similarity index 68% rename from tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php rename to tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php index 2842183..f46a054 100644 --- a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php +++ b/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php @@ -13,7 +13,7 @@ use aik099\PHPUnit\BrowserTestCase; -abstract class BrowserStackAwareTestCase extends BrowserTestCase +abstract class SauceLabsAwareTestCase extends BrowserTestCase { /** @@ -22,7 +22,7 @@ abstract class BrowserStackAwareTestCase extends BrowserTestCase * @var array */ public static $browsers = array( - array('alias' => 'browserstack'), + array('alias' => 'saucelabs'), ); /** @@ -32,8 +32,8 @@ abstract class BrowserStackAwareTestCase extends BrowserTestCase */ protected function setUp() { - if ( !getenv('BS_USERNAME') || !getenv('BS_ACCESS_KEY') ) { - $this->markTestSkipped('BrowserStack integration is not configured'); + if ( !getenv('SAUCE_USERNAME') || !getenv('SAUCE_ACCESS_KEY') ) { + $this->markTestSkipped('SauceLabs integration is not configured'); } parent::setUp(); @@ -61,17 +61,13 @@ public function getCollectCodeCoverageInformation() public function getBrowserAliases() { return array( - 'browserstack' => array( - 'type' => 'browserstack', - 'api_username' => getenv('BS_USERNAME'), - 'api_key' => getenv('BS_ACCESS_KEY'), - 'browserName' => 'Firefox', - 'desiredCapabilities' => array( - 'browser_version' => '41.0', - 'os' => 'Windows', - 'os_version' => '7', - 'project' => 'PHPUnit-Mink', - ), + 'saucelabs' => array( + 'type' => 'saucelabs', + 'apiUsername' => getenv('SAUCE_USERNAME'), + 'apiKey' => getenv('SAUCE_ACCESS_KEY'), + + 'browserName' => 'chrome', + 'desiredCapabilities' => array('version' => 28), 'baseUrl' => 'http://www.google.com', ), ); diff --git a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php index b0621dc..be3054d 100644 --- a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php @@ -11,7 +11,7 @@ namespace tests\aik099\PHPUnit\Integration; -class SharedSessionStrategyTest extends BrowserStackAwareTestCase +class SharedSessionStrategyTest extends SauceLabsAwareTestCase { /** @@ -21,7 +21,7 @@ class SharedSessionStrategyTest extends BrowserStackAwareTestCase */ public static $browsers = array( array( - 'alias' => 'browserstack', + 'alias' => 'saucelabs', 'sessionStrategy' => 'shared', ), ); From e0a8989c50b6750cd9123eadf49dfb5f96d4f25e Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 20 Oct 2015 17:43:33 +0300 Subject: [PATCH 096/204] Don't check how long test runs --- phpunit.xml.dist | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3fdccbf..b3fbb5f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,15 +1,10 @@ - + verbose="true" + beStrictAboutChangesToGlobalState="true" + beStrictAboutOutputDuringTests="true"> From b496627df4f232646630bc097910e80f3570b26b Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 20 Oct 2015 17:56:05 +0300 Subject: [PATCH 097/204] Return timeout checking, but allow for longer execution time (1 minute) --- phpunit.xml.dist | 3 ++- .../PHPUnit/Integration/IsolatedSessionStrategyTest.php | 4 ++-- .../aik099/PHPUnit/Integration/SharedSessionStrategyTest.php | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index b3fbb5f..fa6afdd 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -4,7 +4,8 @@ colors="true" verbose="true" beStrictAboutChangesToGlobalState="true" - beStrictAboutOutputDuringTests="true"> + beStrictAboutOutputDuringTests="true" + beStrictAboutTestSize="true"> diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index 5a1ee18..f190f69 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -27,7 +27,7 @@ class IsolatedSessionStrategyTest extends SauceLabsAwareTestCase ); /** - * @medium + * @large */ public function testOne() { @@ -38,7 +38,7 @@ public function testOne() } /** - * @medium + * @large * @depends testOne */ public function testTwo() diff --git a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php index be3054d..26fffc5 100644 --- a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php @@ -27,7 +27,7 @@ class SharedSessionStrategyTest extends SauceLabsAwareTestCase ); /** - * @medium + * @large */ public function testOne() { @@ -38,7 +38,7 @@ public function testOne() } /** - * @medium + * @large * @depends testOne */ public function testTwo() From 46ad4442b5a09b09b69125da59d1fbe47f189c55 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 20 Oct 2015 18:12:34 +0300 Subject: [PATCH 098/204] The "assertNotContains" doesn't like nulls --- .../aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index f190f69..b2fd562 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -44,7 +44,7 @@ public function testOne() public function testTwo() { $session = $this->getSession(); - $url = $session->isStarted() ? $session->getCurrentUrl() : null; + $url = $session->isStarted() ? $session->getCurrentUrl() : ''; $this->assertNotContains('https://www.google.com', $url); } From b74a495f46909c563b3b2bac1b8d4027a54f06ba Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 11 Nov 2015 21:14:42 +0200 Subject: [PATCH 099/204] Fixes suite building test on PHPUnit 4.6+ --- tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php index 2b344dd..2a570b4 100644 --- a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php @@ -98,6 +98,7 @@ protected function createTestSuite($class_name) $suite = m::mock($class_name); $suite->shouldReceive('getGroups')->once()->andReturn(array()); + $suite->shouldReceive('setDisallowChangesToGlobalState'); // Since PHPUnit 4.6.0. $suite->shouldReceive('setBackupGlobals'); $suite->shouldReceive('setBackupStaticAttributes'); $suite->shouldReceive('setRunTestInSeparateProcess'); From b9f83d6361de6082899ecd4fe52c88089770bd53 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Thu, 7 Jan 2016 10:33:03 +0200 Subject: [PATCH 100/204] Use stable version of coverage reporting library during the build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5dbb9d8..96e824c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ env: - secure: HQQ1FY27tpn0Idy+NDYXdbnMjHKIOsZoE59qYfs18euS0zM559gcuMk4OQ/J2lcDFmdb6vjSFlznwH+6iVyoLuC5WAP3JGQ3UXSJ+7huRV/eDI6WepmEymjEOSWvTT+RYpmQu1lQWC2Y3zBCVbVT7sbVsqXvmuR2daBL11dpU+g= install: - - composer require satooshi/php-coveralls:dev-master --dev + - composer require satooshi/php-coveralls:^1.0 --dev before_script: - mkdir -p build/logs From 261295a2e7a27f9f7feb53549489c13c2090636b Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Tue, 12 Jan 2016 21:38:07 +0200 Subject: [PATCH 101/204] Avoid test, that run test suite themselves to be marked as risky --- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 13 +++++++++++++ .../PHPUnit/Integration/ApiIntegrationTest.php | 12 ++++++++++++ .../PHPUnit/Integration/EventDispatchingTest.php | 12 ++++++++++++ 3 files changed, 37 insertions(+) diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index beb0dad..8b6da14 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -49,6 +49,11 @@ protected function setUp() { parent::setUp(); + // Define the constant because this test is running PHPUnit testcases manually. + if ( $this->isInIsolation() ) { + define('PHPUNIT_TESTSUITE', true); + } + $this->browserConfigurationFactory = m::mock( 'aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory' ); @@ -270,6 +275,8 @@ public function testGetCollectCodeCoverageInformationSuccess() * Test description. * * @return void + * @large + * @runInSeparateProcess */ public function testRun() { @@ -284,6 +291,8 @@ public function testRun() * Test description. * * @return void + * @large + * @runInSeparateProcess */ public function testRunCreateResult() { @@ -297,6 +306,8 @@ public function testRunCreateResult() * Test description. * * @return void + * @large + * @runInSeparateProcess */ public function testRunWithCoverageWithoutRemoteUrl() { @@ -333,6 +344,8 @@ public function testRunWithCoverageWithoutRemoteUrl() * Test description. * * @return void + * @large + * @runInSeparateProcess */ public function testRunWithCoverage() { diff --git a/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php b/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php index 7203f71..f5214dc 100644 --- a/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php +++ b/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php @@ -17,10 +17,22 @@ class ApiIntegrationTest extends \PHPUnit_Framework_TestCase { + protected function setUp() + { + parent::setUp(); + + // Define the constant because this test is running PHPUnit testcases manually. + if ( $this->isInIsolation() ) { + define('PHPUNIT_TESTSUITE', true); + } + } + /** * Test description. * * @return void + * @large + * @runInSeparateProcess */ public function testAPICalls() { diff --git a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php index b55869e..6047ffa 100644 --- a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php +++ b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php @@ -17,10 +17,22 @@ class EventDispatchingTest extends \PHPUnit_Framework_TestCase { + protected function setUp() + { + parent::setUp(); + + // Define the constant because this test is running PHPUnit testcases manually. + if ( $this->isInIsolation() ) { + define('PHPUNIT_TESTSUITE', true); + } + } + /** * Test description. * * @return void + * @large + * @runInSeparateProcess */ public function testSetupEvent() { From dc95ae9fc782c8ce5fb70c2ff91beecd9930dd6b Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Fri, 26 Feb 2016 15:53:42 +0100 Subject: [PATCH 102/204] Add testing on PHP 7 --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 96e824c..4161ec6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,11 +11,13 @@ php: - 5.4 - 5.5 - 5.6 + - 7.0 - hhvm matrix: include: - env: BUILD_TYPE=doc # marker environment variable to make the build matrix more readable in the UI + php: none # unused by the python language but allows to clean the display of the matrix # Override the different steps of the build config language: python before_install: [] From fe2917888eeae9fb1b9ffeffdcca2a22f803b3fc Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Fri, 26 Feb 2016 16:06:08 +0100 Subject: [PATCH 103/204] Use a bound constraint for PHPUnit and allow Symfony 3 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 7c06c1a..9db4f30 100644 --- a/composer.json +++ b/composer.json @@ -16,9 +16,9 @@ "php": ">=5.3.2", "behat/mink": "~1.6@dev", "behat/mink-selenium2-driver": "~1.2", - "symfony/event-dispatcher": "~2.4", + "symfony/event-dispatcher": "~2.4|~3.0", "pimple/pimple": "~2.0|~3.0", - "phpunit/phpunit": ">=3.7.8" + "phpunit/phpunit": "~4|~5" }, "require-dev": { From 3ddd70647ea30df245c42a24558f0a2894a69b25 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Fri, 26 Feb 2016 23:50:40 +0200 Subject: [PATCH 104/204] CS fixes --- library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php | 2 +- library/aik099/PHPUnit/BrowserTestCase.php | 2 -- library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php | 1 + library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php | 1 + library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php | 1 + library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php | 1 + library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php | 1 + 7 files changed, 6 insertions(+), 3 deletions(-) diff --git a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php index 3abe7d5..9ba8c9f 100644 --- a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php @@ -100,7 +100,7 @@ protected function execute($request_method, $url, $parameters = null) $url = 'https://www.browserstack.com/automate/' . $url; - list($raw_results, ) = $this->_curlService->execute($request_method, $url, $parameters, $extra_options); + list($raw_results,) = $this->_curlService->execute($request_method, $url, $parameters, $extra_options); return json_decode($raw_results, true); } diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index ffa0c8e..ff1e30f 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -308,7 +308,6 @@ public function getSession() * @param \PHPUnit_Framework_TestResult $result Test result. * * @return \PHPUnit_Framework_TestResult - * @throws \PHPUnit_Framework_Exception When exception was thrown during a test. */ public function run(\PHPUnit_Framework_TestResult $result = null) { @@ -356,7 +355,6 @@ public function getCollectCodeCoverageInformation() * Override to tell remote website, that code coverage information needs to be collected. * * @return mixed - * @throws \Exception When exception was thrown inside the test. */ protected function runTest() { diff --git a/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php b/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php index dadb84d..d10117a 100644 --- a/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php +++ b/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php @@ -28,6 +28,7 @@ class DriverFactoryRegistry * @param IMinkDriverFactory $driver_factory Driver factory. * * @return void + * @throws \LogicException When driver factory is already registered. */ public function add(IMinkDriverFactory $driver_factory) { diff --git a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php index 5e3efac..f2453f6 100644 --- a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php @@ -49,6 +49,7 @@ public function getDriverDefaults() * @param BrowserConfiguration $browser The browser configuration. * * @return DriverInterface + * @throws \RuntimeException When driver isn't installed. */ public function createDriver(BrowserConfiguration $browser) { diff --git a/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php index 152bf5c..a0f2539 100644 --- a/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php @@ -51,6 +51,7 @@ public function getDriverDefaults() * @param BrowserConfiguration $browser The browser configuration. * * @return DriverInterface + * @throws \RuntimeException When driver isn't installed. */ public function createDriver(BrowserConfiguration $browser) { diff --git a/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php b/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php index 7de9072..02a184e 100644 --- a/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php @@ -47,6 +47,7 @@ public function getDriverDefaults() * @param BrowserConfiguration $browser The browser configuration. * * @return DriverInterface + * @throws \RuntimeException When driver isn't installed. */ public function createDriver(BrowserConfiguration $browser) { diff --git a/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php index dee21bc..10a00bf 100644 --- a/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php @@ -52,6 +52,7 @@ public function getDriverDefaults() * @param BrowserConfiguration $browser The browser configuration. * * @return DriverInterface + * @throws \RuntimeException When driver isn't installed. */ public function createDriver(BrowserConfiguration $browser) { From 108459acac38a5a7ce3e282c3cbc56d49a2d9ec2 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Tue, 1 Mar 2016 16:54:23 +0100 Subject: [PATCH 105/204] Allow failures on PHP 7 until PHPUnit 5 is supported --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4161ec6..cf4eb4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,8 @@ matrix: before_script: [] script: sphinx-build -nW -b html -d docs/build/doctrees docs docs/build/html after_script: [] + allow_failures: + - php: 7.0 env: global: From 30a89b85995de2b875fcb2b9ecaf1868fff90568 Mon Sep 17 00:00:00 2001 From: Yann Kechichian Date: Mon, 7 Mar 2016 22:57:04 +1100 Subject: [PATCH 106/204] Add compatibility with Guzzle 6. Fixes CS. --- .../MinkDriver/GoutteDriverFactory.php | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php index f2453f6..f512a8c 100644 --- a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php @@ -64,6 +64,9 @@ public function createDriver(BrowserConfiguration $browser) if ( $this->_isGoutte1() ) { $guzzle_client = $this->_buildGuzzle3Client($driver_options['guzzle_parameters']); } + elseif ( $this->_isGuzzle6() ) { + $guzzle_client = $this->_buildGuzzle6Client($driver_options['guzzle_parameters']); + } else { $guzzle_client = $this->_buildGuzzle4Client($driver_options['guzzle_parameters']); } @@ -74,6 +77,23 @@ public function createDriver(BrowserConfiguration $browser) return new \Behat\Mink\Driver\GoutteDriver($goutte_client); } + /** + * Builds Guzzle 6 client. + * + * @param array $parameters Parameters. + * + * @return \GuzzleHttp\Client + */ + private function _buildGuzzle6Client(array $parameters) + { + // Force the parameters set by default in Goutte to reproduce its behavior. + $parameters['allow_redirects'] = false; + $parameters['cookies'] = true; + + return new \GuzzleHttp\Client($parameters); + + } + /** * Builds Guzzle 4 client. * @@ -121,5 +141,16 @@ private function _isGoutte1() return false; } + + /** + * Determines Guzzle version. + * + * @return boolean + */ + private function _isGuzzle6() + { + return interface_exists('GuzzleHttp\ClientInterface') && + version_compare(\GuzzleHttp\ClientInterface::VERSION, '6.0.0', '>='); + } } From c0230d67a4f390ef9824bbdeb6e3fc94d02d2bd4 Mon Sep 17 00:00:00 2001 From: Alexander Obuhovich Date: Wed, 11 Nov 2015 21:34:18 +0200 Subject: [PATCH 107/204] Remove dependency on Pimple --- composer.json | 11 +- composer.lock | 520 +++++++++--------- library/PimpleCopy/Pimple/Container.php | 287 ++++++++++ .../Pimple/ServiceProviderInterface.php | 51 ++ library/aik099/PHPUnit/DIContainer.php | 2 +- phpunit.xml.dist | 4 + .../PimpleCopy/Pimple/Fixtures/Invokable.php | 41 ++ .../Pimple/Fixtures/NonInvokable.php | 37 ++ .../Pimple/Fixtures/PimpleServiceProvider.php | 59 ++ tests/PimpleCopy/Pimple/Fixtures/Service.php | 38 ++ .../PimpleServiceProviderInterfaceTest.php | 78 +++ tests/PimpleCopy/Pimple/PimpleTest.php | 448 +++++++++++++++ 12 files changed, 1312 insertions(+), 264 deletions(-) create mode 100644 library/PimpleCopy/Pimple/Container.php create mode 100644 library/PimpleCopy/Pimple/ServiceProviderInterface.php create mode 100644 tests/PimpleCopy/Pimple/Fixtures/Invokable.php create mode 100644 tests/PimpleCopy/Pimple/Fixtures/NonInvokable.php create mode 100644 tests/PimpleCopy/Pimple/Fixtures/PimpleServiceProvider.php create mode 100644 tests/PimpleCopy/Pimple/Fixtures/Service.php create mode 100644 tests/PimpleCopy/Pimple/PimpleServiceProviderInterfaceTest.php create mode 100644 tests/PimpleCopy/Pimple/PimpleTest.php diff --git a/composer.json b/composer.json index 9db4f30..2f766fc 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,6 @@ "behat/mink": "~1.6@dev", "behat/mink-selenium2-driver": "~1.2", "symfony/event-dispatcher": "~2.4|~3.0", - "pimple/pimple": "~2.0|~3.0", "phpunit/phpunit": "~4|~5" }, @@ -27,14 +26,16 @@ }, "autoload": { - "psr-0": { - "aik099\\": "./library/" + "psr-4": { + "aik099\\PHPUnit\\": "library/aik099/PHPUnit", + "PimpleCopy\\Pimple\\": "library/PimpleCopy/Pimple" } }, "autoload-dev": { - "psr-0": { - "tests\\aik099\\": "./" + "psr-4": { + "tests\\aik099\\PHPUnit\\": "tests/aik099/PHPUnit", + "tests\\PimpleCopy\\Pimple\\": "tests/PimpleCopy/Pimple" } }, diff --git a/composer.lock b/composer.lock index 07c5da3..d515936 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,11 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "961c9cfcd51f5d93088d7f57ab5a788b", + "hash": "911498094053187c90eedcf84edceaf7", + "content-hash": "657e476ce9cc45689f057e102efebca8", "packages": [ { "name": "behat/mink", @@ -12,17 +13,20 @@ "source": { "type": "git", "url": "https://github.com/minkphp/Mink.git", - "reference": "30014f0a15579176b7fca879cb461aad900f4db5" + "reference": "d2c32350b42a4d4713e107bcc3fb4a4bd525fdb3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/Mink/zipball/30014f0a15579176b7fca879cb461aad900f4db5", - "reference": "30014f0a15579176b7fca879cb461aad900f4db5", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/d2c32350b42a4d4713e107bcc3fb4a4bd525fdb3", + "reference": "d2c32350b42a4d4713e107bcc3fb4a4bd525fdb3", "shasum": "" }, "require": { "php": ">=5.3.1", - "symfony/css-selector": "~2.0" + "symfony/css-selector": "~2.1|~3.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7|~3.0" }, "suggest": { "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)", @@ -59,36 +63,39 @@ "testing", "web" ], - "time": "2015-02-21 12:27:56" + "time": "2016-03-05 08:33:20" }, { "name": "behat/mink-selenium2-driver", - "version": "v1.2.0", + "version": "v1.3.1", "source": { "type": "git", "url": "https://github.com/minkphp/MinkSelenium2Driver.git", - "reference": "8018fee80bf6573f909ece3e0dfc07d0eb352210" + "reference": "473a9f3ebe0c134ee1e623ce8a9c852832020288" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/8018fee80bf6573f909ece3e0dfc07d0eb352210", - "reference": "8018fee80bf6573f909ece3e0dfc07d0eb352210", + "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/473a9f3ebe0c134ee1e623ce8a9c852832020288", + "reference": "473a9f3ebe0c134ee1e623ce8a9c852832020288", "shasum": "" }, "require": { - "behat/mink": "~1.6@dev", + "behat/mink": "~1.7@dev", "instaclick/php-webdriver": "~1.1", "php": ">=5.3.1" }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, "type": "mink-driver", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.3.x-dev" } }, "autoload": { - "psr-0": { - "Behat\\Mink\\Driver": "src/" + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -117,20 +124,20 @@ "testing", "webdriver" ], - "time": "2014-09-29 13:12:12" + "time": "2016-03-05 09:10:18" }, { "name": "doctrine/instantiator", - "version": "1.0.4", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", - "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", "shasum": "" }, "require": { @@ -141,7 +148,7 @@ "ext-pdo": "*", "ext-phar": "*", "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "2.0.*@ALPHA" + "squizlabs/php_codesniffer": "~2.0" }, "type": "library", "extra": { @@ -150,8 +157,8 @@ } }, "autoload": { - "psr-0": { - "Doctrine\\Instantiator\\": "src" + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", @@ -171,20 +178,20 @@ "constructor", "instantiate" ], - "time": "2014-10-13 12:58:55" + "time": "2015-06-14 21:17:01" }, { "name": "instaclick/php-webdriver", - "version": "1.4.1", + "version": "1.4.3", "source": { "type": "git", "url": "https://github.com/instaclick/php-webdriver.git", - "reference": "a57b2bcd9467e217134a2248b261b8b3a90ccea0" + "reference": "0c20707dcf30a32728fd6bdeeab996c887fdb2fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/a57b2bcd9467e217134a2248b261b8b3a90ccea0", - "reference": "a57b2bcd9467e217134a2248b261b8b3a90ccea0", + "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/0c20707dcf30a32728fd6bdeeab996c887fdb2fb", + "reference": "0c20707dcf30a32728fd6bdeeab996c887fdb2fb", "shasum": "" }, "require": { @@ -229,7 +236,7 @@ "webdriver", "webtest" ], - "time": "2014-05-12 21:03:05" + "time": "2015-06-15 20:19:33" }, { "name": "phpdocumentor/reflection-docblock", @@ -282,21 +289,24 @@ }, { "name": "phpspec/prophecy", - "version": "v1.3.1", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9" + "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9", - "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972", + "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972", "shasum": "" }, "require": { - "doctrine/instantiator": "~1.0,>=1.0.2", - "phpdocumentor/reflection-docblock": "~2.0" + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "~2.0", + "sebastian/comparator": "~1.1", + "sebastian/recursion-context": "~1.0" }, "require-dev": { "phpspec/phpspec": "~2.0" @@ -304,7 +314,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.5.x-dev" } }, "autoload": { @@ -328,7 +338,7 @@ } ], "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "http://phpspec.org", + "homepage": "https://github.com/phpspec/prophecy", "keywords": [ "Double", "Dummy", @@ -337,20 +347,20 @@ "spy", "stub" ], - "time": "2014-11-17 16:23:49" + "time": "2016-02-15 07:46:21" }, { "name": "phpunit/php-code-coverage", - "version": "2.0.15", + "version": "2.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "34cc484af1ca149188d0d9e91412191e398e0b67" + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67", - "reference": "34cc484af1ca149188d0d9e91412191e398e0b67", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", "shasum": "" }, "require": { @@ -358,7 +368,7 @@ "phpunit/php-file-iterator": "~1.3", "phpunit/php-text-template": "~1.2", "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "~1.0", + "sebastian/environment": "^1.3.2", "sebastian/version": "~1.0" }, "require-dev": { @@ -373,7 +383,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "2.2.x-dev" } }, "autoload": { @@ -399,35 +409,37 @@ "testing", "xunit" ], - "time": "2015-01-24 10:06:35" + "time": "2015-10-06 15:47:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.3.4", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", "shasum": "" }, "require": { "php": ">=5.3.3" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, "autoload": { "classmap": [ - "File/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -444,20 +456,20 @@ "filesystem", "iterator" ], - "time": "2013-10-10 15:34:57" + "time": "2015-06-21 13:08:43" }, { "name": "phpunit/php-text-template", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "shasum": "" }, "require": { @@ -466,20 +478,17 @@ "type": "library", "autoload": { "classmap": [ - "Text/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -488,20 +497,20 @@ "keywords": [ "template" ], - "time": "2014-01-30 17:20:04" + "time": "2015-06-21 13:50:34" }, { "name": "phpunit/php-timer", - "version": "1.0.5", + "version": "1.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", "shasum": "" }, "require": { @@ -510,13 +519,10 @@ "type": "library", "autoload": { "classmap": [ - "PHP/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -532,20 +538,20 @@ "keywords": [ "timer" ], - "time": "2013-08-02 07:42:54" + "time": "2015-06-21 08:01:12" }, { "name": "phpunit/php-token-stream", - "version": "1.4.0", + "version": "1.4.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74" + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74", - "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", "shasum": "" }, "require": { @@ -581,20 +587,20 @@ "keywords": [ "tokenizer" ], - "time": "2015-01-17 09:51:32" + "time": "2015-09-15 10:49:45" }, { "name": "phpunit/phpunit", - "version": "4.5.0", + "version": "4.8.23", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5" + "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5b578d3865a9128b9c209b011fda6539ec06e7a5", - "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6e351261f9cd33daf205a131a1ba61c6d33bd483", + "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483", "shasum": "" }, "require": { @@ -604,19 +610,19 @@ "ext-reflection": "*", "ext-spl": "*", "php": ">=5.3.3", - "phpspec/prophecy": "~1.3.1", - "phpunit/php-code-coverage": "~2.0", - "phpunit/php-file-iterator": "~1.3.2", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "~1.0.2", + "phpunit/php-timer": ">=1.0.6", "phpunit/phpunit-mock-objects": "~2.3", "sebastian/comparator": "~1.1", - "sebastian/diff": "~1.1", - "sebastian/environment": "~1.2", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", "sebastian/exporter": "~1.2", "sebastian/global-state": "~1.0", "sebastian/version": "~1.0", - "symfony/yaml": "~2.0" + "symfony/yaml": "~2.1|~3.0" }, "suggest": { "phpunit/php-invoker": "~1.1" @@ -627,7 +633,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.5.x-dev" + "dev-master": "4.8.x-dev" } }, "autoload": { @@ -653,29 +659,30 @@ "testing", "xunit" ], - "time": "2015-02-05 15:51:19" + "time": "2016-02-11 14:56:33" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.0", + "version": "2.3.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "c63d2367247365f688544f0d500af90a11a44c65" + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65", - "reference": "c63d2367247365f688544f0d500af90a11a44c65", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", "shasum": "" }, "require": { - "doctrine/instantiator": "~1.0,>=1.0.1", + "doctrine/instantiator": "^1.0.2", "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2" + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" }, "require-dev": { - "phpunit/phpunit": "~4.3" + "phpunit/phpunit": "~4.4" }, "suggest": { "ext-soap": "*" @@ -708,66 +715,20 @@ "mock", "xunit" ], - "time": "2014-10-03 05:12:11" - }, - { - "name": "pimple/pimple", - "version": "v3.0.0", - "source": { - "type": "git", - "url": "https://github.com/silexphp/Pimple.git", - "reference": "876bf0899d01feacd2a2e83f04641e51350099ef" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/876bf0899d01feacd2a2e83f04641e51350099ef", - "reference": "876bf0899d01feacd2a2e83f04641e51350099ef", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Pimple": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Pimple is a simple Dependency Injection Container for PHP 5.3", - "homepage": "http://pimple.sensiolabs.org", - "keywords": [ - "container", - "dependency injection" - ], - "time": "2014-07-24 09:48:15" + "time": "2015-10-02 06:51:40" }, { "name": "sebastian/comparator", - "version": "1.1.1", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", - "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", + "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", "shasum": "" }, "require": { @@ -781,7 +742,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -818,32 +779,32 @@ "compare", "equality" ], - "time": "2015-01-29 16:28:08" + "time": "2015-07-26 15:48:44" }, { "name": "sebastian/diff", - "version": "1.2.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", - "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "~4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -866,36 +827,36 @@ } ], "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", + "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff" ], - "time": "2014-08-15 10:29:00" + "time": "2015-12-08 07:14:41" }, { "name": "sebastian/environment", - "version": "1.2.1", + "version": "1.3.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7" + "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7", - "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", + "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.3" + "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.3.x-dev" } }, "autoload": { @@ -920,20 +881,20 @@ "environment", "hhvm" ], - "time": "2014-10-25 08:00:45" + "time": "2016-02-26 18:40:46" }, { "name": "sebastian/exporter", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "84839970d05254c73cde183a721c7af13aede943" + "reference": "7ae5513327cb536431847bcc0c10edba2701064e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", - "reference": "84839970d05254c73cde183a721c7af13aede943", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e", + "reference": "7ae5513327cb536431847bcc0c10edba2701064e", "shasum": "" }, "require": { @@ -986,20 +947,20 @@ "export", "exporter" ], - "time": "2015-01-27 07:23:06" + "time": "2015-06-21 07:55:53" }, { "name": "sebastian/global-state", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", "shasum": "" }, "require": { @@ -1037,20 +998,20 @@ "keywords": [ "global state" ], - "time": "2014-10-06 09:23:50" + "time": "2015-10-12 03:26:01" }, { "name": "sebastian/recursion-context", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "3989662bbb30a29d20d9faa04a846af79b276252" + "reference": "913401df809e99e4f47b27cdd781f4a258d58791" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", - "reference": "3989662bbb30a29d20d9faa04a846af79b276252", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", + "reference": "913401df809e99e4f47b27cdd781f4a258d58791", "shasum": "" }, "require": { @@ -1090,20 +1051,20 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-01-24 09:48:32" + "time": "2015-11-11 19:50:13" }, { "name": "sebastian/version", - "version": "1.0.4", + "version": "1.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b" + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b", - "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", "shasum": "" }, "type": "library", @@ -1125,49 +1086,44 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2014-12-15 14:25:24" + "time": "2015-06-21 13:59:46" }, { "name": "symfony/css-selector", - "version": "v2.6.5", - "target-dir": "Symfony/Component/CssSelector", + "version": "v2.8.3", "source": { "type": "git", - "url": "https://github.com/symfony/CssSelector.git", - "reference": "86cf0aa16065ffc4545374e9479dd7878bf1d90f" + "url": "https://github.com/symfony/css-selector.git", + "reference": "8d83ff9777cdbd83e7f90d9c48f4729823791a5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/CssSelector/zipball/86cf0aa16065ffc4545374e9479dd7878bf1d90f", - "reference": "86cf0aa16065ffc4545374e9479dd7878bf1d90f", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/8d83ff9777cdbd83e7f90d9c48f4729823791a5e", + "reference": "8d83ff9777cdbd83e7f90d9c48f4729823791a5e", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" + "php": ">=5.3.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.8-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\CssSelector\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Jean-François Simon", "email": "jeanfrancois.simon@sensiolabs.com" @@ -1175,37 +1131,39 @@ { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony CssSelector Component", - "homepage": "http://symfony.com", - "time": "2015-02-24 11:52:21" + "homepage": "https://symfony.com", + "time": "2016-01-27 05:14:19" }, { "name": "symfony/event-dispatcher", - "version": "v2.6.5", - "target-dir": "Symfony/Component/EventDispatcher", + "version": "v2.8.3", "source": { "type": "git", - "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/70f7c8478739ad21e3deef0d977b38c77f1fb284", - "reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/78c468665c9568c3faaa9c416a7134308f2d85c3", + "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.0,>=2.0.5", - "symfony/dependency-injection": "~2.6", - "symfony/expression-language": "~2.6", - "symfony/phpunit-bridge": "~2.7", - "symfony/stopwatch": "~2.3" + "symfony/config": "~2.0,>=2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" }, "suggest": { "symfony/dependency-injection": "", @@ -1214,81 +1172,83 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.8-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony EventDispatcher Component", - "homepage": "http://symfony.com", - "time": "2015-03-13 17:37:22" + "homepage": "https://symfony.com", + "time": "2016-01-27 05:14:19" }, { "name": "symfony/yaml", - "version": "v2.6.5", - "target-dir": "Symfony/Component/Yaml", + "version": "v2.8.3", "source": { "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d" + "url": "https://github.com/symfony/yaml.git", + "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/0cd8e72071e46e15fc072270ae39ea1b66b10a9d", - "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d", + "url": "https://api.github.com/repos/symfony/yaml/zipball/2a4ee40acb880c56f29fb1b8886e7ffe94f3b995", + "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" + "php": ">=5.3.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.8-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Yaml\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Yaml Component", - "homepage": "http://symfony.com", - "time": "2015-03-12 10:28:44" + "homepage": "https://symfony.com", + "time": "2016-02-23 07:41:20" } ], "packages-dev": [ @@ -1298,12 +1258,12 @@ "source": { "type": "git", "url": "https://github.com/aik099/CodingStandard.git", - "reference": "f01c2c5cd22381566aa3daf9083deea6d323637a" + "reference": "eab50b83546dbbee649c06c6a42c8f2761b2b653" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/f01c2c5cd22381566aa3daf9083deea6d323637a", - "reference": "f01c2c5cd22381566aa3daf9083deea6d323637a", + "url": "https://api.github.com/repos/aik099/CodingStandard/zipball/eab50b83546dbbee649c06c6a42c8f2761b2b653", + "reference": "eab50b83546dbbee649c06c6a42c8f2761b2b653", "shasum": "" }, "require-dev": { @@ -1330,30 +1290,74 @@ "PHP_CodeSniffer", "codesniffer" ], - "time": "2015-03-18 08:14:41" + "time": "2016-02-26 20:33:27" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/b37020aa976fa52d3de9aa904aa2522dc518f79c", + "reference": "b37020aa976fa52d3de9aa904aa2522dc518f79c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "1.3.3", + "satooshi/php-coveralls": "dev-master" + }, + "type": "library", + "autoload": { + "classmap": [ + "hamcrest" + ], + "files": [ + "hamcrest/Hamcrest.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2015-05-11 14:41:42" }, { "name": "mockery/mockery", - "version": "0.9.3", + "version": "0.9.4", "source": { "type": "git", "url": "https://github.com/padraic/mockery.git", - "reference": "686f85fa5b3b079cc0157d7cd3e9adb97f0b41e1" + "reference": "70bba85e4aabc9449626651f48b9018ede04f86b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/padraic/mockery/zipball/686f85fa5b3b079cc0157d7cd3e9adb97f0b41e1", - "reference": "686f85fa5b3b079cc0157d7cd3e9adb97f0b41e1", + "url": "https://api.github.com/repos/padraic/mockery/zipball/70bba85e4aabc9449626651f48b9018ede04f86b", + "reference": "70bba85e4aabc9449626651f48b9018ede04f86b", "shasum": "" }, "require": { + "hamcrest/hamcrest-php": "~1.1", "lib-pcre": ">=7.0", "php": ">=5.3.2" }, "require-dev": { - "hamcrest/hamcrest-php": "~1.1", - "phpunit/phpunit": "~4.0", - "satooshi/php-coveralls": "~0.7@dev" + "phpunit/phpunit": "~4.0" }, "type": "library", "extra": { @@ -1382,7 +1386,7 @@ "homepage": "http://davedevelopment.co.uk" } ], - "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succint API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", + "description": "Mockery is a simple yet flexible PHP mock object framework for use in unit testing with PHPUnit, PHPSpec or any other testing framework. Its core goal is to offer a test double framework with a succinct API capable of clearly defining all possible object operations and interactions using a human readable Domain Specific Language (DSL). Designed as a drop in alternative to PHPUnit's phpunit-mock-objects library, Mockery is easy to integrate with PHPUnit and can operate alongside phpunit-mock-objects without the World ending.", "homepage": "http://github.com/padraic/mockery", "keywords": [ "BDD", @@ -1396,7 +1400,7 @@ "test double", "testing" ], - "time": "2014-12-22 10:06:19" + "time": "2015-04-02 19:54:00" } ], "aliases": [], diff --git a/library/PimpleCopy/Pimple/Container.php b/library/PimpleCopy/Pimple/Container.php new file mode 100644 index 0000000..417b39b --- /dev/null +++ b/library/PimpleCopy/Pimple/Container.php @@ -0,0 +1,287 @@ +factories = new \SplObjectStorage(); + $this->protected = new \SplObjectStorage(); + + foreach ( $values as $key => $value ) { + $this->offsetSet($key, $value); + } + } + + /** + * Sets a parameter or an object. + * + * Objects must be defined as Closures. + * + * Allowing any PHP callable leads to difficult to debug problems + * as function names (strings) are callable (creating a function with + * the same name as an existing parameter would break your container). + * + * @param string $id The unique identifier for the parameter or object. + * @param mixed $value The value of the parameter or a closure to define an object. + * + * @return void + * @throws \RuntimeException Prevent override of a frozen service. + */ + public function offsetSet($id, $value) + { + if ( isset($this->frozen[$id]) ) { + throw new \RuntimeException(sprintf('Cannot override frozen service "%s".', $id)); + } + + $this->values[$id] = $value; + $this->keys[$id] = true; + } + + /** + * Gets a parameter or an object. + * + * @param string $id The unique identifier for the parameter or object. + * + * @return mixed The value of the parameter or an object + * @throws \InvalidArgumentException If the identifier is not defined. + */ + public function offsetGet($id) + { + if ( !isset($this->keys[$id]) ) { + throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id)); + } + + if ( isset($this->raw[$id]) + || !is_object($this->values[$id]) + || isset($this->protected[$this->values[$id]]) + || !method_exists($this->values[$id], '__invoke') + ) { + return $this->values[$id]; + } + + if ( isset($this->factories[$this->values[$id]]) ) { + return $this->values[$id]($this); + } + + $raw = $this->values[$id]; + $val = $this->values[$id] = $raw($this); + $this->raw[$id] = $raw; + + $this->frozen[$id] = true; + + return $val; + } + + /** + * Checks if a parameter or an object is set. + * + * @param string $id The unique identifier for the parameter or object. + * + * @return boolean + */ + public function offsetExists($id) + { + return isset($this->keys[$id]); + } + + /** + * Unsets a parameter or an object. + * + * @param string $id The unique identifier for the parameter or object. + * + * @return void + */ + public function offsetUnset($id) + { + if ( isset($this->keys[$id]) ) { + if ( is_object($this->values[$id]) ) { + unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]); + } + + unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]); + } + } + + /** + * Marks a callable as being a factory service. + * + * @param callable $callable A service definition to be used as a factory. + * + * @return callable The passed callable + * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object. + */ + public function factory($callable) + { + if ( !method_exists($callable, '__invoke') ) { + throw new \InvalidArgumentException('Service definition is not a Closure or invokable object.'); + } + + $this->factories->attach($callable); + + return $callable; + } + + /** + * Protects a callable from being interpreted as a service. + * + * This is useful when you want to store a callable as a parameter. + * + * @param callable $callable A callable to protect from being evaluated. + * + * @return callable The passed callable + * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object. + */ + public function protect($callable) + { + if ( !method_exists($callable, '__invoke') ) { + throw new \InvalidArgumentException('Callable is not a Closure or invokable object.'); + } + + $this->protected->attach($callable); + + return $callable; + } + + /** + * Gets a parameter or the closure defining an object. + * + * @param string $id The unique identifier for the parameter or object. + * + * @return mixed The value of the parameter or the closure defining an object + * @throws \InvalidArgumentException If the identifier is not defined. + */ + public function raw($id) + { + if ( !isset($this->keys[$id]) ) { + throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id)); + } + + if ( isset($this->raw[$id]) ) { + return $this->raw[$id]; + } + + return $this->values[$id]; + } + + /** + * Extends an object definition. + * + * Useful when you want to extend an existing object definition, + * without necessarily loading that object. + * + * @param string $id The unique identifier for the object. + * @param callable $callable A service definition to extend the original. + * + * @return callable The wrapped callable + * @throws \InvalidArgumentException If the identifier is not defined or not a service definition. + */ + public function extend($id, $callable) + { + if ( !isset($this->keys[$id]) ) { + throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id)); + } + + if ( !is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke') ) { + throw new \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id)); + } + + if ( !is_object($callable) || !method_exists($callable, '__invoke') ) { + throw new \InvalidArgumentException('Extension service definition is not a Closure or invokable object.'); + } + + $factory = $this->values[$id]; + + $extended = function ($c) use ($callable, $factory) { + return $callable($factory($c), $c); + }; + + if ( isset($this->factories[$factory]) ) { + $this->factories->detach($factory); + $this->factories->attach($extended); + } + + return $this[$id] = $extended; + } + + /** + * Returns all defined value names. + * + * @return array An array of value names + */ + public function keys() + { + return array_keys($this->values); + } + + /** + * Registers a service provider. + * + * @param ServiceProviderInterface $provider A ServiceProviderInterface instance. + * @param array $values An array of values that customizes the provider. + * + * @return static + */ + public function register(ServiceProviderInterface $provider, array $values = array()) + { + $provider->register($this); + + foreach ( $values as $key => $value ) { + $this[$key] = $value; + } + + return $this; + } + +} diff --git a/library/PimpleCopy/Pimple/ServiceProviderInterface.php b/library/PimpleCopy/Pimple/ServiceProviderInterface.php new file mode 100644 index 0000000..e1d1d71 --- /dev/null +++ b/library/PimpleCopy/Pimple/ServiceProviderInterface.php @@ -0,0 +1,51 @@ + tests/aik099/PHPUnit + + tests/PimpleCopy/Pimple + - - - - library/aik099/PHPUnit diff --git a/tests/PimpleCopy/Pimple/PimpleTest.php b/tests/PimpleCopy/Pimple/PimpleTest.php index 4f8d925..760cb81 100644 --- a/tests/PimpleCopy/Pimple/PimpleTest.php +++ b/tests/PimpleCopy/Pimple/PimpleTest.php @@ -29,12 +29,15 @@ use Mockery as m; use PHPUnit\Framework\TestCase; use PimpleCopy\Pimple\Container; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; /** * @author Igor Wiedler */ class PimpleTest extends TestCase { + use ExpectException; + public function testWithString() { $pimple = new Container(); @@ -107,12 +110,11 @@ public function testConstructorInjection() $this->assertSame($params['param'], $pimple['param']); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Identifier "foo" is not defined. - */ public function testOffsetGetValidatesKeyIsPresent() { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Identifier "foo" is not defined.'); + $pimple = new Container(); echo $pimple['foo']; } @@ -197,12 +199,11 @@ public function testFluentRegister() $this->assertSame($pimple, $pimple->register($serviceProviderMock)); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Identifier "foo" is not defined. - */ public function testRawValidatesKeyIsPresent() { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Identifier "foo" is not defined.'); + $pimple = new Container(); $pimple->raw('foo'); } @@ -262,12 +263,11 @@ public function testExtendDoesNotLeakWithFactories() $this->assertCount(0, $p->getValue($pimple)); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Identifier "foo" is not defined. - */ public function testExtendValidatesKeyIsPresent() { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Identifier "foo" is not defined.'); + $pimple = new Container(); $pimple->extend('foo', function () {}); } @@ -301,33 +301,36 @@ public function settingNonInvokableObjectShouldTreatItAsParameter() /** * @dataProvider badServiceDefinitionProvider - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Service definition is not a Closure or invokable object. */ public function testFactoryFailsForInvalidServiceDefinitions($service) { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Service definition is not a Closure or invokable object.'); + $pimple = new Container(); $pimple->factory($service); } /** * @dataProvider badServiceDefinitionProvider - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Callable is not a Closure or invokable object. */ public function testProtectFailsForInvalidServiceDefinitions($service) { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Callable is not a Closure or invokable object.'); + $pimple = new Container(); $pimple->protect($service); } /** * @dataProvider badServiceDefinitionProvider - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Identifier "foo" does not contain an object definition. */ public function testExtendFailsForKeysNotContainingServiceDefinitions($service) { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Identifier "foo" does not contain an object definition.'); + $pimple = new Container(); $pimple['foo'] = $service; $pimple->extend('foo', function () {}); @@ -335,11 +338,12 @@ public function testExtendFailsForKeysNotContainingServiceDefinitions($service) /** * @dataProvider badServiceDefinitionProvider - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Extension service definition is not a Closure or invokable object. */ public function testExtendFailsForInvalidServiceDefinitions($service) { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Extension service definition is not a Closure or invokable object.'); + $pimple = new Container(); $pimple['foo'] = function () {}; $pimple->extend('foo', $service); @@ -386,12 +390,11 @@ public function testDefiningNewServiceAfterFreeze() $this->assertSame('bar', $pimple['bar']); } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessage Cannot override frozen service "foo". - */ public function testOverridingServiceAfterFreeze() { + $this->expectException('RuntimeException'); + $this->expectExceptionMessage('Cannot override frozen service "foo".'); + $pimple = new Container(); $pimple['foo'] = function () { return 'foo'; diff --git a/tests/aik099/PHPUnit/ApplicationTest.php b/tests/aik099/PHPUnit/ApplicationTest.php index 4a86551..f88797b 100644 --- a/tests/aik099/PHPUnit/ApplicationTest.php +++ b/tests/aik099/PHPUnit/ApplicationTest.php @@ -11,13 +11,16 @@ namespace tests\aik099\PHPUnit; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Application; use Mockery as m; -use PHPUnit\Framework\TestCase; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class ApplicationTest extends TestCase +class ApplicationTest extends AbstractPHPUnitCompatibilityTestCase { + use ExpectException; + /** * Application. * @@ -26,14 +29,10 @@ class ApplicationTest extends TestCase private $_application; /** - * Creates container for testing. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); - $this->_application = new Application(); } @@ -89,10 +88,11 @@ public function testReplaceObjectSuccess() * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testReplaceObjectFailure() { + $this->expectException('InvalidArgumentException'); + $this->_application->replaceObject('bad_service', function () { }); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 85f9aa0..7712012 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -16,13 +16,17 @@ use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Event\TestEvent; use aik099\PHPUnit\Session\ISessionStrategyFactory; +use aik099\PHPUnit\Framework\TestResult; use Symfony\Component\EventDispatcher\EventDispatcher; use aik099\PHPUnit\BrowserTestCase; use Mockery as m; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; abstract class ApiBrowserConfigurationTestCase extends BrowserConfigurationTest { + use ExpectException; + const PORT = 80; const AUTOMATIC_TEST_NAME = 'AUTOMATIC'; @@ -42,11 +46,9 @@ abstract class ApiBrowserConfigurationTestCase extends BrowserConfigurationTest protected $apiClient; /** - * Configures all tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { $this->testsRequireSubscriber[] = 'testTestSetupEvent'; $this->testsRequireSubscriber[] = 'testTestEndedEvent'; @@ -57,7 +59,7 @@ protected function setUp() $this->mockBrowserMethods[] = 'getAPIClient'; } - parent::setUp(); + parent::setUpTest(); $this->setup['port'] = 80; $this->setup['apiUsername'] = 'UN'; @@ -311,7 +313,7 @@ public function testTestEndedEvent($driver_type) } else { $driver = m::mock('\\Behat\\Mink\\Driver\\DriverInterface'); - $this->setExpectedException('RuntimeException'); + $this->expectException('RuntimeException'); } $session = m::mock('Behat\\Mink\\Session'); @@ -321,7 +323,7 @@ public function testTestEndedEvent($driver_type) $event_dispatcher = new EventDispatcher(); $event_dispatcher->addSubscriber($this->browser); - $test_result = m::mock('PHPUnit_Framework_TestResult'); + $test_result = new TestResult(); // Can't mock, because it's a final class. $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index f2e8d3c..635a10e 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -16,10 +16,13 @@ use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Mockery as m; use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; class BrowserConfigurationFactoryTest extends EventDispatcherAwareTestCase { + use ExpectException; + /** * Browser configuration factory. * @@ -35,13 +38,11 @@ class BrowserConfigurationFactoryTest extends EventDispatcherAwareTestCase private $_driverFactoryRegistry; /** - * Configures the tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); + parent::setUpTest(); $this->_factory = new BrowserConfigurationFactory(); $this->_driverFactoryRegistry = $this->createDriverFactoryRegistry(); @@ -122,10 +123,11 @@ public function createBrowserConfigurationDataProvider() * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testCreateBrowserConfigurationError() { + $this->expectException('InvalidArgumentException'); + $browser_aliases = array('alias-one' => array()); $test_case = m::mock('aik099\\PHPUnit\\BrowserTestCase'); @@ -138,10 +140,11 @@ public function testCreateBrowserConfigurationError() * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testRegisterFailure() { + $this->expectException('InvalidArgumentException'); + $browser_configuration = $this->_createBrowserConfiguration('new-one'); $this->_factory->register($browser_configuration); $this->_factory->register($browser_configuration); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 331b5f9..d188f56 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -18,13 +18,17 @@ use aik099\PHPUnit\Session\ISessionStrategyFactory; use Mockery as m; use Mockery\Generator\MockConfigurationBuilder; +use aik099\PHPUnit\Framework\TestResult; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; class BrowserConfigurationTest extends EventDispatcherAwareTestCase { + use ExpectException; + const TEST_CASE_CLASS = '\\aik099\\PHPUnit\\BrowserTestCase'; const HOST = 'example_host'; @@ -88,13 +92,11 @@ class BrowserConfigurationTest extends EventDispatcherAwareTestCase protected $testsRequireSubscriber = array(); /** - * Configures all tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); + parent::setUpTest(); if ( !$this->browserConfigurationClass ) { $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; @@ -239,10 +241,11 @@ public function aliasResolutionDataProvider() * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testResolveAliasesUsingIncorrectAlias() { + $this->expectException('InvalidArgumentException'); + $this->browser->setup(array('alias' => 'not_found')); } @@ -266,10 +269,11 @@ public function testAttachToTestCase() * Test description. * * @return void - * @expectedException \RuntimeException */ public function testGetTestCaseException() { + $this->expectException('RuntimeException'); + $this->browser->getTestCase(); } @@ -296,10 +300,11 @@ public function testSetup() * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testSetupScreamsAboutUnknownParameters() { + $this->expectException('InvalidArgumentException'); + $this->browser->setup(array('unknown-parameter' => 'value')); } @@ -308,12 +313,11 @@ public function testGetType() $this->assertEquals('default', $this->browser->getType()); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage The Mink driver name must be a string - */ public function testSetDriverIncorrect() { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('The Mink driver name must be a string'); + $this->browser->setDriver(array()); } @@ -344,10 +348,11 @@ public function testDriverFactoryDefaultsApplied() * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testSetHostIncorrect() { + $this->expectException('InvalidArgumentException'); + $this->browser->setHost(5555); } @@ -367,10 +372,11 @@ public function testSetHostCorrect() * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testSetPortIncorrect() { + $this->expectException('InvalidArgumentException'); + $this->browser->setPort('5555'); } @@ -390,10 +396,11 @@ public function testSetPortCorrect() * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testSetBrowserNameIncorrect() { + $this->expectException('InvalidArgumentException'); + $this->browser->setBrowserName(5555); } @@ -413,10 +420,11 @@ public function testSetBrowserNameCorrect() * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testSetBaseUrlIncorrect() { + $this->expectException('InvalidArgumentException'); + $this->browser->setBaseUrl(5555); } @@ -452,10 +460,11 @@ public function testSetDesiredCapabilitiesCorrect(array $desired_capabilities = * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testSetTimeoutIncorrect() { + $this->expectException('InvalidArgumentException'); + $this->browser->setTimeout('5555'); } @@ -485,12 +494,11 @@ public function testSetSessionStrategy($expected) $this->assertSame($expected, $this->browser->getSessionStrategy()); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Unable to get unknown parameter "nonExisting" - */ public function testGetParameterIncorrect() { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Unable to get unknown parameter "nonExisting"'); + $this->browser->getNonExisting(); } @@ -505,8 +513,8 @@ public function testCreateDriver() public function testNonExistingMethod() { - $this->setExpectedException( - '\BadMethodCallException', + $this->expectException('BadMethodCallException'); + $this->expectExceptionMessage( 'Method "nonExistingMethod" does not exist on ' . get_class($this->browser) . ' class' ); @@ -575,7 +583,7 @@ public function testGetTestStatusIsolated() { $test_case = m::mock(self::TEST_CASE_CLASS); $test_case->shouldReceive('hasFailed')->once()->andReturn(false); - $test_result = m::mock('\\PHPUnit_Framework_TestResult'); + $test_result = new TestResult(); // Can't mock, because it's a final class. $this->browser->setSessionStrategy(ISessionStrategyFactory::TYPE_ISOLATED); $this->assertTrue($this->browser->getTestStatus($test_case, $test_result)); @@ -589,8 +597,7 @@ public function testGetTestStatusIsolated() public function testGetTestStatusShared() { $test_case = m::mock(self::TEST_CASE_CLASS); - $test_result = m::mock('\\PHPUnit_Framework_TestResult'); - $test_result->shouldReceive('wasSuccessful')->once()->andReturn(true); + $test_result = new TestResult(); // Can't mock, because it's a final class. $this->browser->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED); $this->assertTrue($this->browser->getTestStatus($test_case, $test_result)); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php index 8ea93b5..4e6f60e 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -19,11 +19,9 @@ class BrowserStackBrowserConfigurationTest extends ApiBrowserConfigurationTestCa const HOST = ':@hub.browserstack.com'; /** - * Configures all tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserStackBrowserConfiguration'; @@ -32,7 +30,7 @@ protected function setUp() 'browserstack.localIdentifier' => 'env:PHPUNIT_MINK_TUNNEL_ID', ); - parent::setUp(); + parent::setUpTest(); $this->setup['desiredCapabilities'] = array( 'os' => 'Windows', 'os_version' => 'XP', 'version' => 10, diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index a8e9c75..ccbd3ec 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -19,11 +19,9 @@ class SauceLabsBrowserConfigurationTest extends ApiBrowserConfigurationTestCase const HOST = ':@ondemand.saucelabs.com'; /** - * Configures all tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\SauceLabsBrowserConfiguration'; @@ -31,7 +29,7 @@ protected function setUp() 'tunnel-identifier' => 'env:PHPUNIT_MINK_TUNNEL_ID', ); - parent::setUp(); + parent::setUpTest(); $this->setup['host'] = 'UN:AK@ondemand.saucelabs.com'; } diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 63004d3..dbd100c 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -15,18 +15,27 @@ use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageTool; use aik099\PHPUnit\Session\ISessionStrategy; use aik099\PHPUnit\Session\SessionStrategyManager; use Mockery as m; use Mockery\MockInterface; +use aik099\PHPUnit\Framework\TestResult; +use aik099\SebastianBergmann\CodeCoverage\CodeCoverage; +use aik099\SebastianBergmann\CodeCoverage\Filter; +use SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData; +use SebastianBergmann\CodeCoverage\RawCodeCoverageData; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; class BrowserTestCaseTest extends EventDispatcherAwareTestCase { + use ExpectException; + const BROWSER_CLASS = '\\aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; const MANAGER_CLASS = '\\aik099\\PHPUnit\\Session\\SessionStrategyManager'; @@ -41,13 +50,11 @@ class BrowserTestCaseTest extends EventDispatcherAwareTestCase protected $browserConfigurationFactory; /** - * Configures all tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); + parent::setUpTest(); // Define the constant because this test is running PHPUnit testcases manually. if ( $this->isInIsolation() ) { @@ -122,10 +129,11 @@ protected function createDriverFactoryRegistry() * Test description. * * @return void - * @expectedException \RuntimeException */ public function testGetBrowserNotSpecified() { + $this->expectException('RuntimeException'); + $test_case = new WithoutBrowserConfig(); $test_case->getBrowser(); } @@ -207,7 +215,7 @@ public function testGetSession() $test_case = $this->getFixture($session_strategy); $test_case->setBrowser($browser); - $test_case->setTestResultObject($this->getTestResult($test_case, 0)); + $test_case->setTestResultObject(new TestResult()); // Create session when missing. $session1 = $test_case->getSession(); @@ -222,11 +230,12 @@ public function testGetSession() * Test description. * * @return void - * @expectedException \Exception - * @expectedExceptionMessage MSG_SKIP */ public function testGetSessionDriverError() { + $this->expectException('Exception'); + $this->expectExceptionMessage('MSG_SKIP'); + $browser = $this->getBrowser(1); /* @var $session_strategy ISessionStrategy */ @@ -265,7 +274,24 @@ protected function getBrowser($times) public function testGetCollectCodeCoverageInformationSuccess() { $test_case = $this->getFixture(); - $test_result = $this->getTestResult($test_case, 0, true); + + $test_result = new TestResult(); + + // Can't mock due to class being marked as final. + if ( \interface_exists('\PHP_CodeCoverage_Driver') ) { + $code_coverage = new CodeCoverage( + m::mock('\PHP_CodeCoverage_Driver'), + new Filter() + ); + } + else { + $code_coverage = new CodeCoverage( + m::mock('\\aik099\\SebastianBergmann\\CodeCoverage\\Driver\\Driver'), + new Filter() + ); + } + + $test_result->setCodeCoverage($code_coverage); $test_case->setTestResultObject($test_result); $this->assertTrue($test_case->getCollectCodeCoverageInformation()); @@ -282,7 +308,7 @@ public function testRun() { /* @var $test_case BrowserTestCase */ list($test_case,) = $this->prepareForRun(); - $result = $this->getTestResult($test_case, 1); + $result = new TestResult(); $this->assertSame($result, $test_case->run($result)); } @@ -299,7 +325,7 @@ public function testRunCreateResult() /* @var $test_case BrowserTestCase */ list($test_case,) = $this->prepareForRun(); - $this->assertInstanceOf('\\PHPUnit_Framework_TestResult', $test_case->run()); + $this->assertInstanceOf('\\aik099\\PHPUnit\\Framework\\TestResult', $test_case->run()); } /** @@ -315,12 +341,20 @@ public function testRunWithCoverageWithoutRemoteUrl() /* @var $session_strategy ISessionStrategy */ list($test_case, $session_strategy) = $this->prepareForRun(array()); $test_case->setName('getTestId'); - - $code_coverage = m::mock('\\PHP_CodeCoverage'); - $code_coverage->shouldReceive('append')->with(m::mustBe(array()), $test_case)->once(); - - $result = $this->getTestResult($test_case, 1, true); - $result->shouldReceive('getCodeCoverage')->once()->andReturn($code_coverage); + $test_case->setRemoteCoverageHelper($this->getRemoteCoverageHelperMock()); + + $result = new TestResult(); + $code_coverage = $this->getCodeCoverageMock(array( + $this->getCoverageFixtureFile() => array ( + 7 => -1, // Means line not executed. + 8 => -1, + 9 => -1, + 12 => -1, + 13 => -1, + 14 => -1, + ), + )); + $result->setCodeCoverage($code_coverage); $test_id = $test_case->getTestId(); $this->assertEmpty($test_id); @@ -337,6 +371,32 @@ public function testRunWithCoverageWithoutRemoteUrl() $test_case->run($result); + if ( \class_exists('\SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData') ) { + $actual_coverage = $code_coverage->getData(); + $expected_coverage = new ProcessedCodeCoverageData(); + $expected_coverage->setLineCoverage(array( + $this->getCoverageFixtureFile() => array( + 8 => array(), // First "return null;" statement. + 13 => array(), // Second "return null;" statement. + ), + )); + $this->assertEquals($expected_coverage, $actual_coverage); + } + else { + $actual_coverage = $code_coverage->getData(); + $expected_coverage = array( + $this->getCoverageFixtureFile() => array ( + 7 => array(), // Means, that this test hasn't executed a tested code. + 8 => array(), + 9 => array(), + 12 => array(), + 13 => array(), + 14 => array(), + ), + ); + $this->assertEquals($expected_coverage, $actual_coverage); + } + $this->assertNotEmpty($test_case->getTestId()); } @@ -349,26 +409,27 @@ public function testRunWithCoverageWithoutRemoteUrl() */ public function testRunWithCoverage() { - $expected_coverage = array('test1' => 'test2'); - - $remote_coverage_helper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); - $remote_coverage_helper - ->shouldReceive('get') - ->with('some-url', 'tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig__getTestId') - ->andReturn($expected_coverage); + $expected_coverage = array( + $this->getCoverageFixtureFile() => array ( + 7 => 1, // Means line executed. + 8 => -1, // Means, that this test hasn't executed a tested code. + 9 => 1, + 12 => 1, + 13 => 1, + 14 => 1, + ), + ); /* @var $test_case BrowserTestCase */ /* @var $session_strategy ISessionStrategy */ list($test_case, $session_strategy) = $this->prepareForRun(); $test_case->setName('getTestId'); - $test_case->setRemoteCoverageHelper($remote_coverage_helper); + $test_case->setRemoteCoverageHelper($this->getRemoteCoverageHelperMock($expected_coverage)); $test_case->setRemoteCoverageScriptUrl('some-url'); - $code_coverage = m::mock('\\PHP_CodeCoverage'); - $code_coverage->shouldReceive('append')->with($expected_coverage, $test_case)->once(); - - $result = $this->getTestResult($test_case, 1, true); - $result->shouldReceive('getCodeCoverage')->once()->andReturn($code_coverage); + $result = new TestResult(); + $code_coverage = $this->getCodeCoverageMock($expected_coverage); + $result->setCodeCoverage($code_coverage); $test_id = $test_case->getTestId(); $this->assertEmpty($test_id); @@ -385,9 +446,129 @@ public function testRunWithCoverage() $test_case->run($result); + $covered_by_test = 'tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig::getTestId'; + + if ( \class_exists('\SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData') ) { + $expected_coverage = new ProcessedCodeCoverageData(); + $expected_coverage->setLineCoverage(array( + $this->getCoverageFixtureFile() => array( + 8 => array(), // Means, that this test hasn't executed a tested code. + 13 => array($covered_by_test, $covered_by_test), // Means, covered by this test twice. + ), + )); + $actual_coverage = $code_coverage->getData(); + $this->assertEquals($expected_coverage, $actual_coverage); + } + else { + $actual_coverage = $code_coverage->getData(); + $expected_coverage = array( + $this->getCoverageFixtureFile() => array ( + 7 => array($covered_by_test), // Means, covered by this test. + 8 => array(), // Means, that this test hasn't executed a tested code. + 9 => array($covered_by_test), + 12 => array($covered_by_test), + 13 => array($covered_by_test), + 14 => array($covered_by_test), + ), + ); + $this->assertEquals($expected_coverage, $actual_coverage); + } + $this->assertNotEmpty($test_case->getTestId()); } + /** + * Returns the coverage fixture file. + * + * @return string + */ + protected function getCoverageFixtureFile() + { + return \realpath(__DIR__ . '/Fixture/DummyClass.php'); + } + + /** + * Returns remote coverage helper mock. + * + * @param array|null $expected_coverage Expected coverage. + * + * @return RemoteCoverageHelper + */ + protected function getRemoteCoverageHelperMock(array $expected_coverage = null) + { + $remote_coverage_helper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); + + if ( $expected_coverage !== null ) { + if ( \class_exists('\SebastianBergmann\CodeCoverage\RawCodeCoverageData') ) { + $remote_coverage_helper + ->shouldReceive('get') + ->with('some-url', 'tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig__getTestId') + ->andReturn(RawCodeCoverageData::fromXdebugWithoutPathCoverage($expected_coverage)); + } + else { + $remote_coverage_helper + ->shouldReceive('get') + ->with('some-url', 'tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig__getTestId') + ->andReturn($expected_coverage); + } + } + + if ( \class_exists('\SebastianBergmann\CodeCoverage\RawCodeCoverageData') ) { + $remote_coverage_helper + ->shouldReceive('getEmpty') + ->andReturn(RawCodeCoverageData::fromXdebugWithoutPathCoverage(array())); + } + else { + $remote_coverage_helper + ->shouldReceive('getEmpty') + ->andReturn(array()); + } + + return $remote_coverage_helper; + } + + /** + * Returns code coverage mock. + * + * @param array $expected_coverage Expected coverage. + * + * @return CodeCoverage + */ + protected function getCodeCoverageMock(array $expected_coverage) + { + if ( \interface_exists('\PHP_CodeCoverage_Driver') ) { + $driver = m::mock('\PHP_CodeCoverage_Driver'); + } + else { + $driver = m::mock('\\aik099\\SebastianBergmann\\CodeCoverage\\Driver\\Driver'); + } + + $driver->shouldReceive('start')->once(); + + // Can't assert call count, because expectations are verified prior to coverage being queried. + if ( \class_exists('\SebastianBergmann\CodeCoverage\RawCodeCoverageData') ) { + $driver->shouldReceive('stop') + /*->once()*/ + ->andReturn( + RawCodeCoverageData::fromXdebugWithoutPathCoverage($expected_coverage) + ); + } + else { + $driver->shouldReceive('stop')->/*once()->*/andReturn($expected_coverage); + } + + $filter = new Filter(); + + if ( \method_exists($filter, 'addFileToWhitelist') ) { + $filter->addFileToWhitelist($this->getCoverageFixtureFile()); + } + elseif ( \method_exists($filter, 'includeFile') ) { + $filter->includeFile($this->getCoverageFixtureFile()); + } + + return new CodeCoverage($driver, $filter); + } + /** * Test description. * @@ -411,11 +592,12 @@ public function testEndOfTestCase() * Test description. * * @return void - * @expectedException \Exception - * @expectedExceptionMessage MSG_TEST */ public function testOnTestFailed() { + $this->expectException('Exception'); + $this->expectExceptionMessage('MSG_TEST'); + $this->expectEvent(BrowserTestCase::TEST_FAILED_EVENT); /* @var $session_strategy ISessionStrategy */ @@ -445,19 +627,14 @@ public function testGetBrowserAliases() /** * Prepares test case to be used by "run" method. * - * @param array $mock_methods Method names to mock. - * @param boolean $expect_test_ended Tells, that we should expect "test.ended" event. + * @param array $mock_methods Method names to mock. * * @return array */ - protected function prepareForRun(array $mock_methods = array(), $expect_test_ended = true) + protected function prepareForRun(array $mock_methods = array()) { $this->expectEvent(BrowserTestCase::TEST_SETUP_EVENT); - if ( $expect_test_ended ) { - $this->expectEvent(BrowserTestCase::TEST_ENDED_EVENT); - } - /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); @@ -467,31 +644,9 @@ protected function prepareForRun(array $mock_methods = array(), $expect_test_end $browser = $this->getBrowser(0); $test_case->setBrowser($browser); - return array($test_case, $session_strategy); - } - - /** - * Returns test result. - * - * @param BrowserTestCase $test_case Browser test case. - * @param integer $run_count Test run count. - * @param boolean $collect_coverage Should collect coverage information. - * - * @return \PHPUnit_Framework_TestResult|MockInterface - */ - protected function getTestResult(BrowserTestCase $test_case, $run_count, $collect_coverage = false) - { - $result = m::mock('\\PHPUnit_Framework_TestResult'); - $result->shouldReceive('getCollectCodeCoverageInformation')->withNoArgs()->withAnyArgs()->andReturn($collect_coverage); + $this->expectEvent(\aik099\PHPUnit\BrowserTestCase::TEST_ENDED_EVENT); - $result->shouldReceive('run') - ->with($test_case) - ->times($run_count) - ->andReturnUsing(function () use ($test_case) { - $test_case->runBare(); - }); - - return $result; + return array($test_case, $session_strategy); } /** diff --git a/tests/aik099/PHPUnit/Event/TestEndedEventTest.php b/tests/aik099/PHPUnit/Event/TestEndedEventTest.php index 37dca83..0621b79 100644 --- a/tests/aik099/PHPUnit/Event/TestEndedEventTest.php +++ b/tests/aik099/PHPUnit/Event/TestEndedEventTest.php @@ -12,6 +12,7 @@ use aik099\PHPUnit\Event\TestEndedEvent; +use aik099\PHPUnit\Framework\TestResult; class TestEndedEventTest extends TestEventTest { @@ -19,20 +20,18 @@ class TestEndedEventTest extends TestEventTest /** * Test result. * - * @var \PHPUnit_Framework_TestResult + * @var TestResult */ private $_testResult; /** - * Prepares the tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - $this->_testResult = new \PHPUnit_Framework_TestResult(); + $this->_testResult = new TestResult(); - parent::setUp(); + parent::setUpTest(); } /** diff --git a/tests/aik099/PHPUnit/Event/TestEventTest.php b/tests/aik099/PHPUnit/Event/TestEventTest.php index 6f27a5b..5734645 100644 --- a/tests/aik099/PHPUnit/Event/TestEventTest.php +++ b/tests/aik099/PHPUnit/Event/TestEventTest.php @@ -11,13 +11,13 @@ namespace tests\aik099\PHPUnit\Event; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\Event\TestEvent; use Behat\Mink\Session; use Mockery as m; -use PHPUnit\Framework\TestCase; -class TestEventTest extends TestCase +class TestEventTest extends AbstractPHPUnitCompatibilityTestCase { /** @@ -42,14 +42,10 @@ class TestEventTest extends TestCase protected $session; /** - * Prepares the tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); - $this->testCase = m::mock('aik099\\PHPUnit\\BrowserTestCase'); $this->session = m::mock('Behat\\Mink\\Session'); $this->event = $this->createEvent(); diff --git a/tests/aik099/PHPUnit/Event/TestFailedEventTest.php b/tests/aik099/PHPUnit/Event/TestFailedEventTest.php index a53fb10..48bf46a 100644 --- a/tests/aik099/PHPUnit/Event/TestFailedEventTest.php +++ b/tests/aik099/PHPUnit/Event/TestFailedEventTest.php @@ -25,15 +25,13 @@ class TestFailedEventTest extends TestEventTest private $_exception; /** - * Prepares the tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { $this->_exception = new Exception(); - parent::setUp(); + parent::setUpTest(); } /** diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php index 23c8699..146a9af 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php @@ -22,11 +22,9 @@ class SetupEventFixture extends BrowserTestCase { /** - * Creating browser configuration that would listen for events. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { $api_client = m::mock('aik099\\PHPUnit\\APIClient\\IAPIClient'); $api_client->shouldReceive('updateStatus')->withAnyArgs()->once(); @@ -38,7 +36,7 @@ protected function setUp() $browser = m::mock( 'aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration[getAPIClient]', - array($this->readAttribute($this, '_eventDispatcher'), $this->createDriverFactoryRegistry()) + array($this->getObjectProperty($this, '_eventDispatcher'), $this->createDriverFactoryRegistry()) ); // These magic methods can't be properly passed through to mocked object otherwise. @@ -57,7 +55,31 @@ protected function setUp() $this->setBrowserFromConfiguration($browser_config); - parent::setUp(); + parent::setUpTest(); + } + + /** + * Returns object property value. + * + * @param mixed $object Object. + * @param string $property_name Property name. + * + * @return mixed + */ + protected function getObjectProperty($object, $property_name) + { + $reflector = new \ReflectionObject($object); + + while ( !$reflector->hasProperty($property_name) && $reflector->getParentClass() !== false ) { + $reflector = $reflector->getParentClass(); + } + + $attribute = $reflector->getProperty($property_name); + $attribute->setAccessible(true); + $value = $attribute->getValue($object); + $attribute->setAccessible(false); + + return $value; } /** @@ -95,9 +117,7 @@ public function testEvents() // For SauceLabsBrowserConfiguration::onTestEnded. $session->shouldReceive('getDriver')->once()->andReturn($driver); - // For IsolatedSessionStrategy::onTestEnd (twice per each browser because - // we have 2 strategies listening for test end + IsolatedSessionStrategyTest with 2 tests). - $session->shouldReceive('stop')->times(6); + $session->shouldReceive('stop')->once(); $session->shouldReceive('isStarted')->andReturn(true); $this->_setSession($session); diff --git a/tests/aik099/PHPUnit/Fixture/WithoutBrowserConfig.php b/tests/aik099/PHPUnit/Fixture/WithoutBrowserConfig.php index 62770e6..fe8ea97 100644 --- a/tests/aik099/PHPUnit/Fixture/WithoutBrowserConfig.php +++ b/tests/aik099/PHPUnit/Fixture/WithoutBrowserConfig.php @@ -23,7 +23,7 @@ class WithoutBrowserConfig extends BrowserTestCase */ public function testSuccess() { - + echo ''; } /** diff --git a/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php b/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php index fa7e7b0..2a9d318 100644 --- a/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php +++ b/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php @@ -11,16 +11,18 @@ namespace tests\aik099\PHPUnit\Integration; -use PHPUnit\Framework\TestCase; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; +use aik099\PHPUnit\Framework\TestResult; use tests\aik099\PHPUnit\Fixture\ApiIntegrationFixture; -class ApiIntegrationTest extends TestCase +class ApiIntegrationTest extends AbstractPHPUnitCompatibilityTestCase { - protected function setUp() + /** + * @before + */ + protected function setUpTest() { - parent::setUp(); - // Define the constant because this test is running PHPUnit testcases manually. if ( $this->isInIsolation() ) { define('PHPUNIT_TESTSUITE', true); @@ -36,7 +38,7 @@ protected function setUp() */ public function testAPICalls() { - $result = new \PHPUnit_Framework_TestResult(); + $result = new TestResult(); $suite = ApiIntegrationFixture::suite('tests\\aik099\\PHPUnit\\Fixture\\ApiIntegrationFixture'); $suite->run($result); diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index 16d0e21..9a4f887 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\Integration; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Application; use aik099\PHPUnit\DIContainer; -use PHPUnit\Framework\TestCase; -class DIContainerTest extends TestCase +class DIContainerTest extends AbstractPHPUnitCompatibilityTestCase { /** @@ -28,12 +28,10 @@ class DIContainerTest extends TestCase /** * Creates container for testing. * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); - $this->_container = new DIContainer(); $this->_container->setApplication(new Application()); } diff --git a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php index e5b0b9d..25be854 100644 --- a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php +++ b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php @@ -11,16 +11,18 @@ namespace tests\aik099\PHPUnit\Integration; -use PHPUnit\Framework\TestCase; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; +use aik099\PHPUnit\Framework\TestResult; use tests\aik099\PHPUnit\Fixture\SetupEventFixture; -class EventDispatchingTest extends TestCase +class EventDispatchingTest extends AbstractPHPUnitCompatibilityTestCase { - protected function setUp() + /** + * @before + */ + protected function setUpTest() { - parent::setUp(); - // Define the constant because this test is running PHPUnit testcases manually. if ( $this->isInIsolation() ) { define('PHPUNIT_TESTSUITE', true); @@ -51,7 +53,7 @@ public function testSetupEvent() * - SharedSessionStrategy::onTestFailed */ - $result = new \PHPUnit_Framework_TestResult(); + $result = new TestResult(); $suite = SetupEventFixture::suite('tests\\aik099\\PHPUnit\\Fixture\\SetupEventFixture'); $suite->run($result); diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index b2fd562..77df275 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -11,9 +11,13 @@ namespace tests\aik099\PHPUnit\Integration; +use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains; + class IsolatedSessionStrategyTest extends SauceLabsAwareTestCase { + use AssertStringContains; + /** * Browser list to be used in tests. * @@ -46,7 +50,7 @@ public function testTwo() $session = $this->getSession(); $url = $session->isStarted() ? $session->getCurrentUrl() : ''; - $this->assertNotContains('https://www.google.com', $url); + $this->assertStringNotContainsString('https://www.google.com', $url); } } diff --git a/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php b/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php index f46a054..28f3b4e 100644 --- a/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php +++ b/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php @@ -26,17 +26,13 @@ abstract class SauceLabsAwareTestCase extends BrowserTestCase ); /** - * Set session meta-info for "Sauce Labs". - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { if ( !getenv('SAUCE_USERNAME') || !getenv('SAUCE_ACCESS_KEY') ) { $this->markTestSkipped('SauceLabs integration is not configured'); } - - parent::setUp(); } /** diff --git a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php index 26fffc5..5b4c4a4 100644 --- a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php @@ -11,9 +11,13 @@ namespace tests\aik099\PHPUnit\Integration; +use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains; + class SharedSessionStrategyTest extends SauceLabsAwareTestCase { + use AssertStringContains; + /** * Browser list to be used in tests. * @@ -46,7 +50,7 @@ public function testTwo() $session = $this->getSession(); $url = $session->getCurrentUrl(); - $this->assertContains('https://www.google.com', $url); + $this->assertStringContainsString('https://www.google.com', $url); } } diff --git a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php index 4fbe27f..ca96faf 100644 --- a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php @@ -11,15 +11,17 @@ namespace tests\aik099\PHPUnit\Integration; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\TestSuite\BrowserTestSuite; use aik099\PHPUnit\TestSuite\RegularTestSuite; -use PHPUnit\Framework\TestCase; +use aik099\PHPUnit\Framework\TestResult; +use PHPUnit\Runner\Version; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use Mockery as m; -class SuiteBuildingTest extends TestCase +class SuiteBuildingTest extends AbstractPHPUnitCompatibilityTestCase { const SUITE_CLASS = '\\aik099\\PHPUnit\\TestSuite\\RegularTestSuite'; @@ -84,10 +86,7 @@ public function testSuiteTearDown() $suite->addTest($sub_browser_suite); $suite->addTest($sub_test_suite); - $result = m::mock('\\PHPUnit_Framework_TestResult'); - $result->shouldReceive('startTestSuite'); - $result->shouldReceive('shouldStop')->andReturn(false); - $result->shouldReceive('endTestSuite'); + $result = new TestResult(); // Can't mock, because it's a final class. $this->assertSame($result, $suite->run($result)); } @@ -109,20 +108,39 @@ protected function createTestSuite($class_name) $suite->shouldReceive('setBackupStaticAttributes'); $suite->shouldReceive('setRunTestInSeparateProcess'); - $suite->shouldReceive('run')->once(); + $suite->shouldReceive('run')->once()->andReturnUsing(function ($result = null) { + return $result; + }); $suite->shouldReceive('onTestSuiteEnded')->once(); - if ( version_compare(\PHPUnit_Runner_Version::id(), '4.0.0', '>=') ) { + $phpunit_version = $this->getPhpUnitVersion(); + + // Pretend, that mocked test suite has 1 test inside it. + if ( version_compare($phpunit_version, '4.0.0', '>=') ) { $suite->shouldReceive('count')->once()->andReturn(1); } - if ( version_compare(\PHPUnit_Runner_Version::id(), '5.0.0', '>=') ) { + if ( version_compare($phpunit_version, '5.0.0', '>=') ) { $suite->shouldReceive('setBeStrictAboutChangesToGlobalState'); } return $suite; } + /** + * Returns PHPUnit version. + * + * @return string + */ + protected function getPhpUnitVersion() + { + if ( \class_exists('PHPUnit\Runner\Version') ) { + return Version::id(); + } + + return \PHPUnit_Runner_Version::id(); + } + /** * Checks, that array has a desired structure & contents. * diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php index 3223dd1..6be3e48 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php @@ -12,13 +12,16 @@ namespace tests\aik099\PHPUnit\MinkDriver; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Mockery as m; -use PHPUnit\Framework\TestCase; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class DriverFactoryRegistryTest extends TestCase +class DriverFactoryRegistryTest extends AbstractPHPUnitCompatibilityTestCase { + use ExpectException; + /** * Driver factory registry. * @@ -26,10 +29,11 @@ class DriverFactoryRegistryTest extends TestCase */ private $_driverFactoryRegistry; - public function setUp() + /** + * @before + */ + public function setUpTest() { - parent::setUp(); - $this->_driverFactoryRegistry = new DriverFactoryRegistry(); } @@ -43,12 +47,11 @@ public function testAddingAndGetting() $this->assertSame($factory, $this->_driverFactoryRegistry->get('test')); } - /** - * @expectedException \LogicException - * @expectedExceptionMessage Driver factory for "test" driver is already registered. - */ public function testAddingExisting() { + $this->expectException('LogicException'); + $this->expectExceptionMessage('Driver factory for "test" driver is already registered.'); + $factory = m::mock('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); $factory->shouldReceive('getDriverName')->andReturn('test'); @@ -56,12 +59,11 @@ public function testAddingExisting() $this->_driverFactoryRegistry->add($factory); } - /** - * @expectedException \OutOfBoundsException - * @expectedExceptionMessage No driver factory for "test" driver. - */ public function testGettingNonExisting() { + $this->expectException('OutOfBoundsException'); + $this->expectExceptionMessage('No driver factory for "test" driver.'); + $this->_driverFactoryRegistry->get('test'); } diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php index 91dcb3f..ad4f2e1 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php @@ -12,15 +12,18 @@ namespace tests\aik099\PHPUnit\MinkDriver; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\DIContainer; use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; use Mockery as m; -use PHPUnit\Framework\TestCase; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class DriverFactoryTest extends TestCase +class DriverFactoryTest extends AbstractPHPUnitCompatibilityTestCase { + use ExpectException; + /** * @dataProvider driverDataProvider */ @@ -49,8 +52,8 @@ public function testMinkDriverMissingError($driver_class, $factory_class) $factory = new $factory_class(); $driver_class_parts = explode('\\', $driver_class); - $this->setExpectedException( - '\RuntimeException', + $this->expectException('RuntimeException'); + $this->expectExceptionMessage( 'Install Mink' . end($driver_class_parts) . ' in order to use ' . $factory->getDriverName() . ' driver.' ); $factory->createDriver($this->createBrowserConfiguration($factory)); diff --git a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php index 560570f..6140e2f 100644 --- a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php +++ b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php @@ -11,15 +11,20 @@ namespace tests\aik099\PHPUnit\RemoteCoverage; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteUrl; use Mockery as m; use Mockery\MockInterface; -use PHPUnit\Framework\TestCase; +use SebastianBergmann\CodeCoverage\RawCodeCoverageData; +use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class RemoteCoverageHelperTest extends TestCase +class RemoteCoverageHelperTest extends AbstractPHPUnitCompatibilityTestCase { + use ExpectException, AssertIsType; + /** * Remote URL. * @@ -37,12 +42,10 @@ class RemoteCoverageHelperTest extends TestCase /** * Prepares test. * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); - $this->_remoteUrl = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteUrl'); $this->_remoteCoverageHelper = new RemoteCoverageHelper($this->_remoteUrl); } @@ -55,10 +58,11 @@ protected function setUp() * * @return void * @dataProvider createUrlErrorDataProvider - * @expectedException \InvalidArgumentException */ public function testCreateUrlError($coverage_script_url, $test_id) { + $this->expectException('InvalidArgumentException'); + $this->_remoteCoverageHelper->get($coverage_script_url, $test_id); } @@ -95,8 +99,15 @@ public function testCreateUrl($coverage_script_url, $test_id, $expected_url) ->andReturn(false); $result = $this->_remoteCoverageHelper->get($coverage_script_url, $test_id); - $this->assertInternalType('array', $result); - $this->assertCount(0, $result); + + if ( \class_exists('\SebastianBergmann\CodeCoverage\RawCodeCoverageData') ) { + $this->assertInstanceOf('\SebastianBergmann\CodeCoverage\RawCodeCoverageData', $result); + $this->assertCount(0, $result->lineCoverage()); + } + else { + $this->assertIsArray($result); + $this->assertCount(0, $result); + } } /** @@ -116,10 +127,11 @@ public function createUrlDataProvider() * Test description. * * @return void - * @expectedException \RuntimeException */ public function testReturnedCoverageNotASerializedArray() { + $this->expectException('RuntimeException'); + $this->_remoteUrl ->shouldReceive('getPageContent') ->once() @@ -154,7 +166,12 @@ public function testValidCoverageIsReturned() 14 => 1, ); - $this->assertEquals($expected, $content[$class_source_file]); + if ( \class_exists('\SebastianBergmann\CodeCoverage\RawCodeCoverageData') ) { + $this->assertEquals(array($class_source_file => $expected), $content->lineCoverage()); + } + else { + $this->assertEquals($expected, $content[$class_source_file]); + } } } diff --git a/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php b/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php index 1eaad6e..2e3c1cb 100644 --- a/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php +++ b/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php @@ -11,10 +11,10 @@ namespace tests\aik099\PHPUnit\RemoteCoverage; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\RemoteCoverage\RemoteUrl; -use PHPUnit\Framework\TestCase; -class RemoteUrlTest extends TestCase +class RemoteUrlTest extends AbstractPHPUnitCompatibilityTestCase { /** diff --git a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php index c768be7..8648f79 100644 --- a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php @@ -17,6 +17,7 @@ use aik099\PHPUnit\Session\IsolatedSessionStrategy; use Mockery as m; use Mockery\MockInterface; +use aik099\PHPUnit\Framework\TestResult; class IsolatedSessionStrategyTest extends SessionStrategyTestCase { @@ -29,16 +30,14 @@ class IsolatedSessionStrategyTest extends SessionStrategyTestCase private $_factory; /** - * Creates session strategy. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { $this->_factory = m::mock('aik099\\PHPUnit\\Session\\ISessionFactory'); $this->strategy = new IsolatedSessionStrategy($this->_factory); - parent::setUp(); + parent::setUpTest(); } /** @@ -81,7 +80,7 @@ public function testOnTestEnd() BrowserTestCase::TEST_ENDED_EVENT, new TestEndedEvent( $test_case, - m::mock('PHPUnit_Framework_TestResult'), + new TestResult() /* Can't mock, because it's a final class. */, $session ) ); diff --git a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php index f22e5b3..45813d4 100644 --- a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php +++ b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\Session; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Session\SessionFactory; use Mockery as m; -use PHPUnit\Framework\TestCase; -class SessionFactoryTest extends TestCase +class SessionFactoryTest extends AbstractPHPUnitCompatibilityTestCase { /** @@ -26,14 +26,10 @@ class SessionFactoryTest extends TestCase private $_factory; /** - * Creates session strategy. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); - $this->_factory = new SessionFactory(); } diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php index 874b852..7106fb1 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php @@ -15,10 +15,13 @@ use aik099\PHPUnit\Session\SessionStrategyFactory; use Mockery as m; use tests\aik099\PHPUnit\TestCase\ApplicationAwareTestCase; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; class SessionStrategyFactoryTest extends ApplicationAwareTestCase { + use ExpectException; + /** * Session factory. * @@ -27,13 +30,11 @@ class SessionStrategyFactoryTest extends ApplicationAwareTestCase private $_factory; /** - * Creates session strategy. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); + parent::setUpTest(); $this->_factory = new SessionStrategyFactory(); $this->_factory->setApplication($this->application); @@ -72,10 +73,11 @@ public function createStrategyDataProvider() * Test description. * * @return void - * @expectedException \InvalidArgumentException */ public function testCreateStrategyFailure() { + $this->expectException('InvalidArgumentException'); + $this->_factory->createStrategy('wrong'); } diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php index e41cd4c..b6d4ee9 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php @@ -11,14 +11,14 @@ namespace tests\aik099\PHPUnit\Session; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Session\ISessionStrategy; use aik099\PHPUnit\Session\ISessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyManager; use Mockery as m; -use PHPUnit\Framework\TestCase; -class SessionStrategyManagerTest extends TestCase +class SessionStrategyManagerTest extends AbstractPHPUnitCompatibilityTestCase { /** @@ -36,14 +36,10 @@ class SessionStrategyManagerTest extends TestCase protected $factory; /** - * Creates session strategy manager to use for tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); - $this->factory = m::mock('aik099\\PHPUnit\\Session\\ISessionStrategyFactory'); $this->manager = new SessionStrategyManager($this->factory); } diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php b/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php index 91d5089..d0955c9 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\Session; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Session\ISessionStrategy; -use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcher; -class SessionStrategyTestCase extends TestCase +class SessionStrategyTestCase extends AbstractPHPUnitCompatibilityTestCase { const BROWSER_CLASS = '\\aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; @@ -39,14 +39,10 @@ class SessionStrategyTestCase extends TestCase protected $strategy; /** - * Configures all tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); - $this->eventDispatcher = new EventDispatcher(); $this->strategy->setEventDispatcher($this->eventDispatcher); } diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index a5eb02f..629d950 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -20,6 +20,8 @@ use Behat\Mink\Session; use Mockery as m; use Mockery\MockInterface; +use aik099\PHPUnit\Framework\IncompleteTestError; +use aik099\PHPUnit\Framework\SkippedTestError; class SharedSessionStrategyTest extends SessionStrategyTestCase { @@ -46,11 +48,9 @@ class SharedSessionStrategyTest extends SessionStrategyTestCase private $_session2; /** - * Creates session strategy. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { $this->_session1 = $this->createSession(); $this->_session2 = $this->createSession(); @@ -58,7 +58,7 @@ protected function setUp() $this->_isolatedStrategy = m::mock('\\aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'); $this->strategy = new SharedSessionStrategy($this->_isolatedStrategy); - parent::setUp(); + parent::setUpTest(); } /** @@ -95,8 +95,8 @@ public function ignoreExceptionDataProvider() { return array( array(null), - array(new \PHPUnit_Framework_IncompleteTestError()), - array(new \PHPUnit_Framework_SkippedTestError()), + array(new IncompleteTestError()), + array(new SkippedTestError()), ); } diff --git a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php index 6c83dca..8429b8c 100644 --- a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php +++ b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php @@ -11,12 +11,12 @@ namespace tests\aik099\PHPUnit\TestCase; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Application; use Mockery\MockInterface; use Mockery as m; -use PHPUnit\Framework\TestCase; -class ApplicationAwareTestCase extends TestCase +class ApplicationAwareTestCase extends AbstractPHPUnitCompatibilityTestCase { /** @@ -27,14 +27,10 @@ class ApplicationAwareTestCase extends TestCase protected $application; /** - * Configures the tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); - $this->application = m::mock('aik099\\PHPUnit\\Application'); } diff --git a/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php index d496615..27a8281 100644 --- a/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php +++ b/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php @@ -11,12 +11,12 @@ namespace tests\aik099\PHPUnit\TestCase; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use Mockery\MockInterface; use Mockery as m; -use PHPUnit\Framework\TestCase; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -class EventDispatcherAwareTestCase extends TestCase +class EventDispatcherAwareTestCase extends AbstractPHPUnitCompatibilityTestCase { /** @@ -27,14 +27,10 @@ class EventDispatcherAwareTestCase extends TestCase protected $eventDispatcher; /** - * Configures the tests. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); - $this->eventDispatcher = m::mock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); } diff --git a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php index 303d713..4fa3f24 100644 --- a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php @@ -26,13 +26,11 @@ class BrowserTestSuiteTest extends EventDispatcherAwareTestCase private $_suite; /** - * Creates suite for testing. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); + parent::setUpTest(); $this->_suite = new BrowserTestSuite(); $this->_suite->setEventDispatcher($this->eventDispatcher); @@ -77,7 +75,7 @@ public function nameFromBrowserDataProvider() public function testSetBrowserFromConfiguration() { $browser = array('name' => 'safari'); - $test = m::mock('PHPUnit_Framework_Test'); + $test = m::mock('\\aik099\\PHPUnit\\Framework\\Test'); $test->shouldReceive('setBrowserFromConfiguration')->with($browser)->once(); $this->_suite->addTest($test); diff --git a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php index 730e15e..4b910e8 100644 --- a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php @@ -43,7 +43,7 @@ public function testSetTestDependencies() $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); $helper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); - $test = m::mock('PHPUnit_Framework_Test'); + $test = m::mock('\\aik099\\PHPUnit\\Framework\\Test'); $test->shouldReceive('setEventDispatcher')->with($this->eventDispatcher)->once(); $test->shouldReceive('setSessionStrategyManager')->with($manager)->once(); $test->shouldReceive('setBrowserConfigurationFactory')->with($factory)->once(); diff --git a/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php b/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php index 43b992c..f3c2da6 100644 --- a/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php +++ b/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php @@ -51,13 +51,11 @@ class TestSuiteFactoryTest extends ApplicationAwareTestCase private $_remoteCoverageHelper; /** - * Creates suite for testing. - * - * @return void + * @before */ - protected function setUp() + protected function setUpTest() { - parent::setUp(); + parent::setUpTest(); $this->_manager = m::mock('aik099\\PHPUnit\\Session\\SessionStrategyManager'); $this->_browserFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); From 2f80d83eb1ed7da1c5c96b1eb7bab6687193493e Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 24 Nov 2022 17:03:10 +0200 Subject: [PATCH 127/204] Prepare 2.3.0 release --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b64a02e..39c4bfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added ... +### Changed +... + +### Fixed +... + +## [2.3.0] - 2022-11-24 ### Changed - Bumped minimum PHPUnit version to 4.8.35 or 5.4.3. - Lifted restriction on used PHPUnit version. From ac1b2570be5106c5d17d7abce872bebc7ce8dacc Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 24 Nov 2022 19:11:34 +0200 Subject: [PATCH 128/204] Updated setup method name in the documentation --- docs/configuration.rst | 4 ++-- docs/remote-code-coverage.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index a65ff2d..65175d4 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -6,7 +6,7 @@ All possible ways of browser configuration are described below. Per Test Configuration ^^^^^^^^^^^^^^^^^^^^^^ It is possible to configure browser individually for each test within a test case by creating -an instance of ``\aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration`` class in ``setUp`` +an instance of ``\aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration`` class in ``setUpTest`` method in of test case class and setting it via ``setBrowser`` method. .. literalinclude:: examples/configuration/config_via_setup_method.php @@ -69,6 +69,6 @@ Name Description ======================= ================================================================================================== There are also corresponding setters (e.g. ``setHost``) and getters (e.g. ``getHost``) for each of mentioned -above settings, that allow to individually change them from ``setUp`` method before test has started. +above settings, that allow to individually change them from ``setUpTest`` method before test has started. .. _`Mink`: https://github.com/Behat/Mink diff --git a/docs/remote-code-coverage.rst b/docs/remote-code-coverage.rst index 9a12e81..6d7c10e 100644 --- a/docs/remote-code-coverage.rst +++ b/docs/remote-code-coverage.rst @@ -23,7 +23,7 @@ On Test Machine ^^^^^^^^^^^^^^^ This is machine, where PHPUnit tests are being executed. -Following code needs to be placed in the ``setUp`` method of the test case class (that extends ``BrowserTestCase`` +Following code needs to be placed in the ``setUpTest`` method of the test case class (that extends ``BrowserTestCase`` class) to enable remote coverage information collection: .. code-block:: php From 75d946fe26508d96c17e9c210217342258def1cc Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 14:47:05 +0200 Subject: [PATCH 129/204] Bump PHP version to 5.6 --- .github/workflows/tests.yml | 6 +- CHANGELOG.md | 2 +- composer.json | 2 +- composer.lock | 825 ++++++++++++++++++++++++++++++------ 4 files changed, 690 insertions(+), 145 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4b724b3..7fd54cd 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - php: [ '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1' ] + php: [ '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1' ] with_coverage: [ false ] include: - php: '7.4' @@ -31,12 +31,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: 2 - name: Setup PHP - uses: shivammathur/setup-php@2.21.2 + uses: shivammathur/setup-php@v2 with: coverage: "xdebug" php-version: "${{ matrix.php }}" diff --git a/CHANGELOG.md b/CHANGELOG.md index 39c4bfb..3cafd69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ... ### Changed -... +- Bumped minimum PHP version to 5.6. ### Fixed ... diff --git a/composer.json b/composer.json index cf47956..a78944d 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ ], "require": { - "php": ">=5.4.7", + "php": ">=5.6", "behat/mink": "~1.6@dev", "behat/mink-selenium2-driver": "~1.2", "symfony/event-dispatcher": "~2.4|~3.0", diff --git a/composer.lock b/composer.lock index 95d9641..8c8ef67 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1264a9c8ae73b9b4c307e3f2fd97da17", + "content-hash": "c892952697bda295a3aa6a24532c8e84", "packages": [ { "name": "behat/mink", @@ -66,6 +66,10 @@ "testing", "web" ], + "support": { + "issues": "https://github.com/minkphp/Mink/issues", + "source": "https://github.com/minkphp/Mink/tree/v1.9.0" + }, "time": "2021-10-11T11:58:47+00:00" }, { @@ -127,6 +131,10 @@ "testing", "webdriver" ], + "support": { + "issues": "https://github.com/minkphp/MinkSelenium2Driver/issues", + "source": "https://github.com/minkphp/MinkSelenium2Driver/tree/v1.5.0" + }, "time": "2021-10-12T16:01:47+00:00" }, { @@ -181,20 +189,38 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.0.5" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], "time": "2015-06-14T21:17:01+00:00" }, { "name": "instaclick/php-webdriver", - "version": "1.4.16", + "version": "1.4.18", "source": { "type": "git", "url": "https://github.com/instaclick/php-webdriver.git", - "reference": "a39a1f6dc0f4ddd8b2438fa5eb1f67755730d606" + "reference": "a61a8459f86c79dd1f19934ea3929804f2e41f8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/a39a1f6dc0f4ddd8b2438fa5eb1f67755730d606", - "reference": "a39a1f6dc0f4ddd8b2438fa5eb1f67755730d606", + "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/a61a8459f86c79dd1f19934ea3929804f2e41f8c", + "reference": "a61a8459f86c79dd1f19934ea3929804f2e41f8c", "shasum": "" }, "require": { @@ -240,41 +266,199 @@ "webdriver", "webtest" ], - "time": "2022-10-28T13:30:35+00:00" + "support": { + "issues": "https://github.com/instaclick/php-webdriver/issues", + "source": "https://github.com/instaclick/php-webdriver/tree/1.4.18" + }, + "time": "2023-12-08T07:11:19+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.x" + }, + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master" + }, + "time": "2017-09-11T18:02:19+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "2.0.5", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b" + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b", - "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.6 || ^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" }, - "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/3.x" + }, + "time": "2017-11-10T14:09:06+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { - "psr-0": { - "phpDocumentor": [ + "psr-4": { + "phpDocumentor\\Reflection\\": [ "src/" ] } @@ -286,10 +470,14 @@ "authors": [ { "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" + "email": "me@mikevanriel.com" } ], - "time": "2016-01-25T08:17:30+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/master" + }, + "time": "2017-07-14T14:27:02+00:00" }, { "name": "phpspec/prophecy", @@ -352,43 +540,48 @@ "spy", "stub" ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" + }, "time": "2020-03-05T15:02:03+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "2.2.4", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", "shasum": "" }, "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.2 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "^1.0 || ^2.0" }, "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" + "ext-xdebug": "^2.1.4", + "phpunit/phpunit": "^5.7" }, "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" + "ext-xdebug": "^2.5.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2.x-dev" + "dev-master": "4.0.x-dev" } }, "autoload": { @@ -414,7 +607,12 @@ "testing", "xunit" ], - "time": "2015-10-06T15:47:00+00:00" + "support": { + "irc": "irc://irc.freenode.net/phpunit", + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/4.0" + }, + "time": "2017-04-02T07:44:40+00:00" }, { "name": "phpunit/php-file-iterator", @@ -461,6 +659,11 @@ "filesystem", "iterator" ], + "support": { + "irc": "irc://irc.freenode.net/phpunit", + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5" + }, "time": "2017-11-27T13:52:08+00:00" }, { @@ -502,6 +705,10 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + }, "time": "2015-06-21T13:50:34+00:00" }, { @@ -551,6 +758,10 @@ "keywords": [ "timer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/master" + }, "time": "2017-02-26T11:10:40+00:00" }, { @@ -600,45 +811,59 @@ "keywords": [ "tokenizer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/1.4" + }, "abandoned": true, "time": "2017-12-04T08:55:13+00:00" }, { "name": "phpunit/phpunit", - "version": "4.8.36", + "version": "5.7.27", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", "shasum": "" }, "require": { "ext-dom": "*", "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.4", "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.2.2", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "^1.2.4", + "sebastian/diff": "^1.4.3", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.1", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "^1.0.6|^2.0.1", + "symfony/yaml": "~2.1|~3.0|~4.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" }, "suggest": { + "ext-xdebug": "*", "phpunit/php-invoker": "~1.1" }, "bin": [ @@ -647,7 +872,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.8.x-dev" + "dev-master": "5.7.x-dev" } }, "autoload": { @@ -673,30 +898,37 @@ "testing", "xunit" ], - "time": "2017-06-21T08:07:12+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/5.7.27" + }, + "time": "2018-02-01T05:50:59+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^5.4" }, "suggest": { "ext-soap": "*" @@ -704,7 +936,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3.x-dev" + "dev-master": "3.2.x-dev" } }, "autoload": { @@ -729,8 +961,68 @@ "mock", "xunit" ], + "support": { + "irc": "irc://irc.freenode.net/phpunit", + "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues", + "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/3.4" + }, "abandoned": true, - "time": "2015-10-02T06:51:40+00:00" + "time": "2017-06-30T09:13:00+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-30T08:15:22+00:00" }, { "name": "sebastian/comparator", @@ -794,6 +1086,10 @@ "compare", "equality" ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/1.2" + }, "time": "2017-01-29T09:50:25+00:00" }, { @@ -846,32 +1142,36 @@ "keywords": [ "diff" ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/1.4" + }, "time": "2017-05-22T07:24:03+00:00" }, { "name": "sebastian/environment", - "version": "1.3.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" + "phpunit/phpunit": "^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -896,25 +1196,29 @@ "environment", "hhvm" ], - "time": "2016-08-18T05:49:44+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/master" + }, + "time": "2016-11-26T07:53:53+00:00" }, { "name": "sebastian/exporter", - "version": "1.2.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", "shasum": "" }, "require": { "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" + "sebastian/recursion-context": "~2.0" }, "require-dev": { "ext-mbstring": "*", @@ -923,7 +1227,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -963,7 +1267,11 @@ "export", "exporter" ], - "time": "2016-06-17T09:04:28+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/master" + }, + "time": "2016-11-19T08:54:04+00:00" }, { "name": "sebastian/global-state", @@ -1014,20 +1322,74 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/1.1.1" + }, "time": "2015-10-12T03:26:01+00:00" }, + { + "name": "sebastian/object-enumerator", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/master" + }, + "time": "2017-02-18T15:18:39+00:00" + }, { "name": "sebastian/recursion-context", - "version": "1.0.5", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", "shasum": "" }, "require": { @@ -1039,7 +1401,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1067,23 +1429,81 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2016-10-03T07:41:43+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/master" + }, + "time": "2016-11-19T07:33:16+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/master" + }, + "time": "2015-07-28T20:34:47+00:00" }, { "name": "sebastian/version", - "version": "1.0.6", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, + "require": { + "php": ">=5.6" + }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -1102,31 +1522,30 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-06-21T13:59:46+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/master" + }, + "time": "2016-10-03T07:35:21+00:00" }, { "name": "symfony/css-selector", - "version": "v2.8.52", + "version": "v3.4.47", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "7b1692e418d7ccac24c373528453bc90e42797de" + "reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/7b1692e418d7ccac24c373528453bc90e42797de", - "reference": "7b1692e418d7ccac24c373528453bc90e42797de", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/da3d9da2ce0026771f5fe64cb332158f1bd2bc33", + "reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^5.5.9|>=7.0.8" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\CssSelector\\": "" @@ -1155,42 +1574,58 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2018-11-11T11:18:13+00:00" + "support": { + "source": "https://github.com/symfony/css-selector/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.52", + "version": "v3.4.47", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0" + "reference": "31fde73757b6bad247c54597beef974919ec6860" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a77e974a5fecb4398833b0709210e3d5e334ffb0", - "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/31fde73757b6bad247c54597beef974919ec6860", + "reference": "31fde73757b6bad247c54597beef974919ec6860", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": "^5.5.9|>=7.0.8" + }, + "conflict": { + "symfony/dependency-injection": "<3.3" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "^2.0.5|~3.0.0", - "symfony/dependency-injection": "~2.6|~3.0.0", - "symfony/expression-language": "~2.6|~3.0.0", - "symfony/stopwatch": "~2.3|~3.0.0" + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/debug": "~3.4|~4.4", + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/stopwatch": "~2.8|~3.0|~4.0" }, "suggest": { "symfony/dependency-injection": "", "symfony/http-kernel": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" @@ -1215,7 +1650,24 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2018-11-21T14:20:20+00:00" + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1277,6 +1729,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1295,28 +1750,32 @@ }, { "name": "symfony/yaml", - "version": "v2.8.52", + "version": "v3.4.47", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "02c1859112aa779d9ab394ae4f3381911d84052b" + "reference": "88289caa3c166321883f67fe5130188ebbb47094" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/02c1859112aa779d9ab394ae4f3381911d84052b", - "reference": "02c1859112aa779d9ab394ae4f3381911d84052b", + "url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094", + "reference": "88289caa3c166321883f67fe5130188ebbb47094", "shasum": "" }, "require": { - "php": ">=5.3.9", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-ctype": "~1.8" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" @@ -1341,7 +1800,77 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-11-11T11:18:13+00:00" + "support": { + "source": "https://github.com/symfony/yaml/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.9.1" + }, + "time": "2020-07-08T17:02:28+00:00" } ], "packages-dev": [ @@ -1363,6 +1892,7 @@ "squizlabs/php_codesniffer": "^3.0", "yoast/phpunit-polyfills": "^1.0" }, + "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -1384,6 +1914,10 @@ "PHP_CodeSniffer", "codesniffer" ], + "support": { + "issues": "https://github.com/aik099/CodingStandard/issues", + "source": "https://github.com/aik099/CodingStandard/tree/master" + }, "time": "2021-11-07T16:55:51+00:00" }, { @@ -1429,6 +1963,10 @@ "keywords": [ "test" ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/master" + }, "time": "2015-05-11T14:41:42+00:00" }, { @@ -1494,20 +2032,24 @@ "test double", "testing" ], + "support": { + "issues": "https://github.com/mockery/mockery/issues", + "source": "https://github.com/mockery/mockery/tree/0.9" + }, "time": "2019-02-12T16:07:13+00:00" }, { "name": "yoast/phpunit-polyfills", - "version": "1.0.3", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", - "reference": "5ea3536428944955f969bc764bbe09738e151ada" + "reference": "224e4a1329c03d8bad520e3fc4ec980034a4b212" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/5ea3536428944955f969bc764bbe09738e151ada", - "reference": "5ea3536428944955f969bc764bbe09738e151ada", + "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/224e4a1329c03d8bad520e3fc4ec980034a4b212", + "reference": "224e4a1329c03d8bad520e3fc4ec980034a4b212", "shasum": "" }, "require": { @@ -1515,13 +2057,12 @@ "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, "require-dev": { - "yoast/yoastcs": "^2.2.0" + "yoast/yoastcs": "^2.3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.x-dev", - "dev-develop": "1.x-dev" + "dev-main": "2.x-dev" } }, "autoload": { @@ -1551,7 +2092,11 @@ "polyfill", "testing" ], - "time": "2021-11-23T01:37:03+00:00" + "support": { + "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues", + "source": "https://github.com/Yoast/PHPUnit-Polyfills" + }, + "time": "2023-08-19T14:25:08+00:00" } ], "aliases": [], @@ -1563,8 +2108,8 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.4.7" + "php": ">=5.6" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.2.0" } From f02d83845fdad7c4e8688343e15e781fdc23d229 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 18:13:48 +0200 Subject: [PATCH 130/204] Improve test error reporting (get nice error messages instead of "Failed asserting that two arrays are identical.") --- .../ApiBrowserConfigurationTestCase.php | 2 +- .../BrowserConfigurationTest.php | 24 +++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 7712012..d26b620 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -182,7 +182,7 @@ public function testSetDesiredCapabilitiesCorrect(array $desired_capabilities = $browser->setApiKey('B'); $this->assertSame($browser, $browser->setDesiredCapabilities($desired_capabilities)); - $this->assertSame($expected, $browser->getDesiredCapabilities()); + $this->assertSame($expected, $browser->getDesiredCapabilities(), 'Failed changing the desired capabilities.'); } /** diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index d188f56..fd62075 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -289,11 +289,19 @@ public function testSetup() $this->assertSame($this->setup['port'], $this->browser->getPort()); $this->assertSame($this->setup['timeout'], $this->browser->getTimeout()); $this->assertSame($this->setup['browserName'], $this->browser->getBrowserName()); - $this->assertSame($this->setup['desiredCapabilities'], $this->browser->getDesiredCapabilities()); + $this->assertSame( + $this->setup['desiredCapabilities'], + $this->browser->getDesiredCapabilities(), + 'The browser\'s desired capabilities weren\'t set to the test case.' + ); $this->assertSame($this->setup['baseUrl'], $this->browser->getBaseUrl()); $this->assertSame($this->setup['sessionStrategy'], $this->browser->getSessionStrategy()); $this->assertSame($this->setup['driver'], $this->browser->getDriver()); - $this->assertSame($this->setup['driverOptions'], $this->browser->getDriverOptions()); + $this->assertSame( + $this->setup['driverOptions'], + $this->browser->getDriverOptions(), + 'The browser\'s driver options weren\'t set to the test case.' + ); } /** @@ -334,7 +342,11 @@ public function testSetDriverOptionsCorrect() $expected_driver_options = array('driverParam1' => 'driverParamValue1') + $user_driver_options; $this->assertSame($this->browser, $this->browser->setDriverOptions($user_driver_options)); - $this->assertSame($expected_driver_options, $this->browser->getDriverOptions()); + $this->assertSame( + $expected_driver_options, + $this->browser->getDriverOptions(), + 'The browser driver options wren\'t set correctly.' + ); } public function testDriverFactoryDefaultsApplied() @@ -453,7 +465,11 @@ public function testSetDesiredCapabilitiesCorrect(array $desired_capabilities = { $expected = array('k1' => 'v1', 'k2' => 'v2'); $this->assertSame($this->browser, $this->browser->setDesiredCapabilities($expected)); - $this->assertSame($expected, $this->browser->getDesiredCapabilities()); + $this->assertSame( + $expected, + $this->browser->getDesiredCapabilities(), + 'The browser desired capabilities wren\'t set correctly.' + ); } /** From 000265bc9ec51001159250b22ddec84e7217ef85 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 18:22:34 +0200 Subject: [PATCH 131/204] Group API-based browser configuration integration tests by a build number --- phpunit.xml.dist | 2 +- .../aik099/PHPUnit/Fixture/ApiIntegrationFixture.php | 4 ++-- .../aik099/PHPUnit/Integration/DataProviderTest.php | 12 ++++++++++++ .../Integration/IsolatedSessionStrategyTest.php | 3 ++- .../PHPUnit/Integration/SauceLabsAwareTestCase.php | 6 ++++-- .../Integration/SharedSessionStrategyTest.php | 3 ++- tests/bootstrap.php | 5 +++++ 7 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 tests/bootstrap.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c369cab..65120c7 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,6 +1,6 @@ getenv('SAUCE_ACCESS_KEY'), 'browserName' => 'chrome', - 'desiredCapabilities' => array('version' => 38), + 'desiredCapabilities' => array('build' => BUILD_NAME, 'version' => 38), 'baseUrl' => 'http://www.google.com', ), 'browserstack' => array( @@ -222,7 +222,7 @@ public function getBrowserAliases() 'api_key' => getenv('BS_ACCESS_KEY'), 'browserName' => 'chrome', - 'desiredCapabilities' => array('browser_version' => '38.0', 'project' => 'PHPUnit-Mink'), + 'desiredCapabilities' => array('build' => BUILD_NAME, 'browser_version' => '38.0'), ), ); } diff --git a/tests/aik099/PHPUnit/Integration/DataProviderTest.php b/tests/aik099/PHPUnit/Integration/DataProviderTest.php index ae24a49..344b5e2 100644 --- a/tests/aik099/PHPUnit/Integration/DataProviderTest.php +++ b/tests/aik099/PHPUnit/Integration/DataProviderTest.php @@ -14,6 +14,18 @@ class DataProviderTest extends SauceLabsAwareTestCase { + /** + * Browser list to be used in tests. + * + * @var array + */ + public static $browsers = array( + array( + 'alias' => 'default', + 'desiredCapabilities' => array('build' => BUILD_NAME, 'name' => 'DataProviderTest'), + ), + ); + public function sampleDataProvider() { return array( diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index 77df275..adfbc90 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -25,8 +25,9 @@ class IsolatedSessionStrategyTest extends SauceLabsAwareTestCase */ public static $browsers = array( array( - 'alias' => 'saucelabs', + 'alias' => 'default', 'sessionStrategy' => 'isolated', + 'desiredCapabilities' => array('build' => BUILD_NAME, 'name' => 'IsolatedSessionStrategyTest'), ), ); diff --git a/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php b/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php index 28f3b4e..129e350 100644 --- a/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php +++ b/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php @@ -22,7 +22,9 @@ abstract class SauceLabsAwareTestCase extends BrowserTestCase * @var array */ public static $browsers = array( - array('alias' => 'saucelabs'), + array( + 'alias' => 'default', + ), ); /** @@ -57,7 +59,7 @@ public function getCollectCodeCoverageInformation() public function getBrowserAliases() { return array( - 'saucelabs' => array( + 'default' => array( 'type' => 'saucelabs', 'apiUsername' => getenv('SAUCE_USERNAME'), 'apiKey' => getenv('SAUCE_ACCESS_KEY'), diff --git a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php index 5b4c4a4..c64eb1d 100644 --- a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php @@ -25,8 +25,9 @@ class SharedSessionStrategyTest extends SauceLabsAwareTestCase */ public static $browsers = array( array( - 'alias' => 'saucelabs', + 'alias' => 'default', 'sessionStrategy' => 'shared', + 'desiredCapabilities' => array('build' => BUILD_NAME, 'name' => 'SharedSessionStrategyTest'), ), ); diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000..3824972 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,5 @@ + Date: Thu, 15 Feb 2024 19:16:19 +0200 Subject: [PATCH 132/204] Run integration tests on BrowserStack instead of SauceLabs --- ...eTestCase.php => BrowserStackAwareTestCase.php} | 14 +++++++------- .../PHPUnit/Integration/DataProviderTest.php | 2 +- .../Integration/IsolatedSessionStrategyTest.php | 2 +- .../Integration/SharedSessionStrategyTest.php | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) rename tests/aik099/PHPUnit/Integration/{SauceLabsAwareTestCase.php => BrowserStackAwareTestCase.php} (76%) diff --git a/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php similarity index 76% rename from tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php rename to tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php index 129e350..c0d6c1b 100644 --- a/tests/aik099/PHPUnit/Integration/SauceLabsAwareTestCase.php +++ b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php @@ -13,7 +13,7 @@ use aik099\PHPUnit\BrowserTestCase; -abstract class SauceLabsAwareTestCase extends BrowserTestCase +abstract class BrowserStackAwareTestCase extends BrowserTestCase { /** @@ -32,8 +32,8 @@ abstract class SauceLabsAwareTestCase extends BrowserTestCase */ protected function setUpTest() { - if ( !getenv('SAUCE_USERNAME') || !getenv('SAUCE_ACCESS_KEY') ) { - $this->markTestSkipped('SauceLabs integration is not configured'); + if ( !getenv('BS_USERNAME') || !getenv('BS_ACCESS_KEY') ) { + $this->markTestSkipped('BrowserStack integration is not configured'); } } @@ -60,12 +60,12 @@ public function getBrowserAliases() { return array( 'default' => array( - 'type' => 'saucelabs', - 'apiUsername' => getenv('SAUCE_USERNAME'), - 'apiKey' => getenv('SAUCE_ACCESS_KEY'), + 'type' => 'browserstack', + 'api_username' => getenv('BS_USERNAME'), + 'api_key' => getenv('BS_ACCESS_KEY'), 'browserName' => 'chrome', - 'desiredCapabilities' => array('version' => 28), + 'desiredCapabilities' => array('browser_version' => 110), 'baseUrl' => 'http://www.google.com', ), ); diff --git a/tests/aik099/PHPUnit/Integration/DataProviderTest.php b/tests/aik099/PHPUnit/Integration/DataProviderTest.php index 344b5e2..aeeaed0 100644 --- a/tests/aik099/PHPUnit/Integration/DataProviderTest.php +++ b/tests/aik099/PHPUnit/Integration/DataProviderTest.php @@ -11,7 +11,7 @@ namespace tests\aik099\PHPUnit\Integration; -class DataProviderTest extends SauceLabsAwareTestCase +class DataProviderTest extends BrowserStackAwareTestCase { /** diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index adfbc90..65a46bc 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -13,7 +13,7 @@ use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains; -class IsolatedSessionStrategyTest extends SauceLabsAwareTestCase +class IsolatedSessionStrategyTest extends BrowserStackAwareTestCase { use AssertStringContains; diff --git a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php index c64eb1d..939ef6d 100644 --- a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php @@ -13,7 +13,7 @@ use Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains; -class SharedSessionStrategyTest extends SauceLabsAwareTestCase +class SharedSessionStrategyTest extends BrowserStackAwareTestCase { use AssertStringContains; From 952d29834849ed4eb2d9593a1126108cb95f89f2 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 19:19:57 +0200 Subject: [PATCH 133/204] Use Chrome 28 on Windows 7 for Integration tests --- tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php index c0d6c1b..5e2239d 100644 --- a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php +++ b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php @@ -65,7 +65,7 @@ public function getBrowserAliases() 'api_key' => getenv('BS_ACCESS_KEY'), 'browserName' => 'chrome', - 'desiredCapabilities' => array('browser_version' => 110), + 'desiredCapabilities' => array('browser_version' => 28), 'baseUrl' => 'http://www.google.com', ), ); From 241ea5230f7e002ea2739cc6aed783e1e3fbc77f Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 19:36:18 +0200 Subject: [PATCH 134/204] Changed default BrowserStack/SauceLabs OS to "Windows 10" --- CHANGELOG.md | 1 + .../BrowserStackBrowserConfiguration.php | 3 ++- .../BrowserConfiguration/SauceLabsBrowserConfiguration.php | 6 +----- .../BrowserConfiguration/BrowserConfigurationTest.php | 2 +- .../BrowserStackBrowserConfigurationTest.php | 2 +- .../SauceLabsBrowserConfigurationTest.php | 7 +++++-- tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php | 4 ++-- .../PHPUnit/Integration/BrowserStackAwareTestCase.php | 2 +- 8 files changed, 14 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cafd69..5f06311 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Bumped minimum PHP version to 5.6. +- Changed default OS from "Windows 7" to "Windows 10" for BrowserStack/SauceLabs browser configurations. ### Fixed ... diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php index fcec94c..f148344 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php @@ -80,6 +80,7 @@ public function getHost() * * @return array * @link http://www.browserstack.com/automate/capabilities + * @link https://www.browserstack.com/docs/automate/selenium/select-browsers-and-devices#Selenium_Legacy_JSON */ public function getDesiredCapabilities() { @@ -87,7 +88,7 @@ public function getDesiredCapabilities() if ( !isset($capabilities['os']) ) { $capabilities['os'] = 'Windows'; - $capabilities['os_version'] = '7'; + $capabilities['os_version'] = '10'; } if ( !isset($capabilities['acceptSslCerts']) ) { diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 02ebf8b..fa24d16 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -81,11 +81,7 @@ public function getDesiredCapabilities() $capabilities = parent::getDesiredCapabilities(); if ( !isset($capabilities['platform']) ) { - $capabilities['platform'] = 'Windows 7'; - } - - if ( !isset($capabilities['version']) ) { - $capabilities['version'] = ''; + $capabilities['platform'] = 'Windows 10'; } return $capabilities; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index fd62075..0673c35 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -107,7 +107,7 @@ protected function setUpTest() 'port' => self::PORT, 'timeout' => 500, 'browserName' => 'safari', - 'desiredCapabilities' => array('platform' => 'Windows 7', 'version' => 10), + 'desiredCapabilities' => array('platform' => 'Windows 10', 'version' => 10), 'baseUrl' => 'http://other-host', 'sessionStrategy' => ISessionStrategyFactory::TYPE_SHARED, 'driver' => 'zombie', diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php index 4e6f60e..ad9f675 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -73,7 +73,7 @@ public function desiredCapabilitiesDataProvider() ), array( array('acceptSslCerts' => 'false'), - array('acceptSslCerts' => 'false', 'os' => 'Windows', 'os_version' => '7'), + array('acceptSslCerts' => 'false', 'os' => 'Windows', 'os_version' => '10'), ), ); } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index ccbd3ec..6142d38 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -31,6 +31,9 @@ protected function setUpTest() parent::setUpTest(); + $this->setup['desiredCapabilities'] = array( + 'platform' => 'Windows 10', + ); $this->setup['host'] = 'UN:AK@ondemand.saucelabs.com'; } @@ -64,11 +67,11 @@ public function desiredCapabilitiesDataProvider() return array( array( array('platform' => 'pl1'), - array('platform' => 'pl1', 'version' => ''), + array('platform' => 'pl1',), ), array( array('version' => 'ver1'), - array('version' => 'ver1', 'platform' => 'Windows 7'), + array('version' => 'ver1', 'platform' => 'Windows 10'), ), ); } diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index e3d6dcd..7611a8b 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -213,7 +213,7 @@ public function getBrowserAliases() 'apiKey' => getenv('SAUCE_ACCESS_KEY'), 'browserName' => 'chrome', - 'desiredCapabilities' => array('build' => BUILD_NAME, 'version' => 38), + 'desiredCapabilities' => array('build' => BUILD_NAME, 'version' => 120), 'baseUrl' => 'http://www.google.com', ), 'browserstack' => array( @@ -222,7 +222,7 @@ public function getBrowserAliases() 'api_key' => getenv('BS_ACCESS_KEY'), 'browserName' => 'chrome', - 'desiredCapabilities' => array('build' => BUILD_NAME, 'browser_version' => '38.0'), + 'desiredCapabilities' => array('build' => BUILD_NAME, 'browser_version' => 120), ), ); } diff --git a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php index 5e2239d..c0d6c1b 100644 --- a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php +++ b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php @@ -65,7 +65,7 @@ public function getBrowserAliases() 'api_key' => getenv('BS_ACCESS_KEY'), 'browserName' => 'chrome', - 'desiredCapabilities' => array('browser_version' => 28), + 'desiredCapabilities' => array('browser_version' => 110), 'baseUrl' => 'http://www.google.com', ), ); From 6588a38b20295cb385081a4ec90841fad5d3efb7 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 19:43:40 +0200 Subject: [PATCH 135/204] Allow usage of self-signed/insecure SSL certificates with SauceLabs --- .../BrowserConfiguration/SauceLabsBrowserConfiguration.php | 4 ++++ .../SauceLabsBrowserConfigurationTest.php | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index fa24d16..4ec743c 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -84,6 +84,10 @@ public function getDesiredCapabilities() $capabilities['platform'] = 'Windows 10'; } + if ( !isset($capabilities['acceptInsecureCerts']) ) { + $capabilities['acceptInsecureCerts'] = true; + } + return $capabilities; } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 6142d38..2014411 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -32,7 +32,7 @@ protected function setUpTest() parent::setUpTest(); $this->setup['desiredCapabilities'] = array( - 'platform' => 'Windows 10', + 'platform' => 'Windows 10', 'acceptInsecureCerts' => true, ); $this->setup['host'] = 'UN:AK@ondemand.saucelabs.com'; } @@ -67,11 +67,11 @@ public function desiredCapabilitiesDataProvider() return array( array( array('platform' => 'pl1'), - array('platform' => 'pl1',), + array('platform' => 'pl1', 'acceptInsecureCerts' => true), ), array( array('version' => 'ver1'), - array('version' => 'ver1', 'platform' => 'Windows 10'), + array('version' => 'ver1', 'platform' => 'Windows 10', 'acceptInsecureCerts' => true), ), ); } From c9870f313ca874782598806e9fbc94de8d54d595 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 19:46:21 +0200 Subject: [PATCH 136/204] Actualized a changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f06311..755b37e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Bumped minimum PHP version to 5.6. - Changed default OS from "Windows 7" to "Windows 10" for BrowserStack/SauceLabs browser configurations. +- Allow using self-signed/invalid SSL certificates during testing on the SauceLabs by default. ### Fixed ... From 1935dc3c34d640ffd5d182f93e263b2de25b4c5d Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 20:16:20 +0200 Subject: [PATCH 137/204] Specify failed assertion message to BrowserStack/SauceLabs --- CHANGELOG.md | 2 +- .../APIClient/BrowserStackAPIClient.php | 12 +++++-- .../aik099/PHPUnit/APIClient/IAPIClient.php | 7 ++-- .../PHPUnit/APIClient/SauceLabsAPIClient.php | 18 +++++++--- .../ApiBrowserConfiguration.php | 3 +- .../BrowserConfiguration.php | 34 +++++++++++++++++++ .../ApiBrowserConfigurationTestCase.php | 3 +- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 26 +++++++++++++- 8 files changed, 91 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 755b37e..3a427b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added -... +- Specify failed PHPUnit assertion text to the BrowserStack ("reason" field)/SauceLabs("custom-data" field) test. ### Changed - Bumped minimum PHP version to 5.6. diff --git a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php index 0ec51f6..9798e7b 100644 --- a/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/BrowserStackAPIClient.php @@ -68,14 +68,20 @@ public function getInfo($session_id) /** * Update status of the test, that was executed in the given session. * - * @param string $session_id Session ID. - * @param boolean $test_status Test status. + * @param string $session_id Session ID. + * @param boolean $test_status Test status. + * @param string $test_status_message Test status message. * * @return array */ - public function updateStatus($session_id, $test_status) + public function updateStatus($session_id, $test_status, $test_status_message) { $data = array('status' => $test_status ? 'passed' : 'failed'); + + if ( $test_status_message ) { + $data['reason'] = $test_status_message; + } + $result = $this->execute('PUT', 'sessions/' . $session_id . '.json', $data); return $result['automation_session']; diff --git a/library/aik099/PHPUnit/APIClient/IAPIClient.php b/library/aik099/PHPUnit/APIClient/IAPIClient.php index 294ae98..19bc025 100644 --- a/library/aik099/PHPUnit/APIClient/IAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/IAPIClient.php @@ -29,11 +29,12 @@ public function getInfo($session_id); /** * Update status of the test, that was executed in the given session. * - * @param string $session_id Session ID. - * @param boolean $test_status Test status. + * @param string $session_id Session ID. + * @param boolean $test_status Test status. + * @param string $test_status_message Test status message. * * @return array */ - public function updateStatus($session_id, $test_status); + public function updateStatus($session_id, $test_status, $test_status_message); } diff --git a/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php b/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php index 4875292..448fd32 100644 --- a/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php +++ b/library/aik099/PHPUnit/APIClient/SauceLabsAPIClient.php @@ -13,6 +13,9 @@ use WebDriver\SauceLabs\SauceRest; +/** + * @link https://docs.saucelabs.com/dev/api/jobs/ + */ class SauceLabsAPIClient implements IAPIClient { @@ -48,14 +51,21 @@ public function getInfo($session_id) /** * Update status of the test, that was executed in the given session. * - * @param string $session_id Session ID. - * @param boolean $test_status Test status. + * @param string $session_id Session ID. + * @param boolean $test_status Test status. + * @param string $test_status_message Test status message. * * @return array */ - public function updateStatus($session_id, $test_status) + public function updateStatus($session_id, $test_status, $test_status_message) { - return $this->_sauceRest->updateJob($session_id, array('passed' => $test_status)); + $data = array('passed' => $test_status); + + if ( $test_status_message ) { + $data['custom-data'] = array('status_message' => $test_status_message); + } + + return $this->_sauceRest->updateJob($session_id, $data); } } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index 8649091..c8db3e6 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -206,7 +206,8 @@ public function onTestEnded(TestEndedEvent $event) $this->getAPIClient()->updateStatus( $this->getSessionId($session), - $this->getTestStatus($test_case, $event->getTestResult()) + $this->getTestStatus($test_case, $event->getTestResult()), + $this->getTestStatusMessage($test_case, $event->getTestResult()) ); } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 0bff67a..2ea425e 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -529,6 +529,40 @@ public function getTestStatus(BrowserTestCase $test_case, TestResult $test_resul return !$test_case->hasFailed(); } + /** + * Returns test status message based on session strategy requested by browser. + * + * @param BrowserTestCase $test_case Browser test case. + * @param TestResult $test_result Test result. + * + * @return boolean + * @see IsolatedSessionStrategy + * @see SharedSessionStrategy + */ + public function getTestStatusMessage(BrowserTestCase $test_case, TestResult $test_result) + { + if ( $this->isShared() ) { + // All tests in a test case use same session -> failed even if 1 test fails. + $test_failures = array(); + + if ( $test_result->errorCount() > 0 ) { + $test_failures = $test_result->errors(); + } + elseif ( $test_result->failureCount() > 0 ) { + $test_failures = $test_result->failures(); + } + elseif ( $test_result->warningCount() > 0 ) { + $test_failures = $test_result->warnings(); + } + + return $test_failures ? reset($test_failures)->exceptionMessage() : ''; + + } + + // Each test in a test case are using it's own session -> failed if test fails. + return $test_case->getStatusMessage(); + } + /** * Returns checksum from current configuration. * diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index d26b620..4feaf7b 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -308,8 +308,9 @@ public function testTestEndedEvent($driver_type) $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); $driver->shouldReceive('getWebDriverSessionId')->once()->andReturn('SID'); - $api_client->shouldReceive('updateStatus')->with('SID', true)->once(); + $api_client->shouldReceive('updateStatus')->with('SID', true, 'test status message')->once(); $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // For shared strategy. + $test_case->shouldReceive('getStatusMessage')->once()->andReturn('test status message'); // For shared strategy. } else { $driver = m::mock('\\Behat\\Mink\\Driver\\DriverInterface'); diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index 7611a8b..5c58a2a 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -125,6 +125,19 @@ public function verifyRemoteAPICalls(TestEvent $event) $session_info['passed'], 'SauceLabs test status set via API' ); + + $custom_data_mapping = array( + 'testSuccess' => null, + 'testFailure' => array( + 'status_message' => "This test is expected to fail.\nFailed asserting that false is true." + ), + ); + + $this->assertSame( + $custom_data_mapping[$test_name], + $session_info['custom-data'], + 'SauceLabs test status message set via API' + ); } elseif ( $browser instanceof BrowserStackBrowserConfiguration ) { $this->assertEquals( @@ -143,6 +156,17 @@ public function verifyRemoteAPICalls(TestEvent $event) $session_info['status'], 'BrowserStack test status set via API' ); + + $reason_mapping = array( + 'testSuccess' => '', + 'testFailure' => "This test is expected to fail.\nFailed asserting that false is true.", + ); + + $this->assertSame( + $reason_mapping[$test_name], + $session_info['reason'], + 'BrowserStack test status message set via API' + ); } } } @@ -194,7 +218,7 @@ public function testFailure() $session = $this->getSession(); $session->visit('http://www.google.com'); - $this->assertTrue(false); + $this->assertTrue(false, 'This test is expected to fail.'); } /** From 2d6de8a22f1dae1daab14854a0834d3459028c90 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 21:49:17 +0200 Subject: [PATCH 138/204] Fixes documentation build --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3d094ba..52ce33c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -18,12 +18,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: 2 - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 - name: Install dependencies run: | From 272aff50d4d1c6ee364e823cc7dcf6d3c87b5a4a Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 21:54:30 +0200 Subject: [PATCH 139/204] Add the ReadTheDocs.org config file --- .readthedocs.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..890f923 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,14 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.12" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + fail_on_warning: true From 518822cc29f510b79a73ad071991975428802e79 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 21:56:14 +0200 Subject: [PATCH 140/204] Changes to ReadTheDocs config should rebuild the docs now --- .github/workflows/docs.yml | 4 ++-- .github/workflows/tests.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 52ce33c..c98f6e0 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -2,9 +2,9 @@ name: Docs on: push: - paths: ['docs/**', '.github/workflows/docs.yml'] + paths: ['docs/**', '.github/workflows/docs.yml', '.readthedocs.yaml'] pull_request: - paths: ['docs/**', '.github/workflows/docs.yml'] + paths: ['docs/**', '.github/workflows/docs.yml', '.readthedocs.yaml'] defaults: run: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7fd54cd..cc0f153 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -2,9 +2,9 @@ name: CI on: push: - paths-ignore: ['docs/**', '.github/workflows/docs.yml'] + paths-ignore: ['docs/**', '.github/workflows/docs.yml', '.readthedocs.yaml'] pull_request: - paths-ignore: ['docs/**', '.github/workflows/docs.yml'] + paths-ignore: ['docs/**', '.github/workflows/docs.yml', '.readthedocs.yaml'] # Cancels all previous workflow runs for the same branch that have not yet completed. concurrency: From 7d83d011b45f769751992df5ea57560be99f1a91 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 22:25:34 +0200 Subject: [PATCH 141/204] Use the "sphinx_rtd_theme" theme for docs --- .readthedocs.yaml | 4 ++++ docs/conf.py | 14 +++++--------- docs/requirements.txt | 1 + 3 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 docs/requirements.txt diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 890f923..c789532 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -12,3 +12,7 @@ build: sphinx: configuration: docs/conf.py fail_on_warning: true + +python: + install: + - requirements: docs/requirements.txt diff --git a/docs/conf.py b/docs/conf.py index 882401c..f42f57a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -6,15 +6,10 @@ import sys import os -# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org -on_rtd = os.environ.get('READTHEDOCS', None) == 'True' - -if not on_rtd: # only import and set the theme if we're building docs locally - import sphinx_rtd_theme - html_theme = 'sphinx_rtd_theme' - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] - -# otherwise, readthedocs.org uses their theme by default, so no need to specify it +# Use theme, that was once default, but now replaced by the Alabaster +import sphinx_rtd_theme +html_theme = 'sphinx_rtd_theme' +#html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # -- General configuration ------------------------------------------------ @@ -22,6 +17,7 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ + 'sphinx_rtd_theme', 'sphinx.ext.autodoc', ] diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..4fedba9 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +sphinx_rtd_theme==2.0.0 From dafacc9844351f3d78025aa5b265f93d0ef45f67 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 22:32:23 +0200 Subject: [PATCH 142/204] Don't test on PHP 7.4 twice --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cc0f153..0fb8a4c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - php: [ '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1' ] + php: [ '5.6', '7.0', '7.1', '7.2', '7.3', '8.0', '8.1' ] with_coverage: [ false ] include: - php: '7.4' From d60ff4aeec2914c5419787ab809185e14c7abe6d Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 22:37:25 +0200 Subject: [PATCH 143/204] Use HTTPS link for BrowserStack website --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7519038..db47222 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,10 @@ This library is an extension for [PHPUnit](https://phpunit.de), that allows to w ## Service Integrations +https://saucelabs.com/ + [![SauceLabs](docs/assets/images/saucelabs_logo.png)](https://saucelabs.com/) -[![BrowserStack](docs/assets/images/browserstack_logo.png)](http://www.browserstack.com/) +[![BrowserStack](docs/assets/images/browserstack_logo.png)](https://www.browserstack.com/) ## Installation using Composer From 4171df4c01945abe606402beebc88140df45a46c Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 22:45:01 +0200 Subject: [PATCH 144/204] Updated Composer's branch alias --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a78944d..5543399 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "2.3.x-dev" } } } From 7250de9feb0018c0d80d3e2d59584156b994fadb Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 22:49:53 +0200 Subject: [PATCH 145/204] Use HTTPS link for BrowserStack --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 94d1e42..eb76992 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -25,7 +25,7 @@ Service Integrations .. _SauceLabs: https://saucelabs.com/ .. |BrowserStack| image:: /assets/images/browserstack_logo.png -.. _BrowserStack: http://www.browserstack.com/ +.. _BrowserStack: https://www.browserstack.com/ .. _`Mink`: https://github.com/Behat/Mink From 8d973584bc6c6816f15e28e8d75c65bee417ffad Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 15 Feb 2024 22:56:06 +0200 Subject: [PATCH 146/204] Improve code coverage a bit by excluding dead code --- .../PHPUnit/BrowserConfiguration/BrowserConfiguration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 2ea425e..b0f8e77 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -633,7 +633,7 @@ public function __call($method, array $args) public function onTestSetup(TestEvent $event) { if ( !$event->validateSubscriber($this->getTestCase()) ) { - return; + return; // @codeCoverageIgnore } // Place code here. From c91a111cd4bc7711b60bc93cf5c01e36bfe72c96 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 16 Feb 2024 08:45:01 +0200 Subject: [PATCH 147/204] Display coverage status in the build name --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0fb8a4c..329d5a7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,7 +18,7 @@ defaults: jobs: tests: - name: Tests (PHP ${{ matrix.php }}) + name: "PHP ${{ matrix.php }} (with coverage: ${{ matrix.with_coverage }})" runs-on: ubuntu-20.04 strategy: matrix: @@ -81,7 +81,7 @@ jobs: - name: Upload Coverage to CodeCov if: "${{ matrix.with_coverage == true }}" - uses: codecov/codecov-action@v2 + uses: codecov/codecov-action@v4 - name: Upload Coverage to Scrutinizer CI (PHP < 8.0) if: "${{ matrix.php < '8.0' && matrix.with_coverage == true }}" From 454bdfaf2da55042e8fea55d13bdd0457ed4c0e5 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 16 Feb 2024 13:51:26 +0200 Subject: [PATCH 148/204] Prettify docs build --- .github/workflows/docs.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c98f6e0..2f0e2b7 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,7 +13,7 @@ defaults: jobs: tests: - name: Tests + name: Documentation runs-on: Ubuntu-20.04 steps: @@ -29,7 +29,6 @@ jobs: run: | pip install Sphinx sphinx_rtd_theme - - name: Run tests run: | sphinx-build -nW -b html -d docs/build/doctrees docs docs/build/html From 1e03b39f493ce330c9fb771ae41a5d56f3ba4aa4 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 16 Feb 2024 14:01:14 +0200 Subject: [PATCH 149/204] Also test on PHP 8.2 and 8.3 --- .github/workflows/tests.yml | 2 +- tests/aik099/PHPUnit/Fixture/coverage_data.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 329d5a7..d079976 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - php: [ '5.6', '7.0', '7.1', '7.2', '7.3', '8.0', '8.1' ] + php: [ '5.6', '7.0', '7.1', '7.2', '7.3', '8.0', '8.1', '8.2', '8.3' ] with_coverage: [ false ] include: - php: '7.4' diff --git a/tests/aik099/PHPUnit/Fixture/coverage_data.txt b/tests/aik099/PHPUnit/Fixture/coverage_data.txt index ec19b7d..ce29cb2 100644 --- a/tests/aik099/PHPUnit/Fixture/coverage_data.txt +++ b/tests/aik099/PHPUnit/Fixture/coverage_data.txt @@ -1 +1 @@ -a:1:{s:75:"/home/giorgio/code/phpunit-mink/tests/aik099/PHPUnit/Fixture/DummyClass.php";a:2:{s:3:"md5";s:32:"290172d322b7de8b5898e54deadbb33e";s:8:"coverage";a:6:{i:3;i:1;i:6;i:1;i:7;i:-2;i:11;i:-1;i:12;i:-2;i:14;i:1;}}} +a:1:{s:75:"/home/giorgio/code/phpunit-mink/tests/aik099/PHPUnit/Fixture/DummyClass.php";a:2:{s:3:"md5";s:32:"290172d322b7de8b5898e54deadbb33e";s:8:"coverage";a:6:{i:3;i:1;i:6;i:1;i:7;i:-2;i:11;i:-1;i:12;i:-2;i:14;i:1;}}} \ No newline at end of file From 63113637b2122c74c7ef9da507679b4395b2c8a9 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 16 Feb 2024 22:53:56 +0200 Subject: [PATCH 150/204] CodeCov V4 GitHub Action stopped working without a token --- .github/workflows/tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d079976..85812a0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -82,6 +82,8 @@ jobs: - name: Upload Coverage to CodeCov if: "${{ matrix.with_coverage == true }}" uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} - name: Upload Coverage to Scrutinizer CI (PHP < 8.0) if: "${{ matrix.php < '8.0' && matrix.with_coverage == true }}" From 28c5c12d6301988bb4e31216a9a209cd59c24800 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 21 Feb 2024 09:22:48 +0200 Subject: [PATCH 151/204] Improve build name --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 85812a0..5b10c93 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,7 +18,7 @@ defaults: jobs: tests: - name: "PHP ${{ matrix.php }} (with coverage: ${{ matrix.with_coverage }})" + name: "PHP ${{ matrix.php }}${{ matrix.with_coverage == true && ' with coverage' || ''}}" runs-on: ubuntu-20.04 strategy: matrix: From 9daeea5f4591e708b6a5f6ce9a76a0d805bbe254 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 8 Mar 2024 17:49:49 +0200 Subject: [PATCH 152/204] Exclude assertion methods during the test suite building --- .../PHPUnit/TestSuite/AbstractTestSuite.php | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index c8b67c6..329679c 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -68,13 +68,13 @@ public function addTestMethods($class_name) if ( \method_exists($this, 'isTestMethod') ) { // PHPUnit < 8.0 is calling "isTestMethod" inside "TestSuite::addTestMethod". - foreach ( $class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method ) { + foreach ( $this->getTestMethods($class) as $method ) { $this->addTestMethod($class, $method); } } else { // PHPUnit >= 8.0 is calling "TestUtil::isTestMethod" outside of "TestSuite::addTestMethod". - foreach ( $class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method ) { + foreach ( $this->getTestMethods($class) as $method ) { if ( TestUtil::isTestMethod($method) ) { $this->addTestMethod($class, $method); } @@ -84,6 +84,22 @@ public function addTestMethods($class_name) return $this; } + /** + * Returns test methods. + * + * @param \ReflectionClass $class Reflection class. + * + * @return \ReflectionMethod[] + */ + protected function getTestMethods(\ReflectionClass $class) + { + $ret = $class->getMethods(\ReflectionMethod::IS_PUBLIC); + + return \array_filter($ret, function (\ReflectionMethod $method) { + return !$method->isStatic(); + }); + } + /** * Sets session strategy manager recursively to all tests. * From 5dce3dfa71d72e0294c057cc9566cc5f51e1f411 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 12 Mar 2024 10:09:41 +0200 Subject: [PATCH 153/204] Removed event dispatcher --- CHANGELOG.md | 1 + composer.json | 1 - composer.lock | 78 +----------- .../ApiBrowserConfiguration.php | 53 +++----- .../BrowserConfiguration.php | 119 +++--------------- .../BrowserStackBrowserConfiguration.php | 15 +-- .../SauceLabsBrowserConfiguration.php | 16 +-- library/aik099/PHPUnit/BrowserTestCase.php | 79 ++++-------- library/aik099/PHPUnit/DIContainer.php | 31 ++--- .../aik099/PHPUnit/Event/TestEndedEvent.php | 54 -------- library/aik099/PHPUnit/Event/TestEvent.php | 83 ------------ .../aik099/PHPUnit/Event/TestFailedEvent.php | 50 -------- .../aik099/PHPUnit/IEventDispatcherAware.php | 31 ----- .../PHPUnit/Session/ISessionStrategy.php | 36 +++++- .../Session/IsolatedSessionStrategy.php | 58 +++------ .../Session/SessionStrategyManager.php | 8 +- .../PHPUnit/Session/SharedSessionStrategy.php | 70 ++--------- .../PHPUnit/TestSuite/AbstractTestSuite.php | 24 +--- .../ApiBrowserConfigurationTestCase.php | 91 +++----------- .../BrowserConfigurationFactoryTest.php | 6 +- .../BrowserConfigurationTest.php | 86 ++++--------- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 34 +++-- .../PHPUnit/Event/TestEndedEventTest.php | 57 --------- tests/aik099/PHPUnit/Event/TestEventTest.php | 84 ------------- .../PHPUnit/Event/TestFailedEventTest.php | 57 --------- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 48 +++---- ...SetupEventFixture.php => SetupFixture.php} | 28 +---- .../PHPUnit/Integration/DIContainerTest.php | 1 - .../Integration/EventDispatchingTest.php | 4 +- .../PHPUnit/MinkDriver/DriverFactoryTest.php | 3 +- .../Session/IsolatedSessionStrategyTest.php | 38 +++--- .../Session/SessionStrategyManagerTest.php | 4 +- .../Session/SessionStrategyTestCase.php | 17 --- .../Session/SharedSessionStrategyTest.php | 34 +++-- .../TestCase/EventDispatcherAwareTestCase.php | 52 -------- .../TestSuite/BrowserTestSuiteTest.php | 7 +- .../TestSuite/RegularTestSuiteTest.php | 7 +- 37 files changed, 266 insertions(+), 1199 deletions(-) delete mode 100644 library/aik099/PHPUnit/Event/TestEndedEvent.php delete mode 100644 library/aik099/PHPUnit/Event/TestEvent.php delete mode 100644 library/aik099/PHPUnit/Event/TestFailedEvent.php delete mode 100644 library/aik099/PHPUnit/IEventDispatcherAware.php delete mode 100644 tests/aik099/PHPUnit/Event/TestEndedEventTest.php delete mode 100644 tests/aik099/PHPUnit/Event/TestEventTest.php delete mode 100644 tests/aik099/PHPUnit/Event/TestFailedEventTest.php rename tests/aik099/PHPUnit/Fixture/{SetupEventFixture.php => SetupFixture.php} (81%) delete mode 100644 tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a427b6..ff4f2c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Bumped minimum PHP version to 5.6. - Changed default OS from "Windows 7" to "Windows 10" for BrowserStack/SauceLabs browser configurations. - Allow using self-signed/invalid SSL certificates during testing on the SauceLabs by default. +- Rewritten library object communication mechanism (the event dispatcher is no longer used). Update any custom session strategy/browser configuration implementations. ### Fixed ... diff --git a/composer.json b/composer.json index 5543399..fa8af6b 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,6 @@ "php": ">=5.6", "behat/mink": "~1.6@dev", "behat/mink-selenium2-driver": "~1.2", - "symfony/event-dispatcher": "~2.4|~3.0", "phpunit/phpunit": ">=4.8.35 <5|>=5.4.3" }, diff --git a/composer.lock b/composer.lock index 8c8ef67..5ba2ba0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c892952697bda295a3aa6a24532c8e84", + "content-hash": "48f60d5675361c47fa38c2ea9526af97", "packages": [ { "name": "behat/mink", @@ -1593,82 +1593,6 @@ ], "time": "2020-10-24T10:57:07+00:00" }, - { - "name": "symfony/event-dispatcher", - "version": "v3.4.47", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "31fde73757b6bad247c54597beef974919ec6860" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/31fde73757b6bad247c54597beef974919ec6860", - "reference": "31fde73757b6bad247c54597beef974919ec6860", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8" - }, - "conflict": { - "symfony/dependency-injection": "<3.3" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.8|~3.0|~4.0", - "symfony/debug": "~3.4|~4.4", - "symfony/dependency-injection": "~3.3|~4.0", - "symfony/expression-language": "~2.8|~3.0|~4.0", - "symfony/stopwatch": "~2.8|~3.0|~4.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v3.4.47" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-24T10:57:07+00:00" - }, { "name": "symfony/polyfill-ctype", "version": "v1.19.0", diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index c8db3e6..6214e7c 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -13,12 +13,10 @@ use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEndedEvent; -use aik099\PHPUnit\Event\TestEvent; +use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Behat\Mink\Driver\Selenium2Driver; use Behat\Mink\Session; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Browser configuration tailored to use with API-based service. @@ -42,18 +40,15 @@ abstract class ApiBrowserConfiguration extends BrowserConfiguration /** * Creates browser configuration. * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * @param DriverFactoryRegistry $driver_factory_registry Driver factory registry. + * @param DriverFactoryRegistry $driver_factory_registry Driver factory registry. */ - public function __construct( - EventDispatcherInterface $event_dispatcher, - DriverFactoryRegistry $driver_factory_registry - ) { + public function __construct(DriverFactoryRegistry $driver_factory_registry) + { $this->defaults['driver'] = 'selenium2'; $this->defaults['apiUsername'] = ''; $this->defaults['apiKey'] = ''; - parent::__construct($event_dispatcher, $driver_factory_registry); + parent::__construct($driver_factory_registry); } /** @@ -137,22 +132,14 @@ public function getBrowserName() } /** - * Hook, called from "BrowserTestCase::setUp" method. - * - * @param TestEvent $event Test event. - * - * @return void + * @inheritDoc */ - public function onTestSetup(TestEvent $event) + public function onTestSetup(BrowserTestCase $test_case) { - if ( !$event->validateSubscriber($this->getTestCase()) ) { - return; - } - - parent::onTestSetup($event); + parent::onTestSetup($test_case); $desired_capabilities = $this->getDesiredCapabilities(); - $desired_capabilities[self::NAME_CAPABILITY] = $this->getJobName($event->getTestCase()); + $desired_capabilities[self::NAME_CAPABILITY] = $this->getJobName($test_case); if ( getenv('BUILD_NUMBER') ) { $desired_capabilities[self::BUILD_NUMBER_CAPABILITY] = getenv('BUILD_NUMBER'); // Jenkins. @@ -181,33 +168,23 @@ protected function getJobName(BrowserTestCase $test_case) } /** - * Hook, called from "BrowserTestCase::run" method. - * - * @param TestEndedEvent $event Test ended event. - * - * @return void + * @inheritDoc */ - public function onTestEnded(TestEndedEvent $event) + public function onTestEnded(BrowserTestCase $test_case, TestResult $test_result) { - if ( !$event->validateSubscriber($this->getTestCase()) ) { - return; - } - - parent::onTestEnded($event); + parent::onTestEnded($test_case, $test_result); - $session = $event->getSession(); + $session = $test_case->getSession(false); if ( $session === null || !$session->isStarted() ) { // Session wasn't used in particular test. return; } - $test_case = $event->getTestCase(); - $this->getAPIClient()->updateStatus( $this->getSessionId($session), - $this->getTestStatus($test_case, $event->getTestResult()), - $this->getTestStatusMessage($test_case, $event->getTestResult()) + $this->getTestStatus($test_case, $test_result), + $this->getTestStatusMessage($test_case, $test_result) ); } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index b0f8e77..ba20eda 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -12,15 +12,11 @@ use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEndedEvent; -use aik099\PHPUnit\Event\TestEvent; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; use aik099\PHPUnit\Session\ISessionStrategyFactory; use Behat\Mink\Driver\DriverInterface; use aik099\PHPUnit\Framework\TestResult; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Browser configuration for browser. @@ -36,7 +32,7 @@ * @method integer getTimeout() Returns server timeout. * @method string getSessionStrategy() Returns session strategy name. */ -class BrowserConfiguration implements EventSubscriberInterface +class BrowserConfiguration { const TYPE = 'default'; @@ -84,20 +80,6 @@ class BrowserConfiguration implements EventSubscriberInterface */ protected $aliases; - /** - * Test case. - * - * @var BrowserTestCase - */ - private $_testCase; - - /** - * Event dispatcher. - * - * @var EventDispatcherInterface - */ - private $_eventDispatcher; - /** * Driver factory registry. * @@ -142,14 +124,10 @@ public static function resolveAliases(array $parameters, array $aliases) /** * Creates browser configuration. * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * @param DriverFactoryRegistry $driver_factory_registry Driver factory registry. + * @param DriverFactoryRegistry $driver_factory_registry Driver factory registry. */ - public function __construct( - EventDispatcherInterface $event_dispatcher, - DriverFactoryRegistry $driver_factory_registry - ) { - $this->_eventDispatcher = $event_dispatcher; + public function __construct(DriverFactoryRegistry $driver_factory_registry) + { $this->_driverFactoryRegistry = $driver_factory_registry; if ( $this->defaults['driver'] ) { @@ -167,60 +145,6 @@ public function getType() return static::TYPE; } - /** - * Returns an array of event names this subscriber wants to listen to. - * - * @return array The event names to listen to - */ - public static function getSubscribedEvents() - { - return array( - BrowserTestCase::TEST_SETUP_EVENT => array('onTestSetup', 100), - BrowserTestCase::TEST_ENDED_EVENT => array('onTestEnded', 100), - ); - } - - /** - * Attaches listeners. - * - * @param BrowserTestCase $test_case Test case. - * - * @return self - */ - public function attachToTestCase(BrowserTestCase $test_case) - { - $this->_testCase = $test_case; - $this->_eventDispatcher->addSubscriber($this); - - return $this; - } - - /** - * Detaches listeners. - * - * @return void - */ - protected function detachFromTestCase() - { - $this->_testCase = null; - $this->_eventDispatcher->removeSubscriber($this); - } - - /** - * Returns associated test case. - * - * @return BrowserTestCase - * @throws \RuntimeException When test case not attached. - */ - public function getTestCase() - { - if ( $this->_testCase === null ) { - throw new \RuntimeException('Test Case not attached, use "attachToTestCase" method'); - } - - return $this->_testCase; - } - /** * Sets aliases. * @@ -495,14 +419,16 @@ public function createDriver() /** * Returns session strategy hash based on given test case and current browser configuration. * + * @param BrowserTestCase $test_case Test case. + * * @return string */ - public function getSessionStrategyHash() + public function getSessionStrategyHash(BrowserTestCase $test_case) { $ret = $this->getChecksum(); if ( $this->isShared() ) { - $ret .= '::' . get_class($this->getTestCase()); + $ret .= '::' . get_class($test_case); } return $ret; @@ -624,35 +550,30 @@ public function __call($method, array $args) } /** - * Hook, called from "BrowserTestCase::setUp" method. + * Hook, called from "BrowserTestCase::setUpTest" method. * - * @param TestEvent $event Test event. + * @param BrowserTestCase $test_case Test case. * - * @return void + * @return void + * @internal */ - public function onTestSetup(TestEvent $event) + public function onTestSetup(BrowserTestCase $test_case) { - if ( !$event->validateSubscriber($this->getTestCase()) ) { - return; // @codeCoverageIgnore - } - // Place code here. } /** - * Hook, called from "BrowserTestCase::run" method. + * Hook, called from "BrowserTestCase::tearDownTest" method. * - * @param TestEndedEvent $event Test ended event. + * @param BrowserTestCase $test_case Test case. + * @param TestResult $test_result Test result. * - * @return void + * @return void + * @internal */ - public function onTestEnded(TestEndedEvent $event) + public function onTestEnded(BrowserTestCase $test_case, TestResult $test_result) { - if ( !$event->validateSubscriber($this->getTestCase()) ) { - return; - } - - $this->detachFromTestCase(); + // Place code here. } } diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php index f148344..7f2a2dc 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php @@ -14,7 +14,6 @@ use aik099\PHPUnit\APIClient\BrowserStackAPIClient; use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEvent; use WebDriver\ServiceFactory; /** @@ -41,19 +40,11 @@ public function getAPIClient() } /** - * Hook, called from "BrowserTestCase::setUp" method. - * - * @param TestEvent $event Test event. - * - * @return void + * @inheritDoc */ - public function onTestSetup(TestEvent $event) + public function onTestSetup(BrowserTestCase $test_case) { - if ( !$event->validateSubscriber($this->getTestCase()) ) { - return; - } - - parent::onTestSetup($event); + parent::onTestSetup($test_case); $desired_capabilities = $this->getDesiredCapabilities(); diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 4ec743c..7417ee2 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -13,7 +13,7 @@ use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\APIClient\SauceLabsAPIClient; -use aik099\PHPUnit\Event\TestEvent; +use aik099\PHPUnit\BrowserTestCase; use WebDriver\SauceLabs\SauceRest; /** @@ -38,19 +38,11 @@ public function getAPIClient() } /** - * Hook, called from "BrowserTestCase::setUp" method. - * - * @param TestEvent $event Test event. - * - * @return void + * @inheritDoc */ - public function onTestSetup(TestEvent $event) + public function onTestSetup(BrowserTestCase $test_case) { - if ( !$event->validateSubscriber($this->getTestCase()) ) { - return; - } - - parent::onTestSetup($event); + parent::onTestSetup($test_case); $desired_capabilities = $this->getDesiredCapabilities(); diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 564b538..2fce0ed 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -15,33 +15,21 @@ use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageTool; -use aik099\PHPUnit\Event\TestEndedEvent; -use aik099\PHPUnit\Event\TestEvent; -use aik099\PHPUnit\Event\TestFailedEvent; use aik099\PHPUnit\Session\ISessionStrategy; use aik099\PHPUnit\Session\SessionStrategyManager; use aik099\PHPUnit\TestSuite\RegularTestSuite; use Behat\Mink\Exception\DriverException; use Behat\Mink\Session; use SebastianBergmann\CodeCoverage\RawCodeCoverageData; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Test Case class for writing browser-based tests. * * @method \Mockery\Expectation shouldReceive(string $name) */ -abstract class BrowserTestCase extends AbstractPHPUnitCompatibilityTestCase implements IEventDispatcherAware +abstract class BrowserTestCase extends AbstractPHPUnitCompatibilityTestCase { - const TEST_ENDED_EVENT = 'test.ended'; - - const TEST_SUITE_ENDED_EVENT = 'test_suite.ended'; - - const TEST_FAILED_EVENT = 'test.failed'; - - const TEST_SETUP_EVENT = 'test.setup'; - /** * Browser list to be used in tests. * @@ -49,13 +37,6 @@ abstract class BrowserTestCase extends AbstractPHPUnitCompatibilityTestCase impl */ public static $browsers = array(); - /** - * Event dispatcher. - * - * @var EventDispatcherInterface - */ - private $_eventDispatcher; - /** * Browser configuration factory. * @@ -124,18 +105,6 @@ public function setBrowserConfigurationFactory(IBrowserConfigurationFactory $bro $this->_browserConfigurationFactory = $browser_configuration_factory; } - /** - * Sets event dispatcher. - * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * - * @return void - */ - public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) - { - $this->_eventDispatcher = $event_dispatcher; - } - /** * Sets session strategy manager. * @@ -182,10 +151,9 @@ public function setRemoteCoverageScriptUrl($url) */ protected function setUpTest() { - $this->_eventDispatcher->dispatch( - self::TEST_SETUP_EVENT, - new TestEvent($this) - ); + if ( $this->_browser !== null ) { + $this->_browser->onTestSetup($this); + } } /** @@ -197,10 +165,12 @@ protected function setUpTest() */ public function setBrowser(BrowserConfiguration $browser) { - $this->_browser = $browser->attachToTestCase($this); + $this->_browser = $browser; // Configure session strategy. - return $this->setSessionStrategy($this->sessionStrategyManager->getSessionStrategy($browser)); + return $this->setSessionStrategy( + $this->sessionStrategyManager->getSessionStrategy($browser, $this) + ); } /** @@ -275,11 +245,13 @@ public function getSessionStrategy() /** * Creates Mink session using current session strategy and returns it. * + * @param boolean $auto_create Automatically create session, when missing. + * * @return Session */ - public function getSession() + public function getSession($auto_create = true) { - if ( $this->_session ) { + if ( $this->_session || $auto_create === false ) { return $this->_session; } @@ -301,7 +273,7 @@ public function getSession() } /** - * Collects remote coverage information and dispatches "test ended" event. + * Collects remote coverage information and notifies strategy/browser about test finish. * * @after */ @@ -313,10 +285,13 @@ protected function tearDownTest() $result->getCodeCoverage()->append($this->getRemoteCodeCoverageInformation(), $this); } - $this->_eventDispatcher->dispatch( - self::TEST_ENDED_EVENT, - new TestEndedEvent($this, $result, $this->_session) - ); + if ( $this->_browser !== null ) { + $this->_browser->onTestEnded($this, $result); + } + + if ( $this->sessionStrategy !== null ) { + $this->sessionStrategy->onTestEnded($this); + } } /** @@ -361,10 +336,9 @@ protected function runTest() */ public function onTestSuiteEnded() { - $this->_eventDispatcher->dispatch( - self::TEST_SUITE_ENDED_EVENT, - new TestEvent($this, $this->_session) - ); + if ( $this->sessionStrategy !== null ) { + $this->sessionStrategy->onTestSuiteEnded($this); + } return $this; } @@ -406,10 +380,9 @@ public static function suite($class_name) */ protected function onNotSuccessfulTestCompatibilized($e) { - $this->_eventDispatcher->dispatch( - self::TEST_FAILED_EVENT, - new TestFailedEvent($e, $this, $this->_session) - ); + if ( $this->sessionStrategy !== null ) { + $this->sessionStrategy->onTestFailed($this, $e); + } } /** diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index 9624565..7c4aa59 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -31,7 +31,6 @@ use aik099\PHPUnit\TestSuite\RegularTestSuite; use aik099\PHPUnit\TestSuite\TestSuiteFactory; use PimpleCopy\Pimple\Container; -use Symfony\Component\EventDispatcher\EventDispatcher; class DIContainer extends Container implements IApplicationAware { @@ -59,10 +58,6 @@ public function __construct(array $values = array()) { parent::__construct($values); - $this['event_dispatcher'] = function () { - return new EventDispatcher(); - }; - $this['session_factory'] = function () { return new SessionFactory(); }; @@ -79,17 +74,11 @@ public function __construct(array $values = array()) }; $this['isolated_session_strategy'] = $this->factory(function ($c) { - $session_strategy = new IsolatedSessionStrategy($c['session_factory']); - $session_strategy->setEventDispatcher($c['event_dispatcher']); - - return $session_strategy; + return new IsolatedSessionStrategy($c['session_factory']); }); $this['shared_session_strategy'] = $this->factory(function ($c) { - $session_strategy = new SharedSessionStrategy($c['isolated_session_strategy']); - $session_strategy->setEventDispatcher($c['event_dispatcher']); - - return $session_strategy; + return new SharedSessionStrategy($c['isolated_session_strategy']); }); $this['remote_url'] = function () { @@ -112,17 +101,11 @@ public function __construct(array $values = array()) }; $this['regular_test_suite'] = $this->factory(function ($c) { - $test_suite = new RegularTestSuite(); - $test_suite->setEventDispatcher($c['event_dispatcher']); - - return $test_suite; + return new RegularTestSuite(); }); $this['browser_test_suite'] = $this->factory(function ($c) { - $test_suite = new BrowserTestSuite(); - $test_suite->setEventDispatcher($c['event_dispatcher']); - - return $test_suite; + return new BrowserTestSuite(); }); $this['driver_factory_registry'] = function () { @@ -140,13 +123,13 @@ public function __construct(array $values = array()) $browser_configuration_factory = new BrowserConfigurationFactory(); $browser_configuration_factory->register( - new BrowserConfiguration($c['event_dispatcher'], $c['driver_factory_registry']) + new BrowserConfiguration($c['driver_factory_registry']) ); $browser_configuration_factory->register( - new SauceLabsBrowserConfiguration($c['event_dispatcher'], $c['driver_factory_registry']) + new SauceLabsBrowserConfiguration($c['driver_factory_registry']) ); $browser_configuration_factory->register( - new BrowserStackBrowserConfiguration($c['event_dispatcher'], $c['driver_factory_registry']) + new BrowserStackBrowserConfiguration($c['driver_factory_registry']) ); return $browser_configuration_factory; diff --git a/library/aik099/PHPUnit/Event/TestEndedEvent.php b/library/aik099/PHPUnit/Event/TestEndedEvent.php deleted file mode 100644 index c1cc980..0000000 --- a/library/aik099/PHPUnit/Event/TestEndedEvent.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit\Event; - - -use aik099\PHPUnit\BrowserTestCase; -use Behat\Mink\Session; -use aik099\PHPUnit\Framework\TestResult; - -class TestEndedEvent extends TestEvent -{ - - /** - * Test result. - * - * @var TestResult - */ - private $_testResult; - - /** - * Remembers the exception which caused test to fail. - * - * @param BrowserTestCase $test_case Test case. - * @param TestResult $test_result Test result. - * @param Session $session Session. - */ - public function __construct( - BrowserTestCase $test_case, - TestResult $test_result, - Session $session = null - ) { - parent::__construct($test_case, $session); - $this->_testResult = $test_result; - } - - /** - * Returns test result. - * - * @return TestResult - */ - public function getTestResult() - { - return $this->_testResult; - } - -} diff --git a/library/aik099/PHPUnit/Event/TestEvent.php b/library/aik099/PHPUnit/Event/TestEvent.php deleted file mode 100644 index ce8622e..0000000 --- a/library/aik099/PHPUnit/Event/TestEvent.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit\Event; - - -use aik099\PHPUnit\BrowserTestCase; -use Behat\Mink\Session; -use Symfony\Component\EventDispatcher\Event; - -class TestEvent extends Event -{ - - /** - * Test case. - * - * @var BrowserTestCase - */ - private $_testCase; - - /** - * Session. - * - * @var Session - */ - private $_session; - - /** - * Creates test event. - * - * @param BrowserTestCase $test_case Test case. - * @param Session $session Session. - */ - public function __construct(BrowserTestCase $test_case, Session $session = null) - { - $this->_testCase = $test_case; - $this->_session = $session; - } - - /** - * Returns test case. - * - * @return BrowserTestCase - */ - public function getTestCase() - { - return $this->_testCase; - } - - /** - * Returns session. - * - * @return Session - */ - public function getSession() - { - return $this->_session; - } - - /** - * Determines if received event is designed for given test case. - * - * @param BrowserTestCase $test_case Test case for comparison. - * - * @return boolean - */ - public function validateSubscriber(BrowserTestCase $test_case) - { - $event_test_case = $this->getTestCase(); - - return get_class($event_test_case) === get_class($test_case) - && $event_test_case->getName() === $test_case->getName() - && $event_test_case->getBrowser()->getChecksum() === $test_case->getBrowser()->getChecksum(); - } - -} diff --git a/library/aik099/PHPUnit/Event/TestFailedEvent.php b/library/aik099/PHPUnit/Event/TestFailedEvent.php deleted file mode 100644 index 37298e3..0000000 --- a/library/aik099/PHPUnit/Event/TestFailedEvent.php +++ /dev/null @@ -1,50 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit\Event; - - -use aik099\PHPUnit\BrowserTestCase; -use Behat\Mink\Session; - -class TestFailedEvent extends TestEvent -{ - - /** - * Exception. - * - * @var \Exception - */ - private $_exception; - - /** - * Remembers the exception which caused test to fail. - * - * @param \Exception|\Throwable $e Exception. - * @param BrowserTestCase $test_case Test case. - * @param Session $session Session. - */ - public function __construct($e, BrowserTestCase $test_case, Session $session = null) - { - parent::__construct($test_case, $session); - $this->_exception = $e; - } - - /** - * Returns exception, that caused test to fail. - * - * @return \Exception|\Throwable - */ - public function getException() - { - return $this->_exception; - } - -} diff --git a/library/aik099/PHPUnit/IEventDispatcherAware.php b/library/aik099/PHPUnit/IEventDispatcherAware.php deleted file mode 100644 index dd3ff9f..0000000 --- a/library/aik099/PHPUnit/IEventDispatcherAware.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit; - - -use Symfony\Component\EventDispatcher\EventDispatcherInterface; - -/** - * Interface to indicate that class is capable of using event dispatcher. - */ -interface IEventDispatcherAware -{ - - /** - * Sets event dispatcher. - * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * - * @return void - */ - public function setEventDispatcher(EventDispatcherInterface $event_dispatcher); - -} diff --git a/library/aik099/PHPUnit/Session/ISessionStrategy.php b/library/aik099/PHPUnit/Session/ISessionStrategy.php index 8d1864b..ce82e91 100644 --- a/library/aik099/PHPUnit/Session/ISessionStrategy.php +++ b/library/aik099/PHPUnit/Session/ISessionStrategy.php @@ -12,16 +12,15 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use aik099\PHPUnit\IEventDispatcherAware; +use aik099\PHPUnit\BrowserTestCase; use Behat\Mink\Session; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Specifies how to create Session objects for running tests. * * @method \Mockery\Expectation shouldReceive(string $name) */ -interface ISessionStrategy extends EventSubscriberInterface, IEventDispatcherAware +interface ISessionStrategy { /** @@ -33,4 +32,35 @@ interface ISessionStrategy extends EventSubscriberInterface, IEventDispatcherAwa */ public function session(BrowserConfiguration $browser); + /** + * Hook, called from "BrowserTestCase::tearDownTest" method. + * + * @param BrowserTestCase $test_case Test case. + * + * @return void + * @internal + */ + public function onTestEnded(BrowserTestCase $test_case); + + /** + * Hook, called from "BrowserTestCase::onNotSuccessfulTestCompatibilized" method. + * + * @param BrowserTestCase $test_case Test case. + * @param \Exception|\Throwable $exception Exception. + * + * @return void + * @internal + */ + public function onTestFailed(BrowserTestCase $test_case, $exception); + + /** + * Hook, called from "BrowserTestCase::onTestSuiteEnded" method. + * + * @param BrowserTestCase $test_case Test case. + * + * @return void + * @internal + */ + public function onTestSuiteEnded(BrowserTestCase $test_case); + } diff --git a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php index 43701eb..ecae412 100644 --- a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php @@ -13,9 +13,7 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEvent; use Behat\Mink\Session; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Produces a new Session object shared for each test. @@ -42,30 +40,6 @@ public function __construct(ISessionFactory $session_factory) $this->_sessionFactory = $session_factory; } - /** - * Returns an array of event names this subscriber wants to listen to. - * - * @return array The event names to listen to - */ - public static function getSubscribedEvents() - { - return array( - BrowserTestCase::TEST_ENDED_EVENT => array('onTestEnd', 0), - ); - } - - /** - * Sets event dispatcher. - * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * - * @return void - */ - public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) - { - $event_dispatcher->addSubscriber($this); - } - /** * Returns Mink session with given browser configuration. * @@ -79,19 +53,11 @@ public function session(BrowserConfiguration $browser) } /** - * Called, when test ends. - * - * @param TestEvent $event Test event. - * - * @return void + * @inheritDoc */ - public function onTestEnd(TestEvent $event) + public function onTestEnded(BrowserTestCase $test_case) { - if ( !$this->_isEventForMe($event) ) { - return; - } - - $session = $event->getSession(); + $session = $test_case->getSession(false); if ( $session !== null && $session->isStarted() ) { $session->stop(); @@ -99,15 +65,19 @@ public function onTestEnd(TestEvent $event) } /** - * Checks, that event can be handled by this class. - * - * @param TestEvent $event Test event. - * - * @return boolean + * @inheritDoc */ - private function _isEventForMe(TestEvent $event) + public function onTestFailed(BrowserTestCase $test_case, $exception) { - return $event->getTestCase()->getSessionStrategy() instanceof self; + + } + + /** + * @inheritDoc + */ + public function onTestSuiteEnded(BrowserTestCase $test_case) + { + } } diff --git a/library/aik099/PHPUnit/Session/SessionStrategyManager.php b/library/aik099/PHPUnit/Session/SessionStrategyManager.php index 4a96fd0..757eab0 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyManager.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyManager.php @@ -12,6 +12,7 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\BrowserTestCase; /** * Manages session strategies used across browser tests. @@ -78,11 +79,12 @@ public function getDefaultSessionStrategy() /** * Initializes session strategy using given browser test case. * - * @param BrowserConfiguration $browser Browser configuration. + * @param BrowserConfiguration $browser Browser configuration. + * @param BrowserTestCase $test_case Test case. * * @return ISessionStrategy */ - public function getSessionStrategy(BrowserConfiguration $browser) + public function getSessionStrategy(BrowserConfiguration $browser, BrowserTestCase $test_case) { /* * This logic creates separate strategy for: @@ -90,7 +92,7 @@ public function getSessionStrategy(BrowserConfiguration $browser) * - each browser configuration in BrowserTestCase::$browsers for each test case class (for shared strategy) */ $strategy_type = $browser->getSessionStrategy(); - $strategy_hash = $browser->getSessionStrategyHash(); + $strategy_hash = $browser->getSessionStrategyHash($test_case); if ( $strategy_hash !== $this->lastUsedSessionStrategyHash ) { $this->sessionStrategiesInUse[$strategy_hash] = $this->_sessionStrategyFactory->createStrategy( diff --git a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php index 685e28e..99f6a84 100644 --- a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -13,12 +13,9 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEvent; -use aik099\PHPUnit\Event\TestFailedEvent; use Behat\Mink\Session; use aik099\PHPUnit\Framework\IncompleteTestError; use aik099\PHPUnit\Framework\SkippedTestError; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Keeps a Session object shared between test runs to save time. @@ -59,31 +56,6 @@ public function __construct(ISessionStrategy $original_strategy) $this->_originalStrategy = $original_strategy; } - /** - * Returns an array of event names this subscriber wants to listen to. - * - * @return array The event names to listen to - */ - public static function getSubscribedEvents() - { - return array( - BrowserTestCase::TEST_FAILED_EVENT => array('onTestFailed', 0), - BrowserTestCase::TEST_SUITE_ENDED_EVENT => array('onTestSuiteEnd', 0), - ); - } - - /** - * Sets event dispatcher. - * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * - * @return void - */ - public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) - { - $event_dispatcher->addSubscriber($this); - } - /** * Returns Mink session with given browser configuration. * @@ -134,16 +106,18 @@ private function _switchToMainWindow() } /** - * Called, when test fails. - * - * @param TestFailedEvent $event Test failed event. - * - * @return void + * @inheritDoc */ - public function onTestFailed(TestFailedEvent $event) + public function onTestEnded(BrowserTestCase $test_case) { - $exception = $event->getException(); + } + + /** + * @inheritDoc + */ + public function onTestFailed(BrowserTestCase $test_case, $exception) + { if ( $exception instanceof IncompleteTestError || $exception instanceof SkippedTestError ) { return; } @@ -152,35 +126,15 @@ public function onTestFailed(TestFailedEvent $event) } /** - * Called, when test case ends. - * - * @param TestEvent $event Test event. - * - * @return void + * @inheritDoc */ - public function onTestSuiteEnd(TestEvent $event) + public function onTestSuiteEnded(BrowserTestCase $test_case) { - if ( !$this->_isEventForMe($event) ) { - return; - } - - $session = $event->getSession(); + $session = $test_case->getSession(false); if ( $session !== null && $session->isStarted() ) { $session->stop(); } } - /** - * Checks, that event can be handled by this class. - * - * @param TestEvent $event Test event. - * - * @return boolean - */ - private function _isEventForMe(TestEvent $event) - { - return $event->getTestCase()->getSessionStrategy() instanceof self; - } - } diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index c8b67c6..3dab462 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -14,28 +14,19 @@ use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestSuite; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\IEventDispatcherAware; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\Session\SessionStrategyManager; use aik099\PHPUnit\Framework\DataProviderTestSuite; use PHPUnit\Util\Test as TestUtil; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Base Test Suite class for browser tests. * * @method \Mockery\Expectation shouldReceive(string $name) */ -abstract class AbstractTestSuite extends AbstractPHPUnitCompatibilityTestSuite implements IEventDispatcherAware +abstract class AbstractTestSuite extends AbstractPHPUnitCompatibilityTestSuite { - /** - * Event dispatcher. - * - * @var EventDispatcherInterface - */ - private $_eventDispatcher; - /** * Overriding the default: Selenium suites are always built from a TestCase class. * @@ -43,18 +34,6 @@ abstract class AbstractTestSuite extends AbstractPHPUnitCompatibilityTestSuite i */ protected $testCase = true; - /** - * Sets event dispatcher. - * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * - * @return void - */ - public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) - { - $this->_eventDispatcher = $event_dispatcher; - } - /** * Adds test methods to the suite. * @@ -115,7 +94,6 @@ public function setTestDependencies( } else { /** @var BrowserTestCase $test */ - $test->setEventDispatcher($this->_eventDispatcher); $test->setSessionStrategyManager($session_strategy_manager); $test->setBrowserConfigurationFactory($browser_configuration_factory); $test->setRemoteCoverageHelper($remote_coverage_helper); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 4feaf7b..ff430b4 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -13,11 +13,8 @@ use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; -use aik099\PHPUnit\Event\TestEndedEvent; -use aik099\PHPUnit\Event\TestEvent; use aik099\PHPUnit\Session\ISessionStrategyFactory; use aik099\PHPUnit\Framework\TestResult; -use Symfony\Component\EventDispatcher\EventDispatcher; use aik099\PHPUnit\BrowserTestCase; use Mockery as m; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; @@ -50,12 +47,7 @@ abstract class ApiBrowserConfigurationTestCase extends BrowserConfigurationTest */ protected function setUpTest() { - $this->testsRequireSubscriber[] = 'testTestSetupEvent'; - $this->testsRequireSubscriber[] = 'testTestEndedEvent'; - $this->testsRequireSubscriber[] = 'testTestEndedWithoutSession'; - $this->testsRequireSubscriber[] = 'testTunnelIdentifier'; - - if ( $this->getName(false) === 'testTestEndedEvent' ) { + if ( $this->getName(false) === 'testOnTestEnded' ) { $this->mockBrowserMethods[] = 'getAPIClient'; } @@ -201,9 +193,9 @@ abstract public function desiredCapabilitiesDataProvider(); * @param string $build_number Build number. * * @return void - * @dataProvider setupEventDataProvider + * @dataProvider setupProcessDataProvider */ - public function testTestSetupEvent($session_strategy, $test_name, $build_env_name = null, $build_number = null) + public function testTestSetupProcess($session_strategy, $test_name, $build_env_name = null, $build_number = null) { // Reset any global env vars that might be left from previous tests. $hhvm_hack = defined('HHVM_VERSION') ? '=' : ''; @@ -221,17 +213,11 @@ public function testTestSetupEvent($session_strategy, $test_name, $build_env_nam ->times($this->_isAutomaticTestName($test_name) ? 0 : 1) ->andReturn($test_name); - $event_dispatcher = new EventDispatcher(); - $event_dispatcher->addSubscriber($this->browser); - if ( $this->_isAutomaticTestName($test_name) ) { $test_name = get_class($test_case); } - $event_dispatcher->dispatch( - BrowserTestCase::TEST_SETUP_EVENT, - new TestEvent($test_case, m::mock('Behat\\Mink\\Session')) - ); + $this->browser->onTestSetup($test_case); $desired_capabilities = $this->browser->getDesiredCapabilities(); @@ -260,11 +246,11 @@ private function _isAutomaticTestName($test_name) } /** - * Data provider for TestSetup event handler. + * Data provider for setup process test. * * @return array */ - public function setupEventDataProvider() + public function setupProcessDataProvider() { $seed = uniqid(); @@ -295,9 +281,9 @@ public function setupEventDataProvider() * @param string $driver_type Driver. * * @return void - * @dataProvider theTestEndedEventDataProvider + * @dataProvider onTestEndedDataProvider */ - public function testTestEndedEvent($driver_type) + public function testOnTestEnded($driver_type) { $test_case = $this->createTestCase('TEST_NAME'); @@ -321,19 +307,11 @@ public function testTestEndedEvent($driver_type) $session->shouldReceive('getDriver')->once()->andReturn($driver); $session->shouldReceive('isStarted')->once()->andReturn(true); - $event_dispatcher = new EventDispatcher(); - $event_dispatcher->addSubscriber($this->browser); + $test_case->shouldReceive('getSession')->with(false)->once()->andReturn($session); $test_result = new TestResult(); // Can't mock, because it's a final class. - $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); - - $event = $event_dispatcher->dispatch( - BrowserTestCase::TEST_ENDED_EVENT, - new TestEndedEvent($test_case, $test_result, $session) - ); - - $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $event); + $this->browser->onTestEnded($test_case, $test_result); } /** @@ -341,7 +319,7 @@ public function testTestEndedEvent($driver_type) * * @return array */ - public function theTestEndedEventDataProvider() + public function onTestEndedDataProvider() { return array( array('selenium'), @@ -354,36 +332,20 @@ public function theTestEndedEventDataProvider() */ public function testTestEndedWithoutSession($stopped_or_missing) { - $test_case = $this->createTestCase('TEST_NAME', false); - - $event_dispatcher = new EventDispatcher(); - $event_dispatcher->addSubscriber($this->browser); - - $event = m::mock('aik099\\PHPUnit\\Event\\TestEndedEvent'); + $test_case = $this->createTestCase('TEST_NAME'); if ( $stopped_or_missing ) { $session = m::mock('Behat\\Mink\\Session'); $session->shouldReceive('isStarted')->once()->andReturn(false); - $event->shouldReceive('getSession')->once()->andReturn($session); + $test_case->shouldReceive('getSession')->with(false)->once()->andReturn($session); } else { - $event->shouldReceive('getSession')->once(); + $test_case->shouldReceive('getSession')->with(false)->once(); } - // Below methods were removed in Symfony 3.0. - if ( \method_exists('\Symfony\Component\EventDispatcher\Event', 'setDispatcher') ) { - $event->shouldReceive('setDispatcher')->once(); - $event->shouldReceive('setName')->once(); - } - - $event->shouldReceive('isPropagationStopped')->once()->andReturn(false); - $event->shouldReceive('getTestCase')->andReturn($test_case); - $event->shouldReceive('validateSubscriber')->with($test_case)->atLeast()->once()->andReturn(true); - - $this->eventDispatcher->shouldReceive('removeSubscriber')->with($this->browser)->once(); - $returned_event = $event_dispatcher->dispatch(BrowserTestCase::TEST_ENDED_EVENT, $event); + $test_result = new TestResult(); // Can't mock, because it's a final class. - $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $returned_event); + $this->browser->onTestEnded($test_case, $test_result); } public function sessionStateDataProvider() @@ -397,22 +359,15 @@ public function sessionStateDataProvider() /** * Create TestCase with Browser. * - * @param string $name Test case name. - * @param boolean $get_browser Create browser expectation. + * @param string $name Test case name. * - * @return BrowserTestCase + * @return BrowserTestCase|m\MockInterface */ - protected function createTestCase($name, $get_browser = true) + protected function createTestCase($name) { $test_case = m::mock(self::TEST_CASE_CLASS); $test_case->shouldReceive('getName')->andReturn($name); - if ( $get_browser ) { - $test_case->shouldReceive('getBrowser')->atLeast()->once()->andReturn($this->browser); - } - - $this->browser->attachToTestCase($test_case); - return $test_case; } @@ -440,13 +395,7 @@ public function testTunnelIdentifier($tunnel_id = null) $test_case = $this->createTestCase('TEST_NAME'); $test_case->shouldReceive('toString')->andReturn('TEST_NAME'); - $event_dispatcher = new EventDispatcher(); - $event_dispatcher->addSubscriber($this->browser); - - $event_dispatcher->dispatch( - BrowserTestCase::TEST_SETUP_EVENT, - new TestEvent($test_case, m::mock('Behat\\Mink\\Session')) - ); + $this->browser->onTestSetup($test_case); $desired_capabilities = $this->browser->getDesiredCapabilities(); diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index 635a10e..f183dc0 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -11,14 +11,14 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Mockery as m; -use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class BrowserConfigurationFactoryTest extends EventDispatcherAwareTestCase +class BrowserConfigurationFactoryTest extends AbstractPHPUnitCompatibilityTestCase { use ExpectException; @@ -42,8 +42,6 @@ class BrowserConfigurationFactoryTest extends EventDispatcherAwareTestCase */ protected function setUpTest() { - parent::setUpTest(); - $this->_factory = new BrowserConfigurationFactory(); $this->_driverFactoryRegistry = $this->createDriverFactoryRegistry(); } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 0673c35..9f09c06 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -11,6 +11,7 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; @@ -21,10 +22,9 @@ use aik099\PHPUnit\Framework\TestResult; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; -use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class BrowserConfigurationTest extends EventDispatcherAwareTestCase +class BrowserConfigurationTest extends AbstractPHPUnitCompatibilityTestCase { use ExpectException; @@ -84,20 +84,11 @@ class BrowserConfigurationTest extends EventDispatcherAwareTestCase */ protected $driverFactoryRegistry; - /** - * Tests names, that require subscriber. - * - * @var array - */ - protected $testsRequireSubscriber = array(); - /** * @before */ protected function setUpTest() { - parent::setUpTest(); - if ( !$this->browserConfigurationClass ) { $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; } @@ -118,7 +109,6 @@ protected function setUpTest() $this->browser = $this->createBrowserConfiguration( array(), - in_array($this->getName(false), $this->testsRequireSubscriber), $this->mockBrowserMethods ); } @@ -249,34 +239,6 @@ public function testResolveAliasesUsingIncorrectAlias() $this->browser->setup(array('alias' => 'not_found')); } - /** - * Test description. - * - * @return void - */ - public function testAttachToTestCase() - { - $browser = $this->createBrowserConfiguration(array(), true); - - /* @var $test_case BrowserTestCase */ - $test_case = m::mock(self::TEST_CASE_CLASS); - - $this->assertSame($browser, $browser->attachToTestCase($test_case)); - $this->assertSame($test_case, $browser->getTestCase()); - } - - /** - * Test description. - * - * @return void - */ - public function testGetTestCaseException() - { - $this->expectException('RuntimeException'); - - $this->browser->getTestCase(); - } - /** * Test description. * @@ -550,13 +512,16 @@ public function testGetSessionStrategyHashBrowserSharing($session_strategy) /* @var $test_case BrowserTestCase */ $test_case = m::mock(self::TEST_CASE_CLASS); - $browser1 = $this->createBrowserConfiguration(array(), true); - $browser1->setSessionStrategy($session_strategy)->attachToTestCase($test_case); + $browser1 = $this->createBrowserConfiguration(); + $browser1->setSessionStrategy($session_strategy); - $browser2 = $this->createBrowserConfiguration(array(), true); - $browser2->setSessionStrategy($session_strategy)->attachToTestCase($test_case); + $browser2 = $this->createBrowserConfiguration(); + $browser2->setSessionStrategy($session_strategy); - $this->assertSame($browser1->getSessionStrategyHash(), $browser2->getSessionStrategyHash()); + $this->assertSame( + $browser1->getSessionStrategyHash($test_case), + $browser2->getSessionStrategyHash($test_case) + ); } /** @@ -580,14 +545,17 @@ public function sessionSharingDataProvider() public function testGetSessionStrategyHashNotSharing() { $test_case1 = new WithBrowserConfig(); - $browser1 = $this->createBrowserConfiguration(array(), true); - $browser1->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED)->attachToTestCase($test_case1); + $browser1 = $this->createBrowserConfiguration(); + $browser1->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED); $test_case2 = new WithoutBrowserConfig(); - $browser2 = $this->createBrowserConfiguration(array(), true); - $browser2->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED)->attachToTestCase($test_case2); + $browser2 = $this->createBrowserConfiguration(); + $browser2->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED); - $this->assertNotSame($browser1->getSessionStrategyHash(), $browser2->getSessionStrategyHash()); + $this->assertNotSame( + $browser1->getSessionStrategyHash($test_case1), + $browser2->getSessionStrategyHash($test_case2) + ); } /** @@ -644,34 +612,28 @@ public function testChecksumMismatch() /** * Creates instance of browser configuration. * - * @param array $aliases Aliases. - * @param boolean $add_subscriber Expect addition of subscriber to event dispatcher. - * @param array $mock_methods Mock methods. + * @param array $aliases Aliases. + * @param array $mock_methods Mock methods. * * @return BrowserConfiguration */ - protected function createBrowserConfiguration( - array $aliases = array(), - $add_subscriber = false, - $mock_methods = array() - ) { + protected function createBrowserConfiguration(array $aliases = array(), $mock_methods = array()) + { if ( $mock_methods ) { /** @var BrowserConfiguration $browser */ $browser = m::mock( $this->browserConfigurationClass . '[' . implode(',', $mock_methods) . ']', - array($this->eventDispatcher, $this->driverFactoryRegistry), + array($this->driverFactoryRegistry), array('getSessionStrategy' => 'isolated') ); } else { /** @var BrowserConfiguration $browser */ - $browser = new $this->browserConfigurationClass($this->eventDispatcher, $this->driverFactoryRegistry); + $browser = new $this->browserConfigurationClass($this->driverFactoryRegistry); } $browser->setAliases($aliases); - $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->times($add_subscriber ? 1 : 0); - return $browser; } diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index dbd100c..70d46cc 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -11,6 +11,7 @@ namespace tests\aik099\PHPUnit; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; @@ -28,10 +29,9 @@ use SebastianBergmann\CodeCoverage\RawCodeCoverageData; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; -use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class BrowserTestCaseTest extends EventDispatcherAwareTestCase +class BrowserTestCaseTest extends AbstractPHPUnitCompatibilityTestCase { use ExpectException; @@ -54,8 +54,6 @@ class BrowserTestCaseTest extends EventDispatcherAwareTestCase */ protected function setUpTest() { - parent::setUpTest(); - // Define the constant because this test is running PHPUnit testcases manually. if ( $this->isInIsolation() ) { define('PHPUNIT_TESTSUITE', true); @@ -97,8 +95,7 @@ public function testSetBrowserCorrect() $test_case = $this->getFixture($session_strategy); - $browser = new BrowserConfiguration($this->eventDispatcher, $this->createDriverFactoryRegistry()); - $this->eventDispatcher->shouldReceive('addSubscriber')->with($browser)->once(); + $browser = new BrowserConfiguration($this->createDriverFactoryRegistry()); $this->assertSame($test_case, $test_case->setBrowser($browser)); $this->assertSame($browser, $test_case->getBrowser()); @@ -261,7 +258,6 @@ protected function getBrowser($times) $browser = m::mock(self::BROWSER_CLASS); $browser->shouldReceive('getHost')->times($times); $browser->shouldReceive('getPort')->times($times); - $browser->shouldReceive('attachToTestCase')->once()->andReturn($browser); return $browser; } @@ -339,7 +335,7 @@ public function testRunWithCoverageWithoutRemoteUrl() { /* @var $test_case BrowserTestCase */ /* @var $session_strategy ISessionStrategy */ - list($test_case, $session_strategy) = $this->prepareForRun(array()); + list($test_case, $session_strategy) = $this->prepareForRun(); $test_case->setName('getTestId'); $test_case->setRemoteCoverageHelper($this->getRemoteCoverageHelperMock()); @@ -576,15 +572,14 @@ protected function getCodeCoverageMock(array $expected_coverage) */ public function testEndOfTestCase() { - $this->expectEvent(BrowserTestCase::TEST_SUITE_ENDED_EVENT); - /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $test_case = new WithoutBrowserConfig(); - $test_case->setEventDispatcher($this->eventDispatcher); $test_case->setSessionStrategy($session_strategy); + $session_strategy->shouldReceive('onTestSuiteEnded')->with($test_case)->once(); + $this->assertSame($test_case, $test_case->onTestSuiteEnded()); } @@ -598,18 +593,19 @@ public function testOnTestFailed() $this->expectException('Exception'); $this->expectExceptionMessage('MSG_TEST'); - $this->expectEvent(BrowserTestCase::TEST_FAILED_EVENT); - /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $test_case = $this->getFixture($session_strategy); $test_case->setSessionStrategy($session_strategy); + $exception = new \Exception('MSG_TEST'); + $session_strategy->shouldReceive('onTestFailed')->with($test_case, $exception)->once(); + $reflection_method = new \ReflectionMethod($test_case, 'onNotSuccessfulTest'); $reflection_method->setAccessible(true); - $reflection_method->invokeArgs($test_case, array(new \Exception('MSG_TEST'))); + $reflection_method->invokeArgs($test_case, array($exception)); } /** @@ -633,18 +629,19 @@ public function testGetBrowserAliases() */ protected function prepareForRun(array $mock_methods = array()) { - $this->expectEvent(BrowserTestCase::TEST_SETUP_EVENT); - /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $test_case = $this->getFixture($session_strategy, $mock_methods); $test_case->setName('testSuccess'); + $session_strategy->shouldReceive('onTestEnded')->with($test_case)->once(); + $browser = $this->getBrowser(0); - $test_case->setBrowser($browser); + $browser->shouldReceive('onTestSetup')->with($test_case)->once(); + $browser->shouldReceive('onTestEnded')->with($test_case, m::type(TestResult::class))->once(); - $this->expectEvent(\aik099\PHPUnit\BrowserTestCase::TEST_ENDED_EVENT); + $test_case->setBrowser($browser); return array($test_case, $session_strategy); } @@ -674,7 +671,6 @@ protected function getFixture(ISessionStrategy $session_strategy = null, array $ $test_case = new WithoutBrowserConfig(); } - $test_case->setEventDispatcher($this->eventDispatcher); $test_case->setBrowserConfigurationFactory($this->browserConfigurationFactory); $test_case->setSessionStrategyManager($manager); diff --git a/tests/aik099/PHPUnit/Event/TestEndedEventTest.php b/tests/aik099/PHPUnit/Event/TestEndedEventTest.php deleted file mode 100644 index 0621b79..0000000 --- a/tests/aik099/PHPUnit/Event/TestEndedEventTest.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace tests\aik099\PHPUnit\Event; - - -use aik099\PHPUnit\Event\TestEndedEvent; -use aik099\PHPUnit\Framework\TestResult; - -class TestEndedEventTest extends TestEventTest -{ - - /** - * Test result. - * - * @var TestResult - */ - private $_testResult; - - /** - * @before - */ - protected function setUpTest() - { - $this->_testResult = new TestResult(); - - parent::setUpTest(); - } - - /** - * Test description. - * - * @return void - */ - public function testGetTestResult() - { - $this->assertSame($this->_testResult, $this->event->getTestResult()); - } - - /** - * Creates new event. - * - * @return TestEndedEvent - */ - protected function createEvent() - { - return new TestEndedEvent($this->testCase, $this->_testResult, $this->session); - } - -} diff --git a/tests/aik099/PHPUnit/Event/TestEventTest.php b/tests/aik099/PHPUnit/Event/TestEventTest.php deleted file mode 100644 index 5734645..0000000 --- a/tests/aik099/PHPUnit/Event/TestEventTest.php +++ /dev/null @@ -1,84 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace tests\aik099\PHPUnit\Event; - - -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; -use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEvent; -use Behat\Mink\Session; -use Mockery as m; - -class TestEventTest extends AbstractPHPUnitCompatibilityTestCase -{ - - /** - * Test event. - * - * @var TestEvent - */ - protected $event; - - /** - * Test case. - * - * @var BrowserTestCase - */ - protected $testCase; - - /** - * Session. - * - * @var Session - */ - protected $session; - - /** - * @before - */ - protected function setUpTest() - { - $this->testCase = m::mock('aik099\\PHPUnit\\BrowserTestCase'); - $this->session = m::mock('Behat\\Mink\\Session'); - $this->event = $this->createEvent(); - } - - /** - * Test description. - * - * @return void - */ - public function testGetTestCase() - { - $this->assertSame($this->testCase, $this->event->getTestCase()); - } - - /** - * Test description. - * - * @return void - */ - public function testGetSession() - { - $this->assertSame($this->session, $this->event->getSession()); - } - - /** - * Creates new event. - * - * @return TestEvent - */ - protected function createEvent() - { - return new TestEvent($this->testCase, $this->session); - } - -} diff --git a/tests/aik099/PHPUnit/Event/TestFailedEventTest.php b/tests/aik099/PHPUnit/Event/TestFailedEventTest.php deleted file mode 100644 index 48bf46a..0000000 --- a/tests/aik099/PHPUnit/Event/TestFailedEventTest.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace tests\aik099\PHPUnit\Event; - - -use aik099\PHPUnit\Event\TestFailedEvent; -use Mockery\CountValidator\Exception; - -class TestFailedEventTest extends TestEventTest -{ - - /** - * Exception. - * - * @var \Exception - */ - private $_exception; - - /** - * @before - */ - protected function setUpTest() - { - $this->_exception = new Exception(); - - parent::setUpTest(); - } - - /** - * Test description. - * - * @return void - */ - public function testGetException() - { - $this->assertSame($this->_exception, $this->event->getException()); - } - - /** - * Creates new event. - * - * @return TestFailedEvent - */ - protected function createEvent() - { - return new TestFailedEvent($this->_exception, $this->testCase, $this->session); - } - -} diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index 5c58a2a..562f25c 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -15,9 +15,7 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEvent; use Mockery as m; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; class ApiIntegrationFixture extends BrowserTestCase { @@ -40,63 +38,47 @@ class ApiIntegrationFixture extends BrowserTestCase private $_sessionIds = array(); /** - * Sets event dispatcher. + * @inheritDoc * - * @param EventDispatcherInterface $event_dispatcher Event dispatcher. - * - * @return void + * @after */ - public function setEventDispatcher(EventDispatcherInterface $event_dispatcher) + protected function tearDownTest() { - parent::setEventDispatcher($event_dispatcher); + $this->recordSessionId(); + + parent::tearDownTest(); - // Use priority for this listener to be called before one, that stops the session. - $event_dispatcher->addListener(self::TEST_ENDED_EVENT, array($this, 'recordSessionId'), 200); - $event_dispatcher->addListener(self::TEST_ENDED_EVENT, array($this, 'verifyRemoteAPICalls')); + $this->verifyRemoteAPICalls(); } /** * Record WebDriver session ID of the test. * - * @param TestEvent $event Event. - * * @return void */ - public function recordSessionId(TestEvent $event) + public function recordSessionId() { - $test_case = $event->getTestCase(); - - if ( get_class($test_case) !== get_class($this) - || $test_case->getName() !== $this->getName() - || $this->_getTestSkipMessage() - ) { + if ( $this->_getTestSkipMessage() ) { return; } - $session = $event->getSession(); + $session = $this->getSession(false); if ( $session === null ) { $this->markTestSkipped('Unable to connect to SauceLabs/BrowserStack. Please check Internet connection.'); } - $this->_sessionIds[$test_case->getName(false)] = $session->getDriver()->getWebDriverSessionId(); + $this->_sessionIds[$this->getName(false)] = $session->getDriver()->getWebDriverSessionId(); } /** * Verify how the API calls were made. * - * @param TestEvent $event Event. - * * @return void */ - public function verifyRemoteAPICalls(TestEvent $event) + public function verifyRemoteAPICalls() { - if ( !$event->validateSubscriber($this) ) { - return; - } - - $test_case = $event->getTestCase(); - $test_name = $test_case->getName(false); + $test_name = $this->getName(false); if ( !isset($this->_sessionIds[$test_name]) ) { return; @@ -110,7 +92,7 @@ public function verifyRemoteAPICalls(TestEvent $event) if ( $browser instanceof SauceLabsBrowserConfiguration ) { $this->assertEquals( - get_class($test_case) . '::' . $test_name, + get_class($this) . '::' . $test_name, $session_info['name'], 'SauceLabs remote session name matches test name' ); @@ -141,7 +123,7 @@ public function verifyRemoteAPICalls(TestEvent $event) } elseif ( $browser instanceof BrowserStackBrowserConfiguration ) { $this->assertEquals( - \str_replace('\\', '-', get_class($test_case) . '::' . $test_name), + \str_replace('\\', '-', get_class($this) . '::' . $test_name), $session_info['name'], 'BrowserStack remote session name matches test name' ); diff --git a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php b/tests/aik099/PHPUnit/Fixture/SetupFixture.php similarity index 81% rename from tests/aik099/PHPUnit/Fixture/SetupEventFixture.php rename to tests/aik099/PHPUnit/Fixture/SetupFixture.php index 146a9af..1aa6b19 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupEventFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupFixture.php @@ -18,7 +18,7 @@ use Behat\Mink\Session; use Mockery as m; -class SetupEventFixture extends BrowserTestCase +class SetupFixture extends BrowserTestCase { /** @@ -36,7 +36,7 @@ protected function setUpTest() $browser = m::mock( 'aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration[getAPIClient]', - array($this->getObjectProperty($this, '_eventDispatcher'), $this->createDriverFactoryRegistry()) + array($this->createDriverFactoryRegistry()) ); // These magic methods can't be properly passed through to mocked object otherwise. @@ -58,30 +58,6 @@ protected function setUpTest() parent::setUpTest(); } - /** - * Returns object property value. - * - * @param mixed $object Object. - * @param string $property_name Property name. - * - * @return mixed - */ - protected function getObjectProperty($object, $property_name) - { - $reflector = new \ReflectionObject($object); - - while ( !$reflector->hasProperty($property_name) && $reflector->getParentClass() !== false ) { - $reflector = $reflector->getParentClass(); - } - - $attribute = $reflector->getProperty($property_name); - $attribute->setAccessible(true); - $value = $attribute->getValue($object); - $attribute->setAccessible(false); - - return $value; - } - /** * Creates driver factory registry. * diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index 9a4f887..a46f8bd 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -59,7 +59,6 @@ public function serviceDefinitionsDataProvider() { return array( array('application', 'aik099\\PHPUnit\\Application'), - array('event_dispatcher', 'Symfony\\Component\\EventDispatcher\\EventDispatcher'), array('session_factory', 'aik099\\PHPUnit\\Session\\SessionFactory'), array('session_strategy_factory', 'aik099\\PHPUnit\\Session\\SessionStrategyFactory'), array('session_strategy_manager', 'aik099\\PHPUnit\\Session\\SessionStrategyManager'), diff --git a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php index 25be854..c9cd6a3 100644 --- a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php +++ b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php @@ -13,7 +13,7 @@ use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Framework\TestResult; -use tests\aik099\PHPUnit\Fixture\SetupEventFixture; +use tests\aik099\PHPUnit\Fixture\SetupFixture; class EventDispatchingTest extends AbstractPHPUnitCompatibilityTestCase { @@ -55,7 +55,7 @@ public function testSetupEvent() $result = new TestResult(); - $suite = SetupEventFixture::suite('tests\\aik099\\PHPUnit\\Fixture\\SetupEventFixture'); + $suite = SetupFixture::suite('tests\\aik099\\PHPUnit\\Fixture\\SetupFixture'); $suite->run($result); $this->assertTrue($result->wasSuccessful(), 'All sub-tests passed'); diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php index ad4f2e1..c2d4930 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php @@ -70,8 +70,7 @@ protected function createBrowserConfiguration(IMinkDriverFactory $factory) { $di = new DIContainer(); - $event_dispatcher = m::mock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); - $browser_configuration = new BrowserConfiguration($event_dispatcher, $di['driver_factory_registry']); + $browser_configuration = new BrowserConfiguration($di['driver_factory_registry']); $browser_configuration->setDriver($factory->getDriverName()); return $browser_configuration; diff --git a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php index 8648f79..43be1b9 100644 --- a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php @@ -11,13 +11,10 @@ namespace tests\aik099\PHPUnit\Session; -use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEndedEvent; use aik099\PHPUnit\Session\ISessionFactory; use aik099\PHPUnit\Session\IsolatedSessionStrategy; use Mockery as m; use Mockery\MockInterface; -use aik099\PHPUnit\Framework\TestResult; class IsolatedSessionStrategyTest extends SessionStrategyTestCase { @@ -36,8 +33,6 @@ protected function setUpTest() { $this->_factory = m::mock('aik099\\PHPUnit\\Session\\ISessionFactory'); $this->strategy = new IsolatedSessionStrategy($this->_factory); - - parent::setUpTest(); } /** @@ -67,25 +62,32 @@ public function testSession() * * @return void */ - public function testOnTestEnd() + public function testOnTestEnded() { $session = m::mock(self::SESSION_CLASS); $session->shouldReceive('stop')->once(); $session->shouldReceive('isStarted')->once()->andReturn(true); $test_case = m::mock(self::TEST_CASE_CLASS); - $test_case->shouldReceive('getSessionStrategy')->once()->andReturn($this->strategy); - - $event = $this->eventDispatcher->dispatch( - BrowserTestCase::TEST_ENDED_EVENT, - new TestEndedEvent( - $test_case, - new TestResult() /* Can't mock, because it's a final class. */, - $session - ) - ); - - $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEndedEvent', $event); + $test_case->shouldReceive('getSession')->with(false)->once()->andReturn($session); + + $this->strategy->onTestEnded($test_case); + } + + public function testOnTestFailed() + { + $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('getSession')->never(); + + $this->strategy->onTestFailed($test_case, new \Exception('test')); + } + + public function testOnTestSuiteEnded() + { + $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('getSession')->never(); + + $this->strategy->onTestSuiteEnded($test_case); } } diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php index b6d4ee9..7ac32f7 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php @@ -136,7 +136,9 @@ private function _getStrategy($strategy_type, $strategy_hash) $browser->shouldReceive('getSessionStrategy')->once()->andReturn($strategy_type); $browser->shouldReceive('getSessionStrategyHash')->once()->andReturn($strategy_hash); - return $this->manager->getSessionStrategy($browser); + $test_case = m::mock('aik099\\PHPUnit\\BrowserTestCase'); + + return $this->manager->getSessionStrategy($browser, $test_case); } } diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php b/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php index d0955c9..7d33e0e 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php @@ -13,7 +13,6 @@ use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Session\ISessionStrategy; -use Symfony\Component\EventDispatcher\EventDispatcher; class SessionStrategyTestCase extends AbstractPHPUnitCompatibilityTestCase { @@ -24,13 +23,6 @@ class SessionStrategyTestCase extends AbstractPHPUnitCompatibilityTestCase const TEST_CASE_CLASS = 'aik099\\PHPUnit\\BrowserTestCase'; - /** - * Event dispatcher. - * - * @var EventDispatcher - */ - protected $eventDispatcher; - /** * Session strategy. * @@ -38,13 +30,4 @@ class SessionStrategyTestCase extends AbstractPHPUnitCompatibilityTestCase */ protected $strategy; - /** - * @before - */ - protected function setUpTest() - { - $this->eventDispatcher = new EventDispatcher(); - $this->strategy->setEventDispatcher($this->eventDispatcher); - } - } diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index 629d950..0de2ff0 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -12,9 +12,6 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Event\TestEvent; -use aik099\PHPUnit\Event\TestFailedEvent; use aik099\PHPUnit\Session\IsolatedSessionStrategy; use aik099\PHPUnit\Session\SharedSessionStrategy; use Behat\Mink\Session; @@ -57,8 +54,6 @@ protected function setUpTest() $this->_isolatedStrategy = m::mock('\\aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'); $this->strategy = new SharedSessionStrategy($this->_isolatedStrategy); - - parent::setUpTest(); } /** @@ -146,16 +141,24 @@ public function testImmediateSessionFailure() * * @param \Exception $e Exception. * - * @return TestFailedEvent + * @return void */ private function _sessionFailure(\Exception $e) { - $event = $this->eventDispatcher->dispatch( - BrowserTestCase::TEST_FAILED_EVENT, - new TestFailedEvent($e, m::mock(self::TEST_CASE_CLASS), $this->_session1) - ); + $this->strategy->onTestFailed(m::mock(self::TEST_CASE_CLASS), $e); + } + + /** + * Test description. + * + * @return void + */ + public function testOnTestEnded() + { + $test_case = m::mock(self::TEST_CASE_CLASS); + $test_case->shouldReceive('getSession')->never(); - return $event; + $this->strategy->onTestEnded($test_case); } /** @@ -170,14 +173,9 @@ public function testEndOfTestCaseWithSession() $session->shouldReceive('isStarted')->once()->andReturn(true); $test_case = m::mock(self::TEST_CASE_CLASS); - $test_case->shouldReceive('getSessionStrategy')->once()->andReturn($this->strategy); - - $event = $this->eventDispatcher->dispatch( - BrowserTestCase::TEST_SUITE_ENDED_EVENT, - new TestEvent($test_case, $session) - ); + $test_case->shouldReceive('getSession')->with(false)->once()->andReturn($session); - $this->assertInstanceOf('aik099\\PHPUnit\\Event\\TestEvent', $event); + $this->strategy->onTestSuiteEnded($test_case); } /** diff --git a/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php deleted file mode 100644 index 27a8281..0000000 --- a/tests/aik099/PHPUnit/TestCase/EventDispatcherAwareTestCase.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace tests\aik099\PHPUnit\TestCase; - - -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; -use Mockery\MockInterface; -use Mockery as m; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; - -class EventDispatcherAwareTestCase extends AbstractPHPUnitCompatibilityTestCase -{ - - /** - * Event dispatcher. - * - * @var EventDispatcherInterface|MockInterface - */ - protected $eventDispatcher; - - /** - * @before - */ - protected function setUpTest() - { - $this->eventDispatcher = m::mock('Symfony\\Component\\EventDispatcher\\EventDispatcherInterface'); - } - - /** - * Expects a specific event to be called. - * - * @param string $event_name Event name. - * - * @return void - */ - protected function expectEvent($event_name) - { - $this->eventDispatcher - ->shouldReceive('dispatch') - ->with($event_name, m::any()) - ->once(); - } - -} diff --git a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php index 4fa3f24..7b3cb62 100644 --- a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\TestSuite; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\TestSuite\BrowserTestSuite; use Mockery as m; -use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; -class BrowserTestSuiteTest extends EventDispatcherAwareTestCase +class BrowserTestSuiteTest extends AbstractPHPUnitCompatibilityTestCase { /** @@ -30,10 +30,7 @@ class BrowserTestSuiteTest extends EventDispatcherAwareTestCase */ protected function setUpTest() { - parent::setUpTest(); - $this->_suite = new BrowserTestSuite(); - $this->_suite->setEventDispatcher($this->eventDispatcher); } /** diff --git a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php index 4b910e8..0be7e58 100644 --- a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\TestSuite; +use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\TestSuite\RegularTestSuite; use Mockery as m; -use tests\aik099\PHPUnit\TestCase\EventDispatcherAwareTestCase; -class RegularTestSuiteTest extends EventDispatcherAwareTestCase +class RegularTestSuiteTest extends AbstractPHPUnitCompatibilityTestCase { /** @@ -44,7 +44,6 @@ public function testSetTestDependencies() $helper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); $test = m::mock('\\aik099\\PHPUnit\\Framework\\Test'); - $test->shouldReceive('setEventDispatcher')->with($this->eventDispatcher)->once(); $test->shouldReceive('setSessionStrategyManager')->with($manager)->once(); $test->shouldReceive('setBrowserConfigurationFactory')->with($factory)->once(); $test->shouldReceive('setRemoteCoverageHelper')->with($helper)->once(); @@ -70,8 +69,6 @@ private function _createSuite(array $mock_methods = array()) $suite = new RegularTestSuite(); } - $suite->setEventDispatcher($this->eventDispatcher); - return $suite; } From 12f65043ad12e3c12dc560bb0e352b9bed3bfdb8 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 12 Mar 2024 12:30:39 +0200 Subject: [PATCH 154/204] Improve PhpStorm auto-complete for DI container --- library/.phpstorm.meta.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 library/.phpstorm.meta.php diff --git a/library/.phpstorm.meta.php b/library/.phpstorm.meta.php new file mode 100644 index 0000000..e26cbbb --- /dev/null +++ b/library/.phpstorm.meta.php @@ -0,0 +1,18 @@ + \aik099\PHPUnit\Session\SessionFactory::class, + 'session_strategy_factory' => \aik099\PHPUnit\Session\SessionStrategyFactory::class, + 'session_strategy_manager' => \aik099\PHPUnit\Session\SessionStrategyManager::class, + 'isolated_session_strategy' => \aik099\PHPUnit\Session\IsolatedSessionStrategy::class, + 'shared_session_strategy' => \aik099\PHPUnit\Session\SharedSessionStrategy::class, + 'remote_url' => \aik099\PHPUnit\RemoteCoverage\RemoteUrl::class, + 'remote_coverage_helper' => \aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper::class, + 'test_suite_factory' => \aik099\PHPUnit\TestSuite\TestSuiteFactory::class, + 'regular_test_suite' => \aik099\PHPUnit\TestSuite\RegularTestSuite::class, + 'browser_test_suite' => \aik099\PHPUnit\TestSuite\BrowserTestSuite::class, + 'driver_factory_registry' => \aik099\PHPUnit\MinkDriver\DriverFactoryRegistry::class, + 'browser_configuration_factory' => \aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory::class, + ])); +} From c680b3082852629d62823d3ee4c95ba503f8e2ee Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 12 Mar 2024 12:32:45 +0200 Subject: [PATCH 155/204] Invoke data provider related code during testing --- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index 562f25c..ae92e2d 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -168,9 +168,12 @@ public function getCollectCodeCoverageInformation() /** * Test description. * - * @return void + * @param boolean $data Data. + * + * @return void + * @dataProvider successDataProvider */ - public function testSuccess() + public function testSuccess($data) { $skip_message = $this->_getTestSkipMessage(); @@ -184,6 +187,14 @@ public function testSuccess() $this->assertTrue(true); } + public function successDataProvider() + { + return array( + 'true' => array(true), + 'false' => array(false), + ); + } + /** * Test description. * From 2f6cc43054950293ec738cba3ef56c571bb54085 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 12 Mar 2024 12:35:00 +0200 Subject: [PATCH 156/204] Use constants from class, that declares them --- tests/aik099/PHPUnit/Fixture/SetupFixture.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/aik099/PHPUnit/Fixture/SetupFixture.php b/tests/aik099/PHPUnit/Fixture/SetupFixture.php index 1aa6b19..f9a2b0e 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupFixture.php @@ -11,6 +11,7 @@ namespace tests\aik099\PHPUnit\Fixture; +use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; @@ -42,7 +43,7 @@ protected function setUpTest() // These magic methods can't be properly passed through to mocked object otherwise. $browser->shouldReceive('getSessionStrategy')->andReturn('isolated'); $browser->shouldReceive('getDesiredCapabilities')->andReturn(array( - SauceLabsBrowserConfiguration::NAME_CAPABILITY => 'something', + ApiBrowserConfiguration::NAME_CAPABILITY => 'something', )); $browser->shouldReceive('getAPIClient')->once()->andReturn($api_client); @@ -90,7 +91,7 @@ public function testEvents() $session = m::mock('Behat\\Mink\\Session'); - // For SauceLabsBrowserConfiguration::onTestEnded. + // For ApiBrowserConfiguration::onTestEnded. $session->shouldReceive('getDriver')->once()->andReturn($driver); $session->shouldReceive('stop')->once(); @@ -98,9 +99,9 @@ public function testEvents() $this->_setSession($session); - // For SauceLabsBrowserConfiguration::onTestSetup. + // For ApiBrowserConfiguration::onTestSetup. $desired_capabilities = $this->getBrowser()->getDesiredCapabilities(); - $this->assertArrayHasKey(SauceLabsBrowserConfiguration::NAME_CAPABILITY, $desired_capabilities); + $this->assertArrayHasKey(ApiBrowserConfiguration::NAME_CAPABILITY, $desired_capabilities); } /** From 2aebb7c7ef8e1f806b2787b99a92f7ec675ec852 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 12 Mar 2024 17:44:15 +0200 Subject: [PATCH 157/204] Specify test name for manually created TestCase objects --- .../BrowserConfigurationTest.php | 4 ++-- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 9f09c06..922e003 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -544,11 +544,11 @@ public function sessionSharingDataProvider() */ public function testGetSessionStrategyHashNotSharing() { - $test_case1 = new WithBrowserConfig(); + $test_case1 = new WithBrowserConfig('test name'); $browser1 = $this->createBrowserConfiguration(); $browser1->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED); - $test_case2 = new WithoutBrowserConfig(); + $test_case2 = new WithoutBrowserConfig('test name'); $browser2 = $this->createBrowserConfiguration(); $browser2->setSessionStrategy(ISessionStrategyFactory::TYPE_SHARED); diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 70d46cc..2a71bf6 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -74,7 +74,7 @@ public function testSetSessionStrategyManager() /* @var $manager SessionStrategyManager */ $manager = m::mock(self::MANAGER_CLASS); - $test_case = new WithoutBrowserConfig(); + $test_case = new WithoutBrowserConfig('test name'); $test_case->setSessionStrategyManager($manager); $property = new \ReflectionProperty($test_case, 'sessionStrategyManager'); @@ -131,7 +131,7 @@ public function testGetBrowserNotSpecified() { $this->expectException('RuntimeException'); - $test_case = new WithoutBrowserConfig(); + $test_case = new WithoutBrowserConfig('test name'); $test_case->getBrowser(); } @@ -167,7 +167,7 @@ public function testSetSessionStrategy() /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - $test_case = new WithoutBrowserConfig(); + $test_case = new WithoutBrowserConfig('test name'); $this->assertSame($test_case, $test_case->setSessionStrategy($session_strategy)); $this->assertSame($session_strategy, $test_case->getSessionStrategy()); } @@ -185,10 +185,10 @@ public function testGetSessionStrategySharing() $manager->shouldReceive('getDefaultSessionStrategy')->twice()->andReturn('STRATEGY'); - $test_case1 = new WithoutBrowserConfig(); + $test_case1 = new WithoutBrowserConfig('test name'); $test_case1->setSessionStrategyManager($manager); - $test_case2 = new WithBrowserConfig(); + $test_case2 = new WithBrowserConfig('test name'); $test_case2->setSessionStrategyManager($manager); $this->assertSame($test_case1->getSessionStrategy(), $test_case2->getSessionStrategy()); @@ -575,7 +575,7 @@ public function testEndOfTestCase() /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - $test_case = new WithoutBrowserConfig(); + $test_case = new WithoutBrowserConfig('test name'); $test_case->setSessionStrategy($session_strategy); $session_strategy->shouldReceive('onTestSuiteEnded')->with($test_case)->once(); @@ -668,7 +668,7 @@ protected function getFixture(ISessionStrategy $session_strategy = null, array $ $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase[' . implode(',', $mock_methods) . ']'); } else { - $test_case = new WithoutBrowserConfig(); + $test_case = new WithoutBrowserConfig('test name'); } $test_case->setBrowserConfigurationFactory($this->browserConfigurationFactory); From 63a15fdc46c7a786aba61f04516eed6019a73226 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 12 Mar 2024 18:33:25 +0200 Subject: [PATCH 158/204] Optimize imports --- .../PHPUnit/BrowserConfiguration/BrowserConfiguration.php | 2 +- library/aik099/PHPUnit/Session/SessionStrategyFactory.php | 2 +- library/aik099/PHPUnit/Session/SharedSessionStrategy.php | 2 +- library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php | 2 +- library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php | 2 +- tests/aik099/PHPUnit/ApplicationTest.php | 1 - .../ApiBrowserConfigurationTestCase.php | 4 ++-- .../BrowserConfiguration/BrowserConfigurationTest.php | 3 +-- .../BrowserStackBrowserConfigurationTest.php | 2 -- .../SauceLabsBrowserConfigurationTest.php | 2 -- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 6 +++--- tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php | 1 - tests/aik099/PHPUnit/Fixture/SetupFixture.php | 1 - tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php | 4 ++-- tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php | 1 - .../PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php | 1 - tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php | 1 - tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php | 4 ++-- tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php | 2 +- 19 files changed, 16 insertions(+), 27 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index ba20eda..3838eda 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -12,11 +12,11 @@ use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; use aik099\PHPUnit\Session\ISessionStrategyFactory; use Behat\Mink\Driver\DriverInterface; -use aik099\PHPUnit\Framework\TestResult; /** * Browser configuration for browser. diff --git a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php index b94ff55..f748a1d 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php @@ -11,8 +11,8 @@ namespace aik099\PHPUnit\Session; -use aik099\PHPUnit\IApplicationAware; use aik099\PHPUnit\Application; +use aik099\PHPUnit\IApplicationAware; /** * Produces sessions. diff --git a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php index 99f6a84..3b4200c 100644 --- a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -13,9 +13,9 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; -use Behat\Mink\Session; use aik099\PHPUnit\Framework\IncompleteTestError; use aik099\PHPUnit\Framework\SkippedTestError; +use Behat\Mink\Session; /** * Keeps a Session object shared between test runs to save time. diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index b4c0d63..eb5ba02 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -14,9 +14,9 @@ use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestSuite; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Framework\DataProviderTestSuite; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\Session\SessionStrategyManager; -use aik099\PHPUnit\Framework\DataProviderTestSuite; use PHPUnit\Util\Test as TestUtil; /** diff --git a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php index a199875..8baf702 100644 --- a/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php +++ b/library/aik099/PHPUnit/TestSuite/TestSuiteFactory.php @@ -11,11 +11,11 @@ namespace aik099\PHPUnit\TestSuite; +use aik099\PHPUnit\Application; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\IApplicationAware; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\Session\SessionStrategyManager; -use aik099\PHPUnit\Application; /** * Creates test suites based on test case class configuration. diff --git a/tests/aik099/PHPUnit/ApplicationTest.php b/tests/aik099/PHPUnit/ApplicationTest.php index f88797b..98e2d6c 100644 --- a/tests/aik099/PHPUnit/ApplicationTest.php +++ b/tests/aik099/PHPUnit/ApplicationTest.php @@ -13,7 +13,6 @@ use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Application; -use Mockery as m; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; class ApplicationTest extends AbstractPHPUnitCompatibilityTestCase diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index ff430b4..c617579 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -13,9 +13,9 @@ use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; -use aik099\PHPUnit\Session\ISessionStrategyFactory; -use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Framework\TestResult; +use aik099\PHPUnit\Session\ISessionStrategyFactory; use Mockery as m; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 922e003..0787467 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -15,11 +15,10 @@ use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use aik099\PHPUnit\Session\ISessionStrategyFactory; use Mockery as m; -use Mockery\Generator\MockConfigurationBuilder; -use aik099\PHPUnit\Framework\TestResult; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php index ad9f675..6d5f1ee 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -11,8 +11,6 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; -use Mockery as m; - class BrowserStackBrowserConfigurationTest extends ApiBrowserConfigurationTestCase { diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 2014411..590a5e0 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -11,8 +11,6 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; -use Mockery as m; - class SauceLabsBrowserConfigurationTest extends ApiBrowserConfigurationTestCase { diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 2a71bf6..bf33de1 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -15,16 +15,16 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageTool; use aik099\PHPUnit\Session\ISessionStrategy; use aik099\PHPUnit\Session\SessionStrategyManager; -use Mockery as m; -use Mockery\MockInterface; -use aik099\PHPUnit\Framework\TestResult; use aik099\SebastianBergmann\CodeCoverage\CodeCoverage; use aik099\SebastianBergmann\CodeCoverage\Filter; +use Mockery as m; +use Mockery\MockInterface; use SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData; use SebastianBergmann\CodeCoverage\RawCodeCoverageData; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index ae92e2d..31a77b8 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -15,7 +15,6 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; -use Mockery as m; class ApiIntegrationFixture extends BrowserTestCase { diff --git a/tests/aik099/PHPUnit/Fixture/SetupFixture.php b/tests/aik099/PHPUnit/Fixture/SetupFixture.php index f9a2b0e..3cacb94 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupFixture.php @@ -13,7 +13,6 @@ use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; -use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Behat\Mink\Session; diff --git a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php index ca96faf..5509d2a 100644 --- a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php @@ -13,13 +13,13 @@ use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserTestCase; +use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\TestSuite\BrowserTestSuite; use aik099\PHPUnit\TestSuite\RegularTestSuite; -use aik099\PHPUnit\Framework\TestResult; +use Mockery as m; use PHPUnit\Runner\Version; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; -use Mockery as m; class SuiteBuildingTest extends AbstractPHPUnitCompatibilityTestCase { diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php index c2d4930..ed9d03f 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php @@ -16,7 +16,6 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\DIContainer; use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; -use Mockery as m; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; class DriverFactoryTest extends AbstractPHPUnitCompatibilityTestCase diff --git a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php index 6140e2f..9e6cdcd 100644 --- a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php +++ b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php @@ -16,7 +16,6 @@ use aik099\PHPUnit\RemoteCoverage\RemoteUrl; use Mockery as m; use Mockery\MockInterface; -use SebastianBergmann\CodeCoverage\RawCodeCoverageData; use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php index 7106fb1..610d9bf 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php @@ -13,7 +13,6 @@ use aik099\PHPUnit\Session\ISessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyFactory; -use Mockery as m; use tests\aik099\PHPUnit\TestCase\ApplicationAwareTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index 0de2ff0..8486bf6 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -12,13 +12,13 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\Framework\IncompleteTestError; +use aik099\PHPUnit\Framework\SkippedTestError; use aik099\PHPUnit\Session\IsolatedSessionStrategy; use aik099\PHPUnit\Session\SharedSessionStrategy; use Behat\Mink\Session; use Mockery as m; use Mockery\MockInterface; -use aik099\PHPUnit\Framework\IncompleteTestError; -use aik099\PHPUnit\Framework\SkippedTestError; class SharedSessionStrategyTest extends SessionStrategyTestCase { diff --git a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php index 8429b8c..fff75a6 100644 --- a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php +++ b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php @@ -13,8 +13,8 @@ use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Application; -use Mockery\MockInterface; use Mockery as m; +use Mockery\MockInterface; class ApplicationAwareTestCase extends AbstractPHPUnitCompatibilityTestCase { From 205a103c236f161a1d75d22e6455e5547ddd4429 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 25 Feb 2024 17:57:47 +0200 Subject: [PATCH 159/204] Split-out PHPUnit compatibility layer into a standalone project --- composer.json | 3 +- composer.lock | 51 +++++++- .../AbstractPHPUnitCompatibilityTestCase.php | 121 ------------------ .../AbstractPHPUnitCompatibilityTestCase5.php | 63 --------- .../AbstractPHPUnitCompatibilityTestCase7.php | 87 ------------- .../AbstractPHPUnitCompatibilityTestSuite.php | 59 --------- ...AbstractPHPUnitCompatibilityTestSuite5.php | 75 ----------- ...AbstractPHPUnitCompatibilityTestSuite7.php | 108 ---------------- .../ApiBrowserConfiguration.php | 2 +- .../BrowserConfiguration.php | 2 +- library/aik099/PHPUnit/BrowserTestCase.php | 11 +- .../PHPUnit/Session/ISessionStrategy.php | 2 +- .../PHPUnit/Session/SharedSessionStrategy.php | 4 +- .../PHPUnit/TestSuite/AbstractTestSuite.php | 10 +- .../PHPUnit/TestSuite/BrowserTestSuite.php | 2 +- tests/aik099/PHPUnit/AbstractTestCase.php | 39 ++++++ tests/aik099/PHPUnit/ApplicationTest.php | 3 +- .../ApiBrowserConfigurationTestCase.php | 2 +- .../BrowserConfigurationFactoryTest.php | 4 +- .../BrowserConfigurationTest.php | 6 +- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 17 ++- .../Integration/ApiIntegrationTest.php | 6 +- .../PHPUnit/Integration/DIContainerTest.php | 4 +- .../Integration/EventDispatchingTest.php | 6 +- .../PHPUnit/Integration/SuiteBuildingTest.php | 6 +- .../MinkDriver/DriverFactoryRegistryTest.php | 4 +- .../PHPUnit/MinkDriver/DriverFactoryTest.php | 4 +- .../RemoteCoverageHelperTest.php | 4 +- .../PHPUnit/RemoteCoverage/RemoteUrlTest.php | 4 +- .../PHPUnit/Session/SessionFactoryTest.php | 4 +- .../Session/SessionStrategyManagerTest.php | 4 +- .../Session/SessionStrategyTestCase.php | 4 +- .../Session/SharedSessionStrategyTest.php | 4 +- .../TestCase/ApplicationAwareTestCase.php | 4 +- .../TestSuite/BrowserTestSuiteTest.php | 6 +- .../TestSuite/RegularTestSuiteTest.php | 6 +- 36 files changed, 156 insertions(+), 585 deletions(-) delete mode 100644 library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase.php delete mode 100644 library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase5.php delete mode 100644 library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase7.php delete mode 100644 library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite.php delete mode 100644 library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite5.php delete mode 100644 library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite7.php create mode 100644 tests/aik099/PHPUnit/AbstractTestCase.php diff --git a/composer.json b/composer.json index fa8af6b..4f16ef4 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ "php": ">=5.6", "behat/mink": "~1.6@dev", "behat/mink-selenium2-driver": "~1.2", - "phpunit/phpunit": ">=4.8.35 <5|>=5.4.3" + "phpunit/phpunit": ">=4.8.35 <5|>=5.4.3", + "console-helpers/phpunit-compat": "^1.0.2" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 5ba2ba0..6be74ea 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "48f60d5675361c47fa38c2ea9526af97", + "content-hash": "494c2858cc1bd23a8dc3131ef787d0c6", "packages": [ { "name": "behat/mink", @@ -137,6 +137,55 @@ }, "time": "2021-10-12T16:01:47+00:00" }, + { + "name": "console-helpers/phpunit-compat", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/console-helpers/phpunit-compat.git", + "reference": "ec8608c3863d75b0389ebb5c0a1f5703b638c451" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/console-helpers/phpunit-compat/zipball/ec8608c3863d75b0389ebb5c0a1f5703b638c451", + "reference": "ec8608c3863d75b0389ebb5c0a1f5703b638c451", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "require-dev": { + "aik099/coding-standard": "dev-master" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "ConsoleHelpers\\PHPUnitCompat\\": "src/PHPUnitCompat/", + "Tests\\ConsoleHelpers\\PHPUnitCompat\\": "tests/PHPUnitCompat/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Alexander Obuhovich", + "email": "aik.bold@gmail.com" + } + ], + "description": "Compatibility layer for PHPUnit test cases/test suite to work on different major PHPUnit versions", + "support": { + "issues": "https://github.com/console-helpers/phpunit-compat/issues", + "source": "https://github.com/console-helpers/phpunit-compat/tree/v1.0.1" + }, + "time": "2024-03-03T21:01:14+00:00" + }, { "name": "doctrine/instantiator", "version": "1.0.5", diff --git a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase.php b/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase.php deleted file mode 100644 index a2234bc..0000000 --- a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit; - - -use PHPUnit\Runner\Version; - -if ( \class_exists('\PHPUnit_Framework_IncompleteTestError') ) { - \class_alias('\PHPUnit_Framework_IncompleteTestError', '\aik099\PHPUnit\Framework\IncompleteTestError'); -} -else { - \class_alias('\PHPUnit\Framework\IncompleteTestError', '\aik099\PHPUnit\Framework\IncompleteTestError'); -} - -if ( class_exists('\PHPUnit_Framework_SkippedTestError') ) { - \class_alias('\PHPUnit_Framework_SkippedTestError', '\aik099\PHPUnit\Framework\SkippedTestError'); -} -else { - \class_alias('\PHPUnit\Framework\SkippedTestError', '\aik099\PHPUnit\Framework\SkippedTestError'); -} - -if ( class_exists('\PHPUnit_Framework_TestSuite_DataProvider') ) { - \class_alias('\PHPUnit_Framework_TestSuite_DataProvider', '\aik099\PHPUnit\Framework\DataProviderTestSuite'); -} -else { - \class_alias('\PHPUnit\Framework\DataProviderTestSuite', '\aik099\PHPUnit\Framework\DataProviderTestSuite'); -} - -if ( class_exists('\PHPUnit_Framework_TestResult') ) { - \class_alias('\PHPUnit_Framework_TestResult', '\aik099\PHPUnit\Framework\TestResult'); -} -else { - \class_alias('\PHPUnit\Framework\TestResult', '\aik099\PHPUnit\Framework\TestResult'); -} - -if ( class_exists('\PHPUnit_Framework_Test') ) { - \class_alias('\PHPUnit_Framework_Test', '\aik099\PHPUnit\Framework\Test'); -} -else { - \class_alias('\PHPUnit\Framework\Test', '\aik099\PHPUnit\Framework\Test'); -} - -if ( class_exists('\PHP_CodeCoverage') ) { - \class_alias('\PHP_CodeCoverage', '\aik099\SebastianBergmann\CodeCoverage\CodeCoverage'); -} -else { - \class_alias('\SebastianBergmann\CodeCoverage\CodeCoverage', '\aik099\SebastianBergmann\CodeCoverage\CodeCoverage'); -} - -if ( \interface_exists('\PHP_CodeCoverage_Driver') ) { - \class_alias('\PHP_CodeCoverage_Driver', '\aik099\SebastianBergmann\CodeCoverage\Driver\Driver'); -} -else { - \class_alias('\SebastianBergmann\CodeCoverage\Driver\Driver', '\aik099\SebastianBergmann\CodeCoverage\Driver\Driver'); -} - -if ( class_exists('\PHP_CodeCoverage_Filter') ) { - \class_alias('\PHP_CodeCoverage_Filter', '\aik099\SebastianBergmann\CodeCoverage\Filter'); -} -else { - \class_alias('\SebastianBergmann\CodeCoverage\Filter', '\aik099\SebastianBergmann\CodeCoverage\Filter'); -} - -if ( \class_exists('PHPUnit\Runner\Version') ) { - $runner_version = Version::id(); -} -else { - $runner_version = \PHPUnit_Runner_Version::id(); -} - - -/** - * @codeCoverageIgnore - */ -trait TAbstractPHPUnitCompatibilityTestCase -{ - - /** - * This method is called when a test method did not execute successfully. - * - * @param \Exception|\Throwable $e Exception. - * - * @return void - */ - protected function onNotSuccessfulTestCompatibilized($e) - { - - } - - /** - * @after - */ - protected function verifyMockeryExpectations() - { - if ( \class_exists('Mockery') ) { - // Add Mockery expectations to assertion count. - if ( ($container = \Mockery::getContainer()) !== null ) { - $this->addToAssertionCount($container->mockery_getExpectationCount()); - } - - // Verify Mockery expectations. - \Mockery::close(); - } - } - -} - -if ( version_compare($runner_version, '6.0.0', '<') ) { - require_once __DIR__ . '/AbstractPHPUnitCompatibilityTestCase5.php'; -} -else { - require_once __DIR__ . '/AbstractPHPUnitCompatibilityTestCase7.php'; -} diff --git a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase5.php b/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase5.php deleted file mode 100644 index 513e13d..0000000 --- a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase5.php +++ /dev/null @@ -1,63 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit; - - -use PHPUnit\Framework\TestCase; - -if ( version_compare($runner_version, '5.0.0', '<') ) { - /** - * Implementation for PHPUnit 4 - * - * @internal - * @codeCoverageIgnore - */ - abstract class AbstractPHPUnitCompatibilityTestCase extends TestCase - { - - use TAbstractPHPUnitCompatibilityTestCase; - - /** - * @inheritDoc - */ - protected function onNotSuccessfulTest(\Exception $e) - { - $this->onNotSuccessfulTestCompatibilized($e); - - parent::onNotSuccessfulTest($e); - } - - } -} -elseif ( version_compare($runner_version, '6.0.0', '<') ) { - /** - * Implementation for PHPUnit 5 - * - * @internal - * @codeCoverageIgnore - */ - abstract class AbstractPHPUnitCompatibilityTestCase extends TestCase - { - - use TAbstractPHPUnitCompatibilityTestCase; - - /** - * @inheritDoc - */ - protected function onNotSuccessfulTest($e) - { - $this->onNotSuccessfulTestCompatibilized($e); - - parent::onNotSuccessfulTest($e); - } - - } -} diff --git a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase7.php b/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase7.php deleted file mode 100644 index 1bcea3a..0000000 --- a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestCase7.php +++ /dev/null @@ -1,87 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit; - - -use PHPUnit\Framework\TestCase; - -if ( version_compare($runner_version, '7.0.0', '<') ) { - /** - * Implementation for PHPUnit 6 - * - * @internal - * @codeCoverageIgnore - */ - abstract class AbstractPHPUnitCompatibilityTestCase extends TestCase - { - - use TAbstractPHPUnitCompatibilityTestCase; - - /** - * @inheritDoc - */ - protected function onNotSuccessfulTest(\Throwable $t) - { - $this->onNotSuccessfulTestCompatibilized($t); - - parent::onNotSuccessfulTest($t); - } - - } -} -elseif ( version_compare($runner_version, '8.0.0', '<') ) { - /** - * Implementation for PHPUnit 7 - * - * @internal - * @codeCoverageIgnore - */ - abstract class AbstractPHPUnitCompatibilityTestCase extends TestCase - { - - use TAbstractPHPUnitCompatibilityTestCase; - - /** - * @inheritDoc - */ - protected function onNotSuccessfulTest(\Throwable $t)/* The :void return type declaration that should be here would cause a BC issue */ - { - $this->onNotSuccessfulTestCompatibilized($t); - - parent::onNotSuccessfulTest($t); - } - - } -} -else { - /** - * Implementation for PHPUnit 8+ - * - * @internal - * @codeCoverageIgnore - */ - abstract class AbstractPHPUnitCompatibilityTestCase extends TestCase - { - - use TAbstractPHPUnitCompatibilityTestCase; - - /** - * @inheritDoc - */ - protected function onNotSuccessfulTest(\Throwable $t): void - { - $this->onNotSuccessfulTestCompatibilized($t); - - parent::onNotSuccessfulTest($t); - } - - } -} diff --git a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite.php b/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite.php deleted file mode 100644 index 5ed8fc8..0000000 --- a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit; - - -use PHPUnit\Framework\TestResult; -use PHPUnit\Runner\Version; - -if ( \class_exists('PHPUnit\Runner\Version') ) { - $runner_version = Version::id(); -} -else { - $runner_version = \PHPUnit_Runner_Version::id(); -} - - -/* - * @codeCoverageIgnore - */ -trait TAbstractPHPUnitCompatibilityTestSuite -{ - - /** - * Runs the tests and collects their result in a TestResult. - * - * @param TestResult $result Test result. - * - * @return TestResult - */ - public function runCompatibilized($result = null) - { - return parent::run($result); - } - - /** - * Template Method that is called after the tests - * of this test suite have finished running. - */ - protected function tearDownCompatibilized() - { - - } - -} - -if ( version_compare($runner_version, '6.0.0', '<') ) { - require_once __DIR__ . '/AbstractPHPUnitCompatibilityTestSuite5.php'; -} -else { - require_once __DIR__ . '/AbstractPHPUnitCompatibilityTestSuite7.php'; -} diff --git a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite5.php b/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite5.php deleted file mode 100644 index 1c29c70..0000000 --- a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite5.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit; - - -use PHPUnit\Framework\TestSuite; - -if ( version_compare($runner_version, '5.0.0', '<') ) { - /** - * Implementation for PHPUnit 4 - * - * @internal - * @codeCoverageIgnore - */ - abstract class AbstractPHPUnitCompatibilityTestSuite extends TestSuite - { - - use TAbstractPHPUnitCompatibilityTestSuite; - - /** - * @inheritDoc - */ - public function run(\PHPUnit_Framework_TestResult $result = null) - { - return $this->runCompatibilized($result); - } - - /** - * @inheritDoc - */ - protected function tearDown() - { - $this->tearDownCompatibilized(); - } - - } -} -elseif ( version_compare($runner_version, '6.0.0', '<') ) { - /** - * Implementation for PHPUnit 5 - * - * @internal - * @codeCoverageIgnore - */ - abstract class AbstractPHPUnitCompatibilityTestSuite extends TestSuite - { - - use TAbstractPHPUnitCompatibilityTestSuite; - - /** - * @inheritDoc - */ - public function run(\PHPUnit_Framework_TestResult $result = null) - { - return $this->runCompatibilized($result); - } - - /** - * @inheritDoc - */ - protected function tearDown() - { - $this->tearDownCompatibilized(); - } - - } -} diff --git a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite7.php b/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite7.php deleted file mode 100644 index e5857b1..0000000 --- a/library/aik099/PHPUnit/AbstractPHPUnitCompatibilityTestSuite7.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit; - - -use PHPUnit\Framework\TestResult; -use PHPUnit\Framework\TestSuite; - -if ( version_compare($runner_version, '7.0.0', '<') ) { - /** - * Implementation for PHPUnit 6 - * - * @internal - * @codeCoverageIgnore - */ - abstract class AbstractPHPUnitCompatibilityTestSuite extends TestSuite - { - - use TAbstractPHPUnitCompatibilityTestSuite; - - /** - * @inheritDoc - */ - public function run(TestResult $result = null) - { - return $this->runCompatibilized($result); - } - - /** - * @inheritDoc - */ - protected function tearDown() - { - $this->tearDownCompatibilized(); - } - - } -} -elseif ( version_compare($runner_version, '8.0.0', '<') ) { - /** - * Implementation for PHPUnit 7 - * - * @internal - * @codeCoverageIgnore - */ - abstract class AbstractPHPUnitCompatibilityTestSuite extends TestSuite - { - - use TAbstractPHPUnitCompatibilityTestSuite; - - /** - * @inheritDoc - */ - public function run(TestResult $result = null): TestResult - { - return $this->runCompatibilized($result); - } - - /** - * @inheritDoc - */ - protected function tearDown(): void - { - $this->tearDownCompatibilized(); - } - - } -} -else { - /** - * Implementation for PHPUnit 8+ - * - * @internal - * @codeCoverageIgnore - */ - abstract class AbstractPHPUnitCompatibilityTestSuite extends TestSuite - { - - use TAbstractPHPUnitCompatibilityTestSuite; - - /** - * @inheritDoc - */ - public function run(TestResult $result = null): TestResult - { - return $this->runCompatibilized($result); - } - - /** - * For PHPUnit < 8.2.0. - * - * @inheritDoc - */ - protected function tearDown(): void - { - $this->tearDownCompatibilized(); - } - - } -} diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index 6214e7c..8afa082 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -13,10 +13,10 @@ use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Behat\Mink\Driver\Selenium2Driver; use Behat\Mink\Session; +use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; /** * Browser configuration tailored to use with API-based service. diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 3838eda..1f5520b 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -12,11 +12,11 @@ use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; use aik099\PHPUnit\Session\ISessionStrategyFactory; use Behat\Mink\Driver\DriverInterface; +use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; /** * Browser configuration for browser. diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 2fce0ed..133e6fa 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -20,6 +20,7 @@ use aik099\PHPUnit\TestSuite\RegularTestSuite; use Behat\Mink\Exception\DriverException; use Behat\Mink\Session; +use ConsoleHelpers\PHPUnitCompat\AbstractTestCase; use SebastianBergmann\CodeCoverage\RawCodeCoverageData; /** @@ -27,7 +28,7 @@ * * @method \Mockery\Expectation shouldReceive(string $name) */ -abstract class BrowserTestCase extends AbstractPHPUnitCompatibilityTestCase +abstract class BrowserTestCase extends AbstractTestCase { /** @@ -372,13 +373,9 @@ public static function suite($class_name) } /** - * This method is called when a test method did not execute successfully. - * - * @param \Exception|\Throwable $e Exception. - * - * @return void + * @inheritDoc */ - protected function onNotSuccessfulTestCompatibilized($e) + protected function onNotSuccessfulTestCompat($e) { if ( $this->sessionStrategy !== null ) { $this->sessionStrategy->onTestFailed($this, $e); diff --git a/library/aik099/PHPUnit/Session/ISessionStrategy.php b/library/aik099/PHPUnit/Session/ISessionStrategy.php index ce82e91..41656f0 100644 --- a/library/aik099/PHPUnit/Session/ISessionStrategy.php +++ b/library/aik099/PHPUnit/Session/ISessionStrategy.php @@ -43,7 +43,7 @@ public function session(BrowserConfiguration $browser); public function onTestEnded(BrowserTestCase $test_case); /** - * Hook, called from "BrowserTestCase::onNotSuccessfulTestCompatibilized" method. + * Hook, called from "BrowserTestCase::onNotSuccessfulTestCompat" method. * * @param BrowserTestCase $test_case Test case. * @param \Exception|\Throwable $exception Exception. diff --git a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php index 3b4200c..9a8b4f6 100644 --- a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -13,9 +13,9 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Framework\IncompleteTestError; -use aik099\PHPUnit\Framework\SkippedTestError; use Behat\Mink\Session; +use ConsoleHelpers\PHPUnitCompat\Framework\IncompleteTestError; +use ConsoleHelpers\PHPUnitCompat\Framework\SkippedTestError; /** * Keeps a Session object shared between test runs to save time. diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index eb5ba02..06b3cba 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -11,12 +11,12 @@ namespace aik099\PHPUnit\TestSuite; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestSuite; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Framework\DataProviderTestSuite; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\Session\SessionStrategyManager; +use ConsoleHelpers\PHPUnitCompat\AbstractTestSuite as PHPUnitCompatAbstractTestSuite; +use ConsoleHelpers\PHPUnitCompat\Framework\DataProviderTestSuite; use PHPUnit\Util\Test as TestUtil; /** @@ -24,7 +24,7 @@ * * @method \Mockery\Expectation shouldReceive(string $name) */ -abstract class AbstractTestSuite extends AbstractPHPUnitCompatibilityTestSuite +abstract class AbstractTestSuite extends PHPUnitCompatAbstractTestSuite { /** @@ -122,9 +122,9 @@ public function setTestDependencies( /** * @inheritDoc */ - public function runCompatibilized($result = null) + public function runCompat($result = null) { - $result = parent::runCompatibilized($result); + $result = parent::runCompat($result); $this->triggerTestSuiteEnded(); diff --git a/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php b/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php index 2cf94f2..d92f6c5 100644 --- a/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php @@ -12,7 +12,7 @@ use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Framework\DataProviderTestSuite; +use ConsoleHelpers\PHPUnitCompat\Framework\DataProviderTestSuite; /** * Test Suite class for a set of tests from a single Test Case Class executed with a particular browser. diff --git a/tests/aik099/PHPUnit/AbstractTestCase.php b/tests/aik099/PHPUnit/AbstractTestCase.php new file mode 100644 index 0000000..c1f1e4a --- /dev/null +++ b/tests/aik099/PHPUnit/AbstractTestCase.php @@ -0,0 +1,39 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit; + + +use PHPUnit\Framework\TestCase; + +abstract class AbstractTestCase extends TestCase +{ + + /** + * @after + */ + protected function verifyMockeryExpectations() + { + if ( !\class_exists('Mockery') ) { + return; + } + + // Add Mockery expectations to assertion count. + $container = \Mockery::getContainer(); + + if ( $container !== null ) { + $this->addToAssertionCount($container->mockery_getExpectationCount()); + } + + // Verify Mockery expectations. + \Mockery::close(); + } + +} diff --git a/tests/aik099/PHPUnit/ApplicationTest.php b/tests/aik099/PHPUnit/ApplicationTest.php index 98e2d6c..407c582 100644 --- a/tests/aik099/PHPUnit/ApplicationTest.php +++ b/tests/aik099/PHPUnit/ApplicationTest.php @@ -11,11 +11,10 @@ namespace tests\aik099\PHPUnit; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Application; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class ApplicationTest extends AbstractPHPUnitCompatibilityTestCase +class ApplicationTest extends AbstractTestCase { use ExpectException; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index c617579..8b734e8 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -14,8 +14,8 @@ use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\Session\ISessionStrategyFactory; +use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; use Mockery as m; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index f183dc0..4e0ea48 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -11,14 +11,14 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Mockery as m; +use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class BrowserConfigurationFactoryTest extends AbstractPHPUnitCompatibilityTestCase +class BrowserConfigurationFactoryTest extends AbstractTestCase { use ExpectException; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 0787467..e6af1e0 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -11,19 +11,19 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use aik099\PHPUnit\Session\ISessionStrategyFactory; +use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; use Mockery as m; +use tests\aik099\PHPUnit\AbstractTestCase; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class BrowserConfigurationTest extends AbstractPHPUnitCompatibilityTestCase +class BrowserConfigurationTest extends AbstractTestCase { use ExpectException; diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index bf33de1..42b8e7c 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -11,18 +11,17 @@ namespace tests\aik099\PHPUnit; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageTool; use aik099\PHPUnit\Session\ISessionStrategy; use aik099\PHPUnit\Session\SessionStrategyManager; -use aik099\SebastianBergmann\CodeCoverage\CodeCoverage; -use aik099\SebastianBergmann\CodeCoverage\Filter; +use ConsoleHelpers\CodeCoverageCompat\CodeCoverage; +use ConsoleHelpers\CodeCoverageCompat\Filter; +use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; use Mockery as m; use Mockery\MockInterface; use SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData; @@ -31,7 +30,7 @@ use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class BrowserTestCaseTest extends AbstractPHPUnitCompatibilityTestCase +class BrowserTestCaseTest extends AbstractTestCase { use ExpectException; @@ -282,7 +281,7 @@ public function testGetCollectCodeCoverageInformationSuccess() } else { $code_coverage = new CodeCoverage( - m::mock('\\aik099\\SebastianBergmann\\CodeCoverage\\Driver\\Driver'), + m::mock('\\ConsoleHelpers\\CodeCoverageCompat\\Driver\\Driver'), new Filter() ); } @@ -321,7 +320,7 @@ public function testRunCreateResult() /* @var $test_case BrowserTestCase */ list($test_case,) = $this->prepareForRun(); - $this->assertInstanceOf('\\aik099\\PHPUnit\\Framework\\TestResult', $test_case->run()); + $this->assertInstanceOf('\\ConsoleHelpers\\PHPUnitCompat\\Framework\\TestResult', $test_case->run()); } /** @@ -449,7 +448,7 @@ public function testRunWithCoverage() $expected_coverage->setLineCoverage(array( $this->getCoverageFixtureFile() => array( 8 => array(), // Means, that this test hasn't executed a tested code. - 13 => array($covered_by_test, $covered_by_test), // Means, covered by this test twice. + 13 => array($covered_by_test), ), )); $actual_coverage = $code_coverage->getData(); @@ -536,7 +535,7 @@ protected function getCodeCoverageMock(array $expected_coverage) $driver = m::mock('\PHP_CodeCoverage_Driver'); } else { - $driver = m::mock('\\aik099\\SebastianBergmann\\CodeCoverage\\Driver\\Driver'); + $driver = m::mock('\\ConsoleHelpers\\CodeCoverageCompat\\Driver\\Driver'); } $driver->shouldReceive('start')->once(); diff --git a/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php b/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php index 2a9d318..82a1e47 100644 --- a/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php +++ b/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\Integration; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; -use aik099\PHPUnit\Framework\TestResult; +use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; +use tests\aik099\PHPUnit\AbstractTestCase; use tests\aik099\PHPUnit\Fixture\ApiIntegrationFixture; -class ApiIntegrationTest extends AbstractPHPUnitCompatibilityTestCase +class ApiIntegrationTest extends AbstractTestCase { /** diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index a46f8bd..fa7899a 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\Integration; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Application; use aik099\PHPUnit\DIContainer; +use tests\aik099\PHPUnit\AbstractTestCase; -class DIContainerTest extends AbstractPHPUnitCompatibilityTestCase +class DIContainerTest extends AbstractTestCase { /** diff --git a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php index c9cd6a3..e4f21c5 100644 --- a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php +++ b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\Integration; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; -use aik099\PHPUnit\Framework\TestResult; +use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; +use tests\aik099\PHPUnit\AbstractTestCase; use tests\aik099\PHPUnit\Fixture\SetupFixture; -class EventDispatchingTest extends AbstractPHPUnitCompatibilityTestCase +class EventDispatchingTest extends AbstractTestCase { /** diff --git a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php index 5509d2a..690584e 100644 --- a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php @@ -11,17 +11,17 @@ namespace tests\aik099\PHPUnit\Integration; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserTestCase; -use aik099\PHPUnit\Framework\TestResult; use aik099\PHPUnit\TestSuite\BrowserTestSuite; use aik099\PHPUnit\TestSuite\RegularTestSuite; +use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; use Mockery as m; use PHPUnit\Runner\Version; +use tests\aik099\PHPUnit\AbstractTestCase; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; -class SuiteBuildingTest extends AbstractPHPUnitCompatibilityTestCase +class SuiteBuildingTest extends AbstractTestCase { const SUITE_CLASS = '\\aik099\\PHPUnit\\TestSuite\\RegularTestSuite'; diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php index 6be3e48..c23d99d 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php @@ -12,12 +12,12 @@ namespace tests\aik099\PHPUnit\MinkDriver; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Mockery as m; +use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class DriverFactoryRegistryTest extends AbstractPHPUnitCompatibilityTestCase +class DriverFactoryRegistryTest extends AbstractTestCase { use ExpectException; diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php index ed9d03f..5c51afc 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php @@ -12,13 +12,13 @@ namespace tests\aik099\PHPUnit\MinkDriver; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\DIContainer; use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; +use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class DriverFactoryTest extends AbstractPHPUnitCompatibilityTestCase +class DriverFactoryTest extends AbstractTestCase { use ExpectException; diff --git a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php index 9e6cdcd..e49f53d 100644 --- a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php +++ b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php @@ -11,15 +11,15 @@ namespace tests\aik099\PHPUnit\RemoteCoverage; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteUrl; use Mockery as m; use Mockery\MockInterface; +use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class RemoteCoverageHelperTest extends AbstractPHPUnitCompatibilityTestCase +class RemoteCoverageHelperTest extends AbstractTestCase { use ExpectException, AssertIsType; diff --git a/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php b/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php index 2e3c1cb..600cc90 100644 --- a/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php +++ b/tests/aik099/PHPUnit/RemoteCoverage/RemoteUrlTest.php @@ -11,10 +11,10 @@ namespace tests\aik099\PHPUnit\RemoteCoverage; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\RemoteCoverage\RemoteUrl; +use tests\aik099\PHPUnit\AbstractTestCase; -class RemoteUrlTest extends AbstractPHPUnitCompatibilityTestCase +class RemoteUrlTest extends AbstractTestCase { /** diff --git a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php index 45813d4..7a8677a 100644 --- a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php +++ b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\Session; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Session\SessionFactory; use Mockery as m; +use tests\aik099\PHPUnit\AbstractTestCase; -class SessionFactoryTest extends AbstractPHPUnitCompatibilityTestCase +class SessionFactoryTest extends AbstractTestCase { /** diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php index 7ac32f7..4f584e3 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php @@ -11,14 +11,14 @@ namespace tests\aik099\PHPUnit\Session; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Session\ISessionStrategy; use aik099\PHPUnit\Session\ISessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyManager; use Mockery as m; +use tests\aik099\PHPUnit\AbstractTestCase; -class SessionStrategyManagerTest extends AbstractPHPUnitCompatibilityTestCase +class SessionStrategyManagerTest extends AbstractTestCase { /** diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php b/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php index 7d33e0e..28f9857 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php @@ -11,10 +11,10 @@ namespace tests\aik099\PHPUnit\Session; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Session\ISessionStrategy; +use tests\aik099\PHPUnit\AbstractTestCase; -class SessionStrategyTestCase extends AbstractPHPUnitCompatibilityTestCase +class SessionStrategyTestCase extends AbstractTestCase { const BROWSER_CLASS = '\\aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index 8486bf6..217fe78 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -12,11 +12,11 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use aik099\PHPUnit\Framework\IncompleteTestError; -use aik099\PHPUnit\Framework\SkippedTestError; use aik099\PHPUnit\Session\IsolatedSessionStrategy; use aik099\PHPUnit\Session\SharedSessionStrategy; use Behat\Mink\Session; +use ConsoleHelpers\PHPUnitCompat\Framework\IncompleteTestError; +use ConsoleHelpers\PHPUnitCompat\Framework\SkippedTestError; use Mockery as m; use Mockery\MockInterface; diff --git a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php index fff75a6..b3a7648 100644 --- a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php +++ b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php @@ -11,12 +11,12 @@ namespace tests\aik099\PHPUnit\TestCase; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\Application; use Mockery as m; use Mockery\MockInterface; +use tests\aik099\PHPUnit\AbstractTestCase; -class ApplicationAwareTestCase extends AbstractPHPUnitCompatibilityTestCase +class ApplicationAwareTestCase extends AbstractTestCase { /** diff --git a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php index 7b3cb62..3e8b8a4 100644 --- a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\TestSuite; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\TestSuite\BrowserTestSuite; use Mockery as m; +use tests\aik099\PHPUnit\AbstractTestCase; -class BrowserTestSuiteTest extends AbstractPHPUnitCompatibilityTestCase +class BrowserTestSuiteTest extends AbstractTestCase { /** @@ -72,7 +72,7 @@ public function nameFromBrowserDataProvider() public function testSetBrowserFromConfiguration() { $browser = array('name' => 'safari'); - $test = m::mock('\\aik099\\PHPUnit\\Framework\\Test'); + $test = m::mock('\\ConsoleHelpers\\PHPUnitCompat\\Framework\\Test'); $test->shouldReceive('setBrowserFromConfiguration')->with($browser)->once(); $this->_suite->addTest($test); diff --git a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php index 0be7e58..beeefb6 100644 --- a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php @@ -11,11 +11,11 @@ namespace tests\aik099\PHPUnit\TestSuite; -use aik099\PHPUnit\AbstractPHPUnitCompatibilityTestCase; use aik099\PHPUnit\TestSuite\RegularTestSuite; use Mockery as m; +use tests\aik099\PHPUnit\AbstractTestCase; -class RegularTestSuiteTest extends AbstractPHPUnitCompatibilityTestCase +class RegularTestSuiteTest extends AbstractTestCase { /** @@ -43,7 +43,7 @@ public function testSetTestDependencies() $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); $helper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); - $test = m::mock('\\aik099\\PHPUnit\\Framework\\Test'); + $test = m::mock('\\ConsoleHelpers\\PHPUnitCompat\\Framework\\Test'); $test->shouldReceive('setSessionStrategyManager')->with($manager)->once(); $test->shouldReceive('setBrowserConfigurationFactory')->with($factory)->once(); $test->shouldReceive('setRemoteCoverageHelper')->with($helper)->once(); From 51b0a78a2840ed467986cc70a7bcc18651f661e2 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 10:26:11 +0200 Subject: [PATCH 160/204] Verify test expectations also in the "SetupFixture" --- tests/aik099/PHPUnit/AbstractTestCase.php | 20 +--------- tests/aik099/PHPUnit/Fixture/SetupFixture.php | 3 ++ .../PHPUnit/TVerifyTestExpectations.php | 37 +++++++++++++++++++ 3 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 tests/aik099/PHPUnit/TVerifyTestExpectations.php diff --git a/tests/aik099/PHPUnit/AbstractTestCase.php b/tests/aik099/PHPUnit/AbstractTestCase.php index c1f1e4a..f959e78 100644 --- a/tests/aik099/PHPUnit/AbstractTestCase.php +++ b/tests/aik099/PHPUnit/AbstractTestCase.php @@ -16,24 +16,6 @@ abstract class AbstractTestCase extends TestCase { - /** - * @after - */ - protected function verifyMockeryExpectations() - { - if ( !\class_exists('Mockery') ) { - return; - } - - // Add Mockery expectations to assertion count. - $container = \Mockery::getContainer(); - - if ( $container !== null ) { - $this->addToAssertionCount($container->mockery_getExpectationCount()); - } - - // Verify Mockery expectations. - \Mockery::close(); - } + use TVerifyTestExpectations; } diff --git a/tests/aik099/PHPUnit/Fixture/SetupFixture.php b/tests/aik099/PHPUnit/Fixture/SetupFixture.php index 3cacb94..fd45f5a 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupFixture.php @@ -17,10 +17,13 @@ use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Behat\Mink\Session; use Mockery as m; +use tests\aik099\PHPUnit\TVerifyAssertions; class SetupFixture extends BrowserTestCase { + use TVerifyTestExpectations; + /** * @before */ diff --git a/tests/aik099/PHPUnit/TVerifyTestExpectations.php b/tests/aik099/PHPUnit/TVerifyTestExpectations.php new file mode 100644 index 0000000..274193f --- /dev/null +++ b/tests/aik099/PHPUnit/TVerifyTestExpectations.php @@ -0,0 +1,37 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit; + + +trait TVerifyTestExpectations +{ + + /** + * @after + */ + protected function verifyMockeryExpectations() + { + if ( !\class_exists('Mockery') ) { + return; + } + + // Add Mockery expectations to assertion count. + $container = \Mockery::getContainer(); + + if ( $container !== null ) { + $this->addToAssertionCount($container->mockery_getExpectationCount()); + } + + // Verify Mockery expectations. + \Mockery::close(); + } + +} From f05f051ee92abe15b7b2bb2e9babeb35f057589c Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 10:27:29 +0200 Subject: [PATCH 161/204] Properly report nested test suite errors during testing --- .../Integration/EventDispatchingTest.php | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php index e4f21c5..56cb306 100644 --- a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php +++ b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php @@ -12,6 +12,7 @@ use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; +use PHPUnit\Framework\TestFailure; use tests\aik099\PHPUnit\AbstractTestCase; use tests\aik099\PHPUnit\Fixture\SetupFixture; @@ -58,7 +59,42 @@ public function testSetupEvent() $suite = SetupFixture::suite('tests\\aik099\\PHPUnit\\Fixture\\SetupFixture'); $suite->run($result); - $this->assertTrue($result->wasSuccessful(), 'All sub-tests passed'); + $error_msgs = array(); + + if ( $result->errorCount() > 0 ) { + foreach ( $result->errors() as $error ) { + $error_msgs[] = $this->prepareErrorMsg($error); + } + } + + if ( $result->failureCount() > 0 ) { + foreach ( $result->failures() as $failure ) { + $error_msgs[] = $this->prepareErrorMsg($failure); + } + } + + if ( $error_msgs ) { + $this->fail( + 'The "SetupFixture" tests failed:' . \PHP_EOL . \PHP_EOL . implode(\PHP_EOL . ' * ', $error_msgs) + ); + } + + $this->assertTrue(true); + } + + /** + * Prepares an error msg. + * + * @param TestFailure $test_failure Exception. + * + * @return string + */ + protected function prepareErrorMsg(TestFailure $test_failure) + { + $ret = $test_failure->toString() . \PHP_EOL; + $ret .= 'Trace:' . \PHP_EOL . $test_failure->thrownException()->getTraceAsString(); + + return $ret; } } From be51ef8b26c3a18defb6d27d46228a8a0a1da154 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 10:34:08 +0200 Subject: [PATCH 162/204] Fixing test suite fatal error --- tests/aik099/PHPUnit/Fixture/SetupFixture.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/aik099/PHPUnit/Fixture/SetupFixture.php b/tests/aik099/PHPUnit/Fixture/SetupFixture.php index fd45f5a..c65dbcc 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupFixture.php @@ -17,7 +17,7 @@ use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Behat\Mink\Session; use Mockery as m; -use tests\aik099\PHPUnit\TVerifyAssertions; +use tests\aik099\PHPUnit\TVerifyTestExpectations; class SetupFixture extends BrowserTestCase { From 0c415709cbc301fcf32e3ba914c371ce7bd87d30 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 12:06:02 +0200 Subject: [PATCH 163/204] Removed dead code from the test suite --- .../BrowserConfigurationFactoryTest.php | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index 4e0ea48..87b280b 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -13,7 +13,6 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; -use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Mockery as m; use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; @@ -30,40 +29,12 @@ class BrowserConfigurationFactoryTest extends AbstractTestCase */ private $_factory; - /** - * Driver factory registry. - * - * @var DriverFactoryRegistry|m\MockInterface - */ - private $_driverFactoryRegistry; - /** * @before */ protected function setUpTest() { $this->_factory = new BrowserConfigurationFactory(); - $this->_driverFactoryRegistry = $this->createDriverFactoryRegistry(); - } - - /** - * Creates driver factory registry. - * - * @return DriverFactoryRegistry - */ - protected function createDriverFactoryRegistry() - { - $registry = m::mock('\\aik099\\PHPUnit\\MinkDriver\\DriverFactoryRegistry'); - - $driver_factory = m::mock('\\aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); - $driver_factory->shouldReceive('getDriverDefaults')->andReturn(array()); - - $registry - ->shouldReceive('get') - ->with('selenium2') - ->andReturn($driver_factory); - - return $registry; } /** From 2ad6c656df9c4be53df880d27a1fc5d679fdc6ca Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 12:46:19 +0200 Subject: [PATCH 164/204] Don't use partial mocks in the test suite (#122) Remove partial mocks from the test suite --- .../PHPUnit/APIClient/APIClientFactory.php | 50 +++++++++++++++ .../ApiBrowserConfiguration.php | 18 +++++- .../BrowserStackBrowserConfiguration.php | 17 ----- .../SauceLabsBrowserConfiguration.php | 15 ----- library/aik099/PHPUnit/DIContainer.php | 9 ++- .../APIClientFactoryTest.php | 64 +++++++++++++++++++ .../ApiBrowserConfigurationTestCase.php | 55 ++++++++++++++-- .../BrowserConfigurationTest.php | 27 ++------ .../BrowserStackBrowserConfigurationTest.php | 5 -- .../SauceLabsBrowserConfigurationTest.php | 5 -- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 44 +++++++------ tests/aik099/PHPUnit/Fixture/SetupFixture.php | 27 ++++---- .../PHPUnit/Integration/DIContainerTest.php | 1 + .../TestSuite/RegularTestSuiteTest.php | 26 ++++---- 14 files changed, 239 insertions(+), 124 deletions(-) create mode 100644 library/aik099/PHPUnit/APIClient/APIClientFactory.php create mode 100644 tests/aik099/PHPUnit/BrowserConfiguration/APIClientFactoryTest.php diff --git a/library/aik099/PHPUnit/APIClient/APIClientFactory.php b/library/aik099/PHPUnit/APIClient/APIClientFactory.php new file mode 100644 index 0000000..f5f9b28 --- /dev/null +++ b/library/aik099/PHPUnit/APIClient/APIClientFactory.php @@ -0,0 +1,50 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\APIClient; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use WebDriver\SauceLabs\SauceRest; +use WebDriver\ServiceFactory; + +class APIClientFactory +{ + + /** + * Creates an API client based on a browser configuration. + * + * @param BrowserConfiguration $browser The browser configuration. + * + * @return IAPIClient + * @throws \LogicException When unsupported browser configuration was given. + */ + public function getAPIClient(BrowserConfiguration $browser) + { + if ( $browser instanceof BrowserStackBrowserConfiguration ) { + return new BrowserStackAPIClient( + $browser->getApiUsername(), + $browser->getApiKey(), + ServiceFactory::getInstance()->getService('service.curl') + ); + } + + if ( $browser instanceof SauceLabsBrowserConfiguration ) { + $sauce_rest = new SauceRest($browser->getApiUsername(), $browser->getApiKey()); + + return new SauceLabsAPIClient($sauce_rest); + } + + throw new \LogicException('The "' . $browser->getType() . '" browser configuration is not supported.'); + } + +} diff --git a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php index 8afa082..3799d6c 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfiguration.php @@ -11,6 +11,7 @@ namespace aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\APIClient\APIClientFactory; use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; @@ -37,17 +38,27 @@ abstract class ApiBrowserConfiguration extends BrowserConfiguration */ const NAME_CAPABILITY = 'name'; + /** + * API client factory. + * + * @var APIClientFactory + */ + protected $apiClientFactory; + /** * Creates browser configuration. * * @param DriverFactoryRegistry $driver_factory_registry Driver factory registry. + * @param APIClientFactory $api_client_factory API client factory. */ - public function __construct(DriverFactoryRegistry $driver_factory_registry) + public function __construct(DriverFactoryRegistry $driver_factory_registry, APIClientFactory $api_client_factory) { $this->defaults['driver'] = 'selenium2'; $this->defaults['apiUsername'] = ''; $this->defaults['apiKey'] = ''; + $this->apiClientFactory = $api_client_factory; + parent::__construct($driver_factory_registry); } @@ -193,7 +204,10 @@ public function onTestEnded(BrowserTestCase $test_case, TestResult $test_result) * * @return IAPIClient */ - public abstract function getAPIClient(); + public function getAPIClient() + { + return $this->apiClientFactory->getAPIClient($this); + } /** * Get Selenium2 current session id. diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php index 7f2a2dc..2ddf8dd 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfiguration.php @@ -11,10 +11,7 @@ namespace aik099\PHPUnit\BrowserConfiguration; -use aik099\PHPUnit\APIClient\BrowserStackAPIClient; -use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserTestCase; -use WebDriver\ServiceFactory; /** * Browser configuration tailored to use with "BrowserStack" service. @@ -25,20 +22,6 @@ class BrowserStackBrowserConfiguration extends ApiBrowserConfiguration { const TYPE = 'browserstack'; - /** - * Returns API class for service interaction. - * - * @return IAPIClient - */ - public function getAPIClient() - { - return new BrowserStackAPIClient( - $this->getApiUsername(), - $this->getApiKey(), - ServiceFactory::getInstance()->getService('service.curl') - ); - } - /** * @inheritDoc */ diff --git a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php index 7417ee2..6d34f4f 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfiguration.php @@ -11,10 +11,7 @@ namespace aik099\PHPUnit\BrowserConfiguration; -use aik099\PHPUnit\APIClient\IAPIClient; -use aik099\PHPUnit\APIClient\SauceLabsAPIClient; use aik099\PHPUnit\BrowserTestCase; -use WebDriver\SauceLabs\SauceRest; /** * Browser configuration tailored to use with "Sauce Labs" service. @@ -25,18 +22,6 @@ class SauceLabsBrowserConfiguration extends ApiBrowserConfiguration { const TYPE = 'saucelabs'; - /** - * Returns API class for service interaction. - * - * @return IAPIClient - */ - public function getAPIClient() - { - $sauce_rest = new SauceRest($this->getApiUsername(), $this->getApiKey()); - - return new SauceLabsAPIClient($sauce_rest); - } - /** * @inheritDoc */ diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index 7c4aa59..5c96632 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -11,6 +11,7 @@ namespace aik099\PHPUnit; +use aik099\PHPUnit\APIClient\APIClientFactory; use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; @@ -119,6 +120,10 @@ public function __construct(array $values = array()) return $registry; }; + $this['api_client_factory'] = function ($c) { + return new APIClientFactory(); + }; + $this['browser_configuration_factory'] = function ($c) { $browser_configuration_factory = new BrowserConfigurationFactory(); @@ -126,10 +131,10 @@ public function __construct(array $values = array()) new BrowserConfiguration($c['driver_factory_registry']) ); $browser_configuration_factory->register( - new SauceLabsBrowserConfiguration($c['driver_factory_registry']) + new SauceLabsBrowserConfiguration($c['driver_factory_registry'], $c['api_client_factory']) ); $browser_configuration_factory->register( - new BrowserStackBrowserConfiguration($c['driver_factory_registry']) + new BrowserStackBrowserConfiguration($c['driver_factory_registry'], $c['api_client_factory']) ); return $browser_configuration_factory; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/APIClientFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/APIClientFactoryTest.php new file mode 100644 index 0000000..a409a85 --- /dev/null +++ b/tests/aik099/PHPUnit/BrowserConfiguration/APIClientFactoryTest.php @@ -0,0 +1,64 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace tests\aik099\PHPUnit\BrowserConfiguration; + + +use aik099\PHPUnit\APIClient\APIClientFactory; +use aik099\PHPUnit\APIClient\BrowserStackAPIClient; +use aik099\PHPUnit\APIClient\SauceLabsAPIClient; +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use Mockery as m; +use PHPUnit\Framework\TestCase; +use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; + +class APIClientFactoryTest extends TestCase +{ + + use ExpectException; + + public function testBrowserStackAPIClient() + { + $browser = m::mock(BrowserStackBrowserConfiguration::class); + $browser->shouldReceive('getApiUsername')->once()->andReturn('username'); + $browser->shouldReceive('getApiKey')->once()->andReturn('key'); + + $factory = new APIClientFactory(); + + $this->assertInstanceOf(BrowserStackAPIClient::class, $factory->getAPIClient($browser)); + } + + public function testSauceLabsAPIClient() + { + $browser = m::mock(SauceLabsBrowserConfiguration::class); + $browser->shouldReceive('getApiUsername')->once()->andReturn('username'); + $browser->shouldReceive('getApiKey')->once()->andReturn('key'); + + $factory = new APIClientFactory(); + + $this->assertInstanceOf(SauceLabsAPIClient::class, $factory->getAPIClient($browser)); + } + + public function testUnknownAPIClient() + { + $browser = m::mock(BrowserConfiguration::class); + $browser->shouldReceive('getType')->once()->andReturn('browser config type'); + + $factory = new APIClientFactory(); + + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('The "browser config type" browser configuration is not supported.'); + + $factory->getAPIClient($browser); + } + +} diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 8b734e8..09e24f9 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -11,6 +11,7 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\APIClient\APIClientFactory; use aik099\PHPUnit\APIClient\IAPIClient; use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; @@ -42,17 +43,33 @@ abstract class ApiBrowserConfigurationTestCase extends BrowserConfigurationTest */ protected $apiClient; + /** + * Driver factory registry. + * + * @var APIClientFactory|m\MockInterface + */ + protected $apiClientFactory; + /** * @before */ protected function setUpTest() { - if ( $this->getName(false) === 'testOnTestEnded' ) { - $this->mockBrowserMethods[] = 'getAPIClient'; + if ( $this->needsAPIClient() ) { + $this->apiClient = m::mock('\\aik099\\PHPUnit\\APIClient\\IAPIClient'); } + $this->apiClientFactory = m::mock('\\aik099\\PHPUnit\\APIClient\\APIClientFactory'); + parent::setUpTest(); + if ( $this->needsAPIClient() ) { + $this->apiClientFactory->shouldReceive('getAPIClient') + ->with($this->browser) + ->once() + ->andReturn($this->apiClient); + } + $this->setup['port'] = 80; $this->setup['apiUsername'] = 'UN'; $this->setup['apiKey'] = 'AK'; @@ -287,14 +304,11 @@ public function testOnTestEnded($driver_type) { $test_case = $this->createTestCase('TEST_NAME'); - $api_client = m::mock('aik099\\PHPUnit\\APIClient\\IAPIClient'); - $this->browser->shouldReceive('getAPIClient')->andReturn($api_client); - if ( $driver_type == 'selenium' ) { $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); $driver->shouldReceive('getWebDriverSessionId')->once()->andReturn('SID'); - $api_client->shouldReceive('updateStatus')->with('SID', true, 'test status message')->once(); + $this->apiClient->shouldReceive('updateStatus')->with('SID', true, 'test status message')->once(); $test_case->shouldReceive('hasFailed')->once()->andReturn(false); // For shared strategy. $test_case->shouldReceive('getStatusMessage')->once()->andReturn('test status message'); // For shared strategy. } @@ -429,4 +443,33 @@ public function tunnelIdentifierDataProvider() ); } + public function testGetAPIClient() + { + $this->assertSame($this->apiClient, $this->browser->getAPIClient()); + } + + /** + * Creates instance of browser configuration. + * + * @return ApiBrowserConfiguration + */ + protected function createBrowserConfiguration() + { + /** @var ApiBrowserConfiguration $browser */ + $browser = new $this->browserConfigurationClass($this->driverFactoryRegistry, $this->apiClientFactory); + $browser->setAliases(); + + return $browser; + } + + /** + * Determines if test needs an API client. + * + * @return boolean + */ + protected function needsAPIClient() + { + return in_array($this->getName(false), array('testOnTestEnded', 'testGetAPIClient')); + } + } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index e6af1e0..f86dc6b 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -106,10 +106,7 @@ protected function setUpTest() $this->driverFactoryRegistry = $this->createDriverFactoryRegistry(); - $this->browser = $this->createBrowserConfiguration( - array(), - $this->mockBrowserMethods - ); + $this->browser = $this->createBrowserConfiguration(); } /** @@ -611,27 +608,13 @@ public function testChecksumMismatch() /** * Creates instance of browser configuration. * - * @param array $aliases Aliases. - * @param array $mock_methods Mock methods. - * * @return BrowserConfiguration */ - protected function createBrowserConfiguration(array $aliases = array(), $mock_methods = array()) + protected function createBrowserConfiguration() { - if ( $mock_methods ) { - /** @var BrowserConfiguration $browser */ - $browser = m::mock( - $this->browserConfigurationClass . '[' . implode(',', $mock_methods) . ']', - array($this->driverFactoryRegistry), - array('getSessionStrategy' => 'isolated') - ); - } - else { - /** @var BrowserConfiguration $browser */ - $browser = new $this->browserConfigurationClass($this->driverFactoryRegistry); - } - - $browser->setAliases($aliases); + /** @var BrowserConfiguration $browser */ + $browser = new $this->browserConfigurationClass($this->driverFactoryRegistry); + $browser->setAliases(); return $browser; } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php index 6d5f1ee..e318071 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -76,9 +76,4 @@ public function desiredCapabilitiesDataProvider() ); } - public function testGetAPIClient() - { - $this->assertInstanceOf('aik099\\PHPUnit\\APIClient\\BrowserStackAPIClient', $this->browser->getAPIClient()); - } - } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index 590a5e0..dc916c8 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -74,9 +74,4 @@ public function desiredCapabilitiesDataProvider() ); } - public function testGetAPIClient() - { - $this->assertInstanceOf('aik099\\PHPUnit\\APIClient\\SauceLabsAPIClient', $this->browser->getAPIClient()); - } - } diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 42b8e7c..09e33a3 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -21,6 +21,7 @@ use aik099\PHPUnit\Session\SessionStrategyManager; use ConsoleHelpers\CodeCoverageCompat\CodeCoverage; use ConsoleHelpers\CodeCoverageCompat\Filter; +use ConsoleHelpers\PHPUnitCompat\Framework\SkippedTestError; use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; use Mockery as m; use Mockery\MockInterface; @@ -229,20 +230,30 @@ public function testGetSession() */ public function testGetSessionDriverError() { - $this->expectException('Exception'); - $this->expectExceptionMessage('MSG_SKIP'); - $browser = $this->getBrowser(1); /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $session_strategy->shouldReceive('session')->andThrow('\Behat\Mink\Exception\DriverException'); - $test_case = $this->getFixture($session_strategy, array('markTestSkipped')); + $test_case = $this->getFixture($session_strategy); $test_case->setBrowser($browser); - $test_case->shouldReceive('markTestSkipped')->once()->andThrow('\Exception', 'MSG_SKIP'); - $test_case->getSession(); + // On PHPUnit 5.x usage of expectException/expectExceptionMessage results in this test being marked as skipped. + try { + $test_case->getSession(); + } + catch ( \Exception $e ) { + $this->assertInstanceOf(SkippedTestError::class, $e); + $this->assertEquals( + 'The Selenium Server is not active on host {hostname} at port {port}', + $e->getMessage() + ); + } + + if ( !isset($e) ) { + $this->fail('No exception about non-working Selenium server was thrown.'); + } } /** @@ -255,8 +266,8 @@ public function testGetSessionDriverError() protected function getBrowser($times) { $browser = m::mock(self::BROWSER_CLASS); - $browser->shouldReceive('getHost')->times($times); - $browser->shouldReceive('getPort')->times($times); + $browser->shouldReceive('getHost')->times($times)->andReturn('{hostname}'); + $browser->shouldReceive('getPort')->times($times)->andReturn('{port}'); return $browser; } @@ -622,16 +633,14 @@ public function testGetBrowserAliases() /** * Prepares test case to be used by "run" method. * - * @param array $mock_methods Method names to mock. - * * @return array */ - protected function prepareForRun(array $mock_methods = array()) + protected function prepareForRun() { /* @var $session_strategy ISessionStrategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - $test_case = $this->getFixture($session_strategy, $mock_methods); + $test_case = $this->getFixture($session_strategy); $test_case->setName('testSuccess'); $session_strategy->shouldReceive('onTestEnded')->with($test_case)->once(); @@ -649,11 +658,10 @@ protected function prepareForRun(array $mock_methods = array()) * Returns test case fixture. * * @param ISessionStrategy|null $session_strategy Session strategy. - * @param array $mock_methods Method names to mock. * * @return WithoutBrowserConfig */ - protected function getFixture(ISessionStrategy $session_strategy = null, array $mock_methods = array()) + protected function getFixture(ISessionStrategy $session_strategy = null) { if ( !isset($session_strategy) ) { $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); @@ -663,13 +671,7 @@ protected function getFixture(ISessionStrategy $session_strategy = null, array $ $manager = m::mock(self::MANAGER_CLASS); $manager->shouldReceive('getSessionStrategy')->andReturn($session_strategy); - if ( $mock_methods ) { - $test_case = m::mock('\\aik099\\PHPUnit\\BrowserTestCase[' . implode(',', $mock_methods) . ']'); - } - else { - $test_case = new WithoutBrowserConfig('test name'); - } - + $test_case = new WithoutBrowserConfig('test name'); $test_case->setBrowserConfigurationFactory($this->browserConfigurationFactory); $test_case->setSessionStrategyManager($manager); diff --git a/tests/aik099/PHPUnit/Fixture/SetupFixture.php b/tests/aik099/PHPUnit/Fixture/SetupFixture.php index c65dbcc..c071c97 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupFixture.php @@ -11,8 +11,9 @@ namespace tests\aik099\PHPUnit\Fixture; +use aik099\PHPUnit\APIClient\APIClientFactory; use aik099\PHPUnit\BrowserConfiguration\ApiBrowserConfiguration; -use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; +use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; use Behat\Mink\Session; @@ -32,23 +33,21 @@ protected function setUpTest() $api_client = m::mock('aik099\\PHPUnit\\APIClient\\IAPIClient'); $api_client->shouldReceive('updateStatus')->withAnyArgs()->once(); - /** @var IBrowserConfigurationFactory $factory */ - $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + /** @var APIClientFactory $api_client_factory */ + $api_client_factory = m::mock('\\aik099\\PHPUnit\\APIClient\\APIClientFactory'); - $browser_config = array('apiUsername' => 'a', 'apiKey' => 'b'); + $browser = new SauceLabsBrowserConfiguration($this->createDriverFactoryRegistry(), $api_client_factory); - $browser = m::mock( - 'aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration[getAPIClient]', - array($this->createDriverFactoryRegistry()) - ); + $desired_capabilities = $browser->getDesiredCapabilities(); + $desired_capabilities[ApiBrowserConfiguration::NAME_CAPABILITY] = 'something'; + $browser->setDesiredCapabilities($desired_capabilities); - // These magic methods can't be properly passed through to mocked object otherwise. - $browser->shouldReceive('getSessionStrategy')->andReturn('isolated'); - $browser->shouldReceive('getDesiredCapabilities')->andReturn(array( - ApiBrowserConfiguration::NAME_CAPABILITY => 'something', - )); + $api_client_factory->shouldReceive('getAPIClient')->with($browser)->once()->andReturn($api_client); - $browser->shouldReceive('getAPIClient')->once()->andReturn($api_client); + $browser_config = array('apiUsername' => 'a', 'apiKey' => 'b'); + + /** @var IBrowserConfigurationFactory $factory */ + $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); $factory->shouldReceive('createBrowserConfiguration') ->with($browser_config, $this) diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index fa7899a..65204e7 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -69,6 +69,7 @@ public function serviceDefinitionsDataProvider() array('test_suite_factory', 'aik099\\PHPUnit\\TestSuite\\TestSuiteFactory'), array('regular_test_suite', 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'), array('browser_test_suite', 'aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'), + array('api_client_factory', 'aik099\\PHPUnit\\APIClient\\APIClientFactory'), array( 'browser_configuration_factory', 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfigurationFactory', diff --git a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php index beeefb6..e6a2b1b 100644 --- a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php @@ -25,11 +25,12 @@ class RegularTestSuiteTest extends AbstractTestCase */ public function testAddTestMethods() { - $suite = $this->_createSuite(array('addTest')); - $suite->shouldReceive('addTest')->twice(); + $suite = $this->_createSuite(); $actual = $suite->addTestMethods('tests\\aik099\\PHPUnit\\Fixture\\WithoutBrowserConfig'); - $this->assertSame($suite, $actual); + $this->assertSame($suite, $actual, 'The fluid interface doesn\'t work.'); + + $this->assertCount(2, $actual->tests(), 'Not all tests were added.'); } /** @@ -50,26 +51,21 @@ public function testSetTestDependencies() $suite = $this->_createSuite(); $suite->addTest($test); - $this->assertSame($suite, $suite->setTestDependencies($manager, $factory, $helper)); + $this->assertSame( + $suite, + $suite->setTestDependencies($manager, $factory, $helper), + 'The fluid interface doesn\'t work.' + ); } /** * Creates suite. * - * @param array $mock_methods Mock methods. - * * @return RegularTestSuite */ - private function _createSuite(array $mock_methods = array()) + private function _createSuite() { - if ( $mock_methods ) { - $suite = m::mock('aik099\\PHPUnit\\TestSuite\\RegularTestSuite[' . implode(',', $mock_methods) . ']'); - } - else { - $suite = new RegularTestSuite(); - } - - return $suite; + return new RegularTestSuite(); } } From 4b69ac7971d87fdc37dc4d11461712fd9013f574 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 13:18:36 +0200 Subject: [PATCH 165/204] Indicate supported PHPUnit versions in the Changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff4f2c9..5e7e1ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [2.3.0] - 2022-11-24 ### Changed - Bumped minimum PHPUnit version to 4.8.35 or 5.4.3. -- Lifted restriction on used PHPUnit version. +- Added support for PHPUnit 6.x, PHPUnit 7.x, PHPUnit 8.x and PHPUnit 9.x versions. - Use namespaced class versions of PHPUnit. - Bumped minimum PHP version to 5.4.7. - Test case configuration method renamed from "BrowserTestCase::setUp" into "BrowserTestCase::setUpTest". From 4b3bb1ca4e4c97d019b7416a7b7b5ae775622ea9 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 15:40:01 +0200 Subject: [PATCH 166/204] Fixed "@var" comments syntax in the test suite --- .../BrowserConfigurationTest.php | 2 +- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 32 +++++++++---------- .../Session/SharedSessionStrategyTest.php | 4 +-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index f86dc6b..1f8abe6 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -505,7 +505,7 @@ public function testNonExistingMethod() */ public function testGetSessionStrategyHashBrowserSharing($session_strategy) { - /* @var $test_case BrowserTestCase */ + /** @var BrowserTestCase $test_case */ $test_case = m::mock(self::TEST_CASE_CLASS); $browser1 = $this->createBrowserConfiguration(); diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 09e33a3..02466fd 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -71,7 +71,7 @@ protected function setUpTest() */ public function testSetSessionStrategyManager() { - /* @var $manager SessionStrategyManager */ + /** @var SessionStrategyManager $manager */ $manager = m::mock(self::MANAGER_CLASS); $test_case = new WithoutBrowserConfig('test name'); @@ -90,8 +90,8 @@ public function testSetSessionStrategyManager() */ public function testSetBrowserCorrect() { + /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - /* @var $session_strategy ISessionStrategy */ $test_case = $this->getFixture($session_strategy); @@ -164,7 +164,7 @@ public function testSetBrowserFromConfigurationDefault() */ public function testSetSessionStrategy() { - /* @var $session_strategy ISessionStrategy */ + /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $test_case = new WithoutBrowserConfig('test name'); @@ -180,7 +180,7 @@ public function testSetSessionStrategy() */ public function testGetSessionStrategySharing() { - /* @var $manager SessionStrategyManager */ + /** @var SessionStrategyManager $manager */ $manager = m::mock(self::MANAGER_CLASS); $manager->shouldReceive('getDefaultSessionStrategy')->twice()->andReturn('STRATEGY'); @@ -206,7 +206,7 @@ public function testGetSession() $expected_session1 = m::mock('\\Behat\\Mink\\Session'); $expected_session2 = m::mock('\\Behat\\Mink\\Session'); - /* @var $session_strategy ISessionStrategy */ + /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $session_strategy->shouldReceive('session')->with($browser)->andReturn($expected_session1, $expected_session2); @@ -232,7 +232,7 @@ public function testGetSessionDriverError() { $browser = $this->getBrowser(1); - /* @var $session_strategy ISessionStrategy */ + /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $session_strategy->shouldReceive('session')->andThrow('\Behat\Mink\Exception\DriverException'); @@ -312,7 +312,7 @@ public function testGetCollectCodeCoverageInformationSuccess() */ public function testRun() { - /* @var $test_case BrowserTestCase */ + /** @var BrowserTestCase $test_case */ list($test_case,) = $this->prepareForRun(); $result = new TestResult(); @@ -328,7 +328,7 @@ public function testRun() */ public function testRunCreateResult() { - /* @var $test_case BrowserTestCase */ + /** @var BrowserTestCase $test_case */ list($test_case,) = $this->prepareForRun(); $this->assertInstanceOf('\\ConsoleHelpers\\PHPUnitCompat\\Framework\\TestResult', $test_case->run()); @@ -343,8 +343,8 @@ public function testRunCreateResult() */ public function testRunWithCoverageWithoutRemoteUrl() { - /* @var $test_case BrowserTestCase */ - /* @var $session_strategy ISessionStrategy */ + /** @var BrowserTestCase $test_case */ + /** @var ISessionStrategy $session_strategy */ list($test_case, $session_strategy) = $this->prepareForRun(); $test_case->setName('getTestId'); $test_case->setRemoteCoverageHelper($this->getRemoteCoverageHelperMock()); @@ -426,8 +426,8 @@ public function testRunWithCoverage() ), ); - /* @var $test_case BrowserTestCase */ - /* @var $session_strategy ISessionStrategy */ + /** @var BrowserTestCase $test_case */ + /** @var ISessionStrategy $session_strategy */ list($test_case, $session_strategy) = $this->prepareForRun(); $test_case->setName('getTestId'); $test_case->setRemoteCoverageHelper($this->getRemoteCoverageHelperMock($expected_coverage)); @@ -582,7 +582,7 @@ protected function getCodeCoverageMock(array $expected_coverage) */ public function testEndOfTestCase() { - /* @var $session_strategy ISessionStrategy */ + /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $test_case = new WithoutBrowserConfig('test name'); @@ -603,7 +603,7 @@ public function testOnTestFailed() $this->expectException('Exception'); $this->expectExceptionMessage('MSG_TEST'); - /* @var $session_strategy ISessionStrategy */ + /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $test_case = $this->getFixture($session_strategy); @@ -637,7 +637,7 @@ public function testGetBrowserAliases() */ protected function prepareForRun() { - /* @var $session_strategy ISessionStrategy */ + /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $test_case = $this->getFixture($session_strategy); @@ -667,7 +667,7 @@ protected function getFixture(ISessionStrategy $session_strategy = null) $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); } - /* @var $manager SessionStrategyManager */ + /** @var SessionStrategyManager $manager */ $manager = m::mock(self::MANAGER_CLASS); $manager->shouldReceive('getSessionStrategy')->andReturn($session_strategy); diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index 217fe78..6234f9f 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -66,7 +66,7 @@ protected function setUpTest() */ public function testSessionSharing(\Exception $e = null) { - /* @var $browser BrowserConfiguration */ + /** @var BrowserConfiguration $browser */ $browser = m::mock(self::BROWSER_CLASS); $this->_isolatedStrategy->shouldReceive('session')->once()->with($browser)->andReturn($this->_session1); @@ -102,7 +102,7 @@ public function ignoreExceptionDataProvider() */ public function testSessionResetOnFailure() { - /* @var $browser BrowserConfiguration */ + /** @var BrowserConfiguration $browser */ $browser = m::mock(self::BROWSER_CLASS); $this->_isolatedStrategy From 1fe157a1ee77592d75d6c9f39f1ba27499e88734 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 15:42:16 +0200 Subject: [PATCH 167/204] Massive automated CS fixes in the test suite --- tests/PimpleCopy/Pimple/Fixtures/Service.php | 2 +- .../Pimple/PimpleServiceProviderInterfaceTest.php | 1 + tests/PimpleCopy/Pimple/PimpleTest.php | 1 + tests/aik099/PHPUnit/BrowserTestCaseTest.php | 8 ++++---- tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php | 7 ++----- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/PimpleCopy/Pimple/Fixtures/Service.php b/tests/PimpleCopy/Pimple/Fixtures/Service.php index 347e809..9147dd8 100644 --- a/tests/PimpleCopy/Pimple/Fixtures/Service.php +++ b/tests/PimpleCopy/Pimple/Fixtures/Service.php @@ -28,7 +28,7 @@ /** - * @author Igor Wiedler + * @author Igor Wiedler */ class Service { diff --git a/tests/PimpleCopy/Pimple/PimpleServiceProviderInterfaceTest.php b/tests/PimpleCopy/Pimple/PimpleServiceProviderInterfaceTest.php index 1418f5c..136de61 100644 --- a/tests/PimpleCopy/Pimple/PimpleServiceProviderInterfaceTest.php +++ b/tests/PimpleCopy/Pimple/PimpleServiceProviderInterfaceTest.php @@ -35,6 +35,7 @@ */ class PimpleServiceProviderInterfaceTest extends TestCase { + public function testProvider() { $pimple = new Container(); diff --git a/tests/PimpleCopy/Pimple/PimpleTest.php b/tests/PimpleCopy/Pimple/PimpleTest.php index 760cb81..7937532 100644 --- a/tests/PimpleCopy/Pimple/PimpleTest.php +++ b/tests/PimpleCopy/Pimple/PimpleTest.php @@ -26,6 +26,7 @@ namespace tests\PimpleCopy\Pimple; + use Mockery as m; use PHPUnit\Framework\TestCase; use PimpleCopy\Pimple\Container; diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 02466fd..935a078 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -351,7 +351,7 @@ public function testRunWithCoverageWithoutRemoteUrl() $result = new TestResult(); $code_coverage = $this->getCodeCoverageMock(array( - $this->getCoverageFixtureFile() => array ( + $this->getCoverageFixtureFile() => array( 7 => -1, // Means line not executed. 8 => -1, 9 => -1, @@ -391,7 +391,7 @@ public function testRunWithCoverageWithoutRemoteUrl() else { $actual_coverage = $code_coverage->getData(); $expected_coverage = array( - $this->getCoverageFixtureFile() => array ( + $this->getCoverageFixtureFile() => array( 7 => array(), // Means, that this test hasn't executed a tested code. 8 => array(), 9 => array(), @@ -416,7 +416,7 @@ public function testRunWithCoverageWithoutRemoteUrl() public function testRunWithCoverage() { $expected_coverage = array( - $this->getCoverageFixtureFile() => array ( + $this->getCoverageFixtureFile() => array( 7 => 1, // Means line executed. 8 => -1, // Means, that this test hasn't executed a tested code. 9 => 1, @@ -468,7 +468,7 @@ public function testRunWithCoverage() else { $actual_coverage = $code_coverage->getData(); $expected_coverage = array( - $this->getCoverageFixtureFile() => array ( + $this->getCoverageFixtureFile() => array( 7 => array($covered_by_test), // Means, covered by this test. 8 => array(), // Means, that this test hasn't executed a tested code. 9 => array($covered_by_test), diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index 31a77b8..f64ce6c 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -110,7 +110,7 @@ public function verifyRemoteAPICalls() $custom_data_mapping = array( 'testSuccess' => null, 'testFailure' => array( - 'status_message' => "This test is expected to fail.\nFailed asserting that false is true." + 'status_message' => "This test is expected to fail.\nFailed asserting that false is true.", ), ); @@ -153,10 +153,7 @@ public function verifyRemoteAPICalls() } /** - * Whatever or not code coverage information should be gathered. - * - * @return boolean - * @throws \RuntimeException When used before test is started. + * @inheritDoc */ public function getCollectCodeCoverageInformation() { From 24c344cf8a23ccb1cb4b30fea370585cebf2471c Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 15:44:38 +0200 Subject: [PATCH 168/204] Massive automated CS fixes in the library code itself --- .../PHPUnit/BrowserConfiguration/BrowserConfiguration.php | 1 - library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php | 4 ++-- library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php | 2 +- library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index 1f5520b..a7158f9 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -482,7 +482,6 @@ public function getTestStatusMessage(BrowserTestCase $test_case, TestResult $tes } return $test_failures ? reset($test_failures)->exceptionMessage() : ''; - } // Each test in a test case are using it's own session -> failed if test fails. diff --git a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php index f512a8c..31b7075 100644 --- a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php @@ -141,7 +141,7 @@ private function _isGoutte1() return false; } - + /** * Determines Guzzle version. * @@ -149,7 +149,7 @@ private function _isGoutte1() */ private function _isGuzzle6() { - return interface_exists('GuzzleHttp\ClientInterface') && + return interface_exists('GuzzleHttp\ClientInterface') && version_compare(\GuzzleHttp\ClientInterface::VERSION, '6.0.0', '>='); } diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index 06b3cba..411d2fc 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -157,7 +157,7 @@ protected function triggerTestSuiteEnded(array $tests = null) /* * Once browser test suite ends the shared sessions strategy can stop the browser. */ - /* @var $test BrowserTestCase|AbstractTestSuite */ + /** @var BrowserTestCase|AbstractTestSuite $test */ $test->onTestSuiteEnded(); } } diff --git a/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php b/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php index d92f6c5..b12034a 100644 --- a/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/BrowserTestSuite.php @@ -59,7 +59,7 @@ public function setBrowserFromConfiguration(array $browser, array $tests = null) $this->setBrowserFromConfiguration($browser, $test->tests()); } else { - /* @var $test BrowserTestCase */ + /** @var BrowserTestCase $test */ $test->setBrowserFromConfiguration($browser); } } From efd9e1d68bd963585eb3a2f97d4c9dbad9c62084 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 17:02:47 +0200 Subject: [PATCH 169/204] Reduce SessionStrategyManager memory usage --- .../PHPUnit/Session/SessionStrategyManager.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/library/aik099/PHPUnit/Session/SessionStrategyManager.php b/library/aik099/PHPUnit/Session/SessionStrategyManager.php index 757eab0..a4fc77d 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyManager.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyManager.php @@ -30,11 +30,11 @@ class SessionStrategyManager protected $lastUsedSessionStrategyHash; /** - * Session strategy, that was requested in browser configuration. + * Session strategy, that was last requested in the browser configuration. * - * @var ISessionStrategy[] + * @var ISessionStrategy */ - protected $sessionStrategiesInUse = array(); + protected $lastUsedSessionStrategy; /** * Session strategy, that will be used by default. @@ -94,15 +94,14 @@ public function getSessionStrategy(BrowserConfiguration $browser, BrowserTestCas $strategy_type = $browser->getSessionStrategy(); $strategy_hash = $browser->getSessionStrategyHash($test_case); - if ( $strategy_hash !== $this->lastUsedSessionStrategyHash ) { - $this->sessionStrategiesInUse[$strategy_hash] = $this->_sessionStrategyFactory->createStrategy( - $strategy_type - ); + if ( $strategy_hash === $this->lastUsedSessionStrategyHash ) { + return $this->lastUsedSessionStrategy; } + $this->lastUsedSessionStrategy = $this->_sessionStrategyFactory->createStrategy($strategy_type); $this->lastUsedSessionStrategyHash = $strategy_hash; - return $this->sessionStrategiesInUse[$strategy_hash]; + return $this->lastUsedSessionStrategy; } } From 01c25b6f87379b241b828b95576d606dba310ac4 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 17:50:38 +0200 Subject: [PATCH 170/204] Reduce SessionStrategyFactory memory usage --- CHANGELOG.md | 1 + library/.phpstorm.meta.php | 2 - library/aik099/PHPUnit/DIContainer.php | 22 ++++---- .../Session/SessionStrategyFactory.php | 36 ++++++------- .../PHPUnit/Integration/DIContainerTest.php | 2 - .../Session/SessionStrategyFactoryTest.php | 51 +++++++------------ 6 files changed, 50 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e7e1ce..530b170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Changed default OS from "Windows 7" to "Windows 10" for BrowserStack/SauceLabs browser configurations. - Allow using self-signed/invalid SSL certificates during testing on the SauceLabs by default. - Rewritten library object communication mechanism (the event dispatcher is no longer used). Update any custom session strategy/browser configuration implementations. +- Reduce memory consumption by rewriting `SessionStrategyFactory` and `SessionStrategyManager` classes. ### Fixed ... diff --git a/library/.phpstorm.meta.php b/library/.phpstorm.meta.php index e26cbbb..dcf009c 100644 --- a/library/.phpstorm.meta.php +++ b/library/.phpstorm.meta.php @@ -5,8 +5,6 @@ 'session_factory' => \aik099\PHPUnit\Session\SessionFactory::class, 'session_strategy_factory' => \aik099\PHPUnit\Session\SessionStrategyFactory::class, 'session_strategy_manager' => \aik099\PHPUnit\Session\SessionStrategyManager::class, - 'isolated_session_strategy' => \aik099\PHPUnit\Session\IsolatedSessionStrategy::class, - 'shared_session_strategy' => \aik099\PHPUnit\Session\SharedSessionStrategy::class, 'remote_url' => \aik099\PHPUnit\RemoteCoverage\RemoteUrl::class, 'remote_coverage_helper' => \aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper::class, 'test_suite_factory' => \aik099\PHPUnit\TestSuite\TestSuiteFactory::class, diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index 5c96632..c6e7fbe 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -23,6 +23,7 @@ use aik099\PHPUnit\MinkDriver\ZombieDriverFactory; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteUrl; +use aik099\PHPUnit\Session\ISessionStrategyFactory; use aik099\PHPUnit\Session\IsolatedSessionStrategy; use aik099\PHPUnit\Session\SessionFactory; use aik099\PHPUnit\Session\SessionStrategyFactory; @@ -65,7 +66,18 @@ public function __construct(array $values = array()) $this['session_strategy_factory'] = function ($c) { $session_strategy_factory = new SessionStrategyFactory(); - $session_strategy_factory->setApplication($c['application']); + + $session_strategy_factory->register( + ISessionStrategyFactory::TYPE_ISOLATED, + new IsolatedSessionStrategy($c['session_factory']) + ); + + $session_strategy_factory->register( + ISessionStrategyFactory::TYPE_SHARED, + new SharedSessionStrategy( + new IsolatedSessionStrategy($c['session_factory']) + ) + ); return $session_strategy_factory; }; @@ -74,14 +86,6 @@ public function __construct(array $values = array()) return new SessionStrategyManager($c['session_strategy_factory']); }; - $this['isolated_session_strategy'] = $this->factory(function ($c) { - return new IsolatedSessionStrategy($c['session_factory']); - }); - - $this['shared_session_strategy'] = $this->factory(function ($c) { - return new SharedSessionStrategy($c['isolated_session_strategy']); - }); - $this['remote_url'] = function () { return new RemoteUrl(); }; diff --git a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php index f748a1d..9905039 100644 --- a/library/aik099/PHPUnit/Session/SessionStrategyFactory.php +++ b/library/aik099/PHPUnit/Session/SessionStrategyFactory.php @@ -11,34 +11,39 @@ namespace aik099\PHPUnit\Session; -use aik099\PHPUnit\Application; -use aik099\PHPUnit\IApplicationAware; - /** * Produces sessions. * * @method \Mockery\Expectation shouldReceive(string $name) */ -class SessionStrategyFactory implements ISessionStrategyFactory, IApplicationAware +class SessionStrategyFactory implements ISessionStrategyFactory { /** - * Application. + * Session strategies. * - * @var Application + * @var ISessionStrategy[] */ - protected $application; + protected $sessionStrategies = array(); /** - * Sets application. + * Registers a browser configuration. * - * @param Application $application The application. + * @param string $strategy_type Session strategy type. + * @param ISessionStrategy $session_strategy Session strategy. * * @return void + * @throws \InvalidArgumentException When session strategy is already registered. */ - public function setApplication(Application $application) + public function register($strategy_type, ISessionStrategy $session_strategy) { - $this->application = $application; + if ( isset($this->sessionStrategies[$strategy_type]) ) { + throw new \InvalidArgumentException( + 'Session strategy with type "' . $strategy_type . '" is already registered' + ); + } + + $this->sessionStrategies[$strategy_type] = $session_strategy; } /** @@ -51,14 +56,11 @@ public function setApplication(Application $application) */ public function createStrategy($strategy_type) { - if ( $strategy_type == ISessionStrategyFactory::TYPE_ISOLATED ) { - return $this->application->getObject('isolated_session_strategy'); - } - elseif ( $strategy_type == ISessionStrategyFactory::TYPE_SHARED ) { - return $this->application->getObject('shared_session_strategy'); + if ( !isset($this->sessionStrategies[$strategy_type]) ) { + throw new \InvalidArgumentException('Session strategy type "' . $strategy_type . '" not registered'); } - throw new \InvalidArgumentException('Incorrect session strategy type'); + return clone $this->sessionStrategies[$strategy_type]; } } diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index 65204e7..ee3c327 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -62,8 +62,6 @@ public function serviceDefinitionsDataProvider() array('session_factory', 'aik099\\PHPUnit\\Session\\SessionFactory'), array('session_strategy_factory', 'aik099\\PHPUnit\\Session\\SessionStrategyFactory'), array('session_strategy_manager', 'aik099\\PHPUnit\\Session\\SessionStrategyManager'), - array('isolated_session_strategy', 'aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'), - array('shared_session_strategy', 'aik099\\PHPUnit\\Session\\SharedSessionStrategy'), array('remote_url', 'aik099\\PHPUnit\\RemoteCoverage\\RemoteUrl'), array('remote_coverage_helper', 'aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'), array('test_suite_factory', 'aik099\\PHPUnit\\TestSuite\\TestSuiteFactory'), diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php index 610d9bf..e805edb 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyFactoryTest.php @@ -11,12 +11,13 @@ namespace tests\aik099\PHPUnit\Session; -use aik099\PHPUnit\Session\ISessionStrategyFactory; +use aik099\PHPUnit\Session\ISessionStrategy; use aik099\PHPUnit\Session\SessionStrategyFactory; -use tests\aik099\PHPUnit\TestCase\ApplicationAwareTestCase; +use Mockery as m; +use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; -class SessionStrategyFactoryTest extends ApplicationAwareTestCase +class SessionStrategyFactoryTest extends AbstractTestCase { use ExpectException; @@ -33,49 +34,31 @@ class SessionStrategyFactoryTest extends ApplicationAwareTestCase */ protected function setUpTest() { - parent::setUpTest(); - $this->_factory = new SessionStrategyFactory(); - $this->_factory->setApplication($this->application); } - /** - * Test description. - * - * @param string $strategy_type Strategy type. - * @param string $service_id Service ID. - * - * @return void - * @dataProvider createStrategyDataProvider - */ - public function testCreateStrategySuccess($strategy_type, $service_id) + public function testRegisterSuccess() { - $expected = 'OK'; - $this->expectFactoryCall($service_id, $expected); - $this->assertEquals($expected, $this->_factory->createStrategy($strategy_type)); + $session_strategy = m::mock(ISessionStrategy::class); + $this->_factory->register('strategy-type', $session_strategy); + + $this->assertInstanceOf(ISessionStrategy::class, $this->_factory->createStrategy('strategy-type')); } - /** - * Returns possible strategies. - * - * @return array - */ - public function createStrategyDataProvider() + public function testRegisterFailure() { - return array( - array(ISessionStrategyFactory::TYPE_ISOLATED, 'isolated_session_strategy'), - array(ISessionStrategyFactory::TYPE_SHARED, 'shared_session_strategy'), - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Session strategy with type "strategy-type" is already registered'); + + $session_strategy = m::mock(ISessionStrategy::class); + $this->_factory->register('strategy-type', $session_strategy); + $this->_factory->register('strategy-type', $session_strategy); } - /** - * Test description. - * - * @return void - */ public function testCreateStrategyFailure() { $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Session strategy type "wrong" not registered'); $this->_factory->createStrategy('wrong'); } From fcba51e853ae099b77af0b59547b171689b041ee Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 20:20:22 +0200 Subject: [PATCH 171/204] Added config to reduce distributed package size --- .gitattributes | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7a3d215 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +/.github export-ignore +/docs export-ignore +/tests export-ignore +.gitattributes export-ignore +.gitignore export-ignore +CONTRIBUTING.md export-ignore +.readthedocs.yaml export-ignore +phpunit.xml.dist export-ignore From f5a1acb11e4f806d1dd93c611383316ce5416b47 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 21:08:06 +0200 Subject: [PATCH 172/204] Made data provider methods static --- tests/PimpleCopy/Pimple/PimpleTest.php | 4 ++-- .../ApiBrowserConfigurationTestCase.php | 14 +++++++++----- .../BrowserConfigurationFactoryTest.php | 2 +- .../BrowserConfigurationTest.php | 4 ++-- .../BrowserStackBrowserConfigurationTest.php | 6 ++---- .../SauceLabsBrowserConfigurationTest.php | 6 ++---- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 2 +- .../aik099/PHPUnit/Integration/DIContainerTest.php | 2 +- .../PHPUnit/Integration/DataProviderTest.php | 2 +- .../PHPUnit/MinkDriver/DriverFactoryTest.php | 2 +- .../RemoteCoverage/RemoteCoverageHelperTest.php | 4 ++-- .../PHPUnit/Session/SharedSessionStrategyTest.php | 2 +- .../PHPUnit/TestSuite/BrowserTestSuiteTest.php | 2 +- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/PimpleCopy/Pimple/PimpleTest.php b/tests/PimpleCopy/Pimple/PimpleTest.php index 7937532..b856970 100644 --- a/tests/PimpleCopy/Pimple/PimpleTest.php +++ b/tests/PimpleCopy/Pimple/PimpleTest.php @@ -353,7 +353,7 @@ public function testExtendFailsForInvalidServiceDefinitions($service) /** * Provider for invalid service definitions. */ - public function badServiceDefinitionProvider() + public static function badServiceDefinitionProvider() { return array( array(123), @@ -364,7 +364,7 @@ public function badServiceDefinitionProvider() /** * Provider for service definitions. */ - public function serviceDefinitionProvider() + public static function serviceDefinitionProvider() { return array( array(function ($value) { diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 09e24f9..13b0e6b 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -198,8 +198,12 @@ public function testSetDesiredCapabilitiesCorrect(array $desired_capabilities = * Desired capability data provider. * * @return array + * @throws \RuntimeException When not overridden in a subclass. */ - abstract public function desiredCapabilitiesDataProvider(); + public static function desiredCapabilitiesDataProvider() + { + throw new \RuntimeException('Not overridden in a subclass'); + } /** * Test description. @@ -267,7 +271,7 @@ private function _isAutomaticTestName($test_name) * * @return array */ - public function setupProcessDataProvider() + public static function setupProcessDataProvider() { $seed = uniqid(); @@ -333,7 +337,7 @@ public function testOnTestEnded($driver_type) * * @return array */ - public function onTestEndedDataProvider() + public static function onTestEndedDataProvider() { return array( array('selenium'), @@ -362,7 +366,7 @@ public function testTestEndedWithoutSession($stopped_or_missing) $this->browser->onTestEnded($test_case, $test_result); } - public function sessionStateDataProvider() + public static function sessionStateDataProvider() { return array( 'session stopped/missing' => array(true), @@ -435,7 +439,7 @@ public function testTunnelIdentifier($tunnel_id = null) * * @return array */ - public function tunnelIdentifierDataProvider() + public static function tunnelIdentifierDataProvider() { return array( array('AAA'), diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index 87b280b..a9d330f 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -80,7 +80,7 @@ public function testCreateBrowserConfiguration(array $browser_config, $type) * * @return array */ - public function createBrowserConfigurationDataProvider() + public static function createBrowserConfigurationDataProvider() { return array( array(array('type' => 'test'), 'test'), diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 1f8abe6..3998f2c 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -166,7 +166,7 @@ public function testAliasResolution(array $aliases, array $browser_config, array * * @return array */ - public function aliasResolutionDataProvider() + public static function aliasResolutionDataProvider() { return array( 'single alias' => array( @@ -525,7 +525,7 @@ public function testGetSessionStrategyHashBrowserSharing($session_strategy) * * @return array */ - public function sessionSharingDataProvider() + public static function sessionSharingDataProvider() { return array( array(ISessionStrategyFactory::TYPE_ISOLATED), diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php index e318071..d567fcb 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -58,11 +58,9 @@ public function testSetHostCorrect() } /** - * Desired capability data provider. - * - * @return array + * @inheritDoc */ - public function desiredCapabilitiesDataProvider() + public static function desiredCapabilitiesDataProvider() { return array( array( diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index dc916c8..f528a2c 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -56,11 +56,9 @@ public function testSetHostCorrect() } /** - * Desired capability data provider. - * - * @return array + * @inheritDoc */ - public function desiredCapabilitiesDataProvider() + public static function desiredCapabilitiesDataProvider() { return array( array( diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index f64ce6c..c83c3b6 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -183,7 +183,7 @@ public function testSuccess($data) $this->assertTrue(true); } - public function successDataProvider() + public static function successDataProvider() { return array( 'true' => array(true), diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index ee3c327..20af4ca 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -55,7 +55,7 @@ public function testServiceDefinitions($service_id, $class_name) * * @return array */ - public function serviceDefinitionsDataProvider() + public static function serviceDefinitionsDataProvider() { return array( array('application', 'aik099\\PHPUnit\\Application'), diff --git a/tests/aik099/PHPUnit/Integration/DataProviderTest.php b/tests/aik099/PHPUnit/Integration/DataProviderTest.php index aeeaed0..c42068e 100644 --- a/tests/aik099/PHPUnit/Integration/DataProviderTest.php +++ b/tests/aik099/PHPUnit/Integration/DataProviderTest.php @@ -26,7 +26,7 @@ class DataProviderTest extends BrowserStackAwareTestCase ), ); - public function sampleDataProvider() + public static function sampleDataProvider() { return array( array('case1'), diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php index 5c51afc..8a17918 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php @@ -75,7 +75,7 @@ protected function createBrowserConfiguration(IMinkDriverFactory $factory) return $browser_configuration; } - public function driverDataProvider() + public static function driverDataProvider() { return array( 'goutte' => array( diff --git a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php index e49f53d..67e1faa 100644 --- a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php +++ b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php @@ -70,7 +70,7 @@ public function testCreateUrlError($coverage_script_url, $test_id) * * @return array */ - public function createUrlErrorDataProvider() + public static function createUrlErrorDataProvider() { return array( array('', 'test-id'), @@ -114,7 +114,7 @@ public function testCreateUrl($coverage_script_url, $test_id, $expected_url) * * @return array */ - public function createUrlDataProvider() + public static function createUrlDataProvider() { return array( array('http://host', 'test-id', 'http://host?rct_mode=output&PHPUNIT_MINK_TEST_ID=test-id'), diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index 6234f9f..898b1f4 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -86,7 +86,7 @@ public function testSessionSharing(\Exception $e = null) * * @return array */ - public function ignoreExceptionDataProvider() + public static function ignoreExceptionDataProvider() { return array( array(null), diff --git a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php index 3e8b8a4..f9a6805 100644 --- a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php @@ -52,7 +52,7 @@ public function testNameFromBrowser(array $browser, $expected_name) * * @return array */ - public function nameFromBrowserDataProvider() + public static function nameFromBrowserDataProvider() { return array( array(array('alias' => 'match'), 'match'), From 0d91116e67feb4662b4b67db95d6fa220dfcd930 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 21:54:34 +0200 Subject: [PATCH 173/204] Use the "::class" in test suite for class referencing --- tests/aik099/PHPUnit/ApplicationTest.php | 8 ++-- .../ApiBrowserConfigurationTestCase.php | 15 +++--- .../BrowserConfigurationFactoryTest.php | 9 ++-- .../BrowserConfigurationTest.php | 11 +++-- .../BrowserStackBrowserConfigurationTest.php | 4 +- .../SauceLabsBrowserConfigurationTest.php | 4 +- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 46 +++++++++---------- tests/aik099/PHPUnit/Fixture/SetupFixture.php | 21 +++++---- .../Integration/ApiIntegrationTest.php | 2 +- .../PHPUnit/Integration/DIContainerTest.php | 38 +++++++++------ .../Integration/EventDispatchingTest.php | 2 +- .../PHPUnit/Integration/SuiteBuildingTest.php | 13 +++--- .../MinkDriver/DriverFactoryRegistryTest.php | 5 +- .../PHPUnit/MinkDriver/DriverFactoryTest.php | 20 ++++---- .../RemoteCoverageHelperTest.php | 9 ++-- .../Session/IsolatedSessionStrategyTest.php | 2 +- .../PHPUnit/Session/SessionFactoryTest.php | 9 ++-- .../Session/SessionStrategyManagerTest.php | 16 ++++--- .../Session/SessionStrategyTestCase.php | 9 ++-- .../Session/SharedSessionStrategyTest.php | 2 +- .../TestCase/ApplicationAwareTestCase.php | 2 +- .../TestSuite/BrowserTestSuiteTest.php | 3 +- .../TestSuite/RegularTestSuiteTest.php | 15 ++++-- .../TestSuite/TestSuiteFactoryTest.php | 19 ++++---- 24 files changed, 163 insertions(+), 121 deletions(-) diff --git a/tests/aik099/PHPUnit/ApplicationTest.php b/tests/aik099/PHPUnit/ApplicationTest.php index 407c582..4c8f480 100644 --- a/tests/aik099/PHPUnit/ApplicationTest.php +++ b/tests/aik099/PHPUnit/ApplicationTest.php @@ -13,6 +13,7 @@ use aik099\PHPUnit\Application; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; +use aik099\PHPUnit\TestSuite\TestSuiteFactory; class ApplicationTest extends AbstractTestCase { @@ -51,10 +52,7 @@ public function testInstanceIsShared() */ public function testGetTestSuiteFactory() { - $this->assertInstanceOf( - 'aik099\\PHPUnit\\TestSuite\\TestSuiteFactory', - $this->_application->getTestSuiteFactory() - ); + $this->assertInstanceOf(TestSuiteFactory::class, $this->_application->getTestSuiteFactory()); } /** @@ -64,7 +62,7 @@ public function testGetTestSuiteFactory() */ public function testGetObject() { - $this->assertInstanceOf('aik099\\PHPUnit\\Application', $this->_application->getObject('application')); + $this->assertInstanceOf(Application::class, $this->_application->getObject('application')); } /** diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php index 13b0e6b..d3202d0 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/ApiBrowserConfigurationTestCase.php @@ -19,6 +19,9 @@ use ConsoleHelpers\PHPUnitCompat\Framework\TestResult; use Mockery as m; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; +use Behat\Mink\Driver\Selenium2Driver; +use Behat\Mink\Driver\DriverInterface; +use Behat\Mink\Session; abstract class ApiBrowserConfigurationTestCase extends BrowserConfigurationTest { @@ -56,10 +59,10 @@ abstract class ApiBrowserConfigurationTestCase extends BrowserConfigurationTest protected function setUpTest() { if ( $this->needsAPIClient() ) { - $this->apiClient = m::mock('\\aik099\\PHPUnit\\APIClient\\IAPIClient'); + $this->apiClient = m::mock(IAPIClient::class); } - $this->apiClientFactory = m::mock('\\aik099\\PHPUnit\\APIClient\\APIClientFactory'); + $this->apiClientFactory = m::mock(APIClientFactory::class); parent::setUpTest(); @@ -309,7 +312,7 @@ public function testOnTestEnded($driver_type) $test_case = $this->createTestCase('TEST_NAME'); if ( $driver_type == 'selenium' ) { - $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); + $driver = m::mock(Selenium2Driver::class); $driver->shouldReceive('getWebDriverSessionId')->once()->andReturn('SID'); $this->apiClient->shouldReceive('updateStatus')->with('SID', true, 'test status message')->once(); @@ -317,11 +320,11 @@ public function testOnTestEnded($driver_type) $test_case->shouldReceive('getStatusMessage')->once()->andReturn('test status message'); // For shared strategy. } else { - $driver = m::mock('\\Behat\\Mink\\Driver\\DriverInterface'); + $driver = m::mock(DriverInterface::class); $this->expectException('RuntimeException'); } - $session = m::mock('Behat\\Mink\\Session'); + $session = m::mock(Session::class); $session->shouldReceive('getDriver')->once()->andReturn($driver); $session->shouldReceive('isStarted')->once()->andReturn(true); @@ -353,7 +356,7 @@ public function testTestEndedWithoutSession($stopped_or_missing) $test_case = $this->createTestCase('TEST_NAME'); if ( $stopped_or_missing ) { - $session = m::mock('Behat\\Mink\\Session'); + $session = m::mock(Session::class); $session->shouldReceive('isStarted')->once()->andReturn(false); $test_case->shouldReceive('getSession')->with(false)->once()->andReturn($session); } diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php index a9d330f..ade1567 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationFactoryTest.php @@ -16,6 +16,7 @@ use Mockery as m; use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; +use aik099\PHPUnit\BrowserTestCase; class BrowserConfigurationFactoryTest extends AbstractTestCase { @@ -51,7 +52,7 @@ public function testCreateBrowserConfiguration(array $browser_config, $type) { $browser_aliases = array('alias-one' => array()); - $test_case = m::mock('aik099\\PHPUnit\\BrowserTestCase'); + $test_case = m::mock(BrowserTestCase::class); $test_case->shouldReceive('getBrowserAliases')->once()->andReturn($browser_aliases); $cleaned_browser_config = $browser_config; @@ -72,7 +73,7 @@ public function testCreateBrowserConfiguration(array $browser_config, $type) $actual_browser = $this->_factory->createBrowserConfiguration($browser_config, $test_case); $this->assertEquals($type, $actual_browser->getType()); - $this->assertInstanceOf('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration', $actual_browser); + $this->assertInstanceOf(BrowserConfiguration::class, $actual_browser); } /** @@ -99,7 +100,7 @@ public function testCreateBrowserConfigurationError() $browser_aliases = array('alias-one' => array()); - $test_case = m::mock('aik099\\PHPUnit\\BrowserTestCase'); + $test_case = m::mock(BrowserTestCase::class); $test_case->shouldReceive('getBrowserAliases')->once()->andReturn($browser_aliases); $this->_factory->createBrowserConfiguration(array('type' => 'test'), $test_case); @@ -128,7 +129,7 @@ public function testRegisterFailure() */ private function _createBrowserConfiguration($type) { - $browser_configuration = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser_configuration = m::mock(BrowserConfiguration::class); $browser_configuration->shouldReceive('getType')->andReturn($type); return $browser_configuration; diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php index 3998f2c..bfad600 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserConfigurationTest.php @@ -22,13 +22,14 @@ use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; +use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; class BrowserConfigurationTest extends AbstractTestCase { use ExpectException; - const TEST_CASE_CLASS = '\\aik099\\PHPUnit\\BrowserTestCase'; + const TEST_CASE_CLASS = BrowserTestCase::class; const HOST = 'example_host'; @@ -89,7 +90,7 @@ class BrowserConfigurationTest extends AbstractTestCase protected function setUpTest() { if ( !$this->browserConfigurationClass ) { - $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; + $this->browserConfigurationClass = BrowserConfiguration::class; } $this->setup = array( @@ -116,9 +117,9 @@ protected function setUpTest() */ protected function createDriverFactoryRegistry() { - $registry = m::mock('\\aik099\\PHPUnit\\MinkDriver\\DriverFactoryRegistry'); + $registry = m::mock(DriverFactoryRegistry::class); - $selenium2_driver_factory = m::mock('\\aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $selenium2_driver_factory = m::mock(IMinkDriverFactory::class); $selenium2_driver_factory->shouldReceive('getDriverDefaults')->andReturn(array( 'baseUrl' => 'http://www.super-url.com', 'driverOptions' => array( @@ -130,7 +131,7 @@ protected function createDriverFactoryRegistry() ->with('selenium2') ->andReturn($selenium2_driver_factory); - $zombie_driver_factory = m::mock('\\aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $zombie_driver_factory = m::mock(IMinkDriverFactory::class); $zombie_driver_factory->shouldReceive('getDriverDefaults')->andReturn(array()); $registry ->shouldReceive('get') diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php index d567fcb..c157b55 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/BrowserStackBrowserConfigurationTest.php @@ -11,6 +11,8 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; + class BrowserStackBrowserConfigurationTest extends ApiBrowserConfigurationTestCase { @@ -21,7 +23,7 @@ class BrowserStackBrowserConfigurationTest extends ApiBrowserConfigurationTestCa */ protected function setUpTest() { - $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserStackBrowserConfiguration'; + $this->browserConfigurationClass = BrowserStackBrowserConfiguration::class; $this->tunnelCapabilities = array( 'browserstack.local' => 'true', diff --git a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php index f528a2c..2d97375 100644 --- a/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php +++ b/tests/aik099/PHPUnit/BrowserConfiguration/SauceLabsBrowserConfigurationTest.php @@ -11,6 +11,8 @@ namespace tests\aik099\PHPUnit\BrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; + class SauceLabsBrowserConfigurationTest extends ApiBrowserConfigurationTestCase { @@ -21,7 +23,7 @@ class SauceLabsBrowserConfigurationTest extends ApiBrowserConfigurationTestCase */ protected function setUpTest() { - $this->browserConfigurationClass = 'aik099\\PHPUnit\\BrowserConfiguration\\SauceLabsBrowserConfiguration'; + $this->browserConfigurationClass = SauceLabsBrowserConfiguration::class; $this->tunnelCapabilities = array( 'tunnel-identifier' => 'env:PHPUNIT_MINK_TUNNEL_ID', diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 935a078..d648731 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -30,17 +30,20 @@ use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; +use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; +use Behat\Mink\Session; +use ConsoleHelpers\CodeCoverageCompat\Driver\Driver; class BrowserTestCaseTest extends AbstractTestCase { use ExpectException; - const BROWSER_CLASS = '\\aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; + const BROWSER_CLASS = BrowserConfiguration::class; - const MANAGER_CLASS = '\\aik099\\PHPUnit\\Session\\SessionStrategyManager'; + const MANAGER_CLASS = SessionStrategyManager::class; - const SESSION_STRATEGY_INTERFACE = '\\aik099\\PHPUnit\\Session\\ISessionStrategy'; + const SESSION_STRATEGY_INTERFACE = ISessionStrategy::class; /** * Browser configuration factory. @@ -59,9 +62,7 @@ protected function setUpTest() define('PHPUNIT_TESTSUITE', true); } - $this->browserConfigurationFactory = m::mock( - 'aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory' - ); + $this->browserConfigurationFactory = m::mock(IBrowserConfigurationFactory::class); } /** @@ -109,9 +110,9 @@ public function testSetBrowserCorrect() */ protected function createDriverFactoryRegistry() { - $registry = m::mock('\\aik099\\PHPUnit\\MinkDriver\\DriverFactoryRegistry'); + $registry = m::mock(DriverFactoryRegistry::class); - $driver_factory = m::mock('\\aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $driver_factory = m::mock(IMinkDriverFactory::class); $driver_factory->shouldReceive('getDriverDefaults')->andReturn(array()); $registry @@ -203,8 +204,8 @@ public function testGetSession() { $browser = $this->getBrowser(0); - $expected_session1 = m::mock('\\Behat\\Mink\\Session'); - $expected_session2 = m::mock('\\Behat\\Mink\\Session'); + $expected_session1 = m::mock(Session::class); + $expected_session2 = m::mock(Session::class); /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); @@ -291,10 +292,7 @@ public function testGetCollectCodeCoverageInformationSuccess() ); } else { - $code_coverage = new CodeCoverage( - m::mock('\\ConsoleHelpers\\CodeCoverageCompat\\Driver\\Driver'), - new Filter() - ); + $code_coverage = new CodeCoverage(m::mock(Driver::class), new Filter()); } $test_result->setCodeCoverage($code_coverage); @@ -331,7 +329,7 @@ public function testRunCreateResult() /** @var BrowserTestCase $test_case */ list($test_case,) = $this->prepareForRun(); - $this->assertInstanceOf('\\ConsoleHelpers\\PHPUnitCompat\\Framework\\TestResult', $test_case->run()); + $this->assertInstanceOf(TestResult::class, $test_case->run()); } /** @@ -368,7 +366,7 @@ public function testRunWithCoverageWithoutRemoteUrl() $browser = $test_case->getBrowser(); $browser->shouldReceive('getBaseUrl')->once()->andReturn('A'); - $session = m::mock('\\Behat\\Mink\\Session'); + $session = m::mock(Session::class); $session->shouldReceive('visit')->with('A')->once(); $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, null)->once(); $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, m::not(''))->once(); @@ -377,7 +375,7 @@ public function testRunWithCoverageWithoutRemoteUrl() $test_case->run($result); - if ( \class_exists('\SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData') ) { + if ( \class_exists(ProcessedCodeCoverageData::class) ) { $actual_coverage = $code_coverage->getData(); $expected_coverage = new ProcessedCodeCoverageData(); $expected_coverage->setLineCoverage(array( @@ -443,7 +441,7 @@ public function testRunWithCoverage() $browser = $test_case->getBrowser(); $browser->shouldReceive('getBaseUrl')->once()->andReturn('A'); - $session = m::mock('\\Behat\\Mink\\Session'); + $session = m::mock(Session::class); $session->shouldReceive('visit')->with('A')->once(); $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, null)->once(); $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, m::not(''))->once(); @@ -454,7 +452,7 @@ public function testRunWithCoverage() $covered_by_test = 'tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig::getTestId'; - if ( \class_exists('\SebastianBergmann\CodeCoverage\ProcessedCodeCoverageData') ) { + if ( \class_exists(ProcessedCodeCoverageData::class) ) { $expected_coverage = new ProcessedCodeCoverageData(); $expected_coverage->setLineCoverage(array( $this->getCoverageFixtureFile() => array( @@ -502,10 +500,10 @@ protected function getCoverageFixtureFile() */ protected function getRemoteCoverageHelperMock(array $expected_coverage = null) { - $remote_coverage_helper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); + $remote_coverage_helper = m::mock(RemoteCoverageHelper::class); if ( $expected_coverage !== null ) { - if ( \class_exists('\SebastianBergmann\CodeCoverage\RawCodeCoverageData') ) { + if ( \class_exists(RawCodeCoverageData::class) ) { $remote_coverage_helper ->shouldReceive('get') ->with('some-url', 'tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig__getTestId') @@ -519,7 +517,7 @@ protected function getRemoteCoverageHelperMock(array $expected_coverage = null) } } - if ( \class_exists('\SebastianBergmann\CodeCoverage\RawCodeCoverageData') ) { + if ( \class_exists(RawCodeCoverageData::class) ) { $remote_coverage_helper ->shouldReceive('getEmpty') ->andReturn(RawCodeCoverageData::fromXdebugWithoutPathCoverage(array())); @@ -546,13 +544,13 @@ protected function getCodeCoverageMock(array $expected_coverage) $driver = m::mock('\PHP_CodeCoverage_Driver'); } else { - $driver = m::mock('\\ConsoleHelpers\\CodeCoverageCompat\\Driver\\Driver'); + $driver = m::mock(Driver::class); } $driver->shouldReceive('start')->once(); // Can't assert call count, because expectations are verified prior to coverage being queried. - if ( \class_exists('\SebastianBergmann\CodeCoverage\RawCodeCoverageData') ) { + if ( \class_exists(RawCodeCoverageData::class) ) { $driver->shouldReceive('stop') /*->once()*/ ->andReturn( diff --git a/tests/aik099/PHPUnit/Fixture/SetupFixture.php b/tests/aik099/PHPUnit/Fixture/SetupFixture.php index c071c97..b88a393 100644 --- a/tests/aik099/PHPUnit/Fixture/SetupFixture.php +++ b/tests/aik099/PHPUnit/Fixture/SetupFixture.php @@ -19,6 +19,10 @@ use Behat\Mink\Session; use Mockery as m; use tests\aik099\PHPUnit\TVerifyTestExpectations; +use aik099\PHPUnit\APIClient\IAPIClient; +use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; +use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; +use Behat\Mink\Driver\Selenium2Driver; class SetupFixture extends BrowserTestCase { @@ -30,11 +34,11 @@ class SetupFixture extends BrowserTestCase */ protected function setUpTest() { - $api_client = m::mock('aik099\\PHPUnit\\APIClient\\IAPIClient'); + $api_client = m::mock(IAPIClient::class); $api_client->shouldReceive('updateStatus')->withAnyArgs()->once(); /** @var APIClientFactory $api_client_factory */ - $api_client_factory = m::mock('\\aik099\\PHPUnit\\APIClient\\APIClientFactory'); + $api_client_factory = m::mock(APIClientFactory::class); $browser = new SauceLabsBrowserConfiguration($this->createDriverFactoryRegistry(), $api_client_factory); @@ -46,8 +50,7 @@ protected function setUpTest() $browser_config = array('apiUsername' => 'a', 'apiKey' => 'b'); - /** @var IBrowserConfigurationFactory $factory */ - $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); + $factory = m::mock(IBrowserConfigurationFactory::class); $factory->shouldReceive('createBrowserConfiguration') ->with($browser_config, $this) @@ -67,9 +70,9 @@ protected function setUpTest() */ protected function createDriverFactoryRegistry() { - $registry = m::mock('\\aik099\\PHPUnit\\MinkDriver\\DriverFactoryRegistry'); + $registry = m::mock(DriverFactoryRegistry::class); - $driver_factory = m::mock('\\aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $driver_factory = m::mock(IMinkDriverFactory::class); $driver_factory->shouldReceive('getDriverDefaults')->andReturn(array()); $registry @@ -87,10 +90,10 @@ protected function createDriverFactoryRegistry() */ public function testEvents() { - $driver = m::mock('\\Behat\\Mink\\Driver\\Selenium2Driver'); + $driver = m::mock(Selenium2Driver::class); $driver->shouldReceive('getWebDriverSessionId')->once()->andReturn('SID'); - $session = m::mock('Behat\\Mink\\Session'); + $session = m::mock(Session::class); // For ApiBrowserConfiguration::onTestEnded. $session->shouldReceive('getDriver')->once()->andReturn($driver); @@ -114,7 +117,7 @@ public function testEvents() */ private function _setSession(Session $session) { - $property = new \ReflectionProperty('aik099\\PHPUnit\\BrowserTestCase', '_session'); + $property = new \ReflectionProperty(BrowserTestCase::class, '_session'); $property->setAccessible(true); $property->setValue($this, $session); } diff --git a/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php b/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php index 82a1e47..93f827c 100644 --- a/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php +++ b/tests/aik099/PHPUnit/Integration/ApiIntegrationTest.php @@ -40,7 +40,7 @@ public function testAPICalls() { $result = new TestResult(); - $suite = ApiIntegrationFixture::suite('tests\\aik099\\PHPUnit\\Fixture\\ApiIntegrationFixture'); + $suite = ApiIntegrationFixture::suite(ApiIntegrationFixture::class); $suite->run($result); $this->assertTrue(true); diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index 20af4ca..82e9acd 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -14,6 +14,17 @@ use aik099\PHPUnit\Application; use aik099\PHPUnit\DIContainer; use tests\aik099\PHPUnit\AbstractTestCase; +use aik099\PHPUnit\TestSuite\RegularTestSuite; +use aik099\PHPUnit\TestSuite\BrowserTestSuite; +use aik099\PHPUnit\APIClient\APIClientFactory; +use aik099\PHPUnit\TestSuite\TestSuiteFactory; +use aik099\PHPUnit\RemoteCoverage\RemoteUrl; +use aik099\PHPUnit\Session\SessionStrategyManager; +use aik099\PHPUnit\Session\SessionStrategyFactory; +use aik099\PHPUnit\Session\SessionFactory; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; +use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; +use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; class DIContainerTest extends AbstractTestCase { @@ -58,21 +69,18 @@ public function testServiceDefinitions($service_id, $class_name) public static function serviceDefinitionsDataProvider() { return array( - array('application', 'aik099\\PHPUnit\\Application'), - array('session_factory', 'aik099\\PHPUnit\\Session\\SessionFactory'), - array('session_strategy_factory', 'aik099\\PHPUnit\\Session\\SessionStrategyFactory'), - array('session_strategy_manager', 'aik099\\PHPUnit\\Session\\SessionStrategyManager'), - array('remote_url', 'aik099\\PHPUnit\\RemoteCoverage\\RemoteUrl'), - array('remote_coverage_helper', 'aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'), - array('test_suite_factory', 'aik099\\PHPUnit\\TestSuite\\TestSuiteFactory'), - array('regular_test_suite', 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'), - array('browser_test_suite', 'aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'), - array('api_client_factory', 'aik099\\PHPUnit\\APIClient\\APIClientFactory'), - array( - 'browser_configuration_factory', - 'aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfigurationFactory', - ), - array('driver_factory_registry', 'aik099\\PHPUnit\\MinkDriver\\DriverFactoryRegistry'), + array('application', Application::class), + array('session_factory', SessionFactory::class), + array('session_strategy_factory', SessionStrategyFactory::class), + array('session_strategy_manager', SessionStrategyManager::class), + array('remote_url', RemoteUrl::class), + array('remote_coverage_helper', RemoteCoverageHelper::class), + array('test_suite_factory', TestSuiteFactory::class), + array('regular_test_suite', RegularTestSuite::class), + array('browser_test_suite', BrowserTestSuite::class), + array('api_client_factory', APIClientFactory::class), + array('browser_configuration_factory', BrowserConfigurationFactory::class), + array('driver_factory_registry', DriverFactoryRegistry::class), ); } diff --git a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php index 56cb306..dbf9a31 100644 --- a/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php +++ b/tests/aik099/PHPUnit/Integration/EventDispatchingTest.php @@ -56,7 +56,7 @@ public function testSetupEvent() $result = new TestResult(); - $suite = SetupFixture::suite('tests\\aik099\\PHPUnit\\Fixture\\SetupFixture'); + $suite = SetupFixture::suite(SetupFixture::class); $suite->run($result); $error_msgs = array(); diff --git a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php index 690584e..c176c7c 100644 --- a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php @@ -20,17 +20,18 @@ use tests\aik099\PHPUnit\AbstractTestCase; use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; +use aik099\PHPUnit\Session\ISessionStrategy; class SuiteBuildingTest extends AbstractTestCase { - const SUITE_CLASS = '\\aik099\\PHPUnit\\TestSuite\\RegularTestSuite'; + const SUITE_CLASS = RegularTestSuite::class; - const BROWSER_SUITE_CLASS = '\\aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'; + const BROWSER_SUITE_CLASS = BrowserTestSuite::class; - const TEST_CASE_WITH_CONFIG = '\\tests\\aik099\\PHPUnit\\Fixture\\WithBrowserConfig'; + const TEST_CASE_WITH_CONFIG = WithBrowserConfig::class; - const TEST_CASE_WITHOUT_CONFIG = '\\tests\\aik099\\PHPUnit\\Fixture\\WithoutBrowserConfig'; + const TEST_CASE_WITHOUT_CONFIG = WithoutBrowserConfig::class; /** * Tests, that suite is built correctly in case, when static $browsers array is filled-in in test case class. @@ -53,7 +54,7 @@ public function testWithBrowserConfiguration() $suite_tests = $test_suite->tests(); $this->checkArray($suite_tests, 2, self::TEST_CASE_WITH_CONFIG); - $this->assertInstanceOf('aik099\PHPUnit\Session\ISessionStrategy', $suite_tests[0]->getSessionStrategy()); + $this->assertInstanceOf(ISessionStrategy::class, $suite_tests[0]->getSessionStrategy()); } } @@ -134,7 +135,7 @@ protected function createTestSuite($class_name) */ protected function getPhpUnitVersion() { - if ( \class_exists('PHPUnit\Runner\Version') ) { + if ( \class_exists(Version::class) ) { return Version::id(); } diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php index c23d99d..d60dd82 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php @@ -16,6 +16,7 @@ use Mockery as m; use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; +use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; class DriverFactoryRegistryTest extends AbstractTestCase { @@ -39,7 +40,7 @@ public function setUpTest() public function testAddingAndGetting() { - $factory = m::mock('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $factory = m::mock(IMinkDriverFactory::class); $factory->shouldReceive('getDriverName')->andReturn('test'); $this->_driverFactoryRegistry->add($factory); @@ -52,7 +53,7 @@ public function testAddingExisting() $this->expectException('LogicException'); $this->expectExceptionMessage('Driver factory for "test" driver is already registered.'); - $factory = m::mock('aik099\\PHPUnit\\MinkDriver\\IMinkDriverFactory'); + $factory = m::mock(IMinkDriverFactory::class); $factory->shouldReceive('getDriverName')->andReturn('test'); $this->_driverFactoryRegistry->add($factory); diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php index 8a17918..54b6360 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php @@ -17,6 +17,10 @@ use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; +use aik099\PHPUnit\MinkDriver\GoutteDriverFactory; +use aik099\PHPUnit\MinkDriver\SahiDriverFactory; +use aik099\PHPUnit\MinkDriver\Selenium2DriverFactory; +use aik099\PHPUnit\MinkDriver\ZombieDriverFactory; class DriverFactoryTest extends AbstractTestCase { @@ -79,20 +83,20 @@ public static function driverDataProvider() { return array( 'goutte' => array( - 'Behat\\Mink\\Driver\\GoutteDriver', - 'aik099\PHPUnit\MinkDriver\GoutteDriverFactory', + '\Behat\Mink\Driver\GoutteDriver', + GoutteDriverFactory::class, ), 'sahi' => array( - 'Behat\\Mink\\Driver\\SahiDriver', - 'aik099\PHPUnit\MinkDriver\SahiDriverFactory', + '\Behat\Mink\Driver\SahiDriver', + SahiDriverFactory::class, ), 'selenium2' => array( - 'Behat\\Mink\\Driver\\Selenium2Driver', - 'aik099\PHPUnit\MinkDriver\Selenium2DriverFactory', + '\Behat\Mink\Driver\Selenium2Driver', + Selenium2DriverFactory::class, ), 'zombie' => array( - 'Behat\\Mink\\Driver\\ZombieDriver', - 'aik099\PHPUnit\MinkDriver\ZombieDriverFactory', + '\Behat\Mink\Driver\ZombieDriver', + ZombieDriverFactory::class, ), ); } diff --git a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php index 67e1faa..952f06c 100644 --- a/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php +++ b/tests/aik099/PHPUnit/RemoteCoverage/RemoteCoverageHelperTest.php @@ -18,6 +18,7 @@ use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\AssertIsType; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; +use SebastianBergmann\CodeCoverage\RawCodeCoverageData; class RemoteCoverageHelperTest extends AbstractTestCase { @@ -45,7 +46,7 @@ class RemoteCoverageHelperTest extends AbstractTestCase */ protected function setUpTest() { - $this->_remoteUrl = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteUrl'); + $this->_remoteUrl = m::mock(RemoteUrl::class); $this->_remoteCoverageHelper = new RemoteCoverageHelper($this->_remoteUrl); } @@ -99,8 +100,8 @@ public function testCreateUrl($coverage_script_url, $test_id, $expected_url) $result = $this->_remoteCoverageHelper->get($coverage_script_url, $test_id); - if ( \class_exists('\SebastianBergmann\CodeCoverage\RawCodeCoverageData') ) { - $this->assertInstanceOf('\SebastianBergmann\CodeCoverage\RawCodeCoverageData', $result); + if ( \class_exists(RawCodeCoverageData::class) ) { + $this->assertInstanceOf(RawCodeCoverageData::class, $result); $this->assertCount(0, $result->lineCoverage()); } else { @@ -165,7 +166,7 @@ public function testValidCoverageIsReturned() 14 => 1, ); - if ( \class_exists('\SebastianBergmann\CodeCoverage\RawCodeCoverageData') ) { + if ( \class_exists(RawCodeCoverageData::class) ) { $this->assertEquals(array($class_source_file => $expected), $content->lineCoverage()); } else { diff --git a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php index 43be1b9..3f40dfd 100644 --- a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php @@ -31,7 +31,7 @@ class IsolatedSessionStrategyTest extends SessionStrategyTestCase */ protected function setUpTest() { - $this->_factory = m::mock('aik099\\PHPUnit\\Session\\ISessionFactory'); + $this->_factory = m::mock(ISessionFactory::class); $this->strategy = new IsolatedSessionStrategy($this->_factory); } diff --git a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php index 7a8677a..9e016c6 100644 --- a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php +++ b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php @@ -14,6 +14,9 @@ use aik099\PHPUnit\Session\SessionFactory; use Mockery as m; use tests\aik099\PHPUnit\AbstractTestCase; +use Behat\Mink\Driver\DriverInterface; +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use Behat\Mink\Session; class SessionFactoryTest extends AbstractTestCase { @@ -40,15 +43,15 @@ protected function setUpTest() */ public function testCreateSession() { - $driver = m::mock('Behat\\Mink\\Driver\\DriverInterface'); + $driver = m::mock(DriverInterface::class); $driver->shouldReceive('setSession')->with(m::any())->once(); - $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser = m::mock(BrowserConfiguration::class); $browser->shouldReceive('createDriver')->once()->andReturn($driver); $session = $this->_factory->createSession($browser); - $this->assertInstanceOf('Behat\\Mink\\Session', $session); + $this->assertInstanceOf(Session::class, $session); $this->assertSame($driver, $session->getDriver()); } diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php index 4f584e3..14c8d35 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyManagerTest.php @@ -17,6 +17,10 @@ use aik099\PHPUnit\Session\SessionStrategyManager; use Mockery as m; use tests\aik099\PHPUnit\AbstractTestCase; +use aik099\PHPUnit\Session\IsolatedSessionStrategy; +use aik099\PHPUnit\Session\SharedSessionStrategy; +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\BrowserTestCase; class SessionStrategyManagerTest extends AbstractTestCase { @@ -40,7 +44,7 @@ class SessionStrategyManagerTest extends AbstractTestCase */ protected function setUpTest() { - $this->factory = m::mock('aik099\\PHPUnit\\Session\\ISessionStrategyFactory'); + $this->factory = m::mock(ISessionStrategyFactory::class); $this->manager = new SessionStrategyManager($this->factory); } @@ -79,7 +83,7 @@ public function testGetSessionStrategySharing() $this->factory ->shouldReceive('createStrategy') ->andReturnUsing(function () { - return m::mock('aik099\\PHPUnit\\Session\\ISessionStrategy'); + return m::mock(ISessionStrategy::class); }); // Sequential identical browser configurations share strategy. @@ -103,7 +107,7 @@ public function testGetSessionStrategySharing() */ public function testGetSessionStrategyIsolated() { - $expected = '\\aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'; + $expected = IsolatedSessionStrategy::class; $this->factory->shouldReceive('createStrategy')->andReturn(m::mock($expected)); $this->assertInstanceOf($expected, $this->_getStrategy(ISessionStrategyFactory::TYPE_ISOLATED, 'IS1')); @@ -116,7 +120,7 @@ public function testGetSessionStrategyIsolated() */ public function testGetSessionStrategyShared() { - $expected = '\\aik099\\PHPUnit\\Session\\SharedSessionStrategy'; + $expected = SharedSessionStrategy::class; $this->factory->shouldReceive('createStrategy')->andReturn(m::mock($expected)); $this->assertInstanceOf($expected, $this->_getStrategy(ISessionStrategyFactory::TYPE_SHARED, 'SH1')); @@ -132,11 +136,11 @@ public function testGetSessionStrategyShared() */ private function _getStrategy($strategy_type, $strategy_hash) { - $browser = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'); + $browser = m::mock(BrowserConfiguration::class); $browser->shouldReceive('getSessionStrategy')->once()->andReturn($strategy_type); $browser->shouldReceive('getSessionStrategyHash')->once()->andReturn($strategy_hash); - $test_case = m::mock('aik099\\PHPUnit\\BrowserTestCase'); + $test_case = m::mock(BrowserTestCase::class); return $this->manager->getSessionStrategy($browser, $test_case); } diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php b/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php index 28f9857..a3e4354 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php +++ b/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php @@ -13,15 +13,18 @@ use aik099\PHPUnit\Session\ISessionStrategy; use tests\aik099\PHPUnit\AbstractTestCase; +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use Behat\Mink\Session; +use aik099\PHPUnit\BrowserTestCase; class SessionStrategyTestCase extends AbstractTestCase { - const BROWSER_CLASS = '\\aik099\\PHPUnit\\BrowserConfiguration\\BrowserConfiguration'; + const BROWSER_CLASS = BrowserConfiguration::class; - const SESSION_CLASS = '\\Behat\\Mink\\Session'; + const SESSION_CLASS = Session::class; - const TEST_CASE_CLASS = 'aik099\\PHPUnit\\BrowserTestCase'; + const TEST_CASE_CLASS = BrowserTestCase::class; /** * Session strategy. diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index 898b1f4..aa0abe1 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -52,7 +52,7 @@ protected function setUpTest() $this->_session1 = $this->createSession(); $this->_session2 = $this->createSession(); - $this->_isolatedStrategy = m::mock('\\aik099\\PHPUnit\\Session\\IsolatedSessionStrategy'); + $this->_isolatedStrategy = m::mock(IsolatedSessionStrategy::class); $this->strategy = new SharedSessionStrategy($this->_isolatedStrategy); } diff --git a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php index b3a7648..1596729 100644 --- a/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php +++ b/tests/aik099/PHPUnit/TestCase/ApplicationAwareTestCase.php @@ -31,7 +31,7 @@ class ApplicationAwareTestCase extends AbstractTestCase */ protected function setUpTest() { - $this->application = m::mock('aik099\\PHPUnit\\Application'); + $this->application = m::mock(Application::class); } /** diff --git a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php index f9a6805..9d00b1e 100644 --- a/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/BrowserTestSuiteTest.php @@ -14,6 +14,7 @@ use aik099\PHPUnit\TestSuite\BrowserTestSuite; use Mockery as m; use tests\aik099\PHPUnit\AbstractTestCase; +use ConsoleHelpers\PHPUnitCompat\Framework\Test; class BrowserTestSuiteTest extends AbstractTestCase { @@ -72,7 +73,7 @@ public static function nameFromBrowserDataProvider() public function testSetBrowserFromConfiguration() { $browser = array('name' => 'safari'); - $test = m::mock('\\ConsoleHelpers\\PHPUnitCompat\\Framework\\Test'); + $test = m::mock(Test::class); $test->shouldReceive('setBrowserFromConfiguration')->with($browser)->once(); $this->_suite->addTest($test); diff --git a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php index e6a2b1b..badb265 100644 --- a/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php +++ b/tests/aik099/PHPUnit/TestSuite/RegularTestSuiteTest.php @@ -14,6 +14,11 @@ use aik099\PHPUnit\TestSuite\RegularTestSuite; use Mockery as m; use tests\aik099\PHPUnit\AbstractTestCase; +use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; +use aik099\PHPUnit\Session\SessionStrategyManager; +use aik099\PHPUnit\BrowserConfiguration\IBrowserConfigurationFactory; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; +use ConsoleHelpers\PHPUnitCompat\Framework\Test; class RegularTestSuiteTest extends AbstractTestCase { @@ -27,7 +32,7 @@ public function testAddTestMethods() { $suite = $this->_createSuite(); - $actual = $suite->addTestMethods('tests\\aik099\\PHPUnit\\Fixture\\WithoutBrowserConfig'); + $actual = $suite->addTestMethods(WithoutBrowserConfig::class); $this->assertSame($suite, $actual, 'The fluid interface doesn\'t work.'); $this->assertCount(2, $actual->tests(), 'Not all tests were added.'); @@ -40,11 +45,11 @@ public function testAddTestMethods() */ public function testSetTestDependencies() { - $manager = m::mock('aik099\\PHPUnit\\Session\\SessionStrategyManager'); - $factory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); - $helper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); + $manager = m::mock(SessionStrategyManager::class); + $factory = m::mock(IBrowserConfigurationFactory::class); + $helper = m::mock(RemoteCoverageHelper::class); - $test = m::mock('\\ConsoleHelpers\\PHPUnitCompat\\Framework\\Test'); + $test = m::mock(Test::class); $test->shouldReceive('setSessionStrategyManager')->with($manager)->once(); $test->shouldReceive('setBrowserConfigurationFactory')->with($factory)->once(); $test->shouldReceive('setRemoteCoverageHelper')->with($helper)->once(); diff --git a/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php b/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php index f3c2da6..ac13fc5 100644 --- a/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php +++ b/tests/aik099/PHPUnit/TestSuite/TestSuiteFactoryTest.php @@ -18,6 +18,9 @@ use aik099\PHPUnit\TestSuite\TestSuiteFactory; use Mockery as m; use tests\aik099\PHPUnit\TestCase\ApplicationAwareTestCase; +use aik099\PHPUnit\TestSuite\RegularTestSuite; +use tests\aik099\PHPUnit\Fixture\WithoutBrowserConfig; +use tests\aik099\PHPUnit\Fixture\WithBrowserConfig; class TestSuiteFactoryTest extends ApplicationAwareTestCase { @@ -57,9 +60,9 @@ protected function setUpTest() { parent::setUpTest(); - $this->_manager = m::mock('aik099\\PHPUnit\\Session\\SessionStrategyManager'); - $this->_browserFactory = m::mock('aik099\\PHPUnit\\BrowserConfiguration\\IBrowserConfigurationFactory'); - $this->_remoteCoverageHelper = m::mock('aik099\\PHPUnit\\RemoteCoverage\\RemoteCoverageHelper'); + $this->_manager = m::mock(SessionStrategyManager::class); + $this->_browserFactory = m::mock(IBrowserConfigurationFactory::class); + $this->_remoteCoverageHelper = m::mock(RemoteCoverageHelper::class); $this->_factory = new TestSuiteFactory($this->_manager, $this->_browserFactory, $this->_remoteCoverageHelper); $this->_factory->setApplication($this->application); @@ -72,8 +75,8 @@ protected function setUpTest() */ public function testCreateSuiteFromTestCaseWithoutBrowsers() { - $suite_class_name = 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'; - $test_case_class_name = 'tests\\aik099\\PHPUnit\\Fixture\\WithoutBrowserConfig'; + $suite_class_name = RegularTestSuite::class; + $test_case_class_name = WithoutBrowserConfig::class; $suite = m::mock($suite_class_name); $suite->shouldReceive('setName')->with($test_case_class_name)->once(); @@ -95,8 +98,8 @@ public function testCreateSuiteFromTestCaseWithoutBrowsers() */ public function testCreateSuiteFromTestCaseWithBrowsers() { - $suite_class_name = 'aik099\\PHPUnit\\TestSuite\\RegularTestSuite'; - $test_case_class_name = 'tests\\aik099\\PHPUnit\\Fixture\\WithBrowserConfig'; + $suite_class_name = RegularTestSuite::class; + $test_case_class_name = WithBrowserConfig::class; $browser_suite1 = $this->_createBrowserTestSuiteMock($test_case_class_name, array( 'browserName' => 'firefox', 'host' => 'localhost', @@ -126,7 +129,7 @@ public function testCreateSuiteFromTestCaseWithBrowsers() */ private function _createBrowserTestSuiteMock($class_name, array $browser) { - $suite = m::mock('aik099\\PHPUnit\\TestSuite\\BrowserTestSuite'); + $suite = m::mock(BrowserTestSuite::class); $suite->shouldReceive('nameFromBrowser')->with($browser)->once()->andReturn('OK'); $suite->shouldReceive('setName')->with($class_name . ': OK')->once(); $suite->shouldReceive('addTestMethods')->with($class_name)->once(); From fae94210a97e684b86b6b4c3f6823913254da94e Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 13 Mar 2024 22:09:14 +0200 Subject: [PATCH 174/204] Reduce code duplication during browser configuration driver creation --- .../PHPUnit/BrowserConfiguration/BrowserConfiguration.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index a7158f9..b12748a 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -411,9 +411,7 @@ protected function getParameter($name) */ public function createDriver() { - $factory = $this->_driverFactoryRegistry->get($this->getDriver()); - - return $factory->createDriver($this); + return $this->_driverFactory->createDriver($this); } /** From 3819b147d3f1662fd68fbc25dcb12b3df3aa0d83 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 14 Mar 2024 10:30:47 +0200 Subject: [PATCH 175/204] Use "::class" in the Pimple test suite --- .../PimpleServiceProviderInterfaceTest.php | 13 ++++----- tests/PimpleCopy/Pimple/PimpleTest.php | 27 ++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/tests/PimpleCopy/Pimple/PimpleServiceProviderInterfaceTest.php b/tests/PimpleCopy/Pimple/PimpleServiceProviderInterfaceTest.php index 136de61..74d7aaa 100644 --- a/tests/PimpleCopy/Pimple/PimpleServiceProviderInterfaceTest.php +++ b/tests/PimpleCopy/Pimple/PimpleServiceProviderInterfaceTest.php @@ -29,6 +29,7 @@ use PHPUnit\Framework\TestCase; use PimpleCopy\Pimple\Container; +use tests\PimpleCopy\Pimple\Fixtures\Service; /** * @author Dominik Zogg @@ -44,13 +45,13 @@ public function testProvider() $pimple_service_provider->register($pimple); $this->assertEquals('value', $pimple['param']); - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $pimple['service']); + $this->assertInstanceOf(Service::class, $pimple['service']); $service_one = $pimple['factory']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_one); + $this->assertInstanceOf(Service::class, $service_one); $service_two = $pimple['factory']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_two); + $this->assertInstanceOf(Service::class, $service_two); $this->assertNotSame($service_one, $service_two); } @@ -66,13 +67,13 @@ public function testProviderWithRegisterMethod() $this->assertEquals('value', $pimple['param']); $this->assertEquals('anotherValue', $pimple['anotherParameter']); - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $pimple['service']); + $this->assertInstanceOf(Service::class, $pimple['service']); $service_one = $pimple['factory']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_one); + $this->assertInstanceOf(Service::class, $service_one); $service_two = $pimple['factory']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_two); + $this->assertInstanceOf(Service::class, $service_two); $this->assertNotSame($service_one, $service_two); } diff --git a/tests/PimpleCopy/Pimple/PimpleTest.php b/tests/PimpleCopy/Pimple/PimpleTest.php index b856970..1abd5ff 100644 --- a/tests/PimpleCopy/Pimple/PimpleTest.php +++ b/tests/PimpleCopy/Pimple/PimpleTest.php @@ -31,6 +31,9 @@ use PHPUnit\Framework\TestCase; use PimpleCopy\Pimple\Container; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; +use tests\PimpleCopy\Pimple\Fixtures\Service; +use PimpleCopy\Pimple\ServiceProviderInterface; +use tests\PimpleCopy\Pimple\Fixtures\NonInvokable; /** * @author Igor Wiedler @@ -54,7 +57,7 @@ public function testWithClosure() return new Fixtures\Service(); }; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $pimple['service']); + $this->assertInstanceOf(Service::class, $pimple['service']); } public function testServicesShouldBeDifferent() @@ -65,10 +68,10 @@ public function testServicesShouldBeDifferent() }); $service_one = $pimple['service']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_one); + $this->assertInstanceOf(Service::class, $service_one); $service_two = $pimple['service']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_two); + $this->assertInstanceOf(Service::class, $service_two); $this->assertNotSame($service_one, $service_two); } @@ -149,10 +152,10 @@ public function testShare($service) $pimple['shared_service'] = $service; $service_one = $pimple['shared_service']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_one); + $this->assertInstanceOf(Service::class, $service_one); $service_two = $pimple['shared_service']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_two); + $this->assertInstanceOf(Service::class, $service_two); $this->assertSame($service_one, $service_two); } @@ -194,7 +197,7 @@ public function testRawHonorsNullValues() public function testFluentRegister() { $pimple = new Container(); - $serviceProviderMock = m::mock('PimpleCopy\Pimple\ServiceProviderInterface'); + $serviceProviderMock = m::mock(ServiceProviderInterface::class); $serviceProviderMock->shouldReceive('register'); $this->assertSame($pimple, $pimple->register($serviceProviderMock)); @@ -224,17 +227,17 @@ public function testExtend($service) $pimple->extend('shared_service', $service); $service_one = $pimple['shared_service']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_one); + $this->assertInstanceOf(Service::class, $service_one); $service_two = $pimple['shared_service']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_two); + $this->assertInstanceOf(Service::class, $service_two); $this->assertSame($service_one, $service_two); $this->assertSame($service_one->value, $service_two->value); $pimple->extend('factory_service', $service); $service_one = $pimple['factory_service']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_one); + $this->assertInstanceOf(Service::class, $service_one); $service_two = $pimple['factory_service']; - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $service_two); + $this->assertInstanceOf(Service::class, $service_two); $this->assertNotSame($service_one, $service_two); $this->assertNotSame($service_one->value, $service_two->value); } @@ -288,7 +291,7 @@ public function settingAnInvokableObjectShouldTreatItAsFactory() $pimple = new Container(); $pimple['invokable'] = new Fixtures\Invokable(); - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\Service', $pimple['invokable']); + $this->assertInstanceOf(Service::class, $pimple['invokable']); } /** @test */ @@ -297,7 +300,7 @@ public function settingNonInvokableObjectShouldTreatItAsParameter() $pimple = new Container(); $pimple['non_invokable'] = new Fixtures\NonInvokable(); - $this->assertInstanceOf('tests\PimpleCopy\Pimple\Fixtures\NonInvokable', $pimple['non_invokable']); + $this->assertInstanceOf(NonInvokable::class, $pimple['non_invokable']); } /** From d84f6cdfb2034dfab6fd0dccc4f8a30bfbee30c4 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 14 Mar 2024 10:46:07 +0200 Subject: [PATCH 176/204] Don't enable remote code coverage without a collection URL --- library/aik099/PHPUnit/BrowserTestCase.php | 4 ++ tests/aik099/PHPUnit/BrowserTestCaseTest.php | 37 ++++++++++++------- .../PHPUnit/Fixture/ApiIntegrationFixture.php | 9 ----- .../Integration/BrowserStackAwareTestCase.php | 12 ------ 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 133e6fa..5a9c1ce 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -303,6 +303,10 @@ protected function tearDownTest() */ public function getCollectCodeCoverageInformation() { + if ( !$this->_remoteCoverageScriptUrl ) { + return false; + } + $result = $this->getTestResultObject(); if ( !is_object($result) ) { diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index d648731..101917f 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -274,11 +274,11 @@ protected function getBrowser($times) } /** - * Test description. + * @param string $remote_coverage_script_url Remote coverage script URL. * - * @return void + * @dataProvider getCollectCodeCoverageInformationSuccessDataProvider */ - public function testGetCollectCodeCoverageInformationSuccess() + public function testGetCollectCodeCoverageInformationSuccess($remote_coverage_script_url) { $test_case = $this->getFixture(); @@ -298,7 +298,22 @@ public function testGetCollectCodeCoverageInformationSuccess() $test_result->setCodeCoverage($code_coverage); $test_case->setTestResultObject($test_result); - $this->assertTrue($test_case->getCollectCodeCoverageInformation()); + // Failed. + if ( $remote_coverage_script_url ) { + $test_case->setRemoteCoverageScriptUrl($remote_coverage_script_url); + $this->assertTrue($test_case->getCollectCodeCoverageInformation()); + } + else { + $this->assertFalse($test_case->getCollectCodeCoverageInformation()); + } + } + + public function getCollectCodeCoverageInformationSuccessDataProvider() + { + return array( + 'with remote coverage url' => array('http://localhost/'), + 'without remote coverage url' => array(''), + ); } /** @@ -360,18 +375,12 @@ public function testRunWithCoverageWithoutRemoteUrl() )); $result->setCodeCoverage($code_coverage); - $test_id = $test_case->getTestId(); - $this->assertEmpty($test_id); + $this->assertEmpty($test_case->getTestId()); $browser = $test_case->getBrowser(); - $browser->shouldReceive('getBaseUrl')->once()->andReturn('A'); + $browser->shouldReceive('getBaseUrl')->never(); - $session = m::mock(Session::class); - $session->shouldReceive('visit')->with('A')->once(); - $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, null)->once(); - $session->shouldReceive('setCookie')->with(RemoteCoverageTool::TEST_ID_VARIABLE, m::not(''))->once(); - - $session_strategy->shouldReceive('session')->once()->andReturn($session); + $session_strategy->shouldReceive('session')->never(); $test_case->run($result); @@ -401,7 +410,7 @@ public function testRunWithCoverageWithoutRemoteUrl() $this->assertEquals($expected_coverage, $actual_coverage); } - $this->assertNotEmpty($test_case->getTestId()); + $this->assertEmpty($test_case->getTestId()); } /** diff --git a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php index c83c3b6..227a5d0 100644 --- a/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php +++ b/tests/aik099/PHPUnit/Fixture/ApiIntegrationFixture.php @@ -152,15 +152,6 @@ public function verifyRemoteAPICalls() } } - /** - * @inheritDoc - */ - public function getCollectCodeCoverageInformation() - { - // FIXME: Workaround for https://github.com/minkphp/phpunit-mink/issues/35 bug. - return false; - } - /** * Test description. * diff --git a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php index c0d6c1b..2cb17a8 100644 --- a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php +++ b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php @@ -37,18 +37,6 @@ protected function setUpTest() } } - /** - * Whatever or not code coverage information should be gathered. - * - * @return boolean - * @throws \RuntimeException When used before test is started. - */ - public function getCollectCodeCoverageInformation() - { - // FIXME: Workaround for https://github.com/minkphp/phpunit-mink/issues/35 bug. - return false; - } - /** * Gets browser configuration aliases. * From e3af8bf0b88f1d8c92f7179f353da10dddf2259e Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 14 Mar 2024 11:35:02 +0200 Subject: [PATCH 177/204] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 530b170..4726982 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Reduce memory consumption by rewriting `SessionStrategyFactory` and `SessionStrategyManager` classes. ### Fixed -... +- Don't set remote code coverage collection cookies, when the remote code coverage script URL isn't specified. ## [2.3.0] - 2022-11-24 ### Changed From 85e986b58d1dfed4c768d815709f399e69167e23 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 14 Mar 2024 21:39:42 +0200 Subject: [PATCH 178/204] Reduce "BrowserTestCase" class method visibility, that were made public only for testing purposes --- CHANGELOG.md | 2 + library/aik099/PHPUnit/BrowserTestCase.php | 58 +++++++++--------- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 60 ++++++++++++------- .../PHPUnit/Integration/SuiteBuildingTest.php | 5 +- 4 files changed, 76 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4726982..3ca158a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Allow using self-signed/invalid SSL certificates during testing on the SauceLabs by default. - Rewritten library object communication mechanism (the event dispatcher is no longer used). Update any custom session strategy/browser configuration implementations. - Reduce memory consumption by rewriting `SessionStrategyFactory` and `SessionStrategyManager` classes. +- (Not a BC break) Some public methods of the `BrowserTestCase` class are protected now. Affected methods: `setRemoteCoverageScriptUrl`, `setBrowser`, `getBrowser`, `setSessionStrategy`, `getSessionStrategy`, `getCollectCodeCoverageInformation`, `getRemoteCodeCoverageInformation`. +- (Not a BC break) Some protected properties of the `BrowserTestCase` class are private now. Affected properties: `sessionStrategyManager`, `remoteCoverageHelper`, `sessionStrategy`. ### Fixed - Don't set remote code coverage collection cookies, when the remote code coverage script URL isn't specified. diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 5a9c1ce..2661f06 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -71,21 +71,21 @@ abstract class BrowserTestCase extends AbstractTestCase * * @var SessionStrategyManager */ - protected $sessionStrategyManager; + private $_sessionStrategyManager; /** * Remote coverage helper. * * @var RemoteCoverageHelper */ - protected $remoteCoverageHelper; + private $_remoteCoverageHelper; /** * Session strategy, used currently. * * @var ISessionStrategy */ - protected $sessionStrategy; + private $_sessionStrategy; /** * Test ID. @@ -115,7 +115,7 @@ public function setBrowserConfigurationFactory(IBrowserConfigurationFactory $bro */ public function setSessionStrategyManager(SessionStrategyManager $session_strategy_manager) { - $this->sessionStrategyManager = $session_strategy_manager; + $this->_sessionStrategyManager = $session_strategy_manager; return $this; } @@ -129,7 +129,7 @@ public function setSessionStrategyManager(SessionStrategyManager $session_strate */ public function setRemoteCoverageHelper(RemoteCoverageHelper $remote_coverage_helper) { - $this->remoteCoverageHelper = $remote_coverage_helper; + $this->_remoteCoverageHelper = $remote_coverage_helper; } /** @@ -139,7 +139,7 @@ public function setRemoteCoverageHelper(RemoteCoverageHelper $remote_coverage_he * * @return void */ - public function setRemoteCoverageScriptUrl($url) + protected function setRemoteCoverageScriptUrl($url) { $this->_remoteCoverageScriptUrl = $url; } @@ -164,14 +164,16 @@ protected function setUpTest() * * @return self */ - public function setBrowser(BrowserConfiguration $browser) + protected function setBrowser(BrowserConfiguration $browser) { $this->_browser = $browser; // Configure session strategy. - return $this->setSessionStrategy( - $this->sessionStrategyManager->getSessionStrategy($browser, $this) + $this->setSessionStrategy( + $this->_sessionStrategyManager->getSessionStrategy($browser, $this) ); + + return $this; } /** @@ -180,7 +182,7 @@ public function setBrowser(BrowserConfiguration $browser) * @return BrowserConfiguration * @throws \RuntimeException When browser configuration isn't defined. */ - public function getBrowser() + protected function getBrowser() { if ( !is_object($this->_browser) ) { throw new \RuntimeException('Browser configuration not defined'); @@ -198,7 +200,9 @@ public function getBrowser() */ public function setBrowserFromConfiguration(array $browser_config) { - return $this->setBrowser($this->createBrowserConfiguration($browser_config)); + return $this->setBrowser( + $this->createBrowserConfiguration($browser_config) + ); } /** @@ -220,9 +224,9 @@ protected function createBrowserConfiguration(array $browser_config) * * @return self */ - public function setSessionStrategy(ISessionStrategy $session_strategy = null) + protected function setSessionStrategy(ISessionStrategy $session_strategy = null) { - $this->sessionStrategy = $session_strategy; + $this->_sessionStrategy = $session_strategy; return $this; } @@ -233,14 +237,14 @@ public function setSessionStrategy(ISessionStrategy $session_strategy = null) * @return ISessionStrategy * @see setSessionStrategy() */ - public function getSessionStrategy() + protected function getSessionStrategy() { - if ( $this->sessionStrategy ) { - return $this->sessionStrategy; + if ( $this->_sessionStrategy !== null ) { + return $this->_sessionStrategy; } // Default session strategy (not session itself) shared across all test cases. - return $this->sessionStrategyManager->getDefaultSessionStrategy(); + return $this->_sessionStrategyManager->getDefaultSessionStrategy(); } /** @@ -290,8 +294,8 @@ protected function tearDownTest() $this->_browser->onTestEnded($this, $result); } - if ( $this->sessionStrategy !== null ) { - $this->sessionStrategy->onTestEnded($this); + if ( $this->_sessionStrategy !== null ) { + $this->_sessionStrategy->onTestEnded($this); } } @@ -301,7 +305,7 @@ protected function tearDownTest() * @return boolean * @throws \RuntimeException When used before test is started. */ - public function getCollectCodeCoverageInformation() + protected function getCollectCodeCoverageInformation() { if ( !$this->_remoteCoverageScriptUrl ) { return false; @@ -341,8 +345,8 @@ protected function runTest() */ public function onTestSuiteEnded() { - if ( $this->sessionStrategy !== null ) { - $this->sessionStrategy->onTestSuiteEnded($this); + if ( $this->_sessionStrategy !== null ) { + $this->_sessionStrategy->onTestSuiteEnded($this); } return $this; @@ -353,13 +357,13 @@ public function onTestSuiteEnded() * * @return array|RawCodeCoverageData */ - public function getRemoteCodeCoverageInformation() + protected function getRemoteCodeCoverageInformation() { if ( $this->_remoteCoverageScriptUrl ) { - return $this->remoteCoverageHelper->get($this->_remoteCoverageScriptUrl, $this->_testId); + return $this->_remoteCoverageHelper->get($this->_remoteCoverageScriptUrl, $this->_testId); } - return $this->remoteCoverageHelper->getEmpty(); + return $this->_remoteCoverageHelper->getEmpty(); } /** @@ -381,8 +385,8 @@ public static function suite($class_name) */ protected function onNotSuccessfulTestCompat($e) { - if ( $this->sessionStrategy !== null ) { - $this->sessionStrategy->onTestFailed($this, $e); + if ( $this->_sessionStrategy !== null ) { + $this->_sessionStrategy->onTestFailed($this, $e); } } diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index 101917f..ffe0b69 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -33,11 +33,13 @@ use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; use Behat\Mink\Session; use ConsoleHelpers\CodeCoverageCompat\Driver\Driver; +use Behat\Mink\Exception\DriverException; -class BrowserTestCaseTest extends AbstractTestCase +class BrowserTestCaseTest extends BrowserTestCase { use ExpectException; + use TVerifyTestExpectations; const BROWSER_CLASS = BrowserConfiguration::class; @@ -76,9 +78,14 @@ public function testSetSessionStrategyManager() $manager = m::mock(self::MANAGER_CLASS); $test_case = new WithoutBrowserConfig('test name'); - $test_case->setSessionStrategyManager($manager); - $property = new \ReflectionProperty($test_case, 'sessionStrategyManager'); + $this->assertSame( + $test_case, + $test_case->setSessionStrategyManager($manager), + 'The fluid interface doesn\'t work.' + ); + + $property = new \ReflectionProperty(BrowserTestCase::class, '_sessionStrategyManager'); $property->setAccessible(true); $this->assertSame($manager, $property->getValue($test_case)); @@ -94,7 +101,7 @@ public function testSetBrowserCorrect() /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - $test_case = $this->getFixture($session_strategy); + $test_case = $this->getFixture(true, $session_strategy); $browser = new BrowserConfiguration($this->createDriverFactoryRegistry()); @@ -118,6 +125,7 @@ protected function createDriverFactoryRegistry() $registry ->shouldReceive('get') ->with('selenium2') + ->once() ->andReturn($driver_factory); return $registry; @@ -143,9 +151,10 @@ public function testGetBrowserNotSpecified() */ public function testSetBrowserFromConfigurationDefault() { - $test_case = $this->getFixture(); + $test_case = $this->getFixture(true); + $test_case->setBrowserConfigurationFactory($this->browserConfigurationFactory); - $browser = $this->getBrowser(0); + $browser = $this->getBrowserMock(0); $browser_config = array('browserName' => 'safari'); $this->browserConfigurationFactory @@ -200,9 +209,9 @@ public function testGetSessionStrategySharing() * * @return void */ - public function testGetSession() + public function testGetSessionWithAutoCreate() { - $browser = $this->getBrowser(0); + $browser = $this->getBrowserMock(0); $expected_session1 = m::mock(Session::class); $expected_session2 = m::mock(Session::class); @@ -211,7 +220,7 @@ public function testGetSession() $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); $session_strategy->shouldReceive('session')->with($browser)->andReturn($expected_session1, $expected_session2); - $test_case = $this->getFixture($session_strategy); + $test_case = $this->getFixture(true, $session_strategy); $test_case->setBrowser($browser); $test_case->setTestResultObject(new TestResult()); @@ -224,6 +233,13 @@ public function testGetSession() $this->assertSame($session1, $session2); } + public function testGetSessionWithoutAutoCreate() + { + $test_case = $this->getFixture(false); + + $this->assertNull($test_case->getSession(false), 'The session was created upon request.'); + } + /** * Test description. * @@ -231,13 +247,13 @@ public function testGetSession() */ public function testGetSessionDriverError() { - $browser = $this->getBrowser(1); + $browser = $this->getBrowserMock(1); /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - $session_strategy->shouldReceive('session')->andThrow('\Behat\Mink\Exception\DriverException'); + $session_strategy->shouldReceive('session')->andThrow(DriverException::class); - $test_case = $this->getFixture($session_strategy); + $test_case = $this->getFixture(true, $session_strategy); $test_case->setBrowser($browser); // On PHPUnit 5.x usage of expectException/expectExceptionMessage results in this test being marked as skipped. @@ -264,7 +280,7 @@ public function testGetSessionDriverError() * * @return BrowserConfiguration */ - protected function getBrowser($times) + protected function getBrowserMock($times) { $browser = m::mock(self::BROWSER_CLASS); $browser->shouldReceive('getHost')->times($times)->andReturn('{hostname}'); @@ -280,7 +296,7 @@ protected function getBrowser($times) */ public function testGetCollectCodeCoverageInformationSuccess($remote_coverage_script_url) { - $test_case = $this->getFixture(); + $test_case = $this->getFixture(false); $test_result = new TestResult(); @@ -613,7 +629,7 @@ public function testOnTestFailed() /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - $test_case = $this->getFixture($session_strategy); + $test_case = $this->getFixture(false, $session_strategy); $test_case->setSessionStrategy($session_strategy); $exception = new \Exception('MSG_TEST'); @@ -632,7 +648,7 @@ public function testOnTestFailed() */ public function testGetBrowserAliases() { - $test_case = $this->getFixture(); + $test_case = $this->getFixture(false); $this->assertEmpty($test_case->getBrowserAliases(), 'Browser configuration aliases are empty by default'); } @@ -647,12 +663,12 @@ protected function prepareForRun() /** @var ISessionStrategy $session_strategy */ $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); - $test_case = $this->getFixture($session_strategy); + $test_case = $this->getFixture(true, $session_strategy); $test_case->setName('testSuccess'); $session_strategy->shouldReceive('onTestEnded')->with($test_case)->once(); - $browser = $this->getBrowser(0); + $browser = $this->getBrowserMock(0); $browser->shouldReceive('onTestSetup')->with($test_case)->once(); $browser->shouldReceive('onTestEnded')->with($test_case, m::type(TestResult::class))->once(); @@ -664,11 +680,12 @@ protected function prepareForRun() /** * Returns test case fixture. * + * @param boolean $return_strategy Session strategy manager would be asked for a strategy. * @param ISessionStrategy|null $session_strategy Session strategy. * * @return WithoutBrowserConfig */ - protected function getFixture(ISessionStrategy $session_strategy = null) + protected function getFixture($return_strategy, ISessionStrategy $session_strategy = null) { if ( !isset($session_strategy) ) { $session_strategy = m::mock(self::SESSION_STRATEGY_INTERFACE); @@ -676,10 +693,11 @@ protected function getFixture(ISessionStrategy $session_strategy = null) /** @var SessionStrategyManager $manager */ $manager = m::mock(self::MANAGER_CLASS); - $manager->shouldReceive('getSessionStrategy')->andReturn($session_strategy); + $manager->shouldReceive('getSessionStrategy') + ->times($return_strategy ? 1 : 0) + ->andReturn($session_strategy); $test_case = new WithoutBrowserConfig('test name'); - $test_case->setBrowserConfigurationFactory($this->browserConfigurationFactory); $test_case->setSessionStrategyManager($manager); return $test_case; diff --git a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php index c176c7c..29b3792 100644 --- a/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php +++ b/tests/aik099/PHPUnit/Integration/SuiteBuildingTest.php @@ -49,12 +49,15 @@ public function testWithBrowserConfiguration() $this->checkArray($test_suites, 2, self::BROWSER_SUITE_CLASS); + $property = new \ReflectionProperty(BrowserTestCase::class, '_sessionStrategy'); + $property->setAccessible(true); + foreach ( $test_suites as $test_suite ) { /** @var BrowserTestCase[] $suite_tests */ $suite_tests = $test_suite->tests(); $this->checkArray($suite_tests, 2, self::TEST_CASE_WITH_CONFIG); - $this->assertInstanceOf(ISessionStrategy::class, $suite_tests[0]->getSessionStrategy()); + $this->assertInstanceOf(ISessionStrategy::class, $property->getValue($suite_tests[0])); } } From 5ce036eb73aa0e76d101885637142d14caaa85fe Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 14 Mar 2024 22:39:51 +0200 Subject: [PATCH 179/204] The live documentation build server is now listening on all network interfaces (not only the localhost) --- docs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Makefile b/docs/Makefile index f669162..732a350 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -55,7 +55,7 @@ html: @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." livehtml: - sphinx-autobuild -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + sphinx-autobuild --host 0.0.0.0 -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml From 3c6040aee7db0c258c9cea356f53d6c0cb1e9968 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 14 Mar 2024 23:17:48 +0200 Subject: [PATCH 180/204] Correcting errors in the documentation --- docs/browser-aliases.rst | 12 ++--- docs/configuration.rst | 52 +++++++++---------- .../configuration/config_via_setup_method.php | 12 ++--- .../cloud_selenium_configs.php | 6 ++- docs/getting-started.rst | 38 +++++++------- docs/index.rst | 2 +- docs/remote-code-coverage.rst | 18 ++++--- 7 files changed, 72 insertions(+), 68 deletions(-) diff --git a/docs/browser-aliases.rst b/docs/browser-aliases.rst index 33997b7..5b4261e 100644 --- a/docs/browser-aliases.rst +++ b/docs/browser-aliases.rst @@ -2,19 +2,19 @@ Browser Aliases =============== All previous examples demonstrate various ways how browser configuration can be defined, but they all have same downside - server connection details stay hard-coded in test case classes. This could become very -problematic if: +problematic when: -* same test cases needs to be executed on different servers (e.g. each developer runs them on his own machine) -* due change in server connection details each test case class needs to be changed +* the same test cases needs to be executed on the different servers (e.g. each developer runs them on his own machine) +* due change in the server connection details each test case class needs to be changed -To solve this problem a browser aliases were introduced. Basically a browser alias is predefined browser +To solve this problem a browser aliases were introduced. Basically a browser alias is a predefined browser configuration, that is available in the test case by it's alias. Here is how it can be used: #. create base test case class, by extending ``BrowserTestCase`` class in the project with ``getBrowserAliases`` method in it -#. the ``getBrowserAliases`` method will return an associative array of a browser configurations (array key acts as alias name) +#. the ``getBrowserAliases`` method will return an associative array of a browser configurations (array key acts as an alias name) #. in any place, where browser configuration is defined use ``'alias' => 'alias_name_here'`` instead of actual browser configuration -#. feel free to override any part of configuration defined in alias +#. feel free to override any part of the configuration defined in the alias .. note:: Nested aliases are also supported. diff --git a/docs/configuration.rst b/docs/configuration.rst index 65175d4..5811dc7 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1,13 +1,13 @@ Configuring Browser =================== -The browser needs to be configured in a test case before being able to access `Mink`_ session. -All possible ways of browser configuration are described below. +The browser needs to be configured in a test case before being able to access the `Mink`_ session. +All possible ways of the browser configuration are described below. Per Test Configuration ^^^^^^^^^^^^^^^^^^^^^^ It is possible to configure browser individually for each test within a test case by creating -an instance of ``\aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration`` class in ``setUpTest`` -method in of test case class and setting it via ``setBrowser`` method. +an instance of the ``\aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration`` class in the +``setUpTest`` method of test case class and setting it through the ``setBrowser`` method. .. literalinclude:: examples/configuration/config_via_setup_method.php :linenos: @@ -16,22 +16,22 @@ method in of test case class and setting it via ``setBrowser`` method. Per Test Case Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^ In case, when all tests in a test case share same browser configuration it's easier to specify it via -static ``$browsers`` property (array, where each item represents a single browser -configuration) in that test case class. +the static ``$browsers`` property (array, where each element represents a single browser configuration) +in that test case class. .. literalinclude:: examples/configuration/config_via_browsers_property.php :linenos: :emphasize-lines: 8,9,16 -.. note:: When several browser configurations are specified in ``$browsers`` array, then each test - in a test case will be executed against each of browser configurations. +.. note:: When several browser configurations are specified in the ``$browsers`` array, then each test + in a test case will be executed against each of the browser configurations. Browser Session Sharing ^^^^^^^^^^^^^^^^^^^^^^^ -As a benefit of shared (per test case) browser configuration, that was described above is an ability -to not only share browser configuration, that is used to create `Mink`_ session, but to actually share -created sessions between all tests in a single test case. This can be done by adding ``sessionStrategy`` -option (line 14) to the browser configuration. +As a benefit of the shared (per test case) browser configuration, that was described above is an ability +to not only to share the browser configuration, that is used to create `Mink`_ session, but to actually share +created sessions between all tests in a single test case. This can be done by adding the ``sessionStrategy`` +option (line 15) to the browser configuration. .. literalinclude:: examples/configuration/per_test_case_browser_config.php :linenos: @@ -39,7 +39,7 @@ option (line 14) to the browser configuration. Selecting the Mink Driver ^^^^^^^^^^^^^^^^^^^^^^^^^ -With the help of ``driver`` and ``driverOptions`` browser configuration settings (since v2.1.0) it's possible to +With the help of the ``driver`` and the ``driverOptions`` browser configuration settings (since v2.1.0) it's possible to specify which `Mink`_ driver to use. This file demonstrates how to use each driver: .. literalinclude:: examples/configuration/driver_showcase.php @@ -53,22 +53,22 @@ Each browser configuration consists of the following settings (all optional): ======================= ================================================================================================== Name Description ======================= ================================================================================================== -``driver`` Mink driver name (defaults to ``selenium2``, since v2.1.0) +``driver`` Mink driver name (defaults to the ``selenium2``, since v2.1.0) ``driverOptions`` Mink driver specific options (since v2.1.0) -``host`` host, where driver's server is located (defaults to ``localhost``) -``port`` port, on which driver's server is listening for incoming connections (determined by driver) +``host`` host, where driver's server is located (defaults to the ``localhost``) +``port`` port, on which driver's server is listening for the incoming connections (determined by the driver) ``timeout`` connection timeout of the server in seconds ('selenium2' driver only, defaults to ``60``) -``browserName`` name of browser to use (e.g. ``firefox``, ``chrome``, etc., defaults to ``firefox``) -``desiredCapabilities`` parameters, that allow to fine-tune browser and other 'selenium2' driver options (e.g. 'tags', - 'project', 'os', 'version') -``baseUrl`` base url of website, that is tested +``browserName`` name of the browser to use (e.g. ``firefox``, ``chrome``, etc., defaults to the ``firefox``) +``desiredCapabilities`` parameters, that allow to fine-tune browser and other ``selenium2`` driver options (e.g. ``tags``, + ``project``, ``os``, ``version``) +``baseUrl`` base url of the website, that is tested ``sessionStrategy`` used session strategy (defaults to ``isolated``) -``type`` type of configuration (defaults to ``default``, but can also be ``saucelabs`` or ``browserstack``) -``apiUsername`` API username of used service (applicable to 'saucelabs' and 'browserstack' browser configurations) -``apiKey`` API key of used service (applicable to 'saucelabs' and 'browserstack' browser configurations) +``type`` type of the configuration (defaults to ``default``, but also can be ``saucelabs`` or ``browserstack``) +``apiUsername`` API username of the used service (applicable to the ``saucelabs`` and ``browserstack`` browser configurations) +``apiKey`` API key of the used service (applicable to ``saucelabs`` and ``browserstack`` browser configurations) ======================= ================================================================================================== -There are also corresponding setters (e.g. ``setHost``) and getters (e.g. ``getHost``) for each of mentioned -above settings, that allow to individually change them from ``setUpTest`` method before test has started. +There are also corresponding setters (e.g. ``setHost``) and getters (e.g. ``getHost``) for each of the mentioned +above settings, that allow to individually change them from the ``setUpTest`` method before test has started. -.. _`Mink`: https://github.com/Behat/Mink +.. _`Mink`: https://github.com/minkphp/Mink diff --git a/docs/examples/configuration/config_via_setup_method.php b/docs/examples/configuration/config_via_setup_method.php index 17aea90..07ef629 100644 --- a/docs/examples/configuration/config_via_setup_method.php +++ b/docs/examples/configuration/config_via_setup_method.php @@ -10,12 +10,12 @@ class PerTestBrowserConfigTest extends BrowserTestCase */ protected function setUpTest() { - // To create regular browser configuration via BrowserConfigurationFactory. + // Creates the regular browser configuration using "BrowserConfigurationFactory". $browser = $this->createBrowserConfiguration(array( // options goes here (optional) )); - // To create "Sauce Labs" browser configuration via BrowserConfigurationFactory. + // Creates the "Sauce Labs" browser configuration using "BrowserConfigurationFactory". $browser = $this->createBrowserConfiguration(array( // required 'type' => 'saucelabs', @@ -24,12 +24,12 @@ protected function setUpTest() // optional options goes here )); - // To create "BrowserStack" browser configuration via BrowserConfigurationFactory. + // Creates the "BrowserStack" browser configuration using "BrowserConfigurationFactory". $browser = $this->createBrowserConfiguration(array( // required 'type' => 'browserstack', - 'api_username' => 'bs_username', - 'api_key' => 'bs_api_key', + 'apiUsername' => 'bs_username', + 'apiKey' => 'bs_api_key', // optional options goes here )); @@ -40,7 +40,7 @@ protected function setUpTest() )); $browser->setBaseUrl('http://www.test-host.com'); - // Set browser configuration to test case. + // Set browser configuration to the test case. $this->setBrowser($browser); parent::setUpTest(); diff --git a/docs/examples/getting-started/cloud_selenium_configs.php b/docs/examples/getting-started/cloud_selenium_configs.php index 7d74afa..df74b36 100644 --- a/docs/examples/getting-started/cloud_selenium_configs.php +++ b/docs/examples/getting-started/cloud_selenium_configs.php @@ -14,14 +14,16 @@ class BrowserConfigExampleTest extends BrowserTestCase 'browserName' => 'firefox', 'baseUrl' => 'http://www.google.com', ), + // BrowserStack browser configuration. array( 'type' => 'browserstack', - 'api_username' => '...', - 'api_key' => '...', + 'apiUsername' => '...', + 'apiKey' => '...', 'browserName' => 'firefox', 'baseUrl' => 'http://www.google.com', ), + // Regular browser configuration. array( 'driver' => 'selenium2', diff --git a/docs/getting-started.rst b/docs/getting-started.rst index 1770efe..1a222e4 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -1,10 +1,10 @@ Getting Started =============== -Below you'll find all needed information to find your way across the library. +Below you'll find all the needed information to find your way across the library. Installation ^^^^^^^^^^^^ -Library can be installed using Composer like so: +The library can be installed using Composer like so: 1. define the dependencies in your ``composer.json``: @@ -25,45 +25,45 @@ Library can be installed using Composer like so: Basic Usage ^^^^^^^^^^^ -#. sub-class test case class from ``\aik099\PHPUnit\BrowserTestCase`` class (line 5) -#. define used browser configurations in static ``$browsers`` property of that class (line 8-21) -#. access `Mink`_ session by calling ``$this->getSession()`` method in your test (line 26) -#. access browser configuration by calling ``$this->getBrowser()`` method in your test (line 40) +#. sub-class the test case class from the ``\aik099\PHPUnit\BrowserTestCase`` class (line 5) +#. define used browser configurations in the static ``$browsers`` property of that class (line 8-16) +#. access the `Mink`_ session by calling the ``$this->getSession()`` method in your test (line 21) +#. access browser configuration by calling the ``$this->getBrowser()`` method in your test (line 35) .. literalinclude:: examples/getting-started/general_test.php :linenos: - :emphasize-lines: 5,8,21,35 + :emphasize-lines: 5,8-16,21,35 -Selenium in Cloud -^^^^^^^^^^^^^^^^^ -When using Selenium-based solution for automated testing in the cloud (e.g. `Sauce Labs`_ or `BrowserStack`_) you need to -specify following settings: +Selenium in the Cloud +^^^^^^^^^^^^^^^^^^^^^ +When using Selenium-based solution for the automated testing in the cloud (e.g. `Sauce Labs`_ or `BrowserStack`_) +you'll need to specify the following settings: * ``'type' => 'saucelabs'`` or ``'type' => 'browserstack'`` * ``'apiUsername' => '...'`` * ``'apiKey' => '...'`` -instead of ``host`` and ``port`` settings. In all other aspects everything will work the same as if all +instead of the ``host`` and ``port`` settings. In all other aspects everything will work the same as if all tests were running locally. .. literalinclude:: examples/getting-started/cloud_selenium_configs.php :linenos: - :emphasize-lines: 11-13,19-21 + :emphasize-lines: 11-13,20-22 Continuous Integration ^^^^^^^^^^^^^^^^^^^^^^ -When website under test isn't publicly accessible, then: +When the website under test isn't publicly accessible, then: -#. secure tunnel needs to be created from website under test to server, that runs the tests -#. created tunnel identifier needs to specified in the ``PHPUNIT_MINK_TUNNEL_ID`` environment variable +#. secure tunnel needs to be created from the website under test to the server, that runs the tests +#. the created tunnel identifier needs to specified in the ``PHPUNIT_MINK_TUNNEL_ID`` environment variable .. note:: Before v2.1.0 the environment variable was called ``TRAVIS_JOB_NUMBER``. How to Create a Tunnel ---------------------- -* SauceLabs: https://wiki.saucelabs.com/display/DOCS/Sauce+Connect+Proxy -* BrowserStack: http://www.browserstack.com/automate/php#setting-local-tunnel +* SauceLabs: https://docs.saucelabs.com/secure-connections/sauce-connect-5/ +* BrowserStack: https://www.browserstack.com/docs/automate/selenium/getting-started/php/local-testing -.. _`Mink`: https://github.com/Behat/Mink +.. _`Mink`: https://github.com/minkphp/Mink .. _`Sauce Labs`: https://saucelabs.com/ .. _`BrowserStack`: http://www.browserstack.com/ diff --git a/docs/index.rst b/docs/index.rst index eb76992..f864978 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -27,7 +27,7 @@ Service Integrations .. |BrowserStack| image:: /assets/images/browserstack_logo.png .. _BrowserStack: https://www.browserstack.com/ -.. _`Mink`: https://github.com/Behat/Mink +.. _`Mink`: https://github.com/minkphp/Mink .. toctree:: :maxdepth: 2 diff --git a/docs/remote-code-coverage.rst b/docs/remote-code-coverage.rst index 6d7c10e..eabfab4 100644 --- a/docs/remote-code-coverage.rst +++ b/docs/remote-code-coverage.rst @@ -1,6 +1,6 @@ Remote Code Coverage ==================== -Browser tests are executed on different machine, then one, where code coverage information is collected +Browser tests are executed on the different machine, than one, where the code coverage information is collected (and tests are executed). To solve that problem this library uses remote coverage collection. Following steps needs to be performed before using this feature: @@ -8,8 +8,8 @@ On Remote Server ^^^^^^^^^^^^^^^^ This is web-server, where website used in tests is located. -#. Install `Xdebug `_ PHP extension on web-server -#. Copy ``library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php`` into web-server's DocumentRoot directory. +#. Install the `Xdebug`_ PHP extension on the web-server +#. Copy the ``library/aik099/PHPUnit/RemoteCoverage/RemoteCoverageTool.php`` file into the web-server's DocumentRoot directory. #. Include following code before your application bootstraps: .. code-block:: php @@ -21,9 +21,9 @@ This is web-server, where website used in tests is located. On Test Machine ^^^^^^^^^^^^^^^ -This is machine, where PHPUnit tests are being executed. +This is machine, where the PHPUnit tests are being executed. -Following code needs to be placed in the ``setUpTest`` method of the test case class (that extends ``BrowserTestCase`` +Following code needs to be placed in the ``setUpTest`` method of the test case class (that extends the ``BrowserTestCase`` class) to enable remote coverage information collection: .. code-block:: php @@ -35,7 +35,9 @@ class) to enable remote coverage information collection: How This Works ^^^^^^^^^^^^^^ -#. each test sets a special cookie on website under test -#. when cookie is present, then ``RemoteCoverageTool.php`` script collects coverage information and stores it on disk -#. once test finishes, then ``http://host/?rct_mode=output`` url is accessed on remote server, which in turn returns collected coverage information +#. each test sets a special cookie on the website under test +#. when cookie is present, then the ``RemoteCoverageTool.php`` script collects coverage information and stores it on disk +#. once test finishes, then the ``http://host/?rct_mode=output`` url is accessed on remote server, which in turn returns collected coverage information #. remote coverage information is then joined with coverage information collected locally on test machine + +.. _`Xdebug`: https://xdebug.org/ From 142cc3a4f46c9cbd37e971ba9be0e4412e606d62 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 14 Mar 2024 23:29:10 +0200 Subject: [PATCH 181/204] Describe changes in the `BrowserTestCase::getSession` method in the Changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ca158a..6dbfc38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added - Specify failed PHPUnit assertion text to the BrowserStack ("reason" field)/SauceLabs("custom-data" field) test. +- Added the `$auto_create` parameter to the `BrowserTestCase::getSession` method, which allows to verify is session is already started. ### Changed - Bumped minimum PHP version to 5.6. From 40f48f6328cade9b65b2cbe9deb9d7bb9938e396 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 14 Mar 2024 23:32:39 +0200 Subject: [PATCH 182/204] Removed debug code --- tests/aik099/PHPUnit/BrowserTestCaseTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/aik099/PHPUnit/BrowserTestCaseTest.php b/tests/aik099/PHPUnit/BrowserTestCaseTest.php index ffe0b69..f43fe32 100644 --- a/tests/aik099/PHPUnit/BrowserTestCaseTest.php +++ b/tests/aik099/PHPUnit/BrowserTestCaseTest.php @@ -314,7 +314,6 @@ public function testGetCollectCodeCoverageInformationSuccess($remote_coverage_sc $test_result->setCodeCoverage($code_coverage); $test_case->setTestResultObject($test_result); - // Failed. if ( $remote_coverage_script_url ) { $test_case->setRemoteCoverageScriptUrl($remote_coverage_script_url); $this->assertTrue($test_case->getCollectCodeCoverageInformation()); From f1bb9dba1afba7364e474168d9e53705e48a7d6b Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 15 Mar 2024 10:26:12 +0200 Subject: [PATCH 183/204] Fixed remote code coverage collection error, introduced in the #126 (not released) --- library/aik099/PHPUnit/BrowserTestCase.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 2661f06..559c493 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -286,7 +286,7 @@ protected function tearDownTest() { $result = $this->getTestResultObject(); - if ( $result->getCollectCodeCoverageInformation() ) { + if ( $this->getCollectCodeCoverageInformation() ) { $result->getCodeCoverage()->append($this->getRemoteCodeCoverageInformation(), $this); } @@ -359,11 +359,7 @@ public function onTestSuiteEnded() */ protected function getRemoteCodeCoverageInformation() { - if ( $this->_remoteCoverageScriptUrl ) { - return $this->_remoteCoverageHelper->get($this->_remoteCoverageScriptUrl, $this->_testId); - } - - return $this->_remoteCoverageHelper->getEmpty(); + return $this->_remoteCoverageHelper->get($this->_remoteCoverageScriptUrl, $this->_testId); } /** From 6c10c4baf977e66f1da1c88ddc958350ee623642 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 15 Mar 2024 10:41:51 +0200 Subject: [PATCH 184/204] Corrected line number highlighting in documentation's code examples --- docs/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 5811dc7..21da167 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -11,7 +11,7 @@ an instance of the ``\aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration`` .. literalinclude:: examples/configuration/config_via_setup_method.php :linenos: - :emphasize-lines: 11,16,25,34-38,41 + :emphasize-lines: 14,19,28,37-41,44 Per Test Case Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 0837f604d4428d893720c0ad14e0fcfd4d000136 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 15 Mar 2024 18:26:46 +0200 Subject: [PATCH 185/204] Corrected method DocBlock --- library/aik099/PHPUnit/BrowserTestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/aik099/PHPUnit/BrowserTestCase.php b/library/aik099/PHPUnit/BrowserTestCase.php index 559c493..8a31340 100644 --- a/library/aik099/PHPUnit/BrowserTestCase.php +++ b/library/aik099/PHPUnit/BrowserTestCase.php @@ -145,7 +145,7 @@ protected function setRemoteCoverageScriptUrl($url) } /** - * Set session meta-info for "Sauce Labs". + * Set session meta-info for an API-based browser configurations. * * @return void * @before From 4dac104cadc3e541d9fb893f01165abb7df96654 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 15 Mar 2024 18:39:39 +0200 Subject: [PATCH 186/204] Test, that DIContainer is properly assembling factory objects --- .../PHPUnit/Integration/DIContainerTest.php | 83 ++++++++++++++++--- 1 file changed, 73 insertions(+), 10 deletions(-) diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index 82e9acd..dc0ec05 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -11,20 +11,32 @@ namespace tests\aik099\PHPUnit\Integration; +use aik099\PHPUnit\APIClient\APIClientFactory; use aik099\PHPUnit\Application; +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; +use aik099\PHPUnit\BrowserConfiguration\BrowserStackBrowserConfiguration; +use aik099\PHPUnit\BrowserConfiguration\SauceLabsBrowserConfiguration; +use aik099\PHPUnit\BrowserTestCase; use aik099\PHPUnit\DIContainer; -use tests\aik099\PHPUnit\AbstractTestCase; -use aik099\PHPUnit\TestSuite\RegularTestSuite; -use aik099\PHPUnit\TestSuite\BrowserTestSuite; -use aik099\PHPUnit\APIClient\APIClientFactory; -use aik099\PHPUnit\TestSuite\TestSuiteFactory; +use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; +use aik099\PHPUnit\MinkDriver\GoutteDriverFactory; +use aik099\PHPUnit\MinkDriver\SahiDriverFactory; +use aik099\PHPUnit\MinkDriver\Selenium2DriverFactory; +use aik099\PHPUnit\MinkDriver\ZombieDriverFactory; +use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteUrl; -use aik099\PHPUnit\Session\SessionStrategyManager; -use aik099\PHPUnit\Session\SessionStrategyFactory; +use aik099\PHPUnit\Session\ISessionStrategyFactory; +use aik099\PHPUnit\Session\IsolatedSessionStrategy; use aik099\PHPUnit\Session\SessionFactory; -use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; -use aik099\PHPUnit\BrowserConfiguration\BrowserConfigurationFactory; -use aik099\PHPUnit\MinkDriver\DriverFactoryRegistry; +use aik099\PHPUnit\Session\SessionStrategyFactory; +use aik099\PHPUnit\Session\SessionStrategyManager; +use aik099\PHPUnit\Session\SharedSessionStrategy; +use aik099\PHPUnit\TestSuite\BrowserTestSuite; +use aik099\PHPUnit\TestSuite\RegularTestSuite; +use aik099\PHPUnit\TestSuite\TestSuiteFactory; +use Mockery as m; +use tests\aik099\PHPUnit\AbstractTestCase; class DIContainerTest extends AbstractTestCase { @@ -84,4 +96,55 @@ public static function serviceDefinitionsDataProvider() ); } + public function testSessionStrategyFactory() + { + /** @var SessionStrategyFactory $session_strategy_factory */ + $session_strategy_factory = $this->_container['session_strategy_factory']; + + $this->assertInstanceOf( + IsolatedSessionStrategy::class, + $session_strategy_factory->createStrategy(ISessionStrategyFactory::TYPE_ISOLATED) + ); + + $this->assertInstanceOf( + SharedSessionStrategy::class, + $session_strategy_factory->createStrategy(ISessionStrategyFactory::TYPE_SHARED) + ); + } + + public function testDriverFactoryRegistry() + { + /** @var DriverFactoryRegistry $driver_factory_registry */ + $driver_factory_registry = $this->_container['driver_factory_registry']; + + $this->assertInstanceOf(Selenium2DriverFactory::class, $driver_factory_registry->get('selenium2')); + $this->assertInstanceOf(SahiDriverFactory::class, $driver_factory_registry->get('sahi')); + $this->assertInstanceOf(GoutteDriverFactory::class, $driver_factory_registry->get('goutte')); + $this->assertInstanceOf(ZombieDriverFactory::class, $driver_factory_registry->get('zombie')); + } + + public function testBrowserConfigurationFactory() + { + $test_case = m::mock(BrowserTestCase::class); + $test_case->shouldReceive('getBrowserAliases')->andReturn(array()); + + /** @var BrowserConfigurationFactory $browser_configuration_factory */ + $browser_configuration_factory = $this->_container['browser_configuration_factory']; + + $this->assertInstanceOf( + BrowserConfiguration::class, + $browser_configuration_factory->createBrowserConfiguration(array('type' => 'default'), $test_case) + ); + + $this->assertInstanceOf( + BrowserStackBrowserConfiguration::class, + $browser_configuration_factory->createBrowserConfiguration(array('type' => 'browserstack'), $test_case) + ); + + $this->assertInstanceOf( + SauceLabsBrowserConfiguration::class, + $browser_configuration_factory->createBrowserConfiguration(array('type' => 'saucelabs'), $test_case) + ); + } + } From 899922799c6d8c54764a1e1eda073a1c9fa92962 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 15 Mar 2024 13:21:11 +0200 Subject: [PATCH 187/204] Ability to determine session freshness state --- CHANGELOG.md | 1 + docs/configuration.rst | 4 +- .../per_test_case_browser_config.php | 38 ++++++++++ .../Session/AbstractSessionStrategy.php | 74 +++++++++++++++++++ .../PHPUnit/Session/ISessionStrategy.php | 7 ++ .../Session/IsolatedSessionStrategy.php | 33 ++------- .../PHPUnit/Session/SharedSessionStrategy.php | 36 +++------ ...hp => AbstractSessionStrategyTestCase.php} | 7 +- .../Session/IsolatedSessionStrategyTest.php | 14 +++- .../Session/SharedSessionStrategyTest.php | 36 ++++++--- 10 files changed, 185 insertions(+), 65 deletions(-) create mode 100644 library/aik099/PHPUnit/Session/AbstractSessionStrategy.php rename tests/aik099/PHPUnit/Session/{SessionStrategyTestCase.php => AbstractSessionStrategyTestCase.php} (79%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dbfc38..ffde367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - Specify failed PHPUnit assertion text to the BrowserStack ("reason" field)/SauceLabs("custom-data" field) test. - Added the `$auto_create` parameter to the `BrowserTestCase::getSession` method, which allows to verify is session is already started. +- Added the `ISessionStrategy::isFreshSession` method to indicate fact, that previous `ISessionStrategy::session` call have created a new session instead of reusing a previously created one. Can be used to perform a login once per a test case class. ### Changed - Bumped minimum PHP version to 5.6. diff --git a/docs/configuration.rst b/docs/configuration.rst index 21da167..c563f1b 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -29,13 +29,13 @@ in that test case class. Browser Session Sharing ^^^^^^^^^^^^^^^^^^^^^^^ As a benefit of the shared (per test case) browser configuration, that was described above is an ability -to not only to share the browser configuration, that is used to create `Mink`_ session, but to actually share +to not only share the browser configuration, that is used to create `Mink`_ session, but to actually share created sessions between all tests in a single test case. This can be done by adding the ``sessionStrategy`` option (line 15) to the browser configuration. .. literalinclude:: examples/configuration/per_test_case_browser_config.php :linenos: - :emphasize-lines: 15 + :emphasize-lines: 15,26,48 Selecting the Mink Driver ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/examples/configuration/per_test_case_browser_config.php b/docs/examples/configuration/per_test_case_browser_config.php index 87f7a1a..689cab5 100644 --- a/docs/examples/configuration/per_test_case_browser_config.php +++ b/docs/examples/configuration/per_test_case_browser_config.php @@ -16,4 +16,42 @@ class CommonBrowserConfigTest extends BrowserTestCase ), ); + /** + * @before + */ + public function setUpTest() + { + parent::setUpTest(); + + if ( $this->getSessionStrategy()->isFreshSession() ) { + // login once before any of the tests was started + } + } + + public function testOne() + { + // user will be already logged-in regardless + // of the test execution order/filtering + } + + public function testTwo() + { + // user will be already logged-in regardless + // of the test execution order/filtering + } + + /** + * @inheritDoc + */ + public function onTestSuiteEnded() + { + $session = $this->getSession(false); + + if ( $session !== null && $session->isStarted() ) { + // logout once after all the tests were finished + } + + return parent::onTestSuiteEnded(); + } + } diff --git a/library/aik099/PHPUnit/Session/AbstractSessionStrategy.php b/library/aik099/PHPUnit/Session/AbstractSessionStrategy.php new file mode 100644 index 0000000..09f30f6 --- /dev/null +++ b/library/aik099/PHPUnit/Session/AbstractSessionStrategy.php @@ -0,0 +1,74 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + +namespace aik099\PHPUnit\Session; + + +use aik099\PHPUnit\BrowserTestCase; +use Behat\Mink\Session; + +abstract class AbstractSessionStrategy implements ISessionStrategy +{ + + /** + * Determines if the session was just started. + * + * @var boolean|null + */ + protected $isFreshSession; + + /** + * @inheritDoc + */ + public function isFreshSession() + { + return $this->isFreshSession; + } + + /** + * @inheritDoc + */ + public function onTestEnded(BrowserTestCase $test_case) + { + + } + + /** + * @inheritDoc + */ + public function onTestFailed(BrowserTestCase $test_case, $exception) + { + + } + + /** + * @inheritDoc + */ + public function onTestSuiteEnded(BrowserTestCase $test_case) + { + + } + + /** + * Stops the session. + * + * @param Session|null $session Session. + * + * @return void + */ + protected function stopSession(Session $session = null) + { + if ( $session !== null && $session->isStarted() ) { + $session->stop(); + $this->isFreshSession = null; + } + } + +} diff --git a/library/aik099/PHPUnit/Session/ISessionStrategy.php b/library/aik099/PHPUnit/Session/ISessionStrategy.php index 41656f0..3f3b159 100644 --- a/library/aik099/PHPUnit/Session/ISessionStrategy.php +++ b/library/aik099/PHPUnit/Session/ISessionStrategy.php @@ -32,6 +32,13 @@ interface ISessionStrategy */ public function session(BrowserConfiguration $browser); + /** + * Determines if the session was just started. + * + * @return boolean|null + */ + public function isFreshSession(); + /** * Hook, called from "BrowserTestCase::tearDownTest" method. * diff --git a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php index ecae412..2cdbf18 100644 --- a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php @@ -20,7 +20,7 @@ * * @method \Mockery\Expectation shouldReceive(string $name) */ -class IsolatedSessionStrategy implements ISessionStrategy +class IsolatedSessionStrategy extends AbstractSessionStrategy { /** @@ -41,15 +41,14 @@ public function __construct(ISessionFactory $session_factory) } /** - * Returns Mink session with given browser configuration. - * - * @param BrowserConfiguration $browser Browser configuration for a session. - * - * @return Session + * @inheritDoc */ public function session(BrowserConfiguration $browser) { - return $this->_sessionFactory->createSession($browser); + $session = $this->_sessionFactory->createSession($browser); + $this->isFreshSession = true; + + return $session; } /** @@ -59,25 +58,7 @@ public function onTestEnded(BrowserTestCase $test_case) { $session = $test_case->getSession(false); - if ( $session !== null && $session->isStarted() ) { - $session->stop(); - } - } - - /** - * @inheritDoc - */ - public function onTestFailed(BrowserTestCase $test_case, $exception) - { - - } - - /** - * @inheritDoc - */ - public function onTestSuiteEnded(BrowserTestCase $test_case) - { - + $this->stopSession($session); } } diff --git a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php index 9a8b4f6..9b003dc 100644 --- a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -22,7 +22,7 @@ * * @method \Mockery\Expectation shouldReceive(string $name) */ -class SharedSessionStrategy implements ISessionStrategy +class SharedSessionStrategy extends AbstractSessionStrategy { /** @@ -57,23 +57,21 @@ public function __construct(ISessionStrategy $original_strategy) } /** - * Returns Mink session with given browser configuration. - * - * @param BrowserConfiguration $browser Browser configuration for a session. - * - * @return Session + * @inheritDoc */ public function session(BrowserConfiguration $browser) { if ( $this->_lastTestFailed ) { - $this->stopSession(); + $this->stopAndForgetSession(); $this->_lastTestFailed = false; } if ( $this->_session === null ) { $this->_session = $this->_originalStrategy->session($browser); + $this->isFreshSession = $this->_originalStrategy->isFreshSession(); } else { + $this->isFreshSession = false; $this->_switchToMainWindow(); } @@ -81,18 +79,16 @@ public function session(BrowserConfiguration $browser) } /** - * Stops session. + * Stops and forgets a session. * * @return void */ - protected function stopSession() + protected function stopAndForgetSession() { - if ( $this->_session === null ) { - return; + if ( $this->_session !== null ) { + $this->stopSession($this->_session); + $this->_session = null; } - - $this->_session->stop(); - $this->_session = null; } /** @@ -105,14 +101,6 @@ private function _switchToMainWindow() $this->_session->switchToWindow(null); } - /** - * @inheritDoc - */ - public function onTestEnded(BrowserTestCase $test_case) - { - - } - /** * @inheritDoc */ @@ -132,9 +120,7 @@ public function onTestSuiteEnded(BrowserTestCase $test_case) { $session = $test_case->getSession(false); - if ( $session !== null && $session->isStarted() ) { - $session->stop(); - } + $this->stopSession($session); } } diff --git a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php b/tests/aik099/PHPUnit/Session/AbstractSessionStrategyTestCase.php similarity index 79% rename from tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php rename to tests/aik099/PHPUnit/Session/AbstractSessionStrategyTestCase.php index a3e4354..ffbff9a 100644 --- a/tests/aik099/PHPUnit/Session/SessionStrategyTestCase.php +++ b/tests/aik099/PHPUnit/Session/AbstractSessionStrategyTestCase.php @@ -17,7 +17,7 @@ use Behat\Mink\Session; use aik099\PHPUnit\BrowserTestCase; -class SessionStrategyTestCase extends AbstractTestCase +abstract class AbstractSessionStrategyTestCase extends AbstractTestCase { const BROWSER_CLASS = BrowserConfiguration::class; @@ -33,4 +33,9 @@ class SessionStrategyTestCase extends AbstractTestCase */ protected $strategy; + public function testUnknownSessionFreshnessStateUntilItsStarted() + { + $this->assertNull($this->strategy->isFreshSession()); + } + } diff --git a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php index 3f40dfd..664c7e2 100644 --- a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php @@ -16,7 +16,7 @@ use Mockery as m; use Mockery\MockInterface; -class IsolatedSessionStrategyTest extends SessionStrategyTestCase +class IsolatedSessionStrategyTest extends AbstractSessionStrategyTestCase { /** @@ -57,6 +57,18 @@ public function testSession() $this->assertEquals($session2, $this->strategy->session($browser)); } + public function testIsFreshSessionAfterSessionIsStarted() + { + $browser = m::mock(self::BROWSER_CLASS); + $session = m::mock(self::SESSION_CLASS); + + $this->_factory->shouldReceive('createSession')->with($browser)->once()->andReturn($session); + + $this->strategy->session($browser); + + $this->assertTrue($this->strategy->isFreshSession()); + } + /** * Test description. * diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index aa0abe1..28a84d9 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -12,6 +12,7 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; +use aik099\PHPUnit\Session\ISessionStrategy; use aik099\PHPUnit\Session\IsolatedSessionStrategy; use aik099\PHPUnit\Session\SharedSessionStrategy; use Behat\Mink\Session; @@ -20,7 +21,7 @@ use Mockery as m; use Mockery\MockInterface; -class SharedSessionStrategyTest extends SessionStrategyTestCase +class SharedSessionStrategyTest extends AbstractSessionStrategyTestCase { /** @@ -28,7 +29,7 @@ class SharedSessionStrategyTest extends SessionStrategyTestCase * * @var IsolatedSessionStrategy */ - private $_isolatedStrategy; + private $_originalStrategy; /** * First created session. @@ -52,8 +53,8 @@ protected function setUpTest() $this->_session1 = $this->createSession(); $this->_session2 = $this->createSession(); - $this->_isolatedStrategy = m::mock(IsolatedSessionStrategy::class); - $this->strategy = new SharedSessionStrategy($this->_isolatedStrategy); + $this->_originalStrategy = m::mock(ISessionStrategy::class); + $this->strategy = new SharedSessionStrategy($this->_originalStrategy); } /** @@ -68,17 +69,20 @@ public function testSessionSharing(\Exception $e = null) { /** @var BrowserConfiguration $browser */ $browser = m::mock(self::BROWSER_CLASS); - $this->_isolatedStrategy->shouldReceive('session')->once()->with($browser)->andReturn($this->_session1); + $this->_originalStrategy->shouldReceive('session')->once()->with($browser)->andReturn($this->_session1); + $this->_originalStrategy->shouldReceive('isFreshSession')->once()->andReturn(true); $this->_session1->shouldReceive('switchToWindow')->once(); $this->assertSame($this->_session1, $this->strategy->session($browser)); + $this->assertTrue($this->strategy->isFreshSession(), 'First created session must be fresh'); if ( isset($e) ) { $this->_sessionFailure($e); } $this->assertSame($this->_session1, $this->strategy->session($browser)); + $this->assertFalse($this->strategy->isFreshSession(), 'Reused session must not be fresh'); } /** @@ -89,9 +93,9 @@ public function testSessionSharing(\Exception $e = null) public static function ignoreExceptionDataProvider() { return array( - array(null), - array(new IncompleteTestError()), - array(new SkippedTestError()), + 'no error' => array(null), + 'incomplete test' => array(new IncompleteTestError()), + 'skipped test' => array(new SkippedTestError()), ); } @@ -105,22 +109,31 @@ public function testSessionResetOnFailure() /** @var BrowserConfiguration $browser */ $browser = m::mock(self::BROWSER_CLASS); - $this->_isolatedStrategy + $this->_originalStrategy ->shouldReceive('session') ->with($browser) ->twice() ->andReturn($this->_session1, $this->_session2); + $this->_originalStrategy + ->shouldReceive('isFreshSession') + ->twice() + ->andReturn(true); + $this->_session1->shouldReceive('isStarted')->once()->andReturn(true); $this->_session1->shouldReceive('stop')->once(); $this->_session2->shouldReceive('switchToWindow')->once(); $session = $this->strategy->session($browser); $this->assertSame($this->_session1, $session); + $this->assertTrue($this->strategy->isFreshSession(), 'First created session must be fresh'); $this->_sessionFailure(new \Exception()); $this->assertSame($this->_session2, $this->strategy->session($browser)); + $this->assertTrue($this->strategy->isFreshSession(), 'First created session after failure must be fresh'); + $this->assertSame($this->_session2, $this->strategy->session($browser)); + $this->assertFalse($this->strategy->isFreshSession(), 'Reused session must not be fresh'); } /** @@ -132,8 +145,11 @@ public function testImmediateSessionFailure() { $this->_sessionFailure(new \Exception()); - $this->_isolatedStrategy->shouldReceive('session')->once()->andReturn($this->_session1); + $this->_originalStrategy->shouldReceive('session')->once()->andReturn($this->_session1); + $this->_originalStrategy->shouldReceive('isFreshSession')->once()->andReturn(true); + $this->assertSame($this->_session1, $this->strategy->session(m::mock(self::BROWSER_CLASS))); + $this->assertTrue($this->strategy->isFreshSession(), 'First created session after failure must be fresh'); } /** From 1c7a6e21c937e0954c89dfe968fb66691dc99908 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 16 Mar 2024 17:20:13 +0200 Subject: [PATCH 188/204] Iterate PHPUnit test suite correctly --- CHANGELOG.md | 1 + .../aik099/PHPUnit/TestSuite/AbstractTestSuite.php | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffde367..9a6b5d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Don't set remote code coverage collection cookies, when the remote code coverage script URL isn't specified. +- The `BrowserTestCase::onTestSuiteEnded` method was called for tests, excluded through the `--filter` option of the PHPUnit. ## [2.3.0] - 2022-11-24 ### Changed diff --git a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php index 411d2fc..39b3c09 100644 --- a/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php +++ b/library/aik099/PHPUnit/TestSuite/AbstractTestSuite.php @@ -134,24 +134,24 @@ public function runCompat($result = null) /** * Report back suite ending to each it's test. * - * @param array $tests Tests to process. + * @param \IteratorAggregate|null $test_suite Test suite. * * @return void */ - protected function triggerTestSuiteEnded(array $tests = null) + protected function triggerTestSuiteEnded(\IteratorAggregate $test_suite = null) { - if ( !isset($tests) ) { - $tests = $this->tests(); + if ( $test_suite === null ) { + $test_suite = $this; } - foreach ( $tests as $test ) { + foreach ( $test_suite as $test ) { if ( $test instanceof DataProviderTestSuite ) { /* * Use our test suite method to tear down * supported test suites wrapped in a data * provider test suite. */ - $this->triggerTestSuiteEnded($test->tests()); + $this->triggerTestSuiteEnded($test); } else { /* From b641d94727152624bdadcd3816c56fe9ba6570db Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 16 Mar 2024 18:12:04 +0200 Subject: [PATCH 189/204] Removed the `SessionProxy` class --- CHANGELOG.md | 1 + composer.json | 2 +- composer.lock | 26 +++++++------- .../aik099/PHPUnit/Session/SessionFactory.php | 2 +- .../aik099/PHPUnit/Session/SessionProxy.php | 35 ------------------- 5 files changed, 16 insertions(+), 50 deletions(-) delete mode 100644 library/aik099/PHPUnit/Session/SessionProxy.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a6b5d7..1a62e1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Reduce memory consumption by rewriting `SessionStrategyFactory` and `SessionStrategyManager` classes. - (Not a BC break) Some public methods of the `BrowserTestCase` class are protected now. Affected methods: `setRemoteCoverageScriptUrl`, `setBrowser`, `getBrowser`, `setSessionStrategy`, `getSessionStrategy`, `getCollectCodeCoverageInformation`, `getRemoteCodeCoverageInformation`. - (Not a BC break) Some protected properties of the `BrowserTestCase` class are private now. Affected properties: `sessionStrategyManager`, `remoteCoverageHelper`, `sessionStrategy`. +- Bumped minimal required `Behat/Mink` version to 1.8 (needed after `SessionProxy` class removal). ### Fixed - Don't set remote code coverage collection cookies, when the remote code coverage script URL isn't specified. diff --git a/composer.json b/composer.json index 4f16ef4..5d220f6 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "require": { "php": ">=5.6", - "behat/mink": "~1.6@dev", + "behat/mink": "^1.8@dev", "behat/mink-selenium2-driver": "~1.2", "phpunit/phpunit": ">=4.8.35 <5|>=5.4.3", "console-helpers/phpunit-compat": "^1.0.2" diff --git a/composer.lock b/composer.lock index 6be74ea..5bdb766 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "494c2858cc1bd23a8dc3131ef787d0c6", + "content-hash": "308a4f814b44da8fd1eea8bd79b02b69", "packages": [ { "name": "behat/mink", @@ -139,16 +139,16 @@ }, { "name": "console-helpers/phpunit-compat", - "version": "v1.0.1", + "version": "v1.0.2", "source": { "type": "git", "url": "https://github.com/console-helpers/phpunit-compat.git", - "reference": "ec8608c3863d75b0389ebb5c0a1f5703b638c451" + "reference": "6b7dcb5a4f5c334b9eb7f41acba5554382d2d5c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/console-helpers/phpunit-compat/zipball/ec8608c3863d75b0389ebb5c0a1f5703b638c451", - "reference": "ec8608c3863d75b0389ebb5c0a1f5703b638c451", + "url": "https://api.github.com/repos/console-helpers/phpunit-compat/zipball/6b7dcb5a4f5c334b9eb7f41acba5554382d2d5c1", + "reference": "6b7dcb5a4f5c334b9eb7f41acba5554382d2d5c1", "shasum": "" }, "require": { @@ -182,9 +182,9 @@ "description": "Compatibility layer for PHPUnit test cases/test suite to work on different major PHPUnit versions", "support": { "issues": "https://github.com/console-helpers/phpunit-compat/issues", - "source": "https://github.com/console-helpers/phpunit-compat/tree/v1.0.1" + "source": "https://github.com/console-helpers/phpunit-compat/tree/v1.0.2" }, - "time": "2024-03-03T21:01:14+00:00" + "time": "2024-03-12T11:33:58+00:00" }, { "name": "doctrine/instantiator", @@ -1020,16 +1020,16 @@ }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", "shasum": "" }, "require": { @@ -1063,7 +1063,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.3" }, "funding": [ { @@ -1071,7 +1071,7 @@ "type": "github" } ], - "time": "2020-11-30T08:15:22+00:00" + "time": "2024-03-01T13:45:45+00:00" }, { "name": "sebastian/comparator", diff --git a/library/aik099/PHPUnit/Session/SessionFactory.php b/library/aik099/PHPUnit/Session/SessionFactory.php index 5a6c064..80a6e1e 100644 --- a/library/aik099/PHPUnit/Session/SessionFactory.php +++ b/library/aik099/PHPUnit/Session/SessionFactory.php @@ -31,7 +31,7 @@ class SessionFactory implements ISessionFactory */ public function createSession(BrowserConfiguration $browser) { - return new SessionProxy($browser->createDriver()); + return new Session($browser->createDriver()); } } diff --git a/library/aik099/PHPUnit/Session/SessionProxy.php b/library/aik099/PHPUnit/Session/SessionProxy.php deleted file mode 100644 index e6c0e57..0000000 --- a/library/aik099/PHPUnit/Session/SessionProxy.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit\Session; - - -use Behat\Mink\Session; - -class SessionProxy extends Session -{ - - /** - * Visit specified URL. - * - * @param string $url Url of the page. - * - * @return void - */ - public function visit($url) - { - if ( !$this->isStarted() ) { - $this->start(); - } - - parent::visit($url); - } - -} From 9449daf4da495ebdcc0c84abe956d5637c339b8c Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 16 Mar 2024 18:20:25 +0200 Subject: [PATCH 190/204] Rephrase change log message --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a62e1a..a1b746e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Bumped minimal required `Behat/Mink` version to 1.8 (needed after `SessionProxy` class removal). ### Fixed -- Don't set remote code coverage collection cookies, when the remote code coverage script URL isn't specified. +- The remote code coverage collection cookies were set even, when the remote code coverage script URL wasn't specified. - The `BrowserTestCase::onTestSuiteEnded` method was called for tests, excluded through the `--filter` option of the PHPUnit. ## [2.3.0] - 2022-11-24 From c621fe261575b89d12ecffe6f4c368701f8bb0fd Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 16 Mar 2024 18:25:31 +0200 Subject: [PATCH 191/204] Update documentation links Closes #82 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index db47222..74ea2bd 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # PHPUnit-Mink [![CI](https://github.com/minkphp/phpunit-mink/actions/workflows/tests.yml/badge.svg)](https://github.com/minkphp/phpunit-mink/actions/workflows/tests.yml) [![Docs](https://github.com/minkphp/phpunit-mink/actions/workflows/docs.yml/badge.svg)](https://github.com/minkphp/phpunit-mink/actions/workflows/docs.yml) -[![Documentation](https://readthedocs.org/projects/phpunit-mink/badge/?version=latest)](http://phpunit-mink.readthedocs.org/en/latest/) +[![Documentation Status](https://readthedocs.org/projects/phpunit-mink/badge/?version=latest)](https://phpunit-mink.readthedocs.io/en/latest/?badge=latest) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/minkphp/phpunit-mink/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/minkphp/phpunit-mink/?branch=master) [![codecov](https://codecov.io/gh/minkphp/phpunit-mink/branch/master/graph/badge.svg?token=GV4K2at1WW)](https://codecov.io/gh/minkphp/phpunit-mink) @@ -13,7 +13,7 @@ This library is an extension for [PHPUnit](https://phpunit.de), that allows to w ## Documentation -* http://phpunit-mink.readthedocs.org +* https://phpunit-mink.readthedocs.io/ ## Service Integrations From 2588d78e13f64f0994975aa08badc42dbae1387c Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 16 Mar 2024 19:40:50 +0200 Subject: [PATCH 192/204] Integrated `SessionFactory` class into the `IsolatedSessionStrategy` class --- library/.phpstorm.meta.php | 1 - library/aik099/PHPUnit/DIContainer.php | 9 +-- .../PHPUnit/Session/ISessionFactory.php | 34 ----------- .../Session/IsolatedSessionStrategy.php | 19 +----- .../aik099/PHPUnit/Session/SessionFactory.php | 37 ------------ .../PHPUnit/Integration/DIContainerTest.php | 2 - .../Session/IsolatedSessionStrategyTest.php | 43 +++++++------- .../PHPUnit/Session/SessionFactoryTest.php | 58 ------------------- 8 files changed, 23 insertions(+), 180 deletions(-) delete mode 100644 library/aik099/PHPUnit/Session/ISessionFactory.php delete mode 100644 library/aik099/PHPUnit/Session/SessionFactory.php delete mode 100644 tests/aik099/PHPUnit/Session/SessionFactoryTest.php diff --git a/library/.phpstorm.meta.php b/library/.phpstorm.meta.php index dcf009c..9ac0f13 100644 --- a/library/.phpstorm.meta.php +++ b/library/.phpstorm.meta.php @@ -2,7 +2,6 @@ namespace PHPSTORM_META { override(\aik099\PHPUnit\Application::getObject(), map([ - 'session_factory' => \aik099\PHPUnit\Session\SessionFactory::class, 'session_strategy_factory' => \aik099\PHPUnit\Session\SessionStrategyFactory::class, 'session_strategy_manager' => \aik099\PHPUnit\Session\SessionStrategyManager::class, 'remote_url' => \aik099\PHPUnit\RemoteCoverage\RemoteUrl::class, diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index c6e7fbe..5352de6 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -25,7 +25,6 @@ use aik099\PHPUnit\RemoteCoverage\RemoteUrl; use aik099\PHPUnit\Session\ISessionStrategyFactory; use aik099\PHPUnit\Session\IsolatedSessionStrategy; -use aik099\PHPUnit\Session\SessionFactory; use aik099\PHPUnit\Session\SessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyManager; use aik099\PHPUnit\Session\SharedSessionStrategy; @@ -60,22 +59,18 @@ public function __construct(array $values = array()) { parent::__construct($values); - $this['session_factory'] = function () { - return new SessionFactory(); - }; - $this['session_strategy_factory'] = function ($c) { $session_strategy_factory = new SessionStrategyFactory(); $session_strategy_factory->register( ISessionStrategyFactory::TYPE_ISOLATED, - new IsolatedSessionStrategy($c['session_factory']) + new IsolatedSessionStrategy() ); $session_strategy_factory->register( ISessionStrategyFactory::TYPE_SHARED, new SharedSessionStrategy( - new IsolatedSessionStrategy($c['session_factory']) + new IsolatedSessionStrategy() ) ); diff --git a/library/aik099/PHPUnit/Session/ISessionFactory.php b/library/aik099/PHPUnit/Session/ISessionFactory.php deleted file mode 100644 index 1f9fd8a..0000000 --- a/library/aik099/PHPUnit/Session/ISessionFactory.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit\Session; - - -use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Session; - -/** - * Specifies how to create Session objects for running tests. - * - * @method \Mockery\Expectation shouldReceive(string $name) - */ -interface ISessionFactory -{ - - /** - * Creates new session based on browser configuration. - * - * @param BrowserConfiguration $browser Browser configuration. - * - * @return Session - */ - public function createSession(BrowserConfiguration $browser); - -} diff --git a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php index 2cdbf18..7bbd7d2 100644 --- a/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/IsolatedSessionStrategy.php @@ -23,29 +23,12 @@ class IsolatedSessionStrategy extends AbstractSessionStrategy { - /** - * Session factory. - * - * @var ISessionFactory - */ - private $_sessionFactory; - - /** - * Creates isolated session strategy instance. - * - * @param ISessionFactory $session_factory Session factory. - */ - public function __construct(ISessionFactory $session_factory) - { - $this->_sessionFactory = $session_factory; - } - /** * @inheritDoc */ public function session(BrowserConfiguration $browser) { - $session = $this->_sessionFactory->createSession($browser); + $session = new Session($browser->createDriver()); $this->isFreshSession = true; return $session; diff --git a/library/aik099/PHPUnit/Session/SessionFactory.php b/library/aik099/PHPUnit/Session/SessionFactory.php deleted file mode 100644 index 80a6e1e..0000000 --- a/library/aik099/PHPUnit/Session/SessionFactory.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace aik099\PHPUnit\Session; - - -use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Session; - -/** - * Produces sessions. - * - * @method \Mockery\Expectation shouldReceive(string $name) - */ -class SessionFactory implements ISessionFactory -{ - - /** - * Creates new session based on browser configuration. - * - * @param BrowserConfiguration $browser Browser configuration. - * - * @return Session - */ - public function createSession(BrowserConfiguration $browser) - { - return new Session($browser->createDriver()); - } - -} diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index dc0ec05..8f79467 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -28,7 +28,6 @@ use aik099\PHPUnit\RemoteCoverage\RemoteUrl; use aik099\PHPUnit\Session\ISessionStrategyFactory; use aik099\PHPUnit\Session\IsolatedSessionStrategy; -use aik099\PHPUnit\Session\SessionFactory; use aik099\PHPUnit\Session\SessionStrategyFactory; use aik099\PHPUnit\Session\SessionStrategyManager; use aik099\PHPUnit\Session\SharedSessionStrategy; @@ -82,7 +81,6 @@ public static function serviceDefinitionsDataProvider() { return array( array('application', Application::class), - array('session_factory', SessionFactory::class), array('session_strategy_factory', SessionStrategyFactory::class), array('session_strategy_manager', SessionStrategyManager::class), array('remote_url', RemoteUrl::class), diff --git a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php index 664c7e2..0528abb 100644 --- a/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/IsolatedSessionStrategyTest.php @@ -11,28 +11,20 @@ namespace tests\aik099\PHPUnit\Session; -use aik099\PHPUnit\Session\ISessionFactory; use aik099\PHPUnit\Session\IsolatedSessionStrategy; +use Behat\Mink\Driver\DriverInterface; +use Behat\Mink\Session; use Mockery as m; -use Mockery\MockInterface; class IsolatedSessionStrategyTest extends AbstractSessionStrategyTestCase { - /** - * Session factory. - * - * @var ISessionFactory|MockInterface - */ - private $_factory; - /** * @before */ protected function setUpTest() { - $this->_factory = m::mock(ISessionFactory::class); - $this->strategy = new IsolatedSessionStrategy($this->_factory); + $this->strategy = new IsolatedSessionStrategy(); } /** @@ -44,25 +36,30 @@ public function testSession() { $browser = m::mock(self::BROWSER_CLASS); - $session1 = m::mock(self::SESSION_CLASS); - $session2 = m::mock(self::SESSION_CLASS); + $driver1 = m::mock(DriverInterface::class); + $driver1->shouldReceive('setSession')->with(m::type(Session::class))->once(); + + $driver2 = m::mock(DriverInterface::class); + $driver2->shouldReceive('setSession')->with(m::type(Session::class))->once(); - $this->_factory - ->shouldReceive('createSession') - ->with($browser) - ->twice() - ->andReturn($session1, $session2); + $browser->shouldReceive('createDriver')->twice()->andReturn($driver1, $driver2); - $this->assertEquals($session1, $this->strategy->session($browser)); - $this->assertEquals($session2, $this->strategy->session($browser)); + $session1 = $this->strategy->session($browser); + $this->assertInstanceOf(Session::class, $session1); + $this->assertSame($driver1, $session1->getDriver()); + + $session2 = $this->strategy->session($browser); + $this->assertInstanceOf(Session::class, $session2); + $this->assertSame($driver2, $session2->getDriver()); } public function testIsFreshSessionAfterSessionIsStarted() { - $browser = m::mock(self::BROWSER_CLASS); - $session = m::mock(self::SESSION_CLASS); + $driver = m::mock(DriverInterface::class); + $driver->shouldReceive('setSession')->with(m::type(Session::class))->once(); - $this->_factory->shouldReceive('createSession')->with($browser)->once()->andReturn($session); + $browser = m::mock(self::BROWSER_CLASS); + $browser->shouldReceive('createDriver')->once()->andReturn($driver); $this->strategy->session($browser); diff --git a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php b/tests/aik099/PHPUnit/Session/SessionFactoryTest.php deleted file mode 100644 index 9e016c6..0000000 --- a/tests/aik099/PHPUnit/Session/SessionFactoryTest.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @link https://github.com/aik099/phpunit-mink - */ - -namespace tests\aik099\PHPUnit\Session; - - -use aik099\PHPUnit\Session\SessionFactory; -use Mockery as m; -use tests\aik099\PHPUnit\AbstractTestCase; -use Behat\Mink\Driver\DriverInterface; -use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Session; - -class SessionFactoryTest extends AbstractTestCase -{ - - /** - * Session factory. - * - * @var SessionFactory - */ - private $_factory; - - /** - * @before - */ - protected function setUpTest() - { - $this->_factory = new SessionFactory(); - } - - /** - * Test description. - * - * @return void - */ - public function testCreateSession() - { - $driver = m::mock(DriverInterface::class); - $driver->shouldReceive('setSession')->with(m::any())->once(); - - $browser = m::mock(BrowserConfiguration::class); - $browser->shouldReceive('createDriver')->once()->andReturn($driver); - - $session = $this->_factory->createSession($browser); - - $this->assertInstanceOf(Session::class, $session); - $this->assertSame($driver, $session->getDriver()); - } - -} From 86ce20f3efb5d63dbd6ba3f0b195fb2581a76050 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 17 Mar 2024 16:14:00 +0200 Subject: [PATCH 193/204] Simplify driver installation process --- .../MinkDriver/AbstractDriverFactory.php | 39 +++++++++++++++++++ .../MinkDriver/GoutteDriverFactory.php | 24 ++++++------ .../PHPUnit/MinkDriver/IMinkDriverFactory.php | 8 ++++ .../PHPUnit/MinkDriver/SahiDriverFactory.php | 24 ++++++------ .../MinkDriver/Selenium2DriverFactory.php | 24 ++++++------ .../MinkDriver/ZombieDriverFactory.php | 24 ++++++------ .../PHPUnit/MinkDriver/DriverFactoryTest.php | 7 +++- 7 files changed, 96 insertions(+), 54 deletions(-) create mode 100644 library/aik099/PHPUnit/MinkDriver/AbstractDriverFactory.php diff --git a/library/aik099/PHPUnit/MinkDriver/AbstractDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/AbstractDriverFactory.php new file mode 100644 index 0000000..efb0a6b --- /dev/null +++ b/library/aik099/PHPUnit/MinkDriver/AbstractDriverFactory.php @@ -0,0 +1,39 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace aik099\PHPUnit\MinkDriver; + + +abstract class AbstractDriverFactory implements IMinkDriverFactory +{ + + /** + * Throws an exception with driver installation instructions. + * + * @param string $class_name Driver class name. + * + * @return void + * @throws \RuntimeException When driver isn't installed. + */ + protected function assertInstalled($class_name) + { + if ( !class_exists($class_name) ) { + throw new \RuntimeException( + sprintf( + 'The "%s" driver package is not installed. Please follow installation instructions at %s.', + $this->getDriverName(), + $this->getDriverPackageUrl() + ) + ); + } + } + +} diff --git a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php index 31b7075..c68438e 100644 --- a/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/GoutteDriverFactory.php @@ -13,9 +13,8 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Driver\DriverInterface; -class GoutteDriverFactory implements IMinkDriverFactory +class GoutteDriverFactory extends AbstractDriverFactory { /** @@ -28,6 +27,14 @@ public function getDriverName() return 'goutte'; } + /** + * @inheritDoc + */ + public function getDriverPackageUrl() + { + return 'https://packagist.org/packages/behat/mink-goutte-driver'; + } + /** * Returns default values for browser configuration. * @@ -44,20 +51,11 @@ public function getDriverDefaults() } /** - * Returns a new driver instance according to the browser configuration. - * - * @param BrowserConfiguration $browser The browser configuration. - * - * @return DriverInterface - * @throws \RuntimeException When driver isn't installed. + * @inheritDoc */ public function createDriver(BrowserConfiguration $browser) { - if ( !class_exists('Behat\Mink\Driver\GoutteDriver') ) { - throw new \RuntimeException( - 'Install MinkGoutteDriver in order to use goutte driver.' - ); - } + $this->assertInstalled('Behat\Mink\Driver\GoutteDriver'); $driver_options = $browser->getDriverOptions(); diff --git a/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php index 9ee6eb9..dadce1d 100644 --- a/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/IMinkDriverFactory.php @@ -25,6 +25,13 @@ interface IMinkDriverFactory */ public function getDriverName(); + /** + * Returns driver package URL. + * + * @return string + */ + public function getDriverPackageUrl(); + /** * Returns default values for browser configuration. * @@ -38,6 +45,7 @@ public function getDriverDefaults(); * @param BrowserConfiguration $browser The browser configuration. * * @return DriverInterface + * @throws \RuntimeException When driver isn't installed. */ public function createDriver(BrowserConfiguration $browser); diff --git a/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php index a0f2539..5fa3cd0 100644 --- a/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/SahiDriverFactory.php @@ -13,9 +13,8 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Driver\DriverInterface; -class SahiDriverFactory implements IMinkDriverFactory +class SahiDriverFactory extends AbstractDriverFactory { /** @@ -28,6 +27,14 @@ public function getDriverName() return 'sahi'; } + /** + * @inheritDoc + */ + public function getDriverPackageUrl() + { + return 'https://packagist.org/packages/behat/mink-sahi-driver'; + } + /** * Returns default values for browser configuration. * @@ -46,20 +53,11 @@ public function getDriverDefaults() } /** - * Returns a new driver instance according to the browser configuration. - * - * @param BrowserConfiguration $browser The browser configuration. - * - * @return DriverInterface - * @throws \RuntimeException When driver isn't installed. + * @inheritDoc */ public function createDriver(BrowserConfiguration $browser) { - if ( !class_exists('Behat\Mink\Driver\SahiDriver') ) { - throw new \RuntimeException( - 'Install MinkSahiDriver in order to use sahi driver.' - ); - } + $this->assertInstalled('Behat\Mink\Driver\SahiDriver'); $driver_options = $browser->getDriverOptions(); diff --git a/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php b/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php index 02a184e..7667fe8 100644 --- a/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/Selenium2DriverFactory.php @@ -13,9 +13,8 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Driver\DriverInterface; -class Selenium2DriverFactory implements IMinkDriverFactory +class Selenium2DriverFactory extends AbstractDriverFactory { /** @@ -28,6 +27,14 @@ public function getDriverName() return 'selenium2'; } + /** + * @inheritDoc + */ + public function getDriverPackageUrl() + { + return 'https://packagist.org/packages/behat/mink-selenium2-driver'; + } + /** * Returns default values for browser configuration. * @@ -42,20 +49,11 @@ public function getDriverDefaults() } /** - * Returns a new driver instance according to the browser configuration. - * - * @param BrowserConfiguration $browser The browser configuration. - * - * @return DriverInterface - * @throws \RuntimeException When driver isn't installed. + * @inheritDoc */ public function createDriver(BrowserConfiguration $browser) { - if ( !class_exists('Behat\Mink\Driver\Selenium2Driver') ) { - throw new \RuntimeException( - 'Install MinkSelenium2Driver in order to use selenium2 driver.' - ); - } + $this->assertInstalled('Behat\Mink\Driver\Selenium2Driver'); $browser_name = $browser->getBrowserName(); $capabilities = $browser->getDesiredCapabilities(); diff --git a/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php b/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php index 10a00bf..59bef48 100644 --- a/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php +++ b/library/aik099/PHPUnit/MinkDriver/ZombieDriverFactory.php @@ -13,9 +13,8 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; -use Behat\Mink\Driver\DriverInterface; -class ZombieDriverFactory implements IMinkDriverFactory +class ZombieDriverFactory extends AbstractDriverFactory { /** @@ -28,6 +27,14 @@ public function getDriverName() return 'zombie'; } + /** + * @inheritDoc + */ + public function getDriverPackageUrl() + { + return 'https://packagist.org/packages/behat/mink-zombie-driver'; + } + /** * Returns default values for browser configuration. * @@ -47,20 +54,11 @@ public function getDriverDefaults() } /** - * Returns a new driver instance according to the browser configuration. - * - * @param BrowserConfiguration $browser The browser configuration. - * - * @return DriverInterface - * @throws \RuntimeException When driver isn't installed. + * @inheritDoc */ public function createDriver(BrowserConfiguration $browser) { - if ( !class_exists('Behat\Mink\Driver\ZombieDriver') ) { - throw new \RuntimeException( - 'Install MinkZombieDriver in order to use zombie driver.' - ); - } + $this->assertInstalled('Behat\Mink\Driver\ZombieDriver'); $driver_options = $browser->getDriverOptions(); diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php index 54b6360..caca5e8 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php @@ -53,11 +53,14 @@ public function testMinkDriverMissingError($driver_class, $factory_class) /** @var IMinkDriverFactory $factory */ $factory = new $factory_class(); - $driver_class_parts = explode('\\', $driver_class); $this->expectException('RuntimeException'); $this->expectExceptionMessage( - 'Install Mink' . end($driver_class_parts) . ' in order to use ' . $factory->getDriverName() . ' driver.' + sprintf( + 'The "%s" driver package is not installed. Please follow installation instructions at %s.', + $factory->getDriverName(), + $factory->getDriverPackageUrl() + ) ); $factory->createDriver($this->createBrowserConfiguration($factory)); } From fb1f217ac9097b14456932455615e27317c66c78 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 17 Mar 2024 16:41:13 +0200 Subject: [PATCH 194/204] Improve error, when unknown driver is being used --- .../MinkDriver/DriverFactoryRegistry.php | 9 +++++++- .../MinkDriver/DriverFactoryRegistryTest.php | 22 +++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php b/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php index d10117a..03336f7 100644 --- a/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php +++ b/library/aik099/PHPUnit/MinkDriver/DriverFactoryRegistry.php @@ -52,7 +52,14 @@ public function add(IMinkDriverFactory $driver_factory) public function get($driver_name) { if ( !isset($this->_registry[$driver_name]) ) { - throw new \OutOfBoundsException(sprintf('No driver factory for "%s" driver.', $driver_name)); + $error_msg = 'The "' . $driver_name . '" driver is unknown.'; + + if ( $this->_registry ) { + $drivers = '"' . implode('", "', array_keys($this->_registry)) . '"'; + $error_msg .= ' Please instead use any of these supported drivers: ' . $drivers . '.'; + } + + throw new \OutOfBoundsException($error_msg); } return $this->_registry[$driver_name]; diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php index d60dd82..97ad462 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryRegistryTest.php @@ -60,10 +60,28 @@ public function testAddingExisting() $this->_driverFactoryRegistry->add($factory); } - public function testGettingNonExisting() + public function testGettingNonExistingWithoutAlternatives() { $this->expectException('OutOfBoundsException'); - $this->expectExceptionMessage('No driver factory for "test" driver.'); + $this->expectExceptionMessage('The "test" driver is unknown.'); + + $this->_driverFactoryRegistry->get('test'); + } + + public function testGettingNonExistingWithAlternatives() + { + $this->expectException('OutOfBoundsException'); + $this->expectExceptionMessage( + 'The "test" driver is unknown. Please instead use any of these supported drivers: "driver1", "driver2".' + ); + + $factory1 = m::mock(IMinkDriverFactory::class); + $factory1->shouldReceive('getDriverName')->once()->andReturn('driver1'); + $this->_driverFactoryRegistry->add($factory1); + + $factory2 = m::mock(IMinkDriverFactory::class); + $factory2->shouldReceive('getDriverName')->once()->andReturn('driver2'); + $this->_driverFactoryRegistry->add($factory2); $this->_driverFactoryRegistry->get('test'); } From 6f7c188b28a5a99e7757b66c82a59fdc8039dcc7 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 7 Apr 2024 22:45:20 +0300 Subject: [PATCH 195/204] Closes popups after test finishes (shared strategy) --- CHANGELOG.md | 1 + .../PHPUnit/Session/SharedSessionStrategy.php | 13 ++++++++- .../Integration/SharedSessionStrategyTest.php | 29 +++++++++++++++++-- .../Session/SharedSessionStrategyTest.php | 19 ++++++++++-- 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1b746e..28a7121 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - (Not a BC break) Some public methods of the `BrowserTestCase` class are protected now. Affected methods: `setRemoteCoverageScriptUrl`, `setBrowser`, `getBrowser`, `setSessionStrategy`, `getSessionStrategy`, `getCollectCodeCoverageInformation`, `getRemoteCodeCoverageInformation`. - (Not a BC break) Some protected properties of the `BrowserTestCase` class are private now. Affected properties: `sessionStrategyManager`, `remoteCoverageHelper`, `sessionStrategy`. - Bumped minimal required `Behat/Mink` version to 1.8 (needed after `SessionProxy` class removal). +- Shared session strategy now also closes popups left order from the previous test before switching back to the main window. ### Fixed - The remote code coverage collection cookies were set even, when the remote code coverage script URL wasn't specified. diff --git a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php index 9b003dc..89bb8cd 100644 --- a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -98,7 +98,18 @@ protected function stopAndForgetSession() */ private function _switchToMainWindow() { - $this->_session->switchToWindow(null); + $this->_session->switchToWindow(); + $actual_initial_window_name = $this->_session->getWindowName(); // Account for initial window rename. + + foreach ( $this->_session->getWindowNames() as $name ) { + if ( $name === $actual_initial_window_name ) { + continue; + } + + $this->_session->switchToWindow($name); + $this->_session->executeScript('window.close();'); + $this->_session->switchToWindow(); + } } /** diff --git a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php index 939ef6d..ad0ce2a 100644 --- a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php @@ -34,7 +34,7 @@ class SharedSessionStrategyTest extends BrowserStackAwareTestCase /** * @large */ - public function testOne() + public function testOpensPage() { $session = $this->getSession(); $session->visit('https://www.google.com'); @@ -44,9 +44,9 @@ public function testOne() /** * @large - * @depends testOne + * @depends testOpensPage */ - public function testTwo() + public function testUsesOpenedPage() { $session = $this->getSession(); $url = $session->getCurrentUrl(); @@ -54,4 +54,27 @@ public function testTwo() $this->assertStringContainsString('https://www.google.com', $url); } + public function testOpensPopups() + { + $session = $this->getSession(); + $session->visit('https://the-internet.herokuapp.com/windows'); + + $page = $session->getPage(); + $page->clickLink('Click Here'); + $page->clickLink('Click Here'); + + $this->assertCount(3, $session->getWindowNames()); // Main window + 2 popups. + } + + /** + * @depends testOpensPopups + */ + public function testNoPopupsBeforeTest() + { + $session = $this->getSession(); + $this->assertEquals('https://the-internet.herokuapp.com/windows', $session->getCurrentUrl()); + + $this->assertCount(1, $session->getWindowNames()); // Main window. + } + } diff --git a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php index 28a84d9..a8d5d58 100644 --- a/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Session/SharedSessionStrategyTest.php @@ -72,7 +72,7 @@ public function testSessionSharing(\Exception $e = null) $this->_originalStrategy->shouldReceive('session')->once()->with($browser)->andReturn($this->_session1); $this->_originalStrategy->shouldReceive('isFreshSession')->once()->andReturn(true); - $this->_session1->shouldReceive('switchToWindow')->once(); + $this->expectNoPopups($this->_session1); $this->assertSame($this->_session1, $this->strategy->session($browser)); $this->assertTrue($this->strategy->isFreshSession(), 'First created session must be fresh'); @@ -85,6 +85,21 @@ public function testSessionSharing(\Exception $e = null) $this->assertFalse($this->strategy->isFreshSession(), 'Reused session must not be fresh'); } + /** + * Expects no popups. + * + * @param MockInterface $session Session. + * + * @return void + */ + protected function expectNoPopups(MockInterface $session) + { + // Testing if popup windows are actually closed will be done in the integration test. + $session->shouldReceive('switchToWindow')->atLeast()->once(); + $session->shouldReceive('getWindowName')->once()->andReturn('initial-window-name'); + $session->shouldReceive('getWindowNames')->once()->andReturn(array('initial-window-name')); + } + /** * Returns exceptions, that doesn't reset session. * @@ -121,7 +136,7 @@ public function testSessionResetOnFailure() $this->_session1->shouldReceive('isStarted')->once()->andReturn(true); $this->_session1->shouldReceive('stop')->once(); - $this->_session2->shouldReceive('switchToWindow')->once(); + $this->expectNoPopups($this->_session2); $session = $this->strategy->session($browser); $this->assertSame($this->_session1, $session); From 21a79f7bdfad93f23c8d6e6dc25cd3a2178ef09c Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 10 Apr 2024 11:06:56 +0300 Subject: [PATCH 196/204] Micro-optimization of the window closing inside the shared session strategy --- library/aik099/PHPUnit/Session/SharedSessionStrategy.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php index 89bb8cd..0fccc57 100644 --- a/library/aik099/PHPUnit/Session/SharedSessionStrategy.php +++ b/library/aik099/PHPUnit/Session/SharedSessionStrategy.php @@ -98,7 +98,7 @@ protected function stopAndForgetSession() */ private function _switchToMainWindow() { - $this->_session->switchToWindow(); + $this->_session->switchToWindow(); // Switch to the window before attempting to execute any window-based calls. $actual_initial_window_name = $this->_session->getWindowName(); // Account for initial window rename. foreach ( $this->_session->getWindowNames() as $name ) { @@ -108,8 +108,9 @@ private function _switchToMainWindow() $this->_session->switchToWindow($name); $this->_session->executeScript('window.close();'); - $this->_session->switchToWindow(); } + + $this->_session->switchToWindow(); } /** From b841ec566df1f9cf35c3426ee3fd48f8f3afc414 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 9 Jul 2024 16:21:40 +0300 Subject: [PATCH 197/204] Fixed typos in the CHANGELOG.md --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28a7121..2152920 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added - Specify failed PHPUnit assertion text to the BrowserStack ("reason" field)/SauceLabs("custom-data" field) test. -- Added the `$auto_create` parameter to the `BrowserTestCase::getSession` method, which allows to verify is session is already started. -- Added the `ISessionStrategy::isFreshSession` method to indicate fact, that previous `ISessionStrategy::session` call have created a new session instead of reusing a previously created one. Can be used to perform a login once per a test case class. +- Added the `$auto_create` parameter to the `BrowserTestCase::getSession` method, which allows to verify if session is already started. +- Added the `ISessionStrategy::isFreshSession` method to indicate fact, that previous `ISessionStrategy::session` call has created a new session instead of reusing a previously created one. Can be used to perform a login once per a test case class. ### Changed - Bumped minimum PHP version to 5.6. @@ -17,7 +17,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - (Not a BC break) Some public methods of the `BrowserTestCase` class are protected now. Affected methods: `setRemoteCoverageScriptUrl`, `setBrowser`, `getBrowser`, `setSessionStrategy`, `getSessionStrategy`, `getCollectCodeCoverageInformation`, `getRemoteCodeCoverageInformation`. - (Not a BC break) Some protected properties of the `BrowserTestCase` class are private now. Affected properties: `sessionStrategyManager`, `remoteCoverageHelper`, `sessionStrategy`. - Bumped minimal required `Behat/Mink` version to 1.8 (needed after `SessionProxy` class removal). -- Shared session strategy now also closes popups left order from the previous test before switching back to the main window. +- Shared session strategy now also closes popups left over from the previous test before switching back to the main window. ### Fixed - The remote code coverage collection cookies were set even, when the remote code coverage script URL wasn't specified. From 9a25aa7d10c19cde39e27d925c7a85f027616334 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 15 Jul 2024 13:46:20 +0300 Subject: [PATCH 198/204] Use newer phpunit-compat --- CHANGELOG.md | 1 + composer.json | 2 +- composer.lock | 45 +++++++++++++++++++++++++-------------------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2152920..8f896ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - (Not a BC break) Some protected properties of the `BrowserTestCase` class are private now. Affected properties: `sessionStrategyManager`, `remoteCoverageHelper`, `sessionStrategy`. - Bumped minimal required `Behat/Mink` version to 1.8 (needed after `SessionProxy` class removal). - Shared session strategy now also closes popups left over from the previous test before switching back to the main window. +- Bumped minimal required `console-helpers/phpunit-compat` version to 1.0.3 to load classes through the custom autoloader script. ### Fixed - The remote code coverage collection cookies were set even, when the remote code coverage script URL wasn't specified. diff --git a/composer.json b/composer.json index 5d220f6..a48a954 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "behat/mink": "^1.8@dev", "behat/mink-selenium2-driver": "~1.2", "phpunit/phpunit": ">=4.8.35 <5|>=5.4.3", - "console-helpers/phpunit-compat": "^1.0.2" + "console-helpers/phpunit-compat": "^1.0.3" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 5bdb766..956eb5b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "308a4f814b44da8fd1eea8bd79b02b69", + "content-hash": "b267284ec13645ff1a614f50a181cc1a", "packages": [ { "name": "behat/mink", @@ -139,16 +139,16 @@ }, { "name": "console-helpers/phpunit-compat", - "version": "v1.0.2", + "version": "v1.0.3", "source": { "type": "git", "url": "https://github.com/console-helpers/phpunit-compat.git", - "reference": "6b7dcb5a4f5c334b9eb7f41acba5554382d2d5c1" + "reference": "096c6e42ebd090415ab03d9ce9edff8ed978a319" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/console-helpers/phpunit-compat/zipball/6b7dcb5a4f5c334b9eb7f41acba5554382d2d5c1", - "reference": "6b7dcb5a4f5c334b9eb7f41acba5554382d2d5c1", + "url": "https://api.github.com/repos/console-helpers/phpunit-compat/zipball/096c6e42ebd090415ab03d9ce9edff8ed978a319", + "reference": "096c6e42ebd090415ab03d9ce9edff8ed978a319", "shasum": "" }, "require": { @@ -164,8 +164,10 @@ } }, "autoload": { + "files": [ + "phpunitcompat_autoloader.php" + ], "psr-4": { - "ConsoleHelpers\\PHPUnitCompat\\": "src/PHPUnitCompat/", "Tests\\ConsoleHelpers\\PHPUnitCompat\\": "tests/PHPUnitCompat/" } }, @@ -182,9 +184,9 @@ "description": "Compatibility layer for PHPUnit test cases/test suite to work on different major PHPUnit versions", "support": { "issues": "https://github.com/console-helpers/phpunit-compat/issues", - "source": "https://github.com/console-helpers/phpunit-compat/tree/v1.0.2" + "source": "https://github.com/console-helpers/phpunit-compat/tree/v1.0.3" }, - "time": "2024-03-12T11:33:58+00:00" + "time": "2024-07-11T11:28:01+00:00" }, { "name": "doctrine/instantiator", @@ -260,16 +262,16 @@ }, { "name": "instaclick/php-webdriver", - "version": "1.4.18", + "version": "1.4.19", "source": { "type": "git", "url": "https://github.com/instaclick/php-webdriver.git", - "reference": "a61a8459f86c79dd1f19934ea3929804f2e41f8c" + "reference": "3b2a2ddc4e0a690cc691d7e5952964cc4b9538b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/a61a8459f86c79dd1f19934ea3929804f2e41f8c", - "reference": "a61a8459f86c79dd1f19934ea3929804f2e41f8c", + "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/3b2a2ddc4e0a690cc691d7e5952964cc4b9538b1", + "reference": "3b2a2ddc4e0a690cc691d7e5952964cc4b9538b1", "shasum": "" }, "require": { @@ -317,9 +319,9 @@ ], "support": { "issues": "https://github.com/instaclick/php-webdriver/issues", - "source": "https://github.com/instaclick/php-webdriver/tree/1.4.18" + "source": "https://github.com/instaclick/php-webdriver/tree/1.4.19" }, - "time": "2023-12-08T07:11:19+00:00" + "time": "2024-03-19T01:58:53+00:00" }, { "name": "myclabs/deep-copy", @@ -2013,16 +2015,16 @@ }, { "name": "yoast/phpunit-polyfills", - "version": "1.1.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", - "reference": "224e4a1329c03d8bad520e3fc4ec980034a4b212" + "reference": "a0f7d708794a738f328d7b6c94380fd1d6c40446" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/224e4a1329c03d8bad520e3fc4ec980034a4b212", - "reference": "224e4a1329c03d8bad520e3fc4ec980034a4b212", + "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/a0f7d708794a738f328d7b6c94380fd1d6c40446", + "reference": "a0f7d708794a738f328d7b6c94380fd1d6c40446", "shasum": "" }, "require": { @@ -2030,7 +2032,9 @@ "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, "require-dev": { - "yoast/yoastcs": "^2.3.0" + "php-parallel-lint/php-console-highlighter": "^1.0.0", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "yoast/yoastcs": "^3.1.0" }, "type": "library", "extra": { @@ -2067,9 +2071,10 @@ ], "support": { "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues", + "security": "https://github.com/Yoast/PHPUnit-Polyfills/security/policy", "source": "https://github.com/Yoast/PHPUnit-Polyfills" }, - "time": "2023-08-19T14:25:08+00:00" + "time": "2024-04-05T16:01:51+00:00" } ], "aliases": [], From 6ebf48d8d76a7054f84de2cbe779318cc3b0f4ab Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 15 Jul 2024 14:00:18 +0300 Subject: [PATCH 199/204] Prepare 2.4.0 release --- CHANGELOG.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f896ef..ad53bb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added +... + +### Changed +... + +### Fixed +... + +## [2.4.0] - 2024-07-15 +### Added - Specify failed PHPUnit assertion text to the BrowserStack ("reason" field)/SauceLabs("custom-data" field) test. - Added the `$auto_create` parameter to the `BrowserTestCase::getSession` method, which allows to verify if session is already started. - Added the `ISessionStrategy::isFreshSession` method to indicate fact, that previous `ISessionStrategy::session` call has created a new session instead of reusing a previously created one. Can be used to perform a login once per a test case class. @@ -105,7 +115,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - Initial release. -[Unreleased]: https://github.com/minkphp/phpunit-mink/compare/v2.2.0...HEAD +[Unreleased]: https://github.com/minkphp/phpunit-mink/compare/v2.4.0...HEAD +[2.4.0]: https://github.com/minkphp/phpunit-mink/compare/v2.3.0...v2.4.0 +[2.3.0]: https://github.com/minkphp/phpunit-mink/compare/v2.2.0...v2.3.0 [2.2.0]: https://github.com/minkphp/phpunit-mink/compare/v2.1.1...v2.2.0 [2.1.1]: https://github.com/minkphp/phpunit-mink/compare/v2.1.0...v2.1.1 [2.1.0]: https://github.com/minkphp/phpunit-mink/compare/v2.0.1...v2.1.0 From e6b575b0f9d223363d833a9565f8f8eb1ec2c8a6 Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 15 Jul 2024 19:31:16 +0300 Subject: [PATCH 200/204] Attempt to avoid "BROWSERSTACK_QUEUE_SIZE_EXCEEDED" BrowserStack error --- .../Integration/BrowserStackAwareTestCase.php | 28 +++++++++++++++++++ .../IsolatedSessionStrategyTest.php | 2 +- .../Integration/SharedSessionStrategyTest.php | 4 +-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php index 2cb17a8..7bec46a 100644 --- a/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php +++ b/tests/aik099/PHPUnit/Integration/BrowserStackAwareTestCase.php @@ -12,6 +12,8 @@ use aik099\PHPUnit\BrowserTestCase; +use Behat\Mink\Exception\DriverException; +use Behat\Mink\Session; abstract class BrowserStackAwareTestCase extends BrowserTestCase { @@ -27,6 +29,32 @@ abstract class BrowserStackAwareTestCase extends BrowserTestCase ), ); + /** + * Visit specified URL and automatically start session if not already running. + * + * @param Session $session Session. + * @param string $url Url of the page. + * + * @return void + * @throws DriverException + */ + protected function openPageWithBackoff(Session $session, $url) + { + try { + $session->visit($url); + } + catch ( DriverException $e ) { + if ( strpos($e->getMessage(), '[BROWSERSTACK_QUEUE_SIZE_EXCEEDED]') !== false ) { + sleep(30); + $this->openPageWithBackoff($session, $url); + + return; + } + + throw $e; + } + } + /** * @before */ diff --git a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php index 65a46bc..ffa4597 100644 --- a/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/IsolatedSessionStrategyTest.php @@ -37,7 +37,7 @@ class IsolatedSessionStrategyTest extends BrowserStackAwareTestCase public function testOne() { $session = $this->getSession(); - $session->visit('https://www.google.com'); + $this->openPageWithBackoff($session, 'https://www.google.com'); $this->assertTrue(true); } diff --git a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php index ad0ce2a..ee4cb62 100644 --- a/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php +++ b/tests/aik099/PHPUnit/Integration/SharedSessionStrategyTest.php @@ -37,7 +37,7 @@ class SharedSessionStrategyTest extends BrowserStackAwareTestCase public function testOpensPage() { $session = $this->getSession(); - $session->visit('https://www.google.com'); + $this->openPageWithBackoff($session, 'https://www.google.com'); $this->assertTrue(true); } @@ -57,7 +57,7 @@ public function testUsesOpenedPage() public function testOpensPopups() { $session = $this->getSession(); - $session->visit('https://the-internet.herokuapp.com/windows'); + $this->openPageWithBackoff($session, 'https://the-internet.herokuapp.com/windows'); $page = $session->getPage(); $page->clickLink('Click Here'); From 0dead48fe541077a0ba86719256b8f5bea485e9b Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 31 Oct 2024 21:25:50 +0200 Subject: [PATCH 201/204] Added support for WebdriverClassicDriver Mink's Driver --- CHANGELOG.md | 2 +- .../configuration/driver_showcase.php | 8 ++ .../BrowserConfiguration.php | 2 +- library/aik099/PHPUnit/DIContainer.php | 2 + .../MinkDriver/WebdriverClassicFactory.php | 74 +++++++++++++++++++ .../PHPUnit/Integration/DIContainerTest.php | 2 + .../PHPUnit/MinkDriver/DriverFactoryTest.php | 5 ++ 7 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 library/aik099/PHPUnit/MinkDriver/WebdriverClassicFactory.php diff --git a/CHANGELOG.md b/CHANGELOG.md index ad53bb7..29ab228 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added -... +- Added support for WebdriverClassicDriver Mink's Driver (supports Selenium 2, 3, 4) as `webdriver-classic`. ### Changed ... diff --git a/docs/examples/configuration/driver_showcase.php b/docs/examples/configuration/driver_showcase.php index 84b28bc..923fb1f 100644 --- a/docs/examples/configuration/driver_showcase.php +++ b/docs/examples/configuration/driver_showcase.php @@ -36,6 +36,14 @@ class DriverShowCaseTest extends BrowserTestCase 'driverOptions' => array(), ), + array( + 'driver' => 'webdriver-classic', + + // Defaults for this driver. + 'port' => 4444, + 'driverOptions' => array(), + ), + array( 'driver' => 'zombie', diff --git a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php index b12748a..98c077f 100644 --- a/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php +++ b/library/aik099/PHPUnit/BrowserConfiguration/BrowserConfiguration.php @@ -47,7 +47,7 @@ class BrowserConfiguration 'driver' => 'selenium2', 'driverOptions' => array(), - // TODO: Move under 'driverOptions' of 'selenium2' driver (BC break). + // TODO: Move under 'driverOptions' of 'selenium2'/'webdriver-classic' driver (BC break). 'desiredCapabilities' => array(), 'timeout' => 60, diff --git a/library/aik099/PHPUnit/DIContainer.php b/library/aik099/PHPUnit/DIContainer.php index 5352de6..bb73c66 100644 --- a/library/aik099/PHPUnit/DIContainer.php +++ b/library/aik099/PHPUnit/DIContainer.php @@ -20,6 +20,7 @@ use aik099\PHPUnit\MinkDriver\GoutteDriverFactory; use aik099\PHPUnit\MinkDriver\SahiDriverFactory; use aik099\PHPUnit\MinkDriver\Selenium2DriverFactory; +use aik099\PHPUnit\MinkDriver\WebdriverClassicFactory; use aik099\PHPUnit\MinkDriver\ZombieDriverFactory; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteUrl; @@ -112,6 +113,7 @@ public function __construct(array $values = array()) $registry = new DriverFactoryRegistry(); $registry->add(new Selenium2DriverFactory()); + $registry->add(new WebdriverClassicFactory()); $registry->add(new SahiDriverFactory()); $registry->add(new GoutteDriverFactory()); $registry->add(new ZombieDriverFactory()); diff --git a/library/aik099/PHPUnit/MinkDriver/WebdriverClassicFactory.php b/library/aik099/PHPUnit/MinkDriver/WebdriverClassicFactory.php new file mode 100644 index 0000000..e528bbf --- /dev/null +++ b/library/aik099/PHPUnit/MinkDriver/WebdriverClassicFactory.php @@ -0,0 +1,74 @@ + + * @link https://github.com/aik099/phpunit-mink + */ + + +namespace aik099\PHPUnit\MinkDriver; + + +use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; + +class WebdriverClassicFactory extends AbstractDriverFactory +{ + + /** + * Returns driver name, that can be used in browser configuration. + * + * @return string + */ + public function getDriverName() + { + return 'webdriver-classic'; + } + + /** + * @inheritDoc + */ + public function getDriverPackageUrl() + { + return 'https://packagist.org/packages/mink/webdriver-classic-driver'; + } + + /** + * Returns default values for browser configuration. + * + * @return array + */ + public function getDriverDefaults() + { + return array( + 'port' => 4444, + 'driverOptions' => array(), + ); + } + + /** + * @inheritDoc + */ + public function createDriver(BrowserConfiguration $browser) + { + $this->assertInstalled('Mink\WebdriverClassicDriver\WebdriverClassicDriver'); + + $browser_name = $browser->getBrowserName(); + $capabilities = $browser->getDesiredCapabilities(); + $capabilities['browserName'] = $browser_name; + + // TODO: Maybe doesn't work! + ini_set('default_socket_timeout', $browser->getTimeout()); + + $driver = new \Mink\WebdriverClassicDriver\WebdriverClassicDriver( + $browser_name, + $capabilities, + 'http://' . $browser->getHost() . ':' . $browser->getPort() . '/wd/hub' + ); + + return $driver; + } + +} diff --git a/tests/aik099/PHPUnit/Integration/DIContainerTest.php b/tests/aik099/PHPUnit/Integration/DIContainerTest.php index 8f79467..c798ead 100644 --- a/tests/aik099/PHPUnit/Integration/DIContainerTest.php +++ b/tests/aik099/PHPUnit/Integration/DIContainerTest.php @@ -23,6 +23,7 @@ use aik099\PHPUnit\MinkDriver\GoutteDriverFactory; use aik099\PHPUnit\MinkDriver\SahiDriverFactory; use aik099\PHPUnit\MinkDriver\Selenium2DriverFactory; +use aik099\PHPUnit\MinkDriver\WebdriverClassicFactory; use aik099\PHPUnit\MinkDriver\ZombieDriverFactory; use aik099\PHPUnit\RemoteCoverage\RemoteCoverageHelper; use aik099\PHPUnit\RemoteCoverage\RemoteUrl; @@ -116,6 +117,7 @@ public function testDriverFactoryRegistry() $driver_factory_registry = $this->_container['driver_factory_registry']; $this->assertInstanceOf(Selenium2DriverFactory::class, $driver_factory_registry->get('selenium2')); + $this->assertInstanceOf(WebdriverClassicFactory::class, $driver_factory_registry->get('webdriver-classic')); $this->assertInstanceOf(SahiDriverFactory::class, $driver_factory_registry->get('sahi')); $this->assertInstanceOf(GoutteDriverFactory::class, $driver_factory_registry->get('goutte')); $this->assertInstanceOf(ZombieDriverFactory::class, $driver_factory_registry->get('zombie')); diff --git a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php index caca5e8..2dda560 100644 --- a/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php +++ b/tests/aik099/PHPUnit/MinkDriver/DriverFactoryTest.php @@ -15,6 +15,7 @@ use aik099\PHPUnit\BrowserConfiguration\BrowserConfiguration; use aik099\PHPUnit\DIContainer; use aik099\PHPUnit\MinkDriver\IMinkDriverFactory; +use aik099\PHPUnit\MinkDriver\WebdriverClassicFactory; use tests\aik099\PHPUnit\AbstractTestCase; use Yoast\PHPUnitPolyfills\Polyfills\ExpectException; use aik099\PHPUnit\MinkDriver\GoutteDriverFactory; @@ -97,6 +98,10 @@ public static function driverDataProvider() '\Behat\Mink\Driver\Selenium2Driver', Selenium2DriverFactory::class, ), + 'webdriver-classic' => array( + '\Mink\WebdriverClassicDriver\WebdriverClassicDriver', + WebdriverClassicFactory::class, + ), 'zombie' => array( '\Behat\Mink\Driver\ZombieDriver', ZombieDriverFactory::class, From 48eb6a56ef02e28212f352ca3215c0faaf6ea307 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 20 Nov 2024 11:41:34 +0200 Subject: [PATCH 202/204] Upload test results to CodeCov --- .github/workflows/tests.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5b10c93..723d5a9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -67,7 +67,7 @@ jobs: BS_ACCESS_KEY: ${{ secrets.BS_ACCESS_KEY }} if: "${{ matrix.with_coverage == true }}" run: | - vendor/bin/phpunit -v --coverage-clover=coverage.clover + vendor/bin/phpunit -v --coverage-clover=coverage.clover --log-junit junit.xml - name: Run tests without Coverage env: @@ -79,12 +79,18 @@ jobs: run: | vendor/bin/phpunit -v - - name: Upload Coverage to CodeCov - if: "${{ matrix.with_coverage == true }}" + - name: Upload coverage to Codecov + if: ${{ matrix.with_coverage == true && !cancelled() }} uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} + - name: Upload test results to Codecov + if: ${{ matrix.with_coverage == true && !cancelled() }} + uses: codecov/test-results-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + - name: Upload Coverage to Scrutinizer CI (PHP < 8.0) if: "${{ matrix.php < '8.0' && matrix.with_coverage == true }}" run: | From aa0e5b251030aeee073fe5376e5b3ea418310510 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 30 Nov 2024 20:46:22 +0200 Subject: [PATCH 203/204] Preparing 2.5.0 release --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29ab228..405f87f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added -- Added support for WebdriverClassicDriver Mink's Driver (supports Selenium 2, 3, 4) as `webdriver-classic`. +... ### Changed ... @@ -12,6 +12,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed ... +## [2.5.0] - 2024-11-30 +### Added +- Added support for WebdriverClassicDriver Mink's Driver (supports Selenium 2, 3, 4) as `webdriver-classic`. + ## [2.4.0] - 2024-07-15 ### Added - Specify failed PHPUnit assertion text to the BrowserStack ("reason" field)/SauceLabs("custom-data" field) test. @@ -115,7 +119,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - Initial release. -[Unreleased]: https://github.com/minkphp/phpunit-mink/compare/v2.4.0...HEAD +[Unreleased]: https://github.com/minkphp/phpunit-mink/compare/v2.5.0...HEAD +[2.5.0]: https://github.com/minkphp/phpunit-mink/compare/v2.4.0...v2.5.0 [2.4.0]: https://github.com/minkphp/phpunit-mink/compare/v2.3.0...v2.4.0 [2.3.0]: https://github.com/minkphp/phpunit-mink/compare/v2.2.0...v2.3.0 [2.2.0]: https://github.com/minkphp/phpunit-mink/compare/v2.1.1...v2.2.0 From 776beecc237c5de4aac6da9b2c4a33792782c3b7 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 1 Dec 2024 06:47:15 +0200 Subject: [PATCH 204/204] Use latest version of the "ramsey/composer-install" GitHub Action --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 723d5a9..59d3d8d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -55,7 +55,7 @@ jobs: composer require --no-update --dev scrutinizer/ocular - name: Install dependencies - uses: "ramsey/composer-install@v2" + uses: "ramsey/composer-install@v3" with: dependency-versions: "highest"