chore: linting

This commit is contained in:
Phan An 2022-04-25 19:38:33 +03:00
parent 734a9936c2
commit 7cb3e27ad8
No known key found for this signature in database
GPG key ID: A81E4477F0BB6FDC
11 changed files with 29 additions and 41 deletions

View file

@ -12,6 +12,11 @@
"@vue/standard", "@vue/standard",
"@vue/typescript/recommended" "@vue/typescript/recommended"
], ],
"ignorePatterns": [
"cypress/fixtures",
"cypress/screenshots",
"resources/assets/js/tests/__coverage__"
],
"plugins": [ "plugins": [
"@typescript-eslint" "@typescript-eslint"
], ],

View file

@ -55,7 +55,6 @@ context('Favorites', { scrollBehavior: false }, () => {
cy.$assertFavoriteSongCount(4) cy.$assertFavoriteSongCount(4)
}) })
it('deletes a favorite with Unlike button', () => { it('deletes a favorite with Unlike button', () => {
cy.intercept('POST', '/api/interaction/like', {}) cy.intercept('POST', '/api/interaction/like', {})
cy.$clickSidebarItem('Favorites') cy.$clickSidebarItem('Favorites')

View file

@ -229,8 +229,8 @@ context('Playlists', () => {
cy.findByText('Created playlist "My Smart Playlist."').should('be.visible') cy.findByText('Created playlist "My Smart Playlist."').should('be.visible')
cy.get('#playlistWrapper .heading-wrapper') cy.get('#playlistWrapper .heading-wrapper')
.should('be.visible') .should('be.visible')
.and('contain', 'My Smart Playlist') .and('contain', 'My Smart Playlist')
cy.$assertSidebarItemActive('My Smart Playlist') cy.$assertSidebarItemActive('My Smart Playlist')
cy.$assertPlaylistSongCount('My Smart Playlist', 3) cy.$assertPlaylistSongCount('My Smart Playlist', 3)

View file

@ -84,9 +84,9 @@ context('Song Context Menu', { scrollBehavior: false }, () => {
}) })
cy.findByTestId('song-context-menu').within(() => { cy.findByTestId('song-context-menu').within(() => {
cy.findByText('Add To').click() cy.findByText('Add To').click()
cy.findByText(config.menuItem).click() cy.findByText(config.menuItem).click()
}) })
cy.$clickSidebarItem('Current Queue') cy.$clickSidebarItem('Current Queue')
cy.get('#queueWrapper').within(() => { cy.get('#queueWrapper').within(() => {
@ -197,13 +197,13 @@ context('Song Context Menu', { scrollBehavior: false }, () => {
cy.findByTestId('song-context-menu').within(() => cy.findByText('Edit').should('not.exist')) cy.findByTestId('song-context-menu').within(() => cy.findByText('Edit').should('not.exist'))
}) })
it("copies a song's URL", () => { it('copies a song\'s URL', () => {
cy.$login() cy.$login()
cy.$clickSidebarItem('All Songs') cy.$clickSidebarItem('All Songs')
cy.window().then(window => cy.spy(window.document, 'execCommand').as('copy')); cy.window().then(window => cy.spy(window.document, 'execCommand').as('copy'))
cy.get('#songsWrapper').within(() => cy.get('tr.song-item:first-child').rightclick()) cy.get('#songsWrapper').within(() => cy.get('tr.song-item:first-child').rightclick())
cy.findByTestId('song-context-menu').within(() => cy.findByText('Copy Shareable URL').click()) cy.findByTestId('song-context-menu').within(() => cy.findByText('Copy Shareable URL').click())
cy.get('@copy').should('be.calledWithExactly', 'copy'); cy.get('@copy').should('be.calledWithExactly', 'copy')
}) })
}) })

View file

@ -94,15 +94,11 @@
"webpack-node-externals": "^3.0.0" "webpack-node-externals": "^3.0.0"
}, },
"scripts": { "scripts": {
"lint": "eslint ./cypress/**/*.ts", "lint": "eslint ./resources/assets/js/**/*.ts && eslint ./cypress/**/*.ts",
"watch.bak": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch-poll.bak": "yarn watch -- --watch-poll",
"hot.bak": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"test:e2e": "kill-port 8080 && start-test dev :8080 'cypress open'", "test:e2e": "kill-port 8080 && start-test dev :8080 'cypress open'",
"test:e2e:ci": "kill-port 8080 && start-test 'php artisan serve --port=8080 --quiet' :8080 'cypress run'", "test:e2e:ci": "kill-port 8080 && start-test 'php artisan serve --port=8080 --quiet' :8080 'cypress run'",
"build": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", "build": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"build-demo": "cross-env NODE_ENV=demo node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js -p", "build-demo": "cross-env NODE_ENV=demo node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js -p",
"production.bak": "yarn build",
"dev": "start-test 'php artisan serve --port=8000 --quiet' :8000 hot", "dev": "start-test 'php artisan serve --port=8000 --quiet' :8000 hot",
"development": "mix", "development": "mix",
"watch": "mix watch", "watch": "mix watch",
@ -122,6 +118,9 @@
], ],
"resources/assets/**/*.ts": [ "resources/assets/**/*.ts": [
"eslint" "eslint"
],
"cypress/**/*.ts": [
"eslint"
] ]
} }
} }

View file

@ -1,2 +0,0 @@
js/libs
js/tests/__coverage__

View file

@ -1,4 +1,3 @@
/// <reference path="./types.d.ts"/>
import '@babel/polyfill' import '@babel/polyfill'
import Vue from 'vue' import Vue from 'vue'
import lodash from 'lodash' import lodash from 'lodash'

View file

@ -12,7 +12,7 @@ declare namespace NodeJS {
Vue: any Vue: any
__UNIT_TESTING__: boolean __UNIT_TESTING__: boolean
_: any _: any
noop: Function noop: TAnyFunction,
IntersectionObserver: any IntersectionObserver: any
document: Document document: Document

View file

@ -6,12 +6,12 @@ import isMobile from 'ismobilejs'
import { playbackService } from '@/services' import { playbackService } from '@/services'
import { eventBus } from '@/utils' import { eventBus } from '@/utils'
import { queueStore, songStore } from '@/stores'
import router from '@/router'
import ControlsToggler from '@/components/ui/ScreenControlsToggler.vue' import ControlsToggler from '@/components/ui/ScreenControlsToggler.vue'
import SongList from '@/components/song/SongList.vue' import SongList from '@/components/song/SongList.vue'
import SongListControls from '@/components/song/SongListControls.vue' import SongListControls from '@/components/song/SongListControls.vue'
import { queueStore, songStore } from '@/stores'
import router from '@/router'
export const useSongList = (songs: Ref<Song[]>, controlsConfig: Partial<SongListControlsConfig> = {}) => { export const useSongList = (songs: Ref<Song[]>, controlsConfig: Partial<SongListControlsConfig> = {}) => {
const vm = getCurrentInstance() const vm = getCurrentInstance()

View file

@ -2,12 +2,12 @@ import { $ } from '@/utils'
import { Directive } from 'vue' import { Directive } from 'vue'
export const droppable: Directive = { export const droppable: Directive = {
created: (el: HTMLElement, { value }: { value: Function | never }): void => { created: (el: HTMLElement, { value }: { value: TAnyFunction | never }) => {
if (!(value instanceof Function)) { if (!(value instanceof Function)) {
throw new Error(`Expect a function, received ${typeof value}`) throw new Error(`Expect a function, received ${typeof value}`)
} }
el.addEventListener('dragenter', (event: DragEvent): boolean => { el.addEventListener('dragenter', (event: DragEvent) => {
event.preventDefault() event.preventDefault()
$.addClass(el, 'droppable') $.addClass(el, 'droppable')
event.dataTransfer!.dropEffect = 'move' event.dataTransfer!.dropEffect = 'move'
@ -17,9 +17,9 @@ export const droppable: Directive = {
el.addEventListener('dragover', (event: DragEvent): void => event.preventDefault()) el.addEventListener('dragover', (event: DragEvent): void => event.preventDefault())
el.addEventListener('dragleave', (): void => $.removeClass(el, 'droppable')) el.addEventListener('dragleave', () => $.removeClass(el, 'droppable'))
el.addEventListener('drop', (event: DragEvent): void => { el.addEventListener('drop', (event: DragEvent) => {
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
$.removeClass(el, 'droppable') $.removeClass(el, 'droppable')

View file

@ -2,23 +2,11 @@
* A utility that aims to replace jQuery for the most basic DOM methods. * A utility that aims to replace jQuery for the most basic DOM methods.
*/ */
export const $ = { export const $ = {
is: (el: Element, selector: string): boolean => { is: (el: Element, selector: string) => el.matches(selector),
return el.matches(selector) addClass: (el: Element | null, className: string) => el?.classList.add(className),
}, removeClass: (el: Element | null, className: string) => el?.classList.remove(className),
addClass: (el: Element | null, className: string): void => { scrollTo (el: Element, to: number, duration: number, cb?: TAnyFunction) {
if (el) {
el.classList.add(className)
}
},
removeClass: (el: Element | null, className: string): void => {
if (el) {
el.classList.remove(className)
}
},
scrollTo (el: Element, to: number, duration: number, cb?: Function): void {
if (duration <= 0 || !el) { if (duration <= 0 || !el) {
return return
} }
@ -26,7 +14,7 @@ export const $ = {
const difference = to - el.scrollTop const difference = to - el.scrollTop
const perTick = difference / duration * 10 const perTick = difference / duration * 10
window.setTimeout((): void => { window.setTimeout(() => {
el.scrollTop = el.scrollTop + perTick el.scrollTop = el.scrollTop + perTick
if (el.scrollTop === to) { if (el.scrollTop === to) {