diff --git a/README.md b/README.md
index 5ef4ccd..0f7ce58 100644
--- a/README.md
+++ b/README.md
@@ -356,11 +356,13 @@ We are looking for contributors to help build these rules out! See [`CONTRIBUTIN
List Header
|
- :white_large_square: |
+ :white_check_mark: |
ion-list-header-ion-label-required
|
- |
+
+ @dwieeb
+ |
diff --git a/src/ionItemIonLabelRequiredRule.ts b/src/ionItemIonLabelRequiredRule.ts
index a7e70d2..c602e59 100644
--- a/src/ionItemIonLabelRequiredRule.ts
+++ b/src/ionItemIonLabelRequiredRule.ts
@@ -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,
diff --git a/src/ionListHeaderIonLabelRequiredRule.ts b/src/ionListHeaderIonLabelRequiredRule.ts
new file mode 100644
index 0000000..70ec58a
--- /dev/null
+++ b/src/ionListHeaderIonLabelRequiredRule.ts
@@ -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
+ })
+ );
+ }
+}
diff --git a/test/ionListHeaderIonLabelRequired.spec.ts b/test/ionListHeaderIonLabelRequired.spec.ts
new file mode 100644
index 0000000..a69b52a
--- /dev/null
+++ b/test/ionListHeaderIonLabelRequired.spec.ts
@@ -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: \`
+
+
+
+
+ Dog
+
+ \`
+ })
+ class Bar{}
+ `;
+ assertSuccess(ruleName, source);
+ });
+
+ it('should work with single ion-label child', () => {
+ let source = `
+ @Component({
+ template: \`
+
+ Dog
+
+ \`
+ })
+ class Bar{}
+ `;
+ assertSuccess(ruleName, source);
+ });
+ });
+
+ describe('failure', () => {
+ it('should fail when ion-label missing', () => {
+ let source = `
+ @Component({
+ template: \`
+
+ ~~~~~~~~~~~~~~~
+
+
+
+ Dog
+
+ \`
+ })
+ 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: \`
+ Dog
+ ~~~~~~~~~~~~~~~
+ \`
+ })
+ class Bar{}
+ `;
+
+ assertAnnotated({
+ ruleName,
+ message: 'The ion-list-header requires an ion-label component. It is no longer automatically added.',
+ source
+ });
+ });
+ });
+});
|