Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rule): add no-queries-parameter rule #571

Merged
merged 1 commit into from Apr 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/index.ts
Expand Up @@ -19,6 +19,7 @@ export { Rule as NoLifeCycleCallRule } from './noLifeCycleCallRule';
export { Rule as NoOutputNamedAfterStandardEventRule } from './noOutputNamedAfterStandardEventRule';
export { Rule as NoOutputOnPrefixRule } from './noOutputOnPrefixRule';
export { Rule as NoOutputRenameRule } from './noOutputRenameRule';
export { Rule as NoQueriesParameterRule } from './noQueriesParameterRule';
export { Rule as NoUnusedCssRule } from './noUnusedCssRule';
export { Rule as PipeImpureRule } from './pipeImpureRule';
export { Rule as PipeNamingRule } from './pipeNamingRule';
Expand Down
33 changes: 33 additions & 0 deletions src/noQueriesParameterRule.ts
@@ -0,0 +1,33 @@
import * as Lint from 'tslint';
import { UsePropertyDecorator } from './propertyDecoratorBase';

export class Rule extends UsePropertyDecorator {
static metadata: Lint.IRuleMetadata = {
description:
'Use @ContentChild, @ContentChildren, @ViewChild or @ViewChildren instead of the `queries` property of ' +
'`@Component` or `@Directive` metadata.',
options: null,
optionsDescription: 'Not configurable.',
rationale:
'The property associated with `@ContentChild`, `@ContentChildren`, `@ViewChild` or `@ViewChildren` ' +
`can be modified only in a single place: in the directive's class. If you use the \`queries\` metadata ` +
'property, you must modify both the property declaration inside the controller, and the metadata ' +
'associated with the directive.',
ruleName: 'no-queries-parameter',
type: 'style',
typescriptOnly: true
};

static FAILURE_STRING = 'Use @ContentChild, @ContentChildren, @ViewChild or @ViewChildren instead of the queries property';

constructor(options: Lint.IOptions) {
super(
{
decoratorName: ['ContentChild', 'ContentChildren', 'ViewChild', 'ViewChildren'],
propertyName: 'queries',
errorMessage: Rule.FAILURE_STRING
},
options
);
}
}
69 changes: 69 additions & 0 deletions test/noQueriesParameterRule.spec.ts
@@ -0,0 +1,69 @@
import { Rule } from '../src/noQueriesParameterRule';
import { assertAnnotated, assertSuccess } from './testHelper';

type MetadataType = 'Component' | 'Directive';

const { FAILURE_STRING, metadata: { ruleName } } = Rule;
const metadataTypes = new Set<MetadataType>(['Component', 'Directive']);

describe(ruleName, () => {
metadataTypes.forEach(metadataType => {
describe(metadataType, () => {
describe('failure', () => {
it('should fail when "queries" is used', () => {
const source = `
@${metadataType}({
queries: {
~~~~~~~~
contentChildren: new ContentChildren(ChildDirective),
viewChildren: new ViewChildren(ChildDirective)
}
~
})
class Test {}
`;
assertAnnotated({
message: FAILURE_STRING,
ruleName,
source
});
});

it('should fail when "queries" is used', () => {
const source = `
@${metadataType}({
queries: {
~~~~~~~~
contentChild: new ContentChild(ChildDirective),
viewChild: new ViewChild(ChildDirective)
}
~
})
class Test {}
`;
assertAnnotated({ message: FAILURE_STRING, ruleName, source });
});
});

describe('success', () => {
it('should succeed when "queries" is not used', () => {
const source = `
@${metadataType}({})
class Test {}
`;
assertSuccess(ruleName, source);
});

it('should succeed when content decorators are used', () => {
const source = `
@${metadataType}({})
class Test {
@ContentChild(ChildDirective) contentChild: ChildDirective;
}
`;
assertSuccess(ruleName, source);
});
});
});
});
});