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

Allow a hook to be executed for all transactions (beforeEach hook) #63

Closed
peterstrapp opened this issue Mar 19, 2014 · 11 comments
Closed

Comments

@peterstrapp
Copy link

Currently hooks have to be applied to a specific transaction.

It would be useful to have "global" hooks that execute before each test, something like this:

before "ALL", (transaction) ->
  console.log 'Displayed before each test'

For now I am working around this limitation by calling runHooksForTransaction two more times (once for before and once for after) in add-hooks.js and passing in a fake transaction name of "ALL".

runner.before('executeTransaction', function(transaction, callback) {
    return runHooksForTransaction(hooks.beforeHooks['ALL'], transaction, callback);
});
@ecordell
Copy link
Contributor

Can I ask what you need to do in a hook for every endpoint that can't be done with flags?

There's a fairly easy way to do this right now: run with --names, copy the list of names, make it an array, and then iterate over them.

Here's an example of mine:

{before, after} = require 'hooks'

endpoints = [
  "Authentication > Users Collection > Create a User",
  "Authentication > Sessions > Create a Session",
  # all endpoints ...
]

for endpoint in endpoints
  before endpoint, (transaction) ->
    delete transaction.expected.headers['Location']
    delete transaction.expected.headers['X-Total-Count']
    delete transaction.expected.headers['Link']

You can have multiple hooks for the same name, so it won't affect anything else.

@peterstrapp
Copy link
Author

I'm templating parts of the blueprint file, substituting place-holders for values. I can't know upfront what endpoints exist as the blueprint file will be modified by other users. I don't want them to have to modify the hook file each time an endpoint is added.

If there's a way of getting the list of endpoints pragmatically, within the hook file, then your approach would be ideal.

@ecordell
Copy link
Contributor

Transactions are exposed in hooks so you can do something like:

{before, after, transactions} = require 'hooks'

endpoints = transactions.map (currentValue, index, array) ->
  currentValue.name

for endpoint in endpoints
  before (transaction, done) ->
    #do something
    done()

@peterstrapp
Copy link
Author

Thanks for the suggestion, I've just given it a try. Unfortunately it seems that 'transactions' isn't populated until after the hook file is executed.

@ecordell
Copy link
Contributor

ecordell commented Apr 1, 2014

Unfortunately it seems that 'transactions' isn't populated until after the hook file is executed.

Hmm, that shouldn't be true - the whole point of exposing the transactions is so that they're available to use in hookfiles. Are you using the latest version of Dredd? Can you post an example of code that doesn't work?

@peterstrapp
Copy link
Author

Yes, I'm using Dredd v0.3.1.

Executing the below hook file prints an empty object ("{}") therefore, when attempting to execute map on it (as in the code above) it fails.

dredd test.md http://a.domain.com -d -m POST --hookfiles=hook.coffee -l error

{before, after, transactions} = require 'hooks'
console.log transactions

@BrianHicks
Copy link

I'm seeing this too, also on Dredd v0.3.1.

@vadim-hbo
Copy link

Ditto Dredd 0.3.9

@dbryand
Copy link

dbryand commented Dec 1, 2014

I'm doing something very similar to this, but I set it all up in the beforeAll hook:

var hook  = require('hooks');

// This patches Dredd so that we can run a function beforeEach.
function setBeforeEach() {
  _.each(hook.transactions, function(transaction) {
    var hooked = hook.beforeHooks[transaction.name] || [];

    hooked.unshift(function(transaction, done) {
      console.log('seen before each');
      done();
    });

    hook.beforeHooks[transaction.name] = hooked;
  });
}

hook.beforeAll(function(done) {
  setBeforeEach();
});

@conord33
Copy link

conord33 commented Dec 8, 2014

Awesome patch @dbryand! I generalized it, in coffeescript, a little more to be used like the before hook.

# before each patch
hooks.beforeEach = (hook) -> 
  hooks.beforeAll (done) ->
    transactionKeys = Object.keys hooks.transactions
    for key in transactionKeys
      hooked = hooks.beforeHooks[key] || []
      hooked.unshift (transaction, done) ->
        hook(transaction)
        done()
      hooks.beforeHooks[key] = hooked
    done()

The method can be called like this

hooks.beforeEach (transaction) ->
  hookToRunBeforeEachTest()

@netmilk netmilk changed the title Allow a hook to be executed for all transactions Allow a hook to be executed for all transactions (beforeEach hook) Feb 23, 2015
@kuba-kubula
Copy link
Member

Hi everyone,

In last month Dredd has undergone some refactoring (it also touched the hooks implementation) so the best approach right now is described in hooks documentation where the beforeAll workaround is taken from pieces of code here and there.

I'll keep this issue open until Dredd has direct support for the beroreEach method, ok?

cc. @conord33 @dbryand @peterstrapp @ecordell @BrianHicks

@netmilk netmilk closed this as completed Aug 19, 2015
artem-zakharchenko pushed a commit that referenced this issue Oct 9, 2019
…names-swagger

Unique transaction names for Swagger
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants