Skip to content

Refactor/mvpn 267 enable tslint #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

Merged
merged 23 commits into from
Oct 18, 2018
Merged

Conversation

mipo47
Copy link
Contributor

@mipo47 mipo47 commented Oct 8, 2018

Please ask questions related with TsLint enabling only :)


interface AppStyles {
interface IAppStyles {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this an interface or a type?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?? Why do we need I prefix for interfaces? It just makes name longer and couples name to the fact that it's an Interface - if we change it to class, than we will have to change name as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"I" is standard for interface types in most of languages. same is required by default tslint config.

Copy link
Contributor

@shroomist shroomist Oct 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is necessary to follow this default rule. thoughts? @donce

Makes it easy to differentiate interfaces from regular classes at a glance.

do we need this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Styling is very subjective, so it's tricky, but I personally agree that it's not needed.

I.e. in typescript compiler repository "I" prefix is forbidden. I've encountered "I" prefix as a bad example of naming in multiple good-naming materials.

We are already using Standard JS for mysterium-vpn - tslint seems to have it as well:
https://github.com/blakeembrey/tslint-config-standard. I've found this because somebody is complaining about tslint defaults not making sense :D palantir/tslint#4199

)
private async onFavoritePress(selectedProviderId: string): Promise<void> {
const favoriteProposals = this.props.proposalsStore.FavoriteProposals
if (!favoriteProposals) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no error handling?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FavoriteProposals is not computed, unable to get exception here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are just silently ignoring an error case here of !favoriteProposals.
why do you think this is good?

this.start(CONFIG.REFRESH_INTERVALS.PROPOSALS)
}

@action
async fetch (): Promise<FavoriteProposalDTO[]> {
const proposals: Array<ProposalDTO> = await this._api.findProposals()
protected async fetch(): Promise<FavoriteProposalDTO[]> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm. how does this modify the state, I don't see.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: fill be fixed

| 'Connecting'
| null = null

constructor(api: TequilapiClient) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IPFetcher doesn't need to know the whole tequila, but just .connectionIP()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but it's easier to give full access instead of extracting interface with connectionIP (less code)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also this way it is more difficult to understand the dependency -> difficult to debug.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: fill be fixed

.prettierrc Outdated
@@ -0,0 +1,5 @@
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this is .prettierrc and not tslint.json?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's good to add prettier or .editorconfig settings to project as it simplifies consistent config across team a lot.

}
} catch (e) {
console.warn('api.identityCreate failed', e)
return

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with internals of TequilapiClient and errors it throws (and if we can inspect error object to log specific failure), but I would prefer one try-catch instead of multiple per each operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you want to change this code?


const favoriteProposal = favoriteProposals.filter(
p => p.id === selectedProviderId
)[0]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could fail with zero-length - you could check it above with if (!favoriteProposals || !favoriteProposals.length)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for zero-length favoriteProposal will be equal to undefined without exception

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so here, user has not added favoutites before. favoriteProposals.length == 0 would be here right?
favoriteProposal would be undefined, and if (favoriteProposal) would never allow to add a favorite.
??

if (JSON.stringify(data) !== JSON.stringify(this._prevData)) {
this._prevData = data
console.info(`Fetcher '${this._name}' returns`, data)
if (JSON.stringify(data) !== JSON.stringify(this.prevData)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would lean on using proper deepEquality util, as maybe in this case it's acceptable, but it would fail if properties are reordered.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

.prettierrc Outdated
@@ -0,0 +1,5 @@
{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's good to add prettier or .editorconfig settings to project as it simplifies consistent config across team a lot.


interface AppStyles {
interface IAppStyles {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?? Why do we need I prefix for interfaces? It just makes name longer and couples name to the fact that it's an Interface - if we change it to class, than we will have to change name as well.

js/app/app.tsx Outdated
super(props)

// Bind local functions
this.connectDisconnect = this.connectDisconnect.bind(this)
}

public render() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?? It returns value, but it's not visible - is it a common practice for react+typescript to ignore return type for render?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, because it can return different types

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is not a common practice.
especially if this returns multiple different values, they Must be specified!
!!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What type should I return?

Copy link
Contributor

@Arrnas Arrnas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't really say much, only thing I noticed were the multiline statements - is there a set char limit for lines? I like to only make multiline statements when a single line goes over limit.

)
private async onFavoritePress(selectedProviderId: string): Promise<void> {
const favoriteProposals = this.props.proposalsStore.FavoriteProposals
if (!favoriteProposals) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are just silently ignoring an error case here of !favoriteProposals.
why do you think this is good?

| 'Connecting'
| null = null

constructor(api: TequilapiClient) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also this way it is more difficult to understand the dependency -> difficult to debug.

store.FavoriteProposals = favoriteProposals

// ensure that proposal is always selected
if (store.FavoriteProposals.length
&& store.FavoriteProposals.filter(p => p.id == store.SelectedProviderId).length === 0
if (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to ensure this?

Copy link
Contributor Author

@mipo47 mipo47 Oct 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropdown doesn't support non selected items, so I decide to select first proposals by default


const favoriteProposal = favoriteProposals.filter(
p => p.id === selectedProviderId
)[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so here, user has not added favoutites before. favoriteProposals.length == 0 would be here right?
favoriteProposal would be undefined, and if (favoriteProposal) would never allow to add a favorite.
??

js/app/stats.tsx Outdated

interface StatsProps {
interface IStatsProps {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean IStatsProps does not have function descriptions, so it should be a type not an interface.

package.json Outdated
@@ -32,9 +33,14 @@
"eslint-plugin-react": "^7.10.0",
"eslint-plugin-standard": "^3.0.1",
"jest-expo": "~27.0.0",
"prettier": "1.14.3",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?? why do we need extra tool if we're adding tslint?
tslint has the --fix flag

js/app/stats.tsx Outdated

interface StatsProps {
interface IStatsProps {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some props are types these are interfaces.
please be consistent

import { store } from '../store/app-store'
import { FetcherBase } from './fetcher-base'

export type IStatsFetcherProps = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!! changed to types but I prefix remains. please fix.

@observable FavoriteProposals: FavoriteProposalDTO[] | null = null
class AppStore {
@observable
public IdentityId: string | null = null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think public IdentityId: ?string could work the same way with less boilerplate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice topic to discuss before starting refactoring task

shroomist
shroomist previously approved these changes Oct 16, 2018
.gitignore Outdated
@@ -24,6 +24,8 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*

.jest/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be here.

protected proposalFetcher = new ProposalsFetcher(api)
protected statusFetcher = new StatusFetcher(api)
protected ipFetcher = new IPFetcher(api)
protected statsFetcher = new StatsFetcher(api)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private

* Tries to connect to selected VPN server
* @returns {Promise<void>}
*/
public async connect(): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be protected.

class Logger {
private debugMode: boolean = false

public showDebugMessages(): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logObservableChanges ?

js/app/app.tsx Outdated
import {observer} from "mobx-react/native";
import Stats from './stats'

logger.showDebugMessages()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this side-effect is a surprise

if (this.debugMode) {
return
}
this.debugMode = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So debugMode ensures that this is run only once - I though that it's a flag you have to change to true to get the debug mode, as #define DEBUG 0 in old days :D
Can we rename this to express it's purpose more accuratly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logingStarted ?


/**
* This exposes the native MysteriumClient module as a JS module.
*/
export default class MysteriumClient {
_client: any
export default class MysteriumClient implements IMysteriumClient {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this class?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate task


constructor (api: TequilapiClient) {
constructor(api: IPFetcherProps) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets call it props?

if (this.debugMode) {
return
}
this.debugMode = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logingStarted ?


/**
* This exposes the native MysteriumClient module as a JS module.
*/
export default class MysteriumClient {
_client: any
export default class MysteriumClient implements IMysteriumClient {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate task

@mipo47 mipo47 self-assigned this Oct 17, 2018
@mipo47 mipo47 added the help wanted Extra attention is needed label Oct 17, 2018
tslint.json Outdated
"arrow-parens": false,

"jsx-no-lambda": false,
"jsx-no-multiline-js": false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?? Do we really need to disable that? Having complex multiline expressions in jsx doesn't seem better to me.

@donce
Copy link
Contributor

donce commented Oct 17, 2018

no-unused-variable is deprecated. Since TypeScript 2.9. Please use the built-in compiler checks instead.

?? So why isn't typescript compiler catching these things, why unused stuff gets through?

js/app/logger.ts Outdated
@@ -0,0 +1,40 @@
import {reaction} from 'mobx'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!! spaces between brackets

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

tslint.json Outdated
"interface-over-type-literal": false,
"quotemark": [true, "single", "jsx-double"],
"no-return-await": true,
"curly": false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?? Why do we need this exception? We're not using it - removing it does not affect anything.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally like "curly": [true, "ignore-same-line"]
which allows for if (!account) return
instead of

    if (!account) { 
        return
    }

iberflow
iberflow previously approved these changes Oct 18, 2018
tslint.json Outdated
"interface-over-type-literal": false,
"quotemark": [true, "single", "jsx-double"],
"no-return-await": true,
"curly": false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally like "curly": [true, "ignore-same-line"]
which allows for if (!account) return
instead of

    if (!account) { 
        return
    }

donce
donce previously approved these changes Oct 18, 2018
iberflow
iberflow previously approved these changes Oct 18, 2018
@donce donce dismissed stale reviews from iberflow and themself via affc3fc October 18, 2018 13:48
@donce donce force-pushed the refactor/MVPN-267-enable-tslint branch from 36d744c to affc3fc Compare October 18, 2018 13:48
@mipo47 mipo47 merged commit 8f31cb6 into master Oct 18, 2018
@Waldz Waldz unassigned mipo47 Dec 7, 2018
@donce donce deleted the refactor/MVPN-267-enable-tslint branch December 11, 2018 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants