From 473679be77da79d4a6ebff2dfdcab79d83bdeebd Mon Sep 17 00:00:00 2001 From: AkiraFukushima Date: Sat, 29 Dec 2018 00:04:17 +0900 Subject: [PATCH 1/2] refs #209 Add Login store unit tests --- package-lock.json | 14 +++-- package.json | 13 ++++- sideci.yml | 1 + spec/mock/electron.js | 6 +++ spec/unit/store/Login.spec.js | 64 +++++++++++++++++++++++ spec/unit/{ => utils}/emojify.spec.js | 2 +- spec/unit/{ => utils}/suggestText.spec.js | 2 +- spec/unit/{ => utils}/tootParser.spec.js | 2 +- spec/unit/{ => utils}/validator.spec.js | 2 +- src/renderer/store/Login.js | 2 +- 10 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 spec/mock/electron.js create mode 100644 spec/unit/store/Login.spec.js rename spec/unit/{ => utils}/emojify.spec.js (97%) rename spec/unit/{ => utils}/suggestText.spec.js (95%) rename spec/unit/{ => utils}/tootParser.spec.js (97%) rename spec/unit/{ => utils}/validator.spec.js (96%) diff --git a/package-lock.json b/package-lock.json index 90a0768b..fcd1cecf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2915,6 +2915,13 @@ "requires": { "core-js": "2.5.7", "regenerator-runtime": "0.11.1" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } } }, "babel-template": { @@ -15677,9 +15684,10 @@ "dev": true }, "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.1.tgz", + "integrity": "sha512-5KzMIyPLvfdPmvsdlYsHqITrDfK9k7bmvf97HvHSN4810i254ponbxCQ1NukpRWlu6en2MBWzAlhDExEKISwAA==", + "dev": true }, "regenerator-transform": { "version": "0.10.1", diff --git a/package.json b/package.json index 092bcd4d..518eacea 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "build:mas": "npm run build:clean && npm run pack && electron-packager ./ 'Whalebird' --platform=mas --arch=x64 --electron-version=3.0.10 --asar.unpackDir='build/sounds' --out=packages --ignore='^/src' --ignore='^/test' --ignore='^/.electron-vue' --ignore='^/.envrc' --ignore='^/packages' --ignore='^/plist' --ignore='^/static' --ignore='^/whalebird.db' --ignore='^/screenshot.png' --prune=true --icon=./build/icons/icon.icns --overwrite --app-bundle-id=org.whalebird.desktop --app-version=$npm_package_config_appVersion --build-version=$npm_package_config_buildVersion --extend-info='./plist/team.plist' --osx-sign --app-category-type=public.app-category.social-networking", "dev": "node .electron-vue/dev-runner.js", "e2e": "npm run pack && mocha test/e2e", - "lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter src test", + "lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter src spec", "lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter --fix src test", "stylelint": "stylelint '**/*.vue' --syntax scss", "pack": "npm run pack:main && npm run pack:renderer", @@ -39,7 +39,7 @@ "test": "npm run unit && npm run e2e", "unit": "karma start test/unit/karma.conf.js", "postinstall": "npm run lint:fix", - "spec:unit": "BABEL_ENV=test jest -u ./spec/unit/*.spec.js" + "spec:unit": "BABEL_ENV=test jest -u ./spec/unit/*/**.spec.js" }, "build": { "productName": "Whalebird", @@ -90,6 +90,13 @@ "category": "Network" } }, + "jest": { + "moduleNameMapper": { + "^@/(.+)": "/src/renderer/$1", + "^~/(.+)": "/$1", + "electron": "/spec/mock/electron.js" + } + }, "dependencies": { "@panter/vue-i18next": "^0.13.0", "@trodi/electron-splashscreen": "^0.3.4", @@ -138,6 +145,7 @@ "ajv": "^6.6.1", "babel-core": "^6.26.3", "babel-eslint": "^10.0.1", + "babel-jest": "^23.6.0", "babel-loader": "^7.1.4", "babel-minify-webpack-plugin": "^0.3.1", "babel-plugin-istanbul": "^5.1.0", @@ -184,6 +192,7 @@ "multispinner": "^0.2.1", "node-loader": "^0.6.0", "node-sass": "^4.10.0", + "regenerator-runtime": "^0.13.1", "sass-loader": "^7.0.3", "style-loader": "^0.23.1", "stylelint": "^9.9.0", diff --git a/sideci.yml b/sideci.yml index cce7e532..884df5e9 100644 --- a/sideci.yml +++ b/sideci.yml @@ -4,6 +4,7 @@ linter: dir: - src - test + - spec options: config: '.eslintrc.js' ext: '.js,.vue' diff --git a/spec/mock/electron.js b/spec/mock/electron.js new file mode 100644 index 00000000..cb4fe45a --- /dev/null +++ b/spec/mock/electron.js @@ -0,0 +1,6 @@ +export const ipcRenderer = { + send: jest.fn(), + on: jest.fn(), + once: jest.fn(), + removeAllListeners: jest.fn() +} diff --git a/spec/unit/store/Login.spec.js b/spec/unit/store/Login.spec.js new file mode 100644 index 00000000..6d398fbf --- /dev/null +++ b/spec/unit/store/Login.spec.js @@ -0,0 +1,64 @@ +import axios from 'axios' +import Login from '@/store/Login' +import { ipcRenderer } from '~/spec/mock/electron' + +jest.mock('axios') + +describe('Login', () => { + describe('mutations', () => { + let state + beforeEach(() => { + state = { + instances: [], + selectedInstance: null, + searching: false + } + }) + describe('changeInstance', () => { + it('should be changed', () => { + Login.mutations.changeInstance(state, 'pleroma.io') + expect(state.selectedInstance).toEqual('pleroma.io') + }) + }) + describe('changeSearching', () => { + it('should be changed', () => { + Login.mutations.changeSearching(state, true) + expect(state.searching).toEqual(true) + }) + }) + }) + + describe('actions', () => { + let state + beforeEach(() => { + state = { + instances: [], + selectedInstance: null, + searching: false + } + }) + describe('fetchLogin', async () => { + const commitMock = jest.fn() + const url = await Login.actions.fetchLogin({ commit: commitMock }, 'pleroma.io') + expect(ipcRenderer.send).toHaveBeenCalledWith('get-auth-url', 'pleroma.io') + }) + describe('pageBack', () => { + const commitMock = jest.fn() + Login.actions.pageBack({ commit: commitMock }) + expect(commitMock).toHaveBeenCalledWith('changeInstance', null) + }) + describe('confirmInstance', async () => { + const resp = { + data: 'test' + } + // Provide Promise.resolve for finally keywrod. + // https://github.com/facebook/jest/issues/6552 + axios.get.mockReturnValue(Promise.resolve(resp)) + const commitMock = jest.fn() + const data = await Login.actions.confirmInstance({ commit: commitMock }, 'pleroma.io') + expect(data).toEqual('test') + // ref: https://eddyerburgh.me/how-to-unit-test-a-vuex-store + expect(commitMock).toHaveBeenCalledWith('changeInstance', 'pleroma.io') + }) + }) +}) diff --git a/spec/unit/emojify.spec.js b/spec/unit/utils/emojify.spec.js similarity index 97% rename from spec/unit/emojify.spec.js rename to spec/unit/utils/emojify.spec.js index ef2c06e1..81ef584b 100644 --- a/spec/unit/emojify.spec.js +++ b/spec/unit/utils/emojify.spec.js @@ -1,5 +1,5 @@ import assert from 'assert' -import emojify from '../../src/renderer/utils/emojify' +import emojify from '@/utils/emojify' describe('emojify', () => { const emoji = [ diff --git a/spec/unit/suggestText.spec.js b/spec/unit/utils/suggestText.spec.js similarity index 95% rename from spec/unit/suggestText.spec.js rename to spec/unit/utils/suggestText.spec.js index 005c9fb5..918c80fd 100644 --- a/spec/unit/suggestText.spec.js +++ b/spec/unit/utils/suggestText.spec.js @@ -1,5 +1,5 @@ import assert from 'assert' -import suggestText from '../../src/renderer/utils/suggestText' +import suggestText from '@/utils/suggestText' describe('account', () => { describe('Only account name', () => { diff --git a/spec/unit/tootParser.spec.js b/spec/unit/utils/tootParser.spec.js similarity index 97% rename from spec/unit/tootParser.spec.js rename to spec/unit/utils/tootParser.spec.js index e25e0476..0c172ad4 100644 --- a/spec/unit/tootParser.spec.js +++ b/spec/unit/utils/tootParser.spec.js @@ -1,6 +1,6 @@ import assert from 'assert' import { JSDOM } from 'jsdom' -import { findLink, findTag, findAccount } from '../../src/renderer/utils/tootParser' +import { findLink, findTag, findAccount } from '@/utils/tootParser' describe('findLink', () => { describe('Pleroma', () => { diff --git a/spec/unit/validator.spec.js b/spec/unit/utils/validator.spec.js similarity index 96% rename from spec/unit/validator.spec.js rename to spec/unit/utils/validator.spec.js index 373df584..b952c20d 100644 --- a/spec/unit/validator.spec.js +++ b/spec/unit/utils/validator.spec.js @@ -1,5 +1,5 @@ import assert from 'assert' -import { domainFormat } from '../../src/renderer/utils/validator' +import { domainFormat } from '@/utils/validator' describe('validator', () => { describe('domainFormat', () => { diff --git a/src/renderer/store/Login.js b/src/renderer/store/Login.js index e34ad362..ec4c7ac8 100644 --- a/src/renderer/store/Login.js +++ b/src/renderer/store/Login.js @@ -17,7 +17,7 @@ const Login = { } }, actions: { - fetchLogin ({ commit }, instance) { + fetchLogin (_, instance) { return new Promise((resolve, reject) => { ipcRenderer.send('get-auth-url', instance) ipcRenderer.once('error-get-auth-url', (event, err) => { From fb429e49268f2dd47cf8602f0623e84204f01022 Mon Sep 17 00:00:00 2001 From: AkiraFukushima Date: Sat, 29 Dec 2018 00:21:26 +0900 Subject: [PATCH 2/2] refs #209 Add eslint config for jest spec codes --- spec/.eslintrc | 5 +++++ spec/unit/store/Login.spec.js | 10 +--------- spec/unit/utils/emojify.spec.js | 15 ++++----------- spec/unit/utils/suggestText.spec.js | 21 ++++++++++----------- spec/unit/utils/tootParser.spec.js | 15 +++++++-------- spec/unit/utils/validator.spec.js | 17 ++++++++--------- 6 files changed, 35 insertions(+), 48 deletions(-) create mode 100644 spec/.eslintrc diff --git a/spec/.eslintrc b/spec/.eslintrc new file mode 100644 index 00000000..7bc296da --- /dev/null +++ b/spec/.eslintrc @@ -0,0 +1,5 @@ +{ + "env": { + "jest": true + } +} \ No newline at end of file diff --git a/spec/unit/store/Login.spec.js b/spec/unit/store/Login.spec.js index 6d398fbf..f32be094 100644 --- a/spec/unit/store/Login.spec.js +++ b/spec/unit/store/Login.spec.js @@ -29,17 +29,9 @@ describe('Login', () => { }) describe('actions', () => { - let state - beforeEach(() => { - state = { - instances: [], - selectedInstance: null, - searching: false - } - }) describe('fetchLogin', async () => { const commitMock = jest.fn() - const url = await Login.actions.fetchLogin({ commit: commitMock }, 'pleroma.io') + await Login.actions.fetchLogin({ commit: commitMock }, 'pleroma.io') expect(ipcRenderer.send).toHaveBeenCalledWith('get-auth-url', 'pleroma.io') }) describe('pageBack', () => { diff --git a/spec/unit/utils/emojify.spec.js b/spec/unit/utils/emojify.spec.js index 81ef584b..0ef34e16 100644 --- a/spec/unit/utils/emojify.spec.js +++ b/spec/unit/utils/emojify.spec.js @@ -1,4 +1,3 @@ -import assert from 'assert' import emojify from '@/utils/emojify' describe('emojify', () => { @@ -20,18 +19,14 @@ describe('emojify', () => { const str = 'I have a pen.' it('should not change', () => { const result = emojify(str, emoji) - assert.strictEqual( - result, - str - ) + expect(result).toEqual(str) }) }) describe('Contain a shortcode', () => { const str = 'I like :python:' it('should replace', () => { const result = emojify(str, emoji) - assert.strictEqual( - result, + expect(result).toEqual( 'I like python' ) }) @@ -40,8 +35,7 @@ describe('emojify', () => { const str = 'I like :python: , :nodejs: and :slack:' it('should replace', () => { const result = emojify(str, emoji) - assert.strictEqual( - result, + expect(result).toEqual( 'I like python , nodejs and slack' ) }) @@ -50,8 +44,7 @@ describe('emojify', () => { const str = 'I like :python: , I love :python:' it('should replace', () => { const result = emojify(str, emoji) - assert.strictEqual( - result, + expect(result).toEqual( 'I like python , I love python' ) }) diff --git a/spec/unit/utils/suggestText.spec.js b/spec/unit/utils/suggestText.spec.js index 918c80fd..0918c174 100644 --- a/spec/unit/utils/suggestText.spec.js +++ b/spec/unit/utils/suggestText.spec.js @@ -1,4 +1,3 @@ -import assert from 'assert' import suggestText from '@/utils/suggestText' describe('account', () => { @@ -6,40 +5,40 @@ describe('account', () => { const str = '@h3pote' it('should match', () => { const [start, word] = suggestText(str, 7) - assert.strictEqual(str, word) - assert.strictEqual(start, 1) + expect(str).toEqual(word) + expect(start).toEqual(1) }) }) describe('Beginning of the sentence', () => { const str = '@h3pote toot body' it('should match', () => { const [start, word] = suggestText(str, 7) - assert.strictEqual(word, '@h3pote') - assert.strictEqual(start, 1) + expect(word).toEqual('@h3pote') + expect(start).toEqual(1) }) }) describe('Halfway of the sentence', () => { const str = 'toot body @h3pote toot' it('should match', () => { const [start, word] = suggestText(str, 17) - assert.strictEqual(word, '@h3pote') - assert.strictEqual(start, 11) + expect(word).toEqual('@h3pote') + expect(start).toEqual(11) }) }) describe('End of the sentence', () => { const str = 'toot body @h3pote' it('should match', () => { const [start, word] = suggestText(str, 17) - assert.strictEqual(word, '@h3pote') - assert.strictEqual(start, 11) + expect(word).toEqual('@h3pote') + expect(start).toEqual(11) }) }) describe('No space', () => { const str = 'tootbody@h3pote' it('should not match', () => { const [start, word] = suggestText(str, 15) - assert.strictEqual(word, null) - assert.strictEqual(start, null) + expect(word).toEqual(null) + expect(start).toEqual(null) }) }) }) diff --git a/spec/unit/utils/tootParser.spec.js b/spec/unit/utils/tootParser.spec.js index 0c172ad4..d441b877 100644 --- a/spec/unit/utils/tootParser.spec.js +++ b/spec/unit/utils/tootParser.spec.js @@ -1,4 +1,3 @@ -import assert from 'assert' import { JSDOM } from 'jsdom' import { findLink, findTag, findAccount } from '@/utils/tootParser' @@ -16,7 +15,7 @@ I released Whalebird version 2.4.1. In version 2.4.0, Whalebird supports streami const target = doc.getElementById('link') it('should find', () => { const res = findLink(target) - assert.strictEqual(res, 'https://github.com/h3poteto/whalebird-desktop/releases/tag/2.4.1') + expect(res).toEqual('https://github.com/h3poteto/whalebird-desktop/releases/tag/2.4.1') }) }) }) @@ -34,7 +33,7 @@ I released Whalebird version 2.4.1. In version 2.4.0, Whalebird supports streami const target = doc.getElementById('tag') it('should find', () => { const res = findTag(target) - assert.strictEqual(res, 'whalebird') + expect(res).toEqual('whalebird') }) }) @@ -50,7 +49,7 @@ I released Whalebird version 2.4.1. In version 2.4.0, Whalebird supports streami const target = doc.getElementById('tag') it('should find', () => { const res = findTag(target) - assert.strictEqual(res, 'whalebird') + expect(res).toEqual('whalebird') }) }) }) @@ -67,8 +66,8 @@ describe('findAccount', () => { const target = doc.getElementById('user') it('should find', () => { const res = findAccount(target) - assert.strictEqual(res.username, '@h3_poteto') - assert.strictEqual(res.acct, '@h3_poteto@social.mikutter.hachune.net') + expect(res.username).toEqual('@h3_poteto') + expect(res.acct).toEqual('@h3_poteto@social.mikutter.hachune.net') }) }) @@ -82,8 +81,8 @@ describe('findAccount', () => { const target = doc.getElementById('user') it('should find', () => { const res = findAccount(target) - assert.strictEqual(res.username, '@h3poteto') - assert.strictEqual(res.acct, '@h3poteto@pleroma.io') + expect(res.username).toEqual('@h3poteto') + expect(res.acct).toEqual('@h3poteto@pleroma.io') }) }) }) diff --git a/spec/unit/utils/validator.spec.js b/spec/unit/utils/validator.spec.js index b952c20d..8a6493c7 100644 --- a/spec/unit/utils/validator.spec.js +++ b/spec/unit/utils/validator.spec.js @@ -1,4 +1,3 @@ -import assert from 'assert' import { domainFormat } from '@/utils/validator' describe('validator', () => { @@ -7,56 +6,56 @@ describe('validator', () => { const domain = 'https://mastodon.social' it('should not match', () => { const res = domain.search(domainFormat) - assert.strictEqual(res, -1) + expect(res).toEqual(-1) }) }) describe('string contains account name', () => { const domain = 'h3_poteto@mastodon.social' it('should not match', () => { const res = domain.search(domainFormat) - assert.strictEqual(res, -1) + expect(res).toEqual(-1) }) }) describe('string is gTLD domain', () => { const domain = 'mastodon.social' it('should match', () => { const res = domain.search(domainFormat) - assert.strictEqual(res, 0) + expect(res).toEqual(0) }) }) describe('string is subdomain', () => { const domain = 'music.mastodon.social' it('should match', () => { const res = domain.search(domainFormat) - assert.strictEqual(res, 0) + expect(res).toEqual(0) }) }) describe('string is subdomain', () => { const domain = 'social.tchncs.de' it('should match', () => { const res = domain.search(domainFormat) - assert.strictEqual(res, 0) + expect(res).toEqual(0) }) }) describe('string is jp domain', () => { const domain = 'mstdn.co.jp' it('should match', () => { const res = domain.search(domainFormat) - assert.strictEqual(res, 0) + expect(res).toEqual(0) }) }) describe('string contains hyphone', () => { const domain = 'music-mastodon.social' it('should match', () => { const res = domain.search(domainFormat) - assert.strictEqual(res, 0) + expect(res).toEqual(0) }) }) describe('string is short domain', () => { const domain = 'id.cc' it('should match', () => { const res = domain.search(domainFormat) - assert.strictEqual(res, 0) + expect(res).toEqual(0) }) }) })