1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
# cucumber-core
[](https://gitter.im/cucumber/cucumber-ruby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](http://travis-ci.org/cucumber/cucumber-ruby-core)
[](https://codeclimate.com/github/cucumber/cucumber-ruby-core)
[](https://coveralls.io/r/cucumber/cucumber-ruby-core?branch=master)
[](https://gemnasium.com/cucumber/cucumber-ruby-core)
Cucumber Core is the [inner hexagon](http://alistair.cockburn.us/Hexagonal+architecture) for the [Ruby flavour of Cucumber](https://github.com/cucumber/cucumber-ruby).
It contains the core domain logic to execute Cucumber features. It has no user interface, just a Ruby API. If you're interested in how Cucumber works, or in building other tools that work with Gherkin documents, you've come to the right place.
## An overview
The entry-point is a single method on the module `Cucumber::Core` called [`#execute`](http://rubydoc.info/gems/cucumber-core/Cucumber/Core#execute-instance_method). Here's what it does:
1. Parses the plain-text Gherkin documents into an **AST**
2. Compiles the AST down to **test cases**
3. Passes the activated test cases through any **filters**
4. Executes the test cases, calling back to the **report**
We've introduced a number of concepts here, so let's go through them in detail.
### The AST
The Abstract Syntax Tree or [AST](http://rubydoc.info/gems/cucumber-core/Cucumber/Core/Ast) is an object graph that represents the Gherkin documents you've passed into the core. Things like [Feature](http://rubydoc.info/gems/cucumber-core/Cucumber/Core/Ast/Feature), [Scenario](http://rubydoc.info/gems/cucumber-core/Cucumber/Core/Ast/Scenario) and [ExamplesTable](ExamplesTable).
These are immutable value objects.
### Test cases
Your gherkin might contain scenarios, as well as examples from tables beneath a scenario outline.
Test cases represent the general case of both of these. We compile the AST down to instances of [`Cucumber::Core::Test::Case`](http://rubydoc.info/gems/cucumber-core/Cucumber/Core/Test/Case), each containing a number of instances of [`Cucumber::Core::Test::Step`](http://rubydoc.info/gems/cucumber-core/Cucumber/Core/Test/Step). It's these that are then filtered and executed.
Test cases and their test steps are also immutable value objects.
### Filters
Once we have the test cases, and they've been activated by the mappings, you may want to pass them through a filter or two. Filters can be used to do things like activate, sort, replace or remove some of the test cases or their steps before they're executed.
### Report
A report is how you find out what is happening during your test run. As the test cases and steps are executed, messages are sent to the report.
A report needs to respond to the following methods:
* `before_test_case(test_case)`
* `after_test_case(test_case, result)`
* `before_test_step(test_step)`
* `after_test_step(test_test, result)`
* `done`
That's probably best illustrated with an example.
## Example
Here's an example of how you might use [`Cucumber::Core#execute`](http://rubydoc.info/gems/cucumber-core/Cucumber/Core#execute-instance_method)
```ruby
require 'cucumber/core'
require 'cucumber/core/filter'
class MyRunner
include Cucumber::Core
end
class ActivateSteps < Cucumber::Core::Filter.new
def test_case(test_case)
test_steps = test_case.test_steps.map do |step|
activate(step)
end
test_case.with_steps(test_steps).describe_to(receiver)
end
private
def activate(step)
case step.name
when /fail/
step.with_action { raise Failure }
when /pass/
step.with_action {}
else
step
end
end
end
class Report
def before_test_step(test_step)
end
def after_test_step(test_step, result)
puts "#{test_step.name} #{result}"
end
def before_test_case(test_case)
end
def after_test_case(test_case, result)
end
def done
end
end
feature = Cucumber::Core::Gherkin::Document.new(__FILE__, <<-GHERKIN)
Feature:
Scenario:
Given passing
And failing
And undefined
GHERKIN
MyRunner.new.execute([feature], Report.new, [ActivateSteps.new])
```
If you run this little Ruby script, you should see the following output:
```
passing ✓
failing ✗
undefined ?
```
## Copyright
Copyright (c) Cucumber Limited.
|