upgraded dependencies

This commit is contained in:
RafficMohammed
2023-01-08 01:59:16 +05:30
parent 51056e3aad
commit f9ae387337
6895 changed files with 133617 additions and 178680 deletions

View File

@@ -1,4 +0,0 @@
* text=auto
*.bat eol=crlf
docs export-ignore

View File

@@ -1,6 +0,0 @@
*.tgz
*.phar
behat.yml
vendor
composer.lock
phpspec.phar

View File

@@ -1,26 +0,0 @@
imports:
- javascript
- php
tools:
php_code_sniffer:
filter:
excluded-paths: [ spec/*, integration/*, features/*, src/PhpSpec/Loader/StreamWrapper.php ]
config:
standard: PSR2
php_analyzer:
filter:
excluded-paths: [ spec/*, integration/* ]
php_sim:
filter:
excluded-paths: [ spec/*, integration/* ]
build_failure_conditions:
- 'issues.label("coding-style").new.exists'
filter:
excluded_paths:
- docs/*
- vendor/*

View File

@@ -1,54 +0,0 @@
language: php
sudo: false
dist: trusty
cache:
directories:
- $HOME/.composer/cache
matrix:
include:
- php: 7.1
env: COMPOSER_FLAGS='--prefer-lowest'
- php: 7.1
- php: 7.2
- php: 7.3
- php: nightly
env: DEPENDENCIES='dev'
env: COMPOSER_FLAGS='--ignore-platform-reqs'
allow_failures:
- php: nightly
fast_finish: true
before_install:
- phpenv config-rm xdebug.ini || true
install:
- export COMPOSER_ROOT_VERSION=dev-master
- if [ "$DEPENDENCIES" == "dev" ]; then composer config minimum-stability dev; fi;
- composer update $COMPOSER_FLAGS
script:
- bin/phpspec run --format=dot
- ./vendor/bin/phpunit
- ./vendor/bin/behat --format=progress
before_deploy:
- curl -LSs https://box-project.github.io/box2/installer.php | php
- export PATH=.:$PATH
- rm -Rf ./vendor
- composer install --no-dev -o
- box.phar build
deploy:
provider: releases
api_key:
secure: eTlXM76IvH1Ws57gtBi5Q7trQ3rEXjt+7wOH4HLw6WhhywMF4THMuQQC0j5DhWtiLJlVYHaIfNbapbG+DVUqyXZZA+aXQSuh9aNM1fbkEShbWFpOrCd+Y3I1lXNvOcGZ5hvJieDVgWSc0osNLCQzaza17fhYUtbKsj4Qwc5ek8k=
file: phpspec.phar
skip_cleanup: true
on:
tags: true
php: 7.1
condition: COMPOSER_FLAGS != "--prefer-lowest"

View File

@@ -1,211 +0,0 @@
2.5.8 / 2017-07-29
==================
* [fixed] parameters after extensions ignored in config file (@borNfreee)
2.5.7 / 2017-05-12
==================
* [fixed] constructor no longer generated multuple tiles (@CarlosV2)
* [fixed] warning when src_path is empty (@vitorf7)
2.5.6 / 2017-04-27
==================
* Support sebastian/exporter 2.0 and 3.0 (@mattsches and @remicollet)
2.5.5 / 2016-12-04
==================
* [fixed] PHP 5.3 support was broken (@unfunco)
2.5.4 / 2016-12-02
==================
* [fixed] Prevent deprecation warning in Symfony 3.2.0 (@veewee)
* [performance] Reduced size of Phar (@unfunco)
2.5.3 / 2016-09-26
==================
* [fixed] Accidental linebreaks in spec name are not allowed (@randompixel)
* [fixed] Throwable can be passed as instance to shouldThrow (@jameshalsall)
* [performance] Phar version now has an optimised autoloader
2.5.2 / 2016-09-04
==================
* [fixed] Exceptions are properly highlighted in error messages (@ciaranmcnulty)
2.5.1 / 2016-07-16
==================
* [fixed] Describing a class providing a namespace with leading backslash (@mheki)
* [fixed] Bug where rerun test suite was uncoloured (@ciaranmcnulty)
* [fixed] Bug in DotFormatter when number of rows is multiple of column width (@bendavies)
2.5.0 / 2016-03-20
==================
* Fixed bug with typehints in classes defined in spec file
* Supports grouped Use statements
* Now shows path in error message when spec file doesn't contain a class
* Supports catching PHP 7 Errors in shouldThrow
* No longer attempts to generate methods with reserved names
* Fixed bug where bootstrapped classes could not be loaded after class generation
* Fixed bug where line numbers were incorrectly reported on PHP 7
* Fixed new methods being inserted incorrectly when strings included closing brace
* Dot formatter now shows spec count on last line
2.4.1 / 2016-01-01
==================
* Correctly handle nested class definitions
* Correctly handle anonymous functions in code generation
* Fixed rerunning on Windows platform
* Fixed code generation on Windows platform
* Fixed issue with fatal errors being suppressed
* Handle underscores correctly when using PSR-4
* Fixed HTML formatter
2.4.0 / 2015-11-28
==================
* Improved docblock for beConstructedThrough()
* Handle and present fatal errors
* Fixed edge case with partial use statements
* Initial support for typehinted doubles in PHP7
* Specs can now be run by specifying a fully qualified class name
* New shouldContain matcher for strings
* Warning added when trying to typehint scalars or callable in spec
* No longer truncates strings when diffing arrays in verbose mode
* New %resource_name% placeholder for generated specs
* Fixed case error in class name that triggered strictness warnings on some platforms
* Fixed undefined index error in some versions of Windows
* Clarified in composer that ext-tokenizer is required
* Supported installation with Symfony 3.0
* Fixed error when spec and src paths are the same
* New event is fired when phpspec creates a file
* Internal refactoring of Presenter objects
2.3.0 / 2015-09-07
==================
* Fixed bugs when generating methods in class with unusual whitespace
* Adds `duringInstantiation()` to more easily test constructor exceptions
* Adds `beConstructedThrough*()` and `beConstructed*()` shortcuts for named constructors
* Generated constructors are now placed at the start of the class
* Offers to make constructors private after generating a named constructor
* Shows a warning when a class is generated in a location that is not autoloadable
* Adds `%paths.config%` placeholder to allow config paths to be relative to config file
* Fixed invalid JUnit output in some non-EN locales
2.2.1 / 2015-05-30
==================
* Fix false positives in `shouldHaveKeyWithValue` matcher
* Fix fatal error in edge case when method call parameters don't match expectations
2.2.0 / 2015-04-18
==================
* Better diffs when presenting unexpected method arguments
* Better handling of methods delclared inside Traits when faking
* Offer to generate interfaces for missing typehinted collaborators
* Support for TAP format output
* Remove deprecated usage of Symfony DialogHelper
* New array `shouldHaveKeyWithValue` matcher
* Clearer error message when specs have incorrect namespace prefix
* Fix suite rerunning for HHVM
* [BC break] The unused `ask` and `askAndValidate` methods on `Console\IO` have been removed
2.1.1 / 2015-01-09
==================
* Smoother rendering for progress bar
* Fixed progress bar for case where no examples are found
* Tidier output alignment + block width
* Removed deprecated calls to Yaml::parse
* More accurate lower bounds for composer installation
2.1.0 / 2014-12-14
==================
* Specify bootstrap file via configuration
* Correct error codes while using --stop-on-failure
* Better detection of empty specs
* Fixed issue where non-spec files in spec folder caused errors
* Better PSR-4 support
* Allow objects to be instantiated via static factory methods
* Automatic generation of return statements using '--fake'
* Test suite is automatically rerun when classes or methods have been generated
* Allow examples to mark themselves as skipped
* PSR-4 support
* PSR-0 locator now supports underscores correctly
* Ability to specify a custom bootstrap file using '--bootstrap' (for autoloader registration etc)
* Ability to have a personal .phpspec.yml in home folder
* Progress bar grows from left to right and flickers less
* Improved diffs for object comparison
* Throw an exception when construction method is redefined
* Non-zero exit code when dependencies are missing
* Respect exit code of commands other than 'run'
* Higher CLI verbosity levels are handled properly
* Code Generation and Stop on Failure are configurable through phpspec.yml
* Fixes for object instantiation changes in newer versions of PHP
* PHP 5.6 support
* Fixes for progress bar sometimes rounding up to 100% when not all specs passed
* Support for non-standard Composer autoloader location
* Improved hhvm support
* Extensions can now register new command
* Resource locator de-duplicates resources (supports custom locators in extensions)
2.0.1 / 2014-07-01
==================
* Fixed the loading of the autoloader for projects using a custom composer vendor folder
2.0.0 / 2014-03-19
==================
* Improve support to windows
* Improve support to hhvm
* Improve acceptance tests coverage with Behat
* Revamped junit formatter
* Fixed #269 Problem with exception masking and generation for not found class
* HHVM is officially supported
* Add psr0 validator
* Remove Nyan from core
* Added an exception if the specified config file does not exist
* Fixed a problem with generating a constructor when it is first time added
* Improved help
* Fixed the suite runner in fast machines
* Fixed the Prophecy constraint as the new release is 1.1
* Refactored formatters to be defined as services
* Fixed the invocation of methods expecting an argument passed by reference
* Fixed the instantiation of the wrapped object in shouldThrow
* Bump the Prophecy requirement to ``~1.0.5@dev``
* Added a JUnit formatter
* Added the ``--stop-on-failure`` option
* Fixed the support of the ``--no-interaction`` option
* Added more events to add extension points
* Added the number of specs in the console output
* Fixed the handling of Windows line endings in the StringEngine and in reading doc comments
* Added extension points in the template loading
* Added a constructor generator
* Added a HTML formatter
* Added a nyan cat formatter
* Add collaborator constructor setter
* Fix couple of bugs in Prophecy integration layer
* New (old) dot formatter
* Prevent loading of unexisting PHP files
* Fix typos in the error messages
* Bump required Prophecy version to 1.0.1
* Support non-string values with ArrayContain matcher
* Create `src` folder if does not exist
* Fix stack trace and matchers failure printing
2.0.0beta1 / 2013-04-29
=======================
* Initial release

View File

@@ -1,85 +0,0 @@
3.4.3 / 2017-12-06
==================
* [fixed] Undefined exception when giving wrong args to Trigger matcher (@greg0ire)
3.4.2 / 2017-08-05
==================
* [fixed] Illegible text when using a white terminal background (@MarcelloDuarte)
3.4.1 / 2017-07-29
==================
* [fixed] parameters after extensions ignored in config file (@borNfreee)
3.4.0 / 2017-05-12
==================
* [fixed] constructor no longer generated multuple tiles (@CarlosV2)
* [fixed] warning when src_path is empty (@vitorf7)
* Support methods with reserved names on PHP 7 (@avant1)
3.3.0 / 2017-04-27
==================
* Support sebastian/exporter 3.0 (@remicollet)
* Support `.phpspec.yml` as a filename (@shrikeh)
3.2.3 / 2016-01-29
==================
* IDE support for shouldYield/shouldStartYielding (@pamil)
3.2.2 / 2016-12-04
==================
* Support sebastian/exporter 2.0 providing PHPUnit 5.7 compatibility (@mattsches)
3.2.1 / 2016-12-02
==================
* [fixed] Prevent deprecation warning in Symfony 3.2.0 (@veewee)
3.2.0 / 2016-11-27
==================
* New `shouldTrigger` matcher for specifying a warning is triggered (@Taluu)
* New `shouldIterateAs` matcher for specifying how a class is iterated (@pamil)
* New `shouldBeApproximately` matcher for comparing floats (@brainrepo)
* [fixed] No longer suggests an outdated version of Nyan formatters (@unfunco)
* [performance] Reduced size of Phar (@unfunco)
3.1.1 / 2016-09-26
==================
* [fixed] Accidental linebreaks in spec name are not allowed (@randompixel)
* [fixed] Throwable can be passed as instance to shouldThrow (@jameshalsall)
* [performance] Phar version now has an optimised autoloader
3.1.0 / 2017-09-17
======================
* Many errors are now caught and handled without ending suite execution (@ciaranmcnulty)
* Validates that matchers specified in config are valid matchers (@avant1)
* Shows Error message even when Exception was expected (@harrisonbro)
* Disallows doubling of PHP 7.1's `iterable` type (@avant1)
* [fixed] Exceptions are properly highlighted in error messages (@ciaranmcnulty)
3.0.0 / 2016-07-16
==================
* Default template now uses `::class` (@ciaranmcnulty)
* No longer declare variables/constants in global scope (@ciaranmcnulty)
* Ability to register matchers quickly via the config file (@gquemener)
* [fixed] Describing a class providing a namespace with leading backslash (@mheki)
* [fixed] Bug where rerun test suite was uncoloured (@ciaranmcnulty)
* [fixed] Bug in DotFormatter when number of rows is multiple of column width (@bendavies)
* [BC break] Removed support for @param for creating doubles (@Sam-Burns)
* [BC break] Bumped dependency versions (see migration guide) (@ciaranmcnulty)
* [BC break] Removed various code branches for support of older dependencies (@ciaranmcnulty)
* [BC break] Made classes final or abstract in simple cases (@ciaranmcnulty)
* [BC break] Removed `*Interface` from all interfaces (@shanethehat)
* [BC break] Removed deprecated code / optional interfaces (@mheki)
* [BC break] Changed extension config format so parameters are scoped to extensions (@docteurklein)
* [BC break] New Extension and ServiceContainer interfaces (@ciaranmcnulty)

View File

@@ -1,84 +0,0 @@
4.3.2 / 2018-09-24
==================
* [fixed] Better error message when trying to call method on scalar return type (@ciaranmcnulty)
4.3.1 / 2018-07-02
==================
* Typehint iteration matchers for IDEs (@l3l0)
* Extension point to help annotation extension (@drupol)
4.3.0 / 2017-12-22
==================
* Add support for .yaml file extension in config file (@unfunco)
* [fixed] src folder is created when does not exist and using PSR-4 (@unfunco)
4.2.5 / 2017-12-06
==================
* [fixed] Undefined exception when giving wrong args to Trigger matcher (@greg0ire)
4.2.4 / 2017-11-24
==================
* [fixed] Errors from incorrect type hint when collaborator method not found (@greg0ire)
4.2.3 / 2017-11-24
==================
* [fixed] Allow installation with Symfony 4 (@sroze, @gnugat)
4.2.2 / 2017-11-17
==================
* [fixed] Missing autocomplete for shouldIterateLike matchers (@pamil)
* [fixed] Regression where config files called .dist or . prefix were not picked up (@jakzal)
4.2.1 / 2017-11-10
==================
* [fixed] Properly handle empty config file (@ciaranmcnulty)
* [fixed] Non-existent folders broke composer detection (@greg0ire)
4.2.0 / 2017-10-28
==================
* Detect autoloader from composer to automatically define spec locations, reducing need for suites with PSR-4 (@greg0ire)
* Describe command without class now shows prompt with autocompleting input (@fullpipe)
4.1.0 / 2017-10-18
==================
* New `shouldIterateLike`/`shouldYieldLike` matcher (@sroze)
* Checks class name is not a reserved word when creating spec (@avant1)
4.0.4 / 2017-09-13
==================
* Allow installation on PHP 7.2 (@ciaranmcnulty)
* [performance] Improved speed when invoking native functions (@bendavies)
4.0.3 / 2017-08-26
==================
* [fixed] TypeError thrown when calling `ExampleEvent::getTime()` on event constructed w/ nullable `$time` (@oxkhar)
* [fixed] TypeError thrown when presenting diff in verbose mode (@avant1)
4.0.2 / 2017-08-05
==================
* [fixed] Illegible text when using a white terminal background (@MarcelloDuarte)
4.0.1 / 2017-07-04
==================
* [fixed] type error when handling errors (@nightlinus)
4.0.0 / 2017-07-29
==================
* Dropped support for PHP versions less than 7.0 (@ciaranmcnulty)
* Added scalar types and return types (@Sam-Burns, @ciaranmcnulty)
* [fixed] parameters after extensions ignored in config file (@borNfreee)

View File

@@ -1,33 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [5.1.0]
### Added
- PHP 7.3 compatibility (@ciaranmcnulty)
- Configure verbosity option in configuration file (@DonCallisto)
## [5.0.3]
### Fixed
- Error with scalarmatcher when type does not match (@DonCallisto)
## [5.0.2]
### Fixed
- Better error message when trying to call method on scalar return type (@ciaranmcnulty)
## [5.0.1]
### Fixed
- Type error when using Object State Matcher (@nightlinus)
## [5.0.0]
### Changed
- Bumped minimum PHP and Symfony dependences (@ciaranmcnulty)
- Added void type hints to codebase (@kix)
[5.1.0]: https://github.com/phpspec/phpspec/compare/5.0.3...5.1.0
[5.0.2]: https://github.com/phpspec/phpspec/compare/5.0.2...5.0.3
[5.0.2]: https://github.com/phpspec/phpspec/compare/5.0.1...5.0.2
[5.0.1]: https://github.com/phpspec/phpspec/compare/5.0.0...5.0.1
[5.0.0]: https://github.com/phpspec/phpspec/compare/4.3.1...5.0.0

View File

@@ -1 +0,0 @@
CHANGES-v5.md

View File

@@ -1,25 +0,0 @@
Contributing
============
PhpSpec is an open source, community-driven project. If you'd like to contribute,
feel free to do this, but remember to follow this few simple rules:
Branching strategy
-------------------
- For new features, or bugs that only affect the 5.x versions, base your changes on the `master` branch and open PRs against `master`
- For bugs that affect 4.3.x versions, base your changes on the `4.3` branch and open PRs agains `4.3`
- Bugs in previous versions are not going to be fixed, upgrade to `4.3` minimum.
Coverage
--------
- All classes that interact solely with the core logic should be covered by Specs
- Any infrastructure adaptors should be covered by integration tests using PHPUnit
- All features should be covered with .feature descriptions automated with Behat
Code style / Formatting
-----------------------
- All new classes must carry the standard copyright notice docblock
- All code in the `src` folder must follow the PSR-2 standard

View File

@@ -3,9 +3,9 @@ phpspec
The main website with documentation is at `http://www.phpspec.net <http://www.phpspec.net>`_.
.. image:: https://travis-ci.org/phpspec/phpspec.svg?branch=master
:target: https://travis-ci.org/phpspec/phpspec
:alt: Master Travis Build Status
.. image:: https://github.com/phpspec/phpspec/workflows/Build/badge.svg
:target: https://github.com/phpspec/phpspec/actions?query=workflow%3ABuild
:alt: Main Build Status
.. image:: https://img.shields.io/scrutinizer/g/phpspec/phpspec.svg
:target: https://scrutinizer-ci.com/g/phpspec/phpspec/build-status/master

View File

@@ -1,63 +0,0 @@
version: '{build}'
build: false
shallow_clone: true
platform: x86
clone_folder: c:\projects\phpspec
environment:
matrix:
- php: 7.2
skip_commits:
message: /\[ci skip\]/
cache:
- C:\ProgramData\chocolatey\bin -> appveyor.yml
- C:\ProgramData\chocolatey\lib -> appveyor.yml
- C:\tools\php -> appveyor.yml
- C:\tools\composer -> appveyor.yml
- '%LOCALAPPDATA%\Composer\files'
init:
- SET PATH=C:\Program Files\OpenSSL;c:\tools\php;C:\tools\composer;%PATH%
- SET COMPOSER_NO_INTERACTION=1
SET COMPOSER_ROOT_VERSION=dev-master
- SET ANSICON=121x90 (121x90)
- git config --global core.autocrlf input
install:
- ps: |
if (!(Test-Path c:\tools\php)) {
appveyor-retry cinst --params '""/InstallDir:C:\tools\php""' --ignore-checksums -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','')
Get-ChildItem -Path c:\tools\php
cd c:\tools\php
# Set PHP environment items that are always needed
copy php.ini-production php.ini
Add-Content php.ini "`n date.timezone=UTC"
Add-Content php.ini "`n extension_dir=ext"
Add-Content php.ini "`n extension=php_openssl.dll"
Add-Content php.ini "`n extension=php_curl.dll"
Add-Content php.ini "`n extension=php_mbstring.dll"
Add-Content php.ini "`n extension=php_fileinfo.dll"
# download Composer
if (!(Test-Path C:\tools\composer)) {
New-Item -path c:\tools -name composer -itemtype directory
}
if (!(Test-Path c:\tools\composer\composer.phar)) {
appveyor-retry appveyor DownloadFile https://getcomposer.org/composer.phar -Filename C:\tools\composer\composer.phar
Set-Content -path 'C:\tools\composer\composer.bat' -Value ('@php C:\tools\composer\composer.phar %*')
}
}
- cd c:\projects\phpspec
- appveyor-retry composer self-update
- appveyor-retry composer install --no-progress --ansi
test_script:
- cd c:\projects\phpspec
- php bin\phpspec run --format=dot
- php vendor\phpunit\phpunit\phpunit
- php vendor\behat\behat\bin\behat --format=progress --tags="~@php-version,@php5.4&&~@hhvm"

View File

@@ -1,15 +0,0 @@
default:
suites:
application:
contexts: [ ApplicationContext, FilesystemContext ]
filters: { tags: "~@isolated" }
isolated:
contexts: [ IsolatedProcessContext, FilesystemContext ]
filters: { tags: "@isolated" }
smoke:
contexts: [ IsolatedProcessContext, FilesystemContext ]
filters: { tags: "@smoke && ~@isolated" }
no-smoke:
suites:
smoke: ~

View File

@@ -24,4 +24,4 @@
(new PhpSpec\Console\Application($version))->run();
})('5.1.0');
})('7.3.0');

View File

@@ -1,19 +0,0 @@
{
"chmod": "0755",
"directories": [
"src"
],
"files": [
"LICENSE"
],
"finder": [
{
"name": "*.php",
"exclude": ["spec", "Tests", "tests"],
"in": "vendor"
}
],
"main": "bin/phpspec",
"output": "phpspec.phar",
"stub": true
}

View File

@@ -1,49 +0,0 @@
<?php
/**
* Sanity-checks a release for consistency
*/
// get the version reported by phpspec --version
if (!preg_match_all('/(?<major>[5-9])\.(?<minor>[0-9]+)\.(?<patch>[0-9]+)/', file_get_contents('bin/phpspec'), $matches) || count($matches[0])!=1) {
echo "👎 could not read version from binary file\n";
exit(1);
}
[
0 => [ 0 => $version],
'major' => [ 0 => $major],
'minor' => [ 0 => $minor],
'patch' => [ 0 => $patch]
] = $matches;
echo "Verifying version $version \n" ;
$composer = file_get_contents('composer.json');
if (!preg_match("/$major\.$minor\.x-dev/", $composer, $matches)) {
echo "👎 composer.json does not contain matching branch alias\n";
exit(1);
}
echo "👍 composer.json contains branch alias {$matches[0]}\n";
$changelog = file_get_contents('CHANGES.md');
if (!preg_match("/## \[$major.$minor.$patch\]/", $changelog, $matches)) {
echo "👎 CHANGES.md does not contain matching heading\n";
exit(1);
}
echo "👍 CHANGES.md contains heading '{$matches[0]}'\n";
if (!preg_match("/\[$major.$minor.$patch\]: https:\/\/github\.com.*$major.$minor.$patch/", $changelog, $matches)) {
echo "👎 CHANGES.md does not contain matching github diff\n";
exit(1);
}
echo "👍 CHANGES.md contains link '{$matches[0]}'\n";
exit(0);

View File

@@ -22,29 +22,34 @@
],
"require": {
"php": "^7.1, <7.4",
"phpspec/prophecy": "^1.7",
"php": "^7.3 || 8.0.* || 8.1.* || 8.2.*",
"phpspec/prophecy": "^1.9",
"phpspec/php-diff": "^1.0.0",
"sebastian/exporter": "^1.0 || ^2.0 || ^3.0",
"symfony/console": "^3.4 || ^4.0",
"symfony/event-dispatcher": "^3.4 || ^4.0",
"symfony/process": "^3.4 || ^4.0",
"symfony/finder": "^3.4 || ^4.0",
"symfony/yaml": "^3.4 || ^4.0",
"sebastian/exporter": "^3.0 || ^4.0",
"symfony/console": "^3.4 || ^4.4 || ^5.0 || ^6.0",
"symfony/event-dispatcher": "^3.4 || ^4.4 || ^5.0 || ^6.0",
"symfony/process": "^3.4 || ^4.4 || ^5.0 || ^6.0",
"symfony/finder": "^3.4 || ^4.4 || ^5.0 || ^6.0",
"symfony/yaml": "^3.4 || ^4.4 || ^5.0 || ^6.0",
"doctrine/instantiator": "^1.0.5",
"ext-tokenizer": "*"
},
"require-dev": {
"behat/behat": "^3.3",
"symfony/filesystem": "^3.4 || ^4.0",
"phpunit/phpunit": "^5.7 || ^6.0"
"symfony/filesystem": "^3.4 || ^4.0 || ^5.0 || ^6.0",
"phpunit/phpunit": "^8.0 || ^9.0",
"vimeo/psalm": "^4.3"
},
"suggest": {
"phpspec/nyan-formatters": "Adds Nyan formatters"
},
"conflict": {
"sebastian/comparator" : "<1.2.4"
},
"autoload": {
"psr-0": {
"PhpSpec": "src/"
@@ -61,7 +66,8 @@
"extra": {
"branch-alias": {
"dev-master": "5.1.x-dev"
"dev-main": "7.3.x-dev"
}
}
}

View File

@@ -1,473 +0,0 @@
<?php
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\PyStringNode;
use Fake\Prompter;
use Fake\ReRunner;
use PhpSpec\Console\Application;
use PhpSpec\Loader\StreamWrapper;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Tester\ApplicationTester;
/**
* Defines application features from the specific context.
*/
class ApplicationContext implements Context
{
const JUNIT_XSD_PATH = '/src/PhpSpec/Resources/schema/junit.xsd';
/**
* @var Application
*/
private $application;
/**
* @var integer
*/
private $lastExitCode;
/**
* @var ApplicationTester
*/
private $tester;
/**
* @var Prompter
*/
private $prompter;
/**
* @var ReRunner
*/
private $reRunner;
/**
* @beforeScenario
*/
public function setupApplication()
{
StreamWrapper::register();
$this->application = new Application('2.1-dev');
$this->application->setAutoExit(false);
$this->setFixedTerminalDimensions();
$this->tester = new ApplicationTester($this->application);
$this->setupReRunner();
$this->setupPrompter();
$this->resetShellVerbosity();
}
private function setFixedTerminalDimensions()
{
putenv('COLUMNS=130');
putenv('LINES=30');
}
private function setupPrompter()
{
$this->prompter = new Prompter();
$this->application->getContainer()->set('console.prompter', $this->prompter);
}
private function setupReRunner()
{
$this->reRunner = new ReRunner;
$this->application->getContainer()->set('process.rerunner.platformspecific', $this->reRunner);
}
private function resetShellVerbosity()
{
putenv(sprintf('SHELL_VERBOSITY=%d', OutputInterface::VERBOSITY_NORMAL));
}
/**
* @Given I have started describing the :class class
* @Given I start describing the :class class
*/
public function iDescribeTheClass($class)
{
$arguments = array(
'command' => 'describe',
'class' => $class
);
if ($this->tester->run($arguments, array('interactive' => false)) !== 0) {
throw new \Exception('Test runner exited with an error');
}
}
/**
* @When I run phpspec (non interactively)
* @When I run phpspec using the :formatter format
* @When I run phpspec with the :option option
* @When I run phpspec with :spec specs to run
* @When /I run phpspec with option (?P<option>.*)/
* @When /I run phpspec (?P<interactive>interactively)$/
* @When /I run phpspec (?P<interactive>interactively) with the (?P<option>.*) option/
*/
public function iRunPhpspec($formatter = null, $option = null, $interactive = null, $spec = null)
{
$arguments = array (
'command' => 'run',
'spec' => $spec
);
if ($formatter) {
$arguments['--format'] = $formatter;
}
$this->addOptionToArguments($option, $arguments);
$this->lastExitCode = $this->tester->run($arguments, array(
'interactive' => (bool)$interactive,
'decorated' => false,
));
}
/**
* @When I run phpspec and answer :answer when asked if I want to generate the code
* @When I run phpspec with the option :option and (I) answer :answer when asked if I want to generate the code
*/
public function iRunPhpspecAndAnswerWhenAskedIfIWantToGenerateTheCode($answer, $option=null)
{
$this->runPhpSpecAndAnswerQuestions($answer, 1, $option);
}
/**
* @When I run phpspec and answer :answer to (the) :amount questions
*/
public function iRunPhpspecAndAnswerToBothQuestions($amount, $answer)
{
$this->runPhpSpecAndAnswerQuestions($answer, ($amount === 'both' ? 2 : 3));
}
/**
* @param string $answer
* @param integer $times
* @param string $option
*/
private function runPhpSpecAndAnswerQuestions($answer, $times, $option = null)
{
$arguments = array (
'command' => 'run'
);
$this->addOptionToArguments($option, $arguments);
$i = 0;
while ($i++ < $times) {
$this->prompter->setAnswer($answer=='y');
}
$this->lastExitCode = $this->tester->run($arguments, array('interactive' => true));
}
/**
* @param string $option
* @param array $arguments
*/
private function addOptionToArguments($option, array &$arguments)
{
if ($option) {
if (preg_match('/(?P<option>[a-z-]+)=(?P<value>[a-z.]+)/', $option, $matches)) {
$arguments[$matches['option']] = $matches['value'];
} else {
$arguments['--' . trim($option, '"')] = true;
}
}
}
/**
* @Then I should see :output
* @Then I should see:
*/
public function iShouldSee($output)
{
$this->checkApplicationOutput((string)$output);
}
/**
* @Then I should be prompted for code generation
*/
public function iShouldBePromptedForCodeGeneration()
{
if(!$this->prompter->hasBeenAsked()) {
throw new \Exception('There was a missing prompt for code generation');
}
}
/**
* @Then I should see the error that :methodCall was not expected on :class
*/
public function iShouldSeeTheErrorThatWasNotExpectedOn($methodCall, $class)
{
$this->checkApplicationOutput((string)$methodCall);
$this->checkApplicationOutput((string)$this->normalize($class));
$output = $this->tester->getDisplay();
$containsOldProphecyMessage = strpos($output, 'was not expected') !== false;
$containsNewProphecyMessage = strpos($output, 'Unexpected method call') !== false;
if (!$containsOldProphecyMessage && !$containsNewProphecyMessage) {
throw new \Exception('Was expecting error message about an unexpected method call');
}
}
/**
* @Then I should not be prompted for code generation
*/
public function iShouldNotBePromptedForCodeGeneration()
{
if($this->prompter->hasBeenAsked()) {
throw new \Exception('There was an unexpected prompt for code generation');
}
}
/**
* @Then the suite should pass
*/
public function theSuiteShouldPass()
{
$this->theExitCodeShouldBe(0);
}
/**
* @Then the suite should not pass
*/
public function theSuiteShouldNotPass()
{
if ($this->lastExitCode === 0) {
throw new \Exception('The application did not exit with an error code');
}
}
/**
* @Then :number example(s) should have been skipped
*/
public function exampleShouldHaveBeenSkipped($number)
{
$this->checkApplicationOutput("($number skipped)");
}
/**
* @Then :number example(s) should have been run
*/
public function examplesShouldHaveBeenRun($number)
{
$this->checkApplicationOutput("$number examples");
}
/**
* @Then the exit code should be :code
*/
public function theExitCodeShouldBe($code)
{
if ($this->lastExitCode !== (int)$code) {
throw new \Exception(sprintf(
'The application existed with an unexpected code: expected: %s, actual: %s',
$code,
$this->lastExitCode
));
}
}
/**
* @Then I should see valid junit output
*/
public function iShouldSeeValidJunitOutput()
{
$dom = new \DOMDocument();
$dom->loadXML($this->tester->getDisplay());
if (!$dom->schemaValidate(__DIR__ . '/../..' . self::JUNIT_XSD_PATH)) {
throw new \Exception(sprintf(
"Output was not valid JUnit XML"
));
}
}
/**
* @Then the tests should be rerun
*/
public function theTestsShouldBeRerun()
{
if (!$this->reRunner->hasBeenReRun()) {
throw new \Exception('The tests should have been rerun');
}
}
/**
* @Then the tests should not be rerun
*/
public function theTestsShouldNotBeRerun()
{
if ($this->reRunner->hasBeenReRun()) {
throw new \Exception('The tests should not have been rerun');
}
}
/**
* @Then I should be prompted with:
*/
public function iShouldBePromptedWith(PyStringNode $question)
{
$stringQuestion = (string)$question;
if (!$this->prompter->hasBeenAsked($stringQuestion)) {
throw new \Exception("The prompt was not shown: $stringQuestion");
}
}
/**
* @Given I have started describing the :class class with the :config (custom) config
* @Given I start describing the :class class with the :config (custom) config
*/
public function iDescribeTheClassWithTheConfig($class, $config)
{
$arguments = array(
'command' => 'describe',
'class' => $class,
'--config' => $config
);
if ($this->tester->run($arguments, array('interactive' => false)) !== 0) {
throw new \Exception('Test runner exited with an error');
}
}
/**
* @Given there is a PSR-:namespaceType namespace :namespace configured for the :source folder
*/
public function thereIsAPsrNamespaceConfiguredForTheFolder($namespaceType, $namespace, $source)
{
if (!is_dir(__DIR__ . '/src')) {
mkdir(__DIR__ . '/src');
}
require_once __DIR__ .'/autoloader/fake_autoload.php';
}
/**
* @When I run phpspec with the :config (custom) config and answer :answer when asked if I want to generate the code
*/
public function iRunPhpspecWithConfigAndAnswerIfIWantToGenerateTheCode($config, $answer)
{
$arguments = array (
'command' => 'run',
'--config' => $config
);
$this->prompter->setAnswer($answer=='y');
$this->lastExitCode = $this->tester->run($arguments, array('interactive' => true));
}
/**
* @When I run phpspec with the spec :spec
*/
public function iRunPhpspecWithTheSpec($spec)
{
$arguments = array (
'command' => 'run',
1 => $spec
);
$this->lastExitCode = $this->tester->run($arguments, array('interactive' => false));
}
/**
* @When I run phpspec with the spec :spec and the config :config
*/
public function iRunPhpspecWithTheSpecAndTheConfig($spec, $config)
{
$arguments = array (
'command' => 'run',
1 => $spec,
'--config' => $config
);
$this->lastExitCode = $this->tester->run($arguments, array('interactive' => false));
}
private function checkApplicationOutput($output)
{
$expected = $this->normalize($output);
$actual = $this->normalize($this->tester->getDisplay(true));
if (strpos($actual, $expected) === false) {
throw new \Exception(sprintf(
"Application output did not contain expected '%s'. Actual output:\n'%s'" ,
$expected,
$this->tester->getDisplay()
));
}
}
private function normalize($string)
{
$string = preg_replace('/\([0-9]+ms\)/', '', $string);
$string = str_replace("\r", '', $string);
$string = preg_replace('#(Double\\\\.+?\\\\P)\d+#u', '$1', $string);
return $string;
}
/**
* @Then I should not be prompted for more questions
*/
public function iShouldNotBePromptedForMoreQuestions()
{
if ($this->prompter->hasUnansweredQuestions()) {
throw new \Exception(
'Not all questions were answered. This might lead into further code generation not reflected in the scenario.'
);
}
}
/**
* @Then I should an error about invalid class name :className to generate spec for
*/
public function iShouldAnErrorAboutImpossibleSpecGenerationForClass($className)
{
$this->checkApplicationOutput("I cannot generate spec for '$className' because class");
$this->checkApplicationOutput('name contains reserved keyword');
}
/**
* @Then The output should contain:
*/
public function outputShouldContain(PyStringNode $expectedOutputPart)
{
$this->checkApplicationOutput("$expectedOutputPart");
}
/**
* @Then Output should not be shown
*/
public function outputShouldNotBeShown()
{
$outputLen = strlen($this->normalize($this->tester->getDisplay(true)));
if ($outputLen) {
throw new \Exception(
'Output was shown when not expected.'
);
}
}
/**
* @Then The output should not contain:
*/
public function outputShouldNotContain(PyStringNode $expectedOutputPart)
{
$expected = $this->normalize($expectedOutputPart);
$actual = $this->normalize($this->tester->getDisplay(true));
if (strpos($actual, $expected) !== false) {
throw new \Exception(sprintf(
"Application output did contain not expected '%s'. Actual output:\n'%s'" ,
$expected,
$this->tester->getDisplay()
));
}
}
}

View File

@@ -1,50 +0,0 @@
<?php
namespace Fake;
use PhpSpec\Console\Prompter as PrompterInterface;
class Prompter implements PrompterInterface
{
private $answers = array();
private $hasBeenAsked = false;
private $question;
private $unansweredQuestions = false;
public function setAnswer($answer)
{
$this->answers[] = $answer;
}
public function askConfirmation(string $question, bool $default = true) : bool
{
$this->hasBeenAsked = true;
$this->question = $question;
$this->unansweredQuestions = count($this->answers) > 1;
return (bool)array_shift($this->answers);
}
public function hasBeenAsked($question = null)
{
if (!$question) {
return $this->hasBeenAsked;
}
return $this->hasBeenAsked
&& $this->normalise($this->question) == $this->normalise($question);
}
public function hasUnansweredQuestions()
{
return $this->unansweredQuestions;
}
/**
* @return mixed
*/
private function normalise($question)
{
return preg_replace('/\s+/', '', trim(strip_tags($question)));
}
}

View File

@@ -1,28 +0,0 @@
<?php
namespace Fake;
use PhpSpec\Process\ReRunner as BaseReRunner;
class ReRunner implements BaseReRunner
{
private $hasBeenReRun = false;
/**
* @return boolean
*/
public function isSupported()
{
return true;
}
public function reRunSuite() : void
{
$this->hasBeenReRun = true;
}
public function hasBeenReRun()
{
return $this->hasBeenReRun;
}
}

View File

@@ -1,169 +0,0 @@
<?php
use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\PyStringNode;
use PHPUnit\Framework\Assert;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
/**
* Defines application features from the specific context.
*/
class FilesystemContext implements Context
{
/**
* @var string
*/
private $workingDirectory;
/**
* @var Filesystem
*/
private $filesystem;
public function __construct()
{
$this->filesystem = new Filesystem();
}
/**
* @beforeScenario
*/
public function prepWorkingDirectory()
{
$this->workingDirectory = tempnam(sys_get_temp_dir(), 'phpspec-behat');
$this->filesystem->remove($this->workingDirectory);
$this->filesystem->mkdir($this->workingDirectory);
chdir($this->workingDirectory);
$fakeHomeDirectory = sprintf('%s/fake-home/', $this->workingDirectory);
$this->filesystem->mkdir($fakeHomeDirectory . '.phpspec');
if (!empty($_SERVER['HOMEDRIVE']) && !empty($_SERVER['HOMEPATH'])) {
$_SERVER['HOMEPATH'] = substr($fakeHomeDirectory, 2);
} else {
putenv(sprintf('HOME=%s', $fakeHomeDirectory));
}
$this->filesystem->mkdir($this->workingDirectory . '/vendor');
$this->filesystem->copy(
__DIR__ . '/autoloader/autoload.php',
$this->workingDirectory . '/vendor/autoload.php'
);
}
/**
* @afterScenario
*/
public function removeWorkingDirectory()
{
try {
$this->filesystem->remove($this->workingDirectory);
} catch (IOException $e) {
//ignoring exception
}
}
/**
* @Given I have a custom :template template that contains:
*/
public function iHaveACustomTemplateThatContains($template, PyStringNode $contents)
{
$this->filesystem->dumpFile(sprintf('fake-home/.phpspec/%s.tpl', $template), $contents);
}
/**
* @Given the bootstrap file :file contains:
*/
public function theFileContains($file, PyStringNode $contents)
{
$this->filesystem->dumpFile($file, (string)$contents);
}
/**
* @Given the class file :file contains:
* @Given the trait file :file contains:
*/
public function theClassOrTraitFileContains($file, PyStringNode $contents)
{
$this->theFileContains($file, $contents);
require_once($file);
}
/**
* @Given the spec file :file contains:
*/
public function theSpecFileContains($file, PyStringNode $contents)
{
$this->theFileContains($file, $contents);
}
/**
* @Given the config file contains:
*/
public function theConfigFileContains(PyStringNode $contents)
{
$this->theFileContains('phpspec.yml', $contents);
}
/**
* @Given there is no file :file
*/
public function thereIsNoFile($file)
{
if (file_exists($file)) {
throw new \Exception(sprintf(
"File unexpectedly exists at path '%s'",
$file
));
}
}
/**
* @Then the class in :file should contain:
* @Then a new class/spec should be generated in the :file:
*/
public function theFileShouldContain($file, PyStringNode $contents)
{
if (!file_exists($file)) {
throw new \Exception(sprintf(
"File did not exist at path '%s'",
$file
));
}
$expectedContents = (string)$contents;
if ($expectedContents != file_get_contents($file)) {
throw new \Exception(sprintf(
"File at '%s' did not contain expected contents.\nExpected: '%s'\nActual: '%s'",
$file,
$expectedContents,
file_get_contents($file)
));
}
}
/**
* @Given the config file located in :folder contains:
*/
public function theConfigFileInFolderContains($folder, PyStringNode $contents)
{
$this->theFileContains($folder.DIRECTORY_SEPARATOR.'phpspec.yml', $contents);
}
/**
* @Given I have not configured an autoloader
*/
public function iHaveNotConfiguredAnAutoloader()
{
$this->filesystem->remove($this->workingDirectory . '/vendor/autoload.php');
}
/**
* @Given there should be no file :path
*/
public function thereShouldBeNoFile($path)
{
Assert::assertFileNotExists($path);
}
}

View File

@@ -1,136 +0,0 @@
<?php
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Symfony\Component\Process\Process;
/**
* Defines application features from the specific context.
*/
class IsolatedProcessContext implements Context, SnippetAcceptingContext
{
/**
* @var Process
*/
private $process;
private $lastOutput;
/**
* @Given I have started describing the :class class
*/
public function iHaveStartedDescribingTheClass($class)
{
$command = sprintf('%s %s %s', $this->buildPhpSpecCmd(), 'describe', escapeshellarg($class));
$process = new Process($command);
$process->run();
if ($process->getExitCode() !== 0) {
throw new \Exception('The describe process ended with an error');
}
}
/**
* @When I run phpspec and answer :answer when asked if I want to generate the code
*/
public function iRunPhpspecAndAnswerWhenAskedIfIWantToGenerateTheCode($answer)
{
$command = sprintf('%s %s', $this->buildPhpSpecCmd(), 'run');
$env = array(
'SHELL_INTERACTIVE' => true,
'HOME' => getenv('HOME'),
'PATH' => getenv('PATH'),
'COLUMNS' => 80,
);
$this->process = $process = new Process($command);
$process->setEnv($env);
$process->setInput($answer);
$process->run();
}
/**
* @return string
*/
protected function buildPhpSpecCmd()
{
$isWindows = DIRECTORY_SEPARATOR === '\\';
$cmd = escapeshellcmd('' . __DIR__ . '/../../bin/phpspec');
if ($isWindows) {
$cmd = 'php ' . $cmd;
}
return $cmd;
}
/**
* @Then the tests should be rerun
*/
public function theTestsShouldBeRerun()
{
if (substr_count($this->process->getOutput(), 'specs') !== 2) {
throw new \Exception('The tests were not rerun');
}
}
/**
* @Then I should see an error about the missing autoloader
*/
public function iShouldSeeAnErrorAboutTheMissingAutoloader()
{
if (!preg_match('/autoload/', $this->process->getErrorOutput().$this->process->getOutput())) {
throw new \Exception(sprintf('There was no error regarding a missing autoloader: %s', $this->process->getErrorOutput().$this->process->getOutput()));
}
}
/**
* @When I run phpspec
*/
public function iRunPhpspec()
{
$process = new Process(
$this->buildPhpSpecCmd() . ' run'
);
$process->run();
$this->lastOutput = $process->getOutput();
}
/**
* @When I run phpspec with the :formatter formatter
*/
public function iRunPhpspecWithThe($formatter)
{
$process = new Process(
$this->buildPhpSpecCmd() . " --format=$formatter run"
);
$process->run();
$this->lastOutput = $process->getErrorOutput().$process->getOutput();
}
/**
* @Then I should see :message
*/
public function iShouldSee($message)
{
if (strpos($this->lastOutput, $message) === false) {
throw new \Exception("Missing message: $message");
}
}
/**
* @Then the suite should pass
*/
public function theSuiteShouldPass()
{
$exitCode = $this->process->getExitCode();
if ($exitCode !== 0) {
throw new \Exception(sprintf('Expected that tests will pass, but exit code was %s.', $exitCode));
}
}
}

View File

@@ -1,8 +0,0 @@
<?php
spl_autoload_register(function ($classname) {
$classname = __DIR__ . '/../src/' . str_replace("\\", "/", trim($classname, "\\")) . ".php";
if (file_exists($classname)) { include $classname; }
});
if (class_exists('FakeLoader')) {
return new FakeLoader();
}

View File

@@ -1,21 +0,0 @@
<?php
class FakeLoader
{
public function getPrefixes()
{
return array(
'Andromeda\\N4S4Arm\\' => array(
__DIR__ . '/../src/'
)
);
}
public function getPrefixesPsr4()
{
return array(
'MilkyWay\\OrionCygnusArm\\' => array(
__DIR__ . '/../src/'
)
);
}
}

View File

@@ -1,167 +0,0 @@
Feature: Developer generates a class
As a Developer
I want to automate creating classes
In order to avoid repetitive tasks and interruptions in development flow
@smoke
Scenario: Generating a class
Given I have started describing the "CodeGeneration/ClassExample1/Markdown" class
When I run phpspec and answer "y" when asked if I want to generate the code
Then a new class should be generated in the "src/CodeGeneration/ClassExample1/Markdown.php":
"""
<?php
namespace CodeGeneration\ClassExample1;
class Markdown
{
}
"""
@issue1008
Scenario: Generating a class with a custom template
Given I have started describing the "CodeGeneration/CustomExample/Markdown" class
And I have a custom "class" template that contains:
"""
<?php
/* Custom class template */%namespace_block%
final class %name%
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then a new class should be generated in the "src/CodeGeneration/CustomExample/Markdown.php":
"""
<?php
/* Custom class template */
namespace CodeGeneration\CustomExample;
final class Markdown
{
}
"""
@issue269
Scenario: Generating a class with psr4 prefix
Given the config file contains:
"""
suites:
behat_suite:
namespace: Behat\Tests\MyNamespace
psr4_prefix: Behat\Tests
"""
And I have started describing the "Behat/Tests/MyNamespace/Markdown" class
When I run phpspec and answer "y" when asked if I want to generate the code
Then a new class should be generated in the "src/MyNamespace/Markdown.php":
"""
<?php
namespace Behat\Tests\MyNamespace;
class Markdown
{
}
"""
@issue127
Scenario: Generating a class with PSR0 must convert classname underscores to directory separator
Given I have started describing the "CodeGeneration/ClassExample1/Text_Markdown" class
When I run phpspec and answer "y" when asked if I want to generate the code
Then a new class should be generated in the "src/CodeGeneration/ClassExample1/Text/Markdown.php":
"""
<?php
namespace CodeGeneration\ClassExample1;
class Text_Markdown
{
}
"""
@issue127
Scenario: Generating a class with PSR0 must not convert namespace underscores to directory separator
Given I have started describing the "CodeGeneration/Class_Example2/Text_Markdown" class
When I run phpspec and answer "y" when asked if I want to generate the code
Then a new class should be generated in the "src/CodeGeneration/Class_Example2/Text/Markdown.php":
"""
<?php
namespace CodeGeneration\Class_Example2;
class Text_Markdown
{
}
"""
Scenario: Generating a class when expectations on collaborator are defined
Given the spec file "spec/CodeGeneration/MethodExample2/ForgotPasswordSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\MethodExample2;
use CodeGeneration\MethodExample2\UserRepository;
use CodeGeneration\MethodExample2\User;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ForgotPasswordSpec extends ObjectBehavior
{
function it_changes_password_for_user(UserRepository $repository, User $user)
{
$repository->findOneByEmail('leszek.prabucki@gmail.com')->willReturn($user);
$user->changePassword('123')->shouldBeCalled();
$this->changePassword('leszek.prabucki@gmail.com', '123');
}
}
"""
And the class file "src/CodeGeneration/MethodExample2/User.php" contains:
"""
<?php
namespace CodeGeneration\MethodExample2;
interface User
{
public function changePassword($newPassword);
}
"""
And the class file "src/CodeGeneration/MethodExample2/UserRepository.php" contains:
"""
<?php
namespace CodeGeneration\MethodExample2;
interface UserRepository
{
public function findOneByEmail($email);
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/MethodExample2/ForgotPassword.php" should contain:
"""
<?php
namespace CodeGeneration\MethodExample2;
class ForgotPassword
{
}
"""
@isolated
Scenario: Generating a class outside of autoloadable paths gives a warning
Given I have started describing the "CodeGeneration/ClassExample2/Markdown" class
But I have not configured an autoloader
When I run phpspec and answer "y" when asked if I want to generate the code
Then I should see an error about the missing autoloader

View File

@@ -1,121 +0,0 @@
Feature: Developer generates a collaborator
As a Developer
I want to automate creating collaborators
In order to avoid disrupting my workflow
Scenario: Being prompted but not generating a collaborator
Given the spec file "spec/CodeGeneration/CollaboratorExample1/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\CollaboratorExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use CodeGeneration\CollaboratorExample1\Parser;
class MarkdownSpec extends ObjectBehavior
{
function it_interacts_with_a_collaborator(Parser $parser)
{
$parser->willReturn(true);
}
}
"""
And the class file "src/CodeGeneration/CollaboratorExample1/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorExample1;
class Markdown
{
}
"""
When I run phpspec and answer "n" when asked if I want to generate the code
Then I should be prompted with:
"""
Would you like me to generate an interface
`CodeGeneration\CollaboratorExample1\Parser` for you?
[Y/n]
"""
Scenario: Asking for interface to be generated
Given the spec file "spec/CodeGeneration/CollaboratorExample2/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\CollaboratorExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use CodeGeneration\CollaboratorExample2\Parser;
class MarkdownSpec extends ObjectBehavior
{
function it_interacts_with_a_collaborator(Parser $parser)
{
$parser->willReturn(true);
}
}
"""
And the class file "src/CodeGeneration/CollaboratorExample2/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorExample2;
class Markdown
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/CollaboratorExample2/Parser.php" should contain:
"""
<?php
namespace CodeGeneration\CollaboratorExample2;
interface Parser
{
}
"""
Scenario: Not being prompted when typehint is in spec namespace
Given the spec file "spec/CodeGeneration/CollaboratorExample3/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\CollaboratorExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_interacts_with_a_collaborator(Parser $parser)
{
$parser->willReturn(true);
}
}
"""
And the class file "src/CodeGeneration/CollaboratorExample3/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorExample3;
class Markdown
{
}
"""
When I run phpspec and answer "n" when asked if I want to generate the code
Then I should not be prompted for code generation

View File

@@ -1,132 +0,0 @@
Feature: Developer generates a collaborator
As a Developer
I want to automate creating collaborators
In order to avoid disrupting my workflow
Scenario: Being prompted but not generating a collaborator
Given the spec file "spec/CodeGeneration/CollaboratorExample1/Markdown1Spec.php" contains:
"""
<?php
namespace spec\CodeGeneration\CollaboratorExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use CodeGeneration\CollaboratorExample1\{Tokenizer, Parser};
class Markdown1Spec extends ObjectBehavior
{
function it_interacts_with_a_collaborator(Parser $parser)
{
$parser->willReturn(true);
}
}
"""
And the class file "src/CodeGeneration/CollaboratorExample1/Markdown1.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorExample1;
class Markdown1
{
}
"""
When I run phpspec and answer "n" when asked if I want to generate the code
Then I should be prompted with:
"""
Would you like me to generate an interface
`CodeGeneration\CollaboratorExample1\Parser` for you?
[Y/n]
"""
Scenario: Asking for interface to be generated for second collaborator in group
Given the spec file "spec/CodeGeneration/CollaboratorExample2/Markdown1Spec.php" contains:
"""
<?php
namespace spec\CodeGeneration\CollaboratorExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use CodeGeneration\CollaboratorExample2\{Tokenizer, Parser};
class Markdown1Spec extends ObjectBehavior
{
function it_interacts_with_a_collaborator(Parser $parser)
{
$parser->willReturn(true);
}
}
"""
And the class file "src/CodeGeneration/CollaboratorExample2/Markdown1.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorExample2;
class Markdown1
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/CollaboratorExample2/Parser.php" should contain:
"""
<?php
namespace CodeGeneration\CollaboratorExample2;
interface Parser
{
}
"""
Scenario: Asking for interface to be generated for the first collaborator in group
Given the spec file "spec/CodeGeneration/CollaboratorExample3/Markdown1Spec.php" contains:
"""
<?php
namespace spec\CodeGeneration\CollaboratorExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use CodeGeneration\CollaboratorExample3\{Tokenizer, Parser};
class Markdown1Spec extends ObjectBehavior
{
function it_interacts_with_a_collaborator(Tokenizer $tokenizer)
{
$tokenizer->willReturn(true);
}
}
"""
And the class file "src/CodeGeneration/CollaboratorExample3/Markdown1.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorExample3;
class Markdown1
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/CollaboratorExample3/Tokenizer.php" should contain:
"""
<?php
namespace CodeGeneration\CollaboratorExample3;
interface Tokenizer
{
}
"""

View File

@@ -1,213 +0,0 @@
Feature: Developer generates a collaborator's method
As a Developer
I want to automate creating collaborators' missing methods
In order to avoid disrupting my workflow
Scenario: Being prompted to generate a collaborator method based on typehints
Given the spec file "spec/CodeGeneration/CollaboratorMethodExample1/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\CollaboratorMethodExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use CodeGeneration\CollaboratorMethodExample1\Parser;
class MarkdownSpec extends ObjectBehavior
{
function it_interacts_with_a_collaborator(Parser $parser)
{
$parser->getSuccess()->willReturn(true);
}
}
"""
And the class file "src/CodeGeneration/CollaboratorMethodExample1/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorMethodExample1;
class Markdown
{
}
"""
And the class file "src/CodeGeneration/CollaboratorMethodExample1/Parser.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorMethodExample1;
interface Parser
{
}
"""
When I run phpspec and answer "n" when asked if I want to generate the code
Then I should be prompted with:
"""
Would you like me to generate a method signature
`CodeGeneration\CollaboratorMethodExample1\Parser::getSuccess()` for you?
[Y/n]
"""
Scenario: Asking for the method signature to be generated
Given the spec file "spec/CodeGeneration/CollaboratorMethodExample3/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\CollaboratorMethodExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use CodeGeneration\CollaboratorMethodExample3\Parser;
class MarkdownSpec extends ObjectBehavior
{
function it_interacts_with_a_collaborator(Parser $parser)
{
$parser->getSuccess()->willReturn(true);
}
}
"""
And the class file "src/CodeGeneration/CollaboratorMethodExample3/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorMethodExample3;
class Markdown
{
}
"""
And the class file "src/CodeGeneration/CollaboratorMethodExample3/Parser.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorMethodExample3;
interface Parser
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/CollaboratorMethodExample3/Parser.php" should contain:
"""
<?php
namespace CodeGeneration\CollaboratorMethodExample3;
interface Parser
{
public function getSuccess();
}
"""
Scenario: Asking for the method signature to be generated with multiple parameters
Given the spec file "spec/CodeGeneration/CollaboratorMethodExample4/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\CollaboratorMethodExample4;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use CodeGeneration\CollaboratorMethodExample4\Parser;
class MarkdownSpec extends ObjectBehavior
{
function it_interacts_with_a_collaborator(Parser $parser)
{
$parser->parse('xyz', 2)->willReturn(1);
}
}
"""
And the class file "src/CodeGeneration/CollaboratorMethodExample4/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorMethodExample4;
class Markdown
{
}
"""
And the class file "src/CodeGeneration/CollaboratorMethodExample4/Parser.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorMethodExample4;
interface Parser
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/CollaboratorMethodExample4/Parser.php" should contain:
"""
<?php
namespace CodeGeneration\CollaboratorMethodExample4;
interface Parser
{
public function parse($argument1, $argument2);
}
"""
Scenario: Not being prompted when collaborator is a class
Given the spec file "spec/CodeGeneration/CollaboratorMethodExample5/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\CollaboratorMethodExample5;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use CodeGeneration\CollaboratorMethodExample5\Parser;
class MarkdownSpec extends ObjectBehavior
{
function it_interacts_with_a_collaborator(Parser $parser)
{
$parser->getSuccess()->willReturn(true);
}
}
"""
And the class file "src/CodeGeneration/CollaboratorMethodExample5/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorMethodExample5;
class Markdown
{
}
"""
And the class file "src/CodeGeneration/CollaboratorMethodExample5/Parser.php" contains:
"""
<?php
namespace CodeGeneration\CollaboratorMethodExample5;
class Parser
{
}
"""
When I run phpspec and answer "n" when asked if I want to generate the code
Then I should not be prompted for code generation

View File

@@ -1,422 +0,0 @@
Feature: Developer generates a method
As a Developer
I want to automate creating methods
In order to avoid repetitive tasks and interruptions in development flow
Scenario: Generating a method
Given the spec file "spec/CodeGeneration/MethodExample1/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\MethodExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/CodeGeneration/MethodExample1/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\MethodExample1;
class Markdown
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/MethodExample1/Markdown.php" should contain:
"""
<?php
namespace CodeGeneration\MethodExample1;
class Markdown
{
public function toHtml($argument1)
{
// TODO: write logic here
}
}
"""
Scenario: Generating a method in a class with psr4 prefix
Given the spec file "spec/MyNamespace/PrefixSpec.php" contains:
"""
<?php
namespace spec\Behat\Tests\MyNamespace;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class PrefixSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the config file contains:
"""
suites:
behat_suite:
namespace: Behat\Tests\MyNamespace
psr4_prefix: Behat\Tests
"""
And the class file "src/MyNamespace/Prefix.php" contains:
"""
<?php
namespace Behat\Tests\MyNamespace;
class Prefix
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/MyNamespace/Prefix.php" should contain:
"""
<?php
namespace Behat\Tests\MyNamespace;
class Prefix
{
public function toHtml($argument1)
{
// TODO: write logic here
}
}
"""
Scenario: Generating a constructor in a file with existing methods places the constructor first
Given the spec file "spec/MyNamespace/ConstructorSpec.php" contains:
"""
<?php
namespace spec\MyNamespace;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ConstructorSpec extends ObjectBehavior
{
function it_should_do_something_with_a_constructor()
{
$this->beConstructedWith('anArgument');
$this->foo()->shouldReturn('bar');
}
}
"""
And the class file "src/MyNamespace/Constructor.php" contains:
"""
<?php
namespace MyNamespace;
class Constructor
{
public function foo()
{
return 'bar';
}
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/MyNamespace/Constructor.php" should contain:
"""
<?php
namespace MyNamespace;
class Constructor
{
public function __construct($argument1)
{
// TODO: write logic here
}
public function foo()
{
return 'bar';
}
}
"""
Scenario: Generating a constructor in a file with no methods
Given the spec file "spec/MyNamespace/ConstructorFirstSpec.php" contains:
"""
<?php
namespace spec\MyNamespace;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ConstructorFirstSpec extends ObjectBehavior
{
function it_should_do_something_with_a_constructor()
{
$this->beConstructedWith('anArgument');
$this->foo()->shouldReturn('bar');
}
}
"""
And the class file "src/MyNamespace/ConstructorFirst.php" contains:
"""
<?php
namespace MyNamespace;
class ConstructorFirst
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/MyNamespace/ConstructorFirst.php" should contain:
"""
<?php
namespace MyNamespace;
class ConstructorFirst
{
public function __construct($argument1)
{
// TODO: write logic here
}
}
"""
Scenario: Generating a method in a class with existing methods and new lines
Given the spec file "spec/MyNamespace/ExistingMethodSpec.php" contains:
"""
<?php
namespace spec\MyNamespace;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ExistingMethodSpec extends ObjectBehavior
{
function it_should_do_something()
{
$this->foo()->shouldReturn('bar');
}
}
"""
And the class file "src/MyNamespace/ExistingMethod.php" contains:
"""
<?php
namespace MyNamespace;
class ExistingMethod
{
public function existing()
{
return 'something';
}
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/MyNamespace/ExistingMethod.php" should contain:
"""
<?php
namespace MyNamespace;
class ExistingMethod
{
public function existing()
{
return 'something';
}
public function foo()
{
// TODO: write logic here
}
}
"""
Scenario: Generating a method in a class with existing methods containing anonymous functions
Given the spec file "spec/MyNamespace/ExistingMethodAnonymousFunctionSpec.php" contains:
"""
<?php
namespace spec\MyNamespace;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ExistingMethodAnonymousFunctionSpec extends ObjectBehavior
{
function it_should_do_something()
{
$this->foo()->shouldReturn('bar');
}
}
"""
And the class file "src/MyNamespace/ExistingMethodAnonymousFunction.php" contains:
"""
<?php
namespace MyNamespace;
class ExistingMethodAnonymousFunction
{
public function existing()
{
return function () {
return 'something';
};
}
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/MyNamespace/ExistingMethodAnonymousFunction.php" should contain:
"""
<?php
namespace MyNamespace;
class ExistingMethodAnonymousFunction
{
public function existing()
{
return function () {
return 'something';
};
}
public function foo()
{
// TODO: write logic here
}
}
"""
Scenario: Generating a constructor in a file with no methods
Given the spec file "spec/MyNamespace/CommentMethodSpec.php" contains:
"""
<?php
namespace spec\MyNamespace;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CommentMethodSpec extends ObjectBehavior
{
function it_should_do_something()
{
$this->foo()->shouldReturn('bar');
}
}
"""
And the class file "src/MyNamespace/CommentMethod.php" contains:
"""
<?php
namespace MyNamespace;
class CommentMethod
{
// this is a comment
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/MyNamespace/CommentMethod.php" should contain:
"""
<?php
namespace MyNamespace;
class CommentMethod
{
// this is a comment
public function foo()
{
// TODO: write logic here
}
}
"""
@php:~7 @isolated
Scenario: Successful generation of a method named with a reserved keyword in previous PHP versions
Given the spec file "spec/MyNamespace/KeywordMethodSpec.php" contains:
"""
<?php
namespace spec\MyNamespace;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class KeywordMethodSpec extends ObjectBehavior
{
function it_tries_to_call_wrong_method()
{
$this->throw()->shouldReturn(null);
}
}
"""
And the class file "src/MyNamespace/KeywordMethod.php" contains:
"""
<?php
namespace MyNamespace;
class KeywordMethod
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/MyNamespace/KeywordMethod.php" should contain:
"""
<?php
namespace MyNamespace;
class KeywordMethod
{
public function throw()
{
// TODO: write logic here
}
}
"""
And the suite should pass

View File

@@ -1,516 +0,0 @@
Feature: Developer generates a named constructor
As a Developer
I want to automate creating named constructor
In order to avoid repetitive tasks and interruptions in development flow
Scenario: Generating a named constructor in an empty class
Given the spec file "spec/CodeGeneration/NamedConstructor/UserSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\NamedConstructor;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class UserSpec extends ObjectBehavior
{
function it_registers_a_user()
{
$this->beConstructedThrough('register', array('firstname', 'lastname'));
$this->getFirstname()->shouldBe('firstname');
}
}
"""
And the class file "src/CodeGeneration/NamedConstructor/User.php" contains:
"""
<?php
namespace CodeGeneration\NamedConstructor;
class User
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/NamedConstructor/User.php" should contain:
"""
<?php
namespace CodeGeneration\NamedConstructor;
class User
{
public static function register($argument1, $argument2)
{
$user = new User();
// TODO: write logic here
return $user;
}
}
"""
Scenario: Generating a named constructor with more arguments than an existing constructor accepts
Given the spec file "spec/CodeGeneration/NamedConstructor/TooManyArguments/UserSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\NamedConstructor\TooManyArguments;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class UserSpec extends ObjectBehavior
{
function it_registers_a_user()
{
$this->beConstructedThrough('register', array('firstname', 'lastname'));
$this->getFirstname()->shouldBe('firstname');
}
}
"""
And the class file "src/CodeGeneration/NamedConstructor/TooManyArguments/User.php" contains:
"""
<?php
namespace CodeGeneration\NamedConstructor\TooManyArguments;
class User
{
public function __construct()
{
}
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/NamedConstructor/TooManyArguments/User.php" should contain:
"""
<?php
namespace CodeGeneration\NamedConstructor\TooManyArguments;
class User
{
public function __construct()
{
}
public static function register($argument1, $argument2)
{
throw new \BadMethodCallException("Mismatch between the number of arguments of the factory method and constructor");
}
}
"""
Scenario: Generating a named constructor with less arguments than an existing constructor accepts
Given the spec file "spec/CodeGeneration/NamedConstructor/TooFewArguments/UserSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\NamedConstructor\TooFewArguments;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class UserSpec extends ObjectBehavior
{
function it_registers_a_user()
{
$this->beConstructedThrough('register', array('firstname', 'lastname'));
$this->getFirstname()->shouldBe('firstname');
}
}
"""
And the class file "src/CodeGeneration/NamedConstructor/TooFewArguments/User.php" contains:
"""
<?php
namespace CodeGeneration\NamedConstructor\TooFewArguments;
class User
{
public function __construct($argument1, $argument2, $argument3)
{
}
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/NamedConstructor/TooFewArguments/User.php" should contain:
"""
<?php
namespace CodeGeneration\NamedConstructor\TooFewArguments;
class User
{
public function __construct($argument1, $argument2, $argument3)
{
}
public static function register($argument1, $argument2)
{
throw new \BadMethodCallException("Mismatch between the number of arguments of the factory method and constructor");
}
}
"""
Scenario: Generating a named constructor with a matching number of constructor arguments
Given the spec file "spec/CodeGeneration/NamedConstructor/EqualArguments/UserSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\NamedConstructor\EqualArguments;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class UserSpec extends ObjectBehavior
{
function it_registers_a_user()
{
$this->beConstructedThrough('register', array('firstname', 'lastname'));
$this->getFirstname()->shouldBe('firstname');
}
}
"""
And the class file "src/CodeGeneration/NamedConstructor/EqualArguments/User.php" contains:
"""
<?php
namespace CodeGeneration\NamedConstructor\EqualArguments;
class User
{
public function __construct($argument1, $argument2)
{
}
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/NamedConstructor/EqualArguments/User.php" should contain:
"""
<?php
namespace CodeGeneration\NamedConstructor\EqualArguments;
class User
{
public function __construct($argument1, $argument2)
{
}
public static function register($argument1, $argument2)
{
$user = new User($argument1, $argument2);
// TODO: write logic here
return $user;
}
}
"""
Scenario: Generating a named constructor with the correct number of required constructor arguments
Given the spec file "spec/CodeGeneration/NamedConstructor/OptionalArguments/UserSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\NamedConstructor\OptionalArguments;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class UserSpec extends ObjectBehavior
{
function it_registers_a_user()
{
$this->beConstructedThrough('register', array('firstname', 'lastname'));
$this->getFirstname()->shouldBe('firstname');
}
}
"""
And the class file "src/CodeGeneration/NamedConstructor/OptionalArguments/User.php" contains:
"""
<?php
namespace CodeGeneration\NamedConstructor\OptionalArguments;
class User
{
public function __construct($argument1, $argument2, $argument3 = 'optional')
{
}
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/NamedConstructor/OptionalArguments/User.php" should contain:
"""
<?php
namespace CodeGeneration\NamedConstructor\OptionalArguments;
class User
{
public function __construct($argument1, $argument2, $argument3 = 'optional')
{
}
public static function register($argument1, $argument2)
{
$user = new User($argument1, $argument2);
// TODO: write logic here
return $user;
}
}
"""
Scenario: Generating a named constructor using beConstructedThrough*
Given the spec file "spec/CodeGeneration/ShortSyntax/UserSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\ShortSyntax;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class UserSpec extends ObjectBehavior
{
function it_registers_a_user()
{
$this->beConstructedThroughRegister('firstname', 'lastname');
$this->getFirstname()->shouldBe('firstname');
}
}
"""
And the class file "src/CodeGeneration/ShortSyntax/User.php" contains:
"""
<?php
namespace CodeGeneration\ShortSyntax;
class User
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/ShortSyntax/User.php" should contain:
"""
<?php
namespace CodeGeneration\ShortSyntax;
class User
{
public static function register($argument1, $argument2)
{
$user = new User();
// TODO: write logic here
return $user;
}
}
"""
Scenario: Generating a named constructor using beConstructed*
Given the spec file "spec/CodeGeneration/ShortSyntax2/UserSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\ShortSyntax2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class UserSpec extends ObjectBehavior
{
function it_registers_a_user()
{
$this->beConstructedFromString('firstname', 'lastname');
$this->getFirstname()->shouldBe('firstname');
}
}
"""
And the class file "src/CodeGeneration/ShortSyntax2/User.php" contains:
"""
<?php
namespace CodeGeneration\ShortSyntax2;
class User
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/ShortSyntax2/User.php" should contain:
"""
<?php
namespace CodeGeneration\ShortSyntax2;
class User
{
public static function fromString($argument1, $argument2)
{
$user = new User();
// TODO: write logic here
return $user;
}
}
"""
Scenario: Generating the private constructor
Given the spec file "spec/CodeGeneration/PrivateConstructor/UserSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\PrivateConstructor;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class UserSpec extends ObjectBehavior
{
function it_registers_a_user()
{
$this->beConstructedThrough('register', array('firstname', 'lastname'));
$this->getFirstname()->shouldBe('firstname');
}
}
"""
And the class file "src/CodeGeneration/PrivateConstructor/User.php" contains:
"""
<?php
namespace CodeGeneration\PrivateConstructor;
class User
{
}
"""
When I run phpspec and answer "y" to both questions
Then the class in "src/CodeGeneration/PrivateConstructor/User.php" should contain:
"""
<?php
namespace CodeGeneration\PrivateConstructor;
class User
{
private function __construct()
{
}
public static function register($argument1, $argument2)
{
$user = new User();
// TODO: write logic here
return $user;
}
}
"""
Scenario: Generating multiple named constructors at once
Given the spec file "spec/CodeGeneration/PrivateConstructor/AgeSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\PrivateConstructor;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class AgeSpec extends ObjectBehavior
{
function it_is_constructed_from_string()
{
$this->beConstructedFromString('30');
$this->getAge()->shouldReturn(30);
}
function it_is_constructed_from_integer()
{
$this->beConstructedFromInteger(30);
$this->getAge()->shouldReturn(30);
}
}
"""
And the class file "src/CodeGeneration/PrivateConstructor/Age.php" contains:
"""
<?php
namespace CodeGeneration\PrivateConstructor;
class Age
{
}
"""
When I run phpspec and answer "y" to the three questions
Then I should not be prompted for more questions
And the class in "src/CodeGeneration/PrivateConstructor/Age.php" should contain:
"""
<?php
namespace CodeGeneration\PrivateConstructor;
class Age
{
private function __construct()
{
}
public static function fromInteger($argument1)
{
$age = new Age();
// TODO: write logic here
return $age;
}
public static function fromString($argument1)
{
$age = new Age();
// TODO: write logic here
return $age;
}
}
"""

View File

@@ -1,323 +0,0 @@
Feature: Developer generates a method returning a constant
As a Developer
I want to automate creating methods that return constants
In order to avoid having to manually write the code
Scenario: Generating a scalar return type when method exists
Given the spec file "spec/CodeGeneration/ConstantExample1/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\ConstantExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/CodeGeneration/ConstantExample1/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\ConstantExample1;
class Markdown
{
public function toHtml($argument1)
{}
}
"""
When I run phpspec with the option "fake" and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/ConstantExample1/Markdown.php" should contain:
"""
<?php
namespace CodeGeneration\ConstantExample1;
class Markdown
{
public function toHtml($argument1)
{
return '<p>Hi, there</p>';
}
}
"""
Scenario: Generating a scalar return type when method contains comments
Given the spec file "spec/CodeGeneration/ConstantExample2/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\ConstantExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/CodeGeneration/ConstantExample2/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\ConstantExample2;
class Markdown
{
public function toHtml($argument1)
{
// TODO: Add Logic here
/*
This code is inactive
*/
}
}
"""
When I run phpspec with the option "fake" and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/ConstantExample2/Markdown.php" should contain:
"""
<?php
namespace CodeGeneration\ConstantExample2;
class Markdown
{
public function toHtml($argument1)
{
return '<p>Hi, there</p>';
}
}
"""
Scenario: No prompt when method contains code
Given the spec file "spec/CodeGeneration/ConstantExample3/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\ConstantExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/CodeGeneration/ConstantExample3/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\ConstantExample3;
class Markdown
{
public function toHtml($argument1)
{
$foo = 'bar';
}
}
"""
When I run phpspec interactively with the "fake" option
Then I should not be prompted for code generation
Scenario: No prompt when examples contradict code
Given the spec file "spec/CodeGeneration/ConstantExample4/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\ConstantExample4;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
function it_converts_more_plain_text_to_html_paragraphs()
{
$this->toHtml('Hello, there')->shouldReturn('<p>Hello, there</p>');
}
}
"""
And the class file "src/CodeGeneration/ConstantExample4/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\ConstantExample4;
class Markdown
{
public function toHtml($argument1)
{
}
}
"""
When I run phpspec interactively with the "fake" option
Then I should not be prompted for code generation
Scenario: No prompt when CLI option is not used
Given the spec file "spec/CodeGeneration/ConstantExample5/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\ConstantExample5;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/CodeGeneration/ConstantExample5/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\ConstantExample5;
class Markdown
{
public function toHtml($argument1)
{
}
}
"""
When I run phpspec interactively
Then I should not be prompted for code generation
Scenario: Prompted when CLI option is not used but config flag is set
Given the spec file "spec/CodeGeneration/ConstantExample6/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\ConstantExample6;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/CodeGeneration/ConstantExample6/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\ConstantExample6;
class Markdown
{
public function toHtml($argument1)
{
}
}
"""
And the config file contains:
"""
fake: true
"""
When I run phpspec interactively
Then I should be prompted for code generation
Scenario: Generating a scalar return type when method is in trait
Given the spec file "spec/CodeGeneration/ConstantExample7/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\ConstantExample7;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the trait file "src/CodeGeneration/ConstantExample7/MarkdownTrait.php" contains:
"""
<?php
namespace CodeGeneration\ConstantExample7;
trait MarkdownTrait
{
public function toHtml($argument1)
{
}
}
"""
And the class file "src/CodeGeneration/ConstantExample7/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\ConstantExample7;
class Markdown
{
use MarkdownTrait;
}
"""
When I run phpspec with the option "fake" and answer "y" when asked if I want to generate the code
Then the class in "src/CodeGeneration/ConstantExample7/MarkdownTrait.php" should contain:
"""
<?php
namespace CodeGeneration\ConstantExample7;
trait MarkdownTrait
{
public function toHtml($argument1)
{
return '<p>Hi, there</p>';
}
}
"""

View File

@@ -1,194 +0,0 @@
Feature: Developer generates a spec
As a Developer
I want to automate creating specs
In order to avoid repetitive tasks and interruptions in development flow
Scenario: Generating a spec
When I start describing the "CodeGeneration/SpecExample1/Markdown" class
Then a new spec should be generated in the "spec/CodeGeneration/SpecExample1/MarkdownSpec.php":
"""
<?php
namespace spec\CodeGeneration\SpecExample1;
use CodeGeneration\SpecExample1\Markdown;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(Markdown::class);
}
}
"""
@issue1210
Scenario: Generating a spec with alphabetised imports
When I start describing the "Zyzzyva/SpecExample/Example" class
Then a new spec should be generated in the "spec/Zyzzyva/SpecExample/ExampleSpec.php":
"""
<?php
namespace spec\Zyzzyva\SpecExample;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Zyzzyva\SpecExample\Example;
class ExampleSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(Example::class);
}
}
"""
@issue687
Scenario: Generating a spec with the same namespace as the source
Given the config file contains:
"""
suites:
code_generator_suite:
namespace: CodeGeneration\SpecExample2
spec_path: spec/
spec_prefix: ''
"""
When I start describing the "CodeGeneration/SpecExample2/Markdown" class
Then a new spec should be generated in the "spec/CodeGeneration/SpecExample2/MarkdownSpec.php":
"""
<?php
namespace CodeGeneration\SpecExample2;
use CodeGeneration\SpecExample2\Markdown;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(Markdown::class);
}
}
"""
@issue687
Scenario: Generating a spec with the same namespace as the source even with psr4 prefix on src
Given the config file contains:
"""
suites:
code_generator_suite:
namespace: CodeGeneration\SpecExample2
psr4_prefix: CodeGeneration
spec_path: spec/
spec_prefix: ''
"""
When I start describing the "CodeGeneration/SpecExample2/Markdown" class
Then a new spec should be generated in the "spec/SpecExample2/MarkdownSpec.php":
"""
<?php
namespace CodeGeneration\SpecExample2;
use CodeGeneration\SpecExample2\Markdown;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(Markdown::class);
}
}
"""
@issue127
Scenario: Generating a spec with PSR0 must convert classname underscores to directory separator
When I start describing the "CodeGeneration/SpecExample1/Text_Markdown" class
Then a new spec should be generated in the "spec/CodeGeneration/SpecExample1/Text/MarkdownSpec.php":
"""
<?php
namespace spec\CodeGeneration\SpecExample1;
use CodeGeneration\SpecExample1\Text_Markdown;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class Text_MarkdownSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(Text_Markdown::class);
}
}
"""
@issue127
Scenario: Generating a spec with PSR0 must not convert namespace underscores to directory separator
When I start describing the "CodeGeneration/Spec_Example2/Text_Markdown" class
Then a new spec should be generated in the "spec/CodeGeneration/Spec_Example2/Text/MarkdownSpec.php":
"""
<?php
namespace spec\CodeGeneration\Spec_Example2;
use CodeGeneration\Spec_Example2\Text_Markdown;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class Text_MarkdownSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(Text_Markdown::class);
}
}
"""
Scenario: Generating a spec for a class with psr4 prefix
Given the config file contains:
"""
suites:
behat_suite:
namespace: Behat\CodeGeneration
psr4_prefix: Behat\CodeGeneration
"""
When I start describing the "Behat/CodeGeneration/Markdown" class
Then a new spec should be generated in the "spec/MarkdownSpec.php":
"""
<?php
namespace spec\Behat\CodeGeneration;
use Behat\CodeGeneration\Markdown;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(Markdown::class);
}
}
"""
Scenario: Generating a spec for class with namespace containing reserved keyword
Given I have started describing the "Namespace/ClassExample1/Markdown" class
Then I should an error about invalid class name "Namespace\ClassExample1\Markdown" to generate spec for
And there should be no file "spec/Namespace/ClassExample1/MarkdownSpec.php"

View File

@@ -1,62 +0,0 @@
Feature: Developer generates a class
As a Developer
I want the tests to automatically rerun after code generation events
In order to avoid repetitive tasks and interruptions in development flow
@smoke
Scenario: Rerun after class generation
Given I have started describing the "CodeGeneration/RerunExample1/Markdown" class
When I run phpspec and answer "y" when asked if I want to generate the code
Then the tests should be rerun
Scenario: Rerun after method generation
Given the spec file "spec/CodeGeneration/RerunExample2/MarkdownSpec.php" contains:
"""
<?php
namespace spec\CodeGeneration\RerunExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/CodeGeneration/RerunExample2/Markdown.php" contains:
"""
<?php
namespace CodeGeneration\RerunExample2;
class Markdown
{
}
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the tests should be rerun
Scenario: No rerun if code generation is off
Given I have started describing the "CodeGeneration/RerunExample3/Markdown" class
When I run phpspec non interactively
Then the tests should not be rerun
Scenario: No rerun if rerun flag is passed
Given I have started describing the "CodeGeneration/RerunExample4/Markdown" class
When I run phpspec with the option "no-rerun" and I answer "y" when asked if I want to generate the code
Then the tests should not be rerun
Scenario: No rerun if rerun flag is passed
Given I have started describing the "CodeGeneration/RerunExample5/Markdown" class
And the config file contains:
"""
rerun: false
"""
When I run phpspec and answer "y" when asked if I want to generate the code
Then the tests should not be rerun

View File

@@ -1,59 +0,0 @@
Feature: Composer can be leveraged to create suites
As a Developer
I need the autoload rules I defined to be reused by phpspec
So I may enable the Composer namespace provider and get one suite per autoload rule
Scenario: Using composer as namespace_provider in a PSR0 namespace
Given the config file located in "." contains:
"""
composer_suite_detection: true
"""
And there is a PSR-0 namespace "Andromeda\N4S4Arm\" configured for the "src" folder
When I start describing the "Andromeda/N4S4Arm/Gazorpazorp" class with the "phpspec.yml" custom config
Then a new spec should be generated in the "spec/Andromeda/N4S4Arm/GazorpazorpSpec.php":
"""
<?php
namespace spec\Andromeda\N4S4Arm;
use Andromeda\N4S4Arm\Gazorpazorp;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class GazorpazorpSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(Gazorpazorp::class);
}
}
"""
Scenario: Using composer as namespace_provider in a PSR4 namespace
Given the config file located in "." contains:
"""
composer_suite_detection : true
"""
And there is a PSR-4 namespace "MilkyWay\OrionCygnusArm\" configured for the "src" folder
When I start describing the "MilkyWay/OrionCygnusArm/LocalBubble" class with the "phpspec.yml" custom config
Then a new spec should be generated in the "spec/LocalBubbleSpec.php":
"""
<?php
namespace spec\MilkyWay\OrionCygnusArm;
use MilkyWay\OrionCygnusArm\LocalBubble;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class LocalBubbleSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(LocalBubble::class);
}
}
"""

View File

@@ -1,104 +0,0 @@
Feature: Config directory can be used in spec and src paths
As a Developer
I need a path variable representing the config directory
So I may use the directory of the config in spec and src paths and thus be able to run tests regardless of the current working directory
Scenario: Using %paths.config% variable in spec_path
Given the config file located in "Awesome" contains:
"""
suites:
behat_suite:
namespace: MilkyWay\OrionCygnusArm
spec_path: "%paths.config%"
"""
When I start describing the "MilkyWay/OrionCygnusArm/LocalBubble" class with the "Awesome/phpspec.yml" custom config
Then a new spec should be generated in the "Awesome/spec/MilkyWay/OrionCygnusArm/LocalBubbleSpec.php":
"""
<?php
namespace spec\MilkyWay\OrionCygnusArm;
use MilkyWay\OrionCygnusArm\LocalBubble;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class LocalBubbleSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(LocalBubble::class);
}
}
"""
Scenario: Not using %paths.config% variable in spec_path
Given the config file located in "Awesome" contains:
"""
suites:
behat_suite:
namespace: MilkyWay\OrionCygnusArm
"""
When I start describing the "MilkyWay/OrionCygnusArm/ButterflyCluster" class with the "Awesome/phpspec.yml" custom config
Then a new spec should be generated in the "spec/MilkyWay/OrionCygnusArm/ButterflyClusterSpec.php":
"""
<?php
namespace spec\MilkyWay\OrionCygnusArm;
use MilkyWay\OrionCygnusArm\ButterflyCluster;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ButterflyClusterSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(ButterflyCluster::class);
}
}
"""
Scenario: Using %paths.config% variable in src_path
Given the config file located in "Awesome" contains:
"""
suites:
behat_suite:
namespace: MilkyWay\OrionCygnusArm
src_path: "%paths.config%/src"
"""
And I have started describing the "MilkyWay/OrionCygnusArm/Pleiades/Alcyone" class with the "Awesome/phpspec.yml" custom config
When I run phpspec with the "Awesome/phpspec.yml" custom config and answer "y" when asked if I want to generate the code
Then a new class should be generated in the "Awesome/src/MilkyWay/OrionCygnusArm/Pleiades/Alcyone.php":
"""
<?php
namespace MilkyWay\OrionCygnusArm\Pleiades;
class Alcyone
{
}
"""
Scenario: Not using %paths.config% variable in src_path
Given the config file located in "Awesome" contains:
"""
suites:
behat_suite:
namespace: MilkyWay\OrionCygnusArm
"""
And I have started describing the "MilkyWay/OrionCygnusArm/BehiveCluster" class with the "Awesome/phpspec.yml" custom config
When I run phpspec with the "Awesome/phpspec.yml" custom config and answer "y" when asked if I want to generate the code
Then a new class should be generated in the "src/MilkyWay/OrionCygnusArm/BehiveCluster.php":
"""
<?php
namespace MilkyWay\OrionCygnusArm;
class BehiveCluster
{
}
"""

View File

@@ -1,102 +0,0 @@
Feature: Developer enables extensions
As a Developer
I want to enable and configure extensions
In order to customize or add features to phpspec behavior
Scenario: Adding parametrized extensions with correct config
Given the class file "src/Configuration/Extension2.php" contains:
"""
<?php
namespace Configuration;
class Extension2 implements \PhpSpec\Extension
{
public function load(\PhpSpec\ServiceContainer $container, array $params)
{
throw new \Exception(get_class().' enabled'. print_r($params, true));
}
}
"""
And the config file contains:
"""
extensions:
Configuration\Extension2: ~
Configuration\Extension2: [testParam]
"""
When I run phpspec
Then I should see "Extension2 enabled"
And I should see "testParam"
Scenario: Adding parametrized extensions with incorrect config
Given the class file "src/Configuration/Extension3.php" contains:
"""
<?php
namespace Configuration;
class Extension3 implements \PhpSpec\Extension
{
public function load(\PhpSpec\ServiceContainer $container, array $params)
{
throw new \Exception(get_class().' enabled'. print_r($params, true));
}
}
"""
And the config file contains:
"""
extensions:
Configuration\Extension3: test
"""
When I run phpspec
Then I should see "Extension configuration must be an array or null"
Scenario: Adding a non existent class as extension
Given the class file "src/Configuration/Extension4.php" contains:
"""
<?php
namespace Configuration;
class NOPE implements \PhpSpec\Extension
{
public function load(\PhpSpec\ServiceContainer $container, array $params)
{
throw new \Exception(get_class().' enabled'. print_r($params, true));
}
}
"""
And the config file contains:
"""
extensions:
Configuration\Extension4: ~
"""
When I run phpspec
Then I should see "Extension class `Configuration\Extension4` does not exist"
Scenario: Adding parametrized extensions without parameters
Given the class file "src/Configuration/Extension4.php" contains:
"""
<?php
namespace Configuration;
class Extension4 implements \PhpSpec\Extension
{
public function load(\PhpSpec\ServiceContainer $container, array $params)
{
throw new \Exception(get_class().' enabled'. print_r($params, true));
}
}
"""
And the config file contains:
"""
extensions:
Configuration\Extension4: ~
"""
When I run phpspec
Then I should see "Extension4 enabled"

View File

@@ -1,436 +0,0 @@
Feature: Developer specifies object construction
As a Developer
I want to describe how objects are constructed
In order to be able to test objects with non-trivial construction
Scenario: Class is initialised using a constructor
Given the spec file "spec/Runner/ConstructorExample1/ClassWithConstructorSpec.php" contains:
"""
<?php
namespace spec\Runner\ConstructorExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithConstructorSpec extends ObjectBehavior
{
function let(\DateTime $date)
{
$this->beConstructedWith($date);
}
function it_is_initializable()
{
$this->shouldHaveType('Runner\ConstructorExample1\ClassWithConstructor');
}
}
"""
And the class file "src/Runner/ConstructorExample1/ClassWithConstructor.php" contains:
"""
<?php
namespace Runner\ConstructorExample1;
class ClassWithConstructor
{
private $date;
public function __construct(\DateTime $date)
{
$this->date = $date;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Class is initialized using a static factory method and a collaborator as argument
Given the spec file "spec/Runner/ConstructorExample2/ClassWithStaticFactoryMethodSpec.php" contains:
"""
<?php
namespace spec\Runner\ConstructorExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithStaticFactoryMethodSpec extends ObjectBehavior
{
function let(\DateTime $date)
{
$this->beConstructedThrough('getInstance', array($date));
}
function it_is_initializable()
{
$this->shouldHaveType('Runner\ConstructorExample2\ClassWithStaticFactoryMethod');
}
}
"""
And the class file "src/Runner/ConstructorExample2/ClassWithStaticFactoryMethod.php" contains:
"""
<?php
namespace Runner\ConstructorExample2;
class ClassWithStaticFactoryMethod
{
private $date;
public static function getInstance(\DateTime $date)
{
return new ClassWithStaticFactoryMethod($date);
}
private function __construct(\DateTime $date)
{
$this->date = $date;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Default static constructor parameter is overridden in example
Given the spec file "spec/Runner/ConstructorExample3/ClassWithConstructorSpec.php" contains:
"""
<?php
namespace spec\Runner\ConstructorExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithConstructorSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedWith('foo');
}
function it_is_initializable()
{
$this->beConstructedWith('bar');
$this->getType()->shouldReturn('bar');
}
}
"""
And the class file "src/Runner/ConstructorExample3/ClassWithConstructor.php" contains:
"""
<?php
namespace Runner\ConstructorExample3;
class ClassWithConstructor
{
private $type;
public function __construct($type)
{
$this->type = $type;
}
public function getType()
{
return $this->type;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Static constructor is overridden in example
Given the spec file "spec/Runner/ConstructorExample4/ClassWithStaticFactoryMethodSpec.php" contains:
"""
<?php
namespace spec\Runner\ConstructorExample4;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithStaticFactoryMethodSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedThrough('getInstanceOfType', array('foo'));
}
function it_is_initializable()
{
$this->beConstructedThrough('getInstanceOfType', array('bar'));
$this->getType()->shouldReturn('bar');
}
}
"""
And the class file "src/Runner/ConstructorExample4/ClassWithStaticFactoryMethod.php" contains:
"""
<?php
namespace Runner\ConstructorExample4;
class ClassWithStaticFactoryMethod
{
private $type;
private function __construct($type)
{
$this->type = $type;
}
public static function getInstanceOfType($type)
{
return new self($type);
}
public function getType()
{
return $this->type;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Static constructor set in example used instead factory method set in let
Given the spec file "spec/Runner/ConstructorExample7/ClassWithStaticFactoryMethodAndConstructorSpec.php" contains:
"""
<?php
namespace spec\Runner\ConstructorExample7;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithStaticFactoryMethodAndConstructorSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedThrough('getInstanceOfType', array('foo'));
}
function it_is_initializable()
{
$this->beConstructedWith('bar');
$this->getType()->shouldReturn('bar');
$this->wasConstructedWith()->shouldReturn('__construct');
}
}
"""
And the class file "src/Runner/ConstructorExample7/ClassWithStaticFactoryMethodAndConstructor.php" contains:
"""
<?php
namespace Runner\ConstructorExample7;
class ClassWithStaticFactoryMethodAndConstructor
{
private $type;
private $wasConstructedWith;
public function __construct($type)
{
$this->type = $type;
$this->wasConstructedWith = '__construct';
}
public static function getInstanceOfType($type)
{
$created = new self($type);
$created->wasConstructedWith = 'getInstanceOfType';
return $created;
}
public function getType()
{
return $this->type;
}
public function wasConstructedWith()
{
return $this->wasConstructedWith;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Factory method set in example used instead of constructor set in let
Given the spec file "spec/Runner/ConstructorExample8/ClassWithStaticFactoryMethodAndConstructorSpec.php" contains:
"""
<?php
namespace spec\Runner\ConstructorExample8;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithStaticFactoryMethodAndConstructorSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedWith('bar');
$this->beConstructedThrough('getInstanceOfType', array('foo'));
}
function it_is_initializable()
{
$this->beConstructedThrough('getInstanceOfType', array('foo'));
$this->getType()->shouldReturn('foo');
$this->wasConstructedWith()->shouldReturn('getInstanceOfType');
}
}
"""
And the class file "src/Runner/ConstructorExample8/ClassWithStaticFactoryMethodAndConstructor.php" contains:
"""
<?php
namespace Runner\ConstructorExample8;
class ClassWithStaticFactoryMethodAndConstructor
{
private $type;
private $wasConstructedWith;
public function __construct($type)
{
$this->type = $type;
$this->wasConstructedWith = '__construct';
}
public static function getInstanceOfType($type)
{
$created = new self($type);
$created->wasConstructedWith = 'getInstanceOfType';
return $created;
}
public function getType()
{
return $this->type;
}
public function wasConstructedWith()
{
return $this->wasConstructedWith;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Developer cannot redefine constructor parameters if object is already instantiated
Given the spec file "spec/Runner/ConstructorExample9/ClassConstructorSpec.php" contains:
"""
<?php
namespace spec\Runner\ConstructorExample9;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassConstructorSpec extends ObjectBehavior
{
function it_behaves_differently_depending_on_type()
{
$this->beConstructedWith('foo');
$this->getType()->shouldReturn('foo');
$this->beConstructedWith('bar');
$this->getType()->shouldReturn('bar');
}
}
"""
And the class file "src/Runner/ConstructorExample9/ClassConstructor.php" contains:
"""
<?php
namespace Runner\ConstructorExample9;
class ClassConstructor
{
public function __construct($type)
{
$this->type = $type;
}
public function getType()
{
return $this->type;
}
}
"""
When I run phpspec
Then I should see "you can not change object construction method when it is already instantiated"
Scenario: Developer cannot redefine factory method if object is already instantiated
Given the spec file "spec/Runner/ConstructorExample10/ClassWithFactoryMethodSpec.php" contains:
"""
<?php
namespace spec\Runner\ConstructorExample10;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithFactoryMethodSpec extends ObjectBehavior
{
function it_behaves_differently_depending_on_type()
{
$this->beConstructedThrough('createFoo');
$this->getType()->shouldReturn('foo');
$this->beConstructedWith('createBar');
$this->getType()->shouldReturn('bar');
}
}
"""
And the class file "src/Runner/ConstructorExample10/ClassWithFactoryMethod.php" contains:
"""
<?php
namespace Runner\ConstructorExample10;
class ClassWithFactoryMethod
{
private function __construct($type)
{
$this->type = $type;
}
public function getType()
{
return $this->type;
}
public static function createFoo()
{
return new self('foo');
}
public static function createBar()
{
return new self('bar');
}
}
"""
When I run phpspec
Then I should see "you can not change object construction method when it is already instantiated"

View File

@@ -1,46 +0,0 @@
Feature: Developer has defined a supporting class and should not see a silent error
As a Developer
I want to see if my supporting class is properly defined
So that I can better trace where my changes caused a fatal error
@isolated
Scenario: Spec attempts to run a class with an undeclared interface, outputs to stdout
Given the spec file "spec/SomethingSpec.php" contains:
"""
<?php
namespace spec;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class SomethingSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Something');
}
}
class ExampleClass implements NotDefinedInterface
{
}
"""
And the class file "src/Something.php" contains:
"""
<?php
namespace spec;
class Something
{
public function __construct($param)
{
if ($param == 'throw') {
throw new \Exception();
}
}
}
"""
When I run phpspec
Then I should see "Fatal error happened while executing the following"

View File

@@ -1,81 +0,0 @@
Feature: Developer is shown a parse error
As a Developer
I want to know if a parse error was thrown
So that I can know that I can handle pass errors
Scenario: Parse error in class
Given the spec file "spec/Message/Fatal/ParseSpec.php" contains:
"""
<?php
namespace spec\Message\Fatal;
use Parse;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ParseSpec extends ObjectBehavior
{
function it_throws_a_syntax_error()
{
$this->cool();
}
}
"""
And the spec file "src/Message/Fatal/Parse.php" contains:
"""
<?php
namespace Message\Parse;
class Par se
{
public function cool()
{
return true;
}
}
"""
When I run phpspec
Then I should see "1 broken"
Scenario: Parse error in spec
Given the spec file "spec/Message/Fatal2/ParseSpec.php" contains:
"""
<?php
namespace spec\Message\Fatal2;
use Parse;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ParseSpec extends ObjectBehavior
{
function it_thro ws_a_syntax_error()
{
$this->cool();
}
}
"""
And the spec file "src/Message/Fatal2/Parse.php" contains:
"""
<?php
namespace Message\Parse2;
class Parse
{
public function cool()
{
return true;
}
}
"""
When I run phpspec
Then I should see "1 broken"
And I should see "syntax error"

View File

@@ -1,87 +0,0 @@
Feature: Developer is shown runtime errors
As a developer
To debug fatal errors better
I should be shown errors but the rest of the suite should run
Scenario: Runtime error in class being specified
Given the spec file "spec/Message/Fatal/RuntimeSpec.php" contains:
"""
<?php
namespace spec\Message\Fatal;
use PhpSpec\ObjectBehavior;
class RuntimeSpec extends ObjectBehavior
{
function it_breaks()
{
$this->broken();
}
function it_passes()
{
$this->passing();
}
}
"""
And the class file "src/Message/Fatal/Runtime.php" contains:
"""
<?php
namespace Message\Fatal;
class Runtime
{
public function broken()
{
foo();
}
public function passing()
{
}
}
"""
When I run phpspec
Then I should see "1 passed, 1 broken"
Scenario: Runtime error in spec
Given the spec file "spec/Message/Fatal2/RuntimeSpec.php" contains:
"""
<?php
namespace spec\Message\Fatal2;
use PhpSpec\ObjectBehavior;
class RuntimeSpec extends ObjectBehavior
{
function it_breaks()
{
foo();
}
function it_passes()
{
$this->passing();
}
}
"""
And the class file "src/Message/Fatal2/Runtime.php" contains:
"""
<?php
namespace Message\Fatal2;
class Runtime
{
public function passing()
{
}
}
"""
When I run phpspec
Then I should see "1 passed, 1 broken"

View File

@@ -1,48 +0,0 @@
Feature: Developer specifies exception behaviour
As a Developer
I want to be able to specify the exceptions by SUS will throw
In order to drive the design of my exception handling
Scenario: Throwing an exception during construction when beConstructedWith specifies valid parameters
Given the spec file "spec/Runner/ExceptionExample3/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\ExceptionExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedWith('nothrow');
}
function it_throws_an_exception_using_magic_syntax()
{
$this->shouldThrow('Exception')->during__construct('throw');
}
}
"""
And the class file "src/Runner/ExceptionExample3/Markdown.php" contains:
"""
<?php
namespace Runner\ExceptionExample3;
class Markdown
{
public function __construct($param)
{
if ($param == 'throw') {
throw new \Exception();
}
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,61 +0,0 @@
Feature: Developer uses bootstrap config key in any place
As a Developer
I want to place configuration options at any part of the config file
Scenario: Extension does not break container parameters
Given the config file contains:
"""
extensions:
Example1\PhpSpec\LoadsConsoleIoExtension\Extension: ~
bootstrap: NotExisting.php
"""
And the class file "src/Example1/PhpSpec/LoadsConsoleIoExtension/Extension.php" contains:
"""
<?php
namespace Example1\PhpSpec\LoadsConsoleIoExtension;
use PhpSpec\Extension as PhpSpecExtension;
use PhpSpec\ServiceContainer;
class Extension implements PhpSpecExtension
{
public function load(ServiceContainer $container, array $params)
{
$container->get('console.io');
}
}
"""
And the spec file "spec/Example1/TestConfigSpec.php" contains:
"""
<?php
namespace spec\Example1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class TestConfigSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Example1\TestConfig');
}
}
"""
And the class file "src/Example1/TestConfig.php" contains:
"""
<?php
namespace Example1;
class TestConfig
{
}
"""
When I run phpspec
Then I should see "Bootstrap file 'NotExisting.php' does not exist"

View File

@@ -1,247 +0,0 @@
Feature: Developer uses extension
As a Developer
I want to use my extension
Scenario: Extension can provide a new matcher
Given the config file contains:
"""
extensions:
Example1\PhpSpec\MatcherExtension\Extension: ~
"""
And the class file "src/Example1/PhpSpec/MatcherExtension/Extension.php" contains:
"""
<?php
namespace Example1\PhpSpec\MatcherExtension;
use PhpSpec\Extension as PhpSpecExtension;
use PhpSpec\ServiceContainer;
class Extension implements PhpSpecExtension
{
public function load(ServiceContainer $container, array $params)
{
$container->define('matchers.seven', function (ServiceContainer $c) {
return new BeSevenMatcher($c->get('formatter.presenter'));
}, ['matchers']);
}
}
"""
And the class file "src/Example1/PhpSpec/MatcherExtension/BeSevenMatcher.php" contains:
"""
<?php
namespace Example1\PhpSpec\MatcherExtension;
use PhpSpec\Formatter\Presenter\Presenter;
use PhpSpec\Exception\Example\FailureException;
use PhpSpec\Matcher\BasicMatcher;
class BeSevenMatcher extends BasicMatcher
{
/**
* @var \PhpSpec\Formatter\Presenter\Presenter
*/
private $presenter;
/**
* @param Presenter $presenter
*/
public function __construct(Presenter $presenter)
{
$this->presenter = $presenter;
}
/**
* @param string $name
* @param mixed $subject
* @param array $arguments
*
* @return bool
*/
public function supports(string $name, $subject, array $arguments): bool
{
return 'beSeven' === $name
&& is_int($subject)
&& 0 == count($arguments)
;
}
/**
* @param mixed $subject
* @param array $arguments
*
* @return bool
*/
protected function matches($subject, array $arguments): bool
{
return ($subject === 7);
}
/**
* @param string $name
* @param mixed $subject
* @param array $arguments
*
* @return FailureException
*/
protected function getFailureException(string $name, $subject, array $arguments): FailureException
{
return new FailureException(sprintf(
'Seven expected %s to be 7, but it is not.',
$this->presenter->presentString($subject)
));
}
/**
* @param string $name
* @param mixed $subject
* @param array $arguments
*
* @return FailureException
*/
protected function getNegativeFailureException(string $name, $subject, array $arguments): FailureException
{
return new FailureException(sprintf(
'Seven did not expect %s to 7, but it is.',
$this->presenter->presentString($subject)
));
}
}
"""
And the spec file "spec/Example1/DummySpec.php" contains:
"""
<?php
namespace spec\Example1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class DummySpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Example1\Dummy');
}
function it_should_succeed_in_using_new_matcher()
{
$this->getSeven()->shouldBeSeven();
$this->getFive()->shouldNotBeSeven();
}
}
"""
And the class file "src/Example1/Dummy.php" contains:
"""
<?php
namespace Example1;
class Dummy
{
public function getSeven()
{
return 7;
}
public function getFive()
{
return 5;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Using an extension with an event listener
Given the config file contains:
"""
extensions:
Example2\PhpSpec\Extensions\EventSubscriberExtension: ~
"""
And the class file "src/Example2/PhpSpec/Extensions/EventSubscriberExtension.php" contains:
"""
<?php
namespace Example2\PhpSpec\Extensions;
use PhpSpec\Extension as PhpSpecExtension;
use PhpSpec\ServiceContainer;
class EventSubscriberExtension implements PhpSpecExtension
{
public function load(ServiceContainer $compositeContainer, array $params)
{
$io = $compositeContainer->get('console.io');
$eventDispatcher = $compositeContainer->get('event_dispatcher');
$eventDispatcher->addSubscriber(new MyEventSubscriber($io));
}
}
"""
And the class file "src/Example2/PhpSpec/Extensions/MyEventSubscriber.php" contains:
"""
<?php
namespace Example2\PhpSpec\Extensions;
use PhpSpec\Event\SuiteEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MyEventSubscriber implements EventSubscriberInterface
{
private $io;
public function __construct($io)
{
$this->io = $io;
}
public static function getSubscribedEvents()
{
return ['afterSuite' => ['afterSuite', 11]];
}
public function afterSuite(SuiteEvent $event)
{
$this->io->writeln('Omg suite ran! :-)');
}
}
"""
And the spec file "spec/Example2/DummySpec.php" contains:
"""
<?php
namespace spec\Example2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Example2\Dummy;
class DummySpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType(Dummy::class);
}
}
"""
And the class file "src/Example2/Dummy.php" contains:
"""
<?php
namespace Example2;
class Dummy
{
}
"""
When I run phpspec
Then I should see "Omg suite ran! :-)"

View File

@@ -1,647 +0,0 @@
Feature: Developer is shown diffs
In order to debug failing tests
As a developer
I should be shown a detailed diff when expected values do not match
Scenario: String diffing
Given the spec file "spec/Diffs/DiffExample1/ClassWithStringsSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithStringsSpec extends ObjectBehavior
{
function it_is_equal()
{
$this->getString()->shouldReturn('foo');
}
}
"""
And the class file "src/Diffs/DiffExample1/ClassWithStrings.php" contains:
"""
<?php
namespace Diffs\DiffExample1;
class ClassWithStrings
{
public function getString()
{
return 'bar';
}
}
"""
When I run phpspec with the "verbose" option
Then I should see:
"""
@@ -1,1 +1,1 @@
-foo
+bar
"""
Scenario: Array diffing
Given the spec file "spec/Diffs/DiffExample2/ClassWithArraysSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithArraysSpec extends ObjectBehavior
{
function it_is_equal()
{
$this->getArray()->shouldReturn(array(
'int' => 1,
'string' => 'foo'
));
}
}
"""
And the class file "src/Diffs/DiffExample2/ClassWithArrays.php" contains:
"""
<?php
namespace Diffs\DiffExample2;
class ClassWithArrays
{
public function getArray()
{
return array(
'int' => 3,
'string' => 'bar'
);
}
}
"""
When I run phpspec with the "verbose" option
Then I should see:
"""
@@ -1,4 +1,4 @@
[
- int => 1,
- string => "foo",
+ int => 3,
+ string => "bar",
]
"""
Scenario: Array of object diffing
Given the spec file "spec/Diffs/DiffExample2/ClassWithArraysOfObjectsSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithArraysOfObjectsSpec extends ObjectBehavior
{
function it_is_equal()
{
$std = new \stdClass;
$std->test = 'anotherProperty';
$this->getArray()->shouldBeLike([$std]);
}
}
"""
And the class file "src/Diffs/DiffExample2/ClassWithArraysOfObjects.php" contains:
"""
<?php
namespace Diffs\DiffExample2;
class ClassWithArraysOfObjects
{
public function getArray()
{
$std = new \stdClass;
$std->property = 'testValue';
$std->hash = 'fooHash';
return [$std];
}
}
"""
When I run phpspec with the "verbose" option
Then I should see:
"""
- 'test' => 'anotherProperty'
"""
And I should see:
"""
+ 'property' => 'testValue'
"""
And I should see:
"""
+ 'hash' => 'fooHash'
"""
Scenario: Object diffing
Given the spec file "spec/Diffs/DiffExample3/ClassWithObjectsSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithObjectsSpec extends ObjectBehavior
{
function it_is_equal()
{
$obj = new \StdClass;
$obj->i = 1;
$obj->s = 'foo';
$this->getObject()->shouldReturn($obj);
}
}
"""
And the class file "src/Diffs/DiffExample3/ClassWithObjects.php" contains:
"""
<?php
namespace Diffs\DiffExample3;
class ClassWithObjects
{
public function getObject()
{
$obj = new \StdClass;
$obj->i = 2;
$obj->s = 'bar';
return $obj;
}
}
"""
When I run phpspec with the "verbose" option
Then I should see:
"""
- 'i' => 1
- 's' => 'foo'
"""
And I should see:
"""
+ 'i' => 2
+ 's' => 'bar'
"""
Scenario: Unexpected method arguments call arguments string diffing
Given the spec file "spec/Diffs/DiffExample4/ClassUnderSpecificationSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample4;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Diffs\DiffExample4\ClassBeingMocked;
class ClassUnderSpecificationSpec extends ObjectBehavior
{
function it_can_do_work(ClassBeingMocked $objectBeingMocked)
{
$objectBeingMocked->setValue('some really really long string, and even more, and more!')->shouldBeCalled();
$this->doWork($objectBeingMocked);
}
}
"""
And the class file "src/Diffs/DiffExample4/ClassUnderSpecification.php" contains:
"""
<?php
namespace Diffs\DiffExample4;
class ClassUnderSpecification
{
public function doWork(ClassBeingMocked $objectBeingMocked)
{
$objectBeingMocked->setValue('some really really long string, and even more, and more');
}
}
"""
And the class file "src/Diffs/DiffExample4/ClassBeingMocked.php" contains:
"""
<?php
namespace Diffs\DiffExample4;
class ClassBeingMocked
{
public function setValue($value)
{
}
}
"""
When I run phpspec with the "verbose" option
Then I should see:
"""
@@ -1,1 +1,1 @@
-some really really long string, and even more, and more!
+some really really long string, and even more, and more
"""
Scenario: Unexpected method arguments call arguments array diffing
Given the spec file "spec/Diffs/DiffExample5/ClassUnderSpecificationSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample5;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Diffs\DiffExample5\ClassBeingMocked;
class ClassUnderSpecificationSpec extends ObjectBehavior
{
function it_can_do_work(ClassBeingMocked $objectBeingMocked)
{
$objectBeingMocked->setValue(array(
'key1' => 'val1',
'key2' => 'val2',
))->shouldBeCalled();
$this->doWork($objectBeingMocked);
}
}
"""
And the class file "src/Diffs/DiffExample5/ClassUnderSpecification.php" contains:
"""
<?php
namespace Diffs\DiffExample5;
class ClassUnderSpecification
{
public function doWork(ClassBeingMocked $objectBeingMocked)
{
$objectBeingMocked->setValue(array(
'key1' => 'val1',
'key5' => 'val5',
));
}
}
"""
And the class file "src/Diffs/DiffExample5/ClassBeingMocked.php" contains:
"""
<?php
namespace Diffs\DiffExample5;
class ClassBeingMocked
{
public function setValue($value)
{
}
}
"""
When I run phpspec with the "verbose" option
Then I should see:
"""
@@ -1,4 +1,4 @@
[
key1 => "val1",
- key2 => "val2",
+ key5 => "val5",
]
"""
Scenario: Unexpected method arguments call with multiple arguments including null diffing
Given the spec file "spec/Diffs/DiffExample6/ClassUnderSpecificationSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample6;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Diffs\DiffExample6\ClassBeingMocked;
class ClassUnderSpecificationSpec extends ObjectBehavior
{
function it_can_do_work(ClassBeingMocked $objectBeingMocked)
{
$objectBeingMocked->setValue(array(
'key' => 'value'
), 'foo', null)->shouldBeCalled();
$this->doWork($objectBeingMocked);
}
}
"""
And the class file "src/Diffs/DiffExample6/ClassUnderSpecification.php" contains:
"""
<?php
namespace Diffs\DiffExample6;
class ClassUnderSpecification
{
public function doWork(ClassBeingMocked $objectBeingMocked)
{
$objectBeingMocked->setValue(array(
'key' => 'another value'
), 'foo', 'bar');
}
}
"""
And the class file "src/Diffs/DiffExample6/ClassBeingMocked.php" contains:
"""
<?php
namespace Diffs\DiffExample6;
class ClassBeingMocked
{
public function setValue($value)
{
}
}
"""
When I run phpspec with the "verbose" option
Then I should see:
"""
@@ -1,3 +1,3 @@
[
- key => "value",
+ key => "another value",
]
"""
And I should see:
"""
@@ -1,1 +1,1 @@
-null
+bar
"""
Scenario: Unexpected method call
Given the spec file "spec/Diffs/DiffExample7/ClassUnderSpecificationSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample7;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Diffs\DiffExample7\ClassBeingMocked;
class ClassUnderSpecificationSpec extends ObjectBehavior
{
function it_can_do_work(ClassBeingMocked $objectBeingMocked)
{
$objectBeingMocked->methodOne('value')->shouldBeCalled();
$this->doWork($objectBeingMocked);
}
}
"""
And the class file "src/Diffs/DiffExample7/ClassUnderSpecification.php" contains:
"""
<?php
namespace Diffs\DiffExample7;
class ClassUnderSpecification
{
public function doWork(ClassBeingMocked $objectBeingMocked)
{
$objectBeingMocked->methodTwo('value');
}
}
"""
And the class file "src/Diffs/DiffExample7/ClassBeingMocked.php" contains:
"""
<?php
namespace Diffs\DiffExample7;
class ClassBeingMocked
{
public function methodOne($value)
{
}
public function methodTwo($value)
{
}
}
"""
When I run phpspec with the "verbose" option
Then I should see the error that 'methodTwo("value")' was not expected on "Double\Diffs\DiffExample7\ClassBeingMocked\P13"
Scenario: Unexpected method call when another prophecy for that call with not matching arguments exists
Given the spec file "spec/Diffs/DiffExample8/ClassUnderSpecificationSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample8;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Diffs\DiffExample8\ClassBeingMocked;
class ClassUnderSpecificationSpec extends ObjectBehavior
{
function it_can_do_work(ClassBeingMocked $objectBeingMocked)
{
$objectBeingMocked->methodTwo('value')->shouldBeCalled();
$objectBeingMocked->methodOne('another value')->shouldBeCalled();
$this->doWork($objectBeingMocked);
}
}
"""
And the class file "src/Diffs/DiffExample8/ClassUnderSpecification.php" contains:
"""
<?php
namespace Diffs\DiffExample8;
class ClassUnderSpecification
{
public function doWork(ClassBeingMocked $objectBeingMocked)
{
$objectBeingMocked->methodTwo('value');
$objectBeingMocked->methodTwo('another value');
}
}
"""
And the class file "src/Diffs/DiffExample8/ClassBeingMocked.php" contains:
"""
<?php
namespace Diffs\DiffExample8;
class ClassBeingMocked
{
public function methodOne($value)
{
}
public function methodTwo($value)
{
}
}
"""
When I run phpspec with the "verbose" option
Then I should see the error that 'methodTwo("another value")' was not expected on "Double\Diffs\DiffExample8\ClassBeingMocked\P14"
Scenario: Array diffing with long strings
Given the spec file "spec/Diffs/DiffExample9/ClassWithArraysSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample9;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithArraysSpec extends ObjectBehavior
{
function it_is_equal()
{
$this->getArray()->shouldReturn(array(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam nunc nulla, posuere et arcu ut.'
));
}
}
"""
And the class file "src/Diffs/DiffExample9/ClassWithArrays.php" contains:
"""
<?php
namespace Diffs\DiffExample9;
class ClassWithArrays
{
public function getArray()
{
return array(
'Vestibulum vehicula nisl at ex maximus, nec lobortis orci luctus. Integer euismod in nunc nec lobortis'
);
}
}
"""
When I run phpspec with the "verbose" option
Then I should see:
"""
@@ -1,3 +1,3 @@
[
- 0 => "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam nunc nulla, posuere et arcu ut.",
+ 0 => "Vestibulum vehicula nisl at ex maximus, nec lobortis orci luctus. Integer euismod in nunc nec lobortis",
]
"""
Scenario: Array diffing with multi line strings
Given the spec file "spec/Diffs/DiffExample10/ClassWithArraysSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample10;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ClassWithArraysSpec extends ObjectBehavior
{
function it_is_equal()
{
$this->getArray()->shouldReturn(array(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Etiam nunc nulla, posuere et arcu ut.'
));
}
}
"""
And the class file "src/Diffs/DiffExample10/ClassWithArrays.php" contains:
"""
<?php
namespace Diffs\DiffExample10;
class ClassWithArrays
{
public function getArray()
{
return array(
'Vestibulum vehicula nisl at ex maximus, nec lobortis orci luctus.
Integer euismod in nunc nec lobortis'
);
}
}
"""
When I run phpspec with the "verbose" option
Then I should see:
"""
@@ -1,4 +1,4 @@
[
- 0 => "Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Etiam nunc nulla, posuere et arcu ut.",
+ 0 => "Vestibulum vehicula nisl at ex maximus, nec lobortis orci luctus.
+ Integer euismod in nunc nec lobortis",
]
"""
Scenario: Integer diff in verbose mode
Given the spec file "spec/Diffs/DiffExample11/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Diffs\DiffExample11;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_is_equal()
{
$this->calculate()->shouldReturn(2);
}
}
"""
And the class file "src/Diffs/DiffExample11/Calculator.php" contains:
"""
<?php
namespace Diffs\DiffExample11;
class Calculator
{
public function calculate()
{
return 1;
}
}
"""
When I run phpspec with the "verbose" option
Then I should see:
"""
expected [integer:2], but got [integer:1]
"""

View File

@@ -1,68 +0,0 @@
Feature: Use the JUnit formatter
In order to provide my CI tool with parsable phpspec results
As a developer
I need to be able to use a JUnit formatter
Scenario: Successfully export phpspec results in JUnit format
Given the spec file "spec/Formatter/SpecExample/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Formatter\SpecExample;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
// passed
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
// pending
function it_converts_html_paragraph_to_plain_text()
{
}
// failed
function it_formats_asterik_surrounding_text_in_italic()
{
$this->toHtml('*How are you?*')->shouldReturn('<i>How are you?</i>');
}
// broken
function it_formats_empty_text()
{
$this->toHtml('')->shouldReturn('<p></p>');
}
// skipped
function it_does_some_incompatible_things()
{
throw new \PhpSpec\Exception\Example\SkippingException('skipped');
}
}
"""
And the class file "src/Formatter/SpecExample/Markdown.php" contains:
"""
<?php
namespace Formatter\SpecExample;
class Markdown
{
public function toHtml($text)
{
if (empty($text)) {
throw new \InvalidArgumentException('Text cannot be empty: &$£€<>"');
}
return sprintf('<p>%s</p>', $text);
}
}
"""
When I run phpspec using the "junit" format
Then I should see valid junit output

View File

@@ -1,88 +0,0 @@
Feature: Use the TAP formatter
So that I can get non-XML parseable results
As a Developer
I need to be able to use a TAP formatter
Scenario: A spec which causes various result states
Given the spec file "spec/Formatter/TapExample1/TapSpec.php" contains:
"""
<?php
namespace spec\Formatter\TapExample1;
use PhpSpec\ObjectBehavior;
use PhpSpec\Exception\Example\SkippingException;
class TapSpec extends ObjectBehavior
{
function it_is_most_definitely_pending()
{
}
function it_is_most_definitely_passing()
{
$this->fire('pass')->shouldReturn('pass');
}
function it_is_most_definitely_failing()
{
$this->fire('fail')->shouldReturn('pass');
}
function it_is_most_definitely_broken()
{
$this->fire('broken')->shouldReturn('pass');
}
function it_is_most_definitely_skipping()
{
throw new SkippingException('php is not installed');
}
}
"""
And the class file "src/Formatter/TapExample1/Tap.php" contains:
"""
<?php
namespace Formatter\TapExample1;
use PhpSpec\Exception\Example\ErrorException;
class Tap
{
public function fire($stuff)
{
switch ($stuff) {
case 'pass':
return 'pass';
case 'fail':
return 'fail';
case 'broken':
throw new ErrorException('error','something terrible occurred','foo.php',99);
}
}
}
"""
When I run phpspec using the "tap" format
Then I should see:
"""
TAP version 13
not ok 1 - Formatter\TapExample1\Tap: is most definitely pending # TODO todo: write pending example
---
severity: todo
...
ok 2 - Formatter\TapExample1\Tap: is most definitely passing
not ok 3 - Formatter\TapExample1\Tap: is most definitely failing
---
message: 'Expected "pass", but got "fail".'
severity: fail
...
not ok 4 - Formatter\TapExample1\Tap: is most definitely broken
---
message: 'error: something terrible occurred in foo.php line 99'
severity: fail
...
ok 5 - Formatter\TapExample1\Tap: is most definitely skipping # SKIP skipped: php is not installed
1..5
"""

View File

@@ -1,126 +0,0 @@
Feature: Developer uses unsupported collaborator type hinting
As a developer
I should be shown special exception when I declare collaborators with unsupported type hinting
Scenario: Array collaborator type hinting
Given the spec file "spec/InvalidUsage/InvalidUsageExample1/StorageSpec.php" contains:
"""
<?php
namespace spec\InvalidUsage\InvalidUsageExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class StorageSpec extends ObjectBehavior
{
function it_can_store_data(array $data)
{
$this->store($data)->shouldReturn(true);
}
}
"""
And the class file "src/InvalidUsage/InvalidUsageExample1/Storage.php" contains:
"""
<?php
namespace InvalidUsage\InvalidUsageExample1;
class Storage
{
public function store(array $data)
{
return true;
}
}
"""
When I run phpspec
Then I should see:
"""
collaborator must be an object: argument 0 defined in
spec\InvalidUsage\InvalidUsageExample1\StorageSpec::it_can_store_data.
"""
Scenario: Callable collaborator type hinting
Given the spec file "spec/InvalidUsage/InvalidUsageExample2/InvokerSpec.php" contains:
"""
<?php
namespace spec\InvalidUsage\InvalidUsageExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class InvokerSpec extends ObjectBehavior
{
function it_invokes_callable(callable $callback)
{
$this->invoke($callback)->shouldReturn(true);
}
}
"""
And the class file "src/InvalidUsage/InvalidUsageExample2/Invoker.php" contains:
"""
<?php
namespace InvalidUsage\InvalidUsageExample2;
class Invoker
{
public function invoke(callable $data, array $parameters = array())
{
return true;
}
}
"""
When I run phpspec
Then I should see:
"""
collaborator must be an object: argument 0 defined in
spec\InvalidUsage\InvalidUsageExample2\InvokerSpec::it_invokes_callable.
"""
Scenario: Integer collaborator type hinting
Given the spec file "spec/InvalidUsage/InvalidUsageExample3/StorageSpec.php" contains:
"""
<?php
namespace spec\InvalidUsage\InvalidUsageExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class StorageSpec extends ObjectBehavior
{
function it_can_store_data(int $data)
{
$this->store($data)->shouldReturn(true);
}
}
"""
And the class file "src/InvalidUsage/InvalidUsageExample3/Storage.php" contains:
"""
<?php
namespace InvalidUsage\InvalidUsageExample3;
class Storage
{
public function store(int $data)
{
return true;
}
}
"""
When I run phpspec
Then I should see:
"""
collaborator must be an object: argument 0 defined in
spec\InvalidUsage\InvalidUsageExample3\StorageSpec::it_can_store_data.
"""

View File

@@ -1,42 +0,0 @@
Feature: Developer uses approximately matcher
As a Developer
I want an approximately matcher
In order to verify if two floats can be close
@issue581
Scenario: "Approximately" alias matches using the approximately matcher
Given the spec file "spec/Matchers/FloatApproximatelyExample1/GeoCoordSpec.php" contains:
"""
<?php
namespace spec\Matchers\FloatApproximatelyExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class GeoCoordSpec extends ObjectBehavior
{
function it_should_have_lat_approximate()
{
$this->getLat()->shouldBeApproximately(1.4477, 1.0e-2);
}
}
"""
And the class file "src/Matchers/FloatApproximatelyExample1/GeoCoord.php" contains:
"""
<?php
namespace Matchers\FloatApproximatelyExample1;
class GeoCoord
{
public function getLat()
{
return 1.444444;
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,41 +0,0 @@
Feature: Developer uses array-contain matcher
As a Developer
I want an array-contain matcher
In order to confirm an array contains an expected value
Scenario: "Contain" alias matches using the array-contain matcher
Given the spec file "spec/Matchers/ArrayContainExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\ArrayContainExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_contain_jane_smith_in_the_cast()
{
$this->getCast()->shouldContain('Jane Smith');
}
}
"""
And the class file "src/Matchers/ArrayContainExample1/Movie.php" contains:
"""
<?php
namespace Matchers\ArrayContainExample1;
class Movie
{
public function getCast()
{
return array('John Smith', 'Jane Smith');
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,41 +0,0 @@
Feature: Developer uses array-count matcher
As a Developer
I want an array-count matcher
In order to compare an array count against an expectation
Scenario: "HaveCount" alias matches using the array-count matcher
Given the spec file "spec/Matchers/ArrayCountExample1/CarSpec.php" contains:
"""
<?php
namespace spec\Matchers\ArrayCountExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarSpec extends ObjectBehavior
{
function it_returns_the_number_of_wheels()
{
$this->getWheels()->shouldHaveCount(4);
}
}
"""
And the class file "src/Matchers/ArrayCountExample1/Car.php" contains:
"""
<?php
namespace Matchers\ArrayCountExample1;
class Car
{
public function getWheels()
{
return array('wheel', 'wheel', 'wheel', 'wheel');
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,44 +0,0 @@
Feature: Developer uses array-key matcher
As a Developer
I want an array-key matcher
In order to confirm an array contains an expected key
Scenario: "HaveKey" alias matches using the array-key matcher
Given the spec file "spec/Matchers/ArrayKeyExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\ArrayKeyExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_have_a_release_date_for_france()
{
$this->getReleaseDates()->shouldHaveKey('France');
}
}
"""
And the class file "src/Matchers/ArrayKeyExample1/Movie.php" contains:
"""
<?php
namespace Matchers\ArrayKeyExample1;
class Movie
{
public function getReleaseDates()
{
return array(
'Australia' => '12 April 2013',
'France' => '24 April 2013',
);
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,41 +0,0 @@
Feature: Developer uses array-key-value matcher
As a Developer
I want an array-key-value matcher
In order to confirm an array the expected value for a key
Scenario: "HaveKeyWithValue" alias matches using the array-key-value matcher
Given the spec file "spec/Matchers/ArrayKeyValueExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\ArrayKeyValueExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_contain_jane_smith_in_the_cast()
{
$this->getCast()->shouldHaveKeyWithValue('leadRole', 'John Smith');
}
}
"""
And the class file "src/Matchers/ArrayKeyValueExample1/Movie.php" contains:
"""
<?php
namespace Matchers\ArrayKeyValueExample1;
class Movie
{
public function getCast()
{
return array('leadRole' => 'John Smith', 'supportingRole' => 'Jane Smith');
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,41 +0,0 @@
Feature: Developer uses comparison matcher
As a Developer
I want a comparison matcher
In order to loosely compare a value against an expectation
Scenario: "BeLike" alias matches using comparison operator
Given the spec file "spec/Matchers/ComparisonExample1/StringCalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\ComparisonExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class StringCalculatorSpec extends ObjectBehavior
{
function it_returns_the_value_of_a_string()
{
$this->calc('5')->shouldBeLike('5');
}
}
"""
And the class file "src/Matchers/ComparisonExample1/StringCalculator.php" contains:
"""
<?php
namespace Matchers\ComparisonExample1;
class StringCalculator
{
public function calc($string)
{
return (int) $string;
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,99 +0,0 @@
Feature: Developer uses custom matcher
As a Developer
I want a custom matcher
In order to confirm any custom assertion I need
Scenario: Succesfully register a custom matcher
Given the spec file "spec/Matchers/Custom/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\Custom;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_have_some_specific_options_by_default()
{
$this->getEntries()->shouldTotalize(130);
}
}
"""
And the class file "src/Matchers/Custom/TotalizeMatcher.php" contains:
"""
<?php
namespace Matchers\Custom;
use PhpSpec\Matcher\BasicMatcher;
use PhpSpec\Exception\Example\FailureException;
class TotalizeMatcher extends BasicMatcher
{
public function supports(string $name, $subject, array $arguments): bool
{
return 'totalize' === $name &&
is_array($subject) &&
isset($arguments[0]) &&
is_int($arguments[0])
;
}
protected function matches($subject, array $arguments): bool
{
return array_sum($subject) === $arguments[0];
}
protected function getFailureException(string $name, $subject, array $arguments): FailureException
{
return new FailureException(sprintf(
'Expected to totalize %d, but got %d.',
$arguments[0],
array_sum($subject)
));
}
protected function getNegativeFailureException(string $name, $subject, array $arguments): FailureException
{
return new FailureException(sprintf(
'Expected to not totalize %d, but it does.',
$arguments[0]
));
}
}
"""
And the class file "src/Matchers/Custom/Movie.php" contains:
"""
<?php
namespace Matchers\Custom;
class Movie
{
public function getEntries()
{
return [100, 10, 20];
}
}
"""
And the config file contains:
"""
matchers:
- Matchers\Custom\TotalizeMatcher
"""
When I run phpspec
Then the suite should pass
Scenario: Developer adds class that is not Matcher to custom matchers list
Given the config file contains:
"""
matchers:
- ArrayObject
"""
When I run phpspec
Then I should see "Custom matcher ArrayObject must implement PhpSpec\Matcher\Matcher interface, but it does not"

View File

@@ -1,448 +0,0 @@
Feature: Developer uses identity matcher
As a Developer
I want an identity matcher
In order to match the identity of a value against an expectation
Scenario: "Return" alias matching using identity operator
Given the spec file "spec/Matchers/IdentityExample1/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldReturn(3);
}
}
"""
And the class file "src/Matchers/IdentityExample1/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample1;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Return" alias not matching using identity operator
Given the spec file "spec/Matchers/IdentityExample2/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldNotReturn(4);
}
}
"""
And the class file "src/Matchers/IdentityExample2/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample2;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Return" alias not matching type using identity operator
Given the spec file "spec/Matchers/IdentityExample3/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldNotReturn("3");
}
}
"""
And the class file "src/Matchers/IdentityExample3/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample3;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Be" alias matching using identity operator
Given the spec file "spec/Matchers/IdentityExample4/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample4;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldBe(3);
}
}
"""
And the class file "src/Matchers/IdentityExample4/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample4;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Be" alias not matching using identity operator
Given the spec file "spec/Matchers/IdentityExample5/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample5;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldNotBe(4);
}
}
"""
And the class file "src/Matchers/IdentityExample5/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample5;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Be" alias not matching type using identity operator
Given the spec file "spec/Matchers/IdentityExample6/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample6;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldNotBe("3");
}
}
"""
And the class file "src/Matchers/IdentityExample6/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample6;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Equal" alias matching using identity operator
Given the spec file "spec/Matchers/IdentityExample7/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample7;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldEqual(3);
}
}
"""
And the class file "src/Matchers/IdentityExample7/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample7;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Equal" alias not matching using identity operator
Given the spec file "spec/Matchers/IdentityExample8/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample8;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldNotEqual(4);
}
}
"""
And the class file "src/Matchers/IdentityExample8/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample8;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Equal" alias not matching type using identity operator
Given the spec file "spec/Matchers/IdentityExample9/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample9;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldNotEqual("3");
}
}
"""
And the class file "src/Matchers/IdentityExample9/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample9;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "BeEqualTo" alias matching using identity operator
Given the spec file "spec/Matchers/IdentityExample10/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample10;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldEqual(3);
}
}
"""
And the class file "src/Matchers/IdentityExample10/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample10;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Equal" alias not matching using identity operator
Given the spec file "spec/Matchers/IdentityExample11/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample11;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldNotEqual(4);
}
}
"""
And the class file "src/Matchers/IdentityExample11/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample11;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Equal" alias not matching type using identity operator
Given the spec file "spec/Matchers/IdentityExample12/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\IdentityExample12;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2)->shouldNotEqual("3");
}
}
"""
And the class file "src/Matchers/IdentityExample12/Calculator.php" contains:
"""
<?php
namespace Matchers\IdentityExample12;
class Calculator
{
public function sum($x, $y)
{
return $x + $y;
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,161 +0,0 @@
Feature: Developer uses inline matcher
As a Developer
I want an inline matcher
So I can create expectations in a language closer to the domain I am describing
Scenario: Inline matcher with no argument
Given the spec file "spec/Matchers/InlineExample1/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\InlineExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2);
$this->shouldBePositive();
}
function getMatchers(): array
{
return array ('bePositive' => function($subject) {
return $subject->getTotal() > 0;
});
}
}
"""
And the class file "src/Matchers/InlineExample1/Calculator.php" contains:
"""
<?php
namespace Matchers\InlineExample1;
class Calculator
{
private $total;
public function sum($x, $y)
{
$this->total = $x + $y;
}
public function getTotal()
{
return $this->total;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Inline matcher with an argument
Given the spec file "spec/Matchers/InlineExample2/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\InlineExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_calculates_the_sum_of_two_addends()
{
$this->sum(1, 2);
$this->shouldTotal(3);
}
function getMatchers() : array
{
return array ('total' => function($subject, $total) {
return $subject->getTotal() === $total;
});
}
}
"""
And the class file "src/Matchers/InlineExample2/Calculator.php" contains:
"""
<?php
namespace Matchers\InlineExample2;
class Calculator
{
private $total;
public function sum($x, $y)
{
$this->total = $x + $y;
}
public function getTotal()
{
return $this->total;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Inline matcher throwing an exception
Given the spec file "spec/Matchers/InlineExample3/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Matchers\InlineExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use PhpSpec\Exception\Example\FailureException;
class CalculatorSpec extends ObjectBehavior
{
function it_uses_inline_matcher_that_throws_an_exception()
{
$this->shouldDoSomething('abc');
}
function getMatchers(): array
{
return array ('doSomething' => function($subject, $param) {
throw new FailureException(sprintf(
'a very important message with subject "%s" and param "%s".',
$subject, $param
));
});
}
}
"""
And the class file "src/Matchers/InlineExample3/Calculator.php" contains:
"""
<?php
namespace Matchers\InlineExample3;
class Calculator
{
public function __toString()
{
return 'Hi';
}
}
"""
When I run phpspec
Then the suite should not pass
Then I should see "a very important message"

View File

@@ -1,40 +0,0 @@
Feature: Developer uses iterate-as matcher
As a Developer
I want an iterate-as matcher
In order to confirm an traversable the expected value for a key
Scenario: "Iterate" alias matches using the iterate-as matcher
Given the spec file "spec/Matchers/IterateExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\IterateExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_contain_jane_smith_in_the_cast()
{
$this->getCast()->shouldIterateAs(['supportingRole' => 'Jane Smith', 'leadRole' => 'John Smith']);
}
}
"""
And the class file "src/Matchers/IterateExample1/Movie.php" contains:
"""
<?php
namespace Matchers\IterateExample1;
class Movie
{
public function getCast()
{
yield 'supportingRole' => 'Jane Smith';
yield 'leadRole' => 'John Smith';
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,39 +0,0 @@
Feature: Developer uses iterate-as matcher
As a Developer
I want an iterate-like matcher
In order to confirm an traversable the expected loosely-typed value for a key
Scenario: "Iterate" alias matches using the iterate-like matcher
Given the spec file "spec/Matchers/IterateLikeExample1/IterSpec.php" contains:
"""
<?php
namespace spec\Matchers\IterateLikeExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class IterSpec extends ObjectBehavior
{
function it_should_contain_object_in_the_elements()
{
$this->getElements()->shouldIterateLike([ (object)['foo' => 'bar'] ]);
}
}
"""
And the class file "src/Matchers/IterateLikeExample1/Iter.php" contains:
"""
<?php
namespace Matchers\IterateLikeExample1;
class Iter
{
public function getElements()
{
yield (object)['foo' => 'bar'];
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,78 +0,0 @@
Feature: Developer uses object-state matcher
As a Developer
I want an object-state matcher
In order to validate objects against an expectation
Scenario: "Have" alias matches using the object-state matcher
Given the spec file "spec/Matchers/ObjectStateExample1/CarSpec.php" contains:
"""
<?php
namespace spec\Matchers\ObjectStateExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarSpec extends ObjectBehavior
{
function it_returns_true_if_it_has_an_wheels()
{
$this->shouldHaveWheels();
}
}
"""
And the class file "src/Matchers/ObjectStateExample1/Car.php" contains:
"""
<?php
namespace Matchers\ObjectStateExample1;
class Car
{
public function hasWheels()
{
return true;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Be" alias matches using the object-state matcher
Given the spec file "spec/Matchers/ObjectStateExample2/CarSpec.php" contains:
"""
<?php
namespace spec\Matchers\ObjectStateExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarSpec extends ObjectBehavior
{
function it_returns_true_if_it_is_available()
{
$this->shouldBeAvailable();
}
}
"""
And the class file "src/Matchers/ObjectStateExample2/Car.php" contains:
"""
<?php
namespace Matchers\ObjectStateExample2;
class Car
{
public function isAvailable()
{
return true;
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,53 +0,0 @@
Feature: Developer uses scalar matcher
As a Developer
I want an scalar matcher
In order to match against various scalar values against their expectations
Scenario: Scalar matching aliases match using the scalar matcher
Given the spec file "spec/Matchers/ScalarExample1/CarSpec.php" contains:
"""
<?php
namespace spec\Matchers\ScalarExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarSpec extends ObjectBehavior
{
function it_returns_the_result()
{
$result = $this->getDetails();
$result['name']->shouldBeString();
$result['age']->shouldBeInteger();
$result['price']->shouldBeFloat();
$result['sale']->shouldBeBool();
$result['callback']->shouldBeCallable();
}
}
"""
And the class file "src/Matchers/ScalarExample1/Car.php" contains:
"""
<?php
namespace Matchers\ScalarExample1;
class Car
{
public function getDetails()
{
return array(
'name' => 'astra',
'age' => 34,
'price' => 10.99,
'sale' => true,
'callback' => function() {}
);
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,41 +0,0 @@
Feature: Developer uses start-iterate-as matcher
As a Developer
I want an start-iterate-as matcher
In order to confirm an traversable the expected value for a key
Scenario: "StartIterating" alias matches using the start-iterate-as matcher
Given the spec file "spec/Matchers/StartIteratingExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\StartIteratingExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_contain_jane_smith_in_the_cast()
{
$this->getCast()->shouldStartIteratingAs(['supportingRole' => 'Jane Smith', 'leadRole' => 'John Smith']);
}
}
"""
And the class file "src/Matchers/StartIteratingExample1/Movie.php" contains:
"""
<?php
namespace Matchers\StartIteratingExample1;
class Movie
{
public function getCast()
{
yield 'supportingRole' => 'Jane Smith';
yield 'leadRole' => 'John Smith';
yield 'supportingRole' => 'Will Smith';
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,41 +0,0 @@
Feature: Developer uses string-contain matcher
As a Developer
I want a string-contain matcher
In order to confirm a string contains an expected substring
Scenario: "Contain" alias matches using the string-contain matcher
Given the spec file "spec/Matchers/StringContainExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\StringContainExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_have_a_title_that_contains_days()
{
$this->getTitle()->shouldContain('days');
}
}
"""
And the class file "src/Matchers/StringContainExample1/Movie.php" contains:
"""
<?php
namespace Matchers\StringContainExample1;
class Movie
{
public function getTitle()
{
return 'The future days of past';
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,41 +0,0 @@
Feature: Developer uses string-end matcher
As a Developer
I want an string-end matcher
In order to confirm a string ends with an expected substring
Scenario: "EndsWith" alias matches using the string-end matcher
Given the spec file "spec/Matchers/StringEndExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\StringEndExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_have_a_title_that_ends_with_of_oz()
{
$this->getTitle()->shouldEndWith('of Oz');
}
}
"""
And the class file "src/Matchers/StringEndExample1/Movie.php" contains:
"""
<?php
namespace Matchers\StringEndExample1;
class Movie
{
public function getTitle()
{
return 'The Wizard of Oz';
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,41 +0,0 @@
Feature: Developer uses string-regex matcher
As a Developer
I want an string-regex matcher
In order to confirm a string matches against an expected regular expression
Scenario: "Matches" alias matches using the string-regex matcher
Given the spec file "spec/Matchers/StringRegexExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\StringRegexExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_have_a_title_that_contains_wizard()
{
$this->getTitle()->shouldMatch('/wizard/i');
}
}
"""
And the class file "src/Matchers/StringRegexExample1/Movie.php" contains:
"""
<?php
namespace Matchers\StringRegexExample1;
class Movie
{
public function getTitle()
{
return 'The Wizard of Oz';
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,41 +0,0 @@
Feature: Developer uses string-start matcher
As a Developer
I want an string-start matcher
In order to confirm a string starts with an expected substring
Scenario: "StartWith" alias matches using the string-start matcher
Given the spec file "spec/Matchers/StringStartExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\StringStartExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_have_a_title_that_starts_with_the_wizard()
{
$this->getTitle()->shouldStartWith('The Wizard');
}
}
"""
And the class file "src/Matchers/StringStartExample1/Movie.php" contains:
"""
<?php
namespace Matchers\StringStartExample1;
class Movie
{
public function getTitle()
{
return 'The Wizard of Oz';
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,256 +0,0 @@
Feature: Developer uses throw matcher
As a Developer
I want a throw matcher
In order to validate objects exceptions against my expectations
Scenario: "Throw" alias matches using the throw matcher with explicit method name
Given the spec file "spec/Matchers/ThrowExample1/EmployeeSpec.php" contains:
"""
<?php
namespace spec\Matchers\ThrowExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class EmployeeSpec extends ObjectBehavior
{
function it_throws_an_exception_when_arguments_are_invalid()
{
$this->shouldThrow('\InvalidArgumentException')->during('setAge', array(0));
}
}
"""
And the class file "src/Matchers/ThrowExample1/Employee.php" contains:
"""
<?php
namespace Matchers\ThrowExample1;
class Employee
{
public function setAge($age)
{
if (0 === $age) {
throw new \InvalidArgumentException();
}
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Throw" alias matches using the throw matcher with implicit method name
Given the spec file "spec/Matchers/ThrowExample2/EmployeeSpec.php" contains:
"""
<?php
namespace spec\Matchers\ThrowExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class EmployeeSpec extends ObjectBehavior
{
function it_throws_an_exception_when_arguments_are_invalid()
{
$this->shouldThrow('\InvalidArgumentException')->duringSetAge(0);
}
}
"""
And the class file "src/Matchers/ThrowExample2/Employee.php" contains:
"""
<?php
namespace Matchers\ThrowExample2;
class Employee
{
public function setAge($age)
{
if (0 === $age) {
throw new \InvalidArgumentException();
}
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Throw" alias matches using the throw matcher with specific exception message
Given the spec file "spec/Matchers/ThrowExample3/EmployeeSpec.php" contains:
"""
<?php
namespace spec\Matchers\ThrowExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class EmployeeSpec extends ObjectBehavior
{
function it_throws_an_exception_when_arguments_are_invalid()
{
$this->shouldThrow(new \InvalidArgumentException('Invalid age'))->duringSetAge(0);
}
}
"""
And the class file "src/Matchers/ThrowExample3/Employee.php" contains:
"""
<?php
namespace Matchers\ThrowExample3;
class Employee
{
public function setAge($age)
{
if (0 === $age) {
throw new \InvalidArgumentException('Invalid age');
}
}
}
"""
When I run phpspec
Then the suite should pass
@issue134
Scenario: Throwing an exception during object construction
Given the spec file "spec/Runner/ThrowExample4/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\ThrowExample4;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_throws_an_exception_using_during_syntax()
{
$this->shouldThrow('Exception')->during('__construct', array(1,2));
}
function it_throws_an_exception_using_magic_syntax()
{
$this->shouldThrow('Exception')->during__construct(1,2);
}
}
"""
And the class file "src/Runner/ThrowExample4/Markdown.php" contains:
"""
<?php
namespace Runner\ThrowExample4;
class Markdown
{
public function __construct($num1, $num2)
{
throw new \Exception();
}
}
"""
When I run phpspec
Then the suite should pass
@issue610
Scenario: Throwing an exception during object construction
Given the spec file "spec/Runner/ThrowExample5/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\ThrowExample5;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_throws_an_exception_using_during_instantiation_syntax()
{
$this->beConstructedWith(1, 2);
$this->shouldThrow('\InvalidArgumentException')->duringInstantiation();
}
function it_throws_an_exception_using_during_named_instantiation_syntax()
{
$this->beConstructedThrough('defaultNumber2', array(1));
$this->shouldThrow('\InvalidArgumentException')->duringInstantiation();
}
}
"""
And the class file "src/Runner/ThrowExample5/Markdown.php" contains:
"""
<?php
namespace Runner\ThrowExample5;
class Markdown
{
public function __construct($num1, $num2)
{
throw new \InvalidArgumentException();
}
public static function defaultNumber2($num1, $num2 = 2)
{
return new self($num1, $num2);
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Throw matcher supports Error
Given the spec file "spec/Runner/ThrowExample6/CalculatorSpec.php" contains:
"""
<?php
namespace spec\Runner\ThrowExample6;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CalculatorSpec extends ObjectBehavior
{
function it_throws_error_during_division_by_zero()
{
$this->shouldThrow(new \DivisionByZeroError())->duringDivide(10, 0);
}
}
"""
And the class file "src/Runner/ThrowExample6/Calculator.php" contains:
"""
<?php
namespace Runner\ThrowExample6;
class Calculator
{
public function divide(int $dividend, int $divider): float
{
if ($divider === 0) {
throw new \DivisionByZeroError();
}
return $dividend / $divider;
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,40 +0,0 @@
Feature: Developer uses traversable-contain matcher
As a Developer
I want an traversable-contain matcher
In order to confirm an traversable contains an expected value
Scenario: "Contain" alias matches using the traversable-contain matcher
Given the spec file "spec/Matchers/TraversableContainExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\TraversableContainExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_contain_jane_smith_in_the_cast()
{
$this->getCast()->shouldContain('Jane Smith');
}
}
"""
And the class file "src/Matchers/TraversableContainExample1/Movie.php" contains:
"""
<?php
namespace Matchers\TraversableContainExample1;
class Movie
{
public function getCast()
{
yield 'John Smith';
yield 'Jane Smith';
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,42 +0,0 @@
Feature: Developer uses traversable-count matcher
As a Developer
I want an traversable-count matcher
In order to compare an array count against an expectation
Scenario: "HaveCount" alias matches using the traversable-count matcher
Given the spec file "spec/Matchers/TraversableCountExample1/CarSpec.php" contains:
"""
<?php
namespace spec\Matchers\TraversableCountExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarSpec extends ObjectBehavior
{
function it_returns_the_number_of_wheels()
{
$this->getWheels()->shouldHaveCount(4);
}
}
"""
And the class file "src/Matchers/TraversableCountExample1/Car.php" contains:
"""
<?php
namespace Matchers\TraversableCountExample1;
class Car
{
public function getWheels()
{
yield 'wheel';
yield 'wheel';
yield 'wheel';
yield 'wheel';
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,40 +0,0 @@
Feature: Developer uses traversable-key matcher
As a Developer
I want an traversable-key matcher
In order to confirm an array contains an expected key
Scenario: "HaveKey" alias matches using the traversable-key matcher
Given the spec file "spec/Matchers/TraversableKeyExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\TraversableKeyExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_have_a_release_date_for_france()
{
$this->getReleaseDates()->shouldHaveKey('France');
}
}
"""
And the class file "src/Matchers/TraversableKeyExample1/Movie.php" contains:
"""
<?php
namespace Matchers\TraversableKeyExample1;
class Movie
{
public function getReleaseDates()
{
yield 'Australia' => '12 April 2013';
yield 'France' => '24 April 2013';
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,40 +0,0 @@
Feature: Developer uses traversable-key-value matcher
As a Developer
I want an traversable-key-value matcher
In order to confirm an traversable the expected value for a key
Scenario: "HaveKeyWithValue" alias matches using the traversable-key-value matcher
Given the spec file "spec/Matchers/TraversableKeyValueExample1/MovieSpec.php" contains:
"""
<?php
namespace spec\Matchers\TraversableKeyValueExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MovieSpec extends ObjectBehavior
{
function it_should_contain_jane_smith_in_the_cast()
{
$this->getCast()->shouldHaveKeyWithValue('leadRole', 'John Smith');
}
}
"""
And the class file "src/Matchers/TraversableKeyValueExample1/Movie.php" contains:
"""
<?php
namespace Matchers\TraversableKeyValueExample1;
class Movie
{
public function getCast()
{
yield 'supportingRole' => 'Jane Smith';
yield 'leadRole' => 'John Smith';
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,119 +0,0 @@
Feature: Developer uses trigger matcher
As a Developer
I want a trigger matcher
In order to validate triggered exceptions against my expectations
Scenario: Checking if a deprecated error has been triggered
Given the spec file "spec/Matchers/TriggerExample1/FooSpec.php" contains:
"""
<?php
namespace spec\Matchers\TriggerExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class FooSpec extends ObjectBehavior
{
function it_triggers_an_error_when_calling_something_deprecated()
{
$this->shouldTrigger(E_USER_DEPRECATED)->duringDoDeprecatedStuff();
}
}
"""
And the class file "src/Matchers/TriggerExample1/Foo.php" contains:
"""
<?php
namespace Matchers\TriggerExample1;
class Foo
{
public function doDeprecatedStuff()
{
trigger_error('Foo', E_USER_DEPRECATED);
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: Checking that a deprecated error has the right message
Given the spec file "spec/Matchers/TriggerExample2/FooSpec.php" contains:
"""
<?php
namespace spec\Matchers\TriggerExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class FooSpec extends ObjectBehavior
{
function it_triggers_a_specific_deprecated_error_when_calling_deprecated_method()
{
$this->shouldTrigger(E_USER_DEPRECATED, 'This is deprecated')->duringDoDeprecatedStuff();
}
}
"""
And the class file "src/Matchers/TriggerExample2/Foo.php" contains:
"""
<?php
namespace Matchers\TriggerExample2;
class Foo
{
public function doDeprecatedStuff()
{
trigger_error('This is deprecated', E_USER_DEPRECATED);
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Trigger" alias matches using the trigger matcher and let the code continue afterwards
Given the spec file "spec/Matchers/TriggerExample3/FooSpec.php" contains:
"""
<?php
namespace spec\Matchers\TriggerExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class FooSpec extends ObjectBehavior
{
function it_triggers_a_deprecated_error_when_calling_deprecated_method_but_do_not_interrupt()
{
$this->shouldTrigger(E_USER_DEPRECATED, 'This is deprecated')->duringDoDeprecatedStuff(0);
$this->getDeprecated()->shouldBe(0);
}
}
"""
And the class file "src/Matchers/TriggerExample3/Foo.php" contains:
"""
<?php
namespace Matchers\TriggerExample3;
class Foo
{
private $deprecated;
public function getDeprecated()
{
return $this->deprecated;
}
public function doDeprecatedStuff($value)
{
trigger_error('This is deprecated', E_USER_DEPRECATED);
$this->deprecated = $value;
}
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,145 +0,0 @@
Feature: Developer uses type matcher
As a Developer
I want a type matcher
In order to confirm that my object is of a given type
Scenario: "HaveType" alias matches using the type matcher
Given the spec file "spec/Matchers/TypeExample1/CarSpec.php" contains:
"""
<?php
namespace spec\Matchers\TypeExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarSpec extends ObjectBehavior
{
function it_should_be_a_car()
{
$this->shouldHaveType('Matchers\TypeExample1\Car');
}
}
"""
And the class file "src/Matchers/TypeExample1/Car.php" contains:
"""
<?php
namespace Matchers\TypeExample1;
class Car
{
}
"""
When I run phpspec
Then the suite should pass
Scenario: "ReturnAnInstanceOf" alias matches using the type matcher
Given the spec file "spec/Matchers/TypeExample2/CarSpec.php" contains:
"""
<?php
namespace spec\Matchers\TypeExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarSpec extends ObjectBehavior
{
function it_should_be_a_car()
{
$this->get()->shouldReturnAnInstanceOf('Matchers\TypeExample2\Car');
}
}
"""
And the class file "src/Matchers/TypeExample2/Car.php" contains:
"""
<?php
namespace Matchers\TypeExample2;
class Car
{
public function get()
{
return $this;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "BeAnInstanceOf" alias matches using the type matcher
Given the spec file "spec/Matchers/TypeExample3/CarSpec.php" contains:
"""
<?php
namespace spec\Matchers\TypeExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarSpec extends ObjectBehavior
{
function it_should_be_a_car()
{
$this->get()->shouldBeAnInstanceOf('Matchers\TypeExample3\Car');
}
}
"""
And the class file "src/Matchers/TypeExample3/Car.php" contains:
"""
<?php
namespace Matchers\TypeExample3;
class Car
{
public function get()
{
return $this;
}
}
"""
When I run phpspec
Then the suite should pass
Scenario: "Implement" alias matches using the type matcher
Given the spec file "spec/Matchers/TypeExample4/CarSpec.php" contains:
"""
<?php
namespace spec\Matchers\TypeExample4;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class CarSpec extends ObjectBehavior
{
function it_should_be_a_car()
{
$this->shouldImplement('Matchers\TypeExample4\Car');
}
}
"""
And the class file "src/Matchers/TypeExample4/Car.php" contains:
"""
<?php
namespace Matchers\TypeExample4;
class Car
{
}
"""
When I run phpspec
Then the suite should pass

View File

@@ -1,81 +0,0 @@
Feature: Developer chooses no code generation
As a Developer
I want to set the no code generation setting option
In order to specify how phpspec behaves when a class is not found
@issue352
Scenario: code-generation defaults to off
Given the spec file "spec/NoCodeGeneration/SpecExample1/NewClassSpec.php" contains:
"""
<?php
namespace spec\NoCodeGeneration\SpecExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class NewClassSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldBeAnInstanceOf('NoCodeGeneration\NewClass');
}
}
"""
When I run phpspec interactively
Then I should be prompted for code generation
@issue352
Scenario: code-generation is specified in the config
Given the config file contains:
"""
code_generation: false
"""
And the spec file "spec/NoCodeGeneration/SpecExample2/NewClassSpec.php" contains:
"""
<?php
namespace spec\NoCodeGeneration\SpecExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class NewClassSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldBeAnInstanceOf('NoCodeGeneration\NewClass');
}
}
"""
When I run phpspec interactively
Then I should not be prompted for code generation
@issue352
Scenario: code-generation on the command line takes priority
Given the config file contains:
"""
code_generation: true
"""
And the spec file "spec/NoCodeGeneration/SpecExample3/NewClassSpec.php" contains:
"""
<?php
namespace spec\NoCodeGeneration\SpecExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class NewClassSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldBeAnInstanceOf('NoCodeGeneration\NewClass');
}
}
"""
When I run phpspec interactively with the "no-code-generation" option
Then I should not be prompted for code generation

View File

@@ -1,144 +0,0 @@
Feature: Developer chooses stop on failure
As a Developer
I want to set the stop on failure setting option
In order to specify how phpspec behaves on failure
@issue352
Scenario: stop-on-failure defaults to off
Given the spec file "spec/SkipOnFailure/SpecExample1/FirstFailSpec.php" contains:
"""
<?php
namespace spec\SkipOnFailure\SpecExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class FirstFailSpec extends ObjectBehavior
{
function it_fails()
{
$this->getValue()->shouldReturn(2);
}
function it_should_never_get_called()
{
$this->getValue()->shouldReturn(1);
}
}
"""
And the class file "src/SkipOnFailure/SpecExample1/FirstFail.php" contains:
"""
<?php
namespace SkipOnFailure\SpecExample1;
class FirstFail
{
public function getValue()
{
return 1;
}
}
"""
When I run phpspec
Then 2 examples should have been run
@issue352
Scenario: stop-on-failure is specified in the config
Given the config file contains:
"""
stop_on_failure: true
"""
And the spec file "spec/SkipOnFailure/SpecExample2/FirstFailSpec.php" contains:
"""
<?php
namespace spec\SkipOnFailure\SpecExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class FirstFailSpec extends ObjectBehavior
{
function it_fails()
{
$this->getValue()->shouldReturn(2);
}
function it_should_never_get_called()
{
$this->getValue()->shouldReturn(1);
}
}
"""
And the class file "src/SkipOnFailure/SpecExample2/FirstFail.php" contains:
"""
<?php
namespace SkipOnFailure\SpecExample2;
class FirstFail
{
public function getValue()
{
return 1;
}
}
"""
When I run phpspec
Then 1 example should have been run
And the exit code should be 1
@issue352
Scenario: stop-on-failure at command line overrides config
Given the config file contains:
"""
stop_on_failure: false
"""
And the spec file "spec/SkipOnFailure/SpecExample3/FirstFailSpec.php" contains:
"""
<?php
namespace spec\SkipOnFailure\SpecExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class FirstFailSpec extends ObjectBehavior
{
function it_fails()
{
$this->getValue()->shouldReturn(2);
}
function it_should_never_get_called()
{
$this->getValue()->shouldReturn(1);
}
}
"""
And the class file "src/SkipOnFailure/SpecExample3/FirstFail.php" contains:
"""
<?php
namespace SkipOnFailure\SpecExample3;
class FirstFail
{
public function getValue()
{
return 1;
}
}
"""
When I run phpspec with the "stop-on-failure" option
Then 1 example should have been run
And the exit code should be 1

View File

@@ -1,183 +0,0 @@
Feature: Developer chooses verbosity output
As a Developer
I want to set the verbose setting option
In order to specify how console output bheaves on failure
Scenario: config verbosity used if console verbosity not quiet
Given the config file contains:
"""
verbose: true
"""
Given the spec file "spec/Verbose/SpecExample1/ConfigVerbosityConsoleNotSetSpec.php" contains:
"""
<?php
namespace spec\Verbose\SpecExample1;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ConfigVerbosityConsoleNotSetSpec extends ObjectBehavior
{
function it_fails()
{
$this->getValue()->shouldReturn([0, 1]);
}
}
"""
And the class file "src/Verbose/SpecExample1/ConfigVerbosityConsoleNotSet.php" contains:
"""
<?php
namespace Verbose\SpecExample1;
class ConfigVerbosityConsoleNotSet
{
public function getValue()
{
return [0];
}
}
"""
When I run phpspec
Then The output should contain:
"""
expected [array:2], but got [array:1].
"""
And The output should contain:
"""
- 1 => 1,
"""
Scenario: config verbosity not set
Given the spec file "spec/Verbose/SpecExample2/ConfigVerbosityNotSetConsoleNotSetSpec.php" contains:
"""
<?php
namespace spec\Verbose\SpecExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ConfigVerbosityNotSetConsoleNotSetSpec extends ObjectBehavior
{
function it_fails()
{
$this->getValue()->shouldReturn([0, 1]);
}
}
"""
And the class file "src/Verbose/SpecExample2/ConfigVerbosityNotSetConsoleNotSet.php" contains:
"""
<?php
namespace Verbose\SpecExample2;
class ConfigVerbosityNotSetConsoleNotSet
{
public function getValue()
{
return [0];
}
}
"""
When I run phpspec
Then The output should contain:
"""
expected [array:2], but got [array:1].
"""
And The output should not contain:
"""
- 1 => 1,
"""
Scenario: config verbosity set to true overriden if console verbosity is quiet
Given the config file contains:
"""
verbose: true
"""
Given the spec file "spec/Verbose/SpecExample3/ConsoleQuietVerbosityOverrideConfigVerbositySpec.php" contains:
"""
<?php
namespace spec\Verbose\SpecExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ConsoleQuietVerbosityOverrideConfigVerbositySpec extends ObjectBehavior
{
function it_fails()
{
$this->getValue()->shouldReturn([0, 1]);
}
}
"""
And the class file "src/Verbose/SpecExample3/ConsoleQuietVerbosityOverrideConfigVerbosity.php" contains:
"""
<?php
namespace Verbose\SpecExample3;
class ConsoleQuitenessOverrideConfigVerbosity
{
public function getValue()
{
return [0];
}
}
"""
When I run phpspec with the "quiet" option
Then Output should not be shown
Scenario: config verbosity set to false overriden if console verbosity set
Given the config file contains:
"""
verbose: false
"""
Given the spec file "spec/Verbose/SpecExample4/ConsoleVerbosityOverrideConfigVerbosityFalseSpec.php" contains:
"""
<?php
namespace spec\Verbose\SpecExample4;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ConsoleVerbosityOverrideConfigVerbosityFalseSpec extends ObjectBehavior
{
function it_fails()
{
$this->getValue()->shouldReturn([0, 1]);
}
}
"""
And the class file "src/Verbose/SpecExample4/ConsoleVerbosityOverrideConfigVerbosityFalse.php" contains:
"""
<?php
namespace Verbose\SpecExample4;
class ConsoleVerbosityOverrideConfigVerbosityFalse
{
public function getValue()
{
return [0];
}
}
"""
When I run phpspec with the "verbose" option
Then The output should contain:
"""
- 1 => 1,
"""

View File

@@ -1,124 +0,0 @@
Feature: Developer is told about pending specs
So that I remember to implement specs
As a Developer
I should be told about specs with missing bodies
Scenario: Empty spec causes pending result
Given the spec file "spec/Runner/PendingExample1/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\PendingExample1;
use PhpSpec\ObjectBehavior;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
}
}
"""
When I run phpspec using the "pretty" format
Then I should see:
"""
9 - converts plain text to html paragraphs
todo: write pending example
1 specs
1 examples (1 pending)
"""
Scenario: Spec with comments causes pending result
Given the spec file "spec/Runner/PendingExample2/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\PendingExample2;
use PhpSpec\ObjectBehavior;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
/**
multi-line doc - comment
*/
/*
multi-line comment
*/
// single-line comment
}
}
"""
When I run phpspec using the "pretty" format
Then I should see:
"""
9 - converts plain text to html paragraphs
todo: write pending example
1 specs
1 examples (1 pending)
"""
@issue492
Scenario: Comments with braces do not confuse the parser
Given the spec file "spec/Runner/PendingExample3/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\PendingExample3;
use PhpSpec\ObjectBehavior;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
pow(2,2);
// {
}
}
"""
When I run phpspec using the "pretty" format
Then I should see:
"""
1 examples (1 passed)
"""
Scenario: Spec defined in trait does not cause pending
Given the trait file "spec/Runner/PendingExample4/PartialSpecTrait.php" contains:
"""
<?php
namespace spec\Runner\PendingExample4;
trait PartialSpecTrait
{
function it_converts_plain_text_to_html_paragraphs()
{
pow(2,2);
}
}
"""
And the spec file "spec/Runner/PendingExample4/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\PendingExample4;
use PhpSpec\ObjectBehavior;
class MarkdownSpec extends ObjectBehavior
{
use PartialSpecTrait;
}
"""
When I run phpspec using the "pretty" format
Then I should see:
"""
1 examples (1 passed)
"""

View File

@@ -1,204 +0,0 @@
Feature: Developer runs the specs
As a Developer
I want to run the specs
In order to get feedback on a state of my application
Scenario: Running a spec with a class that doesn't exist
Given I have started describing the "Runner/SpecExample1/Markdown" class
When I run phpspec
Then I should see "class Runner\SpecExample1\Markdown does not exist"
Scenario: Reporting success when running a spec with correctly implemented class
Given the spec file "spec/Runner/SpecExample2/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\SpecExample2;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/Runner/SpecExample2/Markdown.php" contains:
"""
<?php
namespace Runner\SpecExample2;
class Markdown
{
public function toHtml($text)
{
return sprintf('<p>%s</p>', $text);
}
}
"""
When I run phpspec
Then the suite should pass
@issue214
Scenario: Letgo is executed after successful spec
Given the spec file "spec/Runner/SpecExample3/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\SpecExample3;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function letgo()
{
throw new \Exception('Letgo is called');
}
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/Runner/SpecExample3/Markdown.php" contains:
"""
<?php
namespace Runner\SpecExample3;
class Markdown
{
public function toHtml($text)
{
return sprintf('<p>%s</p>', $text);
}
}
"""
When I run phpspec
Then I should see "Letgo is called"
@issue214
Scenario: Letgo is executed after exception is thrown
Given the spec file "spec/Runner/SpecExample4/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\SpecExample4;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function letgo()
{
throw new \Exception('Letgo is called');
}
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/Runner/SpecExample4/Markdown.php" contains:
"""
<?php
namespace Runner\SpecExample4;
class Markdown
{
public function toHtml($text)
{
throw new \Exception('Some exception');
}
}
"""
When I run phpspec
Then I should see "Letgo is called"
Scenario: Fully qualified class name can run specs
Given the spec file "spec/Runner/Namespace/Example1Spec.php" contains:
"""
<?php
namespace spec\Runner\TestNamespace;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class Example1Spec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Runner\TestNamespace\Example1');
}
}
"""
And the class file "src/Runner/TestNamespace/Example1.php" contains:
"""
<?php
namespace Runner\TestNamespace;
class Example1
{
}
"""
When I run phpspec with the spec "Runner\TestNamespace\Example1"
Then the suite should pass
Scenario: Fully qualified PSR4 class name can run specs
Given the spec file "spec/Runner/Namespace/Example2Spec.php" contains:
"""
<?php
namespace spec\Psr4\Runner\TestNamespace;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class Example2Spec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Psr4\Runner\TestNamespace\Example2');
}
}
"""
And the class file "src/Psr4/Runner/TestNamespace/Example2.php" contains:
"""
<?php
namespace Psr4\Runner\TestNamespace;
class Example2
{
}
"""
And the config file located in "Psr4" contains:
"""
suites:
behat_suite:
namespace: Psr4
psr4_prefix: Psr4
"""
When I run phpspec with the spec "Psr4\Runner\TestNamespace\Example2" and the config "Psr4/phpspec.yml"
Then the suite should pass

View File

@@ -1,31 +0,0 @@
Feature: Developer runs the specs with bootstrap option
As a Developer
I want to run the specs and specify bootstrap file
In order to get feedback on a state of my application
Scenario: Running a spec with --bootstrap option
Given the bootstrap file "bootstrap.php" contains:
"""
<?php
throw new \Exception('bootstrap file is loaded');
"""
When I run phpspec with option --bootstrap=bootstrap.php
Then I should see "bootstrap file is loaded"
Scenario: Running a spec with bootstrap option in config file
Given the bootstrap file "bootstrap.php" contains:
"""
<?php
throw new \Exception('bootstrap file is loaded');
"""
And the config file contains:
"""
bootstrap: bootstrap.php
"""
When I run phpspec
Then I should see "bootstrap file is loaded"
Scenario: Running a spec with --bootstrap option and bootstrap file is missing.
Given there is no file "missing.php"
When I run phpspec with option --bootstrap=missing.php
Then I should see "Bootstrap file 'missing.php' does not exist"

View File

@@ -1,52 +0,0 @@
Feature: Developer runs specs with the given specs path configured to be the same as source path
As a Developer
I want to run the specs from given directory
In order to get feedback on a state of requested part of my application
Scenario: Reporting success when running a spec with correctly implemented class, passing spec path as an argument
Given the config file contains:
"""
suites:
code_generator_suite:
namespace: Runner\SpecPathExample
psr4_prefix: Runner\SpecPathExample
src_path: src/Runner/SpecPathExample
spec_path: src/Runner/SpecPathExample
"""
And the spec file "src/Runner/SpecPathExample/spec/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\SpecPathExample;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_to_html_paragraphs()
{
$this->toHtml('Hi, there')->shouldReturn('<p>Hi, there</p>');
}
}
"""
And the class file "src/Runner/SpecPathExample/Markdown.php" contains:
"""
<?php
namespace Runner\SpecPathExample;
class Markdown
{
public function toHtml($text)
{
return sprintf('<p>%s</p>', $text);
}
}
"""
When I run phpspec with "src/Runner/SpecPathExample/spec" specs to run
Then 1 example should have been run
And the suite should pass

View File

@@ -1,42 +0,0 @@
Feature: Developer skips examples
As a Developer
I want to skip some examples I know won't pass
In order to sanitize my result output
Scenario: Skip a spec with and run it using the dot formatter
Given the spec file "spec/Runner/SpecExample/MarkdownSpec.php" contains:
"""
<?php
namespace spec\Runner\SpecExample;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use PhpSpec\Exception\Example\SkippingException;
class MarkdownSpec extends ObjectBehavior
{
function it_converts_plain_text_table_to_html_table()
{
throw new SkippingException('subject to a php bug');
}
}
"""
And the class file "src/Runner/SpecExample/Markdown.php" contains:
"""
<?php
namespace Runner\SpecExample;
class Markdown
{
public function toHtml($text)
{
}
}
"""
When I run phpspec using the "dot" format
Then 1 example should have been skipped
But the suite should pass

View File

@@ -1,70 +0,0 @@
<?php
namespace integration\PhpSpec\Console\Prompter;
use PhpSpec\Console\Prompter\Question;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Question\ConfirmationQuestion;
/**
* @requires function \Symfony\Component\Console\Helper\QuestionHelper::ask
*/
class QuestionTest extends TestCase
{
/**
* @var \Symfony\Component\Console\Input\InputInterface
*/
private $input;
/**
* @var \Symfony\Component\Console\Output\OutputInterface
*/
private $output;
/**
* @var \Symfony\Component\Console\Helper\QuestionHelper
*/
private $questionHelper;
/**
* @var \PhpSpec\Console\Prompter
*/
private $prompter;
protected function setUp()
{
$this->input = $this->createMock('Symfony\Component\Console\Input\InputInterface');
$this->output = $this->createMock('Symfony\Component\Console\Output\OutputInterface');
$this->questionHelper = $this->createMock('Symfony\Component\Console\Helper\QuestionHelper');
$this->prompter = new Question($this->input, $this->output, $this->questionHelper);
}
/**
* @test
*/
function it_is_a_prompter()
{
$this->assertInstanceOf('PhpSpec\Console\Prompter', $this->prompter);
}
/**
* @test
*/
function it_can_ask_a_question_and_return_the_result()
{
$this->questionHelper->expects($this->once())
->method('ask')
->with(
$this->identicalTo($this->input),
$this->identicalTo($this->output),
$this->equalTo(new ConfirmationQuestion('Are you sure?', true))
)
->willReturn(true);
$result = $this->prompter->askConfirmation('Are you sure?');
$this->assertEquals(true, $result);
}
}

View File

@@ -1,36 +0,0 @@
<?php
namespace integration\PhpSpec\Loader;
use PhpSpec\CodeAnalysis\TokenizedNamespaceResolver;
use PhpSpec\CodeAnalysis\TokenizedTypeHintRewriter;
use PhpSpec\Loader\StreamWrapper;
use PhpSpec\Loader\Transformer\InMemoryTypeHintIndex;
use PhpSpec\Loader\Transformer\TypeHintRewriter;
use PHPUnit\Framework\TestCase;
class StreamWrapperTest extends TestCase
{
function setUp()
{
$wrapper = new StreamWrapper();
$wrapper->addTransformer(new TypeHintRewriter(new TokenizedTypeHintRewriter(new InMemoryTypeHintIndex(), new TokenizedNamespaceResolver())));
StreamWrapper::register();
}
/**
* @test
* @requires PHP 7.0
*/
function it_loads_a_spec_with_no_typehints()
{
require StreamWrapper::wrapPath(__DIR__.'/examples/ExampleSpec.php');
$reflection = new \ReflectionClass('integration\PhpSpec\Loader\examples\ExampleSpec');
$method = $reflection->getMethod('it_requires_a_stdclass');
$parameters = $method->getParameters();
$this->assertNull($parameters[0]->getClass());
}
}

View File

@@ -1,13 +0,0 @@
<?php
namespace integration\PhpSpec\Loader\examples;
use PhpSpec\ObjectBehavior;
class ExampleSpec extends ObjectBehavior
{
function it_requires_a_stdclass(\stdClass $class)
{
}
}

View File

@@ -1,10 +0,0 @@
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.7/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true">
<testsuites>
<testsuite name="PhpSpec">
<directory suffix="Test.php">integration</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@@ -1,98 +0,0 @@
<?php
namespace spec\PhpSpec\CodeAnalysis;
use Phpspec\CodeAnalysis\AccessInspector;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class MagicAwareAccessInspectorSpec extends ObjectBehavior
{
function let(AccessInspector $accessInspector)
{
$this->beConstructedWith($accessInspector);
}
function it_should_be_an_access_inspector()
{
$this->shouldImplement('PhpSpec\CodeAnalysis\AccessInspector');
}
function it_should_detect_a_magic_getter_if_no_value_is_given()
{
$this->isPropertyReadable(new ObjectWithMagicGet, 'property')->shouldReturn(true);
}
function it_should_detect_a_magic_setter_if_a_value_is_given()
{
$this->isPropertyWritable(new ObjectWithMagicSet, 'property', true)->shouldReturn(true);
}
function it_should_detect_a_magic_call_method()
{
$this->isMethodCallable(new ObjectWithMagicCall, 'method')->shouldreturn(true);
}
function it_should_not_detect_a_getter_if_there_is_no_magic_getter_and_wrapped_inspector_finds_none(AccessInspector $accessInspector)
{
$accessInspector->isPropertyReadable(new \StdClass(), 'foo')->willReturn(false);
$this->isPropertyReadable(new \StdClass(), 'foo')->shouldReturn(false);
}
function it_should_detect_a_getter_if_there_is_no_magic_getter_but_wrapped_inspector_finds_one(AccessInspector $accessInspector)
{
$accessInspector->isPropertyReadable(new \StdClass(), 'foo')->willReturn(true);
$this->isPropertyReadable(new \StdClass(), 'foo')->shouldReturn(true);
}
function it_should_not_detect_a_setter_if_there_is_no_magic_setter_and_wrapped_inspector_finds_none(AccessInspector $accessInspector)
{
$accessInspector->isPropertyWritable(new \StdClass(), 'foo')->willReturn(false);
$this->isPropertyWritable(new \StdClass(), 'foo')->shouldReturn(false);
}
function it_should_detect_a_setter_if_there_is_no_magic_setter_but_wrapped_inspector_finds_one(AccessInspector $accessInspector)
{
$accessInspector->isPropertyWritable(new \StdClass(), 'foo')->willReturn(true);
$this->isPropertyWritable(new \StdClass(), 'foo')->shouldReturn(true);
}
function it_should_detect_a_method_if_there_is_no_magic_caller_and_wrapped_inspector_finds_none(AccessInspector $accessInspector)
{
$accessInspector->isMethodCallable(new \StdClass(), 'foo')->willReturn(false);
$this->isMethodCallable(new \StdClass(), 'foo')->shouldReturn(false);
}
function it_should_detect_a_method_if_there_is_no_magic_caller_but_wrapped_inspector_finds_one(AccessInspector $accessInspector)
{
$accessInspector->isMethodCallable(new \StdClass(), 'foo')->willReturn(true);
$this->isMethodCallable(new \StdClass(), 'foo')->shouldReturn(true);
}
}
class ObjectWithMagicGet
{
public function __get($name)
{
}
}
class ObjectWithMagicSet
{
public function __set($name, $value)
{
}
}
class ObjectWithMagicCall
{
public function __call($name, $args)
{
}
}

View File

@@ -1,44 +0,0 @@
<?php
namespace spec\PhpSpec\CodeAnalysis;
use PhpSpec\CodeAnalysis\DisallowedNonObjectTypehintException;
use PhpSpec\CodeAnalysis\NamespaceResolver;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class StaticRejectingNamespaceResolverSpec extends ObjectBehavior
{
function let(NamespaceResolver $namespaceResolver)
{
$this->beConstructedWith($namespaceResolver);
}
function it_is_initializable()
{
$this->shouldHaveType('PhpSpec\CodeAnalysis\NamespaceResolver');
}
function it_delegates_analysis_to_wrapped_resolver(NamespaceResolver $namespaceResolver)
{
$this->analyse('foo');
$namespaceResolver->analyse('foo')->shouldhaveBeenCalled();
}
function it_delegates_resolution_to_wrapped_resolver(NamespaceResolver $namespaceResolver)
{
$namespaceResolver->resolve('Bar')->willReturn('Foo\Bar');
$this->resolve('Bar')->shouldReturn('Foo\Bar');
}
function it_does_not_allow_resolution_of_non_object_types()
{
$this->shouldThrow(DisallowedNonObjectTypehintException::class)->duringResolve('int');
$this->shouldThrow(DisallowedNonObjectTypehintException::class)->duringResolve('float');
$this->shouldThrow(DisallowedNonObjectTypehintException::class)->duringResolve('string');
$this->shouldThrow(DisallowedNonObjectTypehintException::class)->duringResolve('bool');
$this->shouldThrow(DisallowedNonObjectTypehintException::class)->duringResolve('iterable');
}
}

View File

@@ -1,128 +0,0 @@
<?php
namespace spec\PhpSpec\CodeAnalysis;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class TokenizedNamespaceResolverSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('PhpSpec\CodeAnalysis\NamespaceResolver');
}
function it_resolves_types_outside_of_namespaces()
{
$this->analyse('
<?php
class Foo
{
}
');
$this->resolve('Bar')->shouldReturn('Bar');
$this->resolve('Bar')->shouldReturn('Bar');
}
function it_resolves_types_from_current_namespace()
{
$this->analyse('
<?php
namespace Baz;
class Foo
{
}
');
$this->resolve('Foo')->shouldReturn('Baz\Foo');
$this->resolve('Bar')->shouldReturn('Baz\Bar');
}
function it_resolves_types_with_use_statements()
{
$this->analyse('
<?php
namespace Baz;
use Boz\Bar;
class Foo
{
}
');
$this->resolve('Foo')->shouldReturn('Baz\Foo');
$this->resolve('Bar')->shouldReturn('Boz\Bar');
}
function it_resolves_types_with_use_aliases()
{
$this->analyse('
<?php
namespace Baz;
use Boz\Bar as Biz;
class Foo
{
}
');
$this->resolve('Foo')->shouldReturn('Baz\Foo');
$this->resolve('Biz')->shouldReturn('Boz\Bar');
}
function it_resolves_types_with_partial_use_statements()
{
$this->analyse('
<?php
namespace Baz;
use Boz\Bar;
class Foo
{
function it_something(Bar\Baz $boz)
{
}
}
');
$this->resolve('Foo')->shouldReturn('Baz\Foo');
$this->resolve('Bar\Baz')->shouldReturn('Boz\Bar\Baz');
}
function it_resolves_types_from_grouped_use_statements()
{
$this->analyse('
<?php
namespace Baz;
use Boz\{Fiz, Buz};
class Foo
{
function it_something(Fiz $fiz, Buz $buz)
{
}
}
');
$this->resolve('Fiz')->shouldReturn('Boz\Fiz');
$this->resolve('Buz')->shouldReturn('Boz\Buz');
}
}

View File

@@ -1,258 +0,0 @@
<?php
namespace spec\PhpSpec\CodeAnalysis;
use PhpSpec\CodeAnalysis\DisallowedNonObjectTypehintException;
use PhpSpec\CodeAnalysis\NamespaceResolver;
use PhpSpec\Loader\Transformer\TypeHintIndex;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class TokenizedTypeHintRewriterSpec extends ObjectBehavior
{
function let(TypeHintIndex $typeHintIndex, NamespaceResolver $namespaceResolver)
{
$this->beConstructedWith($typeHintIndex, $namespaceResolver);
$namespaceResolver->resolve(Argument::cetera())->willReturn('someClass');
$namespaceResolver->analyse(Argument::any())->shouldBeCalled();
}
function it_is_a_typehint_rewriter(TypeHintIndex $typeHintIndex, NamespaceResolver $namespaceResolver)
{
$this->beConstructedWith($typeHintIndex, $namespaceResolver);
$namespaceResolver->resolve(Argument::cetera())->willReturn('someClass');
$namespaceResolver->analyse(Argument::any())->shouldNotBeCalled();
$this->shouldHaveType('PhpSpec\CodeAnalysis\TypeHintRewriter');
}
function it_leaves_alone_specs_with_no_typehints()
{
$this->rewrite('
<?php
class FooSpec
{
public function bar()
{
}
}
')->shouldReturn('
<?php
class FooSpec
{
public function bar()
{
}
}
');
}
function it_removes_typehints_from_single_argument_methods()
{
$this->rewrite('
<?php
class FooSpec
{
public function bar(\Foo\Bar $bar)
{
}
}
')->shouldReturn('
<?php
class FooSpec
{
public function bar( $bar)
{
}
}
');
}
function it_does_not_remove_typehints_in_methods()
{
$this->rewrite('
<?php
class FooSpec
{
public function bar(\Foo\Bar $bar)
{
new class($argument) implements InterfaceName
{
public function foo(Foo $foo) {}
};
}
}
')->shouldReturn('
<?php
class FooSpec
{
public function bar( $bar)
{
new class($argument) implements InterfaceName
{
public function foo(Foo $foo) {}
};
}
}
');
}
function it_removes_typehints_for_multiple_arguments_in_methods()
{
$this->rewrite('
<?php
class FooSpec
{
public function bar(Bar $bar, Baz $baz)
{
}
}
')->shouldReturn('
<?php
class FooSpec
{
public function bar( $bar, $baz)
{
}
}
');
}
function it_indexes_typehints_that_are_removed(TypeHintIndex $typeHintIndex, NamespaceResolver $namespaceResolver)
{
$namespaceResolver->analyse(Argument::any())->shouldBeCalled();
$namespaceResolver->resolve('FooSpec')->willReturn('FooSpec');
$namespaceResolver->resolve('Foo\Bar')->willReturn('Foo\Bar');
$namespaceResolver->resolve('Baz')->willReturn('Baz');
$this->rewrite('
<?php
class FooSpec
{
public function bar(Foo\Bar $bar, Baz $baz)
{
}
}
');
$typeHintIndex->add('FooSpec', 'bar', '$bar', 'Foo\Bar')->shouldHaveBeenCalled();
$typeHintIndex->add('FooSpec', 'bar', '$baz', 'Baz')->shouldHaveBeenCalled();
}
function it_indexes_invalid_typehints(
TypeHintIndex $typeHintIndex,
NamespaceResolver $namespaceResolver
) {
$e = new DisallowedNonObjectTypehintException();
$namespaceResolver->analyse(Argument::any())->shouldBeCalled();
$namespaceResolver->resolve('FooSpec')->willReturn('FooSpec');
$namespaceResolver->resolve('int')->willThrow($e);
$this->rewrite('
<?php
class FooSpec
{
public function bar(int $bar)
{
}
}
');
$typeHintIndex->addInvalid('FooSpec', 'bar', '$bar', $e)->shouldHaveBeenCalled();
$typeHintIndex->add('FooSpec', 'bar', '$bar', Argument::any())->shouldNotHaveBeenCalled();
}
function it_preserves_line_numbers()
{
$this->rewrite('
<?php
class FooSpec
{
public function(
$foo,
array $bar,
Foo\Bar $arg3,
$arg4
)
{
}
}
')->shouldReturn('
<?php
class FooSpec
{
public function(
$foo,
array $bar,
$arg3,
$arg4
)
{
}
}
');
}
function it_do_not_remove_typehints_of_non_spec_classes()
{
$this->rewrite('
<?php
class FooSpec
{
public function bar(Bar $bar, Baz $baz)
{
}
}
class Bar
{
public function foo(Baz $baz)
{
}
}
')->shouldReturn('
<?php
class FooSpec
{
public function bar( $bar, $baz)
{
}
}
class Bar
{
public function foo(Baz $baz)
{
}
}
');
}
}

View File

@@ -1,80 +0,0 @@
<?php
namespace spec\PhpSpec\CodeAnalysis;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class VisibilityAccessInspectorSpec extends ObjectBehavior
{
function it_should_be_an_access_inspector()
{
$this->shouldImplement('PhpSpec\CodeAnalysis\AccessInspector');
}
function it_should_reject_an_object_if_the_property_does_not_exist()
{
$this->isPropertyReadable(new ObjectWithNoProperty, 'property')->shouldReturn(false);
$this->isPropertyWritable(new ObjectWithNoProperty, 'property')->shouldReturn(false);
}
function it_should_reject_a_private_property()
{
$this->isPropertyReadable(new ObjectWithPrivateProperty, 'property')->shouldReturn(false);
$this->isPropertyWritable(new ObjectWithPrivateProperty, 'property')->shouldReturn(false);
}
function it_should_detect_a_public_property()
{
$this->isPropertyReadable(new ObjectWithPublicProperty, 'property')->shouldReturn(true);
$this->isPropertyWritable(new ObjectWithPublicProperty, 'property')->shouldReturn(true);
}
function it_should_reject_an_object_if_a_method_does_not_exist()
{
$this->isMethodCallable(new ObjectWithNoMethod, 'method')->shouldReturn(false);
}
function it_should_reject_a_private_method()
{
$this->isMethodCallable(new ObjectWithPrivateMethod, 'method')->shouldReturn(false);
}
function it_should_detect_a_public_method()
{
$this->isMethodCallable(new ObjectWithPublicMethod, 'method')->shouldReturn(true);
}
}
class ObjectWithNoProperty
{
}
class ObjectWithPrivateProperty
{
private $property;
}
class ObjectWithPublicProperty
{
public $property;
}
class ObjectWithNoMethod
{
}
class ObjectWithPrivateMethod
{
private function method()
{
}
}
class ObjectWithPublicMethod
{
public function method()
{
}
}

View File

@@ -1,143 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator\Generator;
use PhpSpec\ObjectBehavior;
use PhpSpec\Process\Context\ExecutionContext;
use Prophecy\Argument;
use PhpSpec\Console\ConsoleIO;
use PhpSpec\CodeGenerator\TemplateRenderer;
use PhpSpec\Util\Filesystem;
use PhpSpec\Locator\Resource;
class ClassGeneratorSpec extends ObjectBehavior
{
function let(ConsoleIO $io, TemplateRenderer $tpl, Filesystem $fs, ExecutionContext $executionContext)
{
$this->beConstructedWith($io, $tpl, $fs, $executionContext);
}
function it_is_a_generator()
{
$this->shouldBeAnInstanceOf('PhpSpec\CodeGenerator\Generator\Generator');
}
function it_supports_class_generation(Resource $resource)
{
$this->supports($resource, 'class', array())->shouldReturn(true);
}
function it_does_not_support_anything_else(Resource $resource)
{
$this->supports($resource, 'anything_else', array())->shouldReturn(false);
}
function its_priority_is_0()
{
$this->getPriority()->shouldReturn(0);
}
function it_generates_class_from_resource_and_puts_it_into_appropriate_folder(
$io, TemplateRenderer $tpl, $fs, Resource $resource
) {
$resource->getName()->willReturn('App');
$resource->getSrcFilename()->willReturn('/project/src/Acme/App.php');
$resource->getSrcNamespace()->willReturn('Acme');
$resource->getSrcClassname()->willReturn('Acme\App');
$values = array(
'%filepath%' => '/project/src/Acme/App.php',
'%name%' => 'App',
'%namespace%' => 'Acme',
'%namespace_block%' => "\n\nnamespace Acme;",
);
$tpl->render('class', $values)->willReturn('');
$tpl->renderString(Argument::type('string'), $values)->willReturn('generated code');
$fs->pathExists('/project/src/Acme/App.php')->willReturn(false);
$fs->isDirectory('/project/src/Acme')->willReturn(true);
$fs->putFileContents('/project/src/Acme/App.php', 'generated code')->shouldBeCalled();
$this->generate($resource);
}
function it_uses_template_provided_by_templating_system_if_there_is_one(
$io, $tpl, $fs, Resource $resource
) {
$resource->getName()->willReturn('App');
$resource->getSrcFilename()->willReturn('/project/src/Acme/App.php');
$resource->getSrcNamespace()->willReturn('Acme');
$resource->getSrcClassname()->willReturn('Acme\App');
$values = array(
'%filepath%' => '/project/src/Acme/App.php',
'%name%' => 'App',
'%namespace%' => 'Acme',
'%namespace_block%' => "\n\nnamespace Acme;",
);
$tpl->render('class', $values)->willReturn('template code');
$tpl->renderString(Argument::type('string'), $values)->willReturn('generated code');
$fs->pathExists('/project/src/Acme/App.php')->willReturn(false);
$fs->isDirectory('/project/src/Acme')->willReturn(true);
$fs->putFileContents('/project/src/Acme/App.php', 'template code')->shouldBeCalled();
$this->generate($resource);
}
function it_creates_folder_for_class_if_needed($io, TemplateRenderer $tpl, $fs, Resource $resource)
{
$tpl->render('class', Argument::type('array'))->willReturn('rendered string');
$resource->getName()->willReturn('App');
$resource->getSrcFilename()->willReturn('/project/src/Acme/App.php');
$resource->getSrcNamespace()->willReturn('Acme');
$resource->getSrcClassname()->willReturn('Acme\App');
$fs->pathExists('/project/src/Acme/App.php')->willReturn(false);
$fs->isDirectory('/project/src/Acme')->willReturn(false);
$fs->makeDirectory('/project/src/Acme')->shouldBeCalled();
$fs->putFileContents('/project/src/Acme/App.php', Argument::any())->willReturn(null);
$this->generate($resource);
}
function it_asks_confirmation_if_class_already_exists(
$io, $tpl, $fs, Resource $resource
) {
$resource->getName()->willReturn('App');
$resource->getSrcFilename()->willReturn('/project/src/Acme/App.php');
$resource->getSrcNamespace()->willReturn('Acme');
$resource->getSrcClassname()->willReturn('Acme\App');
$fs->pathExists('/project/src/Acme/App.php')->willReturn(true);
$io->askConfirmation(Argument::type('string'), false)->willReturn(false);
$fs->putFileContents(Argument::cetera())->shouldNotBeCalled();
$this->generate($resource);
}
function it_records_that_class_was_created_in_executioncontext(
Resource $resource,
ExecutionContext $executionContext,
TemplateRenderer $tpl,
Filesystem $fs
) {
$tpl->render('class', Argument::type('array'))->willReturn('rendered string');
$fs->isDirectory('/project/src/Acme')->willReturn(true);
$fs->pathExists('/project/src/Acme/App.php')->willReturn(false);
$fs->putFileContents('/project/src/Acme/App.php', Argument::any())->shouldBeCalled();
$resource->getName()->willReturn('App');
$resource->getSrcFilename()->willReturn('/project/src/Acme/App.php');
$resource->getSrcNamespace()->willReturn('Acme');
$resource->getSrcClassname()->willReturn('Acme\App');
$this->generate($resource);
$executionContext->addGeneratedType('Acme\App')->shouldHaveBeenCalled();
}
}

View File

@@ -1,57 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator\Generator;
use PhpSpec\CodeGenerator\Generator\Generator;
use PhpSpec\Console\ConsoleIO;
use PhpSpec\ObjectBehavior;
use PhpSpec\Locator\Resource;
class ConfirmingGeneratorSpec extends ObjectBehavior
{
function let(ConsoleIO $io, Generator $generator)
{
$this->beConstructedWith($io, 'Question for {CLASSNAME}', $generator);
}
function it_is_a_Generator()
{
$this->shouldHaveType('PhpSpec\CodeGenerator\Generator\Generator');
}
function it_supports_the_same_generator_as_its_parent(Generator $generator, Resource $resource)
{
$generator->supports($resource, 'generation', array())->willReturn(true);
$this->supports($resource, 'generation', array())->shouldReturn(true);
}
function it_has_the_same_priority_as_its_parent(Generator $generator)
{
$generator->getPriority()->willReturn(1324);
$this->getPriority()->shouldReturn(1324);
}
function it_does_not_call_the_parent_generate_method_if_the_user_answers_no(Generator $generator, Resource $resource, ConsoleIO $io)
{
$resource->getSrcClassname()->willReturn('Namespace/Classname');
$io->askConfirmation('Question for Namespace/Classname')->willReturn(false);
$this->generate($resource, array());
$generator->generate($resource, array())->shouldNotHaveBeenCalled();
}
function it_calls_the_parent_generate_method_if_the_user_answers_yes(Generator $generator, Resource $resource, ConsoleIO $io)
{
$resource->getSrcClassname()->willReturn('Namespace/Classname');
$io->askConfirmation('Question for Namespace/Classname')->willReturn(true);
$this->generate($resource, array());
$generator->generate($resource, array())->shouldHaveBeenCalled();
}
}

View File

@@ -1,82 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator\Generator;
use PhpSpec\CodeGenerator\Writer\CodeWriter;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use PhpSpec\Console\ConsoleIO;
use PhpSpec\CodeGenerator\TemplateRenderer;
use PhpSpec\Util\Filesystem;
use PhpSpec\Locator\Resource;
class MethodGeneratorSpec extends ObjectBehavior
{
function let(ConsoleIO $io, TemplateRenderer $tpl, Filesystem $fs, CodeWriter $codeWriter)
{
$this->beConstructedWith($io, $tpl, $fs, $codeWriter);
}
function it_is_a_generator()
{
$this->shouldBeAnInstanceOf('PhpSpec\CodeGenerator\Generator\Generator');
}
function it_supports_method_generation(Resource $resource)
{
$this->supports($resource, 'method', array())->shouldReturn(true);
}
function it_does_not_support_anything_else(Resource $resource)
{
$this->supports($resource, 'anything_else', array())->shouldReturn(false);
}
function its_priority_is_0()
{
$this->getPriority()->shouldReturn(0);
}
function it_generates_class_method_from_resource($io, $tpl, $fs, Resource $resource, CodeWriter $codeWriter)
{
$codeWithoutMethod = <<<CODE
<?php
namespace Acme;
class App
{
}
CODE;
$codeWithMethod = <<<CODE
<?php
namespace Acme;
class App
{
METHOD
}
CODE;
$values = array(
'%name%' => 'setName',
'%arguments%' => '$argument1',
);
$resource->getSrcFilename()->willReturn('/project/src/Acme/App.php');
$resource->getSrcClassname()->willReturn('Acme\App');
$tpl->render('method', $values)->willReturn('');
$tpl->renderString(Argument::type('string'), $values)->willReturn('METHOD');
$codeWriter->insertMethodLastInClass($codeWithoutMethod, 'METHOD')->willReturn($codeWithMethod);
$fs->getFileContents('/project/src/Acme/App.php')->willReturn($codeWithoutMethod);
$fs->putFileContents('/project/src/Acme/App.php', $codeWithMethod)->shouldBeCalled();
$this->generate($resource, array('name' => 'setName', 'arguments' => array('everzet')));
}
}

View File

@@ -1,85 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator\Generator;
use PhpSpec\CodeGenerator\TemplateRenderer;
use PhpSpec\CodeGenerator\Writer\CodeWriter;
use PhpSpec\Console\ConsoleIO;
use PhpSpec\Locator\Resource;
use PhpSpec\ObjectBehavior;
use PhpSpec\Util\Filesystem;
use Prophecy\Argument;
class NamedConstructorGeneratorSpec extends ObjectBehavior
{
function let(ConsoleIO $io, TemplateRenderer $tpl, Filesystem $fs, CodeWriter $codeWriter)
{
$this->beConstructedWith($io, $tpl, $fs, $codeWriter);
}
function it_is_a_generator()
{
$this->shouldBeAnInstanceOf('PhpSpec\CodeGenerator\Generator\Generator');
}
function it_supports_static_constructor_generation(Resource $resource)
{
$this->supports($resource, 'named_constructor', array())->shouldReturn(true);
}
function it_does_not_support_anything_else(Resource $resource)
{
$this->supports($resource, 'anything_else', array())->shouldReturn(false);
}
function its_priority_is_0()
{
$this->getPriority()->shouldReturn(0);
}
function it_generates_static_constructor_method_from_resource($io, $tpl, $fs, Resource $resource, CodeWriter $codeWriter)
{
$codeWithoutMethod = <<<CODE
<?php
namespace Acme;
class App
{
}
CODE;
$codeWithMethod = <<<CODE
<?php
namespace Acme;
class App
{
METHOD
}
CODE;
$values = array(
'%methodName%' => 'setName',
'%arguments%' => '$argument1',
'%returnVar%' => '$app',
'%className%' => 'App',
'%constructorArguments%' => ''
);
$resource->getSrcFilename()->willReturn('/project/src/Acme/App.php');
$resource->getSrcClassname()->willReturn('Acme\App');
$resource->getName()->willReturn('App');
$tpl->render('named_constructor_create_object', $values)->willReturn('');
$tpl->renderString(Argument::type('string'), $values)->willReturn('METHOD');
$codeWriter->insertAfterMethod($codeWithoutMethod, '__construct', 'METHOD')->willReturn($codeWithMethod);
$fs->getFileContents('/project/src/Acme/App.php')->willReturn($codeWithoutMethod);
$fs->putFileContents('/project/src/Acme/App.php', $codeWithMethod)->shouldBeCalled();
$this->generate($resource, array('name' => 'setName', 'arguments' => array('jmurphy')));
}
}

View File

@@ -1,119 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator\Generator;
use PhpSpec\CodeGenerator\Generator\Generator;
use PhpSpec\Event\FileCreationEvent;
use PhpSpec\Locator\Resource;
use PhpSpec\ObjectBehavior;
use PhpSpec\Util\Filesystem;
use Prophecy\Argument;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class NewFileNotifyingGeneratorSpec extends ObjectBehavior
{
const EVENT_CLASS = 'PhpSpec\Event\FileCreationEvent';
public function let(Generator $generator, EventDispatcherInterface $dispatcher, Filesystem $filesystem)
{
$this->beConstructedWith($generator, $dispatcher, $filesystem);
}
function it_is_a_code_generator()
{
$this->shouldImplement('PhpSpec\CodeGenerator\Generator\Generator');
}
function it_should_proxy_the_support_call_to_the_decorated_object($generator, Resource $resource)
{
$generator->supports($resource, 'foo', array('bar'))->willReturn(true);
$this->supports($resource, 'foo', array('bar'))->shouldReturn(true);
}
function it_should_proxy_the_priority_call_to_the_decorated_object($generator)
{
$generator->getPriority()->willReturn(5);
$this->getPriority()->shouldReturn(5);
}
function it_should_proxy_the_generate_call_to_the_decorated_object(Generator $generator, Resource $resource, Filesystem $filesystem)
{
$generator->supports(Argument::cetera())->willReturn(true);
$resource->getSpecFilename()->willReturn('');
$filesystem->pathExists(Argument::any())->willReturn(true);
$generator->generate($resource, array())->shouldBeCalled();
$this->generate($resource, array());
}
function it_should_dispatch_an_event_when_a_file_is_created(Generator $generator, $dispatcher, $filesystem, Resource $resource)
{
$generator->supports(Argument::cetera())->willReturn(false);
$path = '/foo';
$resource->getSrcFilename()->willReturn($path);
$event = new FileCreationEvent($path);
$filesystem->pathExists($path)->willReturn(false, true);
$generator->generate($resource, array())->shouldBeCalled();
$this->generate($resource, array());
$dispatcher->dispatch('afterFileCreation', $event)->shouldHaveBeenCalled();
}
function it_should_dispatch_an_event_with_the_spec_path_when_a_spec_is_created($generator, $dispatcher, $filesystem, Resource $resource)
{
$path = '/foo';
$generator->supports($resource, 'specification', array())->willReturn(true);
$generator->generate(Argument::cetera())->shouldBeCalled();
$resource->getSpecFilename()->willReturn($path);
$filesystem->pathExists($path)->willReturn(false, true);
$event = new FileCreationEvent($path);
$this->generate($resource, array());
$dispatcher->dispatch('afterFileCreation', $event)->shouldHaveBeenCalled();
}
function it_should_check_that_the_file_was_created($generator, $filesystem, Resource $resource)
{
$path = '/foo';
$resource->getSrcFilename()->willReturn($path);
$filesystem->pathExists($path)->willReturn(false);
$generator->supports(Argument::cetera())->willReturn(false);
$generator->generate($resource, array())->will(function () use ($filesystem, $path) {
$filesystem->pathExists($path)->willReturn(true);
});
$this->generate($resource, array());
}
function it_should_not_dispatch_an_event_if_the_file_was_not_created(Generator $generator, $dispatcher, $filesystem, Resource $resource)
{
$generator->supports(Argument::cetera())->willReturn(false);
$generator->generate($resource, array())->shouldBeCalled();
$path = '/foo';
$resource->getSrcFilename()->willReturn($path);
$filesystem->pathExists($path)->willReturn(false);
$this->generate($resource, array());
$dispatcher->dispatch('afterFileCreation', Argument::any())->shouldNotHaveBeenCalled();
}
function it_should_not_dispatch_an_event_if_the_file_already_existed(Generator $generator, $dispatcher, $filesystem, Resource $resource)
{
$generator->supports(Argument::cetera())->willReturn(false);
$generator->generate($resource, array())->shouldBeCalled();
$path = '/foo';
$resource->getSrcFilename()->willReturn($path);
$filesystem->pathExists($path)->willReturn(true);
$this->generate($resource, array());
$dispatcher->dispatch('afterFileCreation', Argument::any())->shouldNotHaveBeenCalled();
}
}

View File

@@ -1,54 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator\Generator;
use PhpSpec\CodeGenerator\Generator\Generator;
use PhpSpec\ObjectBehavior;
use PhpSpec\Locator\Resource;
class OneTimeGeneratorSpec extends ObjectBehavior
{
function let(Generator $generator)
{
$this->beConstructedWith($generator);
}
function it_is_a_Generator()
{
$this->shouldHaveType('PhpSpec\CodeGenerator\Generator\Generator');
}
function it_supports_the_same_generator_as_its_parent(Generator $generator, Resource $resource)
{
$generator->supports($resource, 'generation', array())->willReturn(true);
$this->supports($resource, 'generation', array())->shouldReturn(true);
}
function it_has_the_same_priority_as_its_parent(Generator $generator)
{
$generator->getPriority()->willReturn(1324);
$this->getPriority()->shouldReturn(1324);
}
function it_calls_the_parent_generate_method_just_once_for_the_same_classname(Generator $generator, Resource $resource)
{
$resource->getSrcClassname()->willReturn('Namespace/Classname');
$this->generate($resource, array());
$this->generate($resource, array());
$generator->generate($resource, array())->shouldHaveBeenCalledTimes(1);
}
function it_calls_the_parent_generate_method_once_per_each_classname(Generator $generator, Resource $resource)
{
$resource->getSrcClassname()->willReturn('Namespace/Classname1', 'Namespace/Classname2');
$this->generate($resource, array());
$this->generate($resource, array());
$generator->generate($resource, array())->shouldHaveBeenCalledTimes(2);
}
}

View File

@@ -1,38 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator\Generator;
use PhpSpec\CodeGenerator\TemplateRenderer;
use PhpSpec\Console\ConsoleIO;
use PhpSpec\ObjectBehavior;
use PhpSpec\Util\Filesystem;
use Prophecy\Argument;
use PhpSpec\Locator\Resource;
class ReturnConstantGeneratorSpec extends ObjectBehavior
{
function let(ConsoleIO $io, TemplateRenderer $templates, Filesystem $filesystem)
{
$this->beConstructedWith($io, $templates, $filesystem);
}
function it_is_a_generator()
{
$this->shouldHaveType('PhpSpec\CodeGenerator\Generator\Generator');
}
function it_supports_returnConstant_generation(Resource $resource)
{
$this->supports($resource, 'returnConstant', array())->shouldReturn(true);
}
function it_does_not_support_anything_else(Resource $resource)
{
$this->supports($resource, 'anything_else', array())->shouldReturn(false);
}
function its_priority_is_0()
{
$this->getPriority()->shouldReturn(0);
}
}

View File

@@ -1,129 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator\Generator;
use PhpSpec\ObjectBehavior;
use PhpSpec\Process\Context\ExecutionContext;
use Prophecy\Argument;
use PhpSpec\Console\ConsoleIO;
use PhpSpec\CodeGenerator\TemplateRenderer;
use PhpSpec\Util\Filesystem;
use PhpSpec\Locator\Resource;
class SpecificationGeneratorSpec extends ObjectBehavior
{
function let(ConsoleIO $io, TemplateRenderer $tpl, Filesystem $fs, ExecutionContext $context)
{
$this->beConstructedWith($io, $tpl, $fs, $context);
}
function it_is_a_generator()
{
$this->shouldBeAnInstanceOf('PhpSpec\CodeGenerator\Generator\Generator');
}
function it_supports_specification_generations(Resource $resource)
{
$this->supports($resource, 'specification', array())->shouldReturn(true);
}
function it_does_not_support_anything_else(Resource $resource)
{
$this->supports($resource, 'anything_else', array())->shouldReturn(false);
}
function its_priority_is_0()
{
$this->getPriority()->shouldReturn(0);
}
function it_generates_spec_class_from_resource_and_puts_it_into_appropriate_folder(
$io, $tpl, $fs, Resource $resource
) {
$resource->getSpecName()->willReturn('AppSpec');
$resource->getSpecFilename()->willReturn('/project/spec/Acme/AppSpec.php');
$resource->getSpecNamespace()->willReturn('spec\Acme');
$resource->getSrcClassname()->willReturn('Acme\App');
$resource->getName()->willReturn('App');
$values = array(
'%filepath%' => '/project/spec/Acme/AppSpec.php',
'%name%' => 'AppSpec',
'%namespace%' => 'spec\Acme',
'%imports%' => "use Acme\App;\nuse PhpSpec\ObjectBehavior;\nuse Prophecy\Argument;",
'%subject%' => 'Acme\App',
'%subject_class%' => 'App',
);
$tpl->render('specification', $values)->willReturn('');
$tpl->renderString(Argument::type('string'), $values)->willReturn('generated code');
$fs->pathExists('/project/spec/Acme/AppSpec.php')->willReturn(false);
$fs->isDirectory('/project/spec/Acme')->willReturn(true);
$fs->putFileContents('/project/spec/Acme/AppSpec.php', 'generated code')->shouldBeCalled();
$this->generate($resource);
}
function it_uses_template_provided_by_templating_system_if_there_is_one(
$io, $tpl, $fs, Resource $resource
) {
$resource->getSpecName()->willReturn('AppSpec');
$resource->getSpecFilename()->willReturn('/project/spec/Acme/AppSpec.php');
$resource->getSpecNamespace()->willReturn('spec\Acme');
$resource->getSrcClassname()->willReturn('Acme\App');
$resource->getName()->willReturn('App');
$values = array(
'%filepath%' => '/project/spec/Acme/AppSpec.php',
'%name%' => 'AppSpec',
'%namespace%' => 'spec\Acme',
'%imports%' => "use Acme\App;\nuse PhpSpec\ObjectBehavior;\nuse Prophecy\Argument;",
'%subject%' => 'Acme\App',
'%subject_class%' => 'App',
);
$tpl->render('specification', $values)->willReturn('template code');
$tpl->renderString(Argument::type('string'), $values)->willReturn('generated code');
$fs->pathExists('/project/spec/Acme/AppSpec.php')->willReturn(false);
$fs->isDirectory('/project/spec/Acme')->willReturn(true);
$fs->putFileContents('/project/spec/Acme/AppSpec.php', 'template code')->shouldBeCalled();
$this->generate($resource);
}
function it_creates_folder_for_spec_if_needed($io, TemplateRenderer $tpl, $fs, Resource $resource)
{
$tpl->render('specification', Argument::type('array'))->willReturn('rendered string');
$resource->getSpecName()->willReturn('AppAppSpec');
$resource->getSpecFilename()->willReturn('/project/spec/Acme/AppSpec.php');
$resource->getSpecNamespace()->willReturn('spec\Acme');
$resource->getSrcClassname()->willReturn('Acme\App');
$resource->getName()->willReturn('App');
$fs->pathExists('/project/spec/Acme/AppSpec.php')->willReturn(false);
$fs->isDirectory('/project/spec/Acme')->willReturn(false);
$fs->makeDirectory('/project/spec/Acme')->shouldBeCalled();
$fs->putFileContents('/project/spec/Acme/AppSpec.php', Argument::any())->willReturn(null);
$this->generate($resource);
}
function it_asks_confirmation_if_spec_already_exists(
$io, $tpl, $fs, Resource $resource
) {
$resource->getSpecName()->willReturn('AppSpec');
$resource->getSpecFilename()->willReturn('/project/spec/Acme/AppSpec.php');
$resource->getSpecNamespace()->willReturn('spec\Acme');
$resource->getSrcClassname()->willReturn('Acme\App');
$fs->pathExists('/project/spec/Acme/AppSpec.php')->willReturn(true);
$io->askConfirmation(Argument::type('string'), false)->willReturn(false);
$fs->putFileContents(Argument::cetera())->shouldNotBeCalled();
$this->generate($resource);
}
}

View File

@@ -1,75 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator\Generator;
use PhpSpec\CodeGenerator\Generator\ValidateClassNameSpecificationGenerator;
use PhpSpec\CodeGenerator\Generator\Generator;
use PhpSpec\CodeGenerator\Generator\SpecificationGenerator;
use PhpSpec\Console\ConsoleIO;
use PhpSpec\Locator\Resource;
use PhpSpec\ObjectBehavior;
use PhpSpec\Util\NameChecker;
use Prophecy\Argument;
class ValidateClassNameSpecificationGeneratorSpec extends ObjectBehavior
{
function let(NameChecker $classNameChecker, ConsoleIO $io, Generator $originalGenerator)
{
$this->beConstructedWith($classNameChecker, $io, $originalGenerator);
}
function it_is_initializable()
{
$this->shouldHaveType(ValidateClassNameSpecificationGenerator::class);
}
function it_supports_generation_when_original_generator_supports_it(
Generator $originalGenerator,
Resource $resource
) {
$originalGenerator->supports($resource, '', [])->willReturn(true);
$this->supports($resource, '', [])->shouldReturn(true);
}
function it_does_not_support_generation_when_original_generator_doesnt(
Generator $originalGenerator,
Resource $resource
) {
$originalGenerator->supports($resource, '', [])->willReturn(false);
$this->supports($resource, '', [])->shouldReturn(false);
}
function it_delegates_generation_to_original_generator_for_valid_class_name(
Generator $originalGenerator,
Resource $resource,
NameChecker $classNameChecker
) {
$className = 'Acme\Markdown';
$resource->getSrcClassname()->willReturn($className);
$classNameChecker->isNameValid($className)->willReturn(true);
$originalGenerator->generate($resource, [])->shouldBeCalled();
$this->generate($resource, []);
}
function it_prints_error_and_skips_generation_for_invalid_class_name(
Generator $originalGenerator,
Resource $resource,
NameChecker $classNameChecker,
ConsoleIO $io
) {
$className = 'Acme\Markdown';
$resource->getSrcClassname()->willReturn($className);
$classNameChecker->isNameValid($className)->willReturn(false);
$io->writeBrokenCodeBlock(Argument::containingString('because class name contains reserved keyword'), 2)->shouldBeCalled();
$originalGenerator->generate($resource, [])->shouldNotBeCalled();
$this->generate($resource, []);
}
}

View File

@@ -1,46 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use PhpSpec\CodeGenerator\Generator\Generator;
use PhpSpec\Locator\Resource;
class GeneratorManagerSpec extends ObjectBehavior
{
function it_uses_registered_generators_to_generate_code(
Generator $generator, Resource $resource
) {
$generator->getPriority()->willReturn(0);
$generator->supports($resource, 'specification', array())->willReturn(true);
$generator->generate($resource, array())->shouldBeCalled();
$this->registerGenerator($generator);
$this->generate($resource, 'specification');
}
function it_chooses_generator_by_priority(
Generator $generator1, Generator $generator2, Resource $resource
) {
$generator1->supports($resource, 'class', array('class' => 'CustomLoader'))
->willReturn(true);
$generator1->getPriority()->willReturn(0);
$generator2->supports($resource, 'class', array('class' => 'CustomLoader'))
->willReturn(true);
$generator2->getPriority()->willReturn(2);
$generator1->generate($resource, array('class' => 'CustomLoader'))->shouldNotBeCalled();
$generator2->generate($resource, array('class' => 'CustomLoader'))->shouldBeCalled();
$this->registerGenerator($generator1);
$this->registerGenerator($generator2);
$this->generate($resource, 'class', array('class' => 'CustomLoader'));
}
function it_throws_exception_if_no_generator_found(Resource $resource)
{
$this->shouldThrow()->duringGenerate($resource, 'class', array('class' => 'CustomLoader'));
}
}

View File

@@ -1,98 +0,0 @@
<?php
namespace spec\PhpSpec\CodeGenerator;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use PhpSpec\Util\Filesystem;
class TemplateRendererSpec extends ObjectBehavior
{
function let(Filesystem $fs)
{
$this->beConstructedWith($fs);
}
function it_does_not_have_registered_locations_by_default()
{
$this->getLocations()->shouldHaveCount(0);
}
function it_has_locations_setter()
{
$this->setLocations(array('location1', 'location2'));
$this->getLocations()->shouldReturn(array('location1', 'location2'));
}
function it_provides_a_method_to_prepend_location()
{
$this->setLocations(array('location1', 'location2'));
$this->prependLocation('location0');
$this->getLocations()->shouldReturn(array('location0', 'location1', 'location2'));
}
function it_provides_a_method_to_append_location()
{
$this->setLocations(array('location1', 'location2'));
$this->appendLocation('location0');
$this->getLocations()->shouldReturn(array('location1', 'location2', 'location0'));
}
function it_normalizes_locations()
{
$this->setLocations(array('lo/ca\\tion', '\\location', 'location\\'));
$this->getLocations()->shouldReturn(array(
'lo'.DIRECTORY_SEPARATOR.'ca'.DIRECTORY_SEPARATOR.'tion',
DIRECTORY_SEPARATOR.'location',
'location'
));
}
function it_reads_existing_file_from_registered_location($fs)
{
$fs->pathExists('location1'.DIRECTORY_SEPARATOR.'some_file.tpl')->willReturn(true);
$fs->getFileContents('location1'.DIRECTORY_SEPARATOR.'some_file.tpl')->willReturn('cont');
$this->setLocations(array('location1'));
$this->render('some_file')->shouldReturn('cont');
}
function it_reads_existing_file_from_first_registered_location($fs)
{
$fs->pathExists('location1'.DIRECTORY_SEPARATOR.'some_file.tpl')->willReturn(false);
$fs->pathExists('location2'.DIRECTORY_SEPARATOR.'some_file.tpl')->willReturn(true);
$fs->pathExists('location3'.DIRECTORY_SEPARATOR.'some_file.tpl')->willReturn(true);
$fs->getFileContents('location2'.DIRECTORY_SEPARATOR.'some_file.tpl')->willReturn('cont');
$fs->getFileContents('location3'.DIRECTORY_SEPARATOR.'some_file.tpl')->willReturn('cont2');
$this->setLocations(array('location1', 'location2', 'location3'));
$this->render('some_file')->shouldReturn('cont');
}
function it_replaces_placeholders_in_template_with_provided_values($fs)
{
$fs->pathExists('location1'.DIRECTORY_SEPARATOR.'some_file.tpl')->willReturn(true);
$fs->getFileContents('location1'.DIRECTORY_SEPARATOR.'some_file.tpl')
->willReturn('Template #%number%. From %spec_name% spec.');
$this->setLocations(array('location1'));
$this->render('some_file', array('%number%' => 2, '%spec_name%' => 'tpl'))
->shouldReturn('Template #2. From tpl spec.');
}
function it_can_render_template_from_string()
{
$this->renderString('Template #%number%. From %spec_name% spec.', array(
'%number%' => 2,
'%spec_name%' => 'tpl'
))->shouldReturn('Template #2. From tpl spec.');
}
function it_returns_empty_string_if_template_is_not_found_in_any_registered_locations()
{
$this->render('some_file')->shouldReturn('');
}
}

Some files were not shown because too many files have changed in this diff Show More