mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
117616: Ported themed-wrapper-no-input-defaults rule
This commit is contained in:
@@ -266,7 +266,8 @@
|
|||||||
"dspace-angular-ts/alias-imports": "error",
|
"dspace-angular-ts/alias-imports": "error",
|
||||||
"dspace-angular-ts/themed-component-classes": "error",
|
"dspace-angular-ts/themed-component-classes": "error",
|
||||||
"dspace-angular-ts/themed-component-selectors": "error",
|
"dspace-angular-ts/themed-component-selectors": "error",
|
||||||
"dspace-angular-ts/themed-component-usages": "error"
|
"dspace-angular-ts/themed-component-usages": "error",
|
||||||
|
"dspace-angular-ts/themed-wrapper-no-input-defaults": "error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -5,3 +5,4 @@ _______
|
|||||||
- [`dspace-angular-ts/themed-component-classes`](./rules/themed-component-classes.md): Formatting rules for themeable component classes
|
- [`dspace-angular-ts/themed-component-classes`](./rules/themed-component-classes.md): Formatting rules for themeable component classes
|
||||||
- [`dspace-angular-ts/themed-component-selectors`](./rules/themed-component-selectors.md): Themeable component selectors should follow the DSpace convention
|
- [`dspace-angular-ts/themed-component-selectors`](./rules/themed-component-selectors.md): Themeable component selectors should follow the DSpace convention
|
||||||
- [`dspace-angular-ts/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via their `ThemedComponent` wrapper class
|
- [`dspace-angular-ts/themed-component-usages`](./rules/themed-component-usages.md): Themeable components should be used via their `ThemedComponent` wrapper class
|
||||||
|
- [`dspace-angular-ts/themed-wrapper-no-input-defaults`](./rules/themed-wrapper-no-input-defaults.md): ThemedComponent wrappers should not declare input defaults (see [DSpace Angular #2164](https://github.com/DSpace/dspace-angular/pull/2164))
|
||||||
|
82
docs/lint/ts/rules/themed-wrapper-no-input-defaults.md
Normal file
82
docs/lint/ts/rules/themed-wrapper-no-input-defaults.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
[DSpace ESLint plugins](../../../../lint/README.md) > [TypeScript rules](../index.md) > `dspace-angular-ts/themed-wrapper-no-input-defaults`
|
||||||
|
_______
|
||||||
|
|
||||||
|
ThemedComponent wrappers should not declare input defaults (see [DSpace Angular #2164](https://github.com/DSpace/dspace-angular/pull/2164))
|
||||||
|
|
||||||
|
_______
|
||||||
|
|
||||||
|
[Source code](../../../../lint/src/rules/ts/themed-wrapper-no-input-defaults.ts)
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
|
||||||
|
#### Valid code
|
||||||
|
|
||||||
|
##### ThemedComponent wrapper defines an input without a default value
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class TTest extends ThemedComponent<Test> {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Regular class defines an input with a default value
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class Test {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test = 'test';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### Invalid code
|
||||||
|
|
||||||
|
##### ThemedComponent wrapper defines an input with a default value
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class TTest extends ThemedComponent<Test> {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test1 = 'test';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test2 = true;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test2: number = 123;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test3: number[] = [1,2,3];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Will produce the following error(s):
|
||||||
|
```
|
||||||
|
ThemedComponent wrapper declares inputs with defaults
|
||||||
|
ThemedComponent wrapper declares inputs with defaults
|
||||||
|
ThemedComponent wrapper declares inputs with defaults
|
||||||
|
ThemedComponent wrapper declares inputs with defaults
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
##### ThemedComponent wrapper defines an input with an undefined default value
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export class TTest extends ThemedComponent<Test> {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test = undefined;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Will produce the following error(s):
|
||||||
|
```
|
||||||
|
ThemedComponent wrapper declares inputs with defaults
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -14,12 +14,14 @@ import * as aliasImports from './alias-imports';
|
|||||||
import * as themedComponentClasses from './themed-component-classes';
|
import * as themedComponentClasses from './themed-component-classes';
|
||||||
import * as themedComponentSelectors from './themed-component-selectors';
|
import * as themedComponentSelectors from './themed-component-selectors';
|
||||||
import * as themedComponentUsages from './themed-component-usages';
|
import * as themedComponentUsages from './themed-component-usages';
|
||||||
|
import * as themedWrapperNoInputDefaults from './themed-wrapper-no-input-defaults';
|
||||||
|
|
||||||
const index = [
|
const index = [
|
||||||
aliasImports,
|
aliasImports,
|
||||||
themedComponentClasses,
|
themedComponentClasses,
|
||||||
themedComponentSelectors,
|
themedComponentSelectors,
|
||||||
themedComponentUsages,
|
themedComponentUsages,
|
||||||
|
themedWrapperNoInputDefaults,
|
||||||
] as unknown as RuleExports[];
|
] as unknown as RuleExports[];
|
||||||
|
|
||||||
export = {
|
export = {
|
||||||
|
157
lint/src/rules/ts/themed-wrapper-no-input-defaults.ts
Normal file
157
lint/src/rules/ts/themed-wrapper-no-input-defaults.ts
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
import {
|
||||||
|
ESLintUtils,
|
||||||
|
TSESTree,
|
||||||
|
} from '@typescript-eslint/utils';
|
||||||
|
import { RuleContext } from '@typescript-eslint/utils/ts-eslint';
|
||||||
|
|
||||||
|
import {
|
||||||
|
DSpaceESLintRuleInfo,
|
||||||
|
NamedTests,
|
||||||
|
} from '../../util/structure';
|
||||||
|
import { isThemedComponentWrapper } from '../../util/theme-support';
|
||||||
|
|
||||||
|
export enum Message {
|
||||||
|
WRAPPER_HAS_INPUT_DEFAULTS = 'wrapperHasInputDefaults',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const info: DSpaceESLintRuleInfo = {
|
||||||
|
name: 'themed-wrapper-no-input-defaults',
|
||||||
|
meta: {
|
||||||
|
docs: {
|
||||||
|
description: 'ThemedComponent wrappers should not declare input defaults (see [DSpace Angular #2164](https://github.com/DSpace/dspace-angular/pull/2164))',
|
||||||
|
},
|
||||||
|
messages: {
|
||||||
|
[Message.WRAPPER_HAS_INPUT_DEFAULTS]: 'ThemedComponent wrapper declares inputs with defaults',
|
||||||
|
},
|
||||||
|
type: 'problem',
|
||||||
|
schema: [],
|
||||||
|
},
|
||||||
|
defaultOptions: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const rule = ESLintUtils.RuleCreator.withoutDocs({
|
||||||
|
...info,
|
||||||
|
create(context: RuleContext<any, any>, options: any) {
|
||||||
|
return {
|
||||||
|
'ClassBody > PropertyDefinition > Decorator > CallExpression[callee.name=\'Input\']': (node: TSESTree.CallExpression) => {
|
||||||
|
const classDeclaration = (node?.parent?.parent?.parent as TSESTree.Decorator); // todo: clean this up
|
||||||
|
if (!isThemedComponentWrapper(classDeclaration)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const propertyDefinition: TSESTree.PropertyDefinition = (node.parent.parent as any); // todo: clean this up
|
||||||
|
|
||||||
|
if (propertyDefinition.value !== null) {
|
||||||
|
context.report({
|
||||||
|
messageId: Message.WRAPPER_HAS_INPUT_DEFAULTS,
|
||||||
|
node: propertyDefinition.value,
|
||||||
|
// fix(fixer) {
|
||||||
|
// // todo: don't strip type annotations!
|
||||||
|
// // todo: replace default with appropriate type annotation if not present!
|
||||||
|
// return fixer.removeRange([propertyDefinition.key.range[1], (propertyDefinition.value as any).range[1]]);
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const tests: NamedTests = {
|
||||||
|
plugin: info.name,
|
||||||
|
valid: [
|
||||||
|
{
|
||||||
|
name: 'ThemedComponent wrapper defines an input without a default value',
|
||||||
|
code: `
|
||||||
|
export class TTest extends ThemedComponent<Test> {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Regular class defines an input with a default value',
|
||||||
|
code: `
|
||||||
|
export class Test {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test = 'test';
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
invalid: [
|
||||||
|
{
|
||||||
|
name: 'ThemedComponent wrapper defines an input with a default value',
|
||||||
|
code: `
|
||||||
|
export class TTest extends ThemedComponent<Test> {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test1 = 'test';
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test2 = true;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test2: number = 123;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test3: number[] = [1,2,3];
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
messageId: 'wrapperHasInputDefaults',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
messageId: 'wrapperHasInputDefaults',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
messageId: 'wrapperHasInputDefaults',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
messageId: 'wrapperHasInputDefaults',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// output: `
|
||||||
|
// export class TTest extends ThemedComponent<Test> {
|
||||||
|
//
|
||||||
|
// @Input()
|
||||||
|
// test1: string;
|
||||||
|
//
|
||||||
|
// @Input()
|
||||||
|
// test2: boolean;
|
||||||
|
//
|
||||||
|
// @Input()
|
||||||
|
// test2: number;
|
||||||
|
//
|
||||||
|
// @Input()
|
||||||
|
// test3: number[];
|
||||||
|
// }
|
||||||
|
// `,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ThemedComponent wrapper defines an input with an undefined default value',
|
||||||
|
code: `
|
||||||
|
export class TTest extends ThemedComponent<Test> {
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
test = undefined;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
messageId: 'wrapperHasInputDefaults',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// output: `
|
||||||
|
// export class TTest extends ThemedComponent<Test> {
|
||||||
|
//
|
||||||
|
// @Input()
|
||||||
|
// test;
|
||||||
|
// }
|
||||||
|
// `,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
Reference in New Issue
Block a user