cuke4php 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.document ADDED
@@ -0,0 +1,3 @@
1
+ bin/*
2
+ features/**/*.feature
3
+ LICENSE
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :development do
4
+ gem 'bundler', '~> 1.0'
5
+ gem 'jeweler'
6
+ end
7
+
8
+ gem 'cucumber'
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010-2011 Kevin Olbrich, Alessandro Dal Grande
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ cuke4php
2
+ ========
3
+
4
+ This project implements the cucumber wire protocol for PHP projects.
5
+ Information about the wire protocol: http://wiki.github.com/aslakhellesoy/cucumber/wire-protocol
6
+
7
+ Using this protocol it is possible to directly interact with PHP code at any level without the need for a web server. To accomplish this, when cucumber is running against a directory containing feature files and it cannot resolve a particular step definition, it will ask a known wire server (as defined in a .wire file) to interpret and run those steps.
8
+
9
+ Install
10
+ -------
11
+ To install Cuke4Php, follow these steps:
12
+
13
+ * clone
14
+ * install dependencies with bundler
15
+ * run rake build
16
+ * install gem under pkg/ folder
17
+
18
+ Usage
19
+ -----
20
+ * run 'cuke4php path/to/features' from the command line
21
+ * make sure your cucumber features has a 'Cuke4Php.wire' file containing the appropriate information (copy the one in cuke4php/features/step_definitions)
22
+ * you can write both Ruby and PHP steps
23
+ * you should load phpunit from a file in step_definitions/support/
24
+
25
+ Roadmap
26
+ -------
27
+
28
+ ### bin/cuke4php
29
+
30
+ * support an option like 'cuke4php --init' which will generate the directory structure and support files necessary to use cuke4php with a php project.
31
+ * autodetect an available port and then use it to run the cuke4php server pass this on to cucumber by setting an environment variable (requires a modification to cucumber)
32
+
33
+ ### Rakefile
34
+
35
+ * once the patch for erb templating in .wire files is released, we should set a minimum version for it
36
+
37
+ Dependencies
38
+ ------------
39
+ * PHPUnit >= 3.0 (see http://www.phpunit.de/)
40
+
41
+ Goals
42
+ -----
43
+ This project utilizes PHPUnit because it has a robust set of assertions, has good mocking, and is widely used. This will facilitate adoption by developers who are already familiar with it.
44
+
45
+ This project was developed against the 5.2.x versions of PHP, to ensure compatibility with older PHP projects.
46
+
47
+ Support
48
+ -------
49
+ Support for this project was provided by iContact, inc. (http://www.icontact.com)
50
+
51
+ Contributors
52
+ ------------
53
+ Kevin Olbrich, Ph.D. (kevin.olbrich+cuke4php@gmail.com)
54
+ Alessandro Dal Grande (aledelgrande@gmail.com)
data/Rakefile ADDED
@@ -0,0 +1,75 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "cuke4php"
8
+ gem.summary = %Q{Implementation of the Cucumber wire protocol for PHP projects}
9
+ gem.description = %Q{Using this protocol it is possible to directly interact with PHP code at any level without the need for a web server. To accomplish this, when cucumber is running against a directory containing feature files and it cannot resolve a particular step definition, it will ask a known wire server (as defined in a .wire file) to interpret and run those steps.}
10
+ gem.authors = ["Kevin Olbrich", "Alessandro Dal Grande"]
11
+ gem.email = ["kevin.olbrich+cuke4php@gmail.com", "aledalgrande@gmail.com"]
12
+ gem.homepage = "http://github.com/olbrich/cuke4php"
13
+ gem.executables = 'cuke4php'
14
+ gem.add_dependency('cucumber')
15
+ # TODO: once the patch for erb templating in the .wire files is released, we should set a minimum version for it
16
+ gem.add_development_dependency('bundler')
17
+ gem.add_development_dependency('jeweler')
18
+ gem.files.exclude 'phpdoc'
19
+ gem.has_rdoc = false
20
+ gem.requirements << "PHP 5.2+"
21
+ gem.requirements << "PHPUnit 3.0+"
22
+ gem.post_install_message =<<eos
23
+ ********************************************************************************
24
+
25
+ Please install PHPUnit >= 3.0 if you've not already done it!
26
+
27
+ Add PEAR channels:
28
+ pear channel-discover pear.phpunit.de
29
+ pear channel-discover components.ez.no
30
+ pear channel-discover pear.symfony-project.com
31
+
32
+ Install PHPUnit:
33
+ pear install phpunit/PHPUnit
34
+
35
+ ********************************************************************************
36
+ eos
37
+ end
38
+ Jeweler::GemcutterTasks.new
39
+ rescue LoadError
40
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
41
+ end
42
+
43
+ require 'cucumber/rake/task'
44
+ #Cucumber::Rake::Task.new(:features)
45
+
46
+ task :default => [:features, :phpunit]
47
+
48
+ namespace :server do
49
+
50
+ desc "start cuke4php server"
51
+ task :start do
52
+ sh "#{File.dirname(__FILE__)}/php_bin/cuke4php #{ARGV.first ? ARGV.first : 'features'} &"
53
+ end
54
+
55
+ desc "stop cuke4php server"
56
+ task :stop do
57
+ sh "echo 'quit' | nc #{ENV['SERVER'] || 'localhost'} #{ENV['PORT'] || 16816}"
58
+ end
59
+ end
60
+
61
+ desc "Run Cucumber features for Cuke4php"
62
+ task :features do
63
+ sh "bin/cuke4php -p #{ENV['PROFILE'] || 'default'} features"
64
+ end
65
+
66
+ desc "Generate PhpDocs -- requires PhpDocumentor"
67
+ task :phpdoc do
68
+ sh "rm -rf phpdoc/"
69
+ sh "phpdoc -f *.php -d ./lib -t phpdoc/ --title Cuke4Php -dn Cuke4Php -dc Cuke4Php -it @one,@two,@wire"
70
+ end
71
+
72
+ desc "Run PHPUnit tests"
73
+ task :phpunit do
74
+ sh "phpunit tests"
75
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.9.0
data/bin/cuke4php ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # TODO: support an option like 'cuke4php --init' which will generate the directory structure and support files necessary to use cuke4php with a php project.
4
+
5
+ # TODO: autodetect an available port and then use it to run the cuke4php server pass this on to cucumber by setting an environment variable (requires a modification to cucumber)
6
+ # see https://github.com/olbrich/cucumber/commit/0c11d206e08e8d5647e03bf78be93723d59529ef
7
+
8
+ # Note that changing the port number currently requires updating the Cuke4Php.wire file in your project's step_definitions
9
+ # or cucumber will look for the cuke4php server on the wrong port.
10
+ CUKE4PHP_PORT=ENV['CUKE4PHP_PORT'] || 16816
11
+
12
+ server = fork do
13
+ exec "#{File.dirname(__FILE__)}/../php_bin/cuke4php_server -p #{CUKE4PHP_PORT} #{ARGV.last ? ARGV.last : 'features'}"
14
+ end
15
+ #Process.detach(pid)
16
+ sleep 1
17
+ cucumber = fork do
18
+ exec "CUKE4PHP_PORT=#{CUKE4PHP_PORT} && cucumber #{ARGV.join(' ')}" #"; echo 'quit' | nc localhost #{CUKE4PHP_PORT}"
19
+ end
20
+ pid, status = Process.wait2(cucumber,0)
21
+ Process.kill("TERM",server)
22
+ exit status.exitstatus
data/cucumber.yml ADDED
@@ -0,0 +1 @@
1
+ default: --format pretty
data/cuke4php.gemspec ADDED
@@ -0,0 +1,92 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{cuke4php}
8
+ s.version = "0.9.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Kevin Olbrich", "Alessandro Dal Grande"]
12
+ s.date = %q{2011-01-27}
13
+ s.default_executable = %q{cuke4php}
14
+ s.description = %q{Using this protocol it is possible to directly interact with PHP code at any level without the need for a web server. To accomplish this, when cucumber is running against a directory containing feature files and it cannot resolve a particular step definition, it will ask a known wire server (as defined in a .wire file) to interpret and run those steps.}
15
+ s.email = ["kevin.olbrich+cuke4php@gmail.com", "aledalgrande@gmail.com"]
16
+ s.executables = ["cuke4php"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.md"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ "Gemfile",
24
+ "LICENSE",
25
+ "README.md",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bin/cuke4php",
29
+ "cucumber.yml",
30
+ "cuke4php.gemspec",
31
+ "features/Cuke4Php.feature",
32
+ "features/step_definitions/Cuke4Php.wire",
33
+ "features/step_definitions/TestSteps.php",
34
+ "features/step_definitions/WireSteps.php",
35
+ "features/support/Env.php",
36
+ "lib/Cucumber.php",
37
+ "lib/CucumberScenario.php",
38
+ "lib/CucumberSteps.php",
39
+ "lib/Cuke4Php.php",
40
+ "php_bin/cuke4php_server",
41
+ "tests/lib/CucumberScenarioTest.php",
42
+ "tests/lib/Cuke4PhpTest.php"
43
+ ]
44
+ s.homepage = %q{http://github.com/olbrich/cuke4php}
45
+ s.post_install_message = %q{********************************************************************************
46
+
47
+ Please install PHPUnit >= 3.0 if you've not already done it!
48
+
49
+ Add PEAR channels:
50
+ pear channel-discover pear.phpunit.de
51
+ pear channel-discover components.ez.no
52
+ pear channel-discover pear.symfony-project.com
53
+
54
+ Install PHPUnit:
55
+ pear install phpunit/PHPUnit
56
+
57
+ ********************************************************************************
58
+ }
59
+ s.require_paths = ["lib"]
60
+ s.requirements = ["PHP 5.2+", "PHPUnit 3.0+"]
61
+ s.rubygems_version = %q{1.3.7}
62
+ s.summary = %q{Implementation of the Cucumber wire protocol for PHP projects}
63
+
64
+ if s.respond_to? :specification_version then
65
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
66
+ s.specification_version = 3
67
+
68
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
69
+ s.add_runtime_dependency(%q<cucumber>, [">= 0"])
70
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
71
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
72
+ s.add_runtime_dependency(%q<cucumber>, [">= 0"])
73
+ s.add_development_dependency(%q<bundler>, [">= 0"])
74
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
75
+ else
76
+ s.add_dependency(%q<cucumber>, [">= 0"])
77
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
78
+ s.add_dependency(%q<jeweler>, [">= 0"])
79
+ s.add_dependency(%q<cucumber>, [">= 0"])
80
+ s.add_dependency(%q<bundler>, [">= 0"])
81
+ s.add_dependency(%q<jeweler>, [">= 0"])
82
+ end
83
+ else
84
+ s.add_dependency(%q<cucumber>, [">= 0"])
85
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
86
+ s.add_dependency(%q<jeweler>, [">= 0"])
87
+ s.add_dependency(%q<cucumber>, [">= 0"])
88
+ s.add_dependency(%q<bundler>, [">= 0"])
89
+ s.add_dependency(%q<jeweler>, [">= 0"])
90
+ end
91
+ end
92
+
@@ -0,0 +1,42 @@
1
+ @wire
2
+ Feature: Interact with the Cuke4Php server
3
+ As a tester
4
+ I want to run step definitions in PHP
5
+ So that I can execute steps in PHP
6
+
7
+ Scenario: Cuke4Php runs the steps
8
+ Given some setup
9
+ When I take an action
10
+ Then something happens
11
+ And an undefined step with a "param"
12
+ And a step with a "parameter" and the following table:
13
+ | column 1 | data |
14
+ | apples | 10 |
15
+ | oranges | 20 |
16
+ And a step with a multiline string:
17
+ """
18
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pulvinar,
19
+ est at molestie placerat, risus lectus dictum nulla, id blandit nunc metus at
20
+ ligula. Nam purus quam, consectetur ut pulvinar eu, elementum quis nibh. Curabitur
21
+ pellentesque sapien ut dolor commodo ultricies. Sed auctor convallis nunc, et
22
+ dapibus leo ullamcorper scelerisque. Vivamus nisi diam, vestibulum eget consequat
23
+ et, fringilla vitae ipsum. Nam et nisl est. Cras ac iaculis nisl. Quisque
24
+ condimentum tristique tellus, vitae fringilla nulla dictum vel. Proin varius congue
25
+ libero id facilisis. Etiam scelerisque mauris sit amet sem imperdiet a laoreet tellus
26
+ scelerisque. Curabitur vulputate congue malesuada. Aenean tempus viverra arcu, quis
27
+ posuere velit facilisis at. Sed nec rutrum turpis. Nunc mattis magna in ante tincidunt
28
+ fermentum. Donec dapibus porta ipsum, eget porttitor magna viverra vitae. Quisque suscipit,
29
+ metus sit amet placerat interdum, enim turpis imperdiet turpis, in placerat felis
30
+ orci at sem. Suspendisse sagittis, neque quis sodales ornare, dui purus posuere
31
+ lectus, id feugiat nunc lectus ac lectus.
32
+ """
33
+
34
+ Scenario Outline: run several steps many times
35
+ Given I <verb> the <noun>
36
+ Then It should be <adjective>
37
+
38
+ Examples:
39
+ | verb | noun | adjective |
40
+ | shoot | messenger | dead |
41
+ | understand | meaning | clear |
42
+
@@ -0,0 +1,4 @@
1
+ host: localhost
2
+ port: 16816
3
+ invoke:
4
+ timeout: 0.1
@@ -0,0 +1,88 @@
1
+ <?php
2
+ /**
3
+ * @package Cuke4Php
4
+ */
5
+
6
+ /**
7
+ * @package Cuke4Php
8
+ */
9
+ class TestSteps extends CucumberSteps {
10
+
11
+ /**
12
+ * Given /^successful$/
13
+ **/
14
+ public function stepSuccessful() {}
15
+
16
+ /**
17
+ * Given /^incomplete$/
18
+ */
19
+ public function stepIncomplete() {
20
+ self::markTestIncomplete('incomplete');
21
+ }
22
+
23
+ /**
24
+ * Given /^skipped$/
25
+ */
26
+ public function stepSkipped() {
27
+ self::markTestSkipped('skipped');
28
+ }
29
+
30
+ /**
31
+ * Given /^pending$/
32
+ */
33
+ public function stepPending() {
34
+ self::markPending('pending');
35
+ }
36
+
37
+ /**
38
+ * Given /^a failed expectation$/
39
+ */
40
+ public function stepFailed() {
41
+ self::assertEquals(true, false);
42
+ }
43
+
44
+ /**
45
+ * Given /^an exception is thrown$/
46
+ */
47
+ public function stepException() {
48
+ throw new TestException('Exception');
49
+ }
50
+
51
+ /**
52
+ * Given /^"arg1" not equal to "arg2"$/
53
+ */
54
+ public function stepNotEqual($arg1,$arg2) {
55
+ self::assertTrue($arg1 !== $arg2);
56
+ }
57
+
58
+ /**
59
+ * @one
60
+ */
61
+ public function afterWithOneTag() {
62
+
63
+ }
64
+
65
+ /**
66
+ *
67
+ */
68
+ public function afterWithNoTags() {
69
+
70
+ }
71
+
72
+ /**
73
+ * @one
74
+ */
75
+ public function beforeWithOneTag() {
76
+
77
+ }
78
+
79
+ /**
80
+ *
81
+ */
82
+ public function beforeWithNoTags() {
83
+
84
+ }
85
+
86
+ }
87
+
88
+ ?>
@@ -0,0 +1,87 @@
1
+ <?php
2
+ /**
3
+ * @package Cuke4Php
4
+ */
5
+ /**
6
+ * @package Cuke4Php
7
+ */
8
+ class WireSteps extends CucumberSteps {
9
+
10
+ /**
11
+ * @wire
12
+ */
13
+ function beforeWire() {
14
+ $this->aGlobals['before'] = 'beforeWire';
15
+ }
16
+
17
+ function beforeAll() {
18
+
19
+ }
20
+
21
+ /**
22
+ * Given /^some setup$/
23
+ **/
24
+ public function stepSomeSetup() {
25
+
26
+ }
27
+
28
+ /**
29
+ * When /^I take an action$/
30
+ **/
31
+ public function stepITakeAnAction() {
32
+ }
33
+
34
+ /**
35
+ * Then /^something happens$/
36
+ **/
37
+ public function stepSomethingHappens() {
38
+ }
39
+
40
+ /**
41
+ * Then /^an undefined step with a "([^"]*)"$/
42
+ **/
43
+ public function stepAnUndefinedStepWithAParameter($arg1) {
44
+ self::assertEquals('param', $arg1);
45
+ }
46
+
47
+ /**
48
+ * Then /^a step with a "([^"]*)" and the following table\:$/
49
+ **/
50
+ public function stepAStepWithAParameterAndTheFollowingTable($arg1, $table) {
51
+ }
52
+
53
+ /**
54
+ * Given /^I shoot the messenger$/
55
+ **/
56
+ public function stepIShootTheMessenger() {
57
+ }
58
+
59
+ /**
60
+ * Then /^It should be dead$/
61
+ **/
62
+ public function stepItShouldBeDead() {
63
+ }
64
+
65
+ /**
66
+ * Given /^I understand the meaning$/
67
+ **/
68
+ public function stepIUnderstandTheMeaning() {
69
+ }
70
+
71
+ /**
72
+ * Then /^It should be clear$/
73
+ **/
74
+ public function stepItShouldBeClear() {
75
+ }
76
+
77
+ /**
78
+ * Then /^a step with a multiline string\:$/
79
+ **/
80
+ public function stepAStepWithAMultilineString($sString) {
81
+
82
+ }
83
+
84
+
85
+ }
86
+
87
+ ?>
@@ -0,0 +1,13 @@
1
+ <?php
2
+ /**
3
+ * @package Cuke4Php
4
+ */
5
+
6
+ /**
7
+ * load the PHPUnit framework, try to load the new version first
8
+ * then the older one.
9
+ */
10
+ @include_once "PHPUnit/Autoload.php";
11
+ @include_once "PHPUnit/Framework.php";
12
+
13
+ ?>
data/lib/Cucumber.php ADDED
@@ -0,0 +1,14 @@
1
+ <?php
2
+
3
+ /**
4
+ * @package Cuke4Php
5
+ */
6
+
7
+ /**
8
+ * load all php files in this directory
9
+ */
10
+ foreach (glob(dirname(__FILE__) . "/*.php") as $sFilename) {
11
+ require_once $sFilename;
12
+ }
13
+
14
+ ?>
@@ -0,0 +1,122 @@
1
+ <?php
2
+ /**
3
+ * @package Cuke4Php
4
+ */
5
+
6
+ /**
7
+ * load dependencies
8
+ */
9
+ require_once "CucumberSteps.php";
10
+
11
+ /**
12
+ * class CucumberScenario
13
+ * Defines a Cucumber Scenario
14
+ * @package Cuke4Php
15
+ */
16
+ class CucumberScenario {
17
+
18
+ // provide a place we can store data
19
+ public $aGlobals = array();
20
+
21
+ // the world holds the definitions for the before, after, and step definitions
22
+ private $aWorld;
23
+
24
+ static private $oMock;
25
+
26
+ /**
27
+ * @param array $_aWorld
28
+ * @return void
29
+ */
30
+ function __construct($_aWorld = array()) {
31
+ $this->aWorld = $_aWorld;
32
+ }
33
+
34
+ /**
35
+ * @static
36
+ * @param $aWorld
37
+ * @return CucumberScenario
38
+ */
39
+ static function getInstance($aWorld) {
40
+ if (self::$oMock) {
41
+ return self::$oMock;
42
+ } else {
43
+ return new CucumberScenario($aWorld);
44
+ }
45
+ }
46
+
47
+ /**
48
+ * @static
49
+ * @param $oMock
50
+ * @return void
51
+ */
52
+ static function setInstance($oMock) {
53
+ self::$oMock = $oMock;
54
+ }
55
+
56
+ /**
57
+ * @param $aTags
58
+ * @return array
59
+ * invokes all the before hooks defined that either have no tags or tags corresponding to this scenario's tags
60
+ */
61
+ function invokeBeforeHooks($aTags) {
62
+ foreach ($this->aWorld['before'] as $aBeforeHook) {
63
+ if (array_key_exists('tags', $aBeforeHook))
64
+ if (count($aBeforeHook['tags']) == 0 || count(array_intersect($aTags, $aBeforeHook['tags'])) > 0) {
65
+ $oStep = CucumberSteps::getInstance($aBeforeHook['class'], $this->aGlobals);
66
+ $oResult = $oStep->invoke($aBeforeHook['method']);
67
+ if ($oResult === false) {
68
+ return array('failure');
69
+ }
70
+ }
71
+ }
72
+ return array('success');
73
+ }
74
+
75
+ /**
76
+ * @param $aTags
77
+ * @return array
78
+ * invoke all after hooks defined that either have no tags, or tags that match the tags of the current scenario
79
+ */
80
+ function invokeAfterHooks($aTags) {
81
+ foreach ($this->aWorld['after'] as $aAfterHook) {
82
+ if (array_key_exists('tags', $aAfterHook))
83
+ if (count($aAfterHook['tags']) == 0 || count(array_intersect($aTags, $aAfterHook['tags'])) > 0) {
84
+ $oStep = CucumberSteps::getInstance($aAfterHook['class'], $this->aGlobals);
85
+ $oResult = $oStep->invoke($aAfterHook['method']);
86
+ if ($oResult === false) {
87
+ return array('failure');
88
+ }
89
+ }
90
+ }
91
+ return array('success');
92
+ }
93
+
94
+ /**
95
+ * @param $iStepId
96
+ * @param $aArgs
97
+ * @return mixed
98
+ *
99
+ * Invokes a step. Steps can use PHPUnit assertions and will
100
+ * mark themselves as pending if the self::markTestIncomplete() or self:markTestSkipped()
101
+ * functions are called. Failed expectations are returned as messages while all other
102
+ * Exceptions are reported back as exceptions.
103
+ */
104
+ function invoke($iStepId, $aArgs) {
105
+ $aStep = $this->aWorld['steps'][$iStepId];
106
+ $oStep = new $aStep['class']($this->aGlobals);
107
+ try {
108
+ call_user_func_array(array($oStep, $aStep['method']),$aArgs);
109
+ } catch (PHPUnit_Framework_IncompleteTestError $e) {
110
+ return array('pending',$e->getMessage());
111
+ } catch (PHPUnit_Framework_SkippedTestError $e) {
112
+ return array('pending',$e->getMessage());
113
+ } catch (PHPUnit_Framework_ExpectationFailedException $e) {
114
+ return array('fail', array('message' => $e->getMessage()));
115
+ } catch (Exception $e) {
116
+ return array('fail', array('exception' => $e->__toString()));
117
+ }
118
+ return array('success');
119
+ }
120
+
121
+ }
122
+ ?>