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

Core: Add support for multiple hooks #1188

Merged
merged 3 commits into from
Jun 6, 2017

Conversation

trentmwillis
Copy link
Member

Fixes #977.

When using the nested module pattern, you can now define a multiple of each hook (before/beforeEach/afterEach/after). before/beforeEach hooks are run FIFO order and after/afterEach are run in LIFO order. This is consistent with the behavior already exhibited by those hooks when nested in modules.

cc @rwjblue (who I believe is interested in this feature for ember-qunit).

Copy link
Contributor

@platinumazure platinumazure left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I request doc changes in this PR since we have API docs in this repository now?

Code/tests LGTM, assuming we have coverage of things like nested module hooks or multiple tests (for beforeEach​/afterEach callbacks) elsewhere.

Copy link
Contributor

@rwjblue rwjblue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm super excited this, thank you for tackling it @trentmwillis! This should absolutely unblock the much nicer (IMO) API leveraging nested modules that I proposed in emberjs/ember-qunit#258.

I left a few small questions/comments (feel free to disregard as appropriate).

src/core.js Outdated

function setHookFromEnvironment( hooks, environment, name ) {
const potentialHook = environment[ name ];
hooks[ name ] = typeof potentialHook === "function" ? [ potentialHook ] : [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure if it matters, but this creates 4 new arrays per module regardless of if they are needed. Instead of falling back to [] we could set to null, and in setHookFunction below you could check for null and create the array when needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure which is better. I went this route so that we don't have to have as much branching in the logic and I doubt it will have much impact on test performance.

src/test.js Outdated
var promise,
test = this;
queueHook( hook, hookName, hookOwner ) {
const test = this;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use arrow functions below instead? I am unsure if we transpile though...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion. I can do that, but will need to save it to a variable so that we get a name in the stack trace for better debuggability.

@trentmwillis
Copy link
Member Author

Updated to address comments.

Can I request doc changes in this PR since we have API docs in this repository now?

Yep, I added some comments but nothing too lengthy. The entire QUnit.module docs likely need to be reworked as they're kind of confusing as it stands.

Code/tests LGTM, assuming we have coverage of things like nested module hooks or multiple tests (for beforeEach​/afterEach callbacks) elsewhere.

Yeah, the other tests in the file should handle the other features. We can add additional tests later if bugs are found.

@@ -199,10 +199,12 @@ QUnit.test( "makes a car", function( assert ) {

---

Hooks stack on nested modules
`before`/`beforeEach` hooks queue on nested modules. `after`/`afterEach` hooks stack on nested modules.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense for those familiar with the data structures, but it might not be accessible to software engineers who don't have a strong background in data structures. Maybe this could be reworded to say outer and earlier-declared before/beforeEach functions run before​ inner and later-declared ones, and the reverse for after/afterEach? (Though I'll admit what I've proposed isn't great, either.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further up in the document it says:

Additionally, any hook callbacks on a parent module will wrap the hooks on a nested module. In other words, before and beforeEach callbacks will form a queue while the afterEach and after callbacks will form a stack.

So I'm just trying to keep consistent messaging. If you feel strongly, I can reword it now, but as mentioned before I do think we need to rework the majority of this doc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I just missed that. I agree this needs to be reworked later but also agree that consistent messaging now is good.

@trentmwillis
Copy link
Member Author

@qunitjs/qunit-team I'm going to leave this open for another 24 hours in case anyone else wants to review. I know there were some differing opinions on the order of execution for the hooks, so I don't want to jump the gun on merging.

That said, I'm fairly confident in this ordering since it is consistent with the current behavior for nested modules.

setHookFromEnvironment( hooks, testEnvironment, "afterEach" );
setHookFromEnvironment( hooks, testEnvironment, "after" );

function setHookFromEnvironment( hooks, environment, name ) {
Copy link
Member

@Krinkle Krinkle Jun 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure the hooks and environment parameters add value in this case. Is this is a V8-optimisation perhaps?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure what you mean as both parameters are used in the function. Unless you're referring to the function itself, which is really just here to avoid repeating the same code for each hook.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but I was suggesting to have setHookFromEnvironment take only one parameter, name. Since the rest is just here in scope?

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

Successfully merging this pull request may close these issues.

4 participants