Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor DRY the runner and DSL #6

Merged
merged 17 commits into from
May 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
--color
--format documentation
--order rand

10 changes: 10 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,18 @@ GEM
rack-protection (1.5.3)
rack
rake (10.5.0)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-core (3.4.4)
rspec-support (~> 3.4.0)
rspec-expectations (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-mocks (3.4.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
sinatra (1.4.7)
rack (~> 1.5)
Expand All @@ -51,4 +60,5 @@ DEPENDENCIES
bundler (~> 1.6)
dredd_hooks!
rake (~> 10.0)
rspec (~> 3.0)
sinatra (~> 1.4.5)
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,29 @@ Development
rake
```

A few [Cucumber][cucumber] features provide an end-to-end test harness, and a set of [RSpec][rspec] specs provide both a more granular documentation and a unit test harness.

RSpec [tags][tags] are used to categorize the spec examples.

Spec examples that are tagged as `public` describe aspects of the gem public API, and MAY be considered as its documentation.

The `private` or `protected` specs are written for development purpose only. Because they describe internal behaviour which may change at any moment without notice, they are only executed as a secondary task by the [continuous integration service][travis] and SHOULD be ignored.

Run `rake spec:public` to print the gem public documentation.

[cucumber]: https://github.com/cucumber/cucumber-rails
[rspec]: https://www.relishapp.com/rspec
[tags]: https://www.relishapp.com/rspec/rspec-core/v/3-4/docs/command-line/tag-option
[travis]: https://travis-ci.org/gonzalo-bulnes/simple_token_authentication/builds

### Maintenance

Extending the DSL to support new hooks is meant to be easy, see the [maintenance documentation][doc-maintenance] for details. : )

[doc-maintenance]: ./doc/README.md

> Refactored with [love, internet style](https://www.youtube.com/watch?v=Xe1TZaElTAs).

Contributing
------------

Expand Down
28 changes: 27 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,31 @@ require "cucumber/rake/task"

Cucumber::Rake::Task.new

task default: [:cucumber]
begin
require 'rspec/core/rake_task'

desc 'Provide private interfaces documentation'
RSpec::Core::RakeTask.new(:spec)

namespace :spec do
desc 'Provide public interfaces documentation'
RSpec::Core::RakeTask.new(:public) do |t|
t.rspec_opts = "--tag public"
end
end

namespace :spec do
desc 'Provide private interfaces documentation for development purpose'
RSpec::Core::RakeTask.new(:development) do |t|
t.rspec_opts = "--tag protected --tag private"
end
end
rescue LoadError
desc 'RSpec rake task not available'
task :spec do
abort 'RSpec rake task is not available. Be sure to install rspec-core as a gem or plugin'
end
end

task default: ['spec:public', 'spec:development', :cucumber]

27 changes: 27 additions & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
How to Add New Hooks
====================

Dredd does support new hooks? It's time to extend the Ruby DSL!

Most of the new hooks definition is automated, but not everything yet.
In order to enable your new hook in the DSL (`DreddHook::Methods`) and the `DreddHooks::Runner`:

1. Determine if the hook is specific to a transaction or applies to all of them
1. Add the _registration_ and _run_ method to the [runner spec][runner-spec]
1. Add the DSL method to the [DSL spec][methods-spec]
1. Add the usage example to the [**Execution order** feature][feature]
1. Run the entire test suite and watch the tests fail (start worrying if they don't!)
1. Add the hook name to the corresponding list in the [definitions file][def]
1. Add the corresponding Dredd **event** to the [server][server]
1. Run the test suite and watch it pass : )

Finally, bump the [_minor_][semver] version number, update the `README`, the `CHANGELOG` and do anything you need to do in order to release!

[def]: ../lib/dredd_hooks/definitions.rb
[server]: ../lib/dredd_hooks/server.rb

[runner-spec]: ../spec/lib/dredd_hooks/runner_spec.rb
[methods-spec]: ../spec/lib/dredd_hooks/methods_spec.rb
[feature]: ../features/execution_order.feature
[semver]: http://semver.org

5 changes: 3 additions & 2 deletions dredd_hooks.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ Gem::Specification.new do |spec|
spec.license = "MIT"

spec.executables = "dredd-hooks-ruby"
spec.files = Dir["{bin,lib}/**/*", "CHANGELOG.md", "Gemfile", "LICENSE.txt", "Rakefile", "README.md" ]
spec.test_files = Dir["features/**/*"]
spec.files = Dir["{bin,doc,lib}/**/*", "CHANGELOG.md", "Gemfile", "LICENSE.txt", "Rakefile", "README.md" ]
spec.test_files = Dir["{features,spec}/**/*"]

spec.add_development_dependency "aruba", "~> 0.6.2"
spec.add_development_dependency "bundler", "~> 1.6"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "rspec", "~> 3.0"
spec.add_development_dependency "sinatra", "~> 1.4.5"
end
2 changes: 1 addition & 1 deletion features/support/env.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
puts "Killing server..."
system "for i in `ps axu | grep 'server.rb' | grep ruby | awk '{print $2}'`; do kill -9 $i; done > /dev/null 2>&1"

@aruba_timeout_seconds = 10
@aruba_timeout_seconds = 20
end
8 changes: 8 additions & 0 deletions lib/dredd_hooks/definitions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module DreddHooks

HOOKS_ON_SINGLE_TRANSACTIONS = [:before, :before_validation, :after]

HOOKS_ON_MULTIPLE_TRANSACTIONS = [:before_each, :before_each_validation,
:after_each, :before_all, :after_all]
end

80 changes: 43 additions & 37 deletions lib/dredd_hooks/methods.rb
Original file line number Diff line number Diff line change
@@ -1,53 +1,59 @@
module DreddHooks
module Methods
@@before_hooks = {}
@@before_validation_hooks = {}
@@after_hooks = {}
require 'dredd_hooks/definitions'
require 'dredd_hooks/runner'

@@before_each_hooks = []
@@before_each_validation_hooks = []
@@after_each_hooks = []
module DreddHooks

@@before_all_hooks = []
@@after_all_hooks = []
# The Ruby hooks API
module Methods

# Define hook methods in the form of:
#
# Ruby hooks API
# def before(transaction_name, &block)
# runner.register_before_hook(transaction_name, &block)
# end
#
# Hooks names are defined by HOOKS_ON_SINGLE_TRANSACTIONS.
#
# Returns nothing.
def self.define_hooks_on_single_transactions
HOOKS_ON_SINGLE_TRANSACTIONS.each do |hook_name|

def before transaction_name, &block
@@before_hooks[transaction_name] = [] if @@before_hooks[transaction_name].nil?
@@before_hooks[transaction_name].push block
end
define_method hook_name do |transaction_name, &block|
runner.send("register_#{hook_name}_hook", transaction_name, &block)
end

def before_validation transaction_name, &block
@@before_validation_hooks[transaction_name] = [] if @@before_validation_hooks[transaction_name].nil?
@@before_validation_hooks[transaction_name].push block
end
end
private_class_method :define_hooks_on_single_transactions

def after transaction_name, &block
@@after_hooks[transaction_name] = [] if @@after_hooks[transaction_name].nil?
@@after_hooks[transaction_name].push block
end
# Define hook methods in the form of:
#
# def before_all(&block)
# runner.register_before_all_hook(&block)
# end
#
# Hooks names are defined by HOOKS_ON_MULTIPLE_TRANSACTIONS.
#
# Returns nothing.
def self.define_hooks_on_multiple_transactions
HOOKS_ON_MULTIPLE_TRANSACTIONS.each do |hook_name|

def before_each &block
@@before_each_hooks.push block
end
define_method hook_name do |&block|
runner.send("register_#{hook_name}_hook", &block)
end

def before_each_validation &block
@@before_each_validation_hooks.push block
end
end
private_class_method :define_hooks_on_multiple_transactions

def after_each &block
@@after_each_hooks.push block
end
define_hooks_on_single_transactions
define_hooks_on_multiple_transactions

def before_all &block
@@before_all_hooks.push block
end
private

def after_all &block
@@after_all_hooks.push block
end
def runner
Runner.instance
end
end
end
end

Loading