forked from cwoolum/ionicV4-tslint
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(rules): add new ion-button attribute rules
- Loading branch information
Showing
4 changed files
with
281 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
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-button-attributes-are-renamed'; | ||
|
||
class IonButtonAttributesAreRenamedTemplateVisitor extends BasicTemplateAstVisitor { | ||
visitElement(element: ast.ElementAst, context: any): any { | ||
if (element.name && element.name === 'ion-button') { | ||
element.attrs.forEach(attribute => { | ||
let message = ''; | ||
|
||
switch (attribute.name) { | ||
case 'icon-left': | ||
case 'icon-start': | ||
message = `${attribute.name} has been replaced by the slot="start" attribute.`; | ||
break; | ||
|
||
case 'icon-right': | ||
case 'icon-end': | ||
message = `${attribute.name} has been replaced by the slot="end" attribute.`; | ||
break; | ||
|
||
case 'small': | ||
case 'large': | ||
message = `${attribute.name} has been replaced by the size attribute.`; | ||
break; | ||
|
||
case 'clear': | ||
case 'outline': | ||
case 'solid': | ||
message = `${attribute.name} has been replaced by the fill attribute.`; | ||
break; | ||
|
||
case 'full': | ||
case 'block': | ||
message = `${attribute.name} has been replaced by the expand attribute.`; | ||
break; | ||
} | ||
|
||
if (message) { | ||
const start = attribute.sourceSpan.start.offset; | ||
//const absolutePosition = this.getSourcePosition(start - 1); | ||
|
||
this.addFailure(this.createFailure(start, attribute.name.length, message)); | ||
} | ||
}); | ||
} | ||
|
||
super.visitElement(element, context); | ||
} | ||
} | ||
|
||
export class Rule extends Lint.Rules.AbstractRule { | ||
public static metadata: Lint.IRuleMetadata = { | ||
ruleName: ruleName, | ||
type: 'functionality', | ||
description: 'Existing Ion Button attributes 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: IonButtonAttributesAreRenamedTemplateVisitor | ||
}) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
import { ruleName } from '../src/ionButtonAttributesAreRenamedRule'; | ||
import { assertAnnotated, assertSuccess } from './testHelper'; | ||
|
||
describe(ruleName, () => { | ||
describe('success', () => { | ||
it('should work with proper style', () => { | ||
let source = ` | ||
@Component({ | ||
template: \`<ion-button slot="start"><ion-button>\` | ||
}) | ||
class Bar{} | ||
`; | ||
assertSuccess(ruleName, source); | ||
}); | ||
}); | ||
|
||
describe('failure', () => { | ||
it('should fail when icon-left is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button icon-left></ion-button>\` | ||
~~~~~~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'icon-left has been replaced by the slot="start" attribute.', | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when icon-start is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button icon-start></ion-button>\` | ||
~~~~~~~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'icon-start has been replaced by the slot="start" attribute.', | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when icon-right is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button icon-right></ion-button>\` | ||
~~~~~~~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'icon-right has been replaced by the slot="end" attribute.', | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when icon-end is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button icon-end></ion-button>\` | ||
~~~~~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'icon-end has been replaced by the slot="end" attribute.', | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when small is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button small></ion-button>\` | ||
~~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'small has been replaced by the size attribute.', | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when large is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button large></ion-button>\` | ||
~~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'large has been replaced by the size attribute.', | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when clear is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button clear></ion-button>\` | ||
~~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'clear has been replaced by the fill attribute.', | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when outline is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button outline></ion-button>\` | ||
~~~~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'outline has been replaced by the fill attribute.', | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when solid is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button solid></ion-button>\` | ||
~~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'solid has been replaced by the fill attribute.', | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when full is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button full></ion-button>\` | ||
~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'full has been replaced by the expand attribute.', | ||
source | ||
}); | ||
}); | ||
|
||
it('should fail when block is used', () => { | ||
let source = ` | ||
@Component({ | ||
template: \` | ||
<ion-button block></ion-button>\` | ||
~~~~~ | ||
}) | ||
class Bar{} | ||
`; | ||
|
||
assertAnnotated({ | ||
ruleName, | ||
message: 'block has been replaced by the expand attribute.', | ||
source | ||
}); | ||
}); | ||
}); | ||
}); |