Permalink
Browse files

Initial Commit

  • Loading branch information...
0 parents commit 0d470c506e5547b0b0ac8051803c056135415a1f @davedevelopment committed Jun 14, 2012
@@ -0,0 +1,4 @@
+tmp
+vendor
+composer.lock
+bin/behat
@@ -0,0 +1 @@
+5.4.3
19 LICENCE
@@ -0,0 +1,19 @@
+Copyright (C) 2012 Dave Marshall <dave.marshall@atstsolutions.co.uk>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
155 README.md
@@ -0,0 +1,155 @@
+dspec
+=====
+
+`dspec` is a BDD style testing tool for PHP 5.4+. It's a little flaky. It's
+meant to be like the awesome [mocha](http://visionmedia.github.com/mocha/), but
+obviously not that good. There aren't any matchers, I use
+[Hamcrest](http://code.google.com/p/hamcrest/source/browse/trunk/hamcrest-php/)
+for the that, if you want mocks and stubs, use
+[Mockery](http://github.com/padraic/mockery).
+
+Installation
+------------
+
+The only documented way to install `dspec` is with
+[Composer](http://getcomposer.org)
+
+``` bash
+$ composer.phar require --dev davedevelopment/dspec:*
+```
+
+Usage
+-----
+
+Create a Spec file
+
+``` php
+<?php
+
+// BowlingSpec.php
+
+require_once 'Bowling.php';
+require_once 'hamcrest/Hamcrest.php';
+
+describe("Bowling", function() {
+
+ beforeEach(function() { // run before every it() that follows, including in child describes/contexts
+ $this->bowling = new Bowling; // PHP 5.4's closure binding allows the use of this
+ });
+
+ it("should score zero for gutter game", function() {
+ for ($i = 0; $i < 20; $i++) {
+ $this->bowling->hit(0);
+ }
+
+ assertThat($this->bowling->score, equalTo(0)); // hamcrest assertion
+ });
+
+});
+
+```
+
+Run it
+
+``` bash
+$ vendor/bin/dspec BowlingSpec.php
+```
+
+For more examples, checkout the `features` or the `spec` dirs.
+
+Execution Scope
+---------------
+
+By default, DSpec does not tear down the scope before each example, but you can
+choose to during a before or after hook:
+
+``` php
+<?php
+
+beforeEach(function() {
+ $this->tearDown();
+});
+
+```
+
+Using $this is totally optional, using regular variable binding with your closures
+is an alternative option, but can be a bit messier;
+
+``` php
+<?php
+
+describe("Connection", function() {
+
+ $db = new Connection();
+
+ $dave = new User();
+ $bex = new User();
+
+ beforeEach(function() use ($db, $dave, $bex) {
+ $db->truncate('users');
+ $db->save($dave);
+ $db->save($bex);
+ });
+
+ context("#findAll()", function() use ($db) {
+ it("responds with all records", function() use ($db) {
+ $users = $db->find('users');
+ assertThat(count($users), equalTo(2));
+ });
+ });
+
+});
+```
+
+Global functions
+----------------
+
+If global functions aren't your thing, you can use class methods of the DSpec
+class:
+
+``` php
+<?php
+
+use DSpec\DSpec as ds;
+
+ds::describe("something", function() {
+ ds::context("when this", function() {
+ ds::it("does this", function() {
+
+ });
+ });
+});
+
+```
+
+Alternatively, DSpec includes your test files within the scope of the
+`DSpec\Compiler`, so you can also use `$this`, but I think it's a little ugly:
+
+``` php
+<?php
+
+$this->describe("something", function() {
+ $this->context("when this", function() {
+ $this->it("does this", function() {
+
+ });
+ });
+});
+```
+
+Due to the way the `DSpec` class uses statics, the above method is
+how the `DSpec\Compiler` is tested in `spec/DSpec/CompilerSpec.php`
+
+Todo
+----
+
+* Take more than one file (and dirs) as arguments
+* Config files
+* Command line options
+* Formatters
+* Documentation
+
+Copyright
+---------
+
+Copyright (c) 2012 Dave Marshall. See LICENCE for further details
@@ -0,0 +1,7 @@
+default:
+ paths:
+ features: 'features'
+ extensions:
+ Behat\Montserrat\Extension:
+ prepend_paths: ['%behat.paths.base%/bin']
+
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+<?php
+
+if (is_file(__DIR__ . '/../../../autoload.php')) {
+ require __DIR__ . '/../../../autoload.php';
+} else if (is_file(__DIR__ . '/../vendor/autoload.php')) {
+ require __DIR__ . '/../vendor/autoload.php';
+}
+
+use DSpec\DSpec as ds;
+
+function describe($description, \Closure $closure) {
+ ds::describe($description, $closure);
+}
+
+function it($example, \Closure $closure) {
+ ds::it($example, $closure);
+}
+
+function context($context, \Closure $closure) {
+ ds::context($context, $closure);
+}
+
+function beforeEach(\Closure $closure) {
+ ds::beforeEach($closure);
+}
+
+function afterEach(\Closure $closure) {
+ ds::afterEach($closure);
+}
+
+function pending($msg = "{no message}") {
+ ds::pending($msg);
+}
+
+function skip($msg = "{no message}") {
+ ds::skip($msg);
+}
+
+$app = new DSpec\Console\DSpecApplication;
+$app->run();
+
+
@@ -0,0 +1,35 @@
+{
+ "name": "davedevelopment/dspec",
+
+ "require-dev": {
+ "behat/behat": "*",
+ "davedevelopment/montserrat": "*",
+ "mockery/mockery": "*",
+ "davedevelopment/hamcrest-php": "*"
+ },
+
+ "require": {
+ "symfony/console": "2.1.*",
+ "symfony/event-dispatcher": "2.1.*"
+ },
+
+ "suggest": {
+ "mockery/mockery": "For mocks and stubs"
+ },
+
+ "autoload": {
+ "psr-0": {
+ "DSpec": "src/"
+ }
+ },
+
+ "config": {
+ "bin-dir": "bin"
+ },
+
+ "repositories": [
+ {"type": "vcs", "url": "http://github.com/davedevelopment/hamcrest-php"}
+ ],
+
+ "bin": ["bin/dspec"]
+}
@@ -0,0 +1,41 @@
+<?php
+
+use Behat\Behat\Context\ClosuredContextInterface,
+ Behat\Behat\Context\TranslatedContextInterface,
+ Behat\Behat\Context\BehatContext,
+ Behat\Behat\Exception\PendingException;
+use Behat\Gherkin\Node\PyStringNode,
+ Behat\Gherkin\Node\TableNode;
+
+//
+// Require 3rd-party libraries here:
+//
+// require_once 'PHPUnit/Autoload.php';
+// require_once 'PHPUnit/Framework/Assert/Functions.php';
+//
+
+/**
+ * Features context.
+ */
+class FeatureContext extends BehatContext
+{
+ protected $specFileName;
+
+ protected $exitCode;
+
+ protected $output;
+
+ /**
+ * Initializes context.
+ * Every scenario gets it's own context object.
+ *
+ * @param array $parameters context parameters (set them up through behat.yml)
+ */
+ public function __construct(array $parameters)
+ {
+ // Initialize your context here
+ $this->useContext('montserrat', new Behat\Montserrat\Context\MontserratContext());
+ }
+
+
+}
@@ -0,0 +1,69 @@
+Feature: Runner exits with a relevant status
+ In order to see if the tests passed or failed
+ As a runner of the software
+ I'd like to receive a relevant exit code
+
+ Scenario: Passing tests give zero exit code
+ Given a file named "OkSpec.php" with:
+ """
+ <?php
+ describe("pass", function() {
+ it("should pass", function() {
+ });
+ });
+ """
+ When I run `dspec OkSpec.php`
+ Then the exit status should be 0
+
+ Scenario: non-zero exit code for failure
+ Given a file named "FailSpec.php" with:
+ """
+ <?php
+ describe("fail", function() {
+ it("should fail", function() {
+ throw new Exception();
+ });
+ });
+ """
+ When I run `dspec FailSpec.php`
+ Then the exit status should not be 0
+
+ Scenario: non-zero exit code for failure with pass
+ Given a file named "FailSpec.php" with:
+ """
+ <?php
+ describe("fail", function() {
+ it("should fail", function() {
+ throw new Exception();
+ });
+ it("should pass", function() {
+ });
+ });
+ """
+ When I run `dspec FailSpec.php`
+ Then the exit status should not be 0
+
+ Scenario: non-zero exit with nested describes
+ Given a file named "FailSpec.php" with:
+ """
+ <?php
+ describe("passfail", function() {
+ it("should pass", function() {
+ });
+
+ describe("fail", function() {
+ it("should fail", function() {
+ throw new Exception();
+ });
+ });
+ });
+ """
+ When I run `dspec FailSpec.php`
+ Then the exit status should not be 0
+
+ Scenario: Exit with 0 when no examples are run
+ Given an empty file named "EmptySpec.php"
+ """
+ """
+ When I run `dspec EmptySpec.php`
+ Then the exit status should be 0
Oops, something went wrong.

0 comments on commit 0d470c5

Please sign in to comment.