{"id":20827683,"url":"https://github.com/peridot-php/peridot-dsl-example","last_synced_at":"2025-05-07T21:04:44.669Z","repository":{"id":22087770,"uuid":"25417407","full_name":"peridot-php/peridot-dsl-example","owner":"peridot-php","description":"Demonstrating a custom test DSL with Peridot","archived":false,"fork":false,"pushed_at":"2014-11-08T21:46:00.000Z","size":208,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-07T21:04:39.856Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peridot-php.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-10-19T04:05:46.000Z","updated_at":"2020-02-10T10:11:45.000Z","dependencies_parsed_at":"2022-08-05T15:30:28.225Z","dependency_job_id":null,"html_url":"https://github.com/peridot-php/peridot-dsl-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peridot-php%2Fperidot-dsl-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peridot-php%2Fperidot-dsl-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peridot-php%2Fperidot-dsl-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peridot-php%2Fperidot-dsl-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peridot-php","download_url":"https://codeload.github.com/peridot-php/peridot-dsl-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252954432,"owners_count":21830903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T23:12:45.149Z","updated_at":"2025-05-07T21:04:44.647Z","avatar_url":"https://github.com/peridot-php.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"Peridot Custom DSL Example\n==========================\n\nThis repo demonstrates creating a custom DSL for use with the [Peridot](https://github.com/peridot-php/peridot) testing framework for PHP.\n\n##Peridot acceptance testing DSL\n\nThis DSL will allow us to write acceptance tests like so:\n\n```php\n\u003c?php // features/chdir.feature.php\nFeature(\"chdir\",\"\n    As a PHP user\n    I need to be able to change the current working directory\",\n    function() {\n\n        Scenario(function() {\n        \n            Given('I am in this directory', function() {\n                chdir(__DIR__);\n            });\n\n            When('I run getcwd()', function() {\n                $this-\u003ecwd = getcwd();\n            });\n\n            Then('I should get this directory', function() {\n                if ($this-\u003ecwd != __DIR__) {\n                    throw new \\Exception(\"Should be current directory\");\n                }\n            });\n\n        });\n\n    });\n\n```\n\n##The DSL file\n\nOur DSL defines a small set of feature based functions. `Context` is the only singleton in the `Peridot` ecosystem,\nand we use it to add suites and tests. You can browse it's documentation [here](http://peridot-php.github.io/docs/class-Peridot.Runner.Context.html).\n\n```php\n\u003c?php // src/feature.dsl.php\nuse Peridot\\Runner\\Context;\n\nfunction Feature($name, $description,  callable $fn)\n{\n    $description = 'Feature: ' . $name . $description . \"\\n\";\n    Context::getInstance()-\u003eaddSuite($description, $fn);\n}\n\nfunction Scenario(callable $fn)\n{\n    Context::getInstance()-\u003eaddSuite(\"Scenario:\", $fn);\n}\n\nfunction Given($description, callable $fn)\n{\n    $test = Context::getInstance()-\u003eaddTest($description, $fn);\n    $test-\u003egetScope()-\u003eacceptanceDslTitle = \"Given\";\n}\n\nfunction When($description, callable $fn)\n{\n    $test = Context::getInstance()-\u003eaddTest($description, $fn);\n    $test-\u003egetScope()-\u003eacceptanceDslTitle = \"When\";\n}\n\nfunction Then($description, callable $fn)\n{\n    $test = Context::getInstance()-\u003eaddTest($description, $fn);\n    $test-\u003egetScope()-\u003eacceptanceDslTitle = \"Then\";\n}\n```\n\nNotice the use of `Scope` to store additional information about our tests and our DSL.\n\n##Configuring Peridot\n\nWe wire up our custom DSL via the Peridot configuration file.\n\n```php\n\u003c?php // peridot.php\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nreturn function($emitter) {\n    //set the DSL and change the file extension we search for\n    $emitter-\u003eon('peridot.configure', function($config) {\n        $config-\u003esetDsl(__DIR__ . '/src/feature.dsl.php');\n\n        //this fixes the file pattern, you could just as easily use the -g option from the cli\n        $config-\u003esetGrep('*.feature.php');\n    });\n\n    //register a more appropriate reporter for our DSL\n    $emitter-\u003eon('peridot.reporters', function($input, $reporters) {\n        $reporters-\u003eregister('feature', 'A feature reporter', 'Peridot\\Example\\FeatureReporter');\n    });\n};\n```\n\nTo complement our DSL, we have also extended the `SpecReporter`\nwith the `FeatureReporter`.\n\n```php\n\u003c?php // src/Example/FeatureReporter.php\nnamespace Peridot\\Example;\n\nuse Peridot\\Core\\Test;\nuse Peridot\\Reporter\\SpecReporter;\n\n/**\n * The FeatureReporter extends SpecReporter to be more friendly with feature language\n *\n * @package Peridot\\Example\n */\nclass FeatureReporter extends SpecReporter\n{\n    /**\n     * @param Test $test\n     */\n    public function onTestPassed(Test $test)\n    {\n        $title = $this-\u003ehandleGivenWhen($test);\n\n        $this-\u003eoutput-\u003ewriteln(sprintf(\n            \"  %s%s %s\",\n            $this-\u003eindent(),\n            $this-\u003ecolor('success', $title),\n            $this-\u003ecolor('muted', $test-\u003egetDescription())\n        ));\n    }\n\n    /**\n     * Given and When don't represent true tests themselves, so we decrement\n     * the \"passing\" count that is reported for each one\n     *\n     * @param Test $test\n     * @return string\n     */\n    protected function handleGivenWhen(Test $test)\n    {\n        $scope = $test-\u003egetScope();\n        $title = $scope-\u003eacceptanceDslTitle;\n        if (preg_match('/Given|When/', $title)) {\n            $this-\u003epassing--;\n        }\n        return $title;\n    }\n}\n```\n\n##Running the features\n\n```\n$ vendor/bin/peridot features/ -r feature\n```\n\n![Peridot acceptance testing](https://raw.githubusercontent.com/peridot-php/peridot-dsl-example/master/output.png \"Peridot acceptance testing\")\n\n##Note\n\nThis is just an example of creating a custom DSL for Peridot. It probably isn't the most robust solution in it's current state, but it is instead meant to demonstrate what Peridot is capable of.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperidot-php%2Fperidot-dsl-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fperidot-php%2Fperidot-dsl-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperidot-php%2Fperidot-dsl-example/lists"}