-
Notifications
You must be signed in to change notification settings - Fork 309
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
Implement astTransformer - Compatibility with ts-jest 23.10 #204
Conversation
To make the example-app's tests pass again, I would suggest to remove their execution from the circleci tasks for now and add them after this version got published the first time. After that the tests will run again referencing [Edit: removed irrelevant comment about jest config] |
hi @wtho, I tried to check out your branch, ran
The same error I saw when running this |
@thymikee are you familiar with ast transformation ? I don't have much experience with it. |
You are correct with the test! I did not know paths like The transformer now adds The To make the example-app tests pass you have to run: cd example
npm install
# install version of this PR in example-app, will also get [email protected]
# and build InlineHtmlStripStylesTransformer.js from ts
# (did not know about that, but works! npm ftw!)
npm install wtho/jest-preset-angular#ts-jest-23-10
npm test I wanted to add this workaround to the CI-Tests as well until next publication, but yarn does not build the package after installed from github directly as npm does, so it would have been more complicated. I has issues with jest's caching, as I ran the tests long ago, so I run the tests with Also one more test in the example app fails for me, seems to be related to the Serializers (on Linux, Node v11):
|
const templatePathStringLiteral: StringLiteral = assignment.initializer; | ||
// match if it starts with ./ or ../ or / | ||
if (templatePathStringLiteral.text && | ||
!templatePathStringLiteral.text.match(/^(\.\/|\.\.\/|\/)/)) { |
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 haven't tested this improvement yet but by only reading the codes, it's not so generic to me. Because it's not so sure where the users can put their template, it might be ./ , ../../ or some other places within the project. I think it's better to resolve the path within the project or at least within src/app
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.
True!
I just checked the old regex mechanism, it would also not support templateUrl: 'src/page.html'
and transform it to ./src/page.html
.
When the astTransformer hits, it only gets config-set
injected. Luckily, the ConfigSet object seems to have a method resolvePath, I will see later if this serves our purpose on checking if require
will be able to find the file later on.
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.
Ok I looked into the issue a bit and saw the ts-compiler itself (which is also available in the transformer) offers many more path-tools than expected:
toPath, normalizePath, normalizePathAndParts, getDirectoryPath, isRootedDiskPath, isDiskPathRoot, convertToRelativePath, getPathComponents, reducePathComponents, getNormalizedPathComponents, getNormalizedAbsolutePath, getPathFromPathComponents, getRelativePathFromFile, getRelativePathFromDirectory, getRelativePathToDirectoryOrUrl, ensurePathIsNonModuleName, combinePaths, resolvePath, comparePathsCaseSensitive, comparePathsCaseInsensitive, comparePaths, containsPath, extensionFromPath, tryGetExtensionFromPath, getAnyExtensionFromPath, fullTripleSlashReferencePathRegEx, fullTripleSlashAMDReferencePathRegEx, getExternalModuleNameFromPath, getOwnEmitOutputFilePath, getDeclarationEmitOutputFilePath, getSourceFilePathInNewDir, getOutputPathsFor, updateMissingFilePathsWatch, getDefaultLibFilePath
But it feel like it would be an own task to figure out which methods help us to figure out if the file path is relative to the transformed file or relative to the project root using any path-definition inside tsconfig.json
.
I quickly checked resolvePath
, but that always appends the file to the project root.
Would you be ok with opening a new issue and for now keep the same behavior as the regex did before?
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.
Of course opening another PR for it is always fine by us👌 The only problem is we will need to create a temporary branch for this PR to merge in instead of master. Because master branch at the moment doesn't encounter this issue therefore we want to keep the state like it is right now. Until we solve the issue with this resolve path we can merge the branch of this PR into master. Do you agree @thymikee ?
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 disagree, the regex I use, /^(\.\/|\.\.\/|\/)/
, does (in combination with moving the string literal and renaming the property assignment to template) the same thing as the regex in master /templateUrl\s*:\s*('|"|
)(./){0,}(.*)('|"|)/g
, so I see no issue with merging to master for now.
The problem you describe (src/component => ./src/component
) has existed before.
I think this is not a reason to hold back this PR.
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.
hmm ok. I hope we make the users happy with this breaking change before they find out this hidden bug :)
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.
Quick Intro AST and the transformer
(Ignore if you know this already)
If you play with a ast-viewer by putting in a simple Angular Component you can get familiar with the AST that TSC will parse form the code. It is a big tree of nested nodes.
Every AST node will have a kind
-property, which is a SyntaxKind (all of them listed in typescript.d.ts).
For every SyntaxKind there is a is<KIND>(node)
-method, e. g. isStringLiteral(node)
. I use these in the transformer, e. g. here, and can then safely assume the node is of that kind and has the corresponding fields, so there is no need to check against the number 'manually'.
Once called getMutableClone()
on a node it is possible to modify inner nodes. Nodes can also be programmatically created, as explained here in the TS docs. We have to do this in the transformer to e. g. create the require()
-call.
Being familiar with this enables you to write custom TSLint rules as well.
* Remove obsolete processor which does not work with ts-jest 23.10 * Add AstTransformer to work with the new ts-jest API, that replaces templateUrl with template and a require call and strips off styles from Components for Tests in Jest * Add build commands to repository as transformer is written in TypeScript * Call build in prepare-script to include it in publish * ASTTransformer handles non-relative/non-absolute templateUrl by prefixing them with './'
|
thanks 👍 Strange CI still failed because one of the snapshots |
Yeah it's odd, I want to figure this out before merging. |
Ok so this is also a breaking change of ts-jest 23.10, of which they are probably not aware of Previously ts-jest used to handle html just calling now they create a module using This changes the output in the snapshots as (I guess) babel removes the escaping. How do we handle this? |
It comes from stringifyContentPathRegex which to keep backward compat of the old option Btw I like the new snapshot more :) the new snapshot actually is more correct than the old one. |
Ok, so summarizing these things are still open:
Follow-up issues
|
|
Yup, plus if there's a migration path, feel free to also add it to the changelog :) |
I updated the changelog and added a migration guide (ts-jest does apparently not offer one, so I explained the changes to be made in the config). Btw the snapshots does not differ because of Feel free to edit the changelog in any way before the v7 release. |
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.
This is awesome! Thank you so much on working on this. It means a lot, especially since I have no time for feature development like this anymore.
Left 2 small nits to address, once they're resolved we're gonna merge it and ship as an alpha for testing.
Yeah, I would love to! Also thank you both for helping me through this PR so far. |
Published this as |
Closes #195 and closes #201
Breaking Change
This is a breaking change as Configuration Interface changes (see ts-jest v23.10 docs)
This PR is built upon @huafu's #201, kudos to him for setting up everything and pointing out what was still to be done. Transformer and test are also heavily inspired by his examples in ts-jest. Also see the PR for more information.
Implementation Details
Like the Regex, all the transformer does is transform
templateUrl: <PATH>
totemplate: require(<PATH>)
styles: <ANYTHING>
tostyles: []
styleUrls <ANYTHING>
tostyleUrls: []
For more information see the comments in the transformer file or #201.
Edge Cases
I had to make some decisions on how strict the astTransformer is, I decided for this, but I am open to discussion:
Works
Caveat - this also gets transformed
Does not work
Additional Notes
npm test
prepare
-script for was added, which compiles it to JS before publishing and afternpm install
.preprocessor.js
and its unit tests were removed.