cuke4php 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +3 -0
- data/Gemfile +8 -0
- data/LICENSE +20 -0
- data/README.md +54 -0
- data/Rakefile +75 -0
- data/VERSION +1 -0
- data/bin/cuke4php +22 -0
- data/cucumber.yml +1 -0
- data/cuke4php.gemspec +92 -0
- data/features/Cuke4Php.feature +42 -0
- data/features/step_definitions/Cuke4Php.wire +4 -0
- data/features/step_definitions/TestSteps.php +88 -0
- data/features/step_definitions/WireSteps.php +87 -0
- data/features/support/Env.php +13 -0
- data/lib/Cucumber.php +14 -0
- data/lib/CucumberScenario.php +122 -0
- data/lib/CucumberSteps.php +79 -0
- data/lib/Cuke4Php.php +242 -0
- data/php_bin/cuke4php_server +20 -0
- data/tests/lib/CucumberScenarioTest.php +161 -0
- data/tests/lib/Cuke4PhpTest.php +117 -0
- metadata +190 -0
data/.document
ADDED
data/Gemfile
ADDED
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,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
|
+
?>
|
data/lib/Cucumber.php
ADDED
@@ -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
|
+
?>
|