-
Notifications
You must be signed in to change notification settings - Fork 8
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
chore: integrate new lint rules and fix all issues #1488
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1488 +/- ##
==========================================
- Coverage 99.46% 99.42% -0.05%
==========================================
Files 107 110 +3
Lines 3756 3802 +46
Branches 531 521 -10
==========================================
+ Hits 3736 3780 +44
- Misses 20 22 +2
Continue to review full report at Codecov.
|
fefc013
to
c6f227b
Compare
c6f227b
to
5bad3b9
Compare
748b520
to
95f772f
Compare
95f772f
to
cc9d398
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Review In Progress *
Next file is: terminus-ui/file-upload/src/selected-file.ts
In addition to the in-line comments, I have some general questions:
- When to use which linters, which are automatic?
- Will running any of the linter commands help with merging?
- How do I know when 'readonly' is appropriate?
Component-general:
- in autocomplete, is the makeup of OptionType type ever defined, does it change?
- in CHARTS, we've changed a ChartVisualizationOption treemap to tree... will we need a deprecation notice before making this change?
} | ||
|
||
chartCreated(chart) { | ||
chartCreated(chart: TsChart) { | ||
this.setChartData(chart, this.visualization); | ||
} | ||
|
||
|
||
// Currently using `any` here as I'm not sure how to let the consumer know what type is returned |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is no longer valid.
@@ -13,7 +13,17 @@ import { SelectComponent } from './select.component'; | |||
|
|||
@NgModule({ | |||
// tslint:disable-next-line:max-line-length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment not needed
@@ -157,8 +154,7 @@ export class TsButtonComponent implements OnInit, OnDestroy { | |||
|
|||
// Verify the value is allowed | |||
if (tsButtonFormatTypesArray.indexOf(value) < 0 && isDevMode()) { | |||
console.warn(`TsButtonComponent: "${value}" is not an allowed format. ` + | |||
`See TsButtonFormatTypes for available options.`); | |||
console.warn(`TsButtonComponent: "${value}" is not an allowed format. See TsButtonFormatTypes for available options.`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the reasons for using console.warn() vs throw.Error()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
console warn will just show a warning message in browser if that's ever got called. Depending on how consumer deals with errors that thrown, they might be bubbled up to the app, or silent out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've gone back and forth a bit on this.. in general I went with logs simply because they don't completely stop compilation and most of our warnings are around using a component correctly. But usually we don't need to stop all the things.
We're not 100% consistent on this so we'll need to make a more firm decision at some point.
|
||
it(`should set the collapseDelay to default if unset`, () => { | ||
buttonComponent.format = 'collapsable'; | ||
describe('when format === collapsable', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a functional issue, but this is using single quotes instead of ticks.
expect(component['collapseWithDelay']).not.toHaveBeenCalled(); | ||
expect(button.classList).not.toContain('c-button--collapsed'); | ||
}); | ||
it(`should not call collapseWithDelay if the type is not collapsable`, () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it() vs. test().
I know this isn't a change, so maybe it just needs its own ticket. There are other occurrences throughout the file.
@@ -1,9 +1,13 @@ | |||
// tslint:disable: component-class-suffix | |||
import { CommonModule } from '@angular/common'; | |||
import { Component, NgModule } from '@angular/core'; | |||
import { | |||
Component, NgModule, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two lines?
|
||
import { noop } from '@terminus/ngx-tools'; | ||
import { TS_EXPANSION_PANEL_DEFAULT_OPTIONS, TsExpansionPanelModule } from '@terminus/ui/expansion-panel'; | ||
import { | ||
TS_EXPANSION_PANEL_DEFAULT_OPTIONS, TsExpansionPanelModule, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two lines?
import { TsDropProtectionService } from './drop-protection.service'; | ||
import { TsFileImageDimensionConstraints } from './image-dimension-constraints'; | ||
import { TS_ACCEPTED_MIME_TYPES, TsFileAcceptedMimeTypes } from './mime-types'; | ||
import { | ||
TS_ACCEPTED_MIME_TYPES, TsFileAcceptedMimeTypes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two lines
* @param index - The item index | ||
* @return The unique ID | ||
*/ | ||
public trackByFn(index): number { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a test for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's being tested implicitly by other tests
this.onload({} as Event); | ||
}); | ||
// eslint-disable-next-line max-len | ||
public result = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABIAQMAAABvIyEEAAAAA1BMVEXXbFn0Q9OUAAAADklEQVR4AWMYRmAUjAIAAtAAAaW+yXMAAAAASUVORK5CYII='; | ||
} | ||
// Not sure why any is needed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need a // tslint:disable-next-line no-any
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spec files allow any by default now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some questions, some comments.
Most of the time multiple imports came from the same place, each had its own line, but sometimes two were together.
Weird to return undefined.
@@ -159,6 +161,7 @@ const allowedMaskShorcuts: TsMaskShortcutOptions[] = [ | |||
* @param item - The item to check | |||
* @return Whether the item is a function | |||
*/ | |||
// tslint:disable-next-line no-any | |||
function isFunction(item: any): item is Function { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ngx-tools has isFunction
, can that be utilized here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a note above this function about the typings not being correctly coerced when using the function from ngx-tools. There is an open ticket to explore this #1156
@@ -938,12 +951,19 @@ export class TsInputComponent implements | |||
|
|||
// Register this component as the associated input for the Material datepicker | |||
// istanbul ignore else | |||
// NOTE: Dangle naming controlled by Material | |||
// eslint-disable-next-line no-underscore-dangle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're using no-underscore-dangle below, in addition to no-any, would it be clearer/easier to put it in once to cover both cases?
if (this.picker && !this.picker._datepickerInput) { | ||
// NOTE: Dangle naming controlled by Material | ||
/* eslint-disable no-underscore-dangle */ | ||
// tslint:disable-next-line no-any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you can combine tslint:disable's into one line, is there a way to combine tslint and eslint into one line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately not that I know of. Hopefully straddling two tools will be short-lived for us and we can move solely to ESLint
@@ -3,9 +3,15 @@ import { | |||
SimpleChange, | |||
SimpleChanges, | |||
} from '@angular/core'; | |||
import { FormBuilder } from '@angular/forms'; | |||
import { | |||
FormBuilder, FormGroup, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two lines
import { TsValidatorsServiceMock } from '@terminus/ui/validators/testing'; | ||
|
||
import { | ||
fakeAsync, tick, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
two lines
@@ -4,21 +4,17 @@ | |||
"target": "es2015", | |||
"rootDir": ".", | |||
"baseUrl": "", | |||
"experimentalDecorators": true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean we won't have any more TypeScript errors in our .specs?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the hope.. I'm still getting mixed results in vim 😞
@@ -14,7 +14,7 @@ describe(`TsReactiveFormBaseComponent`, function() { | |||
// FIXME: Currently our coverage reporting includes spec files. This test gets us to 100% | |||
// coverage. We should ultimately fix our reporting so that only non-spec files count against our | |||
// coverage report. | |||
/* | |||
/* | |||
* describe(`METHOD_MOCK`, () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unneeded space
@@ -98,6 +100,4 @@ export class TsValidationMessagesService { | |||
return config[validatorName]; | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're invoking this in other places. I remember recently thinking it's pretty weird to to pass a datePipe just to get a validation message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you clarify what you mean by this?
"exclude": [ | ||
".ng_build" | ||
] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no longer excluding .ng-build
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is outdated config
"check-multiline-start" | ||
], | ||
"label-position": true, | ||
"max-line-length": [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These things that were removed here, are they now in eslint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Now projects should only define their own rules for custom overrides (such as enforcing a custom prefix name for components) or places where they are knowingly diverging from agreed upon conventions.
For instance, the library needs to use console warnings so we allow that specific type through in our own rules, but a codebase like Engage should not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a lot of work going into this!
A few comments and questions, but nothing jumps out. Looks good to me!
if (isZeroBased) { | ||
this.pages = Array.from(Array(this.paginator.pagesArray.length).keys()); | ||
} else { | ||
this.pages = Array.from(Array(this.paginator.pagesArray.length).keys()).map(v => ++v); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to make a note here 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hah good call.. added
chart.data = XY_DATA; | ||
|
||
const dateAxis = chart.xAxes.push(new am4charts.DateAxis()); | ||
dateAxis.renderer.grid.template.location = 0; | ||
|
||
const valueAxis = chart.yAxes.push(new am4charts.ValueAxis()); | ||
valueAxis.tooltip.disabled = true; | ||
if (valueAxis.tooltip) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How did typescript let you set disabled
attribute if it's possible to be null or undefined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prior to this lint PR the chart was always any
so there were just no checks at all. Once I added in type coercion functions for all the types, we suddenly see I was doing something dangerous.
@@ -95,7 +95,7 @@ export class NavigationComponent { | |||
|
|||
} | |||
|
|||
updateNav(): void { | |||
public updateNav(): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is public
or private
required now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, one of our rules now is member-access
which requires it be defined for all properties. This is a 'fixable' rule so I think if you don't add anything, it'll slap public
on.
We do not enforce this rule for spec or test component files
"compilerOptions": { | ||
"outDir": "../out-tsc/app", | ||
"outDir": "./../out-tsc/app", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dean purposely changed all those to ../
😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
./
is part of the Angular styleguide!
@@ -13,7 +13,7 @@ | |||
"url": "https://github.com/GetTerminus/terminus-ui/issues" | |||
}, | |||
"scripts": { | |||
"//=> Section: Demo App": "==============================", | |||
"//////// Section: Demo App": "==============================", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Help my dumb eyes see the section better. We were getting so many scripts I was experimenting with ways to better separate sections since we can't add comments to pure JSON.
The old format simply didn't jump out enough to me so it wasn't as helpful as it could be. Trying out a new format that jumps out a bit more.
if (!this.interceptClick) { | ||
this.clicked.emit(event); | ||
} else { | ||
if (this.interceptClick) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no negative condition rules :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, didn't realize I do this everywhere. 🤦♂ Especially in functions - I almost always have a catch for if no value is passed in.
|
||
// Since the toggle state depends on an @Input on the panel, we need to subscribe and trigger change detection manually. | ||
merge( | ||
panel.opened, panel.closed, accordionHideToggleChange, | ||
panel.inputChanges.pipe(filter((changes) => !!(changes['hideToggle'] || changes['disabled']))), | ||
panel.inputChanges.pipe(filter(changes => !!(changes.hideToggle || changes.disabled))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does lint require you to change from []
to .
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, there is a rule called dot-notation
that enforces this.
The dot notation is often preferred because it is easier to read, less verbose, and works better with aggressive JavaScript minimizers. Then on top of that, for TypeScript if --noImplicitAny
is turned off, property access via a string literal will be ‘any’ if the property does not exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This rule is disabled for spec files since we often need to use the bracket approach to access private items.
item.isExternal = this.isExternalLink(item.destination); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dean will ask you to write this block in one line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol.. I actually could have done better here with a map (and I'm changing) but I won't go as far as dean probably wants.. afaik the only way to do this in one line is to use the comma operator. And I personally don't think the lost clarity is worth one less line.
@@ -120,7 +122,7 @@ describe(`TsPaginatorComponent`, function() { | |||
describe(`changePage()`, () => { | |||
|
|||
test(`should fake a changed page event when valid`, () => { | |||
spyOn(component, 'currentPageChanged').and.callThrough(); | |||
jest.spyOn(component, 'currentPageChanged'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the difference between these two? i used quite a big callThrough
in the past.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and.callThrough
is a Jasmine thing. When using jest.spyOn
, the default behavior is to also call the original method.
name: name, | ||
value: value, | ||
name, | ||
value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
We should always use all linters. My goal is to create composable commands in
In the
And most important, my IDE is set up to run
In a way.. it should help us all use more consistent formats etc which should help some automatic merging.
It should be used when the item should never change. A great example is
Yep, the class defines a default value for export class TsAutocompleteComponent<OptionType = {[name: string]: any}> ... So this works just like if we had just simply set the type to type myCoolType = number;
...
@ViewChild(TsAutocompleteComponent<myCoolType>)
auto: TsAutocompleteComponent<myCoolType>; Then for instance, when they pass in a
Good catch. Normally, absolutely. In this case I rolled it into this change simply because I know that no one is even playing with charts yet. |
@shani-terminus @atlwendy all comments have been addressed |
tslint
andeslint
rulesany
/ type coercionVarious learnings
/* foo */
vs// foo
)