Skip to content

Commit

Permalink
feat(rule): ion-item-options markup has changed (#15)
Browse files Browse the repository at this point in the history
* feat(ionItemOptions): add rule ion-item-options

* test(rules): add escaped backtick
  • Loading branch information
mhartington authored and cwoolum committed Jun 28, 2018
1 parent bec1252 commit c48e556
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 5 deletions.
4 changes: 0 additions & 4 deletions .angulardoc.json

This file was deleted.

45 changes: 45 additions & 0 deletions src/ionItemOptionMarkupHasChangedRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import * as ast from '@angular/compiler';
import { NgWalker } from 'codelyzer/angular/ngWalker';
import { BasicTemplateAstVisitor } from 'codelyzer/angular/templates/basicTemplateAstVisitor';
import * as Lint from 'tslint';
import * as ts from 'typescript';

export const ruleName = 'ion-item-option-markup-has-changed';
export const ruleMessage = 'Inside of ion-item-options, ion-item-option must be used instead of ion-button.';

class IonItemOptionMarkupChangedTemplateVisitor extends BasicTemplateAstVisitor {
visitElement(element: ast.ElementAst, context: any): any {
if (element.name && element.name === 'ion-item-options') {
element.children.forEach(child => {
if (
(child instanceof ast.ElementAst && child.name === 'ion-button') ||
(child instanceof ast.ElementAst && child.name === 'button' && !!child.attrs.find(attr => attr.name === 'ion-button'))
) {
const start = child.sourceSpan.start.offset;
this.addFailure(this.createFailure(start + 1, child.name.length, ruleMessage));
}
});
}
super.visitElement(element, context);
}
}

export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: ruleName,
type: 'functionality',
description: 'Buttons in ion-item-options have been renamed.',
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: IonItemOptionMarkupChangedTemplateVisitor
})
);
}
}
2 changes: 1 addition & 1 deletion src/ionNavbarIsNowIonToolbarRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as ts from 'typescript';
export const ruleName = 'ion-navbar-is-now-ion-toolbar';
const InvalidSyntaxBoxOpen = '<ion-navbar>';
const InvalidSyntaxBoxClose = '</ion-navbar>';
const InvalidSyntaxBoxRe = new RegExp('<ion-navbar[^>]*>((.|\n)*?)</ion-navbar>', 's');
const InvalidSyntaxBoxRe = new RegExp('<ion-navbar[^>]*>((.|\n)*?)</ion-navbar>');
const ValidSyntaxOpen = `<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button></ion-back-button>
Expand Down
56 changes: 56 additions & 0 deletions test/ionItemOptionMarkupHasChanged.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { ruleName, ruleMessage as message } from '../src/ionItemOptionMarkupHasChangedRule';
import { assertAnnotated, assertSuccess } from './testHelper';

describe(ruleName, () => {
describe('success', () => {
it('should work when ion-chip-button is used', () => {
let source = `
@Component({
template: \`
<ion-item-sliding>
<ion-item>
<ion-label>Item 1</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option expandable>
<ion-icon name="star"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
\`
})
class Bar{}
`;
assertSuccess(ruleName, source);
});
});

describe('failure', () => {
it('should fail when ion-button is used', () => {
let source = `
@Component({
template: \`
<ion-item-sliding>
<ion-item>
<ion-label>Item 1</ion-label>
</ion-item>
<ion-item-options side="end">
<button ion-button expandable>
~~~~~~
<ion-icon name="star"></ion-icon>
</button>
</ion-item-options>
</ion-item-sliding>
\`
})
class Bar{}
`;

assertAnnotated({
ruleName,
message,
source
});
});
});
});

0 comments on commit c48e556

Please sign in to comment.