-
Notifications
You must be signed in to change notification settings - Fork 82
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
Jasmine/Jest v20+: this syntax codemod #61
Conversation
2d4e56d
to
ce07298
Compare
@avaly thank you so much for contributing. 👍🏻 One thing I would like to figure out is how this new transformer fits with some of the other transformations. Example: when using Mocha, I guess it would make sense to run your transformer as part of the migration. So it this new transformer safe enough to run as part of the other codemods? Let me know what you think. I'll review the code soon. : ) |
@skovhus This codemod assumes the source code already matches Jest's syntax ( |
src/transformers/jasmine-this.js
Outdated
|
||
import detectQuoteStyle from '../utils/quote-style'; | ||
|
||
const testFunctionNames = ['after', 'afterEach', 'before', 'beforeEach', 'it']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Support also test
cc41b88
to
1be51ac
Compare
Thanks for this! Looks good to me. : ) I think it might make sense to run this after the Mocha transformer, similar to how we run chai-should as part of should.js here https://github.com/skovhus/jest-codemods/blob/master/src/transformers/should.js#L89 |
src/cli/index.js
Outdated
@@ -77,6 +79,10 @@ inquirer | |||
value: TRANSFORMER_CHAI_SHOULD, | |||
}, | |||
{ | |||
name: 'Jasmine: this Syntax', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering a bit if we can come up with a more descriptive name... Should we call it "Jasmine: this usage"? Hm.
src/transformers/jasmine-this.js
Outdated
@@ -0,0 +1,201 @@ | |||
/** | |||
* Codemod for transforming Jamine `this` context into Jest v20+ compatible syntax. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jasmine
src/transformers/jasmine-this.js
Outdated
const addLetDeclarations = () => { | ||
Object.keys(replacedIdentifiersMap) | ||
// Reverse the keys because we're adding them one by one to the front of the body array | ||
.sort(reverseComparator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just do .sort().reverse()
Can I get you to rebase master and use the new |
Be aware that Mocha has some magic this functions (see #56) |
1be51ac
to
66a3fc8
Compare
@skovhus I've address your comments, rebased, and added the special Mocha functions to an ignore list. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work! Will hopefully be able to release this tomorrow.
Timeout actually has an equivalent in Jest/Jasmine. You can do this: it('does something', () => {
// some assertion
}, 500); Which sets a 500ms timeout. I don't think it's available for describe blocks though, so if you wanted to add support for this it'd need to be detected on the suite and then added to each |
Thanks for providing an awesome codeshift for this migration 👍 For visibility I ran this locally, and ran into some issues. This was my before code: const asyncCall = function () {
return Promise.resolve({ foo: 10 });
};
describe('async example', function () {
beforeEach(async function () {
this.response = await asyncCall();
});
it('makes the call with token', async function () {
expect(this.response).toEqual({ foo: 10 });
});
}); And this was my after code: const asyncCall = function () {
return Promise.resolve({ foo: 10 });
};
describe('async example', () => {
let responseContext;
beforeEach(() => {
responseContext = await asyncCall();
});
it('makes the call with token', () => {
expect(responseContext).toEqual({ foo: 10 });
});
}); The after code no longer compiles:
i.e. The change from It's possible to fix this by manually adding the
This may not be a problem with this particular code shift, but I thought i'd flag it up for visibility 👍 |
@AlanFoster Thanks for reporting the issue. Indeed I overlooked async functions. I'll patch the codemod when I get a chance to treat async functions as well. |
@avaly No problem! Thanks for the code shift, it saved us a bunch of time 👍 Out of interest - what are your thoughts on this approach: Extract So for one of your examples, we introduce a Current approach: describe('foo', () => {
let barContext;
let fooContext;
beforeEach(() => {
fooContext = { id: 'FOO' };
barContext = { id: 'BAR', child: fooContext };
});
it('should have proper IDs', () => {
expect(fooContext.id).to.equal('FOO');
expect(barContext.id).to.equal('BAR');
expect(barContext.child.id).to.equal('FOO');
});
}); Shared context approach: describe('foo', () => {
let context;
beforeEach(() => {
context = {};
});
beforeEach(() => {
context.foo = { id: 'FOO' };
context.bar = { id: 'BAR', child: context.foo };
});
it('should have proper IDs', () => {
expect(context.foo.id).to.equal('FOO');
expect(context.bar.id).to.equal('BAR');
expect(context.bar.child.id).to.equal('FOO');
});
}); It stops the scenario of leaking test state between tests without realizing it, or tests passing by mistake. It also ensures that future developers who modify the codeshifted files continue to make use of the naming convention of |
Thanks for the feedback @AlanFoster. And thanks @avaly for having a look at fixing it. 🤘🏻 |
66a3fc8
to
6240017
Compare
@AlanFoster I've added the async function support. Feel free to give it another try. I like your suggestion with the context object. I will give that a try later this week. Does anyone else have any better names for |
Closes skovhus#57 Context: jestjs/jest#3553
6240017
to
be985c5
Compare
I've updated the codemod using @AlanFoster's suggestion in #61 (comment) of grouping all context data in a shared object. |
@avaly The latest code shift works great! I was able to transform the entire codebase without any issues, and all tests pass :) One thing that is catching my eye is the rewrite of - it('sets initial state', function() {
- expect(this.state).toEqual({});
+ it('sets initial state', () => {
+ expect(testContext.state).toEqual({});
}); This might be a jest best practice though? I haven't tried out any of the other jest-codemods, but I wasn't able to see any linting rules to enforce using fat arrows within description blocks within eslint-plugin-jest for instance Let me know your thoughts if this code shift should preserve the original function type or always align with ArrowFunctionExpressions 👍 |
@AlanFoster thanks for testing it. I think using arrow functions makes sense for most people and is supported from node@4... Back from vacation now, so let us get this released! @avaly thank you so much for your work. |
@AlanFoster The main reason I chose to also replace normal functions with arrow functions is that since we no longer use |
Closes #57
Context: jestjs/jest#3553