Skip to content

Commit

Permalink
feat(rules): add ion-list-header-ion-label-required rule (#35)
Browse files Browse the repository at this point in the history
* feat(rules): add ion-list-header-ion-label-required rule

* docs(readme): mark rule as complete
  • Loading branch information
imhoffd committed Jul 6, 2018
1 parent 04dae1c commit 94503c2
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 3 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,11 +356,13 @@ We are looking for contributors to help build these rules out! See [`CONTRIBUTIN
<a href="https://github.com/ionic-team/ionic/blob/master/angular/BREAKING.md#list-header">List Header</a>
</th>
<td></td>
<td>:white_large_square:</td>
<td>:white_check_mark:</td>
<td>
<code>ion-list-header-ion-label-required</code>
</td>
<td></td>
<td>
<a href="https://github.com/dwieeb">@dwieeb</a>
</td>
</tr>
<tr>
<th>
Expand Down
2 changes: 1 addition & 1 deletion src/ionItemIonLabelRequiredRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: ruleName,
type: 'functionality',
description: 'The ion-item requires an ion-label component. It is no longer automatically added.',
description: 'The ion-item component requires an ion-label component. It is no longer automatically added.',
options: null,
optionsDescription: 'Not configurable.',
typescriptOnly: false,
Expand Down
29 changes: 29 additions & 0 deletions src/ionListHeaderIonLabelRequiredRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { NgWalker } from 'codelyzer/angular/ngWalker';
import * as Lint from 'tslint';
import * as ts from 'typescript';

import { createIonLabelRequiredTemplateVisitorClass } from './helpers/ionLabelRequired';

export const ruleName = 'ion-list-header-ion-label-required';

const TemplateVisitor = createIonLabelRequiredTemplateVisitorClass('ion-list-header');

export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: ruleName,
type: 'functionality',
description: 'The ion-list-header component requires an ion-label component. It is no longer automatically added.',
options: null,
optionsDescription: 'Not configurable.',
typescriptOnly: false,
hasFix: true
};

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(
new NgWalker(sourceFile, this.getOptions(), {
templateVisitorCtrl: TemplateVisitor
})
);
}
}
80 changes: 80 additions & 0 deletions test/ionListHeaderIonLabelRequired.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { ruleName } from '../src/ionListHeaderIonLabelRequiredRule';
import { assertAnnotated, assertSuccess } from './testHelper';

describe(ruleName, () => {
describe('success', () => {
it('should work with ion-label child', () => {
let source = `
@Component({
template: \`
<ion-list-header>
<ion-thumbnail slot="start">
<img src="http://pngimg.com/upload/dog_png2402.png">
</ion-thumbnail>
<ion-label>Dog</ion-label>
</ion-list-header>
\`
})
class Bar{}
`;
assertSuccess(ruleName, source);
});

it('should work with single ion-label child', () => {
let source = `
@Component({
template: \`
<ion-list-header>
<ion-label>Dog</ion-label>
</ion-list-header>
\`
})
class Bar{}
`;
assertSuccess(ruleName, source);
});
});

describe('failure', () => {
it('should fail when ion-label missing', () => {
let source = `
@Component({
template: \`
<ion-list-header>
~~~~~~~~~~~~~~~
<ion-thumbnail slot="start">
<img src="http://pngimg.com/upload/dog_png2402.png">
</ion-thumbnail>
Dog
</ion-toolbar>
\`
})
class Bar{}
`;

assertAnnotated({
ruleName,
message: 'The ion-list-header requires an ion-label component. It is no longer automatically added.',
source
});
});

it('should fail with only text', () => {
let source = `
@Component({
template: \`
<ion-list-header>Dog</ion-list-header>
~~~~~~~~~~~~~~~
\`
})
class Bar{}
`;

assertAnnotated({
ruleName,
message: 'The ion-list-header requires an ion-label component. It is no longer automatically added.',
source
});
});
});
});

0 comments on commit 94503c2

Please sign in to comment.