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
Fix embedded templates handling in block-indentation
rule
#2838
Fix embedded templates handling in block-indentation
rule
#2838
Conversation
7f13c58
to
9e0d61f
Compare
@@ -2,7 +2,7 @@ import { parseTemplates } from 'ember-template-imports/lib/parse-templates.js'; | |||
import * as util from 'ember-template-imports/src/util.js'; | |||
|
|||
export const SUPPORTED_EXTENSIONS = ['.js', '.ts', '.gjs', '.gts']; | |||
const LOCATION_START = Object.freeze({ line: 0, column: 0, start: 0, end: 0 }); | |||
const LOCATION_START = Object.freeze({ line: 0, column: 0, start: 0, end: 0, columnOffset: 0 }); |
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.
The way I approached it, is that the location of the embedded template is offset by the indentation of the line the template starts at. So, something like
test('it renders', async (assert) => {
await render(hbs`
has an offset of 2, because await
has an indentation of 2 spaces. Based on this info, each rule (block-indentation
in this case, but attribute-indentation
can probably work the same) can adjust the expected indentation if needed.
function removeWhitespaceEnd(str) { | ||
return str.replace(/ +$/, ''); | ||
function addWhitespaceEnd(str, count) { | ||
return `${str}${' '.repeat(count)}`; |
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.
See line 326. The direct child indentation used to only remove whitespaces, but in embedded templates adding whitespaces is now also necessary sometimes.
@@ -306,13 +310,20 @@ export default class BlockIndentation extends Rule { | |||
const hasLeadingContent = | |||
!isDirectChildOfTemplate || this.hasLeadingContent(node, this.template.body); | |||
const startColumn = node.loc.start.column; | |||
const expectedStartColumn = | |||
this.columnOffset === 0 || node.loc.start.line === 1 |
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.
The 'root' node starting at line 1 is meant for cases like:
test('it renders', async (assert) => {
await render(hbs`<div class="parent">
<div class="child"></div>
</div>`);
);
@@ -347,8 +358,12 @@ export default class BlockIndentation extends Rule { | |||
|
|||
let controlCharCount = this.endingControlCharCount(node); | |||
let correctedEndColumn = endColumn - displayName.length - controlCharCount; | |||
let expectedEndColumn = | |||
this.columnOffset === 0 || node.loc.end.line !== this.template.loc.end.line |
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.
Similar to the start of a block:
test('it renders', async (assert) => {
await render(hbs`<div class="parent">
<div class="child"></div>
</div>`);
);
When the node it at the end of the template is and the template is embedded, then the start column should be the columnOffset
@@ -477,7 +494,7 @@ export default class BlockIndentation extends Rule { | |||
|
|||
fixedNode = this.fixLine( | |||
lines, | |||
childStartLine - 1, | |||
childStartLine - (path ? 1 : fixedNode.loc.start.line), |
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 actually seemed to be an existing bug. When I ran the autofixer with master
on our own embedded templates, then I got TypeError: Cannot read property 'startsWith' of undefined
because the childStartLine
was wrong
}, | ||
|
||
verifyResults(results) { | ||
expect(results).toMatchInlineSnapshot(` |
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.
Creating these snapshots was not trivial to do, is there a command for this?
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.
jest --updateSnapshot
?
9e0d61f
to
23e6fa3
Compare
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.
Seems reasonable, thanks! What part of #2826 is still not fixed? CC: @tylerbecks
block-indentation
rule for embedded templatesblock-indentation
rule
Thanks for merging! The part of #2826 that is not fixed is actually the first example mentioned there. I think it's the |
This partially fixes the issue described in #2826. The example in that issue is a combination of
block-indentation
andattribute-indentation
I think, and this PR only fixes theblock-indentation
, which I guess is more important to fix than attribute indentation. I've added some examples to the tests that work now (including autofix), but I'm happy to get feedback on other scenarios that need to be tested as well. An example of what this PR fixes:Before this PR, the linter would only be happy if it were formatted like:
which is not very pretty and intuitive.