Skip to content

Commit

Permalink
should fail when we have two ngFor and the second trackBy function is…
Browse files Browse the repository at this point in the history
… not present (#721)
  • Loading branch information
wKoza authored and mgechev committed Oct 26, 2018
1 parent 9eb3327 commit 9269be6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/trackByFunctionRule.ts
Expand Up @@ -4,6 +4,9 @@ import { SourceFile } from 'typescript/lib/typescript';
import { NgWalker } from './angular/ngWalker';
import { BasicTemplateAstVisitor } from './angular/templates/basicTemplateAstVisitor';

//current offSet into the template
export let curOffSet = 0;

export class Rule extends Rules.AbstractRule {
static readonly metadata: IRuleMetadata = {
description: 'Ensures a trackBy function is used.',
Expand All @@ -18,6 +21,7 @@ export class Rule extends Rules.AbstractRule {
static readonly FAILURE_STRING = 'Missing trackBy function in ngFor directive';

apply(sourceFile: SourceFile): RuleFailure[] {
curOffSet = 0;
return this.applyWithWalker(new NgWalker(sourceFile, this.getOptions(), { templateVisitorCtrl: TrackByTemplateVisitor }));
}
}
Expand All @@ -39,9 +43,10 @@ class TrackByFunctionTemplateVisitor extends BasicTemplateAstVisitor {
return;
}

const pattern = /trackBy\s*:|\[ngForTrackBy\]\s*=\s*['"].*['"]/;
const pattern = /\s*ngFor.*\s*trackBy\s*:|\[ngForTrackBy\]\s*=\s*['"].*['"]/;

if (pattern.test(context.codeWithMap.source!)) {
if (pattern.test(context.codeWithMap.source!.substr(curOffSet))) {
curOffSet = prop.sourceSpan.end.offset;
return;
}

Expand All @@ -51,6 +56,7 @@ class TrackByFunctionTemplateVisitor extends BasicTemplateAstVisitor {
start: { offset: startOffset }
}
} = prop;

context.addFailureFromStartToEnd(startOffset, endOffset, getFailureMessage());
}
}
Expand Down
20 changes: 20 additions & 0 deletions test/trackByFunctionRule.spec.ts
Expand Up @@ -54,6 +54,26 @@ describe(ruleName, () => {
assertAnnotated({ message: getFailureMessage(), ruleName, source });
});

it('should fail when we have two ngFor and the second trackBy function is not present', () => {
const source = `
@Component({
template: \`
<div *ngFor="let item of [1, 2, 3]; trackBy: trackByFn">
{{ item }}
</div>
<ul>
<li *ngFor="let item of [1, 2, 3];">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{{ item }}
</li>
</ul>
\`
})
class Bar {}
`;
assertAnnotated({ message: getFailureMessage(), ruleName, source });
});

it('should fail when trackBy function is missing in multiple *ngFor', () => {
const source = `
@Component({
Expand Down

0 comments on commit 9269be6

Please sign in to comment.